Commit 6a8fab17 authored by David S. Miller's avatar David S. Miller

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

Jeff Kirsher says:

====================
10GbE Intel Wired LAN Driver Updates 2018-07-26

This series contains updates to ixgbe and igb.

Tony fixes ixgbe to add checks to ensure jumbo frames or LRO get enabled
after an XDP program is loaded.

Shannon Nelson adds the missing security configuration registers to the
ixgbe register dump, which will help in debugging.

Christian Grönke fixes an issue in igb that occurs on SGMII based SPF
mdoules, by reverting changes from 2 previous patches.  The issue was
that initialization would fail on the fore mentioned modules because the
driver would try to reset the PHY before obtaining the PHY address of
the SGMII attached PHY.

Venkatesh Srinivas replaces wmb() with dma_wmb() for doorbell writes,
which avoids SFENCEs before the doorbell writes.

Alex cleans up and refactors ixgbe Tx/Rx shutdown to reduce time needed
to stop the device.  The code refactor allows us to take the completion
time into account when disabling queues, so that on some platforms with
higher completion times, would not result in receive queues disabled
messages.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c921d7db 1918e937
...@@ -225,19 +225,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) ...@@ -225,19 +225,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
hw->bus.func = (rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) >> hw->bus.func = (rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) >>
E1000_STATUS_FUNC_SHIFT; E1000_STATUS_FUNC_SHIFT;
/* Make sure the PHY is in a good state. Several people have reported
* firmware leaving the PHY's page select register set to something
* other than the default of zero, which causes the PHY ID read to
* access something other than the intended register.
*/
ret_val = hw->phy.ops.reset(hw);
if (ret_val) {
hw_dbg("Error resetting the PHY.\n");
goto out;
}
/* Set phy->phy_addr and phy->id. */ /* Set phy->phy_addr and phy->id. */
igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, 0);
ret_val = igb_get_phy_id_82575(hw); ret_val = igb_get_phy_id_82575(hw);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
......
...@@ -6031,7 +6031,7 @@ static int igb_tx_map(struct igb_ring *tx_ring, ...@@ -6031,7 +6031,7 @@ static int igb_tx_map(struct igb_ring *tx_ring,
* We also need this memory barrier to make certain all of the * We also need this memory barrier to make certain all of the
* status bits have been updated before next_to_watch is written. * status bits have been updated before next_to_watch is written.
*/ */
wmb(); dma_wmb();
/* set next_to_watch value indicating a packet is present */ /* set next_to_watch value indicating a packet is present */
first->next_to_watch = tx_desc; first->next_to_watch = tx_desc;
...@@ -8531,7 +8531,7 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count) ...@@ -8531,7 +8531,7 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
* applicable for weak-ordered memory model archs, * applicable for weak-ordered memory model archs,
* such as IA-64). * such as IA-64).
*/ */
wmb(); dma_wmb();
writel(i, rx_ring->tail); writel(i, rx_ring->tail);
} }
} }
......
...@@ -855,7 +855,8 @@ void ixgbe_free_rx_resources(struct ixgbe_ring *); ...@@ -855,7 +855,8 @@ void ixgbe_free_rx_resources(struct ixgbe_ring *);
void ixgbe_free_tx_resources(struct ixgbe_ring *); void ixgbe_free_tx_resources(struct ixgbe_ring *);
void ixgbe_configure_rx_ring(struct ixgbe_adapter *, struct ixgbe_ring *); void ixgbe_configure_rx_ring(struct ixgbe_adapter *, struct ixgbe_ring *);
void ixgbe_configure_tx_ring(struct ixgbe_adapter *, struct ixgbe_ring *); void ixgbe_configure_tx_ring(struct ixgbe_adapter *, struct ixgbe_ring *);
void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter, struct ixgbe_ring *); void ixgbe_disable_rx(struct ixgbe_adapter *adapter);
void ixgbe_disable_tx(struct ixgbe_adapter *adapter);
void ixgbe_update_stats(struct ixgbe_adapter *adapter); void ixgbe_update_stats(struct ixgbe_adapter *adapter);
int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
......
...@@ -511,7 +511,7 @@ static void ixgbe_set_msglevel(struct net_device *netdev, u32 data) ...@@ -511,7 +511,7 @@ static void ixgbe_set_msglevel(struct net_device *netdev, u32 data)
static int ixgbe_get_regs_len(struct net_device *netdev) static int ixgbe_get_regs_len(struct net_device *netdev)
{ {
#define IXGBE_REGS_LEN 1139 #define IXGBE_REGS_LEN 1145
return IXGBE_REGS_LEN * sizeof(u32); return IXGBE_REGS_LEN * sizeof(u32);
} }
...@@ -874,6 +874,14 @@ static void ixgbe_get_regs(struct net_device *netdev, ...@@ -874,6 +874,14 @@ static void ixgbe_get_regs(struct net_device *netdev,
/* X540 specific DCB registers */ /* X540 specific DCB registers */
regs_buff[1137] = IXGBE_READ_REG(hw, IXGBE_RTTQCNCR); regs_buff[1137] = IXGBE_READ_REG(hw, IXGBE_RTTQCNCR);
regs_buff[1138] = IXGBE_READ_REG(hw, IXGBE_RTTQCNTG); regs_buff[1138] = IXGBE_READ_REG(hw, IXGBE_RTTQCNTG);
/* Security config registers */
regs_buff[1139] = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
regs_buff[1140] = IXGBE_READ_REG(hw, IXGBE_SECTXSTAT);
regs_buff[1141] = IXGBE_READ_REG(hw, IXGBE_SECTXBUFFAF);
regs_buff[1142] = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
regs_buff[1143] = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
regs_buff[1144] = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
} }
static int ixgbe_get_eeprom_len(struct net_device *netdev) static int ixgbe_get_eeprom_len(struct net_device *netdev)
...@@ -1690,35 +1698,17 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) ...@@ -1690,35 +1698,17 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; /* Shut down the DMA engines now so they can be reinitialized later,
struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; * since the test rings and normally used rings should overlap on
struct ixgbe_hw *hw = &adapter->hw; * queue 0 we can just use the standard disable Rx/Tx calls and they
u32 reg_ctl; * will take care of disabling the test rings for us.
*/
/* shut down the DMA engines now so they can be reinitialized later */
/* first Rx */ /* first Rx */
hw->mac.ops.disable_rx(hw); ixgbe_disable_rx(adapter);
ixgbe_disable_rx_queue(adapter, rx_ring);
/* now Tx */ /* now Tx */
reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx)); ixgbe_disable_tx(adapter);
reg_ctl &= ~IXGBE_TXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl);
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
reg_ctl &= ~IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);
break;
default:
break;
}
ixgbe_reset(adapter); ixgbe_reset(adapter);
......
...@@ -4022,38 +4022,6 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, ...@@ -4022,38 +4022,6 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
} }
} }
void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring)
{
struct ixgbe_hw *hw = &adapter->hw;
int wait_loop = IXGBE_MAX_RX_DESC_POLL;
u32 rxdctl;
u8 reg_idx = ring->reg_idx;
if (ixgbe_removed(hw->hw_addr))
return;
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
rxdctl &= ~IXGBE_RXDCTL_ENABLE;
/* write value back with RXDCTL.ENABLE bit cleared */
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
if (hw->mac.type == ixgbe_mac_82598EB &&
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
return;
/* the hardware may take up to 100us to really disable the rx queue */
do {
udelay(10);
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
} while (--wait_loop && (rxdctl & IXGBE_RXDCTL_ENABLE));
if (!wait_loop) {
e_err(drv, "RXDCTL.ENABLE on Rx queue %d not cleared within "
"the polling period\n", reg_idx);
}
}
void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring) struct ixgbe_ring *ring)
{ {
...@@ -4063,9 +4031,13 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, ...@@ -4063,9 +4031,13 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
u32 rxdctl; u32 rxdctl;
u8 reg_idx = ring->reg_idx; u8 reg_idx = ring->reg_idx;
/* disable queue to avoid issues while updating state */ /* disable queue to avoid use of these values while updating state */
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
ixgbe_disable_rx_queue(adapter, ring); rxdctl &= ~IXGBE_RXDCTL_ENABLE;
/* write value back with RXDCTL.ENABLE bit cleared */
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
IXGBE_WRITE_FLUSH(hw);
IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32))); IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32)));
IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32)); IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32));
...@@ -5633,6 +5605,212 @@ void ixgbe_up(struct ixgbe_adapter *adapter) ...@@ -5633,6 +5605,212 @@ void ixgbe_up(struct ixgbe_adapter *adapter)
ixgbe_up_complete(adapter); ixgbe_up_complete(adapter);
} }
static unsigned long ixgbe_get_completion_timeout(struct ixgbe_adapter *adapter)
{
u16 devctl2;
pcie_capability_read_word(adapter->pdev, PCI_EXP_DEVCTL2, &devctl2);
switch (devctl2 & IXGBE_PCIDEVCTRL2_TIMEO_MASK) {
case IXGBE_PCIDEVCTRL2_17_34s:
case IXGBE_PCIDEVCTRL2_4_8s:
/* For now we cap the upper limit on delay to 2 seconds
* as we end up going up to 34 seconds of delay in worst
* case timeout value.
*/
case IXGBE_PCIDEVCTRL2_1_2s:
return 2000000ul; /* 2.0 s */
case IXGBE_PCIDEVCTRL2_260_520ms:
return 520000ul; /* 520 ms */
case IXGBE_PCIDEVCTRL2_65_130ms:
return 130000ul; /* 130 ms */
case IXGBE_PCIDEVCTRL2_16_32ms:
return 32000ul; /* 32 ms */
case IXGBE_PCIDEVCTRL2_1_2ms:
return 2000ul; /* 2 ms */
case IXGBE_PCIDEVCTRL2_50_100us:
return 100ul; /* 100 us */
case IXGBE_PCIDEVCTRL2_16_32ms_def:
return 32000ul; /* 32 ms */
default:
break;
}
/* We shouldn't need to hit this path, but just in case default as
* though completion timeout is not supported and support 32ms.
*/
return 32000ul;
}
void ixgbe_disable_rx(struct ixgbe_adapter *adapter)
{
unsigned long wait_delay, delay_interval;
struct ixgbe_hw *hw = &adapter->hw;
int i, wait_loop;
u32 rxdctl;
/* disable receives */
hw->mac.ops.disable_rx(hw);
if (ixgbe_removed(hw->hw_addr))
return;
/* disable all enabled Rx queues */
for (i = 0; i < adapter->num_rx_queues; i++) {
struct ixgbe_ring *ring = adapter->rx_ring[i];
u8 reg_idx = ring->reg_idx;
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
rxdctl &= ~IXGBE_RXDCTL_ENABLE;
rxdctl |= IXGBE_RXDCTL_SWFLSH;
/* write value back with RXDCTL.ENABLE bit cleared */
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
}
/* RXDCTL.EN may not change on 82598 if link is down, so skip it */
if (hw->mac.type == ixgbe_mac_82598EB &&
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
return;
/* Determine our minimum delay interval. We will increase this value
* with each subsequent test. This way if the device returns quickly
* we should spend as little time as possible waiting, however as
* the time increases we will wait for larger periods of time.
*
* The trick here is that we increase the interval using the
* following pattern: 1x 3x 5x 7x 9x 11x 13x 15x 17x 19x. The result
* of that wait is that it totals up to 100x whatever interval we
* choose. Since our minimum wait is 100us we can just divide the
* total timeout by 100 to get our minimum delay interval.
*/
delay_interval = ixgbe_get_completion_timeout(adapter) / 100;
wait_loop = IXGBE_MAX_RX_DESC_POLL;
wait_delay = delay_interval;
while (wait_loop--) {
usleep_range(wait_delay, wait_delay + 10);
wait_delay += delay_interval * 2;
rxdctl = 0;
/* OR together the reading of all the active RXDCTL registers,
* and then test the result. We need the disable to complete
* before we start freeing the memory and invalidating the
* DMA mappings.
*/
for (i = 0; i < adapter->num_rx_queues; i++) {
struct ixgbe_ring *ring = adapter->rx_ring[i];
u8 reg_idx = ring->reg_idx;
rxdctl |= IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
}
if (!(rxdctl & IXGBE_RXDCTL_ENABLE))
return;
}
e_err(drv,
"RXDCTL.ENABLE for one or more queues not cleared within the polling period\n");
}
void ixgbe_disable_tx(struct ixgbe_adapter *adapter)
{
unsigned long wait_delay, delay_interval;
struct ixgbe_hw *hw = &adapter->hw;
int i, wait_loop;
u32 txdctl;
if (ixgbe_removed(hw->hw_addr))
return;
/* disable all enabled Tx queues */
for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *ring = adapter->tx_ring[i];
u8 reg_idx = ring->reg_idx;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
}
/* disable all enabled XDP Tx queues */
for (i = 0; i < adapter->num_xdp_queues; i++) {
struct ixgbe_ring *ring = adapter->xdp_ring[i];
u8 reg_idx = ring->reg_idx;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
}
/* If the link is not up there shouldn't be much in the way of
* pending transactions. Those that are left will be flushed out
* when the reset logic goes through the flush sequence to clean out
* the pending Tx transactions.
*/
if (!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
goto dma_engine_disable;
/* Determine our minimum delay interval. We will increase this value
* with each subsequent test. This way if the device returns quickly
* we should spend as little time as possible waiting, however as
* the time increases we will wait for larger periods of time.
*
* The trick here is that we increase the interval using the
* following pattern: 1x 3x 5x 7x 9x 11x 13x 15x 17x 19x. The result
* of that wait is that it totals up to 100x whatever interval we
* choose. Since our minimum wait is 100us we can just divide the
* total timeout by 100 to get our minimum delay interval.
*/
delay_interval = ixgbe_get_completion_timeout(adapter) / 100;
wait_loop = IXGBE_MAX_RX_DESC_POLL;
wait_delay = delay_interval;
while (wait_loop--) {
usleep_range(wait_delay, wait_delay + 10);
wait_delay += delay_interval * 2;
txdctl = 0;
/* OR together the reading of all the active TXDCTL registers,
* and then test the result. We need the disable to complete
* before we start freeing the memory and invalidating the
* DMA mappings.
*/
for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *ring = adapter->tx_ring[i];
u8 reg_idx = ring->reg_idx;
txdctl |= IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
}
for (i = 0; i < adapter->num_xdp_queues; i++) {
struct ixgbe_ring *ring = adapter->xdp_ring[i];
u8 reg_idx = ring->reg_idx;
txdctl |= IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
}
if (!(txdctl & IXGBE_TXDCTL_ENABLE))
goto dma_engine_disable;
}
e_err(drv,
"TXDCTL.ENABLE for one or more queues not cleared within the polling period\n");
dma_engine_disable:
/* Disable the Tx DMA engine on 82599 and later MAC */
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
(IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
~IXGBE_DMATXCTL_TE));
/* fall through */
default:
break;
}
}
void ixgbe_reset(struct ixgbe_adapter *adapter) void ixgbe_reset(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
...@@ -5814,24 +5992,19 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -5814,24 +5992,19 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
if (test_and_set_bit(__IXGBE_DOWN, &adapter->state)) if (test_and_set_bit(__IXGBE_DOWN, &adapter->state))
return; /* do nothing if already down */ return; /* do nothing if already down */
/* disable receives */ /* Shut off incoming Tx traffic */
hw->mac.ops.disable_rx(hw); netif_tx_stop_all_queues(netdev);
/* disable all enabled rx queues */ /* call carrier off first to avoid false dev_watchdog timeouts */
for (i = 0; i < adapter->num_rx_queues; i++) netif_carrier_off(netdev);
/* this call also flushes the previous write */ netif_tx_disable(netdev);
ixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]);
usleep_range(10000, 20000); /* Disable Rx */
ixgbe_disable_rx(adapter);
/* synchronize_sched() needed for pending XDP buffers to drain */ /* synchronize_sched() needed for pending XDP buffers to drain */
if (adapter->xdp_ring[0]) if (adapter->xdp_ring[0])
synchronize_sched(); synchronize_sched();
netif_tx_stop_all_queues(netdev);
/* call carrier off first to avoid false dev_watchdog timeouts */
netif_carrier_off(netdev);
netif_tx_disable(netdev);
ixgbe_irq_disable(adapter); ixgbe_irq_disable(adapter);
...@@ -5859,30 +6032,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -5859,30 +6032,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
} }
/* disable transmits in the hardware now that interrupts are off */ /* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) { ixgbe_disable_tx(adapter);
u8 reg_idx = adapter->tx_ring[i]->reg_idx;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
}
for (i = 0; i < adapter->num_xdp_queues; i++) {
u8 reg_idx = adapter->xdp_ring[i]->reg_idx;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
}
/* Disable the Tx DMA engine on 82599 and later MAC */
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
(IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
~IXGBE_DMATXCTL_TE));
break;
default:
break;
}
if (!pci_channel_offline(adapter->pdev)) if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter); ixgbe_reset(adapter);
...@@ -6469,6 +6619,11 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -6469,6 +6619,11 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
if (adapter->xdp_prog) {
e_warn(probe, "MTU cannot be changed while XDP program is loaded\n");
return -EPERM;
}
/* /*
* For 82599EB we cannot allow legacy VFs to enable their receive * For 82599EB we cannot allow legacy VFs to enable their receive
* paths when MTU greater than 1500 is configured. So display a * paths when MTU greater than 1500 is configured. So display a
...@@ -9407,6 +9562,11 @@ static netdev_features_t ixgbe_fix_features(struct net_device *netdev, ...@@ -9407,6 +9562,11 @@ static netdev_features_t ixgbe_fix_features(struct net_device *netdev,
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE))
features &= ~NETIF_F_LRO; features &= ~NETIF_F_LRO;
if (adapter->xdp_prog && (features & NETIF_F_LRO)) {
e_dev_err("LRO is not supported with XDP\n");
features &= ~NETIF_F_LRO;
}
return features; return features;
} }
......
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