Print this page
6064 ixgbe needs X550 support

*** 1,8 **** /****************************************************************************** ! Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: --- 1,8 ---- /****************************************************************************** ! Copyright (c) 2001-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*** 28,41 **** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ ! /*$FreeBSD: src/sys/dev/ixgbe/ixgbe_common.c,v 1.14 2012/07/05 20:51:44 jfv Exp $*/ #include "ixgbe_common.h" #include "ixgbe_phy.h" #include "ixgbe_api.h" static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); --- 28,43 ---- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ ! /*$FreeBSD$*/ #include "ixgbe_common.h" #include "ixgbe_phy.h" + #include "ixgbe_dcb.h" + #include "ixgbe_dcb_82599.h" #include "ixgbe_api.h" static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
*** 66,190 **** **/ 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); DEBUGFUNC("ixgbe_init_ops_generic"); /* EEPROM */ ! eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic; /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */ if (eec & IXGBE_EEC_PRES) { ! eeprom->ops.read = &ixgbe_read_eerd_generic; ! eeprom->ops.read_buffer = &ixgbe_read_eerd_buffer_generic; } else { ! eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic; eeprom->ops.read_buffer = ! &ixgbe_read_eeprom_buffer_bit_bang_generic; } ! eeprom->ops.write = &ixgbe_write_eeprom_generic; ! eeprom->ops.write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic; eeprom->ops.validate_checksum = ! &ixgbe_validate_eeprom_checksum_generic; ! eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic; ! eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_generic; /* MAC */ ! mac->ops.init_hw = &ixgbe_init_hw_generic; mac->ops.reset_hw = NULL; ! mac->ops.start_hw = &ixgbe_start_hw_generic; ! mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic; mac->ops.get_media_type = NULL; mac->ops.get_supported_physical_layer = NULL; ! mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic; ! mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic; ! mac->ops.stop_adapter = &ixgbe_stop_adapter_generic; ! mac->ops.get_bus_info = &ixgbe_get_bus_info_generic; ! mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie; ! mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync; ! mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync; /* LEDs */ ! mac->ops.led_on = &ixgbe_led_on_generic; ! mac->ops.led_off = &ixgbe_led_off_generic; ! mac->ops.blink_led_start = &ixgbe_blink_led_start_generic; ! mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic; /* RAR, Multicast, VLAN */ ! mac->ops.set_rar = &ixgbe_set_rar_generic; ! mac->ops.clear_rar = &ixgbe_clear_rar_generic; mac->ops.insert_mac_addr = NULL; mac->ops.set_vmdq = NULL; mac->ops.clear_vmdq = NULL; ! mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic; ! mac->ops.update_uc_addr_list = &ixgbe_update_uc_addr_list_generic; ! mac->ops.update_mc_addr_list = &ixgbe_update_mc_addr_list_generic; ! mac->ops.enable_mc = &ixgbe_enable_mc_generic; ! mac->ops.disable_mc = &ixgbe_disable_mc_generic; mac->ops.clear_vfta = NULL; mac->ops.set_vfta = NULL; mac->ops.set_vlvf = NULL; mac->ops.init_uta_tables = NULL; /* Flow Control */ ! mac->ops.fc_enable = &ixgbe_fc_enable_generic; /* Link */ mac->ops.get_link_capabilities = NULL; mac->ops.setup_link = NULL; mac->ops.check_link = NULL; return IXGBE_SUCCESS; } /** ! * ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow ! * control * @hw: pointer to hardware structure * ! * There are several phys that do not support autoneg flow control. This ! * function check the device id to see if the associated phy supports ! * autoneg flow control. **/ ! static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) { DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); switch (hw->device_id) { case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: ! return IXGBE_SUCCESS; ! case IXGBE_DEV_ID_82599_T3_LOM: ! return IXGBE_SUCCESS; default: ! return IXGBE_ERR_FC_NOT_SUPPORTED; } } /** ! * ixgbe_setup_fc - 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 ret_val = IXGBE_SUCCESS; u32 reg = 0, reg_bp = 0; u16 reg_cu = 0; ! DEBUGFUNC("ixgbe_setup_fc"); ! /* ! * Validate the requested mode. Strict IEEE mode does not allow ! * ixgbe_fc_rx_pause because it will cause us to fail at UNH. ! */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { ! DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; goto out; } /* --- 68,231 ---- **/ 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_BY_MAC(hw)); DEBUGFUNC("ixgbe_init_ops_generic"); /* EEPROM */ ! eeprom->ops.init_params = ixgbe_init_eeprom_params_generic; /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */ if (eec & IXGBE_EEC_PRES) { ! eeprom->ops.read = ixgbe_read_eerd_generic; ! eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_generic; } else { ! eeprom->ops.read = ixgbe_read_eeprom_bit_bang_generic; eeprom->ops.read_buffer = ! ixgbe_read_eeprom_buffer_bit_bang_generic; } ! eeprom->ops.write = ixgbe_write_eeprom_generic; ! eeprom->ops.write_buffer = ixgbe_write_eeprom_buffer_bit_bang_generic; eeprom->ops.validate_checksum = ! ixgbe_validate_eeprom_checksum_generic; ! eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_generic; ! eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_generic; /* MAC */ ! mac->ops.init_hw = ixgbe_init_hw_generic; mac->ops.reset_hw = NULL; ! mac->ops.start_hw = ixgbe_start_hw_generic; ! mac->ops.clear_hw_cntrs = ixgbe_clear_hw_cntrs_generic; mac->ops.get_media_type = NULL; mac->ops.get_supported_physical_layer = NULL; ! mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_generic; ! mac->ops.get_mac_addr = ixgbe_get_mac_addr_generic; ! mac->ops.stop_adapter = ixgbe_stop_adapter_generic; ! mac->ops.get_bus_info = ixgbe_get_bus_info_generic; ! mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie; ! mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync; ! mac->ops.release_swfw_sync = ixgbe_release_swfw_sync; ! mac->ops.prot_autoc_read = prot_autoc_read_generic; ! mac->ops.prot_autoc_write = prot_autoc_write_generic; /* LEDs */ ! mac->ops.led_on = ixgbe_led_on_generic; ! mac->ops.led_off = ixgbe_led_off_generic; ! mac->ops.blink_led_start = ixgbe_blink_led_start_generic; ! mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic; /* RAR, Multicast, VLAN */ ! mac->ops.set_rar = ixgbe_set_rar_generic; ! mac->ops.clear_rar = ixgbe_clear_rar_generic; mac->ops.insert_mac_addr = NULL; mac->ops.set_vmdq = NULL; mac->ops.clear_vmdq = NULL; ! mac->ops.init_rx_addrs = ixgbe_init_rx_addrs_generic; ! mac->ops.update_uc_addr_list = ixgbe_update_uc_addr_list_generic; ! mac->ops.update_mc_addr_list = ixgbe_update_mc_addr_list_generic; ! mac->ops.enable_mc = ixgbe_enable_mc_generic; ! mac->ops.disable_mc = ixgbe_disable_mc_generic; mac->ops.clear_vfta = NULL; mac->ops.set_vfta = NULL; mac->ops.set_vlvf = NULL; mac->ops.init_uta_tables = NULL; + mac->ops.enable_rx = ixgbe_enable_rx_generic; + mac->ops.disable_rx = ixgbe_disable_rx_generic; /* 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; mac->ops.setup_link = NULL; mac->ops.check_link = NULL; + mac->ops.dmac_config = NULL; + mac->ops.dmac_update_tcs = NULL; + mac->ops.dmac_config_tcs = NULL; return IXGBE_SUCCESS; } /** ! * ixgbe_device_supports_autoneg_fc - Check if device supports autonegotiation ! * of flow control * @hw: pointer to hardware structure * ! * This function returns TRUE if the device supports flow control ! * autonegotiation, and FALSE if it does not. ! * **/ ! bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) { + bool supported = FALSE; + ixgbe_link_speed speed; + bool link_up; DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber_fixed: + case ixgbe_media_type_fiber_qsfp: + case ixgbe_media_type_fiber: + hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); + /* if link is down, assume supported */ + if (link_up) + supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? + TRUE : FALSE; + else + supported = TRUE; + break; + case ixgbe_media_type_backplane: + supported = TRUE; + break; + case ixgbe_media_type_copper: + /* only some copper devices support flow control autoneg */ switch (hw->device_id) { + case IXGBE_DEV_ID_82599_T3_LOM: case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: ! case IXGBE_DEV_ID_X540_BYPASS: ! case IXGBE_DEV_ID_X550T: ! case IXGBE_DEV_ID_X550T1: ! case IXGBE_DEV_ID_X550EM_X_10G_T: ! supported = TRUE; ! break; default: ! supported = FALSE; } + default: + break; + } + + ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, + "Device %x does not support flow control autoneg", + hw->device_id); + return supported; } /** ! * ixgbe_setup_fc_generic - Set up flow control * @hw: pointer to hardware structure * * Called at init time to set up flow control. **/ ! 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_generic"); ! /* Validate the requested mode */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { ! ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, ! "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; goto out; } /*
*** 198,211 **** * Set up the 1G and 10G flow control advertisement registers so the * HW will be able to do fc autoneg once the cable is plugged in. If * we link at 10G, the 1G advertisement is harmless and vice versa. */ switch (hw->phy.media_type) { - case ixgbe_media_type_fiber: case ixgbe_media_type_backplane: reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); ! reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC); break; case ixgbe_media_type_copper: hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg_cu); break; --- 239,260 ---- * Set up the 1G and 10G flow control advertisement registers so the * HW will be able to do fc autoneg once the cable is plugged in. If * we link at 10G, the 1G advertisement is harmless and vice versa. */ switch (hw->phy.media_type) { case ixgbe_media_type_backplane: + /* some MAC's need RMW protection on AUTOC */ + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &reg_bp); + if (ret_val != IXGBE_SUCCESS) + goto out; + + /* only backplane uses autoc so fall though */ + case ixgbe_media_type_fiber_fixed: + case ixgbe_media_type_fiber_qsfp: + case ixgbe_media_type_fiber: reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); ! break; case ixgbe_media_type_copper: hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg_cu); break;
*** 266,281 **** IXGBE_AUTOC_ASM_PAUSE; else if (hw->phy.media_type == ixgbe_media_type_copper) reg_cu |= IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE; break; default: ! DEBUGOUT("Flow control param set incorrectly\n"); ret_val = IXGBE_ERR_CONFIG; goto out; } ! if (hw->mac.type != ixgbe_mac_X540) { /* * Enable auto-negotiation between the MAC & PHY; * the MAC will advertise clause 37 flow control. */ IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); --- 315,332 ---- IXGBE_AUTOC_ASM_PAUSE; else if (hw->phy.media_type == ixgbe_media_type_copper) reg_cu |= IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE; break; default: ! ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, ! "Flow control param set incorrectly\n"); ret_val = IXGBE_ERR_CONFIG; goto out; + break; } ! if (hw->mac.type < ixgbe_mac_X540) { /* * Enable auto-negotiation between the MAC & PHY; * the MAC will advertise clause 37 flow control. */ IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
*** 294,311 **** * and copper. There is no need to set the PCS1GCTL register. * */ if (hw->phy.media_type == ixgbe_media_type_backplane) { reg_bp |= IXGBE_AUTOC_AN_RESTART; ! IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); } else if ((hw->phy.media_type == ixgbe_media_type_copper) && ! (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) { hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu); } ! DEBUGOUT1("Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); out: return ret_val; } /** --- 345,364 ---- * and copper. There is no need to set the PCS1GCTL register. * */ if (hw->phy.media_type == ixgbe_media_type_backplane) { reg_bp |= IXGBE_AUTOC_AN_RESTART; ! ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked); ! if (ret_val) ! goto out; } else if ((hw->phy.media_type == ixgbe_media_type_copper) && ! (ixgbe_device_supports_autoneg_fc(hw))) { hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu); } ! DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg); out: return ret_val; } /**
*** 430,527 **** { u16 i = 0; DEBUGFUNC("ixgbe_clear_hw_cntrs_generic"); ! (void) IXGBE_READ_REG(hw, IXGBE_CRCERRS); ! (void) IXGBE_READ_REG(hw, IXGBE_ILLERRC); ! (void) IXGBE_READ_REG(hw, IXGBE_ERRBC); ! (void) IXGBE_READ_REG(hw, IXGBE_MSPDC); for (i = 0; i < 8; i++) ! (void) IXGBE_READ_REG(hw, IXGBE_MPC(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_MLFC); ! (void) IXGBE_READ_REG(hw, IXGBE_MRFC); ! (void) IXGBE_READ_REG(hw, IXGBE_RLEC); ! (void) IXGBE_READ_REG(hw, IXGBE_LXONTXC); ! (void) IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); if (hw->mac.type >= ixgbe_mac_82599EB) { ! (void) IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); ! (void) IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); } else { ! (void) IXGBE_READ_REG(hw, IXGBE_LXONRXC); ! (void) IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); } for (i = 0; i < 8; i++) { ! (void) IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); if (hw->mac.type >= ixgbe_mac_82599EB) { ! (void) IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); } else { ! (void) IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); } } if (hw->mac.type >= ixgbe_mac_82599EB) for (i = 0; i < 8; i++) ! (void) IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_PRC64); ! (void) IXGBE_READ_REG(hw, IXGBE_PRC127); ! (void) IXGBE_READ_REG(hw, IXGBE_PRC255); ! (void) IXGBE_READ_REG(hw, IXGBE_PRC511); ! (void) IXGBE_READ_REG(hw, IXGBE_PRC1023); ! (void) IXGBE_READ_REG(hw, IXGBE_PRC1522); ! (void) IXGBE_READ_REG(hw, IXGBE_GPRC); ! (void) IXGBE_READ_REG(hw, IXGBE_BPRC); ! (void) IXGBE_READ_REG(hw, IXGBE_MPRC); ! (void) IXGBE_READ_REG(hw, IXGBE_GPTC); ! (void) IXGBE_READ_REG(hw, IXGBE_GORCL); ! (void) IXGBE_READ_REG(hw, IXGBE_GORCH); ! (void) IXGBE_READ_REG(hw, IXGBE_GOTCL); ! (void) IXGBE_READ_REG(hw, IXGBE_GOTCH); if (hw->mac.type == ixgbe_mac_82598EB) for (i = 0; i < 8; i++) ! (void) IXGBE_READ_REG(hw, IXGBE_RNBC(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_RUC); ! (void) IXGBE_READ_REG(hw, IXGBE_RFC); ! (void) IXGBE_READ_REG(hw, IXGBE_ROC); ! (void) IXGBE_READ_REG(hw, IXGBE_RJC); ! (void) IXGBE_READ_REG(hw, IXGBE_MNGPRC); ! (void) IXGBE_READ_REG(hw, IXGBE_MNGPDC); ! (void) IXGBE_READ_REG(hw, IXGBE_MNGPTC); ! (void) IXGBE_READ_REG(hw, IXGBE_TORL); ! (void) IXGBE_READ_REG(hw, IXGBE_TORH); ! (void) IXGBE_READ_REG(hw, IXGBE_TPR); ! (void) IXGBE_READ_REG(hw, IXGBE_TPT); ! (void) IXGBE_READ_REG(hw, IXGBE_PTC64); ! (void) IXGBE_READ_REG(hw, IXGBE_PTC127); ! (void) IXGBE_READ_REG(hw, IXGBE_PTC255); ! (void) IXGBE_READ_REG(hw, IXGBE_PTC511); ! (void) IXGBE_READ_REG(hw, IXGBE_PTC1023); ! (void) IXGBE_READ_REG(hw, IXGBE_PTC1522); ! (void) IXGBE_READ_REG(hw, IXGBE_MPTC); ! (void) IXGBE_READ_REG(hw, IXGBE_BPTC); for (i = 0; i < 16; i++) { ! (void) IXGBE_READ_REG(hw, IXGBE_QPRC(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_QPTC(i)); if (hw->mac.type >= ixgbe_mac_82599EB) { ! (void) IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); } else { ! (void) IXGBE_READ_REG(hw, IXGBE_QBRC(i)); ! (void) IXGBE_READ_REG(hw, IXGBE_QBTC(i)); } } ! if (hw->mac.type == ixgbe_mac_X540) { if (hw->phy.id == 0) ! (void) ixgbe_identify_phy(hw); hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL, IXGBE_MDIO_PCS_DEV_TYPE, &i); hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH, IXGBE_MDIO_PCS_DEV_TYPE, &i); hw->phy.ops.read_reg(hw, IXGBE_LDPCECL, --- 483,580 ---- { u16 i = 0; DEBUGFUNC("ixgbe_clear_hw_cntrs_generic"); ! IXGBE_READ_REG(hw, IXGBE_CRCERRS); ! IXGBE_READ_REG(hw, IXGBE_ILLERRC); ! IXGBE_READ_REG(hw, IXGBE_ERRBC); ! IXGBE_READ_REG(hw, IXGBE_MSPDC); for (i = 0; i < 8; i++) ! IXGBE_READ_REG(hw, IXGBE_MPC(i)); ! IXGBE_READ_REG(hw, IXGBE_MLFC); ! IXGBE_READ_REG(hw, IXGBE_MRFC); ! IXGBE_READ_REG(hw, IXGBE_RLEC); ! IXGBE_READ_REG(hw, IXGBE_LXONTXC); ! IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); if (hw->mac.type >= ixgbe_mac_82599EB) { ! IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); ! IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); } else { ! IXGBE_READ_REG(hw, IXGBE_LXONRXC); ! IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); } for (i = 0; i < 8; i++) { ! IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); ! IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); if (hw->mac.type >= ixgbe_mac_82599EB) { ! IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); ! IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); } else { ! IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); ! IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); } } if (hw->mac.type >= ixgbe_mac_82599EB) for (i = 0; i < 8; i++) ! IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); ! IXGBE_READ_REG(hw, IXGBE_PRC64); ! IXGBE_READ_REG(hw, IXGBE_PRC127); ! IXGBE_READ_REG(hw, IXGBE_PRC255); ! IXGBE_READ_REG(hw, IXGBE_PRC511); ! IXGBE_READ_REG(hw, IXGBE_PRC1023); ! IXGBE_READ_REG(hw, IXGBE_PRC1522); ! IXGBE_READ_REG(hw, IXGBE_GPRC); ! IXGBE_READ_REG(hw, IXGBE_BPRC); ! IXGBE_READ_REG(hw, IXGBE_MPRC); ! IXGBE_READ_REG(hw, IXGBE_GPTC); ! IXGBE_READ_REG(hw, IXGBE_GORCL); ! IXGBE_READ_REG(hw, IXGBE_GORCH); ! IXGBE_READ_REG(hw, IXGBE_GOTCL); ! IXGBE_READ_REG(hw, IXGBE_GOTCH); if (hw->mac.type == ixgbe_mac_82598EB) for (i = 0; i < 8; i++) ! IXGBE_READ_REG(hw, IXGBE_RNBC(i)); ! IXGBE_READ_REG(hw, IXGBE_RUC); ! IXGBE_READ_REG(hw, IXGBE_RFC); ! IXGBE_READ_REG(hw, IXGBE_ROC); ! IXGBE_READ_REG(hw, IXGBE_RJC); ! IXGBE_READ_REG(hw, IXGBE_MNGPRC); ! IXGBE_READ_REG(hw, IXGBE_MNGPDC); ! IXGBE_READ_REG(hw, IXGBE_MNGPTC); ! IXGBE_READ_REG(hw, IXGBE_TORL); ! IXGBE_READ_REG(hw, IXGBE_TORH); ! IXGBE_READ_REG(hw, IXGBE_TPR); ! IXGBE_READ_REG(hw, IXGBE_TPT); ! IXGBE_READ_REG(hw, IXGBE_PTC64); ! IXGBE_READ_REG(hw, IXGBE_PTC127); ! IXGBE_READ_REG(hw, IXGBE_PTC255); ! IXGBE_READ_REG(hw, IXGBE_PTC511); ! IXGBE_READ_REG(hw, IXGBE_PTC1023); ! IXGBE_READ_REG(hw, IXGBE_PTC1522); ! IXGBE_READ_REG(hw, IXGBE_MPTC); ! IXGBE_READ_REG(hw, IXGBE_BPTC); for (i = 0; i < 16; i++) { ! IXGBE_READ_REG(hw, IXGBE_QPRC(i)); ! IXGBE_READ_REG(hw, IXGBE_QPTC(i)); if (hw->mac.type >= ixgbe_mac_82599EB) { ! IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); ! IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); ! IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); ! IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); ! IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); } else { ! IXGBE_READ_REG(hw, IXGBE_QBRC(i)); ! IXGBE_READ_REG(hw, IXGBE_QBTC(i)); } } ! if (hw->mac.type == ixgbe_mac_X550 || hw->mac.type == ixgbe_mac_X540) { if (hw->phy.id == 0) ! ixgbe_identify_phy(hw); hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL, IXGBE_MDIO_PCS_DEV_TYPE, &i); hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH, IXGBE_MDIO_PCS_DEV_TYPE, &i); hw->phy.ops.read_reg(hw, IXGBE_LDPCECL,
*** 677,686 **** --- 730,928 ---- return IXGBE_SUCCESS; } /** + * ixgbe_read_pba_raw + * @hw: pointer to the HW structure + * @eeprom_buf: optional pointer to EEPROM image + * @eeprom_buf_size: size of EEPROM image in words + * @max_pba_block_size: PBA block size limit + * @pba: pointer to output PBA structure + * + * Reads PBA from EEPROM image when eeprom_buf is not NULL. + * Reads PBA from physical EEPROM device when eeprom_buf is NULL. + * + **/ + s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf, + u32 eeprom_buf_size, u16 max_pba_block_size, + struct ixgbe_pba *pba) + { + s32 ret_val; + u16 pba_block_size; + + if (pba == NULL) + return IXGBE_ERR_PARAM; + + if (eeprom_buf == NULL) { + ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2, + &pba->word[0]); + if (ret_val) + return ret_val; + } else { + if (eeprom_buf_size > IXGBE_PBANUM1_PTR) { + pba->word[0] = eeprom_buf[IXGBE_PBANUM0_PTR]; + pba->word[1] = eeprom_buf[IXGBE_PBANUM1_PTR]; + } else { + return IXGBE_ERR_PARAM; + } + } + + if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) { + if (pba->pba_block == NULL) + return IXGBE_ERR_PARAM; + + ret_val = ixgbe_get_pba_block_size(hw, eeprom_buf, + eeprom_buf_size, + &pba_block_size); + if (ret_val) + return ret_val; + + if (pba_block_size > max_pba_block_size) + return IXGBE_ERR_PARAM; + + if (eeprom_buf == NULL) { + ret_val = hw->eeprom.ops.read_buffer(hw, pba->word[1], + pba_block_size, + pba->pba_block); + if (ret_val) + return ret_val; + } else { + if (eeprom_buf_size > (u32)(pba->word[1] + + pba_block_size)) { + memcpy(pba->pba_block, + &eeprom_buf[pba->word[1]], + pba_block_size * sizeof(u16)); + } else { + return IXGBE_ERR_PARAM; + } + } + } + + return IXGBE_SUCCESS; + } + + /** + * ixgbe_write_pba_raw + * @hw: pointer to the HW structure + * @eeprom_buf: optional pointer to EEPROM image + * @eeprom_buf_size: size of EEPROM image in words + * @pba: pointer to PBA structure + * + * Writes PBA to EEPROM image when eeprom_buf is not NULL. + * Writes PBA to physical EEPROM device when eeprom_buf is NULL. + * + **/ + s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf, + u32 eeprom_buf_size, struct ixgbe_pba *pba) + { + s32 ret_val; + + if (pba == NULL) + return IXGBE_ERR_PARAM; + + if (eeprom_buf == NULL) { + ret_val = hw->eeprom.ops.write_buffer(hw, IXGBE_PBANUM0_PTR, 2, + &pba->word[0]); + if (ret_val) + return ret_val; + } else { + if (eeprom_buf_size > IXGBE_PBANUM1_PTR) { + eeprom_buf[IXGBE_PBANUM0_PTR] = pba->word[0]; + eeprom_buf[IXGBE_PBANUM1_PTR] = pba->word[1]; + } else { + return IXGBE_ERR_PARAM; + } + } + + if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) { + if (pba->pba_block == NULL) + return IXGBE_ERR_PARAM; + + if (eeprom_buf == NULL) { + ret_val = hw->eeprom.ops.write_buffer(hw, pba->word[1], + pba->pba_block[0], + pba->pba_block); + if (ret_val) + return ret_val; + } else { + if (eeprom_buf_size > (u32)(pba->word[1] + + pba->pba_block[0])) { + memcpy(&eeprom_buf[pba->word[1]], + pba->pba_block, + pba->pba_block[0] * sizeof(u16)); + } else { + return IXGBE_ERR_PARAM; + } + } + } + + return IXGBE_SUCCESS; + } + + /** + * ixgbe_get_pba_block_size + * @hw: pointer to the HW structure + * @eeprom_buf: optional pointer to EEPROM image + * @eeprom_buf_size: size of EEPROM image in words + * @pba_data_size: pointer to output variable + * + * Returns the size of the PBA block in words. Function operates on EEPROM + * image if the eeprom_buf pointer is not NULL otherwise it accesses physical + * EEPROM device. + * + **/ + s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf, + u32 eeprom_buf_size, u16 *pba_block_size) + { + s32 ret_val; + u16 pba_word[2]; + u16 length; + + DEBUGFUNC("ixgbe_get_pba_block_size"); + + if (eeprom_buf == NULL) { + ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2, + &pba_word[0]); + if (ret_val) + return ret_val; + } else { + if (eeprom_buf_size > IXGBE_PBANUM1_PTR) { + pba_word[0] = eeprom_buf[IXGBE_PBANUM0_PTR]; + pba_word[1] = eeprom_buf[IXGBE_PBANUM1_PTR]; + } else { + return IXGBE_ERR_PARAM; + } + } + + if (pba_word[0] == IXGBE_PBANUM_PTR_GUARD) { + if (eeprom_buf == NULL) { + ret_val = hw->eeprom.ops.read(hw, pba_word[1] + 0, + &length); + if (ret_val) + return ret_val; + } else { + if (eeprom_buf_size > pba_word[1]) + length = eeprom_buf[pba_word[1] + 0]; + else + return IXGBE_ERR_PARAM; + } + + if (length == 0xFFFF || length == 0) + return IXGBE_ERR_PBA_SECTION; + } else { + /* PBA number in legacy format, there is no PBA Block. */ + length = 0; + } + + if (pba_block_size != NULL) + *pba_block_size = length; + + return IXGBE_SUCCESS; + } + + /** * ixgbe_get_mac_addr_generic - Generic get MAC address * @hw: pointer to hardware structure * @mac_addr: Adapter MAC address * * Reads the adapter's MAC address from first Receive Address Register (RAR0)
*** 706,732 **** return IXGBE_SUCCESS; } /** ! * ixgbe_get_bus_info_generic - Generic set PCI bus info * @hw: pointer to hardware structure * ! * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure **/ ! s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) { struct ixgbe_mac_info *mac = &hw->mac; - u16 link_status; ! DEBUGFUNC("ixgbe_get_bus_info_generic"); ! hw->bus.type = ixgbe_bus_type_pci_express; - /* Get the negotiated link width and speed from PCI config space */ - link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); - switch (link_status & IXGBE_PCI_LINK_WIDTH) { case IXGBE_PCI_LINK_WIDTH_1: hw->bus.width = ixgbe_bus_width_pcie_x1; break; case IXGBE_PCI_LINK_WIDTH_2: --- 948,970 ---- return IXGBE_SUCCESS; } /** ! * ixgbe_set_pci_config_data_generic - Generic store PCI bus info * @hw: pointer to hardware structure + * @link_status: the link status returned by the PCI config space * ! * Stores the PCI bus info (speed, width, type) within the ixgbe_hw structure **/ ! void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status) { struct ixgbe_mac_info *mac = &hw->mac; ! if (hw->bus.type == ixgbe_bus_type_unknown) hw->bus.type = ixgbe_bus_type_pci_express; switch (link_status & IXGBE_PCI_LINK_WIDTH) { case IXGBE_PCI_LINK_WIDTH_1: hw->bus.width = ixgbe_bus_width_pcie_x1; break; case IXGBE_PCI_LINK_WIDTH_2:
*** 757,767 **** --- 995,1024 ---- hw->bus.speed = ixgbe_bus_speed_unknown; break; } mac->ops.set_lan_id(hw); + } + /** + * ixgbe_get_bus_info_generic - Generic set PCI bus info + * @hw: pointer to hardware structure + * + * Gets the PCI bus info (speed, width, type) then calls helper function to + * store this data within the ixgbe_hw structure. + **/ + s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) + { + u16 link_status; + + DEBUGFUNC("ixgbe_get_bus_info_generic"); + + /* Get the negotiated link width and speed from PCI config space */ + link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); + + ixgbe_set_pci_config_data_generic(hw, link_status); + return IXGBE_SUCCESS; } /** * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
*** 780,790 **** reg = IXGBE_READ_REG(hw, IXGBE_STATUS); bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; bus->lan_id = bus->func; /* check for a port swap */ ! reg = IXGBE_READ_REG(hw, IXGBE_FACTPS); if (reg & IXGBE_FACTPS_LFS) bus->func ^= 0x1; } /** --- 1037,1047 ---- reg = IXGBE_READ_REG(hw, IXGBE_STATUS); bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; bus->lan_id = bus->func; /* check for a port swap */ ! reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); if (reg & IXGBE_FACTPS_LFS) bus->func ^= 0x1; } /**
*** 808,824 **** * the hardware */ hw->adapter_stopped = TRUE; /* Disable the receive unit */ ! IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, 0); /* Clear interrupt mask to stop interrupts from being generated */ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); /* Clear any pending interrupts, flush previous writes */ ! (void) IXGBE_READ_REG(hw, IXGBE_EICR); /* Disable the transmit unit. Each queue must be disabled. */ for (i = 0; i < hw->mac.max_tx_queues; i++) IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), IXGBE_TXDCTL_SWFLSH); --- 1065,1081 ---- * the hardware */ hw->adapter_stopped = TRUE; /* Disable the receive unit */ ! ixgbe_disable_rx(hw); /* Clear interrupt mask to stop interrupts from being generated */ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); /* Clear any pending interrupts, flush previous writes */ ! IXGBE_READ_REG(hw, IXGBE_EICR); /* Disable the transmit unit. Each queue must be disabled. */ for (i = 0; i < hw->mac.max_tx_queues; i++) IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), IXGBE_TXDCTL_SWFLSH);
*** 833,843 **** /* flush all queues disables */ IXGBE_WRITE_FLUSH(hw); msec_delay(2); /* ! * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests */ return ixgbe_disable_pcie_master(hw); } --- 1090,1100 ---- /* flush all queues disables */ IXGBE_WRITE_FLUSH(hw); msec_delay(2); /* ! * Prevent the PCI-E bus from hanging by disabling PCI-E master * access and verify no pending requests */ return ixgbe_disable_pcie_master(hw); }
*** 906,916 **** /* * Check for EEPROM present first. * If not present leave as none */ ! eec = IXGBE_READ_REG(hw, IXGBE_EEC); if (eec & IXGBE_EEC_PRES) { eeprom->type = ixgbe_eeprom_spi; /* * SPI EEPROM is assumed here. This code would need to --- 1163,1173 ---- /* * Check for EEPROM present first. * If not present leave as none */ ! eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); if (eec & IXGBE_EEC_PRES) { eeprom->type = ixgbe_eeprom_spi; /* * SPI EEPROM is assumed here. This code would need to
*** 967,979 **** * The EEPROM page size cannot be queried from the chip. We do lazy * initialization. It is worth to do that when we write large buffer. */ if ((hw->eeprom.word_page_size == 0) && (words > IXGBE_EEPROM_PAGE_SIZE_MAX)) ! status = ixgbe_detect_eeprom_page_size_generic(hw, offset); ! if (status != IXGBE_SUCCESS) ! goto out; /* * We cannot hold synchronization semaphores for too long * to avoid other entity starvation. However it is more efficient * to read in bursts than synchronizing access for each word. --- 1224,1234 ---- * The EEPROM page size cannot be queried from the chip. We do lazy * initialization. It is worth to do that when we write large buffer. */ if ((hw->eeprom.word_page_size == 0) && (words > IXGBE_EEPROM_PAGE_SIZE_MAX)) ! ixgbe_detect_eeprom_page_size_generic(hw, offset); /* * We cannot hold synchronization semaphores for too long * to avoid other entity starvation. However it is more efficient * to read in bursts than synchronizing access for each word.
*** 1258,1277 **** hw->eeprom.ops.init_params(hw); if (words == 0) { status = IXGBE_ERR_INVALID_ARGUMENT; goto out; } if (offset >= hw->eeprom.word_size) { status = IXGBE_ERR_EEPROM; goto out; } for (i = 0; i < words; i++) { ! eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) + IXGBE_EEPROM_RW_REG_START; IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ); --- 1513,1534 ---- hw->eeprom.ops.init_params(hw); if (words == 0) { status = IXGBE_ERR_INVALID_ARGUMENT; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words"); goto out; } if (offset >= hw->eeprom.word_size) { status = IXGBE_ERR_EEPROM; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset"); goto out; } for (i = 0; i < words; i++) { ! eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | IXGBE_EEPROM_RW_REG_START; IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
*** 1364,1378 **** --- 1621,1637 ---- hw->eeprom.ops.init_params(hw); if (words == 0) { status = IXGBE_ERR_INVALID_ARGUMENT; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words"); goto out; } if (offset >= hw->eeprom.word_size) { status = IXGBE_ERR_EEPROM; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset"); goto out; } for (i = 0; i < words; i++) { eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
*** 1437,1446 **** --- 1696,1710 ---- status = IXGBE_SUCCESS; break; } usec_delay(5); } + + if (i == IXGBE_EERD_EEWR_ATTEMPTS) + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "EEPROM read/write done polling timed out"); + return status; } /** * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
*** 1460,1486 **** if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != IXGBE_SUCCESS) status = IXGBE_ERR_SWFW_SYNC; if (status == IXGBE_SUCCESS) { ! eec = IXGBE_READ_REG(hw, IXGBE_EEC); /* Request EEPROM Access */ eec |= IXGBE_EEC_REQ; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { ! eec = IXGBE_READ_REG(hw, IXGBE_EEC); if (eec & IXGBE_EEC_GNT) break; usec_delay(5); } /* Release if grant not acquired */ if (!(eec & IXGBE_EEC_GNT)) { eec &= ~IXGBE_EEC_REQ; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); DEBUGOUT("Could not acquire EEPROM grant\n"); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); status = IXGBE_ERR_EEPROM; } --- 1724,1750 ---- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != IXGBE_SUCCESS) status = IXGBE_ERR_SWFW_SYNC; if (status == IXGBE_SUCCESS) { ! eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); /* Request EEPROM Access */ eec |= IXGBE_EEC_REQ; ! 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_BY_MAC(hw)); if (eec & IXGBE_EEC_GNT) break; usec_delay(5); } /* Release if grant not acquired */ if (!(eec & IXGBE_EEC_GNT)) { eec &= ~IXGBE_EEC_REQ; ! 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); status = IXGBE_ERR_EEPROM; }
*** 1487,1497 **** /* Setup EEPROM for Read/Write */ if (status == IXGBE_SUCCESS) { /* Clear CS and SK */ eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } } return status; --- 1751,1761 ---- /* Setup EEPROM for Read/Write */ if (status == IXGBE_SUCCESS) { /* Clear CS and SK */ eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); ! IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } } return status;
*** 1517,1527 **** for (i = 0; i < timeout; i++) { /* * 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); if (!(swsm & IXGBE_SWSM_SMBI)) { status = IXGBE_SUCCESS; break; } usec_delay(50); --- 1781,1791 ---- for (i = 0; i < timeout; i++) { /* * 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_BY_MAC(hw)); if (!(swsm & IXGBE_SWSM_SMBI)) { status = IXGBE_SUCCESS; break; } usec_delay(50);
*** 1542,1570 **** /* * one last try * 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); if (!(swsm & IXGBE_SWSM_SMBI)) status = IXGBE_SUCCESS; } /* 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); /* Set the SW EEPROM semaphore bit to request access */ swsm |= IXGBE_SWSM_SWESMBI; ! IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); /* * If we set the bit successfully then we got the * semaphore. */ ! swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); if (swsm & IXGBE_SWSM_SWESMBI) break; usec_delay(50); } --- 1806,1834 ---- /* * one last try * 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_BY_MAC(hw)); if (!(swsm & IXGBE_SWSM_SMBI)) status = IXGBE_SUCCESS; } /* 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_BY_MAC(hw)); /* Set the SW EEPROM semaphore bit to request access */ swsm |= IXGBE_SWSM_SWESMBI; ! 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_BY_MAC(hw)); if (swsm & IXGBE_SWSM_SWESMBI) break; usec_delay(50); }
*** 1572,1588 **** /* * Release semaphores and return error if SW EEPROM semaphore * was not granted because we don't have access to the EEPROM */ if (i >= timeout) { ! DEBUGOUT("SWESMBI Software EEPROM semaphore " ! "not granted.\n"); ixgbe_release_eeprom_semaphore(hw); status = IXGBE_ERR_EEPROM; } } else { ! DEBUGOUT("Software semaphore SMBI between device drivers " "not granted.\n"); } return status; } --- 1836,1853 ---- /* * Release semaphores and return error if SW EEPROM semaphore * was not granted because we don't have access to the EEPROM */ if (i >= timeout) { ! ERROR_REPORT1(IXGBE_ERROR_POLLING, ! "SWESMBI Software EEPROM semaphore not granted.\n"); ixgbe_release_eeprom_semaphore(hw); status = IXGBE_ERR_EEPROM; } } else { ! ERROR_REPORT1(IXGBE_ERROR_POLLING, ! "Software semaphore SMBI between device drivers " "not granted.\n"); } return status; }
*** 1656,1674 **** { u32 eec; DEBUGFUNC("ixgbe_standby_eeprom"); ! eec = IXGBE_READ_REG(hw, IXGBE_EEC); /* Toggle CS to flush commands */ eec |= IXGBE_EEC_CS; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); eec &= ~IXGBE_EEC_CS; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } /** --- 1921,1939 ---- { u32 eec; DEBUGFUNC("ixgbe_standby_eeprom"); ! 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_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); eec &= ~IXGBE_EEC_CS; ! IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } /**
*** 1684,1694 **** u32 mask; u32 i; DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); ! eec = IXGBE_READ_REG(hw, IXGBE_EEC); /* * Mask is used to shift "count" bits of "data" out to the EEPROM * one bit at a time. Determine the starting bit based on count */ --- 1949,1959 ---- u32 mask; u32 i; DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); ! eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); /* * Mask is used to shift "count" bits of "data" out to the EEPROM * one bit at a time. Determine the starting bit based on count */
*** 1705,1715 **** if (data & mask) eec |= IXGBE_EEC_DI; else eec &= ~IXGBE_EEC_DI; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); ixgbe_raise_eeprom_clk(hw, &eec); --- 1970,1980 ---- if (data & mask) eec |= IXGBE_EEC_DI; else eec &= ~IXGBE_EEC_DI; ! IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); ixgbe_raise_eeprom_clk(hw, &eec);
*** 1722,1732 **** mask = mask >> 1; }; /* 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_FLUSH(hw); } /** * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM --- 1987,1997 ---- mask = mask >> 1; }; /* We leave the "DI" bit set to "0" when we leave this routine. */ eec &= ~IXGBE_EEC_DI; ! IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); IXGBE_WRITE_FLUSH(hw); } /** * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
*** 1745,1763 **** * 'count' bits in from the EEPROM. Bits are "shifted in" by raising * the clock input to the EEPROM (setting the SK bit), and then reading * 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_EEC_DO | IXGBE_EEC_DI); for (i = 0; i < count; i++) { data = data << 1; ixgbe_raise_eeprom_clk(hw, &eec); ! eec = IXGBE_READ_REG(hw, IXGBE_EEC); eec &= ~(IXGBE_EEC_DI); if (eec & IXGBE_EEC_DO) data |= 1; --- 2010,2028 ---- * 'count' bits in from the EEPROM. Bits are "shifted in" by raising * the clock input to the EEPROM (setting the SK bit), and then reading * 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_BY_MAC(hw)); eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); for (i = 0; i < count; i++) { data = data << 1; ixgbe_raise_eeprom_clk(hw, &eec); ! eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); eec &= ~(IXGBE_EEC_DI); if (eec & IXGBE_EEC_DO) data |= 1;
*** 1779,1789 **** /* * Raise the clock input to the EEPROM * (setting the SK bit), then delay */ *eec = *eec | IXGBE_EEC_SK; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } /** --- 2044,2054 ---- /* * Raise the clock input to the EEPROM * (setting the SK bit), then delay */ *eec = *eec | IXGBE_EEC_SK; ! IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } /**
*** 1798,1808 **** /* * Lower the clock input to the EEPROM (clearing the SK bit), then * delay */ *eec = *eec & ~IXGBE_EEC_SK; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } /** --- 2063,2073 ---- /* * Lower the clock input to the EEPROM (clearing the SK bit), then * delay */ *eec = *eec & ~IXGBE_EEC_SK; ! IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); } /**
*** 1813,1835 **** { u32 eec; DEBUGFUNC("ixgbe_release_eeprom"); ! eec = IXGBE_READ_REG(hw, IXGBE_EEC); eec |= IXGBE_EEC_CS; /* Pull CS high */ eec &= ~IXGBE_EEC_SK; /* Lower SCK */ ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); IXGBE_WRITE_FLUSH(hw); usec_delay(1); /* Stop requesting EEPROM access */ eec &= ~IXGBE_EEC_REQ; ! IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); /* Delay before attempt to obtain semaphore again to allow FW access */ msec_delay(hw->eeprom.semaphore_delay); --- 2078,2100 ---- { u32 eec; DEBUGFUNC("ixgbe_release_eeprom"); ! 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_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_BY_MAC(hw), eec); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); /* Delay before attempt to obtain semaphore again to allow FW access */ msec_delay(hw->eeprom.semaphore_delay);
*** 1836,1847 **** } /** * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum * @hw: pointer to hardware structure **/ ! u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) { u16 i; u16 j; u16 checksum = 0; u16 length = 0; --- 2101,2114 ---- } /** * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum * @hw: pointer to hardware structure + * + * Returns a negative error code on error, or the 16-bit checksum **/ ! s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) { u16 i; u16 j; u16 checksum = 0; u16 length = 0;
*** 1850,1886 **** DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic"); /* Include 0x0-0x3F in the checksum */ for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { ! if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) { DEBUGOUT("EEPROM read failed\n"); ! break; } checksum += word; } /* Include all data from pointers except for the fw pointer */ for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { ! hw->eeprom.ops.read(hw, i, &pointer); ! /* Make sure the pointer seems valid */ ! if (pointer != 0xFFFF && pointer != 0) { ! hw->eeprom.ops.read(hw, pointer, &length); ! if (length != 0xFFFF && length != 0) { ! for (j = pointer+1; j <= pointer+length; j++) { ! hw->eeprom.ops.read(hw, j, &word); ! checksum += word; } } } } checksum = (u16)IXGBE_EEPROM_SUM - checksum; ! return checksum; } /** * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum * @hw: pointer to hardware structure --- 2117,2164 ---- DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic"); /* Include 0x0-0x3F in the checksum */ for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { ! if (hw->eeprom.ops.read(hw, i, &word)) { DEBUGOUT("EEPROM read failed\n"); ! return IXGBE_ERR_EEPROM; } checksum += word; } /* Include all data from pointers except for the fw pointer */ for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { ! if (hw->eeprom.ops.read(hw, i, &pointer)) { ! DEBUGOUT("EEPROM read failed\n"); ! return IXGBE_ERR_EEPROM; ! } ! /* If the pointer seems invalid */ ! if (pointer == 0xFFFF || pointer == 0) ! continue; ! if (hw->eeprom.ops.read(hw, pointer, &length)) { ! DEBUGOUT("EEPROM read failed\n"); ! return IXGBE_ERR_EEPROM; } + + if (length == 0xFFFF || length == 0) + continue; + + for (j = pointer + 1; j <= pointer + length; j++) { + if (hw->eeprom.ops.read(hw, j, &word)) { + DEBUGOUT("EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; } + checksum += word; } } checksum = (u16)IXGBE_EEPROM_SUM - checksum; ! return (s32)checksum; } /** * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum * @hw: pointer to hardware structure
*** 1896,1930 **** u16 checksum; u16 read_checksum = 0; DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic"); ! /* ! * Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every * EEPROM read fails */ status = hw->eeprom.ops.read(hw, 0, &checksum); ! if (status == IXGBE_SUCCESS) { ! checksum = hw->eeprom.ops.calc_checksum(hw); ! hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); ! /* ! * Verify read checksum from EEPROM is the same as * calculated checksum */ if (read_checksum != checksum) status = IXGBE_ERR_EEPROM_CHECKSUM; /* If the user cares, return the calculated checksum */ if (checksum_val) *checksum_val = checksum; - } else { - DEBUGOUT("EEPROM read failed\n"); - } return status; } /** --- 2174,2214 ---- u16 checksum; u16 read_checksum = 0; DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic"); ! /* Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every * EEPROM read fails */ status = hw->eeprom.ops.read(hw, 0, &checksum); + if (status) { + DEBUGOUT("EEPROM read failed\n"); + return status; + } ! status = hw->eeprom.ops.calc_checksum(hw); ! if (status < 0) ! return status; ! checksum = (u16)(status & 0xffff); ! status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); ! if (status) { ! DEBUGOUT("EEPROM read failed\n"); ! return status; ! } ! ! /* Verify read checksum from EEPROM is the same as * calculated checksum */ if (read_checksum != checksum) status = IXGBE_ERR_EEPROM_CHECKSUM; /* If the user cares, return the calculated checksum */ if (checksum_val) *checksum_val = checksum; return status; } /**
*** 1936,1961 **** s32 status; u16 checksum; DEBUGFUNC("ixgbe_update_eeprom_checksum_generic"); ! /* ! * Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every * EEPROM read fails */ status = hw->eeprom.ops.read(hw, 0, &checksum); ! ! if (status == IXGBE_SUCCESS) { ! checksum = hw->eeprom.ops.calc_checksum(hw); ! status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, ! checksum); ! } else { DEBUGOUT("EEPROM read failed\n"); } return status; } /** * ixgbe_validate_mac_addr - Validate MAC address * @mac_addr: pointer to MAC address. --- 2220,2248 ---- s32 status; u16 checksum; DEBUGFUNC("ixgbe_update_eeprom_checksum_generic"); ! /* Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every * EEPROM read fails */ status = hw->eeprom.ops.read(hw, 0, &checksum); ! if (status) { DEBUGOUT("EEPROM read failed\n"); + return status; } + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) return status; + + checksum = (u16)(status & 0xffff); + + status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum); + + return status; } /** * ixgbe_validate_mac_addr - Validate MAC address * @mac_addr: pointer to MAC address.
*** 2003,2013 **** DEBUGFUNC("ixgbe_set_rar_generic"); /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { ! DEBUGOUT1("RAR index %d is out of range.\n", index); return IXGBE_ERR_INVALID_ARGUMENT; } /* setup VMDq pool selection before this RAR gets enabled */ hw->mac.ops.set_vmdq(hw, index, vmdq); --- 2290,2301 ---- DEBUGFUNC("ixgbe_set_rar_generic"); /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { ! ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, ! "RAR index %d is out of range.\n", index); return IXGBE_ERR_INVALID_ARGUMENT; } /* setup VMDq pool selection before this RAR gets enabled */ hw->mac.ops.set_vmdq(hw, index, vmdq);
*** 2052,2062 **** DEBUGFUNC("ixgbe_clear_rar_generic"); /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { ! DEBUGOUT1("RAR index %d is out of range.\n", index); return IXGBE_ERR_INVALID_ARGUMENT; } /* * Some parts put the VMDq setting in the extra RAH bits, --- 2340,2351 ---- DEBUGFUNC("ixgbe_clear_rar_generic"); /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { ! ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, ! "RAR index %d is out of range.\n", index); return IXGBE_ERR_INVALID_ARGUMENT; } /* * Some parts put the VMDq setting in the extra RAH bits,
*** 2136,2147 **** DEBUGOUT(" Clearing MTA\n"); for (i = 0; i < hw->mac.mcft_size; i++) IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); ! /* Should always be IXGBE_SUCCESS. */ ! return ixgbe_init_uta_tables(hw); } /** * ixgbe_add_uc_addr - Adds a secondary unicast address. * @hw: pointer to hardware structure --- 2425,2437 ---- DEBUGOUT(" Clearing MTA\n"); for (i = 0; i < hw->mac.mcft_size; i++) IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); ! ixgbe_init_uta_tables(hw); ! ! return IXGBE_SUCCESS; } /** * ixgbe_add_uc_addr - Adds a secondary unicast address. * @hw: pointer to hardware structure
*** 2349,2360 **** hw->addr_ctrl.mta_in_use = 0; /* Clear mta_shadow */ if (clear) { DEBUGOUT(" Clearing MTA\n"); ! (void) memset(&hw->mac.mta_shadow, 0, ! sizeof(hw->mac.mta_shadow)); } /* Update mta_shadow */ for (i = 0; i < mc_addr_count; i++) { DEBUGOUT(" Adding the multicast addresses:\n"); --- 2639,2649 ---- hw->addr_ctrl.mta_in_use = 0; /* Clear mta_shadow */ if (clear) { DEBUGOUT(" Clearing MTA\n"); ! memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); } /* Update mta_shadow */ for (i = 0; i < mc_addr_count; i++) { DEBUGOUT(" Adding the multicast addresses:\n");
*** 2495,2507 **** /* Flow control (both Rx and Tx) is enabled by SW override. */ mflcn_reg |= IXGBE_MFLCN_RFCE; fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; break; default: ! DEBUGOUT("Flow control param set incorrectly\n"); ret_val = IXGBE_ERR_CONFIG; goto out; } /* Set 802.3x based flow control settings. */ mflcn_reg |= IXGBE_MFLCN_DPF; IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); --- 2784,2798 ---- /* Flow control (both Rx and Tx) is enabled by SW override. */ mflcn_reg |= IXGBE_MFLCN_RFCE; fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; break; default: ! ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, ! "Flow control param set incorrectly\n"); ret_val = IXGBE_ERR_CONFIG; goto out; + break; } /* Set 802.3x based flow control settings. */ mflcn_reg |= IXGBE_MFLCN_DPF; IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
*** 2518,2531 **** } else { IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); /* * In order to prevent Tx hangs when the internal Tx * switch is enabled we must set the high water mark ! * to the maximum FCRTH value. This allows the Tx ! * switch to function even under heavy Rx workloads. */ ! fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32; } IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth); } --- 2809,2823 ---- } else { IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); /* * In order to prevent Tx hangs when the internal Tx * switch is enabled we must set the high water mark ! * to the Rx packet buffer size - 24KB. This allows ! * the Tx switch to function even under heavy Rx ! * workloads. */ ! fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576; } IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth); }
*** 2555,2566 **** * advertised settings **/ static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) { ! if ((!(adv_reg)) || (!(lp_reg))) return IXGBE_ERR_FC_NOT_NEGOTIATED; if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { /* * Now we need to check if the user selected Rx ONLY * of pause frames. In this case, we had to advertise --- 2847,2863 ---- * advertised settings **/ static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) { ! if ((!(adv_reg)) || (!(lp_reg))) { ! ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED, ! "Local or link partner's advertised flow control " ! "settings are NULL. Local: %x, link partner: %x\n", ! adv_reg, lp_reg); return IXGBE_ERR_FC_NOT_NEGOTIATED; + } if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { /* * Now we need to check if the user selected Rx ONLY * of pause frames. In this case, we had to advertise
*** 2607,2618 **** * - link is up and AN completed but timed out */ linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || ! (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) goto out; pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg, --- 2904,2917 ---- * - link is up and AN completed but timed out */ linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || ! (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { ! DEBUGOUT("Auto-Negotiation did not complete or timed out\n"); goto out; + } pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg,
*** 2640,2657 **** * On backplane, bail out if * - backplane autoneg was not completed, or if * - we are 82599 and link partner is not AN enabled */ links = IXGBE_READ_REG(hw, IXGBE_LINKS); ! if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) goto out; if (hw->mac.type == ixgbe_mac_82599EB) { links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); ! if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) goto out; } /* * Read the 10g AN autoc and LP ability registers and resolve * local flow control settings accordingly */ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); --- 2939,2960 ---- * On backplane, bail out if * - backplane autoneg was not completed, or if * - we are 82599 and link partner is not AN enabled */ links = IXGBE_READ_REG(hw, IXGBE_LINKS); ! if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { ! DEBUGOUT("Auto-Negotiation did not complete\n"); goto out; + } if (hw->mac.type == ixgbe_mac_82599EB) { links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); ! if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { ! DEBUGOUT("Link partner is not AN enabled\n"); goto out; } + } /* * Read the 10g AN autoc and LP ability registers and resolve * local flow control settings accordingly */ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
*** 2708,2726 **** * AN should have completed when the cable was plugged in. * Look for reasons to bail out. Bail out if: * - FC autoneg is disabled, or if * - link is not up. */ ! if (hw->fc.disable_fc_autoneg) goto out; hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); ! if (!link_up) goto out; switch (hw->phy.media_type) { /* Autoneg flow control on fiber adapters */ case ixgbe_media_type_fiber: if (speed == IXGBE_LINK_SPEED_1GB_FULL) ret_val = ixgbe_fc_autoneg_fiber(hw); break; --- 3011,3036 ---- * AN should have completed when the cable was plugged in. * Look for reasons to bail out. Bail out if: * - FC autoneg is disabled, or if * - link is not up. */ ! if (hw->fc.disable_fc_autoneg) { ! ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, ! "Flow control autoneg is disabled"); goto out; + } hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); ! if (!link_up) { ! ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); goto out; + } switch (hw->phy.media_type) { /* Autoneg flow control on fiber adapters */ + case ixgbe_media_type_fiber_fixed: + case ixgbe_media_type_fiber_qsfp: case ixgbe_media_type_fiber: if (speed == IXGBE_LINK_SPEED_1GB_FULL) ret_val = ixgbe_fc_autoneg_fiber(hw); break;
*** 2729,2739 **** ret_val = ixgbe_fc_autoneg_backplane(hw); break; /* Autoneg flow control on copper adapters */ case ixgbe_media_type_copper: ! if (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS) ret_val = ixgbe_fc_autoneg_copper(hw); break; default: break; --- 3039,3049 ---- ret_val = ixgbe_fc_autoneg_backplane(hw); break; /* Autoneg flow control on copper adapters */ case ixgbe_media_type_copper: ! if (ixgbe_device_supports_autoneg_fc(hw)) ret_val = ixgbe_fc_autoneg_copper(hw); break; default: break;
*** 2746,2755 **** --- 3056,3112 ---- hw->fc.fc_was_autonegged = FALSE; hw->fc.current_mode = hw->fc.requested_mode; } } + /* + * ixgbe_pcie_timeout_poll - Return number of times to poll for completion + * @hw: pointer to hardware structure + * + * System-wide timeout range is encoded in PCIe Device Control2 register. + * + * Add 10% to specified maximum and return the number of times to poll for + * completion timeout, in units of 100 microsec. Never return less than + * 800 = 80 millisec. + */ + static u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw) + { + s16 devctl2; + u32 pollcnt; + + devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2); + devctl2 &= IXGBE_PCIDEVCTRL2_TIMEO_MASK; + + switch (devctl2) { + case IXGBE_PCIDEVCTRL2_65_130ms: + pollcnt = 1300; /* 130 millisec */ + break; + case IXGBE_PCIDEVCTRL2_260_520ms: + pollcnt = 5200; /* 520 millisec */ + break; + case IXGBE_PCIDEVCTRL2_1_2s: + pollcnt = 20000; /* 2 sec */ + break; + case IXGBE_PCIDEVCTRL2_4_8s: + pollcnt = 80000; /* 8 sec */ + break; + case IXGBE_PCIDEVCTRL2_17_34s: + pollcnt = 34000; /* 34 sec */ + break; + case IXGBE_PCIDEVCTRL2_50_100us: /* 100 microsecs */ + case IXGBE_PCIDEVCTRL2_1_2ms: /* 2 millisecs */ + case IXGBE_PCIDEVCTRL2_16_32ms: /* 32 millisec */ + case IXGBE_PCIDEVCTRL2_16_32ms_def: /* 32 millisec default */ + default: + pollcnt = 800; /* 80 millisec minimum */ + break; + } + + /* add 10% to spec maximum */ + return (pollcnt * 11) / 10; + } + /** * ixgbe_disable_pcie_master - Disable PCI-express master access * @hw: pointer to hardware structure * * Disables PCI-Express master access and verifies there are no pending
*** 2758,2776 **** * is returned signifying master requests disabled. **/ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) { s32 status = IXGBE_SUCCESS; ! u32 i; DEBUGFUNC("ixgbe_disable_pcie_master"); /* Always set this bit to ensure any future transactions are blocked */ IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS); ! /* Exit if master requets are blocked */ ! if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) goto out; /* Poll for master request bit to clear */ for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { usec_delay(100); --- 3115,3135 ---- * is returned signifying master requests disabled. **/ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) { s32 status = IXGBE_SUCCESS; ! u32 i, poll; ! u16 value; DEBUGFUNC("ixgbe_disable_pcie_master"); /* Always set this bit to ensure any future transactions are blocked */ IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS); ! /* Exit if master requests are blocked */ ! if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) || ! IXGBE_REMOVED(hw->hw_addr)) goto out; /* Poll for master request bit to clear */ for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { usec_delay(100);
*** 2787,2808 **** * again to clear out any effects they may have had on our device. */ DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n"); hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; /* * Before proceeding, make sure that the PCIe block does not have * transactions pending. */ ! for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { usec_delay(100); ! if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) & ! IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) goto out; } ! DEBUGOUT("PCIe transaction pending bit also did not clear.\n"); status = IXGBE_ERR_MASTER_REQUESTS_PENDING; out: return status; } --- 3146,3174 ---- * again to clear out any effects they may have had on our device. */ 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. */ ! poll = ixgbe_pcie_timeout_poll(hw); ! for (i = 0; i < poll; i++) { usec_delay(100); ! value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS); ! if (IXGBE_REMOVED(hw->hw_addr)) goto out; + if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) + goto out; } ! ERROR_REPORT1(IXGBE_ERROR_POLLING, ! "PCIe transaction pending bit also did not clear.\n"); status = IXGBE_ERR_MASTER_REQUESTS_PENDING; out: return status; }
*** 2813,2862 **** * @mask: Mask to specify which semaphore to acquire * * Acquires the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ ! s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) { ! u32 gssr; u32 swmask = mask; u32 fwmask = mask << 5; ! s32 timeout = 200; DEBUGFUNC("ixgbe_acquire_swfw_sync"); ! while (timeout) { /* ! * SW EEPROM semaphore bit is used for access to all ! * SW_FW_SYNC/GSSR bits (not just EEPROM) */ if (ixgbe_get_eeprom_semaphore(hw)) return IXGBE_ERR_SWFW_SYNC; gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); ! if (!(gssr & (fwmask | swmask))) ! break; ! ! /* ! * Firmware currently using resource (fwmask) or other software ! * thread currently using resource (swmask) ! */ ixgbe_release_eeprom_semaphore(hw); msec_delay(5); - timeout--; } - - if (!timeout) { - DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); - return IXGBE_ERR_SWFW_SYNC; } ! gssr |= swmask; ! IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); ! ixgbe_release_eeprom_semaphore(hw); ! return IXGBE_SUCCESS; } /** * ixgbe_release_swfw_sync - Release SWFW semaphore * @hw: pointer to hardware structure --- 3179,3225 ---- * @mask: Mask to specify which semaphore to acquire * * Acquires the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ ! s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask) { ! u32 gssr = 0; u32 swmask = mask; u32 fwmask = mask << 5; ! u32 timeout = 200; ! u32 i; DEBUGFUNC("ixgbe_acquire_swfw_sync"); ! for (i = 0; i < timeout; i++) { /* ! * SW NVM semaphore bit is used for access to all ! * SW_FW_SYNC bits (not just NVM) */ if (ixgbe_get_eeprom_semaphore(hw)) return IXGBE_ERR_SWFW_SYNC; gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); ! if (!(gssr & (fwmask | swmask))) { ! gssr |= swmask; ! IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); ixgbe_release_eeprom_semaphore(hw); + return IXGBE_SUCCESS; + } else { + /* Resource is currently in use by FW or SW */ + ixgbe_release_eeprom_semaphore(hw); msec_delay(5); } } ! /* If time expired clear the bits holding the lock and retry */ ! if (gssr & (fwmask | swmask)) ! ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask)); ! msec_delay(5); ! return IXGBE_ERR_SWFW_SYNC; } /** * ixgbe_release_swfw_sync - Release SWFW semaphore * @hw: pointer to hardware structure
*** 2863,2880 **** * @mask: Mask to specify which semaphore to release * * Releases the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ ! void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) { u32 gssr; u32 swmask = mask; DEBUGFUNC("ixgbe_release_swfw_sync"); ! (void) ixgbe_get_eeprom_semaphore(hw); gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); gssr &= ~swmask; IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); --- 3226,3243 ---- * @mask: Mask to specify which semaphore to release * * Releases the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ ! void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask) { u32 gssr; u32 swmask = mask; DEBUGFUNC("ixgbe_release_swfw_sync"); ! ixgbe_get_eeprom_semaphore(hw); gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); gssr &= ~swmask; IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
*** 2917,2926 **** --- 3280,3320 ---- return IXGBE_SUCCESS; } /** + * prot_autoc_read_generic - Hides MAC differences needed for AUTOC read + * @hw: pointer to hardware structure + * @reg_val: Value we read from AUTOC + * + * The default case requires no protection so just to the register read. + */ + s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *locked, u32 *reg_val) + { + *locked = FALSE; + *reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC); + return IXGBE_SUCCESS; + } + + /** + * prot_autoc_write_generic - Hides MAC differences needed for AUTOC write + * @hw: pointer to hardware structure + * @reg_val: value to write to AUTOC + * @locked: bool to indicate whether the SW/FW lock was already taken by + * previous read. + * + * The default case requires no protection so just to the register write. + */ + s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked) + { + UNREFERENCED_1PARAMETER(locked); + + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_val); + return IXGBE_SUCCESS; + } + + /** * ixgbe_enable_sec_rx_path_generic - Enables the receive data path * @hw: pointer to hardware structure * * Enables the receive data path. **/
*** 2947,2957 **** **/ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) { DEBUGFUNC("ixgbe_enable_rx_dma_generic"); ! IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); return IXGBE_SUCCESS; } /** --- 3341,3354 ---- **/ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) { DEBUGFUNC("ixgbe_enable_rx_dma_generic"); ! if (regval & IXGBE_RXCTRL_RXEN) ! ixgbe_enable_rx(hw); ! else ! ixgbe_disable_rx(hw); return IXGBE_SUCCESS; } /**
*** 2961,2972 **** **/ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) { ixgbe_link_speed speed = 0; bool link_up = 0; ! u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); DEBUGFUNC("ixgbe_blink_led_start_generic"); /* * Link must be up to auto-blink the LEDs; --- 3358,3371 ---- **/ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) { ixgbe_link_speed speed = 0; bool link_up = 0; ! u32 autoc_reg = 0; u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + s32 ret_val = IXGBE_SUCCESS; + bool locked = FALSE; DEBUGFUNC("ixgbe_blink_led_start_generic"); /* * Link must be up to auto-blink the LEDs;
*** 2973,3021 **** * Force it if link is down. */ hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); if (!link_up) { autoc_reg |= IXGBE_AUTOC_AN_RESTART; autoc_reg |= IXGBE_AUTOC_FLU; ! IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); IXGBE_WRITE_FLUSH(hw); msec_delay(10); } led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_BLINK(index); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); IXGBE_WRITE_FLUSH(hw); ! return IXGBE_SUCCESS; } /** * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. * @hw: pointer to hardware structure * @index: led number to stop blinking **/ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) { ! u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); DEBUGFUNC("ixgbe_blink_led_stop_generic"); autoc_reg &= ~IXGBE_AUTOC_FLU; autoc_reg |= IXGBE_AUTOC_AN_RESTART; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg &= ~IXGBE_LED_BLINK(index); led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); IXGBE_WRITE_FLUSH(hw); ! return IXGBE_SUCCESS; } /** * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM * @hw: pointer to hardware structure --- 3372,3438 ---- * Force it if link is down. */ hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); if (!link_up) { + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); + if (ret_val != IXGBE_SUCCESS) + goto out; + autoc_reg |= IXGBE_AUTOC_AN_RESTART; autoc_reg |= IXGBE_AUTOC_FLU; ! ! ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked); ! if (ret_val != IXGBE_SUCCESS) ! goto out; ! IXGBE_WRITE_FLUSH(hw); msec_delay(10); } led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_BLINK(index); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); IXGBE_WRITE_FLUSH(hw); ! out: ! return ret_val; } /** * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. * @hw: pointer to hardware structure * @index: led number to stop blinking **/ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) { ! u32 autoc_reg = 0; u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + s32 ret_val = IXGBE_SUCCESS; + bool locked = FALSE; DEBUGFUNC("ixgbe_blink_led_stop_generic"); + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); + if (ret_val != IXGBE_SUCCESS) + goto out; autoc_reg &= ~IXGBE_AUTOC_FLU; autoc_reg |= IXGBE_AUTOC_AN_RESTART; + ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked); + if (ret_val != IXGBE_SUCCESS) + goto out; + led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg &= ~IXGBE_LED_BLINK(index); led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); IXGBE_WRITE_FLUSH(hw); ! out: ! return ret_val; } /** * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM * @hw: pointer to hardware structure
*** 3026,3044 **** * get and set mac_addr routines. **/ static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, u16 *san_mac_offset) { DEBUGFUNC("ixgbe_get_san_mac_addr_offset"); /* * First read the EEPROM pointer to see if the MAC addresses are * available. */ ! hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset); ! return IXGBE_SUCCESS; } /** * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM * @hw: pointer to hardware structure --- 3443,3469 ---- * get and set mac_addr routines. **/ static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, u16 *san_mac_offset) { + s32 ret_val; + DEBUGFUNC("ixgbe_get_san_mac_addr_offset"); /* * First read the EEPROM pointer to see if the MAC addresses are * available. */ ! ret_val = hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, ! san_mac_offset); ! if (ret_val) { ! ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, ! "eeprom at offset %d failed", ! IXGBE_SAN_MAC_ADDR_PTR); ! } ! return ret_val; } /** * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM * @hw: pointer to hardware structure
*** 3051,3093 **** **/ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) { u16 san_mac_data, san_mac_offset; u8 i; DEBUGFUNC("ixgbe_get_san_mac_addr_generic"); /* * First read the EEPROM pointer to see if the MAC addresses are * available. If they're not, no point in calling set_lan_id() here. */ ! (void) ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); ! ! if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { ! /* ! * No addresses available in this EEPROM. It's not an ! * error though, so just wipe the local address and return. ! */ ! for (i = 0; i < 6; i++) ! san_mac_addr[i] = 0xFF; ! goto san_mac_addr_out; - } /* make sure we know which port we need to program */ hw->mac.ops.set_lan_id(hw); /* apply the port offset to the address offset */ (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); for (i = 0; i < 3; i++) { ! hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data); san_mac_addr[i * 2] = (u8)(san_mac_data); san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); san_mac_offset++; } san_mac_addr_out: return IXGBE_SUCCESS; } /** * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM --- 3476,3524 ---- **/ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) { u16 san_mac_data, san_mac_offset; u8 i; + s32 ret_val; DEBUGFUNC("ixgbe_get_san_mac_addr_generic"); /* * First read the EEPROM pointer to see if the MAC addresses are * available. If they're not, no point in calling set_lan_id() here. */ ! ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); ! if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF) goto san_mac_addr_out; /* make sure we know which port we need to program */ hw->mac.ops.set_lan_id(hw); /* apply the port offset to the address offset */ (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); for (i = 0; i < 3; i++) { ! ret_val = hw->eeprom.ops.read(hw, san_mac_offset, ! &san_mac_data); ! if (ret_val) { ! ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, ! "eeprom read at offset %d failed", ! san_mac_offset); ! goto san_mac_addr_out; ! } san_mac_addr[i * 2] = (u8)(san_mac_data); san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); san_mac_offset++; } + return IXGBE_SUCCESS; san_mac_addr_out: + /* + * No addresses available in this EEPROM. It's not an + * error though, so just wipe the local address and return. + */ + for (i = 0; i < 6; i++) + san_mac_addr[i] = 0xFF; return IXGBE_SUCCESS; } /** * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM
*** 3096,3119 **** * * Write a SAN MAC address to the EEPROM. **/ s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) { ! s32 status = IXGBE_SUCCESS; u16 san_mac_data, san_mac_offset; u8 i; DEBUGFUNC("ixgbe_set_san_mac_addr_generic"); /* Look for SAN mac address pointer. If not defined, return */ ! (void) ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); - if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { - status = IXGBE_ERR_NO_SAN_ADDR_PTR; - goto san_mac_addr_out; - } - /* Make sure we know which port we need to write */ hw->mac.ops.set_lan_id(hw); /* Apply the port offset to the address offset */ (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); --- 3527,3547 ---- * * Write a SAN MAC address to the EEPROM. **/ s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) { ! s32 ret_val; u16 san_mac_data, san_mac_offset; u8 i; DEBUGFUNC("ixgbe_set_san_mac_addr_generic"); /* Look for SAN mac address pointer. If not defined, return */ ! ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); ! if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF) ! return IXGBE_ERR_NO_SAN_ADDR_PTR; /* Make sure we know which port we need to write */ hw->mac.ops.set_lan_id(hw); /* Apply the port offset to the address offset */ (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
*** 3123,3134 **** san_mac_data |= (u16)(san_mac_addr[i * 2]); hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); san_mac_offset++; } ! san_mac_addr_out: ! return status; } /** * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count * @hw: pointer to hardware structure --- 3551,3561 ---- san_mac_data |= (u16)(san_mac_addr[i * 2]); hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); san_mac_offset++; } ! return IXGBE_SUCCESS; } /** * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count * @hw: pointer to hardware structure
*** 3147,3165 **** --- 3574,3596 ---- pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS; max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598; break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; break; default: return msix_count; } DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); msix_count = IXGBE_READ_PCIE_WORD(hw, pcie_offset); + if (IXGBE_REMOVED(hw->hw_addr)) + msix_count = 0; msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; /* MSI-X count is zero-based in HW */ msix_count++;
*** 3213,3230 **** } } if (rar < hw->mac.rar_highwater) { /* already there so just add to the pool bits */ ! (void) ixgbe_set_vmdq(hw, rar, vmdq); } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { /* stick it into first empty RAR slot we found */ rar = first_empty_rar; ! (void) ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); } else if (rar == hw->mac.rar_highwater) { /* add it to the top of the list and inc the highwater mark */ ! (void) ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); hw->mac.rar_highwater++; } else if (rar >= hw->mac.num_rar_entries) { return IXGBE_ERR_INVALID_MAC_ADDR; } --- 3644,3661 ---- } } if (rar < hw->mac.rar_highwater) { /* already there so just add to the pool bits */ ! ixgbe_set_vmdq(hw, rar, vmdq); } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { /* stick it into first empty RAR slot we found */ rar = first_empty_rar; ! ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); } else if (rar == hw->mac.rar_highwater) { /* add it to the top of the list and inc the highwater mark */ ! ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); hw->mac.rar_highwater++; } else if (rar >= hw->mac.num_rar_entries) { return IXGBE_ERR_INVALID_MAC_ADDR; }
*** 3231,3241 **** /* * If we found rar[0], make sure the default pool bit (we use pool 0) * remains cleared to be sure default pool packets will get delivered */ if (rar == 0) ! (void) ixgbe_clear_vmdq(hw, rar, 0); return rar; } /** --- 3662,3672 ---- /* * If we found rar[0], make sure the default pool bit (we use pool 0) * remains cleared to be sure default pool packets will get delivered */ if (rar == 0) ! ixgbe_clear_vmdq(hw, rar, 0); return rar; } /**
*** 3251,3267 **** DEBUGFUNC("ixgbe_clear_vmdq_generic"); /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { ! DEBUGOUT1("RAR index %d is out of range.\n", rar); return IXGBE_ERR_INVALID_ARGUMENT; } mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); if (!mpsar_lo && !mpsar_hi) goto done; if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { if (mpsar_lo) { --- 3682,3702 ---- DEBUGFUNC("ixgbe_clear_vmdq_generic"); /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { ! ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, ! "RAR index %d is out of range.\n", rar); return IXGBE_ERR_INVALID_ARGUMENT; } mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + if (IXGBE_REMOVED(hw->hw_addr)) + goto done; + if (!mpsar_lo && !mpsar_hi) goto done; if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { if (mpsar_lo) {
*** 3300,3310 **** DEBUGFUNC("ixgbe_set_vmdq_generic"); /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { ! DEBUGOUT1("RAR index %d is out of range.\n", rar); return IXGBE_ERR_INVALID_ARGUMENT; } if (vmdq < 32) { mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); --- 3735,3746 ---- DEBUGFUNC("ixgbe_set_vmdq_generic"); /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { ! ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, ! "RAR index %d is out of range.\n", rar); return IXGBE_ERR_INVALID_ARGUMENT; } if (vmdq < 32) { mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
*** 3399,3409 **** */ if (regindex >= IXGBE_VLVF_ENTRIES) { if (first_empty_slot) regindex = first_empty_slot; else { ! DEBUGOUT("No space in VLVF.\n"); regindex = IXGBE_ERR_NO_SPACE; } } return regindex; --- 3835,3846 ---- */ if (regindex >= IXGBE_VLVF_ENTRIES) { if (first_empty_slot) regindex = first_empty_slot; else { ! ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, ! "No space in VLVF.\n"); regindex = IXGBE_ERR_NO_SPACE; } } return regindex;
*** 3634,3644 **** DEBUGOUT2("LINKS changed from %08X to %08X\n", links_orig, links_reg); } if (link_up_wait_to_complete) { ! for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { if (links_reg & IXGBE_LINKS_UP) { *link_up = TRUE; break; } else { *link_up = FALSE; --- 4071,4081 ---- DEBUGOUT2("LINKS changed from %08X to %08X\n", links_orig, links_reg); } if (link_up_wait_to_complete) { ! for (i = 0; i < hw->mac.max_link_up_time; i++) { if (links_reg & IXGBE_LINKS_UP) { *link_up = TRUE; break; } else { *link_up = FALSE;
*** 3651,3671 **** *link_up = TRUE; else *link_up = FALSE; } ! if ((links_reg & IXGBE_LINKS_SPEED_82599) == ! IXGBE_LINKS_SPEED_10G_82599) *speed = IXGBE_LINK_SPEED_10GB_FULL; ! else if ((links_reg & IXGBE_LINKS_SPEED_82599) == ! IXGBE_LINKS_SPEED_1G_82599) *speed = IXGBE_LINK_SPEED_1GB_FULL; ! else if ((links_reg & IXGBE_LINKS_SPEED_82599) == ! IXGBE_LINKS_SPEED_100_82599) *speed = IXGBE_LINK_SPEED_100_FULL; ! else *speed = IXGBE_LINK_SPEED_UNKNOWN; return IXGBE_SUCCESS; } /** --- 4088,4118 ---- *link_up = TRUE; else *link_up = FALSE; } ! switch (links_reg & IXGBE_LINKS_SPEED_82599) { ! case IXGBE_LINKS_SPEED_10G_82599: *speed = IXGBE_LINK_SPEED_10GB_FULL; ! if (hw->mac.type >= ixgbe_mac_X550) { ! if (links_reg & IXGBE_LINKS_SPEED_NON_STD) ! *speed = IXGBE_LINK_SPEED_2_5GB_FULL; ! } ! break; ! case IXGBE_LINKS_SPEED_1G_82599: *speed = IXGBE_LINK_SPEED_1GB_FULL; ! break; ! case IXGBE_LINKS_SPEED_100_82599: *speed = IXGBE_LINK_SPEED_100_FULL; ! if (hw->mac.type >= ixgbe_mac_X550) { ! if (links_reg & IXGBE_LINKS_SPEED_NON_STD) ! *speed = IXGBE_LINK_SPEED_5GB_FULL; ! } ! break; ! default: *speed = IXGBE_LINK_SPEED_UNKNOWN; + } return IXGBE_SUCCESS; } /**
*** 3689,3720 **** /* clear output first */ *wwnn_prefix = 0xFFFF; *wwpn_prefix = 0xFFFF; /* check if alternative SAN MAC is supported */ ! hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, ! &alt_san_mac_blk_offset); if ((alt_san_mac_blk_offset == 0) || (alt_san_mac_blk_offset == 0xFFFF)) goto wwn_prefix_out; /* check capability in alternative san mac address block */ offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; ! hw->eeprom.ops.read(hw, offset, &caps); if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) goto wwn_prefix_out; /* get the corresponding prefix for WWNN/WWPN */ offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; ! hw->eeprom.ops.read(hw, offset, wwnn_prefix); offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; ! hw->eeprom.ops.read(hw, offset, wwpn_prefix); wwn_prefix_out: return IXGBE_SUCCESS; } /** * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM * @hw: pointer to hardware structure --- 4136,4178 ---- /* clear output first */ *wwnn_prefix = 0xFFFF; *wwpn_prefix = 0xFFFF; /* check if alternative SAN MAC is supported */ ! offset = IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR; ! if (hw->eeprom.ops.read(hw, offset, &alt_san_mac_blk_offset)) ! goto wwn_prefix_err; if ((alt_san_mac_blk_offset == 0) || (alt_san_mac_blk_offset == 0xFFFF)) goto wwn_prefix_out; /* check capability in alternative san mac address block */ offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; ! if (hw->eeprom.ops.read(hw, offset, &caps)) ! goto wwn_prefix_err; if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) goto wwn_prefix_out; /* get the corresponding prefix for WWNN/WWPN */ offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; ! if (hw->eeprom.ops.read(hw, offset, wwnn_prefix)) { ! ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, ! "eeprom read at offset %d failed", offset); ! } offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; ! if (hw->eeprom.ops.read(hw, offset, wwpn_prefix)) ! goto wwn_prefix_err; wwn_prefix_out: return IXGBE_SUCCESS; + + wwn_prefix_err: + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", offset); + return IXGBE_SUCCESS; } /** * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM * @hw: pointer to hardware structure
*** 3808,3818 **** /** * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing * @hw: pointer to hardware structure * @enable: enable or disable switch for VLAN anti-spoofing ! * @pf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing * **/ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) { int vf_target_reg = vf >> 3; --- 4266,4276 ---- /** * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing * @hw: pointer to hardware structure * @enable: enable or disable switch for VLAN anti-spoofing ! * @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing * **/ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) { int vf_target_reg = vf >> 3;
*** 3880,3890 **** * @buffer: pointer to EEPROM * @length: size of EEPROM to calculate a checksum for * Calculates the checksum for some buffer on a specified length. The * checksum calculated is returned. **/ ! static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) { u32 i; u8 sum = 0; DEBUGFUNC("ixgbe_calculate_checksum"); --- 4338,4348 ---- * @buffer: pointer to EEPROM * @length: size of EEPROM to calculate a checksum for * Calculates the checksum for some buffer on a specified length. The * checksum calculated is returned. **/ ! u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) { u32 i; u8 sum = 0; DEBUGFUNC("ixgbe_calculate_checksum");
*** 3902,4001 **** * ixgbe_host_interface_command - Issue command to manageability block * @hw: pointer to the HW structure * @buffer: contains the command to write and where the return status will * be placed * @length: length of buffer, must be multiple of 4 bytes * * Communicates with the manageability block. On success return IXGBE_SUCCESS * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. **/ ! static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ! u32 length) { ! u32 hicr, i, bi; u32 hdr_size = sizeof(struct ixgbe_hic_hdr); ! u8 buf_len, dword_len; - s32 ret_val = IXGBE_SUCCESS; - DEBUGFUNC("ixgbe_host_interface_command"); ! if (length == 0 || length & 0x3 || ! length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { ! DEBUGOUT("Buffer length failure.\n"); ! ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; ! goto out; } /* Check that the host interface is enabled. */ hicr = IXGBE_READ_REG(hw, IXGBE_HICR); if ((hicr & IXGBE_HICR_EN) == 0) { DEBUGOUT("IXGBE_HOST_EN bit disabled.\n"); ! ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; ! goto out; } ! /* Calculate length in DWORDs */ dword_len = length >> 2; ! /* ! * The device driver writes the relevant command block * into the ram area. */ for (i = 0; i < dword_len; i++) IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, i, IXGBE_CPU_TO_LE32(buffer[i])); /* Setting this bit tells the ARC that a new command is pending. */ IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); ! for (i = 0; i < IXGBE_HI_COMMAND_TIMEOUT; i++) { hicr = IXGBE_READ_REG(hw, IXGBE_HICR); if (!(hicr & IXGBE_HICR_C)) break; msec_delay(1); } ! /* Check command successful completion. */ ! if (i == IXGBE_HI_COMMAND_TIMEOUT || ! (!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) { ! DEBUGOUT("Command has failed with no status valid.\n"); ! ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; ! goto out; } /* Calculate length in DWORDs */ dword_len = hdr_size >> 2; /* first pull in the header so we know the buffer length */ for (bi = 0; bi < dword_len; bi++) { buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); ! buffer[bi] = IXGBE_LE32_TO_CPUS(buffer[bi]); } /* If there is any thing in data position pull it in */ buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; if (buf_len == 0) ! goto out; ! if (length < (buf_len + hdr_size)) { DEBUGOUT("Buffer not large enough for reply message.\n"); ! ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; ! goto out; } /* Calculate length in DWORDs, add 3 for odd lengths */ dword_len = (buf_len + 3) >> 2; ! /* Pull in the rest of the buffer (bi is where we left off)*/ for (; bi <= dword_len; bi++) { buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); ! buffer[bi] = IXGBE_LE32_TO_CPUS(buffer[bi]); } ! out: ! return ret_val; } /** * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware * @hw: pointer to the HW structure --- 4360,4470 ---- * ixgbe_host_interface_command - Issue command to manageability block * @hw: pointer to the HW structure * @buffer: contains the command to write and where the return status will * be placed * @length: length of buffer, must be multiple of 4 bytes + * @timeout: time in ms to wait for command completion + * @return_data: read and return data from the buffer (TRUE) or not (FALSE) + * Needed because FW structures are big endian and decoding of + * these fields can be 8 bit or 16 bit based on command. Decoding + * is not easily understood without making a table of commands. + * So we will leave this up to the caller to read back the data + * in these cases. * * Communicates with the manageability block. On success return IXGBE_SUCCESS * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. **/ ! s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ! u32 length, u32 timeout, bool return_data) { ! u32 hicr, i, bi, fwsts; u32 hdr_size = sizeof(struct ixgbe_hic_hdr); ! u16 buf_len; ! u16 dword_len; DEBUGFUNC("ixgbe_host_interface_command"); ! if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { ! DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); ! return IXGBE_ERR_HOST_INTERFACE_COMMAND; } + /* Set bit 9 of FWSTS clearing FW reset indication */ + fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS); + IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI); /* Check that the host interface is enabled. */ hicr = IXGBE_READ_REG(hw, IXGBE_HICR); if ((hicr & IXGBE_HICR_EN) == 0) { DEBUGOUT("IXGBE_HOST_EN bit disabled.\n"); ! return IXGBE_ERR_HOST_INTERFACE_COMMAND; } ! /* Calculate length in DWORDs. We must be DWORD aligned */ ! if ((length % (sizeof(u32))) != 0) { ! DEBUGOUT("Buffer length failure, not aligned to dword"); ! return IXGBE_ERR_INVALID_ARGUMENT; ! } ! dword_len = length >> 2; ! /* The device driver writes the relevant command block * into the ram area. */ for (i = 0; i < dword_len; i++) IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, i, IXGBE_CPU_TO_LE32(buffer[i])); /* Setting this bit tells the ARC that a new command is pending. */ IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); ! for (i = 0; i < timeout; i++) { hicr = IXGBE_READ_REG(hw, IXGBE_HICR); if (!(hicr & IXGBE_HICR_C)) break; msec_delay(1); } ! /* Check command completion */ ! if ((timeout != 0 && i == timeout) || ! !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { ! ERROR_REPORT1(IXGBE_ERROR_CAUTION, ! "Command has failed with no status valid.\n"); ! return IXGBE_ERR_HOST_INTERFACE_COMMAND; } + if (!return_data) + return 0; + /* Calculate length in DWORDs */ dword_len = hdr_size >> 2; /* first pull in the header so we know the buffer length */ for (bi = 0; bi < dword_len; bi++) { buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); ! IXGBE_LE32_TO_CPUS(&buffer[bi]); } /* If there is any thing in data position pull it in */ buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; if (buf_len == 0) ! return 0; ! if (length < buf_len + hdr_size) { DEBUGOUT("Buffer not large enough for reply message.\n"); ! return IXGBE_ERR_HOST_INTERFACE_COMMAND; } /* Calculate length in DWORDs, add 3 for odd lengths */ dword_len = (buf_len + 3) >> 2; ! /* Pull in the rest of the buffer (bi is where we left off) */ for (; bi <= dword_len; bi++) { buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); ! IXGBE_LE32_TO_CPUS(&buffer[bi]); } ! return 0; } /** * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware * @hw: pointer to the HW structure
*** 4037,4049 **** (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); fw_cmd.pad = 0; fw_cmd.pad2 = 0; for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { - /* LINTED */ ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, ! sizeof(fw_cmd)); if (ret_val != IXGBE_SUCCESS) continue; if (fw_cmd.hdr.cmd_or_resp.ret_status == FW_CEM_RESP_STATUS_SUCCESS) --- 4506,4519 ---- (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); fw_cmd.pad = 0; fw_cmd.pad2 = 0; for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, ! sizeof(fw_cmd), ! IXGBE_HI_COMMAND_TIMEOUT, ! TRUE); if (ret_val != IXGBE_SUCCESS) continue; if (fw_cmd.hdr.cmd_or_resp.ret_status == FW_CEM_RESP_STATUS_SUCCESS)
*** 4091,4101 **** pbsize -= rxpktsize * (num_pb / 2); rxpktsize <<= IXGBE_RXPBSIZE_SHIFT; for (; i < (num_pb / 2); i++) IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); /* Fall through to configure remaining packet buffers */ - /* FALLTHRU */ case PBA_STRATEGY_EQUAL: rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT; for (; i < num_pb; i++) IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); break; --- 4561,4570 ----
*** 4127,4137 **** * when a reset occurs. This function prevents this by flushing the PCIe * buffers on the system. **/ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw) { ! u32 gcr_ext, hlreg0; /* * If double reset is not requested then all transactions should * already be clear and as such there is no work to do */ --- 4596,4607 ---- * when a reset occurs. This function prevents this by flushing the PCIe * buffers on the system. **/ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw) { ! u32 gcr_ext, hlreg0, i, poll; ! u16 value; /* * If double reset is not requested then all transactions should * already be clear and as such there is no work to do */
*** 4144,4153 **** --- 4614,4642 ---- * has already been cleared. */ hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK); + /* Wait for a last completion before clearing buffers */ + IXGBE_WRITE_FLUSH(hw); + msec_delay(3); + + /* + * Before proceeding, make sure that the PCIe block does not have + * transactions pending. + */ + poll = ixgbe_pcie_timeout_poll(hw); + for (i = 0; i < poll; i++) { + usec_delay(100); + value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS); + if (IXGBE_REMOVED(hw->hw_addr)) + goto out; + if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) + goto out; + } + + out: /* initiate cleaning flow for buffers in the PCIe transaction layer */ gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR);
*** 4158,4162 **** --- 4647,4982 ---- /* restore previous register values */ IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); } + + /** + * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg + * @hw: pointer to hardware structure + * @map: pointer to u8 arr for returning map + * + * Read the rtrup2tc HW register and resolve its content into map + **/ + void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map) + { + u32 reg, i; + + reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC); + for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++) + map[i] = IXGBE_RTRUP2TC_UP_MASK & + (reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT)); + return; + } + + void ixgbe_disable_rx_generic(struct ixgbe_hw *hw) + { + u32 pfdtxgswc; + u32 rxctrl; + + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + if (hw->mac.type != ixgbe_mac_82598EB) { + pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); + if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) { + pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN; + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); + hw->mac.set_lben = TRUE; + } else { + hw->mac.set_lben = FALSE; + } + } + rxctrl &= ~IXGBE_RXCTRL_RXEN; + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); + } + } + + void ixgbe_enable_rx_generic(struct ixgbe_hw *hw) + { + u32 pfdtxgswc; + u32 rxctrl; + + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, (rxctrl | IXGBE_RXCTRL_RXEN)); + + if (hw->mac.type != ixgbe_mac_82598EB) { + if (hw->mac.set_lben) { + pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); + pfdtxgswc |= IXGBE_PFDTXGSWC_VT_LBEN; + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); + hw->mac.set_lben = FALSE; + } + } + } + + /** + * ixgbe_mng_present - returns TRUE when management capability is present + * @hw: pointer to hardware structure + */ + bool ixgbe_mng_present(struct ixgbe_hw *hw) + { + u32 fwsm; + + if (hw->mac.type < ixgbe_mac_82599EB) + return FALSE; + + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); + fwsm &= IXGBE_FWSM_MODE_MASK; + return fwsm == IXGBE_FWSM_FW_MODE_PT; + } + + /** + * ixgbe_mng_enabled - Is the manageability engine enabled? + * @hw: pointer to hardware structure + * + * Returns TRUE if the manageability engine is enabled. + **/ + bool ixgbe_mng_enabled(struct ixgbe_hw *hw) + { + u32 fwsm, manc, factps; + + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); + if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT) + return FALSE; + + manc = IXGBE_READ_REG(hw, IXGBE_MANC); + if (!(manc & IXGBE_MANC_RCV_TCO_EN)) + return FALSE; + + if (hw->mac.type <= ixgbe_mac_X540) { + 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_fixed: + 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_fixed: + 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; + }