Commit 49eb9446 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2022-11-04 (ixgbe, ixgbevf, igb)

This series contains updates to ixgbe, ixgbevf, and igb drivers.

Daniel Willenson adjusts descriptor buffer limits to be based on what
hardware supports instead of using a generic, least common value for
ixgbe.

Ani removes local variable for ixgbe, instead returning conditional result
directly.

Yang Li removes unneeded semicolon for ixgbe.

Jan adds error messaging when VLAN errors are encountered for ixgbevf.

Kees Cook prevents a potential use after free condition and explicitly
rounds up q_vector allocations so that allocations can be correctly
compared to ksize() for igb.

* '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  igb: Proactively round up to kmalloc bucket size
  igb: Do not free q_vector unless new one was allocated
  ixgbevf: Add error messages on vlan error
  ixgbe: Remove unneeded semicolon
  ixgbe: Remove local variable
  ixgbe: change MAX_RXD/MAX_TXD based on adapter type
====================
Reviewed-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Link: https://lore.kernel.org/r/20221104205414.2354973-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents e6976148 e9d696cb
......@@ -1195,15 +1195,19 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
return -ENOMEM;
ring_count = txr_count + rxr_count;
size = struct_size(q_vector, ring, ring_count);
size = kmalloc_size_roundup(struct_size(q_vector, ring, ring_count));
/* allocate q_vector and rings */
q_vector = adapter->q_vector[v_idx];
if (!q_vector) {
q_vector = kzalloc(size, GFP_KERNEL);
} else if (size > ksize(q_vector)) {
kfree_rcu(q_vector, rcu);
q_vector = kzalloc(size, GFP_KERNEL);
struct igb_q_vector *new_q_vector;
new_q_vector = kzalloc(size, GFP_KERNEL);
if (new_q_vector)
kfree_rcu(q_vector, rcu);
q_vector = new_q_vector;
} else {
memset(q_vector, 0, size);
}
......
......@@ -39,7 +39,10 @@
/* TX/RX descriptor defines */
#define IXGBE_DEFAULT_TXD 512
#define IXGBE_DEFAULT_TX_WORK 256
#define IXGBE_MAX_TXD 4096
#define IXGBE_MAX_TXD_82598 4096
#define IXGBE_MAX_TXD_82599 8192
#define IXGBE_MAX_TXD_X540 8192
#define IXGBE_MAX_TXD_X550 32768
#define IXGBE_MIN_TXD 64
#if (PAGE_SIZE < 8192)
......@@ -47,7 +50,10 @@
#else
#define IXGBE_DEFAULT_RXD 128
#endif
#define IXGBE_MAX_RXD 4096
#define IXGBE_MAX_RXD_82598 4096
#define IXGBE_MAX_RXD_82599 8192
#define IXGBE_MAX_RXD_X540 8192
#define IXGBE_MAX_RXD_X550 32768
#define IXGBE_MIN_RXD 64
/* flow control */
......
......@@ -1117,6 +1117,42 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
drvinfo->n_priv_flags = IXGBE_PRIV_FLAGS_STR_LEN;
}
static u32 ixgbe_get_max_rxd(struct ixgbe_adapter *adapter)
{
switch (adapter->hw.mac.type) {
case ixgbe_mac_82598EB:
return IXGBE_MAX_RXD_82598;
case ixgbe_mac_82599EB:
return IXGBE_MAX_RXD_82599;
case ixgbe_mac_X540:
return IXGBE_MAX_RXD_X540;
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
return IXGBE_MAX_RXD_X550;
default:
return IXGBE_MAX_RXD_82598;
}
}
static u32 ixgbe_get_max_txd(struct ixgbe_adapter *adapter)
{
switch (adapter->hw.mac.type) {
case ixgbe_mac_82598EB:
return IXGBE_MAX_TXD_82598;
case ixgbe_mac_82599EB:
return IXGBE_MAX_TXD_82599;
case ixgbe_mac_X540:
return IXGBE_MAX_TXD_X540;
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
return IXGBE_MAX_TXD_X550;
default:
return IXGBE_MAX_TXD_82598;
}
}
static void ixgbe_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
......@@ -1126,8 +1162,8 @@ static void ixgbe_get_ringparam(struct net_device *netdev,
struct ixgbe_ring *tx_ring = adapter->tx_ring[0];
struct ixgbe_ring *rx_ring = adapter->rx_ring[0];
ring->rx_max_pending = IXGBE_MAX_RXD;
ring->tx_max_pending = IXGBE_MAX_TXD;
ring->rx_max_pending = ixgbe_get_max_rxd(adapter);
ring->tx_max_pending = ixgbe_get_max_txd(adapter);
ring->rx_pending = rx_ring->count;
ring->tx_pending = tx_ring->count;
}
......@@ -1146,11 +1182,11 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
return -EINVAL;
new_tx_count = clamp_t(u32, ring->tx_pending,
IXGBE_MIN_TXD, IXGBE_MAX_TXD);
IXGBE_MIN_TXD, ixgbe_get_max_txd(adapter));
new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE);
new_rx_count = clamp_t(u32, ring->rx_pending,
IXGBE_MIN_RXD, IXGBE_MAX_RXD);
IXGBE_MIN_RXD, ixgbe_get_max_rxd(adapter));
new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE);
if ((new_tx_count == adapter->tx_ring_count) &&
......@@ -1960,18 +1996,13 @@ static bool ixgbe_check_lbtest_frame(struct ixgbe_rx_buffer *rx_buffer,
unsigned int frame_size)
{
unsigned char *data;
bool match = true;
frame_size >>= 1;
data = page_address(rx_buffer->page) + rx_buffer->page_offset;
if (data[3] != 0xFF ||
data[frame_size + 10] != 0xBE ||
data[frame_size + 12] != 0xAF)
match = false;
return match;
return data[3] == 0xFF && data[frame_size + 10] == 0xBE &&
data[frame_size + 12] == 0xAF;
}
static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring,
......
......@@ -1302,7 +1302,7 @@ static void ixgbe_ptp_init_systime(struct ixgbe_adapter *adapter)
default:
/* Other devices aren't supported */
return;
};
}
IXGBE_WRITE_FLUSH(hw);
}
......
......@@ -2044,12 +2044,16 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev,
spin_unlock_bh(&adapter->mbx_lock);
/* translate error return types so error makes sense */
if (err == IXGBE_ERR_MBX)
return -EIO;
if (err) {
netdev_err(netdev, "VF could not set VLAN %d\n", vid);
/* translate error return types so error makes sense */
if (err == IXGBE_ERR_MBX)
return -EIO;
if (err == IXGBE_ERR_INVALID_ARGUMENT)
return -EACCES;
if (err == IXGBE_ERR_INVALID_ARGUMENT)
return -EACCES;
}
set_bit(vid, adapter->active_vlans);
......@@ -2070,6 +2074,9 @@ static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev,
spin_unlock_bh(&adapter->mbx_lock);
if (err)
netdev_err(netdev, "Could not remove VLAN %d\n", vid);
clear_bit(vid, adapter->active_vlans);
return err;
......
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