|
@@ -1,7 +1,7 @@
|
|
|
/*******************************************************************************
|
|
|
|
|
|
Intel 10 Gigabit PCI Express Linux driver
|
|
|
- Copyright(c) 1999 - 2010 Intel Corporation.
|
|
|
+ Copyright(c) 1999 - 2011 Intel Corporation.
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
|
under the terms and conditions of the GNU General Public License,
|
|
@@ -46,10 +46,7 @@ static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
|
|
|
static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
|
|
|
static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
|
|
|
|
|
|
-static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
|
|
|
-static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
|
|
|
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
|
|
|
-static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
|
|
|
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
|
|
|
|
|
|
/**
|
|
@@ -454,8 +451,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
|
|
|
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
|
|
|
* access and verify no pending requests
|
|
|
*/
|
|
|
- if (ixgbe_disable_pcie_master(hw) != 0)
|
|
|
- hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
|
|
|
+ ixgbe_disable_pcie_master(hw);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -603,7 +599,6 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
|
|
|
ixgbe_shift_out_eeprom_bits(hw, data, 16);
|
|
|
ixgbe_standby_eeprom(hw);
|
|
|
|
|
|
- msleep(hw->eeprom.semaphore_delay);
|
|
|
/* Done with writing - release the EEPROM */
|
|
|
ixgbe_release_eeprom(hw);
|
|
|
}
|
|
@@ -747,10 +742,10 @@ s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
|
|
|
static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
s32 status = 0;
|
|
|
- u32 eec = 0;
|
|
|
+ u32 eec;
|
|
|
u32 i;
|
|
|
|
|
|
- if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
|
|
|
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
|
|
|
status = IXGBE_ERR_SWFW_SYNC;
|
|
|
|
|
|
if (status == 0) {
|
|
@@ -773,18 +768,18 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
|
|
|
hw_dbg(hw, "Could not acquire EEPROM grant\n");
|
|
|
|
|
|
- ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
|
|
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
|
|
status = IXGBE_ERR_EEPROM;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /* Setup EEPROM for Read/Write */
|
|
|
- if (status == 0) {
|
|
|
- /* Clear CS and SK */
|
|
|
- eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
|
|
|
- IXGBE_WRITE_FLUSH(hw);
|
|
|
- udelay(1);
|
|
|
+ /* Setup EEPROM for Read/Write */
|
|
|
+ if (status == 0) {
|
|
|
+ /* Clear CS and SK */
|
|
|
+ eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
|
|
|
+ IXGBE_WRITE_FLUSH(hw);
|
|
|
+ udelay(1);
|
|
|
+ }
|
|
|
}
|
|
|
return status;
|
|
|
}
|
|
@@ -798,13 +793,10 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
|
|
|
static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
s32 status = IXGBE_ERR_EEPROM;
|
|
|
- u32 timeout;
|
|
|
+ u32 timeout = 2000;
|
|
|
u32 i;
|
|
|
u32 swsm;
|
|
|
|
|
|
- /* Set timeout value based on size of EEPROM */
|
|
|
- timeout = hw->eeprom.word_size + 1;
|
|
|
-
|
|
|
/* Get SMBI software semaphore between device drivers first */
|
|
|
for (i = 0; i < timeout; i++) {
|
|
|
/*
|
|
@@ -816,7 +808,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
|
|
|
status = 0;
|
|
|
break;
|
|
|
}
|
|
|
- msleep(1);
|
|
|
+ udelay(50);
|
|
|
}
|
|
|
|
|
|
/* Now get the semaphore between SW/FW through the SWESMBI bit */
|
|
@@ -844,11 +836,14 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
|
|
|
* was not granted because we don't have access to the EEPROM
|
|
|
*/
|
|
|
if (i >= timeout) {
|
|
|
- hw_dbg(hw, "Driver can't access the Eeprom - Semaphore "
|
|
|
+ hw_dbg(hw, "SWESMBI Software EEPROM semaphore "
|
|
|
"not granted.\n");
|
|
|
ixgbe_release_eeprom_semaphore(hw);
|
|
|
status = IXGBE_ERR_EEPROM;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ hw_dbg(hw, "Software semaphore SMBI between device drivers "
|
|
|
+ "not granted.\n");
|
|
|
}
|
|
|
|
|
|
return status;
|
|
@@ -1081,10 +1076,13 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
|
|
|
|
|
|
ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
|
|
+
|
|
|
+ /* Delay before attempt to obtain semaphore again to allow FW access */
|
|
|
+ msleep(hw->eeprom.semaphore_delay);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * ixgbe_calc_eeprom_checksum - Calculates and returns the checksum
|
|
|
+ * 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)
|
|
@@ -1190,7 +1188,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
|
|
|
if (status == 0) {
|
|
|
checksum = hw->eeprom.ops.calc_checksum(hw);
|
|
|
status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
|
|
|
- checksum);
|
|
|
+ checksum);
|
|
|
} else {
|
|
|
hw_dbg(hw, "EEPROM read failed\n");
|
|
|
}
|
|
@@ -1238,37 +1236,37 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
|
|
|
u32 rar_low, rar_high;
|
|
|
u32 rar_entries = hw->mac.num_rar_entries;
|
|
|
|
|
|
+ /* Make sure we are using a valid rar index range */
|
|
|
+ if (index >= rar_entries) {
|
|
|
+ hw_dbg(hw, "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);
|
|
|
|
|
|
- /* Make sure we are using a valid rar index range */
|
|
|
- if (index < rar_entries) {
|
|
|
- /*
|
|
|
- * HW expects these in little endian so we reverse the byte
|
|
|
- * order from network order (big endian) to little endian
|
|
|
- */
|
|
|
- rar_low = ((u32)addr[0] |
|
|
|
- ((u32)addr[1] << 8) |
|
|
|
- ((u32)addr[2] << 16) |
|
|
|
- ((u32)addr[3] << 24));
|
|
|
- /*
|
|
|
- * Some parts put the VMDq setting in the extra RAH bits,
|
|
|
- * so save everything except the lower 16 bits that hold part
|
|
|
- * of the address and the address valid bit.
|
|
|
- */
|
|
|
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
|
|
|
- rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
|
|
|
- rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
|
|
|
+ /*
|
|
|
+ * HW expects these in little endian so we reverse the byte
|
|
|
+ * order from network order (big endian) to little endian
|
|
|
+ */
|
|
|
+ rar_low = ((u32)addr[0] |
|
|
|
+ ((u32)addr[1] << 8) |
|
|
|
+ ((u32)addr[2] << 16) |
|
|
|
+ ((u32)addr[3] << 24));
|
|
|
+ /*
|
|
|
+ * Some parts put the VMDq setting in the extra RAH bits,
|
|
|
+ * so save everything except the lower 16 bits that hold part
|
|
|
+ * of the address and the address valid bit.
|
|
|
+ */
|
|
|
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
|
|
|
+ rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
|
|
|
+ rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
|
|
|
|
|
|
- if (enable_addr != 0)
|
|
|
- rar_high |= IXGBE_RAH_AV;
|
|
|
+ if (enable_addr != 0)
|
|
|
+ rar_high |= IXGBE_RAH_AV;
|
|
|
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
|
|
|
- } else {
|
|
|
- hw_dbg(hw, "RAR index %d is out of range.\n", index);
|
|
|
- return IXGBE_ERR_RAR_INDEX;
|
|
|
- }
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1286,58 +1284,26 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
|
|
|
u32 rar_entries = hw->mac.num_rar_entries;
|
|
|
|
|
|
/* Make sure we are using a valid rar index range */
|
|
|
- if (index < rar_entries) {
|
|
|
- /*
|
|
|
- * Some parts put the VMDq setting in the extra RAH bits,
|
|
|
- * so save everything except the lower 16 bits that hold part
|
|
|
- * of the address and the address valid bit.
|
|
|
- */
|
|
|
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
|
|
|
- rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
|
|
|
-
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
|
|
|
- } else {
|
|
|
+ if (index >= rar_entries) {
|
|
|
hw_dbg(hw, "RAR index %d is out of range.\n", index);
|
|
|
- return IXGBE_ERR_RAR_INDEX;
|
|
|
+ return IXGBE_ERR_INVALID_ARGUMENT;
|
|
|
}
|
|
|
|
|
|
- /* clear VMDq pool/queue selection for this RAR */
|
|
|
- hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * ixgbe_enable_rar - Enable Rx address register
|
|
|
- * @hw: pointer to hardware structure
|
|
|
- * @index: index into the RAR table
|
|
|
- *
|
|
|
- * Enables the select receive address register.
|
|
|
- **/
|
|
|
-static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index)
|
|
|
-{
|
|
|
- u32 rar_high;
|
|
|
-
|
|
|
+ /*
|
|
|
+ * Some parts put the VMDq setting in the extra RAH bits,
|
|
|
+ * so save everything except the lower 16 bits that hold part
|
|
|
+ * of the address and the address valid bit.
|
|
|
+ */
|
|
|
rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
|
|
|
- rar_high |= IXGBE_RAH_AV;
|
|
|
+ rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
|
|
|
+
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
|
|
|
-}
|
|
|
|
|
|
-/**
|
|
|
- * ixgbe_disable_rar - Disable Rx address register
|
|
|
- * @hw: pointer to hardware structure
|
|
|
- * @index: index into the RAR table
|
|
|
- *
|
|
|
- * Disables the select receive address register.
|
|
|
- **/
|
|
|
-static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index)
|
|
|
-{
|
|
|
- u32 rar_high;
|
|
|
+ /* clear VMDq pool/queue selection for this RAR */
|
|
|
+ hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
|
|
|
|
|
|
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
|
|
|
- rar_high &= (~IXGBE_RAH_AV);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1386,7 +1352,6 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
|
|
|
}
|
|
|
|
|
|
/* Clear the MTA */
|
|
|
- hw->addr_ctrl.mc_addr_in_rar_count = 0;
|
|
|
hw->addr_ctrl.mta_in_use = 0;
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
|
|
|
|
|
@@ -1400,105 +1365,6 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * ixgbe_add_uc_addr - Adds a secondary unicast address.
|
|
|
- * @hw: pointer to hardware structure
|
|
|
- * @addr: new address
|
|
|
- *
|
|
|
- * Adds it to unused receive address register or goes into promiscuous mode.
|
|
|
- **/
|
|
|
-static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
|
|
|
-{
|
|
|
- u32 rar_entries = hw->mac.num_rar_entries;
|
|
|
- u32 rar;
|
|
|
-
|
|
|
- hw_dbg(hw, " UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
|
|
|
- addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
|
|
|
-
|
|
|
- /*
|
|
|
- * Place this address in the RAR if there is room,
|
|
|
- * else put the controller into promiscuous mode
|
|
|
- */
|
|
|
- if (hw->addr_ctrl.rar_used_count < rar_entries) {
|
|
|
- rar = hw->addr_ctrl.rar_used_count -
|
|
|
- hw->addr_ctrl.mc_addr_in_rar_count;
|
|
|
- hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
|
|
|
- hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
|
|
|
- hw->addr_ctrl.rar_used_count++;
|
|
|
- } else {
|
|
|
- hw->addr_ctrl.overflow_promisc++;
|
|
|
- }
|
|
|
-
|
|
|
- hw_dbg(hw, "ixgbe_add_uc_addr Complete\n");
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
|
|
|
- * @hw: pointer to hardware structure
|
|
|
- * @netdev: pointer to net device structure
|
|
|
- *
|
|
|
- * The given list replaces any existing list. Clears the secondary addrs from
|
|
|
- * receive address registers. Uses unused receive address registers for the
|
|
|
- * first secondary addresses, and falls back to promiscuous mode as needed.
|
|
|
- *
|
|
|
- * Drivers using secondary unicast addresses must set user_set_promisc when
|
|
|
- * manually putting the device into promiscuous mode.
|
|
|
- **/
|
|
|
-s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
|
|
|
- struct net_device *netdev)
|
|
|
-{
|
|
|
- u32 i;
|
|
|
- u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
|
|
|
- u32 uc_addr_in_use;
|
|
|
- u32 fctrl;
|
|
|
- struct netdev_hw_addr *ha;
|
|
|
-
|
|
|
- /*
|
|
|
- * Clear accounting of old secondary address list,
|
|
|
- * don't count RAR[0]
|
|
|
- */
|
|
|
- uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
|
|
|
- hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
|
|
|
- hw->addr_ctrl.overflow_promisc = 0;
|
|
|
-
|
|
|
- /* Zero out the other receive addresses */
|
|
|
- hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use + 1);
|
|
|
- for (i = 0; i < uc_addr_in_use; i++) {
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0);
|
|
|
- }
|
|
|
-
|
|
|
- /* Add the new addresses */
|
|
|
- netdev_for_each_uc_addr(ha, netdev) {
|
|
|
- hw_dbg(hw, " Adding the secondary addresses:\n");
|
|
|
- ixgbe_add_uc_addr(hw, ha->addr, 0);
|
|
|
- }
|
|
|
-
|
|
|
- if (hw->addr_ctrl.overflow_promisc) {
|
|
|
- /* enable promisc if not already in overflow or set by user */
|
|
|
- if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
|
|
|
- hw_dbg(hw, " Entering address overflow promisc mode\n");
|
|
|
- fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
|
|
|
- fctrl |= IXGBE_FCTRL_UPE;
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
|
|
|
- hw->addr_ctrl.uc_set_promisc = true;
|
|
|
- }
|
|
|
- } else {
|
|
|
- /* only disable if set by overflow, not by user */
|
|
|
- if ((old_promisc_setting && hw->addr_ctrl.uc_set_promisc) &&
|
|
|
- !(hw->addr_ctrl.user_set_promisc)) {
|
|
|
- hw_dbg(hw, " Leaving address overflow promisc mode\n");
|
|
|
- fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
|
|
|
- fctrl &= ~IXGBE_FCTRL_UPE;
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
|
|
|
- hw->addr_ctrl.uc_set_promisc = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n");
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* ixgbe_mta_vector - Determines bit-vector in multicast table to set
|
|
|
* @hw: pointer to hardware structure
|
|
@@ -1550,7 +1416,6 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
|
|
|
u32 vector;
|
|
|
u32 vector_bit;
|
|
|
u32 vector_reg;
|
|
|
- u32 mta_reg;
|
|
|
|
|
|
hw->addr_ctrl.mta_in_use++;
|
|
|
|
|
@@ -1568,9 +1433,7 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
|
|
|
*/
|
|
|
vector_reg = (vector >> 5) & 0x7F;
|
|
|
vector_bit = vector & 0x1F;
|
|
|
- mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));
|
|
|
- mta_reg |= (1 << vector_bit);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
|
|
|
+ hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1596,18 +1459,21 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw,
|
|
|
hw->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev);
|
|
|
hw->addr_ctrl.mta_in_use = 0;
|
|
|
|
|
|
- /* Clear the MTA */
|
|
|
+ /* Clear mta_shadow */
|
|
|
hw_dbg(hw, " Clearing MTA\n");
|
|
|
- for (i = 0; i < hw->mac.mcft_size; i++)
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
|
|
|
+ memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
|
|
|
|
|
|
- /* Add the new addresses */
|
|
|
+ /* Update mta shadow */
|
|
|
netdev_for_each_mc_addr(ha, netdev) {
|
|
|
hw_dbg(hw, " Adding the multicast addresses:\n");
|
|
|
ixgbe_set_mta(hw, ha->addr);
|
|
|
}
|
|
|
|
|
|
/* Enable mta */
|
|
|
+ for (i = 0; i < hw->mac.mcft_size; i++)
|
|
|
+ IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i,
|
|
|
+ hw->mac.mta_shadow[i]);
|
|
|
+
|
|
|
if (hw->addr_ctrl.mta_in_use > 0)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
|
|
|
IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
|
|
@@ -1624,15 +1490,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw,
|
|
|
**/
|
|
|
s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
- u32 i;
|
|
|
- u32 rar_entries = hw->mac.num_rar_entries;
|
|
|
struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
|
|
|
|
|
|
- if (a->mc_addr_in_rar_count > 0)
|
|
|
- for (i = (rar_entries - a->mc_addr_in_rar_count);
|
|
|
- i < rar_entries; i++)
|
|
|
- ixgbe_enable_rar(hw, i);
|
|
|
-
|
|
|
if (a->mta_in_use > 0)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
|
|
|
hw->mac.mc_filter_type);
|
|
@@ -1648,15 +1507,8 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
|
|
|
**/
|
|
|
s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
- u32 i;
|
|
|
- u32 rar_entries = hw->mac.num_rar_entries;
|
|
|
struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
|
|
|
|
|
|
- if (a->mc_addr_in_rar_count > 0)
|
|
|
- for (i = (rar_entries - a->mc_addr_in_rar_count);
|
|
|
- i < rar_entries; i++)
|
|
|
- ixgbe_disable_rar(hw, i);
|
|
|
-
|
|
|
if (a->mta_in_use > 0)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
|
|
|
|
|
@@ -1703,7 +1555,9 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
|
|
|
* 2: Tx flow control is enabled (we can send pause frames but
|
|
|
* we do not support receiving pause frames).
|
|
|
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
|
|
+#ifdef CONFIG_DCB
|
|
|
* 4: Priority Flow Control is enabled.
|
|
|
+#endif
|
|
|
* other: Invalid.
|
|
|
*/
|
|
|
switch (hw->fc.current_mode) {
|
|
@@ -2159,10 +2013,16 @@ out:
|
|
|
**/
|
|
|
s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
+ struct ixgbe_adapter *adapter = hw->back;
|
|
|
u32 i;
|
|
|
u32 reg_val;
|
|
|
u32 number_of_queues;
|
|
|
- s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
|
|
|
+ s32 status = 0;
|
|
|
+ u16 dev_status = 0;
|
|
|
+
|
|
|
+ /* Just jump out if bus mastering is already disabled */
|
|
|
+ if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
|
|
|
+ goto out;
|
|
|
|
|
|
/* Disable the receive unit by stopping each queue */
|
|
|
number_of_queues = hw->mac.max_rx_queues;
|
|
@@ -2179,13 +2039,43 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
|
|
|
|
|
|
for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
|
|
|
- if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) {
|
|
|
- status = 0;
|
|
|
+ if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
|
|
|
+ goto check_device_status;
|
|
|
+ udelay(100);
|
|
|
+ }
|
|
|
+
|
|
|
+ hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n");
|
|
|
+ status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Before proceeding, make sure that the PCIe block does not have
|
|
|
+ * transactions pending.
|
|
|
+ */
|
|
|
+check_device_status:
|
|
|
+ for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
|
|
|
+ pci_read_config_word(adapter->pdev, IXGBE_PCI_DEVICE_STATUS,
|
|
|
+ &dev_status);
|
|
|
+ if (!(dev_status & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
|
|
|
break;
|
|
|
- }
|
|
|
udelay(100);
|
|
|
}
|
|
|
|
|
|
+ if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT)
|
|
|
+ hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n");
|
|
|
+ else
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Two consecutive resets are required via CTRL.RST per datasheet
|
|
|
+ * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine
|
|
|
+ * of this need. The first reset prevents new master requests from
|
|
|
+ * being issued by our device. We then must wait 1usec for any
|
|
|
+ * remaining completions from the PCIe bus to trickle in, and then reset
|
|
|
+ * again to clear out any effects they may have had on our device.
|
|
|
+ */
|
|
|
+ hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
|
|
|
+
|
|
|
+out:
|
|
|
return status;
|
|
|
}
|
|
|
|
|
@@ -2206,6 +2096,10 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
|
|
s32 timeout = 200;
|
|
|
|
|
|
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;
|
|
|
|
|
@@ -2223,7 +2117,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
|
|
}
|
|
|
|
|
|
if (!timeout) {
|
|
|
- hw_dbg(hw, "Driver can't access resource, GSSR timeout.\n");
|
|
|
+ hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n");
|
|
|
return IXGBE_ERR_SWFW_SYNC;
|
|
|
}
|
|
|
|
|
@@ -2427,37 +2321,38 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
|
|
|
u32 mpsar_lo, mpsar_hi;
|
|
|
u32 rar_entries = hw->mac.num_rar_entries;
|
|
|
|
|
|
- if (rar < rar_entries) {
|
|
|
- mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
|
|
|
- mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
|
|
|
+ /* Make sure we are using a valid rar index range */
|
|
|
+ if (rar >= rar_entries) {
|
|
|
+ hw_dbg(hw, "RAR index %d is out of range.\n", rar);
|
|
|
+ return IXGBE_ERR_INVALID_ARGUMENT;
|
|
|
+ }
|
|
|
|
|
|
- if (!mpsar_lo && !mpsar_hi)
|
|
|
- goto done;
|
|
|
+ mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
|
|
|
+ mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
|
|
|
|
|
|
- if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
|
|
|
- if (mpsar_lo) {
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
|
|
|
- mpsar_lo = 0;
|
|
|
- }
|
|
|
- if (mpsar_hi) {
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
|
|
|
- mpsar_hi = 0;
|
|
|
- }
|
|
|
- } else if (vmdq < 32) {
|
|
|
- mpsar_lo &= ~(1 << vmdq);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
|
|
|
- } else {
|
|
|
- mpsar_hi &= ~(1 << (vmdq - 32));
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
|
|
|
- }
|
|
|
+ if (!mpsar_lo && !mpsar_hi)
|
|
|
+ goto done;
|
|
|
|
|
|
- /* was that the last pool using this rar? */
|
|
|
- if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
|
|
|
- hw->mac.ops.clear_rar(hw, rar);
|
|
|
+ if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
|
|
|
+ if (mpsar_lo) {
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
|
|
|
+ mpsar_lo = 0;
|
|
|
+ }
|
|
|
+ if (mpsar_hi) {
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
|
|
|
+ mpsar_hi = 0;
|
|
|
+ }
|
|
|
+ } else if (vmdq < 32) {
|
|
|
+ mpsar_lo &= ~(1 << vmdq);
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
|
|
|
} else {
|
|
|
- hw_dbg(hw, "RAR index %d is out of range.\n", rar);
|
|
|
+ mpsar_hi &= ~(1 << (vmdq - 32));
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
|
|
|
}
|
|
|
|
|
|
+ /* was that the last pool using this rar? */
|
|
|
+ if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
|
|
|
+ hw->mac.ops.clear_rar(hw, rar);
|
|
|
done:
|
|
|
return 0;
|
|
|
}
|
|
@@ -2473,18 +2368,20 @@ s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
|
|
|
u32 mpsar;
|
|
|
u32 rar_entries = hw->mac.num_rar_entries;
|
|
|
|
|
|
- if (rar < rar_entries) {
|
|
|
- if (vmdq < 32) {
|
|
|
- mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
|
|
|
- mpsar |= 1 << vmdq;
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
|
|
|
- } else {
|
|
|
- mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
|
|
|
- mpsar |= 1 << (vmdq - 32);
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
|
|
|
- }
|
|
|
- } else {
|
|
|
+ /* Make sure we are using a valid rar index range */
|
|
|
+ if (rar >= rar_entries) {
|
|
|
hw_dbg(hw, "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));
|
|
|
+ mpsar |= 1 << vmdq;
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
|
|
|
+ } else {
|
|
|
+ mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
|
|
|
+ mpsar |= 1 << (vmdq - 32);
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -2497,7 +2394,6 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
-
|
|
|
for (i = 0; i < 128; i++)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
|
|
|
|
|
@@ -2726,12 +2622,21 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
|
|
|
* Reads the links register to determine if link is up and the current speed
|
|
|
**/
|
|
|
s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
|
|
|
- bool *link_up, bool link_up_wait_to_complete)
|
|
|
+ bool *link_up, bool link_up_wait_to_complete)
|
|
|
{
|
|
|
- u32 links_reg;
|
|
|
+ u32 links_reg, links_orig;
|
|
|
u32 i;
|
|
|
|
|
|
+ /* clear the old state */
|
|
|
+ links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
|
|
|
+
|
|
|
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
|
|
|
+
|
|
|
+ if (links_orig != links_reg) {
|
|
|
+ hw_dbg(hw, "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) {
|
|
@@ -2754,10 +2659,13 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
|
|
|
IXGBE_LINKS_SPEED_10G_82599)
|
|
|
*speed = IXGBE_LINK_SPEED_10GB_FULL;
|
|
|
else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
|
|
|
- IXGBE_LINKS_SPEED_1G_82599)
|
|
|
+ IXGBE_LINKS_SPEED_1G_82599)
|
|
|
*speed = IXGBE_LINK_SPEED_1GB_FULL;
|
|
|
- else
|
|
|
+ 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;
|
|
|
|
|
|
/* if link is down, zero out the current_mode */
|
|
|
if (*link_up == false) {
|