Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 6, 2014
2 parents d8febb7 + 0333464 commit ddd5c50
Show file tree
Hide file tree
Showing 18 changed files with 2,404 additions and 323 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ixgbe/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.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_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_dcb_82599.o ixgbe_dcb_nl.o
Expand Down
45 changes: 30 additions & 15 deletions drivers/net/ethernet/intel/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,16 +300,17 @@ enum ixgbe_ring_f_enum {
RING_F_ARRAY_SIZE /* must be last in enum set */
};

#define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_VMDQ_INDICES 64
#define IXGBE_MAX_FDIR_INDICES 63 /* based on q_vector limit */
#define IXGBE_MAX_FCOE_INDICES 8
#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1)
#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1)
#define IXGBE_MAX_L2A_QUEUES 4
#define IXGBE_BAD_L2A_QUEUE 3
#define IXGBE_MAX_MACVLANS 31
#define IXGBE_MAX_DCBMACVLANS 8
#define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_RSS_INDICES_X550 64
#define IXGBE_MAX_VMDQ_INDICES 64
#define IXGBE_MAX_FDIR_INDICES 63 /* based on q_vector limit */
#define IXGBE_MAX_FCOE_INDICES 8
#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1)
#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1)
#define IXGBE_MAX_L2A_QUEUES 4
#define IXGBE_BAD_L2A_QUEUE 3
#define IXGBE_MAX_MACVLANS 31
#define IXGBE_MAX_DCBMACVLANS 8

struct ixgbe_ring_feature {
u16 limit; /* upper limit on feature indices */
Expand Down Expand Up @@ -553,11 +554,6 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
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) \
(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
#define IXGBE_TX_DESC(R, i) \
Expand Down Expand Up @@ -769,6 +765,21 @@ struct ixgbe_adapter {
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 hlist_node fdir_node;
union ixgbe_atr_input filter;
Expand Down Expand Up @@ -804,11 +815,15 @@ enum ixgbe_boards {
board_82598,
board_82599,
board_X540,
board_X550,
board_X550EM_x,
};

extern struct ixgbe_info ixgbe_82598_info;
extern struct ixgbe_info ixgbe_82599_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
extern const struct dcbnl_rtnl_ops dcbnl_ops;
#endif
Expand Down
133 changes: 88 additions & 45 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1625,7 +1625,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
* 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)
s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
{
u16 i;
u16 j;
Expand All @@ -1636,7 +1636,7 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)

/* Include 0x0-0x3F in the checksum */
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");
break;
}
Expand All @@ -1645,24 +1645,35 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)

/* Include all data from pointers except for the fw pointer */
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
hw->eeprom.ops.read(hw, i, &pointer);
if (hw->eeprom.ops.read(hw, i, &pointer)) {
hw_dbg(hw, "EEPROM read failed\n");
return IXGBE_ERR_EEPROM;
}

/* If the pointer seems invalid */
if (pointer == 0xFFFF || pointer == 0)
continue;

/* Make sure the pointer seems valid */
if (pointer != 0xFFFF && pointer != 0) {
hw->eeprom.ops.read(hw, pointer, &length);
if (hw->eeprom.ops.read(hw, pointer, &length)) {
hw_dbg(hw, "EEPROM read failed\n");
return IXGBE_ERR_EEPROM;
}

if (length == 0xFFFF || length == 0)
continue;

if (length != 0xFFFF && length != 0) {
for (j = pointer+1; j <= pointer+length; j++) {
hw->eeprom.ops.read(hw, j, &word);
checksum += word;
}
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;

return checksum;
return (s32)checksum;
}

/**
Expand All @@ -1686,26 +1697,33 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status) {
hw_dbg(hw, "EEPROM read failed\n");
return status;
}

if (status == 0) {
checksum = hw->eeprom.ops.calc_checksum(hw);

hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
status = hw->eeprom.ops.calc_checksum(hw);
if (status < 0)
return status;

/*
* Verify read checksum from EEPROM is the same as
* calculated checksum
*/
if (read_checksum != checksum)
status = IXGBE_ERR_EEPROM_CHECKSUM;
checksum = (u16)(status & 0xffff);

/* If the user cares, return the calculated checksum */
if (checksum_val)
*checksum_val = checksum;
} else {
status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
if (status) {
hw_dbg(hw, "EEPROM read failed\n");
return status;
}

/* Verify read checksum from EEPROM is the same as
* calculated checksum
*/
if (read_checksum != checksum)
status = IXGBE_ERR_EEPROM_CHECKSUM;

/* If the user cares, return the calculated checksum */
if (checksum_val)
*checksum_val = checksum;

return status;
}

Expand All @@ -1724,15 +1742,19 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);

if (status == 0) {
checksum = hw->eeprom.ops.calc_checksum(hw);
status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
checksum);
} else {
if (status) {
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;
}

Expand Down Expand Up @@ -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
* 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 swmask = mask;
Expand Down Expand Up @@ -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
* 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 swmask = mask;
Expand Down Expand Up @@ -3446,31 +3468,47 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
* @buffer: contains the command to write and where the return status will
* be placed
* @length: length of buffer, must be multiple of 4 bytes
* @timeout: time in ms to wait for command completion
* @return_data: read and return data from the buffer (true) or not (false)
* Needed because FW structures are big endian and decoding of
* these fields can be 8 bit or 16 bit based on command. Decoding
* is not easily understood without making a table of commands.
* So we will leave this up to the caller to read back the data
* in these cases.
*
* Communicates with the manageability block. On success return 0
* else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
**/
static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
u32 length)
s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
u32 length, u32 timeout,
bool return_data)
{
u32 hicr, i, bi;
u32 hicr, i, bi, fwsts;
u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
u8 buf_len, dword_len;
u16 buf_len, dword_len;

if (length == 0 || length & 0x3 ||
length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
hw_dbg(hw, "Buffer length failure.\n");
if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length);
return IXGBE_ERR_HOST_INTERFACE_COMMAND;
}

/* Set bit 9 of FWSTS clearing FW reset indication */
fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI);

/* Check that the host interface is enabled. */
hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if ((hicr & IXGBE_HICR_EN) == 0) {
hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n");
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;

/*
Expand All @@ -3484,20 +3522,23 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
/* Setting this bit tells the ARC that a new command is pending. */
IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);

for (i = 0; i < IXGBE_HI_COMMAND_TIMEOUT; i++) {
for (i = 0; i < timeout; i++) {
hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if (!(hicr & IXGBE_HICR_C))
break;
usleep_range(1000, 2000);
}

/* Check command successful completion. */
if (i == IXGBE_HI_COMMAND_TIMEOUT ||
if ((timeout != 0 && i == timeout) ||
(!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) {
hw_dbg(hw, "Command has failed with no status valid.\n");
return IXGBE_ERR_HOST_INTERFACE_COMMAND;
}

if (!return_data)
return 0;

/* Calculate length in DWORDs */
dword_len = hdr_size >> 2;

Expand Down Expand Up @@ -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++) {
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)
continue;

Expand Down
8 changes: 5 additions & 3 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data);
s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
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,
u16 *checksum_val);
s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
Expand All @@ -84,8 +84,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
void ixgbe_fc_autoneg(struct ixgbe_hw *hw);

s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
void ixgbe_release_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, u32 mask);
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_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq);
Expand All @@ -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_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
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);
bool ixgbe_mng_enabled(struct ixgbe_hw *hw);

Expand Down
9 changes: 5 additions & 4 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -2927,7 +2927,7 @@ static unsigned int ixgbe_max_channels(struct ixgbe_adapter *adapter)
max_combined = IXGBE_MAX_FDIR_INDICES;
} else {
/* support up to 16 queues with RSS */
max_combined = IXGBE_MAX_RSS_INDICES;
max_combined = ixgbe_max_rss_indices(adapter);
}

return max_combined;
Expand Down Expand Up @@ -2975,6 +2975,7 @@ static int ixgbe_set_channels(struct net_device *dev,
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
unsigned int count = ch->combined_count;
u8 max_rss_indices = ixgbe_max_rss_indices(adapter);

/* verify they are not requesting separate vectors */
if (!count || ch->rx_count || ch->tx_count)
Expand All @@ -2991,9 +2992,9 @@ static int ixgbe_set_channels(struct net_device *dev,
/* update feature limits from largest to smallest supported values */
adapter->ring_feature[RING_F_FDIR].limit = count;

/* cap RSS limit at 16 */
if (count > IXGBE_MAX_RSS_INDICES)
count = IXGBE_MAX_RSS_INDICES;
/* cap RSS limit */
if (count > max_rss_indices)
count = max_rss_indices;
adapter->ring_feature[RING_F_RSS].limit = count;

#ifdef IXGBE_FCOE
Expand Down
Loading

0 comments on commit ddd5c50

Please sign in to comment.