Commit ddd5c50f authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2014-12-05

This series contains updates to ixgbe and ixgbevf.

Alex provides a couple of patches to cleanup ixgbe.  First cleans up the
page reuse code getting it into a state where all the workarounds needed
are in place as well as cleaning up a few minor oversights such as using
__free_pages instead of put_page to drop a locally allocated page.  Then
cleans up the tail writes for the ixgbe descriptor queues.

Mark Peterson adds support to lookup MAC addresses in Open Firmware or
IDPROM.

Emil provides patches for ixgbe and ixgbevf to fix an issue on rmmod and
to add support for X550 in the VF driver.  First removes the read/write
operations to the CIAA/D registers since it can block access to the PCI
config space and make use of standard kernel functions for accessing the
PCI config space.  Then fixes an issue where the driver has logic to free
up used data in case any of the checks in ixgbe_probe() fail, however
there is a similar set of cleanups that can occur on driver unload in
ixgbe_remove() which can cause the rmmod command to crash.

Don provides the remaining patches in the series to complete the addition
of X550 support into the ixgbe driver.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d8febb77 0333464f
...@@ -34,7 +34,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o ...@@ -34,7 +34,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o
ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
ixgbe_dcb_82599.o ixgbe_dcb_nl.o ixgbe_dcb_82599.o ixgbe_dcb_nl.o
......
...@@ -301,6 +301,7 @@ enum ixgbe_ring_f_enum { ...@@ -301,6 +301,7 @@ enum ixgbe_ring_f_enum {
}; };
#define IXGBE_MAX_RSS_INDICES 16 #define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_RSS_INDICES_X550 64
#define IXGBE_MAX_VMDQ_INDICES 64 #define IXGBE_MAX_VMDQ_INDICES 64
#define IXGBE_MAX_FDIR_INDICES 63 /* based on q_vector limit */ #define IXGBE_MAX_FDIR_INDICES 63 /* based on q_vector limit */
#define IXGBE_MAX_FCOE_INDICES 8 #define IXGBE_MAX_FCOE_INDICES 8
...@@ -553,11 +554,6 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring) ...@@ -553,11 +554,6 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1; return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
} }
static inline void ixgbe_write_tail(struct ixgbe_ring *ring, u32 value)
{
writel(value, ring->tail);
}
#define IXGBE_RX_DESC(R, i) \ #define IXGBE_RX_DESC(R, i) \
(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
#define IXGBE_TX_DESC(R, i) \ #define IXGBE_TX_DESC(R, i) \
...@@ -769,6 +765,21 @@ struct ixgbe_adapter { ...@@ -769,6 +765,21 @@ struct ixgbe_adapter {
unsigned long fwd_bitmask; /* Bitmask indicating in use pools */ unsigned long fwd_bitmask; /* Bitmask indicating in use pools */
}; };
static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
{
switch (adapter->hw.mac.type) {
case ixgbe_mac_82598EB:
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
return IXGBE_MAX_RSS_INDICES;
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
return IXGBE_MAX_RSS_INDICES_X550;
default:
return 0;
}
}
struct ixgbe_fdir_filter { struct ixgbe_fdir_filter {
struct hlist_node fdir_node; struct hlist_node fdir_node;
union ixgbe_atr_input filter; union ixgbe_atr_input filter;
...@@ -804,11 +815,15 @@ enum ixgbe_boards { ...@@ -804,11 +815,15 @@ enum ixgbe_boards {
board_82598, board_82598,
board_82599, board_82599,
board_X540, board_X540,
board_X550,
board_X550EM_x,
}; };
extern struct ixgbe_info ixgbe_82598_info; extern struct ixgbe_info ixgbe_82598_info;
extern struct ixgbe_info ixgbe_82599_info; extern struct ixgbe_info ixgbe_82599_info;
extern struct ixgbe_info ixgbe_X540_info; extern struct ixgbe_info ixgbe_X540_info;
extern struct ixgbe_info ixgbe_X550_info;
extern struct ixgbe_info ixgbe_X550EM_x_info;
#ifdef CONFIG_IXGBE_DCB #ifdef CONFIG_IXGBE_DCB
extern const struct dcbnl_rtnl_ops dcbnl_ops; extern const struct dcbnl_rtnl_ops dcbnl_ops;
#endif #endif
......
...@@ -1625,7 +1625,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) ...@@ -1625,7 +1625,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
* ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
**/ **/
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
{ {
u16 i; u16 i;
u16 j; u16 j;
...@@ -1636,7 +1636,7 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) ...@@ -1636,7 +1636,7 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
/* Include 0x0-0x3F in the checksum */ /* Include 0x0-0x3F in the checksum */
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
if (hw->eeprom.ops.read(hw, i, &word) != 0) { if (hw->eeprom.ops.read(hw, i, &word)) {
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "EEPROM read failed\n");
break; break;
} }
...@@ -1645,24 +1645,35 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) ...@@ -1645,24 +1645,35 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
/* Include all data from pointers except for the fw pointer */ /* Include all data from pointers except for the fw pointer */
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
hw->eeprom.ops.read(hw, i, &pointer); if (hw->eeprom.ops.read(hw, i, &pointer)) {
hw_dbg(hw, "EEPROM read failed\n");
return IXGBE_ERR_EEPROM;
}
/* Make sure the pointer seems valid */ /* If the pointer seems invalid */
if (pointer != 0xFFFF && pointer != 0) { if (pointer == 0xFFFF || pointer == 0)
hw->eeprom.ops.read(hw, pointer, &length); continue;
if (length != 0xFFFF && length != 0) { if (hw->eeprom.ops.read(hw, pointer, &length)) {
for (j = pointer+1; j <= pointer+length; j++) { hw_dbg(hw, "EEPROM read failed\n");
hw->eeprom.ops.read(hw, j, &word); return IXGBE_ERR_EEPROM;
checksum += word;
} }
if (length == 0xFFFF || length == 0)
continue;
for (j = pointer + 1; j <= pointer + length; j++) {
if (hw->eeprom.ops.read(hw, j, &word)) {
hw_dbg(hw, "EEPROM read failed\n");
return IXGBE_ERR_EEPROM;
} }
checksum += word;
} }
} }
checksum = (u16)IXGBE_EEPROM_SUM - checksum; checksum = (u16)IXGBE_EEPROM_SUM - checksum;
return checksum; return (s32)checksum;
} }
/** /**
...@@ -1686,14 +1697,24 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, ...@@ -1686,14 +1697,24 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
* EEPROM read fails * EEPROM read fails
*/ */
status = hw->eeprom.ops.read(hw, 0, &checksum); status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status) {
hw_dbg(hw, "EEPROM read failed\n");
return status;
}
if (status == 0) { status = hw->eeprom.ops.calc_checksum(hw);
checksum = hw->eeprom.ops.calc_checksum(hw); if (status < 0)
return status;
hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); checksum = (u16)(status & 0xffff);
/* status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
* Verify read checksum from EEPROM is the same as if (status) {
hw_dbg(hw, "EEPROM read failed\n");
return status;
}
/* Verify read checksum from EEPROM is the same as
* calculated checksum * calculated checksum
*/ */
if (read_checksum != checksum) if (read_checksum != checksum)
...@@ -1702,9 +1723,6 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, ...@@ -1702,9 +1723,6 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
/* If the user cares, return the calculated checksum */ /* If the user cares, return the calculated checksum */
if (checksum_val) if (checksum_val)
*checksum_val = checksum; *checksum_val = checksum;
} else {
hw_dbg(hw, "EEPROM read failed\n");
}
return status; return status;
} }
...@@ -1724,15 +1742,19 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) ...@@ -1724,15 +1742,19 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
* EEPROM read fails * EEPROM read fails
*/ */
status = hw->eeprom.ops.read(hw, 0, &checksum); status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status) {
if (status == 0) {
checksum = hw->eeprom.ops.calc_checksum(hw);
status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
checksum);
} else {
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "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; return status;
} }
...@@ -2469,7 +2491,7 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) ...@@ -2469,7 +2491,7 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
* Acquires the SWFW semaphore through the GSSR register for the specified * Acquires the SWFW semaphore through the GSSR register for the specified
* function (CSR, PHY0, PHY1, EEPROM, Flash) * function (CSR, PHY0, PHY1, EEPROM, Flash)
**/ **/
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask)
{ {
u32 gssr = 0; u32 gssr = 0;
u32 swmask = mask; u32 swmask = mask;
...@@ -2514,7 +2536,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) ...@@ -2514,7 +2536,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
* Releases the SWFW semaphore through the GSSR register for the specified * Releases the SWFW semaphore through the GSSR register for the specified
* function (CSR, PHY0, PHY1, EEPROM, Flash) * function (CSR, PHY0, PHY1, EEPROM, Flash)
**/ **/
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask)
{ {
u32 gssr; u32 gssr;
u32 swmask = mask; u32 swmask = mask;
...@@ -3446,23 +3468,34 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) ...@@ -3446,23 +3468,34 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
* @buffer: contains the command to write and where the return status will * @buffer: contains the command to write and where the return status will
* be placed * be placed
* @length: length of buffer, must be multiple of 4 bytes * @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 0 * Communicates with the manageability block. On success return 0
* else return IXGBE_ERR_HOST_INTERFACE_COMMAND. * else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
**/ **/
static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
u32 length) u32 length, u32 timeout,
bool return_data)
{ {
u32 hicr, i, bi; u32 hicr, i, bi, fwsts;
u32 hdr_size = sizeof(struct ixgbe_hic_hdr); u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
u8 buf_len, dword_len; u16 buf_len, dword_len;
if (length == 0 || length & 0x3 || if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length);
hw_dbg(hw, "Buffer length failure.\n");
return IXGBE_ERR_HOST_INTERFACE_COMMAND; 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. */ /* Check that the host interface is enabled. */
hicr = IXGBE_READ_REG(hw, IXGBE_HICR); hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if ((hicr & IXGBE_HICR_EN) == 0) { if ((hicr & IXGBE_HICR_EN) == 0) {
...@@ -3470,7 +3503,12 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ...@@ -3470,7 +3503,12 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
return IXGBE_ERR_HOST_INTERFACE_COMMAND; return IXGBE_ERR_HOST_INTERFACE_COMMAND;
} }
/* Calculate length in DWORDs */ /* Calculate length in DWORDs. We must be DWORD aligned */
if ((length % (sizeof(u32))) != 0) {
hw_dbg(hw, "Buffer length failure, not aligned to dword");
return IXGBE_ERR_INVALID_ARGUMENT;
}
dword_len = length >> 2; dword_len = length >> 2;
/* /*
...@@ -3484,7 +3522,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ...@@ -3484,7 +3522,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
/* Setting this bit tells the ARC that a new command is pending. */ /* Setting this bit tells the ARC that a new command is pending. */
IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);
for (i = 0; i < IXGBE_HI_COMMAND_TIMEOUT; i++) { for (i = 0; i < timeout; i++) {
hicr = IXGBE_READ_REG(hw, IXGBE_HICR); hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if (!(hicr & IXGBE_HICR_C)) if (!(hicr & IXGBE_HICR_C))
break; break;
...@@ -3492,12 +3530,15 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ...@@ -3492,12 +3530,15 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
} }
/* Check command successful completion. */ /* Check command successful completion. */
if (i == IXGBE_HI_COMMAND_TIMEOUT || if ((timeout != 0 && i == timeout) ||
(!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) { (!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) {
hw_dbg(hw, "Command has failed with no status valid.\n"); hw_dbg(hw, "Command has failed with no status valid.\n");
return IXGBE_ERR_HOST_INTERFACE_COMMAND; return IXGBE_ERR_HOST_INTERFACE_COMMAND;
} }
if (!return_data)
return 0;
/* Calculate length in DWORDs */ /* Calculate length in DWORDs */
dword_len = hdr_size >> 2; dword_len = hdr_size >> 2;
...@@ -3568,7 +3609,9 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, ...@@ -3568,7 +3609,9 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
sizeof(fw_cmd)); sizeof(fw_cmd),
IXGBE_HI_COMMAND_TIMEOUT,
true);
if (ret_val != 0) if (ret_val != 0)
continue; continue;
......
...@@ -64,7 +64,7 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, ...@@ -64,7 +64,7 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data); u16 *data);
s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data); u16 words, u16 *data);
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw); s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
u16 *checksum_val); u16 *checksum_val);
s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
...@@ -84,8 +84,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw); ...@@ -84,8 +84,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
void ixgbe_fc_autoneg(struct ixgbe_hw *hw); void ixgbe_fc_autoneg(struct ixgbe_hw *hw);
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask); s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask);
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask); void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask);
s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr); s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr);
s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq); s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq);
...@@ -110,6 +110,8 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); ...@@ -110,6 +110,8 @@ 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); s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps);
s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
u8 build, u8 ver); u8 build, u8 ver);
s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
u32 length, u32 timeout, bool return_data);
void ixgbe_clear_tx_pending(struct ixgbe_hw *hw); void ixgbe_clear_tx_pending(struct ixgbe_hw *hw);
bool ixgbe_mng_enabled(struct ixgbe_hw *hw); bool ixgbe_mng_enabled(struct ixgbe_hw *hw);
......
...@@ -2927,7 +2927,7 @@ static unsigned int ixgbe_max_channels(struct ixgbe_adapter *adapter) ...@@ -2927,7 +2927,7 @@ static unsigned int ixgbe_max_channels(struct ixgbe_adapter *adapter)
max_combined = IXGBE_MAX_FDIR_INDICES; max_combined = IXGBE_MAX_FDIR_INDICES;
} else { } else {
/* support up to 16 queues with RSS */ /* support up to 16 queues with RSS */
max_combined = IXGBE_MAX_RSS_INDICES; max_combined = ixgbe_max_rss_indices(adapter);
} }
return max_combined; return max_combined;
...@@ -2975,6 +2975,7 @@ static int ixgbe_set_channels(struct net_device *dev, ...@@ -2975,6 +2975,7 @@ static int ixgbe_set_channels(struct net_device *dev,
{ {
struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_adapter *adapter = netdev_priv(dev);
unsigned int count = ch->combined_count; unsigned int count = ch->combined_count;
u8 max_rss_indices = ixgbe_max_rss_indices(adapter);
/* verify they are not requesting separate vectors */ /* verify they are not requesting separate vectors */
if (!count || ch->rx_count || ch->tx_count) if (!count || ch->rx_count || ch->tx_count)
...@@ -2991,9 +2992,9 @@ static int ixgbe_set_channels(struct net_device *dev, ...@@ -2991,9 +2992,9 @@ static int ixgbe_set_channels(struct net_device *dev,
/* update feature limits from largest to smallest supported values */ /* update feature limits from largest to smallest supported values */
adapter->ring_feature[RING_F_FDIR].limit = count; adapter->ring_feature[RING_F_FDIR].limit = count;
/* cap RSS limit at 16 */ /* cap RSS limit */
if (count > IXGBE_MAX_RSS_INDICES) if (count > max_rss_indices)
count = IXGBE_MAX_RSS_INDICES; count = max_rss_indices;
adapter->ring_feature[RING_F_RSS].limit = count; adapter->ring_feature[RING_F_RSS].limit = count;
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
......
...@@ -49,6 +49,188 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); ...@@ -49,6 +49,188 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw); static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
/**
* ixgbe_out_i2c_byte_ack - Send I2C byte with ack
* @hw: pointer to the hardware structure
* @byte: byte to send
*
* Returns an error code on error.
**/
static s32 ixgbe_out_i2c_byte_ack(struct ixgbe_hw *hw, u8 byte)
{
s32 status;
status = ixgbe_clock_out_i2c_byte(hw, byte);
if (status)
return status;
return ixgbe_get_i2c_ack(hw);
}
/**
* ixgbe_in_i2c_byte_ack - Receive an I2C byte and send ack
* @hw: pointer to the hardware structure
* @byte: pointer to a u8 to receive the byte
*
* Returns an error code on error.
**/
static s32 ixgbe_in_i2c_byte_ack(struct ixgbe_hw *hw, u8 *byte)
{
s32 status;
status = ixgbe_clock_in_i2c_byte(hw, byte);
if (status)
return status;
/* ACK */
return ixgbe_clock_out_i2c_bit(hw, false);
}
/**
* ixgbe_ones_comp_byte_add - Perform one's complement addition
* @add1: addend 1
* @add2: addend 2
*
* Returns one's complement 8-bit sum.
**/
static u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2)
{
u16 sum = add1 + add2;
sum = (sum & 0xFF) + (sum >> 8);
return sum & 0xFF;
}
/**
* ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
* @hw: pointer to the hardware structure
* @addr: I2C bus address to read from
* @reg: I2C device register to read from
* @val: pointer to location to receive read value
*
* Returns an error code on error.
**/
s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
u16 reg, u16 *val)
{
u32 swfw_mask = hw->phy.phy_semaphore_mask;
int max_retry = 10;
int retry = 0;
u8 csum_byte;
u8 high_bits;
u8 low_bits;
u8 reg_high;
u8 csum;
reg_high = ((reg >> 7) & 0xFE) | 1; /* Indicate read combined */
csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
csum = ~csum;
do {
if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
return IXGBE_ERR_SWFW_SYNC;
ixgbe_i2c_start(hw);
/* Device Address and write indication */
if (ixgbe_out_i2c_byte_ack(hw, addr))
goto fail;
/* Write bits 14:8 */
if (ixgbe_out_i2c_byte_ack(hw, reg_high))
goto fail;
/* Write bits 7:0 */
if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
goto fail;
/* Write csum */
if (ixgbe_out_i2c_byte_ack(hw, csum))
goto fail;
/* Re-start condition */
ixgbe_i2c_start(hw);
/* Device Address and read indication */
if (ixgbe_out_i2c_byte_ack(hw, addr | 1))
goto fail;
/* Get upper bits */
if (ixgbe_in_i2c_byte_ack(hw, &high_bits))
goto fail;
/* Get low bits */
if (ixgbe_in_i2c_byte_ack(hw, &low_bits))
goto fail;
/* Get csum */
if (ixgbe_clock_in_i2c_byte(hw, &csum_byte))
goto fail;
/* NACK */
if (ixgbe_clock_out_i2c_bit(hw, false))
goto fail;
ixgbe_i2c_stop(hw);
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
*val = (high_bits << 8) | low_bits;
return 0;
fail:
ixgbe_i2c_bus_clear(hw);
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
retry++;
if (retry < max_retry)
hw_dbg(hw, "I2C byte read combined error - Retry.\n");
else
hw_dbg(hw, "I2C byte read combined error.\n");
} while (retry < max_retry);
return IXGBE_ERR_I2C;
}
/**
* ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
* @hw: pointer to the hardware structure
* @addr: I2C bus address to write to
* @reg: I2C device register to write to
* @val: value to write
*
* Returns an error code on error.
**/
s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
u8 addr, u16 reg, u16 val)
{
int max_retry = 1;
int retry = 0;
u8 reg_high;
u8 csum;
reg_high = (reg >> 7) & 0xFE; /* Indicate write combined */
csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
csum = ixgbe_ones_comp_byte_add(csum, val >> 8);
csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF);
csum = ~csum;
do {
ixgbe_i2c_start(hw);
/* Device Address and write indication */
if (ixgbe_out_i2c_byte_ack(hw, addr))
goto fail;
/* Write bits 14:8 */
if (ixgbe_out_i2c_byte_ack(hw, reg_high))
goto fail;
/* Write bits 7:0 */
if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF))
goto fail;
/* Write data 15:8 */
if (ixgbe_out_i2c_byte_ack(hw, val >> 8))
goto fail;
/* Write data 7:0 */
if (ixgbe_out_i2c_byte_ack(hw, val & 0xFF))
goto fail;
/* Write csum */
if (ixgbe_out_i2c_byte_ack(hw, csum))
goto fail;
ixgbe_i2c_stop(hw);
return 0;
fail:
ixgbe_i2c_bus_clear(hw);
retry++;
if (retry < max_retry)
hw_dbg(hw, "I2C byte write combined error - Retry.\n");
else
hw_dbg(hw, "I2C byte write combined error.\n");
} while (retry < max_retry);
return IXGBE_ERR_I2C;
}
/** /**
* ixgbe_identify_phy_generic - Get physical layer module * ixgbe_identify_phy_generic - Get physical layer module
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -60,6 +242,15 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) ...@@ -60,6 +242,15 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
u32 phy_addr; u32 phy_addr;
u16 ext_ability = 0; u16 ext_ability = 0;
if (!hw->phy.phy_semaphore_mask) {
hw->phy.lan_id = IXGBE_READ_REG(hw, IXGBE_STATUS) &
IXGBE_STATUS_LAN_ID_1;
if (hw->phy.lan_id)
hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
else
hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
}
if (hw->phy.type == ixgbe_phy_unknown) { if (hw->phy.type == ixgbe_phy_unknown) {
for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
hw->phy.mdio.prtad = phy_addr; hw->phy.mdio.prtad = phy_addr;
...@@ -315,12 +506,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, ...@@ -315,12 +506,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
u32 device_type, u16 *phy_data) u32 device_type, u16 *phy_data)
{ {
s32 status; s32 status;
u16 gssr; u32 gssr = hw->phy.phy_semaphore_mask;
if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
gssr = IXGBE_GSSR_PHY1_SM;
else
gssr = IXGBE_GSSR_PHY0_SM;
if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == 0) { if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == 0) {
status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type, status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type,
...@@ -418,7 +604,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, ...@@ -418,7 +604,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
u32 device_type, u16 phy_data) u32 device_type, u16 phy_data)
{ {
s32 status; s32 status;
u16 gssr; u32 gssr;
if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
gssr = IXGBE_GSSR_PHY1_SM; gssr = IXGBE_GSSR_PHY1_SM;
...@@ -1469,15 +1655,10 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, ...@@ -1469,15 +1655,10 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
s32 status; s32 status;
u32 max_retry = 10; u32 max_retry = 10;
u32 retry = 0; u32 retry = 0;
u16 swfw_mask = 0; u32 swfw_mask = hw->phy.phy_semaphore_mask;
bool nack = true; bool nack = true;
*data = 0; *data = 0;
if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
swfw_mask = IXGBE_GSSR_PHY1_SM;
else
swfw_mask = IXGBE_GSSR_PHY0_SM;
do { do {
if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
return IXGBE_ERR_SWFW_SYNC; return IXGBE_ERR_SWFW_SYNC;
...@@ -1555,12 +1736,7 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, ...@@ -1555,12 +1736,7 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
s32 status; s32 status;
u32 max_retry = 1; u32 max_retry = 1;
u32 retry = 0; u32 retry = 0;
u16 swfw_mask = 0; u32 swfw_mask = hw->phy.phy_semaphore_mask;
if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
swfw_mask = IXGBE_GSSR_PHY1_SM;
else
swfw_mask = IXGBE_GSSR_PHY0_SM;
if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
return IXGBE_ERR_SWFW_SYNC; return IXGBE_ERR_SWFW_SYNC;
......
...@@ -77,6 +77,11 @@ ...@@ -77,6 +77,11 @@
#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1 #define IXGBE_I2C_EEPROM_STATUS_PASS 0x1
#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 #define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2
#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
#define IXGBE_CS4227 0xBE /* CS4227 address */
#define IXGBE_CS4227_SPARE24_LSB 0x12B0 /* Reg to program EDC */
#define IXGBE_CS4227_EDC_MODE_CX1 0x0002
#define IXGBE_CS4227_EDC_MODE_SR 0x0004
/* Flow control defines */ /* Flow control defines */
#define IXGBE_TAF_SYM_PAUSE 0x400 #define IXGBE_TAF_SYM_PAUSE 0x400
#define IXGBE_TAF_ASM_PAUSE 0x800 #define IXGBE_TAF_ASM_PAUSE 0x800
...@@ -110,7 +115,6 @@ ...@@ -110,7 +115,6 @@
/* SFP+ SFF-8472 Compliance code */ /* SFP+ SFF-8472 Compliance code */
#define IXGBE_SFF_SFF_8472_UNSUP 0x00 #define IXGBE_SFF_SFF_8472_UNSUP 0x00
s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw);
s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw); s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
...@@ -157,4 +161,8 @@ s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset, ...@@ -157,4 +161,8 @@ s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 *sff8472_data); u8 *sff8472_data);
s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 eeprom_data); u8 eeprom_data);
s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
u16 reg, u16 *val);
s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
u16 reg, u16 val);
#endif /* _IXGBE_PHY_H_ */ #endif /* _IXGBE_PHY_H_ */
...@@ -221,7 +221,8 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter) ...@@ -221,7 +221,8 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
if (adapter->ring_feature[RING_F_VMDQ].limit == 1) { if (adapter->ring_feature[RING_F_VMDQ].limit == 1) {
adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED; adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED;
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
rss = min_t(int, IXGBE_MAX_RSS_INDICES, num_online_cpus()); rss = min_t(int, ixgbe_max_rss_indices(adapter),
num_online_cpus());
} else { } else {
rss = min_t(int, IXGBE_MAX_L2A_QUEUES, num_online_cpus()); rss = min_t(int, IXGBE_MAX_L2A_QUEUES, num_online_cpus());
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "ixgbe.h" #include "ixgbe.h"
#include "ixgbe_phy.h" #include "ixgbe_phy.h"
#include "ixgbe_x540.h"
#define IXGBE_X540_MAX_TX_QUEUES 128 #define IXGBE_X540_MAX_TX_QUEUES 128
#define IXGBE_X540_MAX_RX_QUEUES 128 #define IXGBE_X540_MAX_RX_QUEUES 128
...@@ -42,17 +43,15 @@ ...@@ -42,17 +43,15 @@
static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw);
static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask);
static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask);
static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw);
static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw);
static enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
{ {
return ixgbe_media_type_copper; return ixgbe_media_type_copper;
} }
static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw) s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw)
{ {
struct ixgbe_mac_info *mac = &hw->mac; struct ixgbe_mac_info *mac = &hw->mac;
...@@ -76,8 +75,7 @@ static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw) ...@@ -76,8 +75,7 @@ static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw)
* @speed: new link speed * @speed: new link speed
* @autoneg_wait_to_complete: true when waiting for completion is needed * @autoneg_wait_to_complete: true when waiting for completion is needed
**/ **/
static s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed,
ixgbe_link_speed speed,
bool autoneg_wait_to_complete) bool autoneg_wait_to_complete)
{ {
return hw->phy.ops.setup_link_speed(hw, speed, return hw->phy.ops.setup_link_speed(hw, speed,
...@@ -92,7 +90,7 @@ static s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ...@@ -92,7 +90,7 @@ static s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
* and clears all interrupts, perform a PHY reset, and perform a link (MAC) * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
* reset. * reset.
**/ **/
static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
{ {
s32 status; s32 status;
u32 ctrl, i; u32 ctrl, i;
...@@ -179,7 +177,7 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) ...@@ -179,7 +177,7 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
* and the generation start_hw function. * and the generation start_hw function.
* Then performs revision-specific operations, if any. * Then performs revision-specific operations, if any.
**/ **/
static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
{ {
s32 ret_val; s32 ret_val;
...@@ -197,7 +195,7 @@ static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) ...@@ -197,7 +195,7 @@ static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
* Initializes the EEPROM parameters ixgbe_eeprom_info within the * Initializes the EEPROM parameters ixgbe_eeprom_info within the
* ixgbe_hw struct in order to set up EEPROM access. * ixgbe_hw struct in order to set up EEPROM access.
**/ **/
static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
{ {
struct ixgbe_eeprom_info *eeprom = &hw->eeprom; struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
u32 eec; u32 eec;
...@@ -316,7 +314,7 @@ static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, ...@@ -316,7 +314,7 @@ static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
* *
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
**/ **/
static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) static s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
{ {
u16 i; u16 i;
u16 j; u16 j;
...@@ -324,6 +322,8 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -324,6 +322,8 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
u16 length = 0; u16 length = 0;
u16 pointer = 0; u16 pointer = 0;
u16 word = 0; u16 word = 0;
u16 checksum_last_word = IXGBE_EEPROM_CHECKSUM;
u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
/* /*
* Do not use hw->eeprom.ops.read because we do not want to take * Do not use hw->eeprom.ops.read because we do not want to take
...@@ -332,10 +332,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -332,10 +332,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
*/ */
/* Include 0x0-0x3F in the checksum */ /* Include 0x0-0x3F in the checksum */
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { for (i = 0; i < checksum_last_word; i++) {
if (ixgbe_read_eerd_generic(hw, i, &word) != 0) { if (ixgbe_read_eerd_generic(hw, i, &word)) {
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "EEPROM read failed\n");
break; return IXGBE_ERR_EEPROM;
} }
checksum += word; checksum += word;
} }
...@@ -344,11 +344,11 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -344,11 +344,11 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
* Include all data from pointers 0x3, 0x6-0xE. This excludes the * Include all data from pointers 0x3, 0x6-0xE. This excludes the
* FW, PHY module, and PCIe Expansion/Option ROM pointers. * FW, PHY module, and PCIe Expansion/Option ROM pointers.
*/ */
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
continue; continue;
if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) { if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "EEPROM read failed\n");
break; break;
} }
...@@ -358,8 +358,9 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -358,8 +358,9 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
pointer >= hw->eeprom.word_size) pointer >= hw->eeprom.word_size)
continue; continue;
if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) { if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "EEPROM read failed\n");
return IXGBE_ERR_EEPROM;
break; break;
} }
...@@ -368,10 +369,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -368,10 +369,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
(pointer + length) >= hw->eeprom.word_size) (pointer + length) >= hw->eeprom.word_size)
continue; continue;
for (j = pointer+1; j <= pointer+length; j++) { for (j = pointer + 1; j <= pointer + length; j++) {
if (ixgbe_read_eerd_generic(hw, j, &word) != 0) { if (ixgbe_read_eerd_generic(hw, j, &word)) {
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "EEPROM read failed\n");
break; return IXGBE_ERR_EEPROM;
} }
checksum += word; checksum += word;
} }
...@@ -379,7 +380,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -379,7 +380,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
checksum = (u16)IXGBE_EEPROM_SUM - checksum; checksum = (u16)IXGBE_EEPROM_SUM - checksum;
return checksum; return (s32)checksum;
} }
/** /**
...@@ -410,23 +411,34 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, ...@@ -410,23 +411,34 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
return IXGBE_ERR_SWFW_SYNC; return IXGBE_ERR_SWFW_SYNC;
checksum = hw->eeprom.ops.calc_checksum(hw); status = hw->eeprom.ops.calc_checksum(hw);
if (status < 0)
goto out;
checksum = (u16)(status & 0xffff);
/* Do not use hw->eeprom.ops.read because we do not want to take /* Do not use hw->eeprom.ops.read because we do not want to take
* the synchronization semaphores twice here. * the synchronization semaphores twice here.
*/ */
status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
&read_checksum); &read_checksum);
if (status)
goto out;
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); /* Verify read checksum from EEPROM is the same as
* calculated checksum
*/
if (read_checksum != checksum) {
hw_dbg(hw, "Invalid EEPROM checksum");
status = IXGBE_ERR_EEPROM_CHECKSUM;
}
/* If the user cares, return the calculated checksum */ /* If the user cares, return the calculated checksum */
if (checksum_val) if (checksum_val)
*checksum_val = checksum; *checksum_val = checksum;
/* Verify read and calculated checksums are the same */ out:
if (read_checksum != checksum) hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return IXGBE_ERR_EEPROM_CHECKSUM;
return status; return status;
} }
...@@ -457,15 +469,22 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -457,15 +469,22 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
return IXGBE_ERR_SWFW_SYNC; return IXGBE_ERR_SWFW_SYNC;
checksum = hw->eeprom.ops.calc_checksum(hw); status = hw->eeprom.ops.calc_checksum(hw);
if (status < 0)
goto out;
checksum = (u16)(status & 0xffff);
/* Do not use hw->eeprom.ops.write because we do not want to /* Do not use hw->eeprom.ops.write because we do not want to
* take the synchronization semaphores twice here. * take the synchronization semaphores twice here.
*/ */
status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum); status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
if (!status) if (status)
goto out;
status = ixgbe_update_flash_X540(hw); status = ixgbe_update_flash_X540(hw);
out:
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status; return status;
} }
...@@ -544,7 +563,7 @@ static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) ...@@ -544,7 +563,7 @@ static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
* Acquires the SWFW semaphore thought the SW_FW_SYNC register for * Acquires the SWFW semaphore thought the SW_FW_SYNC register for
* the specified function (CSR, PHY0, PHY1, NVM, Flash) * the specified function (CSR, PHY0, PHY1, NVM, Flash)
**/ **/
static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
{ {
u32 swfw_sync; u32 swfw_sync;
u32 swmask = mask; u32 swmask = mask;
...@@ -612,7 +631,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) ...@@ -612,7 +631,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
* Releases the SWFW semaphore through the SW_FW_SYNC register * Releases the SWFW semaphore through the SW_FW_SYNC register
* for the specified function (CSR, PHY0, PHY1, EVM, Flash) * for the specified function (CSR, PHY0, PHY1, EVM, Flash)
**/ **/
static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
{ {
u32 swfw_sync; u32 swfw_sync;
u32 swmask = mask; u32 swmask = mask;
...@@ -699,7 +718,7 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) ...@@ -699,7 +718,7 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
* Devices that implement the version 2 interface: * Devices that implement the version 2 interface:
* X540 * X540
**/ **/
static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
{ {
u32 macc_reg; u32 macc_reg;
u32 ledctl_reg; u32 ledctl_reg;
...@@ -735,7 +754,7 @@ static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) ...@@ -735,7 +754,7 @@ static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
* Devices that implement the version 2 interface: * Devices that implement the version 2 interface:
* X540 * X540
**/ **/
static s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
{ {
u32 macc_reg; u32 macc_reg;
u32 ledctl_reg; u32 ledctl_reg;
......
/*******************************************************************************
*
* Intel 10 Gigabit PCI Express Linux driver
* Copyright(c) 1999 - 2014 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Contact Information:
* Linux NICS <linux.nics@intel.com>
* e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include "ixgbe_type.h"
s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw);
s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed,
bool autoneg_wait_to_complete);
s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw);
enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw);
s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed,
bool autoneg_wait_to_complete);
s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw);
This diff is collapsed.
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
/* Device IDs */ /* Device IDs */
#define IXGBE_DEV_ID_82599_VF 0x10ED #define IXGBE_DEV_ID_82599_VF 0x10ED
#define IXGBE_DEV_ID_X540_VF 0x1515 #define IXGBE_DEV_ID_X540_VF 0x1515
#define IXGBE_DEV_ID_X550_VF 0x1565
#define IXGBE_DEV_ID_X550EM_X_VF 0x15A8
#define IXGBE_VF_IRQ_CLEAR_MASK 7 #define IXGBE_VF_IRQ_CLEAR_MASK 7
#define IXGBE_VF_MAX_TX_QUEUES 8 #define IXGBE_VF_MAX_TX_QUEUES 8
......
...@@ -432,10 +432,14 @@ enum ixbgevf_state_t { ...@@ -432,10 +432,14 @@ enum ixbgevf_state_t {
enum ixgbevf_boards { enum ixgbevf_boards {
board_82599_vf, board_82599_vf,
board_X540_vf, board_X540_vf,
board_X550_vf,
board_X550EM_x_vf,
}; };
extern const struct ixgbevf_info ixgbevf_82599_vf_info; extern const struct ixgbevf_info ixgbevf_82599_vf_info;
extern const struct ixgbevf_info ixgbevf_X540_vf_info; extern const struct ixgbevf_info ixgbevf_X540_vf_info;
extern const struct ixgbevf_info ixgbevf_X550_vf_info;
extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops; extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
/* needed by ethtool.c */ /* needed by ethtool.c */
......
...@@ -66,6 +66,8 @@ static char ixgbevf_copyright[] = ...@@ -66,6 +66,8 @@ static char ixgbevf_copyright[] =
static const struct ixgbevf_info *ixgbevf_info_tbl[] = { static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
[board_82599_vf] = &ixgbevf_82599_vf_info, [board_82599_vf] = &ixgbevf_82599_vf_info,
[board_X540_vf] = &ixgbevf_X540_vf_info, [board_X540_vf] = &ixgbevf_X540_vf_info,
[board_X550_vf] = &ixgbevf_X550_vf_info,
[board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
}; };
/* ixgbevf_pci_tbl - PCI Device ID Table /* ixgbevf_pci_tbl - PCI Device ID Table
...@@ -79,6 +81,8 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = { ...@@ -79,6 +81,8 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
static const struct pci_device_id ixgbevf_pci_tbl[] = { static const struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
/* required last entry */ /* required last entry */
{0, } {0, }
}; };
...@@ -3529,7 +3533,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -3529,7 +3533,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE;
break; break;
default: default:
if (adapter->hw.mac.type == ixgbe_mac_X540_vf) if (adapter->hw.mac.type != ixgbe_mac_82599_vf)
max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE;
break; break;
} }
...@@ -3733,6 +3737,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3733,6 +3737,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ixgbe_hw *hw = NULL; struct ixgbe_hw *hw = NULL;
const struct ixgbevf_info *ii = ixgbevf_info_tbl[ent->driver_data]; const struct ixgbevf_info *ii = ixgbevf_info_tbl[ent->driver_data];
int err, pci_using_dac; int err, pci_using_dac;
bool disable_dev = false;
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
if (err) if (err)
...@@ -3767,7 +3772,6 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3767,7 +3772,6 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_NETDEV_DEV(netdev, &pdev->dev); SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);
adapter = netdev_priv(netdev); adapter = netdev_priv(netdev);
adapter->netdev = netdev; adapter->netdev = netdev;
...@@ -3856,16 +3860,28 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3856,16 +3860,28 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) if (err)
goto err_register; goto err_register;
pci_set_drvdata(pdev, netdev);
netif_carrier_off(netdev); netif_carrier_off(netdev);
ixgbevf_init_last_counter_stats(adapter); ixgbevf_init_last_counter_stats(adapter);
/* print the MAC address */ /* print the VF info */
hw_dbg(hw, "%pM\n", netdev->dev_addr); dev_info(&pdev->dev, "%pM\n", netdev->dev_addr);
dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type);
hw_dbg(hw, "MAC: %d\n", hw->mac.type); switch (hw->mac.type) {
case ixgbe_mac_X550_vf:
dev_info(&pdev->dev, "Intel(R) X550 Virtual Function\n");
break;
case ixgbe_mac_X540_vf:
dev_info(&pdev->dev, "Intel(R) X540 Virtual Function\n");
break;
case ixgbe_mac_82599_vf:
default:
dev_info(&pdev->dev, "Intel(R) 82599 Virtual Function\n");
break;
}
hw_dbg(hw, "Intel(R) 82599 Virtual Function\n");
return 0; return 0;
err_register: err_register:
...@@ -3874,12 +3890,13 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3874,12 +3890,13 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ixgbevf_reset_interrupt_capability(adapter); ixgbevf_reset_interrupt_capability(adapter);
iounmap(adapter->io_addr); iounmap(adapter->io_addr);
err_ioremap: err_ioremap:
disable_dev = !test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state);
free_netdev(netdev); free_netdev(netdev);
err_alloc_etherdev: err_alloc_etherdev:
pci_release_regions(pdev); pci_release_regions(pdev);
err_pci_reg: err_pci_reg:
err_dma: err_dma:
if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state)) if (!adapter || disable_dev)
pci_disable_device(pdev); pci_disable_device(pdev);
return err; return err;
} }
...@@ -3896,7 +3913,13 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3896,7 +3913,13 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static void ixgbevf_remove(struct pci_dev *pdev) static void ixgbevf_remove(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbevf_adapter *adapter;
bool disable_dev;
if (!netdev)
return;
adapter = netdev_priv(netdev);
set_bit(__IXGBEVF_REMOVING, &adapter->state); set_bit(__IXGBEVF_REMOVING, &adapter->state);
...@@ -3916,9 +3939,10 @@ static void ixgbevf_remove(struct pci_dev *pdev) ...@@ -3916,9 +3939,10 @@ static void ixgbevf_remove(struct pci_dev *pdev)
hw_dbg(&adapter->hw, "Remove complete\n"); hw_dbg(&adapter->hw, "Remove complete\n");
disable_dev = !test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state);
free_netdev(netdev); free_netdev(netdev);
if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state)) if (disable_dev)
pci_disable_device(pdev); pci_disable_device(pdev);
} }
......
...@@ -617,3 +617,13 @@ const struct ixgbevf_info ixgbevf_X540_vf_info = { ...@@ -617,3 +617,13 @@ const struct ixgbevf_info ixgbevf_X540_vf_info = {
.mac = ixgbe_mac_X540_vf, .mac = ixgbe_mac_X540_vf,
.mac_ops = &ixgbevf_mac_ops, .mac_ops = &ixgbevf_mac_ops,
}; };
const struct ixgbevf_info ixgbevf_X550_vf_info = {
.mac = ixgbe_mac_X550_vf,
.mac_ops = &ixgbevf_mac_ops,
};
const struct ixgbevf_info ixgbevf_X550EM_x_vf_info = {
.mac = ixgbe_mac_X550EM_x_vf,
.mac_ops = &ixgbevf_mac_ops,
};
...@@ -74,6 +74,8 @@ enum ixgbe_mac_type { ...@@ -74,6 +74,8 @@ enum ixgbe_mac_type {
ixgbe_mac_unknown = 0, ixgbe_mac_unknown = 0,
ixgbe_mac_82599_vf, ixgbe_mac_82599_vf,
ixgbe_mac_X540_vf, ixgbe_mac_X540_vf,
ixgbe_mac_X550_vf,
ixgbe_mac_X550EM_x_vf,
ixgbe_num_macs ixgbe_num_macs
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment