++ * The low power link up (lplu) state is set to the power management level D3
++ * and SmartSpeed is disabled when active is true, else clear lplu for D3
++ * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
++ * is used during Dx states where the power conservation is most important.
++ * During driver activity, SmartSpeed should be enabled so performance is
++ * maintained.
++ **/
++s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val = E1000_SUCCESS;
++ u16 data;
++
++ DEBUGFUNC("e1000_set_d3_lplu_state_generic");
++
++ if (!(hw->phy.ops.read_reg))
++ goto out;
++
++ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
++ if (ret_val)
++ goto out;
++
++ if (!active) {
++ data &= ~IGP02E1000_PM_D3_LPLU;
++ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
++ data);
++ if (ret_val)
++ goto out;
++ /*
++ * LPLU and SmartSpeed are mutually exclusive. LPLU is used
++ * during Dx states where the power conservation is most
++ * important. During driver activity we should enable
++ * SmartSpeed, so performance is maintained.
++ */
++ if (phy->smart_speed == e1000_smart_speed_on) {
++ ret_val = phy->ops.read_reg(hw,
++ IGP01E1000_PHY_PORT_CONFIG,
++ &data);
++ if (ret_val)
++ goto out;
++
++ data |= IGP01E1000_PSCFR_SMART_SPEED;
++ ret_val = phy->ops.write_reg(hw,
++ IGP01E1000_PHY_PORT_CONFIG,
++ data);
++ if (ret_val)
++ goto out;
++ } else if (phy->smart_speed == e1000_smart_speed_off) {
++ ret_val = phy->ops.read_reg(hw,
++ IGP01E1000_PHY_PORT_CONFIG,
++ &data);
++ if (ret_val)
++ goto out;
++
++ data &= ~IGP01E1000_PSCFR_SMART_SPEED;
++ ret_val = phy->ops.write_reg(hw,
++ IGP01E1000_PHY_PORT_CONFIG,
++ data);
++ if (ret_val)
++ goto out;
++ }
++ } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
++ (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
++ (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
++ data |= IGP02E1000_PM_D3_LPLU;
++ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
++ data);
++ if (ret_val)
++ goto out;
++
++ /* When LPLU is enabled, we should disable SmartSpeed */
++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++ &data);
++ if (ret_val)
++ goto out;
++
++ data &= ~IGP01E1000_PSCFR_SMART_SPEED;
++ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++ data);
++ }
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_check_downshift_generic - Checks whether a downshift in speed occurred
++ * @hw: pointer to the HW structure
++ *
++ * Success returns 0, Failure returns 1
++ *
++ * A downshift is detected by querying the PHY link health.
++ **/
++s32 e1000_check_downshift_generic(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val;
++ u16 phy_data, offset, mask;
++
++ DEBUGFUNC("e1000_check_downshift_generic");
++
++ switch (phy->type) {
++ case e1000_phy_m88:
++ case e1000_phy_gg82563:
++ offset = M88E1000_PHY_SPEC_STATUS;
++ mask = M88E1000_PSSR_DOWNSHIFT;
++ break;
++ case e1000_phy_igp_2:
++ case e1000_phy_igp:
++ case e1000_phy_igp_3:
++ offset = IGP01E1000_PHY_LINK_HEALTH;
++ mask = IGP01E1000_PLHR_SS_DOWNGRADE;
++ break;
++ default:
++ /* speed downshift not supported */
++ phy->speed_downgraded = false;
++ ret_val = E1000_SUCCESS;
++ goto out;
++ }
++
++ ret_val = phy->ops.read_reg(hw, offset, &phy_data);
++
++ if (!ret_val)
++ phy->speed_downgraded = (phy_data & mask) ? true : false;
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_check_polarity_m88 - Checks the polarity.
++ * @hw: pointer to the HW structure
++ *
++ * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
++ *
++ * Polarity is determined based on the PHY specific status register.
++ **/
++s32 e1000_check_polarity_m88(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val;
++ u16 data;
++
++ DEBUGFUNC("e1000_check_polarity_m88");
++
++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
++
++ if (!ret_val)
++ phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
++ ? e1000_rev_polarity_reversed
++ : e1000_rev_polarity_normal;
++
++ return ret_val;
++}
++
++/**
++ * e1000_check_polarity_igp - Checks the polarity.
++ * @hw: pointer to the HW structure
++ *
++ * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
++ *
++ * Polarity is determined based on the PHY port status register, and the
++ * current speed (since there is no polarity at 100Mbps).
++ **/
++s32 e1000_check_polarity_igp(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val;
++ u16 data, offset, mask;
++
++ DEBUGFUNC("e1000_check_polarity_igp");
++
++ /*
++ * Polarity is determined based on the speed of
++ * our connection.
++ */
++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
++ if (ret_val)
++ goto out;
++
++ if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
++ IGP01E1000_PSSR_SPEED_1000MBPS) {
++ offset = IGP01E1000_PHY_PCS_INIT_REG;
++ mask = IGP01E1000_PHY_POLARITY_MASK;
++ } else {
++ /*
++ * This really only applies to 10Mbps since
++ * there is no polarity for 100Mbps (always 0).
++ */
++ offset = IGP01E1000_PHY_PORT_STATUS;
++ mask = IGP01E1000_PSSR_POLARITY_REVERSED;
++ }
++
++ ret_val = phy->ops.read_reg(hw, offset, &data);
++
++ if (!ret_val)
++ phy->cable_polarity = (data & mask)
++ ? e1000_rev_polarity_reversed
++ : e1000_rev_polarity_normal;
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_check_polarity_ife - Check cable polarity for IFE PHY
++ * @hw: pointer to the HW structure
++ *
++ * Polarity is determined on the polarity reversal feature being enabled.
++ **/
++s32 e1000_check_polarity_ife(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val;
++ u16 phy_data, offset, mask;
++
++ DEBUGFUNC("e1000_check_polarity_ife");
++
++ /*
++ * Polarity is determined based on the reversal feature being enabled.
++ */
++ if (phy->polarity_correction) {
++ offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
++ mask = IFE_PESC_POLARITY_REVERSED;
++ } else {
++ offset = IFE_PHY_SPECIAL_CONTROL;
++ mask = IFE_PSC_FORCE_POLARITY;
++ }
++
++ ret_val = phy->ops.read_reg(hw, offset, &phy_data);
++
++ if (!ret_val)
++ phy->cable_polarity = (phy_data & mask)
++ ? e1000_rev_polarity_reversed
++ : e1000_rev_polarity_normal;
++
++ return ret_val;
++}
++
++/**
++ * e1000_wait_autoneg_generic - Wait for auto-neg completion
++ * @hw: pointer to the HW structure
++ *
++ * Waits for auto-negotiation to complete or for the auto-negotiation time
++ * limit to expire, which ever happens first.
++ **/
++s32 e1000_wait_autoneg_generic(struct e1000_hw *hw)
++{
++ s32 ret_val = E1000_SUCCESS;
++ u16 i, phy_status;
++
++ DEBUGFUNC("e1000_wait_autoneg_generic");
++
++ if (!(hw->phy.ops.read_reg))
++ return E1000_SUCCESS;
++
++ /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
++ for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
++ if (ret_val)
++ break;
++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
++ if (ret_val)
++ break;
++ if (phy_status & MII_SR_AUTONEG_COMPLETE)
++ break;
++ msec_delay(100);
++ }
++
++ /*
++ * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
++ * has completed.
++ */
++ return ret_val;
++}
++
++/**
++ * e1000_phy_has_link_generic - Polls PHY for link
++ * @hw: pointer to the HW structure
++ * @iterations: number of times to poll for link
++ * @usec_interval: delay between polling attempts
++ * @success: pointer to whether polling was successful or not
++ *
++ * Polls the PHY status register for link, 'iterations' number of times.
++ **/
++s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
++ u32 usec_interval, bool *success)
++{
++ s32 ret_val = E1000_SUCCESS;
++ u16 i, phy_status;
++
++ DEBUGFUNC("e1000_phy_has_link_generic");
++
++ if (!(hw->phy.ops.read_reg))
++ return E1000_SUCCESS;
++
++ for (i = 0; i < iterations; i++) {
++ /*
++ * Some PHYs require the PHY_STATUS register to be read
++ * twice due to the link bit being sticky. No harm doing
++ * it across the board.
++ */
++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
++ if (ret_val) {
++ /*
++ * If the first read fails, another entity may have
++ * ownership of the resources, wait and try again to
++ * see if they have relinquished the resources yet.
++ */
++ usec_delay(usec_interval);
++ }
++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
++ if (ret_val)
++ break;
++ if (phy_status & MII_SR_LINK_STATUS)
++ break;
++ if (usec_interval >= 1000)
++ msec_delay_irq(usec_interval/1000);
++ else
++ usec_delay(usec_interval);
++ }
++
++ *success = (i < iterations) ? true : false;
++
++ return ret_val;
++}
++
++/**
++ * e1000_get_cable_length_m88 - Determine cable length for m88 PHY
++ * @hw: pointer to the HW structure
++ *
++ * Reads the PHY specific status register to retrieve the cable length
++ * information. The cable length is determined by averaging the minimum and
++ * maximum values to get the "average" cable length. The m88 PHY has four
++ * possible cable length values, which are:
++ * Register Value Cable Length
++ * 0 < 50 meters
++ * 1 50 - 80 meters
++ * 2 80 - 110 meters
++ * 3 110 - 140 meters
++ * 4 > 140 meters
++ **/
++s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val;
++ u16 phy_data, index;
++
++ DEBUGFUNC("e1000_get_cable_length_m88");
++
++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
++ if (ret_val)
++ goto out;
++
++ index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
++ M88E1000_PSSR_CABLE_LENGTH_SHIFT;
++ if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
++ ret_val = -E1000_ERR_PHY;
++ goto out;
++ }
++
++ phy->min_cable_length = e1000_m88_cable_length_table[index];
++ phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
++
++ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY
++ * @hw: pointer to the HW structure
++ *
++ * The automatic gain control (agc) normalizes the amplitude of the
++ * received signal, adjusting for the attenuation produced by the
++ * cable. By reading the AGC registers, which represent the
++ * combination of coarse and fine gain value, the value can be put
++ * into a lookup table to obtain the approximate cable length
++ * for each channel.
++ **/
++s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val = E1000_SUCCESS;
++ u16 phy_data, i, agc_value = 0;
++ u16 cur_agc_index, max_agc_index = 0;
++ u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
++ u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
++ {IGP02E1000_PHY_AGC_A,
++ IGP02E1000_PHY_AGC_B,
++ IGP02E1000_PHY_AGC_C,
++ IGP02E1000_PHY_AGC_D};
++
++ DEBUGFUNC("e1000_get_cable_length_igp_2");
++
++ /* Read the AGC registers for all channels */
++ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
++ ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
++ if (ret_val)
++ goto out;
++
++ /*
++ * Getting bits 15:9, which represent the combination of
++ * coarse and fine gain values. The result is a number
++ * that can be put into the lookup table to obtain the
++ * approximate cable length.
++ */
++ cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
++ IGP02E1000_AGC_LENGTH_MASK;
++
++ /* Array index bound check. */
++ if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
++ (cur_agc_index == 0)) {
++ ret_val = -E1000_ERR_PHY;
++ goto out;
++ }
++
++ /* Remove min & max AGC values from calculation. */
++ if (e1000_igp_2_cable_length_table[min_agc_index] >
++ e1000_igp_2_cable_length_table[cur_agc_index])
++ min_agc_index = cur_agc_index;
++ if (e1000_igp_2_cable_length_table[max_agc_index] <
++ e1000_igp_2_cable_length_table[cur_agc_index])
++ max_agc_index = cur_agc_index;
++
++ agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
++ }
++
++ agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
++ e1000_igp_2_cable_length_table[max_agc_index]);
++ agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
++
++ /* Calculate cable length with the error range of +/- 10 meters. */
++ phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
++ (agc_value - IGP02E1000_AGC_RANGE) : 0;
++ phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
++
++ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_get_phy_info_m88 - Retrieve PHY information
++ * @hw: pointer to the HW structure
++ *
++ * Valid for only copper links. Read the PHY status register (sticky read)
++ * to verify that link is up. Read the PHY special control register to
++ * determine the polarity and 10base-T extended distance. Read the PHY
++ * special status register to determine MDI/MDIx and current speed. If
++ * speed is 1000, then determine cable length, local and remote receiver.
++ **/
++s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val;
++ u16 phy_data;
++ bool link;
++
++ DEBUGFUNC("e1000_get_phy_info_m88");
++
++ if (phy->media_type != e1000_media_type_copper) {
++ DEBUGOUT("Phy info is only valid for copper media\n");
++ ret_val = -E1000_ERR_CONFIG;
++ goto out;
++ }
++
++ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
++ if (ret_val)
++ goto out;
++
++ if (!link) {
++ DEBUGOUT("Phy info is only valid if link is up\n");
++ ret_val = -E1000_ERR_CONFIG;
++ goto out;
++ }
++
++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
++ if (ret_val)
++ goto out;
++
++ phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
++ ? true : false;
++
++ ret_val = e1000_check_polarity_m88(hw);
++ if (ret_val)
++ goto out;
++
++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
++ if (ret_val)
++ goto out;
++
++ phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false;
++
++ if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
++ ret_val = hw->phy.ops.get_cable_length(hw);
++ if (ret_val)
++ goto out;
++
++ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
++ if (ret_val)
++ goto out;
++
++ phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
++ ? e1000_1000t_rx_status_ok
++ : e1000_1000t_rx_status_not_ok;
++
++ phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
++ ? e1000_1000t_rx_status_ok
++ : e1000_1000t_rx_status_not_ok;
++ } else {
++ /* Set values to "undefined" */
++ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
++ phy->local_rx = e1000_1000t_rx_status_undefined;
++ phy->remote_rx = e1000_1000t_rx_status_undefined;
++ }
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_get_phy_info_igp - Retrieve igp PHY information
++ * @hw: pointer to the HW structure
++ *
++ * Read PHY status to determine if link is up. If link is up, then
++ * set/determine 10base-T extended distance and polarity correction. Read
++ * PHY port status to determine MDI/MDIx and speed. Based on the speed,
++ * determine on the cable length, local and remote receiver.
++ **/
++s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val;
++ u16 data;
++ bool link;
++
++ DEBUGFUNC("e1000_get_phy_info_igp");
++
++ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
++ if (ret_val)
++ goto out;
++
++ if (!link) {
++ DEBUGOUT("Phy info is only valid if link is up\n");
++ ret_val = -E1000_ERR_CONFIG;
++ goto out;
++ }
++
++ phy->polarity_correction = true;
++
++ ret_val = e1000_check_polarity_igp(hw);
++ if (ret_val)
++ goto out;
++
++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
++ if (ret_val)
++ goto out;
++
++ phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? true : false;
++
++ if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
++ IGP01E1000_PSSR_SPEED_1000MBPS) {
++ ret_val = phy->ops.get_cable_length(hw);
++ if (ret_val)
++ goto out;
++
++ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
++ if (ret_val)
++ goto out;
++
++ phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
++ ? e1000_1000t_rx_status_ok
++ : e1000_1000t_rx_status_not_ok;
++
++ phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
++ ? e1000_1000t_rx_status_ok
++ : e1000_1000t_rx_status_not_ok;
++ } else {
++ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
++ phy->local_rx = e1000_1000t_rx_status_undefined;
++ phy->remote_rx = e1000_1000t_rx_status_undefined;
++ }
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_phy_sw_reset_generic - PHY software reset
++ * @hw: pointer to the HW structure
++ *
++ * Does a software reset of the PHY by reading the PHY control register and
++ * setting/write the control register reset bit to the PHY.
++ **/
++s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw)
++{
++ s32 ret_val = E1000_SUCCESS;
++ u16 phy_ctrl;
++
++ DEBUGFUNC("e1000_phy_sw_reset_generic");
++
++ if (!(hw->phy.ops.read_reg))
++ goto out;
++
++ ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
++ if (ret_val)
++ goto out;
++
++ phy_ctrl |= MII_CR_RESET;
++ ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
++ if (ret_val)
++ goto out;
++
++ usec_delay(1);
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_phy_hw_reset_generic - PHY hardware reset
++ * @hw: pointer to the HW structure
++ *
++ * Verify the reset block is not blocking us from resetting. Acquire
++ * semaphore (if necessary) and read/set/write the device control reset
++ * bit in the PHY. Wait the appropriate delay time for the device to
++ * reset and release the semaphore (if necessary).
++ **/
++s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
++{
++ struct e1000_phy_info *phy = &hw->phy;
++ s32 ret_val = E1000_SUCCESS;
++ u32 ctrl;
++
++ DEBUGFUNC("e1000_phy_hw_reset_generic");
++
++ ret_val = phy->ops.check_reset_block(hw);
++ if (ret_val) {
++ ret_val = E1000_SUCCESS;
++ goto out;
++ }
++
++ ret_val = phy->ops.acquire(hw);
++ if (ret_val)
++ goto out;
++
++ ctrl = E1000_READ_REG(hw, E1000_CTRL);
++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PHY_RST);
++ E1000_WRITE_FLUSH(hw);
++
++ usec_delay(phy->reset_delay_us);
++
++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
++ E1000_WRITE_FLUSH(hw);
++
++ usec_delay(150);
++
++ phy->ops.release(hw);
++
++ ret_val = phy->ops.get_cfg_done(hw);
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_get_cfg_done_generic - Generic configuration done
++ * @hw: pointer to the HW structure
++ *
++ * Generic function to wait 10 milli-seconds for configuration to complete
++ * and return success.
++ **/
++s32 e1000_get_cfg_done_generic(struct e1000_hw *hw)
++{
++ DEBUGFUNC("e1000_get_cfg_done_generic");
++
++ msec_delay_irq(10);
++
++ return E1000_SUCCESS;
++}
++
++/**
++ * e1000_phy_init_script_igp3 - Inits the IGP3 PHY
++ * @hw: pointer to the HW structure
++ *
++ * Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
++ **/
++s32 e1000_phy_init_script_igp3(struct e1000_hw *hw)
++{
++ DEBUGOUT("Running IGP 3 PHY init script\n");
++
++ /* PHY init IGP 3 */
++ /* Enable rise/fall, 10-mode work in class-A */
++ hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
++ /* Remove all caps from Replica path filter */
++ hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
++ /* Bias trimming for ADC, AFE and Driver (Default) */
++ hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
++ /* Increase Hybrid poly bias */
++ hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
++ /* Add 4% to Tx amplitude in Gig mode */
++ hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
++ /* Disable trimming (TTT) */
++ hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
++ /* Poly DC correction to 94.6% + 2% for all channels */
++ hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
++ /* ABS DC correction to 95.9% */
++ hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
++ /* BG temp curve trim */
++ hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
++ /* Increasing ADC OPAMP stage 1 currents to max */
++ hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
++ /* Force 1000 ( required for enabling PHY regs configuration) */
++ hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
++ /* Set upd_freq to 6 */
++ hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
++ /* Disable NPDFE */
++ hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
++ /* Disable adaptive fixed FFE (Default) */
++ hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
++ /* Enable FFE hysteresis */
++ hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
++ /* Fixed FFE for short cable lengths */
++ hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
++ /* Fixed FFE for medium cable lengths */
++ hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
++ /* Fixed FFE for long cable lengths */
++ hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
++ /* Enable Adaptive Clip Threshold */
++ hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
++ /* AHT reset limit to 1 */
++ hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
++ /* Set AHT master delay to 127 msec */
++ hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
++ /* Set scan bits for AHT */
++ hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
++ /* Set AHT Preset bits */
++ hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
++ /* Change integ_factor of channel A to 3 */
++ hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
++ /* Change prop_factor of channels BCD to 8 */
++ hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
++ /* Change cg_icount + enable integbp for channels BCD */
++ hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
++ /*
++ * Change cg_icount + enable integbp + change prop_factor_master
++ * to 8 for channel A
++ */
++ hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
++ /* Disable AHT in Slave mode on channel A */
++ hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
++ /*
++ * Enable LPLU and disable AN to 1000 in non-D0a states,
++ * Enable SPD+B2B
++ */
++ hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
++ /* Enable restart AN on an1000_dis change */
++ hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
++ /* Enable wh_fifo read clock in 10/100 modes */
++ hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
++ /* Restart AN, Speed selection is 1000 */
++ hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
++
++ return E1000_SUCCESS;
++}
++
++/**
++ * e1000_get_phy_type_from_id - Get PHY type from id
++ * @phy_id: phy_id read from the phy
++ *
++ * Returns the phy type from the id.
++ **/
++enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
++{
++ enum e1000_phy_type phy_type = e1000_phy_unknown;
++
++ switch (phy_id) {
++ case M88E1000_I_PHY_ID:
++ case M88E1000_E_PHY_ID:
++ case M88E1111_I_PHY_ID:
++ case M88E1011_I_PHY_ID:
++ phy_type = e1000_phy_m88;
++ break;
++ case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
++ phy_type = e1000_phy_igp_2;
++ break;
++ case GG82563_E_PHY_ID:
++ phy_type = e1000_phy_gg82563;
++ break;
++ case IGP03E1000_E_PHY_ID:
++ phy_type = e1000_phy_igp_3;
++ break;
++ case IFE_E_PHY_ID:
++ case IFE_PLUS_E_PHY_ID:
++ case IFE_C_E_PHY_ID:
++ phy_type = e1000_phy_ife;
++ break;
++ default:
++ phy_type = e1000_phy_unknown;
++ break;
++ }
++ return phy_type;
++}
++
++/**
++ * e1000_determine_phy_address - Determines PHY address.
++ * @hw: pointer to the HW structure
++ *
++ * This uses a trial and error method to loop through possible PHY
++ * addresses. It tests each by reading the PHY ID registers and
++ * checking for a match.
++ **/
++s32 e1000_determine_phy_address(struct e1000_hw *hw)
++{
++ s32 ret_val = -E1000_ERR_PHY_TYPE;
++ u32 phy_addr = 0;
++ u32 i;
++ enum e1000_phy_type phy_type = e1000_phy_unknown;
++
++ hw->phy.id = phy_type;
++
++ for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
++ hw->phy.addr = phy_addr;
++ i = 0;
++
++ do {
++ e1000_get_phy_id(hw);
++ phy_type = e1000_get_phy_type_from_id(hw->phy.id);
++
++ /*
++ * If phy_type is valid, break - we found our
++ * PHY address
++ */
++ if (phy_type != e1000_phy_unknown) {
++ ret_val = E1000_SUCCESS;
++ goto out;
++ }
++ msec_delay(1);
++ i++;
++ } while (i < 10);
++ }
++
++out:
++ return ret_val;
++}
++
++/**
++ * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
++ * @hw: pointer to the HW structure
++ *
++ * In the case of a PHY power down to save power, or to turn off link during a
++ * driver unload, or wake on lan is not enabled, restore the link to previous
++ * settings.
++ **/
++void e1000_power_up_phy_copper(struct e1000_hw *hw)
++{
++ u16 mii_reg = 0;
++
++ /* The PHY will retain its settings across a power down/up cycle */
++ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
++ mii_reg &= ~MII_CR_POWER_DOWN;
++ hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
++}
++
++/**
++ * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
++ * @hw: pointer to the HW structure
++ *
++ * In the case of a PHY power down to save power, or to turn off link during a
++ * driver unload, or wake on lan is not enabled, restore the link to previous
++ * settings.
++ **/
++void e1000_power_down_phy_copper(struct e1000_hw *hw)
++{
++ u16 mii_reg = 0;
++
++ /* The PHY will retain its settings across a power down/up cycle */
++ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
++ mii_reg |= MII_CR_POWER_DOWN;
++ hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
++ msec_delay(1);
++}
+Index: linux-2.6.22/drivers/net/igb/e1000_phy.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22/drivers/net/igb/e1000_phy.h 2009-12-18 12:39:22.000000000 -0500
+@@ -0,0 +1,163 @@
++/*******************************************************************************
++
++ Intel(R) Gigabit Ethernet Linux driver
++ Copyright(c) 2007-2009 Intel Corporation.
++
++ This program is free software; you can redistribute it and/or modify it
++ under the terms and conditions of the GNU General Public License,
++ version 2, as published by the Free Software Foundation.
++
++ This program is distributed in the hope it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ more details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc.,
++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++
++ The full GNU General Public License is included in this distribution in
++ the file called "COPYING".
++
++ Contact Information:
++ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++*******************************************************************************/
++
++#ifndef _E1000_PHY_H_
++#define _E1000_PHY_H_
++
++void e1000_init_phy_ops_generic(struct e1000_hw *hw);
++s32 e1000_check_downshift_generic(struct e1000_hw *hw);
++s32 e1000_check_polarity_m88(struct e1000_hw *hw);
++s32 e1000_check_polarity_igp(struct e1000_hw *hw);
++s32 e1000_check_polarity_ife(struct e1000_hw *hw);
++s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
++s32 e1000_copper_link_autoneg(struct e1000_hw *hw);
++s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
++s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
++s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
++s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw);
++s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
++s32 e1000_get_cable_length_m88(struct e1000_hw *hw);
++s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw);
++s32 e1000_get_cfg_done_generic(struct e1000_hw *hw);
++s32 e1000_get_phy_id(struct e1000_hw *hw);
++s32 e1000_get_phy_info_igp(struct e1000_hw *hw);
++s32 e1000_get_phy_info_m88(struct e1000_hw *hw);
++s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw);
++void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
++s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw);
++s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw);
++s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data);
++s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data);
++s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
++s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data);
++s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
++s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active);
++s32 e1000_setup_copper_link_generic(struct e1000_hw *hw);
++s32 e1000_wait_autoneg_generic(struct e1000_hw *hw);
++s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data);
++s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data);
++s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
++s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data);
++s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
++s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
++s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
++ u32 usec_interval, bool *success);
++s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
++enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
++s32 e1000_determine_phy_address(struct e1000_hw *hw);
++void e1000_power_up_phy_copper(struct e1000_hw *hw);
++void e1000_power_down_phy_copper(struct e1000_hw *hw);
++s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
++s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
++s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
++s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
++
++#define E1000_MAX_PHY_ADDR 4
++
++/* IGP01E1000 Specific Registers */
++#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
++#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
++#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
++#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
++#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */
++#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */
++#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
++#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
++#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
++#define IGP_PAGE_SHIFT 5
++#define PHY_REG_MASK 0x1F
++
++#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
++#define IGP01E1000_PHY_POLARITY_MASK 0x0078
++
++#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
++#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
++
++#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
++
++/* Enable flexible speed on link-up */
++#define IGP01E1000_GMII_FLEX_SPD 0x0010
++#define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */
++
++#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
++#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
++#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
++
++#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
++
++#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
++#define IGP01E1000_PSSR_MDIX 0x0800
++#define IGP01E1000_PSSR_SPEED_MASK 0xC000
++#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
++
++#define IGP02E1000_PHY_CHANNEL_NUM 4
++#define IGP02E1000_PHY_AGC_A 0x11B1
++#define IGP02E1000_PHY_AGC_B 0x12B1
++#define IGP02E1000_PHY_AGC_C 0x14B1
++#define IGP02E1000_PHY_AGC_D 0x18B1
++
++#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
++#define IGP02E1000_AGC_LENGTH_MASK 0x7F
++#define IGP02E1000_AGC_RANGE 15
++
++#define IGP03E1000_PHY_MISC_CTRL 0x1B
++#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */
++
++#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
++
++#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
++#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
++#define E1000_KMRNCTRLSTA_REN 0x00200000
++#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
++#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */
++#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */
++#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
++
++#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
++#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */
++#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */
++#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
++
++/* IFE PHY Extended Status Control */
++#define IFE_PESC_POLARITY_REVERSED 0x0100
++
++/* IFE PHY Special Control */
++#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
++#define IFE_PSC_FORCE_POLARITY 0x0020
++#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100
++
++/* IFE PHY Special Control and LED Control */
++#define IFE_PSCL_PROBE_MODE 0x0020
++#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
++#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
++
++/* IFE PHY MDIX Control */
++#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
++#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
++#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */
++
++#endif
+Index: linux-2.6.22/drivers/net/igb/e1000_regs.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22/drivers/net/igb/e1000_regs.h 2009-12-18 12:39:22.000000000 -0500
+@@ -0,0 +1,484 @@
++/*******************************************************************************
++
++ Intel(R) Gigabit Ethernet Linux driver
++ Copyright(c) 2007-2009 Intel Corporation.
++
++ This program is free software; you can redistribute it and/or modify it
++ under the terms and conditions of the GNU General Public License,
++ version 2, as published by the Free Software Foundation.
++
++ This program is distributed in the hope it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ more details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc.,
++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++
++ The full GNU General Public License is included in this distribution in
++ the file called "COPYING".
++
++ Contact Information:
++ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++*******************************************************************************/
++
++#ifndef _E1000_REGS_H_
++#define _E1000_REGS_H_
++
++#define E1000_CTRL 0x00000 /* Device Control - RW */
++#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
++#define E1000_STATUS 0x00008 /* Device Status - RO */
++#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
++#define E1000_EERD 0x00014 /* EEPROM Read - RW */
++#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
++#define E1000_FLA 0x0001C /* Flash Access - RW */
++#define E1000_MDIC 0x00020 /* MDI Control - RW */
++#define E1000_SCTL 0x00024 /* SerDes Control - RW */
++#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
++#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
++#define E1000_FEXT 0x0002C /* Future Extended - RW */
++#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
++#define E1000_FCT 0x00030 /* Flow Control Type - RW */
++#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
++#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
++#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
++#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
++#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
++#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
++#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
++#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
++#define E1000_RCTL 0x00100 /* Rx Control - RW */
++#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
++#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
++#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */
++#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
++#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
++#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
++#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
++#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
++#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
++#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
++#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */
++#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
++#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
++#define E1000_TCTL 0x00400 /* Tx Control - RW */
++#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
++#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
++#define E1000_TBT 0x00448 /* Tx Burst Timer - RW */
++#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
++#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
++#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
++#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
++#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
++#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
++#define E1000_PBS 0x01008 /* Packet Buffer Size */
++#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
++#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
++#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
++#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
++#define E1000_FLSWCTL 0x01030 /* FLASH control register */
++#define E1000_FLSWDATA 0x01034 /* FLASH data register */
++#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
++#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
++#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
++#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
++#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */
++#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
++#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
++#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
++#define E1000_VPDDIAG 0x01060 /* VPD Diagnostic - RO */
++#define E1000_ICR_V2 0x01500 /* Interrupt Cause - new location - RC */
++#define E1000_ICS_V2 0x01504 /* Interrupt Cause Set - new location - WO */
++#define E1000_IMS_V2 0x01508 /* Interrupt Mask Set/Read - new location - RW */
++#define E1000_IMC_V2 0x0150C /* Interrupt Mask Clear - new location - WO */
++#define E1000_IAM_V2 0x01510 /* Interrupt Ack Auto Mask - new location - RW */
++#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
++#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
++#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
++#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
++#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
++#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */
++#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
++/* Split and Replication Rx Control - RW */
++#define E1000_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */
++#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */
++#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */
++#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */
++#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */
++#define E1000_PBDIAG 0x02458 /* Packet Buffer Diagnostic - RW */
++#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
++#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
++#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
++/*
++ * Convenience macros
++ *
++ * Note: "_n" is the queue number of the register to be written to.
++ *
++ * Example usage:
++ * E1000_RDBAL_REG(current_rx_queue)
++ */
++#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
++ (0x0C000 + ((_n) * 0x40)))
++#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
++ (0x0C004 + ((_n) * 0x40)))
++#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
++ (0x0C008 + ((_n) * 0x40)))
++#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
++ (0x0C00C + ((_n) * 0x40)))
++#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
++ (0x0C010 + ((_n) * 0x40)))
++#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \
++ (0x0C014 + ((_n) * 0x40)))
++#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n)
++#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
++ (0x0C018 + ((_n) * 0x40)))
++#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
++ (0x0C028 + ((_n) * 0x40)))
++#define E1000_RQDPC(_n) ((_n) < 4 ? (0x02830 + ((_n) * 0x100)) : \
++ (0x0C030 + ((_n) * 0x40)))
++#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
++ (0x0E000 + ((_n) * 0x40)))
++#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
++ (0x0E004 + ((_n) * 0x40)))
++#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
++ (0x0E008 + ((_n) * 0x40)))
++#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
++ (0x0E010 + ((_n) * 0x40)))
++#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \
++ (0x0E014 + ((_n) * 0x40)))
++#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n)
++#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
++ (0x0E018 + ((_n) * 0x40)))
++#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
++ (0x0E028 + ((_n) * 0x40)))
++#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : \
++ (0x0E038 + ((_n) * 0x40)))
++#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : \
++ (0x0E03C + ((_n) * 0x40)))
++#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100))
++#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */
++#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
++#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */
++#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
++#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
++#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
++ (0x054E0 + ((_i - 16) * 8)))
++#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
++ (0x054E4 + ((_i - 16) * 8)))
++#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
++#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
++#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
++#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
++#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
++#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
++#define E1000_PBSLAC 0x03100 /* Packet Buffer Slave Access Control */
++#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Packet Buffer DWORD (_n) */
++#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
++#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
++#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
++#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
++#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
++#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
++#define E1000_TDPUMB 0x0357C /* DMA Tx Descriptor uC Mail Box - RW */
++#define E1000_TDPUAD 0x03580 /* DMA Tx Descriptor uC Addr Command - RW */
++#define E1000_TDPUWD 0x03584 /* DMA Tx Descriptor uC Data Write - RW */
++#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */
++#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */
++#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */
++#define E1000_DTXTCPFLGL 0x0359C /* DMA Tx Control flag low - RW */
++#define E1000_DTXTCPFLGH 0x035A0 /* DMA Tx Control flag high - RW */
++#define E1000_DTXMXSZRQ 0x03540 /* DMA Tx Max Total Allow Size Requests - RW */
++#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
++#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
++#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
++#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
++#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
++#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
++#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
++#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
++#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
++#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
++#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
++#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
++#define E1000_COLC 0x04028 /* Collision Count - R/clr */
++#define E1000_DC 0x04030 /* Defer Count - R/clr */
++#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */
++#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
++#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
++#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
++#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */
++#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */
++#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
++#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
++#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
++#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
++#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
++#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
++#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
++#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
++#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
++#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
++#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
++#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
++#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
++#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
++#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
++#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
++#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
++#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
++#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */
++#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */
++#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */
++#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */
++#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
++#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
++#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
++#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
++#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */
++#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
++#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */
++#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */
++#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */
++#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
++#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
++#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
++#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
++#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
++#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
++#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
++#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
++#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
++#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
++#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
++#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */
++#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */
++#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */
++#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */
++#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
++#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */
++#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */
++#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
++
++#define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */
++#define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */
++#define E1000_LSECTXPKTP 0x04308 /* LinkSec Protected Tx Packet Count - OutPktsProtected */
++#define E1000_LSECTXOCTE 0x0430C /* LinkSec Encrypted Tx Octets Count - OutOctetsEncrypted */
++#define E1000_LSECTXOCTP 0x04310 /* LinkSec Protected Tx Octets Count - OutOctetsProtected */
++#define E1000_LSECRXUT 0x04314 /* LinkSec Untagged non-Strict Rx Packet Count - InPktsUntagged/InPktsNoTag */
++#define E1000_LSECRXOCTD 0x0431C /* LinkSec Rx Octets Decrypted Count - InOctetsDecrypted */
++#define E1000_LSECRXOCTV 0x04320 /* LinkSec Rx Octets Validated - InOctetsValidated */
++#define E1000_LSECRXBAD 0x04324 /* LinkSec Rx Bad Tag - InPktsBadTag */
++#define E1000_LSECRXNOSCI 0x04328 /* LinkSec Rx Packet No SCI Count - InPktsNoSci */
++#define E1000_LSECRXUNSCI 0x0432C /* LinkSec Rx Packet Unknown SCI Count - InPktsUnknownSci */
++#define E1000_LSECRXUNCH 0x04330 /* LinkSec Rx Unchecked Packets Count - InPktsUnchecked */
++#define E1000_LSECRXDELAY 0x04340 /* LinkSec Rx Delayed Packet Count - InPktsDelayed */
++#define E1000_LSECRXLATE 0x04350 /* LinkSec Rx Late Packets Count - InPktsLate */
++#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* LinkSec Rx Packet OK Count - InPktsOk */
++#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* LinkSec Rx Invalid Count - InPktsInvalid */
++#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* LinkSec Rx Not Valid Count - InPktsNotValid */
++#define E1000_LSECRXUNSA 0x043C0 /* LinkSec Rx Unused SA Count - InPktsUnusedSa */
++#define E1000_LSECRXNUSA 0x043D0 /* LinkSec Rx Not Using SA Count - InPktsNotUsingSa */
++#define E1000_LSECTXCAP 0x0B000 /* LinkSec Tx Capabilities Register - RO */
++#define E1000_LSECRXCAP 0x0B300 /* LinkSec Rx Capabilities Register - RO */
++#define E1000_LSECTXCTRL 0x0B004 /* LinkSec Tx Control - RW */
++#define E1000_LSECRXCTRL 0x0B304 /* LinkSec Rx Control - RW */
++#define E1000_LSECTXSCL 0x0B008 /* LinkSec Tx SCI Low - RW */
++#define E1000_LSECTXSCH 0x0B00C /* LinkSec Tx SCI High - RW */
++#define E1000_LSECTXSA 0x0B010 /* LinkSec Tx SA0 - RW */
++#define E1000_LSECTXPN0 0x0B018 /* LinkSec Tx SA PN 0 - RW */
++#define E1000_LSECTXPN1 0x0B01C /* LinkSec Tx SA PN 1 - RW */
++#define E1000_LSECRXSCL 0x0B3D0 /* LinkSec Rx SCI Low - RW */
++#define E1000_LSECRXSCH 0x0B3E0 /* LinkSec Rx SCI High - RW */
++#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 0 - WO */
++#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 1 - WO */
++#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
++#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
++/*
++ * LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
++ * key - RW.
++ */
++#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
++
++#define E1000_SSVPC 0x041A0 /* Switch Security Violation Packet Count */
++#define E1000_IPSCTRL 0xB430 /* IpSec Control Register */
++#define E1000_IPSRXCMD 0x0B408 /* IPSec Rx Command Register - RW */
++#define E1000_IPSRXIDX 0x0B400 /* IPSec Rx Index - RW */
++#define E1000_IPSRXIPADDR(_n) (0x0B420+ (0x04 * (_n))) /* IPSec Rx IPv4/v6 Address - RW */
++#define E1000_IPSRXKEY(_n) (0x0B410 + (0x04 * (_n))) /* IPSec Rx 128-bit Key - RW */
++#define E1000_IPSRXSALT 0x0B404 /* IPSec Rx Salt - RW */
++#define E1000_IPSRXSPI 0x0B40C /* IPSec Rx SPI - RW */
++#define E1000_IPSTXKEY(_n) (0x0B460 + (0x04 * (_n))) /* IPSec Tx 128-bit Key - RW */
++#define E1000_IPSTXSALT 0x0B454 /* IPSec Tx Salt - RW */
++#define E1000_IPSTXIDX 0x0B450 /* IPSec Tx SA IDX - RW */
++#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
++#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
++#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
++#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */
++#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
++#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */
++#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */
++#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
++#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */
++#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */
++#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
++#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
++#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
++#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
++#define E1000_LENERRS 0x04138 /* Length Errors Count */
++#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
++#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */
++#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
++#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
++#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
++#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
++#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */
++#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
++#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
++#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
++#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
++#define E1000_RA 0x05400 /* Receive Address - RW Array */
++#define E1000_RA2 0x054E0 /* 2nd half of receive address array - RW Array */
++#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
++#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
++#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
++#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
++#define E1000_WUC 0x05800 /* Wakeup Control - RW */
++#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
++#define E1000_WUS 0x05810 /* Wakeup Status - RO */
++#define E1000_MANC 0x05820 /* Management Control - RW */
++#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
++#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
++#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
++#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
++#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
++#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */
++#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
++#define E1000_HOST_IF 0x08800 /* Host Interface */
++#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
++#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
++#define E1000_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flexible Host Filter Table */
++#define E1000_FHFT_EXT(_n) (0x09A00 + (_n * 0x100)) /* Ext Flexible Host Filter Table */
++
++
++#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
++#define E1000_MDPHYA 0x0003C /* PHY address - RW */
++#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
++#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
++#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
++#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
++#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
++#define E1000_GCR 0x05B00 /* PCI-Ex Control */
++#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */
++#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
++#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
++#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
++#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
++#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
++#define E1000_SWSM 0x05B50 /* SW Semaphore */
++#define E1000_FWSM 0x05B54 /* FW Semaphore */
++#define E1000_SWSM2 0x05B58 /* Driver-only SW semaphore (not used by BOOT agents) */
++#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
++#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
++#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
++#define E1000_HICR 0x08F00 /* Host Interface Control */
++
++/* RSS registers */
++#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
++#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
++#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
++#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
++#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt Rx VLAN Priority - RW */
++#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Allocation Register
++ * (_i) - RW */
++#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10)) /* MSI-X Table entry addr
++ * low reg - RW */
++#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10)) /* MSI-X Table entry addr
++ * upper reg - RW */
++#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10)) /* MSI-X Table entry
++ * message reg - RW */
++#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10)) /* MSI-X Table entry
++ * vector ctrl reg - RW */
++#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
++#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
++#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
++#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
++#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
++/* VT Registers */
++#define E1000_SWPBS 0x03004 /* Switch Packet Buffer Size - RW */
++#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
++#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
++#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
++#define E1000_VFRE 0x00C8C /* VF Receive Enables */
++#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
++#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
++#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
++#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
++#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
++#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
++#define E1000_VMRCTL 0X05D80 /* Virtual Mirror Rule Control */
++/* These act per VF so an array friendly macro is used */
++#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n)))
++#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
++#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
++#define E1000_VFVMBMEM(_n) (0x00800 + (_n))
++#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
++#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
++ * Filter - RW */
++/* Time Sync */
++#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
++#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
++#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
++#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
++#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
++#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
++#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
++#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
++#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
++#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
++#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
++#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
++
++/* Filtering Registers */
++#define E1000_SAQF(_n) (0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
++#define E1000_DAQF(_n) (0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
++#define E1000_SPQF(_n) (0x059C0 + (4 * (_n))) /* Source Port Queue Fltr */
++#define E1000_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */
++#define E1000_TTQF(_n) (0x059E0 + (4 * (_n))) /* 2-tuple Queue Fltr */
++#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
++#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
++
++#define E1000_RTTDCS 0x3600 /* Reedtown Tx Desc plane control and status */
++#define E1000_RTTPCS 0x3474 /* Reedtown Tx Packet Plane control and status */
++#define E1000_RTRPCS 0x2474 /* Rx packet plane control and status */
++#define E1000_RTRUP2TC 0x05AC4 /* Rx User Priority to Traffic Class */
++#define E1000_RTTUP2TC 0x0418 /* Transmit User Priority to Traffic Class */
++#define E1000_RTTDTCRC(_n) (0x3610 + ((_n) * 4)) /* Tx Desc plane TC Rate-scheduler config */
++#define E1000_RTTPTCRC(_n) (0x3480 + ((_n) * 4)) /* Tx Packet plane TC Rate-Scheduler Config */
++#define E1000_RTRPTCRC(_n) (0x2480 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler Config */
++#define E1000_RTTDTCRS(_n) (0x3630 + ((_n) * 4)) /* Tx Desc Plane TC Rate-Scheduler Status */
++#define E1000_RTTDTCRM(_n) (0x3650 + ((_n) * 4)) /* Tx Desc Plane TC Rate-Scheduler MMW */
++#define E1000_RTTPTCRS(_n) (0x34A0 + ((_n) * 4)) /* Tx Packet plane TC Rate-Scheduler Status */
++#define E1000_RTTPTCRM(_n) (0x34C0 + ((_n) * 4)) /* Tx Packet plane TC Rate-scheduler MMW */
++#define E1000_RTRPTCRS(_n) (0x24A0 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler Status */
++#define E1000_RTRPTCRM(_n) (0x24C0 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler MMW */
++#define E1000_RTTDVMRM(_n) (0x3670 + ((_n) * 4)) /* Tx Desc plane VM Rate-Scheduler MMW*/
++#define E1000_RTTBCNRM(_n) (0x3690 + ((_n) * 4)) /* Tx BCN Rate-Scheduler MMW */
++#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select */
++#define E1000_RTTDVMRC 0x3608 /* Tx Desc Plane VM Rate-Scheduler Config */
++#define E1000_RTTDVMRS 0x360C /* Tx Desc Plane VM Rate-Scheduler Status */
++#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config */
++#define E1000_RTTBCNRS 0x36B4 /* Tx BCN Rate-Scheduler Status */
++#define E1000_RTTBCNCR 0xB200 /* Tx BCN Control Register */
++#define E1000_RTTBCNTG 0x35A4 /* Tx BCN Tagging */
++#define E1000_RTTBCNCP 0xB208 /* Tx BCN Congestion point */
++#define E1000_RTRBCNCR 0xB20C /* Rx BCN Control Register */
++#define E1000_RTTBCNRD 0x36B8 /* Tx BCN Rate Drift */
++#define E1000_PFCTOP 0x1080 /* Priority Flow Control Type and Opcode */
++#define E1000_RTTBCNIDX 0xB204 /* Tx BCN Congestion Point */
++#define E1000_RTTBCNACH 0x0B214 /* Tx BCN Control High */
++#define E1000_RTTBCNACL 0x0B210 /* Tx BCN Control Low */
++
++#endif
+Index: linux-2.6.22/drivers/net/igb/igb.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22/drivers/net/igb/igb.h 2009-12-18 12:39:22.000000000 -0500
+@@ -0,0 +1,444 @@
++/*******************************************************************************
++
++ Intel(R) Gigabit Ethernet Linux driver
++ Copyright(c) 2007-2009 Intel Corporation.
++
++ This program is free software; you can redistribute it and/or modify it
++ under the terms and conditions of the GNU General Public License,
++ version 2, as published by the Free Software Foundation.
++
++ This program is distributed in the hope it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ more details.
++
++ You should have received a copy of the GNU General Public License along with
++ this program; if not, write to the Free Software Foundation, Inc.,
++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++
++ The full GNU General Public License is included in this distribution in
++ the file called "COPYING".
++
++ Contact Information:
++ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++*******************************************************************************/
++
++
++/* Linux PRO/1000 Ethernet Driver main header file */
++
++#ifndef _IGB_H_
++#define _IGB_H_
++
++#include <linux/pci.h>
++#include <linux/netdevice.h>
++#include <linux/vmalloc.h>
++
++#ifdef SIOCETHTOOL
++#include <linux/ethtool.h>
++#endif
++
++#ifdef SIOCSHWTSTAMP
++#include <linux/clocksource.h>
++#include <linux/timecompare.h>
++#include <linux/net_tstamp.h>
++#endif
++struct igb_adapter;
++
++#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
++#define IGB_DCA
++#endif
++#ifdef IGB_DCA
++#include <linux/dca.h>
++#endif
++
++
++#ifdef IGB_LRO
++#undef IGB_LRO
++#ifdef NETIF_F_LRO
++#if defined(CONFIG_INET_LRO) || defined(CONFIG_INET_LRO_MODULE)
++#include <linux/inet_lro.h>
++#define MAX_LRO_DESCRIPTORS 8
++#define IGB_LRO
++#endif
++#endif
++#endif /* IGB_LRO */
++
++#include "kcompat.h"
++
++#include "e1000_api.h"
++#include "e1000_82575.h"
++
++#define IGB_ERR(args...) printk(KERN_ERR "igb: " args)
++
++#define PFX "igb: "
++#define DPRINTK(nlevel, klevel, fmt, args...) \
++ (void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
++ printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
++ __FUNCTION__ , ## args))
++
++/* Interrupt defines */
++#define IGB_START_ITR 648 /* ~6000 ints/sec */
++
++/* Interrupt modes, as used by the IntMode paramter */
++#define IGB_INT_MODE_LEGACY 0
++#define IGB_INT_MODE_MSI 1
++#define IGB_INT_MODE_MSIX 2
++
++#define HW_PERF
++/* TX/RX descriptor defines */
++#define IGB_DEFAULT_TXD 256
++#define IGB_MIN_TXD 80
++#define IGB_MAX_TXD 4096
++
++#define IGB_DEFAULT_RXD 256
++#define IGB_MIN_RXD 80
++#define IGB_MAX_RXD 4096
++
++#define IGB_MIN_ITR_USECS 10 /* 100k irq/sec */
++#define IGB_MAX_ITR_USECS 8191 /* 120 irq/sec */
++
++#define NON_Q_VECTORS 1
++#define MAX_Q_VECTORS 8
++
++/* Transmit and receive queues */
++#define IGB_MAX_RX_QUEUES (adapter->vfs_allocated_count ? 2 : \
++ (hw->mac.type > e1000_82575 ? 8 : 4))
++#define IGB_ABS_MAX_TX_QUEUES 8
++#define IGB_MAX_TX_QUEUES IGB_MAX_RX_QUEUES
++
++#define IGB_MAX_VF_MC_ENTRIES 30
++#define IGB_MAX_VF_FUNCTIONS 8
++#define IGB_MAX_VFTA_ENTRIES 128
++#define IGB_MAX_UTA_ENTRIES 128
++#define MAX_EMULATION_MAC_ADDRS 16
++#define OUI_LEN 3
++
++struct vf_data_storage {
++ unsigned char vf_mac_addresses[ETH_ALEN];
++ u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
++ u16 num_vf_mc_hashes;
++ u16 default_vf_vlan_id;
++ u16 vlans_enabled;
++ unsigned char em_mac_addresses[MAX_EMULATION_MAC_ADDRS * ETH_ALEN];
++ u32 uta_table_copy[IGB_MAX_UTA_ENTRIES];
++ u32 flags;
++ unsigned long last_nack;
++};
++
++#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */
++#define IGB_VF_FLAG_UNI_PROMISC 0x00000002 /* VF has unicast promisc */
++#define IGB_VF_FLAG_MULTI_PROMISC 0x00000004 /* VF has multicast promisc */
++
++/* RX descriptor control thresholds.
++ * PTHRESH - MAC will consider prefetch if it has fewer than this number of
++ * descriptors available in its onboard memory.
++ * Setting this to 0 disables RX descriptor prefetch.
++ * HTHRESH - MAC will only prefetch if there are at least this many descriptors
++ * available in host memory.
++ * If PTHRESH is 0, this should also be 0.
++ * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
++ * descriptors until either it has this many to write back, or the
++ * ITR timer expires.
++ */
++#define IGB_RX_PTHRESH (hw->mac.type <= e1000_82576 ? 16 : 8)
++#define IGB_RX_HTHRESH 8
++#define IGB_RX_WTHRESH 1
++#define IGB_TX_PTHRESH 8
++#define IGB_TX_HTHRESH 1
++#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \
++ adapter->msix_entries) ? 0 : 16)
++
++/* this is the size past which hardware will drop packets when setting LPE=0 */
++#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
++
++/* Supported Rx Buffer Sizes */
++#define IGB_RXBUFFER_128 128 /* Used for packet split */
++#define IGB_RXBUFFER_256 256 /* Used for packet split */
++#define IGB_RXBUFFER_512 512
++#define IGB_RXBUFFER_1024 1024
++#define IGB_RXBUFFER_2048 2048
++#define IGB_RXBUFFER_4096 4096
++#define IGB_RXBUFFER_8192 8192
++#define IGB_RXBUFFER_16384 16384
++
++/* Packet Buffer allocations */
++#define IGB_PBA_BYTES_SHIFT 0xA
++#define IGB_TX_HEAD_ADDR_SHIFT 7
++#define IGB_PBA_TX_MASK 0xFFFF0000
++
++#define IGB_FC_PAUSE_TIME 0x0680 /* 858 usec */
++
++/* How many Tx Descriptors do we need to call netif_wake_queue ? */
++#define IGB_TX_QUEUE_WAKE 32
++/* How many Rx Buffers do we bundle into one write to the hardware ? */
++#define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
++
++#define AUTO_ALL_MODES 0
++#define IGB_EEPROM_APME 0x0400
++
++#ifndef IGB_MASTER_SLAVE
++/* Switch to override PHY master/slave setting */
++#define IGB_MASTER_SLAVE e1000_ms_hw_default
++#endif
++
++#define IGB_MNG_VLAN_NONE -1
++
++/* wrapper around a pointer to a socket buffer,
++ * so a DMA handle can be stored along with the buffer */
++struct igb_buffer {
++ struct sk_buff *skb;
++ dma_addr_t dma;
++ dma_addr_t page_dma;
++ union {
++ /* TX */
++ struct {
++ unsigned long time_stamp;
++ u16 length;
++ u16 next_to_watch;
++ };
++
++#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
++ /* RX */
++ struct {
++ unsigned long page_offset;
++ struct page *page;
++ };
++#endif
++ };
++};
++
++struct igb_queue_stats {
++ u64 packets;
++ u64 bytes;
++};
++
++struct igb_q_vector {
++ struct igb_adapter *adapter; /* backlink */
++ struct igb_ring *rx_ring;
++ struct igb_ring *tx_ring;
++ struct napi_struct napi;
++
++ u32 eims_value;
++ u16 cpu;
++
++ u16 itr_val;
++ u8 set_itr;
++ u8 itr_shift;
++ void __iomem *itr_register;
++
++ char name[IFNAMSIZ + 9];
++#ifndef HAVE_NETDEV_NAPI_LIST
++ struct net_device poll_dev;
++#endif
++};
++
++struct igb_ring {
++ struct igb_q_vector *q_vector; /* backlink to q_vector */
++ struct pci_dev *pdev; /* pci device for dma mapping */
++ dma_addr_t dma; /* phys address of the ring */
++ void *desc; /* descriptor ring memory */
++ unsigned int size; /* length of desc. ring in bytes */
++ u16 count; /* number of desc. in the ring */
++ u16 next_to_use;
++ u16 next_to_clean;
++ u8 queue_index;
++ u8 reg_idx;
++ void __iomem *head;
++ void __iomem *tail;
++ struct igb_buffer *buffer_info; /* array of buffer info structs */
++
++ unsigned int total_bytes;
++ unsigned int total_packets;
++
++ struct igb_queue_stats stats;
++
++ union {
++ /* TX */
++ struct {
++ unsigned int restart_queue;
++ u32 ctx_idx;
++ bool detect_tx_hung;
++ };
++ /* RX */
++ struct {
++ u64 hw_csum_err;
++ u64 hw_csum_good;
++ u32 rx_buffer_len;
++ u16 rx_ps_hdr_size;
++ bool rx_csum;
++#ifdef IGB_LRO
++ struct net_lro_mgr lro_mgr;
++ bool lro_used;
++#endif
++ };
++ };
++};
++
++
++#define IGB_ADVTXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS)
++
++#define IGB_DESC_UNUSED(R) \
++ ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
++ (R)->next_to_clean - (R)->next_to_use - 1)
++
++#define E1000_RX_DESC_ADV(R, i) \
++ (&(((union e1000_adv_rx_desc *)((R).desc))[i]))
++#define E1000_TX_DESC_ADV(R, i) \
++ (&(((union e1000_adv_tx_desc *)((R).desc))[i]))
++#define E1000_TX_CTXTDESC_ADV(R, i) \
++ (&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
++#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
++#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
++#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
++
++#define MAX_MSIX_COUNT 10
++/* board specific private data structure */
++
++struct igb_adapter {
++ struct timer_list watchdog_timer;
++ struct timer_list phy_info_timer;
++ struct vlan_group *vlgrp;
++ u16 mng_vlan_id;
++ u32 bd_number;
++ u32 wol;
++ u32 en_mng_pt;
++ u16 link_speed;
++ u16 link_duplex;
++
++ unsigned int total_tx_bytes;
++ unsigned int total_tx_packets;
++ unsigned int total_rx_bytes;
++ unsigned int total_rx_packets;
++ /* Interrupt Throttle Rate */
++ u32 itr;
++ u32 itr_setting;
++ u16 tx_itr;
++ u16 rx_itr;