X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgbe%2Fbase%2Fixgbe_common.c;h=ec61408d73b195e2aaa699b21f7e025101a1b0f0;hb=e4f4722c14e99c82df624c47d917ea86ce8b085c;hp=81793549b0491c373cf1343521f01113432898e4;hpb=17e80ad00fa9a34c89037c3afdcc9914bbca5de7;p=dpdk.git diff --git a/drivers/net/ixgbe/base/ixgbe_common.c b/drivers/net/ixgbe/base/ixgbe_common.c index 81793549b0..ec61408d73 100644 --- a/drivers/net/ixgbe/base/ixgbe_common.c +++ b/drivers/net/ixgbe/base/ixgbe_common.c @@ -69,7 +69,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) { struct ixgbe_eeprom_info *eeprom = &hw->eeprom; struct ixgbe_mac_info *mac = &hw->mac; - u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC); + u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); DEBUGFUNC("ixgbe_init_ops_generic"); @@ -134,6 +134,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) /* Flow Control */ mac->ops.fc_enable = ixgbe_fc_enable_generic; + mac->ops.setup_fc = ixgbe_setup_fc_generic; /* Link */ mac->ops.get_link_capabilities = NULL; @@ -184,6 +185,8 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: case IXGBE_DEV_ID_X550T: + case IXGBE_DEV_ID_X550T1: + case IXGBE_DEV_ID_X550EM_X_10G_T: supported = true; break; default: @@ -200,19 +203,19 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) } /** - * ixgbe_setup_fc - Set up flow control + * ixgbe_setup_fc_generic - Set up flow control * @hw: pointer to hardware structure * * Called at init time to set up flow control. **/ -STATIC s32 ixgbe_setup_fc(struct ixgbe_hw *hw) +s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw) { s32 ret_val = IXGBE_SUCCESS; u32 reg = 0, reg_bp = 0; u16 reg_cu = 0; bool locked = false; - DEBUGFUNC("ixgbe_setup_fc"); + DEBUGFUNC("ixgbe_setup_fc_generic"); /* Validate the requested mode */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { @@ -1032,7 +1035,7 @@ void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) bus->lan_id = bus->func; /* check for a port swap */ - reg = IXGBE_READ_REG(hw, IXGBE_FACTPS); + reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); if (reg & IXGBE_FACTPS_LFS) bus->func ^= 0x1; } @@ -1158,7 +1161,7 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) * Check for EEPROM present first. * If not present leave as none */ - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); if (eec & IXGBE_EEC_PRES) { eeprom->type = ixgbe_eeprom_spi; @@ -1719,14 +1722,14 @@ STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) status = IXGBE_ERR_SWFW_SYNC; if (status == IXGBE_SUCCESS) { - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); /* Request EEPROM Access */ eec |= IXGBE_EEC_REQ; - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); if (eec & IXGBE_EEC_GNT) break; usec_delay(5); @@ -1735,7 +1738,7 @@ STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) /* Release if grant not acquired */ if (!(eec & IXGBE_EEC_GNT)) { eec &= ~IXGBE_EEC_REQ; - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); DEBUGOUT("Could not acquire EEPROM grant\n"); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); @@ -1746,7 +1749,7 @@ STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) if (status == IXGBE_SUCCESS) { /* Clear CS and SK */ eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } @@ -1776,7 +1779,7 @@ STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) * If the SMBI bit is 0 when we read it, then the bit will be * set and we have the semaphore */ - swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); if (!(swsm & IXGBE_SWSM_SMBI)) { status = IXGBE_SUCCESS; break; @@ -1801,7 +1804,7 @@ STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) * If the SMBI bit is 0 when we read it, then the bit will be * set and we have the semaphore */ - swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); if (!(swsm & IXGBE_SWSM_SMBI)) status = IXGBE_SUCCESS; } @@ -1809,17 +1812,17 @@ STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) /* Now get the semaphore between SW/FW through the SWESMBI bit */ if (status == IXGBE_SUCCESS) { for (i = 0; i < timeout; i++) { - swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); /* Set the SW EEPROM semaphore bit to request access */ swsm |= IXGBE_SWSM_SWESMBI; - IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); + IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm); /* * If we set the bit successfully then we got the * semaphore. */ - swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); if (swsm & IXGBE_SWSM_SWESMBI) break; @@ -1916,15 +1919,15 @@ STATIC void ixgbe_standby_eeprom(struct ixgbe_hw *hw) DEBUGFUNC("ixgbe_standby_eeprom"); - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); /* Toggle CS to flush commands */ eec |= IXGBE_EEC_CS; - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); eec &= ~IXGBE_EEC_CS; - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } @@ -1944,7 +1947,7 @@ STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); /* * Mask is used to shift "count" bits of "data" out to the EEPROM @@ -1965,7 +1968,7 @@ STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, else eec &= ~IXGBE_EEC_DI; - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); @@ -1982,7 +1985,7 @@ STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, /* We leave the "DI" bit set to "0" when we leave this routine. */ eec &= ~IXGBE_EEC_DI; - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); } @@ -2005,7 +2008,7 @@ STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) * the value of the "DO" bit. During this "shifting in" process the * "DI" bit should always be clear. */ - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); @@ -2013,7 +2016,7 @@ STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) data = data << 1; ixgbe_raise_eeprom_clk(hw, &eec); - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); eec &= ~(IXGBE_EEC_DI); if (eec & IXGBE_EEC_DO) @@ -2039,7 +2042,7 @@ STATIC void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) * (setting the SK bit), then delay */ *eec = *eec | IXGBE_EEC_SK; - IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } @@ -2058,7 +2061,7 @@ STATIC void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) * delay */ *eec = *eec & ~IXGBE_EEC_SK; - IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } @@ -2073,19 +2076,19 @@ STATIC void ixgbe_release_eeprom(struct ixgbe_hw *hw) DEBUGFUNC("ixgbe_release_eeprom"); - eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); eec |= IXGBE_EEC_CS; /* Pull CS high */ eec &= ~IXGBE_EEC_SK; /* Lower SCK */ - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); /* Stop requesting EEPROM access */ eec &= ~IXGBE_EEC_REQ; - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); @@ -2240,7 +2243,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) * ixgbe_validate_mac_addr - Validate MAC address * @mac_addr: pointer to MAC address. * - * Tests a MAC address to ensure it is a valid Individual Address + * Tests a MAC address to ensure it is a valid Individual Address. **/ s32 ixgbe_validate_mac_addr(u8 *mac_addr) { @@ -2250,16 +2253,13 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr) /* Make sure it is not a multicast address */ if (IXGBE_IS_MULTICAST(mac_addr)) { - DEBUGOUT("MAC address is multicast\n"); status = IXGBE_ERR_INVALID_MAC_ADDR; /* Not a broadcast address */ } else if (IXGBE_IS_BROADCAST(mac_addr)) { - DEBUGOUT("MAC address is broadcast\n"); status = IXGBE_ERR_INVALID_MAC_ADDR; /* Reject the zero address */ } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { - DEBUGOUT("MAC address is all zeros\n"); status = IXGBE_ERR_INVALID_MAC_ADDR; } return status; @@ -3140,6 +3140,9 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n"); hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + if (hw->mac.type >= ixgbe_mac_X550) + goto out; + /* * Before proceeding, make sure that the PCIe block does not have * transactions pending. @@ -3567,6 +3570,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; break; @@ -4062,7 +4066,7 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, } if (link_up_wait_to_complete) { - for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { + for (i = 0; i < hw->mac.max_link_up_time; i++) { if (links_reg & IXGBE_LINKS_UP) { *link_up = true; break; @@ -4345,36 +4349,6 @@ u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) return (u8) (0 - sum); } -/** - * ixgbe_get_hi_status - Get host interface command status - * @hw: pointer to the HW structure - * @return_code: reads and returns code - * - * Check if command returned with success. On success return IXGBE_SUCCESS - * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. - **/ -s32 ixgbe_get_hi_status(struct ixgbe_hw *hw, u8 *ret_status) -{ - struct ixgbe_hic_hdr response; - u32 *response_val = (u32 *)&response; - - DEBUGFUNC("ixgbe_get_host_interface_status"); - - /* Read the command response */ - *response_val = IXGBE_CPU_TO_LE32(IXGBE_READ_REG(hw, IXGBE_FLEX_MNG)); - - if (ret_status) - *ret_status = response.cmd_or_resp.ret_status; - - if (response.cmd_or_resp.ret_status != FW_CEM_RESP_STATUS_SUCCESS) { - DEBUGOUT1("Host interface error=%x.\n", - response.cmd_or_resp.ret_status); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; - } - - return IXGBE_SUCCESS; -} - /** * ixgbe_host_interface_command - Issue command to manageability block * @hw: pointer to the HW structure @@ -4907,7 +4881,7 @@ bool ixgbe_mng_present(struct ixgbe_hw *hw) if (hw->mac.type < ixgbe_mac_82599EB) return false; - fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM); + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); fwsm &= IXGBE_FWSM_MODE_MASK; return fwsm == IXGBE_FWSM_FW_MODE_PT; } @@ -4922,7 +4896,7 @@ bool ixgbe_mng_enabled(struct ixgbe_hw *hw) { u32 fwsm, manc, factps; - fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM); + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT) return false; @@ -4931,10 +4905,238 @@ bool ixgbe_mng_enabled(struct ixgbe_hw *hw) return false; if (hw->mac.type <= ixgbe_mac_X540) { - factps = IXGBE_READ_REG(hw, IXGBE_FACTPS); + factps = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); if (factps & IXGBE_FACTPS_MNGCG) return false; } return true; } + +/** + * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Set the link speed in the MAC and/or PHY register and restarts link. + **/ +s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN; + ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN; + s32 status = IXGBE_SUCCESS; + u32 speedcnt = 0; + u32 i = 0; + bool autoneg, link_up = false; + + DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber"); + + /* Mask off requested but non-supported speeds */ + status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg); + if (status != IXGBE_SUCCESS) + return status; + + speed &= link_speed; + + /* Try each speed one by one, highest priority first. We do this in + * software because 10Gb fiber doesn't support speed autonegotiation. + */ + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + speedcnt++; + highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; + + /* If we already have link at this speed, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, false); + if (status != IXGBE_SUCCESS) + return status; + + if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up) + goto out; + + /* Set the module link speed */ + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + ixgbe_set_rate_select_speed(hw, + IXGBE_LINK_SPEED_10GB_FULL); + break; + case ixgbe_media_type_fiber_qsfp: + /* QSFP module automatically detects MAC link speed */ + break; + default: + DEBUGOUT("Unexpected media type.\n"); + break; + } + + /* Allow module to change analog characteristics (1G->10G) */ + msec_delay(40); + + status = ixgbe_setup_mac_link(hw, + IXGBE_LINK_SPEED_10GB_FULL, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + return status; + + /* Flap the Tx laser if it has not already been done */ + ixgbe_flap_tx_laser(hw); + + /* Wait for the controller to acquire link. Per IEEE 802.3ap, + * Section 73.10.2, we may have to wait up to 500ms if KR is + * attempted. 82599 uses the same timing for 10g SFI. + */ + for (i = 0; i < 5; i++) { + /* Wait for the link partner to also set speed */ + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, + &link_up, false); + if (status != IXGBE_SUCCESS) + return status; + + if (link_up) + goto out; + } + } + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) { + speedcnt++; + if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) + highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; + + /* If we already have link at this speed, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, false); + if (status != IXGBE_SUCCESS) + return status; + + if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up) + goto out; + + /* Set the module link speed */ + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + ixgbe_set_rate_select_speed(hw, + IXGBE_LINK_SPEED_1GB_FULL); + break; + case ixgbe_media_type_fiber_qsfp: + /* QSFP module automatically detects link speed */ + break; + default: + DEBUGOUT("Unexpected media type.\n"); + break; + } + + /* Allow module to change analog characteristics (10G->1G) */ + msec_delay(40); + + status = ixgbe_setup_mac_link(hw, + IXGBE_LINK_SPEED_1GB_FULL, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + return status; + + /* Flap the Tx laser if it has not already been done */ + ixgbe_flap_tx_laser(hw); + + /* Wait for the link partner to also set speed */ + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, false); + if (status != IXGBE_SUCCESS) + return status; + + if (link_up) + goto out; + } + + /* We didn't get link. Configure back to the highest speed we tried, + * (if there was more than one). We call ourselves back with just the + * single highest speed that the user requested. + */ + if (speedcnt > 1) + status = ixgbe_setup_mac_link_multispeed_fiber(hw, + highest_link_speed, + autoneg_wait_to_complete); + +out: + /* Set autoneg_advertised value based on input link speed */ + hw->phy.autoneg_advertised = 0; + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + return status; +} + +/** + * ixgbe_set_soft_rate_select_speed - Set module link speed + * @hw: pointer to hardware structure + * @speed: link speed to set + * + * Set module link speed via the soft rate select. + */ +void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw, + ixgbe_link_speed speed) +{ + s32 status; + u8 rs, eeprom_data; + + switch (speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + /* one bit mask same as setting on */ + rs = IXGBE_SFF_SOFT_RS_SELECT_10G; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + rs = IXGBE_SFF_SOFT_RS_SELECT_1G; + break; + default: + DEBUGOUT("Invalid fixed module speed\n"); + return; + } + + /* Set RS0 */ + status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + &eeprom_data); + if (status) { + DEBUGOUT("Failed to read Rx Rate Select RS0\n"); + goto out; + } + + eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs; + + status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + eeprom_data); + if (status) { + DEBUGOUT("Failed to write Rx Rate Select RS0\n"); + goto out; + } + + /* Set RS1 */ + status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + &eeprom_data); + if (status) { + DEBUGOUT("Failed to read Rx Rate Select RS1\n"); + goto out; + } + + eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs; + + status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + eeprom_data); + if (status) { + DEBUGOUT("Failed to write Rx Rate Select RS1\n"); + goto out; + } +out: + return; +}