summaryrefslogtreecommitdiff
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c60
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c104
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c112
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h4
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c77
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c109
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c14
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c22
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c7
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h12
-rw-r--r--drivers/net/ixgbe/ixgbe_x540.c192
12 files changed, 485 insertions, 230 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 845c679c8b87..7a64f50435cf 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -37,6 +37,7 @@
#define IXGBE_82598_RAR_ENTRIES 16
#define IXGBE_82598_MC_TBL_SIZE 128
#define IXGBE_82598_VFT_TBL_SIZE 128
+#define IXGBE_82598_RX_PB_SIZE 512
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
@@ -197,14 +198,35 @@ out:
* @hw: pointer to hardware structure
*
* Starts the hardware using the generic start_hw function.
- * Then set pcie completion timeout
+ * Disables relaxed ordering Then set pcie completion timeout
+ *
**/
static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
{
+ u32 regval;
+ u32 i;
s32 ret_val = 0;
ret_val = ixgbe_start_hw_generic(hw);
+ /* Disable relaxed ordering */
+ for (i = 0; ((i < hw->mac.max_tx_queues) &&
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
+ regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
+ }
+
+ for (i = 0; ((i < hw->mac.max_rx_queues) &&
+ (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+ regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+ }
+
+ hw->mac.rx_pb_size = IXGBE_82598_RX_PB_SIZE;
+
/* set the completion timeout for interface */
if (ret_val == 0)
ixgbe_set_pcie_completion_timeout(hw);
@@ -1064,7 +1086,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
break;
- msleep(10);
+ usleep_range(10000, 20000);
}
if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
@@ -1188,6 +1210,38 @@ out:
return physical_layer;
}
+/**
+ * ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
+ * port devices.
+ * @hw: pointer to the HW structure
+ *
+ * Calls common function and corrects issue with some single port devices
+ * that enable LAN1 but not LAN0.
+ **/
+static void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
+{
+ struct ixgbe_bus_info *bus = &hw->bus;
+ u16 pci_gen = 0;
+ u16 pci_ctrl2 = 0;
+
+ ixgbe_set_lan_id_multi_port_pcie(hw);
+
+ /* check if LAN0 is disabled */
+ hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
+ if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
+
+ hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
+
+ /* if LAN0 is completely disabled force function to 0 */
+ if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
+ !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
+ !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
+
+ bus->func = 0;
+ }
+ }
+}
+
static struct ixgbe_mac_operations mac_ops_82598 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82598,
@@ -1199,7 +1253,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
- .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
+ .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie_82598,
.read_analog_reg8 = &ixgbe_read_analog_reg8_82598,
.write_analog_reg8 = &ixgbe_write_analog_reg8_82598,
.setup_link = &ixgbe_setup_mac_link_82598,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 00aeba385a2f..b341ed8ef84f 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -38,6 +38,7 @@
#define IXGBE_82599_RAR_ENTRIES 128
#define IXGBE_82599_MC_TBL_SIZE 128
#define IXGBE_82599_VFT_TBL_SIZE 128
+#define IXGBE_82599_RX_PB_SIZE 512
static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
@@ -61,6 +62,7 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
+static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
@@ -86,7 +88,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
if ((mac->ops.get_media_type(hw) ==
ixgbe_media_type_backplane) &&
(hw->phy.smart_speed == ixgbe_smart_speed_auto ||
- hw->phy.smart_speed == ixgbe_smart_speed_on))
+ hw->phy.smart_speed == ixgbe_smart_speed_on) &&
+ !ixgbe_verify_lesm_fw_enabled_82599(hw))
mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed;
else
mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
@@ -128,8 +131,12 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
/* Release the semaphore */
ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
- /* Delay obtaining semaphore again to allow FW access */
- msleep(hw->eeprom.semaphore_delay);
+ /*
+ * Delay obtaining semaphore again to allow FW access,
+ * semaphore_delay is in ms usleep_range needs us.
+ */
+ usleep_range(hw->eeprom.semaphore_delay * 1000,
+ hw->eeprom.semaphore_delay * 2000);
/* Now restart DSP by setting Restart_AN and clearing LMS */
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
@@ -138,7 +145,7 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
/* Wait for AN to leave state 0 */
for (i = 0; i < 10; i++) {
- msleep(4);
+ usleep_range(4000, 8000);
reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
break;
@@ -353,6 +360,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_SFP:
case IXGBE_DEV_ID_82599_SFP_FCOE:
case IXGBE_DEV_ID_82599_SFP_EM:
+ case IXGBE_DEV_ID_82599_SFP_SF2:
media_type = ixgbe_media_type_fiber;
break;
case IXGBE_DEV_ID_82599_CX4:
@@ -1176,7 +1184,7 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc)
if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
IXGBE_FDIRCTRL_INIT_DONE)
break;
- msleep(1);
+ usleep_range(1000, 2000);
}
if (i >= IXGBE_FDIR_INIT_DONE_POLL)
hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
@@ -1271,7 +1279,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
IXGBE_FDIRCTRL_INIT_DONE)
break;
- msleep(1);
+ usleep_range(1000, 2000);
}
if (i >= IXGBE_FDIR_INIT_DONE_POLL)
hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n");
@@ -1740,30 +1748,29 @@ static s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
* ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure
*
- * Starts the hardware using the generic start_hw function.
- * Then performs device-specific:
- * Clears the rate limiter registers.
+ * Starts the hardware using the generic start_hw function
+ * and the generation start_hw function.
+ * Then performs revision-specific operations, if any.
**/
static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
{
- u32 q_num;
- s32 ret_val;
+ s32 ret_val = 0;
ret_val = ixgbe_start_hw_generic(hw);
+ if (ret_val != 0)
+ goto out;
- /* Clear the rate limiters */
- for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
- IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
- IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
- }
- IXGBE_WRITE_FLUSH(hw);
+ ret_val = ixgbe_start_hw_gen2(hw);
+ if (ret_val != 0)
+ goto out;
/* We need to run link autotry after the driver loads */
hw->mac.autotry_restart = true;
+ hw->mac.rx_pb_size = IXGBE_82599_RX_PB_SIZE;
if (ret_val == 0)
ret_val = ixgbe_verify_fw_version_82599(hw);
-
+out:
return ret_val;
}
@@ -1775,7 +1782,7 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
* If PHY already detected, maintains current PHY type in hw struct,
* otherwise executes the PHY detection routine.
**/
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
@@ -1968,21 +1975,6 @@ static s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
}
/**
- * ixgbe_get_device_caps_82599 - Get additional device capabilities
- * @hw: pointer to hardware structure
- * @device_caps: the EEPROM word with the extra device capabilities
- *
- * This function will read the EEPROM location for the device capabilities,
- * and return the word through device_caps.
- **/
-static s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
-{
- hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
-
- return 0;
-}
-
-/**
* ixgbe_verify_fw_version_82599 - verify fw version for 82599
* @hw: pointer to hardware structure
*
@@ -2030,6 +2022,48 @@ fw_version_out:
return status;
}
+/**
+ * ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state.
+ * @hw: pointer to hardware structure
+ *
+ * Returns true if the LESM FW module is present and enabled. Otherwise
+ * returns false. Smart Speed must be disabled if LESM FW module is enabled.
+ **/
+static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
+{
+ bool lesm_enabled = false;
+ u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
+ s32 status;
+
+ /* get the offset to the Firmware Module block */
+ status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
+
+ if ((status != 0) ||
+ (fw_offset == 0) || (fw_offset == 0xFFFF))
+ goto out;
+
+ /* get the offset to the LESM Parameters block */
+ status = hw->eeprom.ops.read(hw, (fw_offset +
+ IXGBE_FW_LESM_PARAMETERS_PTR),
+ &fw_lesm_param_offset);
+
+ if ((status != 0) ||
+ (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))
+ goto out;
+
+ /* get the lesm state word */
+ status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset +
+ IXGBE_FW_LESM_STATE_1),
+ &fw_lesm_state);
+
+ if ((status == 0) &&
+ (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED))
+ lesm_enabled = true;
+
+out:
+ return lesm_enabled;
+}
+
static struct ixgbe_mac_operations mac_ops_82599 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82599,
@@ -2040,7 +2074,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.enable_rx_dma = &ixgbe_enable_rx_dma_82599,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
- .get_device_caps = &ixgbe_get_device_caps_82599,
+ .get_device_caps = &ixgbe_get_device_caps_generic,
.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index bcd952916eb2..cb2e8e18dd39 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -54,6 +54,7 @@ static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
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);
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
+static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
/**
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
@@ -96,6 +97,45 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_start_hw_gen2 - Init sequence for common device family
+ * @hw: pointer to hw structure
+ *
+ * Performs the init sequence common to the second generation
+ * of 10 GbE devices.
+ * Devices in the second generation:
+ * 82599
+ * X540
+ **/
+s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
+{
+ u32 i;
+ u32 regval;
+
+ /* Clear the rate limiters */
+ for (i = 0; i < hw->mac.max_tx_queues; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+ }
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Disable relaxed ordering */
+ for (i = 0; i < hw->mac.max_tx_queues; i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
+ regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
+ }
+
+ for (i = 0; i < hw->mac.max_rx_queues; i++) {
+ regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+ regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+ }
+
+ return 0;
+}
+
+/**
* ixgbe_init_hw_generic - Generic hardware initialization
* @hw: pointer to hardware structure
*
@@ -464,7 +504,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
reg_val &= ~(IXGBE_RXCTRL_RXEN);
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val);
IXGBE_WRITE_FLUSH(hw);
- msleep(2);
+ usleep_range(2000, 4000);
/* Clear interrupt mask to stop from interrupts being generated */
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
@@ -739,6 +779,47 @@ out:
}
/**
+ * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ u32 eewr;
+ s32 status;
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
+ eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
+ (data << IXGBE_EEPROM_RW_REG_DATA) | IXGBE_EEPROM_RW_REG_START;
+
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
+
+out:
+ return status;
+}
+
+/**
* ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
* @hw: pointer to hardware structure
* @ee_reg: EEPROM flag for polling
@@ -746,7 +827,7 @@ out:
* Polls the status bit (bit 1) of the EERD or EEWR to determine when the
* read or write is done respectively.
**/
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
+static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
{
u32 i;
u32 reg;
@@ -1112,8 +1193,12 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- /* Delay before attempt to obtain semaphore again to allow FW access */
- msleep(hw->eeprom.semaphore_delay);
+ /*
+ * Delay before attempt to obtain semaphore again to allow FW
+ * access. semaphore_delay is in ms we need us for usleep_range
+ */
+ usleep_range(hw->eeprom.semaphore_delay * 1000,
+ hw->eeprom.semaphore_delay * 2000);
}
/**
@@ -2189,7 +2274,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
* thread currently using resource (swmask)
*/
ixgbe_release_eeprom_semaphore(hw);
- msleep(5);
+ usleep_range(5000, 10000);
timeout--;
}
@@ -2263,7 +2348,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
autoc_reg |= IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
- msleep(10);
+ usleep_range(10000, 20000);
}
led_reg &= ~IXGBE_LED_MODE_MASK(index);
@@ -2883,3 +2968,18 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
pfvfspoof &= ~(1 << vf_target_shift);
IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
}
+
+/**
+ * ixgbe_get_device_caps_generic - Get additional device capabilities
+ * @hw: pointer to hardware structure
+ * @device_caps: the EEPROM word with the extra device capabilities
+ *
+ * This function will read the EEPROM location for the device capabilities,
+ * and return the word through device_caps.
+ **/
+s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
+{
+ hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+ return 0;
+}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 508f635fc2ca..e850adbb32a1 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -35,6 +35,7 @@ u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw);
s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
u32 pba_num_size);
@@ -49,13 +50,13 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
+s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data);
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
u16 *checksum_val);
s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
u32 enable_addr);
@@ -89,6 +90,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf);
void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
+s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps);
#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 025af8c53ddb..d50cf78c234d 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -39,36 +39,52 @@
*/
static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, u8 rx_pba)
{
- s32 ret_val = 0;
- u32 value = IXGBE_RXPBSIZE_64KB;
+ int num_tcs = IXGBE_MAX_PACKET_BUFFERS;
+ u32 rx_pb_size = hw->mac.rx_pb_size << IXGBE_RXPBSIZE_SHIFT;
+ u32 rxpktsize;
+ u32 txpktsize;
+ u32 txpbthresh;
u8 i = 0;
- /* Setup Rx packet buffer sizes */
- switch (rx_pba) {
- case pba_80_48:
- /* Setup the first four at 80KB */
- value = IXGBE_RXPBSIZE_80KB;
- for (; i < 4; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
- /* Setup the last four at 48KB...don't re-init i */
- value = IXGBE_RXPBSIZE_48KB;
- /* Fall Through */
- case pba_equal:
- default:
- for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
-
- /* Setup Tx packet buffer sizes */
- for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
- IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
- IXGBE_TXPBSIZE_20KB);
- IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i),
- IXGBE_TXPBTHRESH_DCB);
- }
- break;
+ /*
+ * This really means configure the first half of the TCs
+ * (Traffic Classes) to use 5/8 of the Rx packet buffer
+ * space. To determine the size of the buffer for each TC,
+ * we are multiplying the average size by 5/4 and applying
+ * it to half of the traffic classes.
+ */
+ if (rx_pba == pba_80_48) {
+ rxpktsize = (rx_pb_size * 5) / (num_tcs * 4);
+ rx_pb_size -= rxpktsize * (num_tcs / 2);
+ for (; i < (num_tcs / 2); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
+ }
+
+ /* Divide the remaining Rx packet buffer evenly among the TCs */
+ rxpktsize = rx_pb_size / (num_tcs - i);
+ for (; i < num_tcs; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
+
+ /*
+ * Setup Tx packet buffer and threshold equally for all TCs
+ * TXPBTHRESH register is set in K so divide by 1024 and subtract
+ * 10 since the largest packet we support is just over 9K.
+ */
+ txpktsize = IXGBE_TXPBSIZE_MAX / num_tcs;
+ txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX;
+ for (i = 0; i < num_tcs; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh);
+ }
+
+ /* Clear unused TCs, if any, to zero buffer size*/
+ for (; i < MAX_TRAFFIC_CLASS; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0);
}
- return ret_val;
+ return 0;
}
/**
@@ -285,12 +301,17 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en)
IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
/*
* Enable Receive PFC
- * We will always honor XOFF frames we receive when
- * we are in PFC mode.
+ * 82599 will always honor XOFF frames we receive when
+ * we are in PFC mode however X540 only honors enabled
+ * traffic classes.
*/
reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
reg &= ~IXGBE_MFLCN_RFCE;
reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF;
+
+ if (hw->mac.type == ixgbe_mac_X540)
+ reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
+
IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
} else {
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h
index 148fd8b477a9..2de71a503153 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.h
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h
@@ -92,8 +92,10 @@
#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */
#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */
#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */
+#define IXGBE_TXPBSIZE_MAX 0x00028000 /* 160KB Packet Buffer*/
#define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */
+#define IXGBE_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */
/* SECTXMINIFG DCB */
#define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer IFG */
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index 327c8614198c..5e7ed225851a 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -347,18 +347,28 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct dcb_app app = {
+ .selector = DCB_APP_IDTYPE_ETHTYPE,
+ .protocol = ETH_P_FCOE,
+ };
+ u8 up = dcb_getapp(netdev, &app);
int ret;
- if (!adapter->dcb_set_bitmap ||
- !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
- return DCB_NO_HW_CHG;
-
ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
MAX_TRAFFIC_CLASS);
-
if (ret)
return DCB_NO_HW_CHG;
+ /* In IEEE mode app data must be parsed into DCBX format for
+ * hardware routines.
+ */
+ if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)
+ up = (1 << up);
+
+#ifdef IXGBE_FCOE
+ if (up && (up != (1 << adapter->fcoe.up)))
+ adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+
/*
* Only take down the adapter if an app change occurred. FCoE
* may shuffle tx rings in this case and this can not be done
@@ -366,12 +376,15 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
*/
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
+
+ ixgbe_fcoe_setapp(adapter, up);
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
}
+#endif
if (adapter->dcb_cfg.pfc_mode_enable) {
switch (adapter->hw.mac.type) {
@@ -399,12 +412,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
}
}
+#ifdef IXGBE_FCOE
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
ret = DCB_HW_CHG_RST;
}
+#endif
if (adapter->dcb_set_bitmap & BIT_PFC) {
u8 pfc_en;
@@ -558,68 +573,6 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
return dcb_getapp(netdev, &app);
}
-/**
- * ixgbe_dcbnl_setapp - set the DCBX application user priority
- * @netdev : the corresponding netdev
- * @idtype : identifies the id as ether type or TCP/UDP port number
- * @id: id is either ether type or TCP/UDP port number
- * @up: the 802.1p user priority bitmap
- *
- * Returns : 0 on success or 1 on error
- */
-static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
- u8 idtype, u16 id, u8 up)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u8 rval = 1;
- struct dcb_app app = {
- .selector = idtype,
- .protocol = id,
- .priority = up
- };
-
- if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
- return rval;
-
- rval = dcb_setapp(netdev, &app);
-
- switch (idtype) {
- case DCB_APP_IDTYPE_ETHTYPE:
-#ifdef IXGBE_FCOE
- if (id == ETH_P_FCOE) {
- u8 old_tc;
-
- /* Get current programmed tc */
- old_tc = adapter->fcoe.tc;
- rval = ixgbe_fcoe_setapp(adapter, up);
-
- if (rval ||
- !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) ||
- !(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
- break;
-
- /* The FCoE application priority may be changed multiple
- * times in quick succession with switches that build up
- * TLVs. To avoid creating uneeded device resets this
- * checks the actual HW configuration and clears
- * BIT_APP_UPCHG if a HW configuration change is not
- * need
- */
- if (old_tc == adapter->fcoe.tc)
- adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG;
- else
- adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
- }
-#endif
- break;
- case DCB_APP_IDTYPE_PORTNUM:
- break;
- default:
- break;
- }
- return rval;
-}
-
static int ixgbe_dcbnl_ieee_getets(struct net_device *dev,
struct ieee_ets *ets)
{
@@ -745,25 +698,14 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
return -EINVAL;
-#ifdef IXGBE_FCOE
- if (app->selector == 1 && app->protocol == ETH_P_FCOE) {
- if (adapter->fcoe.tc == app->priority)
- goto setapp;
- /* In IEEE mode map up to tc 1:1 */
- adapter->fcoe.tc = app->priority;
- adapter->fcoe.up = app->priority;
+ dcb_setapp(dev, app);
- /* Force hardware reset required to push FCoE
- * setup on {tx|rx}_rings
- */
- adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+#ifdef IXGBE_FCOE
+ if (app->selector == 1 && app->protocol == ETH_P_FCOE &&
+ adapter->fcoe.tc == app->priority)
ixgbe_dcbnl_set_all(dev);
- }
-
-setapp:
#endif
- dcb_setapp(dev, app);
return 0;
}
@@ -838,7 +780,6 @@ const struct dcbnl_rtnl_ops dcbnl_ops = {
.getpfcstate = ixgbe_dcbnl_getpfcstate,
.setpfcstate = ixgbe_dcbnl_setpfcstate,
.getapp = ixgbe_dcbnl_getapp,
- .setapp = ixgbe_dcbnl_setapp,
.getdcbx = ixgbe_dcbnl_getdcbx,
.setdcbx = ixgbe_dcbnl_setdcbx,
};
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 76380a2b35aa..5005a36f8593 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -931,7 +931,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
}
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (!netif_running(adapter->netdev)) {
for (i = 0; i < adapter->num_tx_queues; i++)
@@ -1417,7 +1417,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
/* Disable all the interrupts */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Test each interrupt */
for (; i < 10; i++) {
@@ -1437,7 +1437,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
~mask & 0x00007FFF);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
~mask & 0x00007FFF);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr & mask) {
*data = 3;
@@ -1454,7 +1454,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
adapter->test_icr = 0;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
- msleep(10);
+ usleep_range(10000, 20000);
if (!(adapter->test_icr &mask)) {
*data = 4;
@@ -1474,7 +1474,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
~mask & 0x00007FFF);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
~mask & 0x00007FFF);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr) {
*data = 5;
@@ -1485,7 +1485,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
/* Disable all the interrupts */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Unhook test interrupt handler */
free_irq(irq, netdev);
@@ -1613,7 +1613,7 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data);
IXGBE_WRITE_FLUSH(&adapter->hw);
- msleep(10);
+ usleep_range(10000, 20000);
/* Disable Atlas Tx lanes; re-enabled in reset path */
if (hw->mac.type == ixgbe_mac_82598EB) {
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 6f8adc7f5d7c..200ae7e60ba0 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -51,8 +51,12 @@
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-
-#define DRV_VERSION "3.2.9-k2"
+#define MAJ 3
+#define MIN 2
+#define BUILD 9
+#define KFIX 2
+#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
+ __stringify(BUILD) "-k" __stringify(KFIX)
const char ixgbe_driver_version[] = DRV_VERSION;
static const char ixgbe_copyright[] =
"Copyright (c) 1999-2011 Intel Corporation.";
@@ -120,6 +124,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T),
board_X540 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2),
+ board_82599 },
/* required last entry */
{0, }
@@ -943,8 +949,6 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
- rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
- IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl);
}
@@ -962,7 +966,6 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
- txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl);
break;
case ixgbe_mac_82599EB:
@@ -972,7 +975,6 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
- txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx), txctrl);
break;
default:
@@ -2731,7 +2733,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
/* poll to verify queue is enabled */
do {
- msleep(1);
+ usleep_range(1000, 2000);
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
@@ -3023,7 +3025,7 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
return;
do {
- msleep(1);
+ usleep_range(1000, 2000);
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
} while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE));
@@ -3945,7 +3947,7 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
{
WARN_ON(in_interrupt());
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
ixgbe_down(adapter);
/*
* If SR-IOV enabled then wait a bit before bringing the adapter
@@ -4150,7 +4152,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
/* this call also flushes the previous write */
ixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]);
- msleep(10);
+ usleep_range(10000, 20000);
netif_tx_stop_all_queues(netdev);
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index df5b8aa4795d..fd381ea17e99 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -449,7 +449,8 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
MDIO_MMD_AN,
&autoneg_reg);
- autoneg_reg &= ~ADVERTISE_100FULL;
+ autoneg_reg &= ~(ADVERTISE_100FULL |
+ ADVERTISE_100HALF);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
autoneg_reg |= ADVERTISE_100FULL;
@@ -753,7 +754,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
&phy_data);
if ((phy_data & MDIO_CTRL1_RESET) == 0)
break;
- msleep(10);
+ usleep_range(10000, 20000);
}
if ((phy_data & MDIO_CTRL1_RESET) != 0) {
@@ -782,7 +783,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
case IXGBE_DELAY_NL:
data_offset++;
hw_dbg(hw, "DELAY: %d MS\n", edata);
- msleep(edata);
+ usleep_range(edata * 1000, edata * 2000);
break;
case IXGBE_DATA_NL:
hw_dbg(hw, "DATA:\n");
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 25c1fb7eda06..f5bec9754c00 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -58,6 +58,7 @@
#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
+#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C
@@ -1616,10 +1617,18 @@
#define IXGBE_FLUDONE_ATTEMPTS 20000
#endif
+#define IXGBE_PCIE_CTRL2 0x5 /* PCIe Control 2 Offset */
+#define IXGBE_PCIE_CTRL2_DUMMY_ENABLE 0x8 /* Dummy Function Enable */
+#define IXGBE_PCIE_CTRL2_LAN_DISABLE 0x2 /* LAN PCI Disable */
+#define IXGBE_PCIE_CTRL2_DISABLE_SELECT 0x1 /* LAN Disable Select */
+
#define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET 0x0
#define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3
#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1
#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2
+#define IXGBE_FW_LESM_PARAMETERS_PTR 0x2
+#define IXGBE_FW_LESM_STATE_1 0x1
+#define IXGBE_FW_LESM_STATE_ENABLED 0x8000 /* LESM Enable bit */
#define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4
#define IXGBE_FW_PATCH_VERSION_4 0x7
@@ -1719,6 +1728,8 @@
#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */
#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */
+#define IXGBE_MFLCN_RPFCE_SHIFT 4
+
/* Multiple Receive Queue Control */
#define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */
#define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */
@@ -2597,6 +2608,7 @@ struct ixgbe_mac_info {
u32 vft_size;
u32 num_rar_entries;
u32 rar_highwater;
+ u32 rx_pb_size;
u32 max_tx_queues;
u32 max_rx_queues;
u32 max_msix_vectors;
diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c
index d9323c08f5c7..932394fce439 100644
--- a/drivers/net/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ixgbe/ixgbe_x540.c
@@ -37,6 +37,7 @@
#define IXGBE_X540_RAR_ENTRIES 128
#define IXGBE_X540_MC_TBL_SIZE 128
#define IXGBE_X540_VFT_TBL_SIZE 128
+#define IXGBE_X540_RX_PB_SIZE 384
static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw);
static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
@@ -226,6 +227,28 @@ mac_reset_top:
}
/**
+ * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
+ *
+ * Starts the hardware using the generic start_hw function
+ * and the generation start_hw function.
+ * Then performs revision-specific operations, if any.
+ **/
+static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
+{
+ s32 ret_val = 0;
+
+ ret_val = ixgbe_start_hw_generic(hw);
+ if (ret_val != 0)
+ goto out;
+
+ ret_val = ixgbe_start_hw_gen2(hw);
+ hw->mac.rx_pb_size = IXGBE_X540_RX_PB_SIZE;
+out:
+ return ret_val;
+}
+
+/**
* ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
* @hw: pointer to hardware structure
*
@@ -300,55 +323,33 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
}
/**
- * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to write
- * @data: word write to the EEPROM
+ * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
*
- * Write a 16 bit word to the EEPROM using the EEWR register.
+ * Write a 16 bit word to the EEPROM using the EEWR register.
**/
static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
{
- u32 eewr;
- s32 status;
-
- hw->eeprom.ops.init_params(hw);
-
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
- (data << IXGBE_EEPROM_RW_REG_DATA) |
- IXGBE_EEPROM_RW_REG_START;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+ s32 status = 0;
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
- }
- } else {
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
+ status = ixgbe_write_eewr_generic(hw, offset, data);
+ else
status = IXGBE_ERR_SWFW_SYNC;
- }
-out:
- ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
}
/**
- * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
- * @hw: pointer to hardware structure
+ * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
+ *
+ * This function does not use synchronization for EERD and EEWR. It can
+ * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
+ *
+ * @hw: pointer to hardware structure
**/
static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
{
@@ -359,9 +360,15 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
u16 pointer = 0;
u16 word = 0;
+ /*
+ * Do not use hw->eeprom.ops.read because we do not want to take
+ * the synchronization semaphores here. Instead use
+ * ixgbe_read_eerd_generic
+ */
+
/* Include 0x0-0x3F in the checksum */
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (hw->eeprom.ops.read(hw, i, &word) != 0) {
+ if (ixgbe_read_eerd_generic(hw, i, &word) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -376,7 +383,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
continue;
- if (hw->eeprom.ops.read(hw, i, &pointer) != 0) {
+ if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -386,7 +393,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
pointer >= hw->eeprom.word_size)
continue;
- if (hw->eeprom.ops.read(hw, pointer, &length) != 0) {
+ if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -397,7 +404,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
continue;
for (j = pointer+1; j <= pointer+length; j++) {
- if (hw->eeprom.ops.read(hw, j, &word) != 0) {
+ if (ixgbe_read_eerd_generic(hw, j, &word) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -411,6 +418,62 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
+ * @hw: pointer to hardware structure
+ * @checksum_val: calculated checksum
+ *
+ * Performs checksum calculation and validates the EEPROM checksum. If the
+ * caller does not need checksum_val, the value can be NULL.
+ **/
+static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
+ u16 *checksum_val)
+{
+ s32 status;
+ u16 checksum;
+ u16 read_checksum = 0;
+
+ /*
+ * 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 != 0) {
+ hw_dbg(hw, "EEPROM read failed\n");
+ goto out;
+ }
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
+ checksum = hw->eeprom.ops.calc_checksum(hw);
+
+ /*
+ * Do not use hw->eeprom.ops.read because we do not want to take
+ * the synchronization semaphores twice here.
+ */
+ ixgbe_read_eerd_generic(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 {
+ status = IXGBE_ERR_SWFW_SYNC;
+ }
+
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+out:
+ return status;
+}
+
+/**
* ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
* @hw: pointer to hardware structure
*
@@ -421,11 +484,35 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
{
s32 status;
+ u16 checksum;
+
+ /*
+ * 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);
- status = ixgbe_update_eeprom_checksum_generic(hw);
+ if (status != 0)
+ hw_dbg(hw, "EEPROM read failed\n");
- if (status)
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
+ checksum = hw->eeprom.ops.calc_checksum(hw);
+
+ /*
+ * Do not use hw->eeprom.ops.write because we do not want to
+ * take the synchronization semaphores twice here.
+ */
+ status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM,
+ checksum);
+
+ if (status == 0)
status = ixgbe_update_flash_X540(hw);
+ else
+ status = IXGBE_ERR_SWFW_SYNC;
+ }
+
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
}
@@ -452,7 +539,7 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
status = ixgbe_poll_flash_update_done_X540(hw);
- if (status)
+ if (status == 0)
hw_dbg(hw, "Flash update complete\n");
else
hw_dbg(hw, "Flash update time out\n");
@@ -466,11 +553,10 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
}
status = ixgbe_poll_flash_update_done_X540(hw);
- if (status)
+ if (status == 0)
hw_dbg(hw, "Flash update complete\n");
else
hw_dbg(hw, "Flash update time out\n");
-
}
out:
return status;
@@ -542,7 +628,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
* resource (swmask)
*/
ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
+ usleep_range(5000, 10000);
}
}
@@ -564,7 +650,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
}
}
- msleep(5);
+ usleep_range(5000, 10000);
return 0;
}
@@ -588,7 +674,7 @@ static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
+ usleep_range(5000, 10000);
}
/**
@@ -661,7 +747,7 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
static struct ixgbe_mac_operations mac_ops_X540 = {
.init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_X540,
- .start_hw = &ixgbe_start_hw_generic,
+ .start_hw = &ixgbe_start_hw_X540,
.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_X540,
.get_supported_physical_layer =
@@ -669,7 +755,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.enable_rx_dma = &ixgbe_enable_rx_dma_generic,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
- .get_device_caps = NULL,
+ .get_device_caps = &ixgbe_get_device_caps_generic,
.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
.get_bus_info = &ixgbe_get_bus_info_generic,
@@ -707,7 +793,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
.read = &ixgbe_read_eerd_X540,
.write = &ixgbe_write_eewr_X540,
.calc_checksum = &ixgbe_calc_eeprom_checksum_X540,
- .validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
+ .validate_checksum = &ixgbe_validate_eeprom_checksum_X540,
.update_checksum = &ixgbe_update_eeprom_checksum_X540,
};