Commit 435c556c authored by David S. Miller's avatar David S. Miller

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

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2016-06-29

This series contains updates and fixes to e1000e, igb, ixgbe and fm10k.  A
true smorgasbord of changes.

Jake cleans up some obscurity by not using the BIT() macro on bitshift
operation and also fixed the calculated index when looping through the
indir array.  Fixes the issue with igb's workqueue item for overflow
check from causing a surprise remove event.  The ptp_flags variable is
added to simplify the work of writing several complex MAC type checks
in the PTP code while fixing the workqueue.

Alex Duyck fixes the receive buffers alignment which should not be L1
cache aligned, but to 512 bytes instead.

Denys Vlasenko prevents a division by zero which was reported under
VMWare for e1000e.

Amritha fixes an issue where filters in a child hash table must be
cleared from the hardware before delete the filter links in ixgbe.

Bhaktipriya Shridhar simply replaces the deprecated create_workqueue()
with alloc_workqueue() for fm10k.

Tony corrects ixgbe ethtool reporting to show x550 supports hardware
timestamping of all packets.

Emil fixes an issue where MAC-VLANs on the VF fail to pass traffic due
to spoofed packets.

Andrew Lunn increases performance on some systems where syncing a buffer
for DMA is expensive.  So rather than sync the whole 2K receive buffer,
only synchronize the length of the frame.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c435e6e0 64f2525c
...@@ -4363,7 +4363,8 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc) ...@@ -4363,7 +4363,8 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
time_delta = systim_next - systim; time_delta = systim_next - systim;
temp = time_delta; temp = time_delta;
rem = do_div(temp, incvalue); /* VMWare users have seen incvalue of zero, don't div / 0 */
rem = incvalue ? do_div(temp, incvalue) : (time_delta != 0);
systim = systim_next; systim = systim_next;
......
...@@ -406,7 +406,7 @@ static inline u16 fm10k_desc_unused(struct fm10k_ring *ring) ...@@ -406,7 +406,7 @@ static inline u16 fm10k_desc_unused(struct fm10k_ring *ring)
(&(((union fm10k_rx_desc *)((R)->desc))[i])) (&(((union fm10k_rx_desc *)((R)->desc))[i]))
#define FM10K_MAX_TXD_PWR 14 #define FM10K_MAX_TXD_PWR 14
#define FM10K_MAX_DATA_PER_TXD BIT(FM10K_MAX_TXD_PWR) #define FM10K_MAX_DATA_PER_TXD (1u << FM10K_MAX_TXD_PWR)
/* Tx Descriptors needed, worst case */ /* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), FM10K_MAX_DATA_PER_TXD) #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), FM10K_MAX_DATA_PER_TXD)
......
...@@ -983,9 +983,10 @@ void fm10k_write_reta(struct fm10k_intfc *interface, const u32 *indir) ...@@ -983,9 +983,10 @@ void fm10k_write_reta(struct fm10k_intfc *interface, const u32 *indir)
/* generate a new table if we weren't given one */ /* generate a new table if we weren't given one */
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
if (indir) if (indir)
n = indir[i + j]; n = indir[4 * i + j];
else else
n = ethtool_rxfh_indir_default(i + j, rss_i); n = ethtool_rxfh_indir_default(4 * i + j,
rss_i);
table[j] = n; table[j] = n;
} }
......
...@@ -56,7 +56,7 @@ static int __init fm10k_init_module(void) ...@@ -56,7 +56,7 @@ static int __init fm10k_init_module(void)
pr_info("%s\n", fm10k_copyright); pr_info("%s\n", fm10k_copyright);
/* create driver workqueue */ /* create driver workqueue */
fm10k_workqueue = create_workqueue("fm10k"); fm10k_workqueue = alloc_workqueue("fm10k", WQ_MEM_RECLAIM, 0);
fm10k_dbg_init(); fm10k_dbg_init();
...@@ -77,7 +77,6 @@ static void __exit fm10k_exit_module(void) ...@@ -77,7 +77,6 @@ static void __exit fm10k_exit_module(void)
fm10k_dbg_exit(); fm10k_dbg_exit();
/* destroy driver workqueue */ /* destroy driver workqueue */
flush_workqueue(fm10k_workqueue);
destroy_workqueue(fm10k_workqueue); destroy_workqueue(fm10k_workqueue);
} }
module_exit(fm10k_exit_module); module_exit(fm10k_exit_module);
...@@ -272,7 +271,7 @@ static bool fm10k_add_rx_frag(struct fm10k_rx_buffer *rx_buffer, ...@@ -272,7 +271,7 @@ static bool fm10k_add_rx_frag(struct fm10k_rx_buffer *rx_buffer,
#if (PAGE_SIZE < 8192) #if (PAGE_SIZE < 8192)
unsigned int truesize = FM10K_RX_BUFSZ; unsigned int truesize = FM10K_RX_BUFSZ;
#else #else
unsigned int truesize = SKB_DATA_ALIGN(size); unsigned int truesize = ALIGN(size, 512);
#endif #endif
unsigned int pull_len; unsigned int pull_len;
......
...@@ -445,6 +445,7 @@ struct igb_adapter { ...@@ -445,6 +445,7 @@ struct igb_adapter {
unsigned long ptp_tx_start; unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check; unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp; unsigned long last_rx_timestamp;
unsigned int ptp_flags;
spinlock_t tmreg_lock; spinlock_t tmreg_lock;
struct cyclecounter cc; struct cyclecounter cc;
struct timecounter tc; struct timecounter tc;
...@@ -474,12 +475,15 @@ struct igb_adapter { ...@@ -474,12 +475,15 @@ struct igb_adapter {
u16 eee_advert; u16 eee_advert;
}; };
/* flags controlling PTP/1588 function */
#define IGB_PTP_ENABLED BIT(0)
#define IGB_PTP_OVERFLOW_CHECK BIT(1)
#define IGB_FLAG_HAS_MSI BIT(0) #define IGB_FLAG_HAS_MSI BIT(0)
#define IGB_FLAG_DCA_ENABLED BIT(1) #define IGB_FLAG_DCA_ENABLED BIT(1)
#define IGB_FLAG_QUAD_PORT_A BIT(2) #define IGB_FLAG_QUAD_PORT_A BIT(2)
#define IGB_FLAG_QUEUE_PAIRS BIT(3) #define IGB_FLAG_QUEUE_PAIRS BIT(3)
#define IGB_FLAG_DMAC BIT(4) #define IGB_FLAG_DMAC BIT(4)
#define IGB_FLAG_PTP BIT(5)
#define IGB_FLAG_RSS_FIELD_IPV4_UDP BIT(6) #define IGB_FLAG_RSS_FIELD_IPV4_UDP BIT(6)
#define IGB_FLAG_RSS_FIELD_IPV6_UDP BIT(7) #define IGB_FLAG_RSS_FIELD_IPV6_UDP BIT(7)
#define IGB_FLAG_WOL_SUPPORTED BIT(8) #define IGB_FLAG_WOL_SUPPORTED BIT(8)
...@@ -546,6 +550,7 @@ void igb_set_fw_version(struct igb_adapter *); ...@@ -546,6 +550,7 @@ void igb_set_fw_version(struct igb_adapter *);
void igb_ptp_init(struct igb_adapter *adapter); void igb_ptp_init(struct igb_adapter *adapter);
void igb_ptp_stop(struct igb_adapter *adapter); void igb_ptp_stop(struct igb_adapter *adapter);
void igb_ptp_reset(struct igb_adapter *adapter); void igb_ptp_reset(struct igb_adapter *adapter);
void igb_ptp_suspend(struct igb_adapter *adapter);
void igb_ptp_rx_hang(struct igb_adapter *adapter); void igb_ptp_rx_hang(struct igb_adapter *adapter);
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb); void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);
void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, unsigned char *va, void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, unsigned char *va,
......
...@@ -2027,6 +2027,7 @@ void igb_reset(struct igb_adapter *adapter) ...@@ -2027,6 +2027,7 @@ void igb_reset(struct igb_adapter *adapter)
wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE); wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
/* Re-enable PTP, where applicable. */ /* Re-enable PTP, where applicable. */
if (adapter->ptp_flags & IGB_PTP_ENABLED)
igb_ptp_reset(adapter); igb_ptp_reset(adapter);
igb_get_phy_info(hw); igb_get_phy_info(hw);
...@@ -6855,12 +6856,12 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer, ...@@ -6855,12 +6856,12 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
**/ **/
static bool igb_add_rx_frag(struct igb_ring *rx_ring, static bool igb_add_rx_frag(struct igb_ring *rx_ring,
struct igb_rx_buffer *rx_buffer, struct igb_rx_buffer *rx_buffer,
unsigned int size,
union e1000_adv_rx_desc *rx_desc, union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct page *page = rx_buffer->page; struct page *page = rx_buffer->page;
unsigned char *va = page_address(page) + rx_buffer->page_offset; unsigned char *va = page_address(page) + rx_buffer->page_offset;
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
#if (PAGE_SIZE < 8192) #if (PAGE_SIZE < 8192)
unsigned int truesize = IGB_RX_BUFSZ; unsigned int truesize = IGB_RX_BUFSZ;
#else #else
...@@ -6912,6 +6913,7 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring, ...@@ -6912,6 +6913,7 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
union e1000_adv_rx_desc *rx_desc, union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb) struct sk_buff *skb)
{ {
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
struct igb_rx_buffer *rx_buffer; struct igb_rx_buffer *rx_buffer;
struct page *page; struct page *page;
...@@ -6947,11 +6949,11 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring, ...@@ -6947,11 +6949,11 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
dma_sync_single_range_for_cpu(rx_ring->dev, dma_sync_single_range_for_cpu(rx_ring->dev,
rx_buffer->dma, rx_buffer->dma,
rx_buffer->page_offset, rx_buffer->page_offset,
IGB_RX_BUFSZ, size,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
/* pull page into skb */ /* pull page into skb */
if (igb_add_rx_frag(rx_ring, rx_buffer, rx_desc, skb)) { if (igb_add_rx_frag(rx_ring, rx_buffer, size, rx_desc, skb)) {
/* hand second half of page back to the ring */ /* hand second half of page back to the ring */
igb_reuse_rx_page(rx_ring, rx_buffer); igb_reuse_rx_page(rx_ring, rx_buffer);
} else { } else {
...@@ -7527,6 +7529,8 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake, ...@@ -7527,6 +7529,8 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake,
if (netif_running(netdev)) if (netif_running(netdev))
__igb_close(netdev, true); __igb_close(netdev, true);
igb_ptp_suspend(adapter);
igb_clear_interrupt_scheme(adapter); igb_clear_interrupt_scheme(adapter);
#ifdef CONFIG_PM #ifdef CONFIG_PM
......
...@@ -684,6 +684,7 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter) ...@@ -684,6 +684,7 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter)
u32 tsyncrxctl = rd32(E1000_TSYNCRXCTL); u32 tsyncrxctl = rd32(E1000_TSYNCRXCTL);
unsigned long rx_event; unsigned long rx_event;
/* Other hardware uses per-packet timestamps */
if (hw->mac.type != e1000_82576) if (hw->mac.type != e1000_82576)
return; return;
...@@ -1042,6 +1043,13 @@ int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr) ...@@ -1042,6 +1043,13 @@ int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
-EFAULT : 0; -EFAULT : 0;
} }
/**
* igb_ptp_init - Initialize PTP functionality
* @adapter: Board private structure
*
* This function is called at device probe to initialize the PTP
* functionality.
*/
void igb_ptp_init(struct igb_adapter *adapter) void igb_ptp_init(struct igb_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
...@@ -1064,8 +1072,7 @@ void igb_ptp_init(struct igb_adapter *adapter) ...@@ -1064,8 +1072,7 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->cc.mask = CYCLECOUNTER_MASK(64); adapter->cc.mask = CYCLECOUNTER_MASK(64);
adapter->cc.mult = 1; adapter->cc.mult = 1;
adapter->cc.shift = IGB_82576_TSYNC_SHIFT; adapter->cc.shift = IGB_82576_TSYNC_SHIFT;
/* Dial the nominal frequency. */ adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
wr32(E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576);
break; break;
case e1000_82580: case e1000_82580:
case e1000_i354: case e1000_i354:
...@@ -1084,8 +1091,7 @@ void igb_ptp_init(struct igb_adapter *adapter) ...@@ -1084,8 +1091,7 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580); adapter->cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580);
adapter->cc.mult = 1; adapter->cc.mult = 1;
adapter->cc.shift = 0; adapter->cc.shift = 0;
/* Enable the timer functions by clearing bit 31. */ adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK;
wr32(E1000_TSAUXC, 0x0);
break; break;
case e1000_i210: case e1000_i210:
case e1000_i211: case e1000_i211:
...@@ -1110,44 +1116,24 @@ void igb_ptp_init(struct igb_adapter *adapter) ...@@ -1110,44 +1116,24 @@ void igb_ptp_init(struct igb_adapter *adapter)
adapter->ptp_caps.settime64 = igb_ptp_settime_i210; adapter->ptp_caps.settime64 = igb_ptp_settime_i210;
adapter->ptp_caps.enable = igb_ptp_feature_enable_i210; adapter->ptp_caps.enable = igb_ptp_feature_enable_i210;
adapter->ptp_caps.verify = igb_ptp_verify_pin; adapter->ptp_caps.verify = igb_ptp_verify_pin;
/* Enable the timer functions by clearing bit 31. */
wr32(E1000_TSAUXC, 0x0);
break; break;
default: default:
adapter->ptp_clock = NULL; adapter->ptp_clock = NULL;
return; return;
} }
wrfl();
spin_lock_init(&adapter->tmreg_lock); spin_lock_init(&adapter->tmreg_lock);
INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work); INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
/* Initialize the clock and overflow work for devices that need it. */ if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK)
if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) {
struct timespec64 ts = ktime_to_timespec64(ktime_get_real());
igb_ptp_settime_i210(&adapter->ptp_caps, &ts);
} else {
timecounter_init(&adapter->tc, &adapter->cc,
ktime_to_ns(ktime_get_real()));
INIT_DELAYED_WORK(&adapter->ptp_overflow_work, INIT_DELAYED_WORK(&adapter->ptp_overflow_work,
igb_ptp_overflow_check); igb_ptp_overflow_check);
schedule_delayed_work(&adapter->ptp_overflow_work,
IGB_SYSTIM_OVERFLOW_PERIOD);
}
/* Initialize the time sync interrupts for devices that support it. */
if (hw->mac.type >= e1000_82580) {
wr32(E1000_TSIM, TSYNC_INTERRUPTS);
wr32(E1000_IMS, E1000_IMS_TS);
}
adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF; adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
igb_ptp_reset(adapter);
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
&adapter->pdev->dev); &adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) { if (IS_ERR(adapter->ptp_clock)) {
...@@ -1156,32 +1142,24 @@ void igb_ptp_init(struct igb_adapter *adapter) ...@@ -1156,32 +1142,24 @@ void igb_ptp_init(struct igb_adapter *adapter)
} else { } else {
dev_info(&adapter->pdev->dev, "added PHC on %s\n", dev_info(&adapter->pdev->dev, "added PHC on %s\n",
adapter->netdev->name); adapter->netdev->name);
adapter->flags |= IGB_FLAG_PTP; adapter->ptp_flags |= IGB_PTP_ENABLED;
} }
} }
/** /**
* igb_ptp_stop - Disable PTP device and stop the overflow check. * igb_ptp_suspend - Disable PTP work items and prepare for suspend
* @adapter: Board private structure. * @adapter: Board private structure
* *
* This function stops the PTP support and cancels the delayed work. * This function stops the overflow check work and PTP Tx timestamp work, and
**/ * will prepare the device for OS suspend.
void igb_ptp_stop(struct igb_adapter *adapter) */
void igb_ptp_suspend(struct igb_adapter *adapter)
{ {
switch (adapter->hw.mac.type) { if (!(adapter->ptp_flags & IGB_PTP_ENABLED))
case e1000_82576:
case e1000_82580:
case e1000_i354:
case e1000_i350:
cancel_delayed_work_sync(&adapter->ptp_overflow_work);
break;
case e1000_i210:
case e1000_i211:
/* No delayed work to cancel. */
break;
default:
return; return;
}
if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK)
cancel_delayed_work_sync(&adapter->ptp_overflow_work);
cancel_work_sync(&adapter->ptp_tx_work); cancel_work_sync(&adapter->ptp_tx_work);
if (adapter->ptp_tx_skb) { if (adapter->ptp_tx_skb) {
...@@ -1189,12 +1167,23 @@ void igb_ptp_stop(struct igb_adapter *adapter) ...@@ -1189,12 +1167,23 @@ void igb_ptp_stop(struct igb_adapter *adapter)
adapter->ptp_tx_skb = NULL; adapter->ptp_tx_skb = NULL;
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
} }
}
/**
* igb_ptp_stop - Disable PTP device and stop the overflow check.
* @adapter: Board private structure.
*
* This function stops the PTP support and cancels the delayed work.
**/
void igb_ptp_stop(struct igb_adapter *adapter)
{
igb_ptp_suspend(adapter);
if (adapter->ptp_clock) { if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock); ptp_clock_unregister(adapter->ptp_clock);
dev_info(&adapter->pdev->dev, "removed PHC on %s\n", dev_info(&adapter->pdev->dev, "removed PHC on %s\n",
adapter->netdev->name); adapter->netdev->name);
adapter->flags &= ~IGB_FLAG_PTP; adapter->ptp_flags &= ~IGB_PTP_ENABLED;
} }
} }
...@@ -1209,9 +1198,6 @@ void igb_ptp_reset(struct igb_adapter *adapter) ...@@ -1209,9 +1198,6 @@ void igb_ptp_reset(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
unsigned long flags; unsigned long flags;
if (!(adapter->flags & IGB_FLAG_PTP))
return;
/* reset the tstamp_config */ /* reset the tstamp_config */
igb_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); igb_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);
...@@ -1248,4 +1234,10 @@ void igb_ptp_reset(struct igb_adapter *adapter) ...@@ -1248,4 +1234,10 @@ void igb_ptp_reset(struct igb_adapter *adapter)
} }
out: out:
spin_unlock_irqrestore(&adapter->tmreg_lock, flags); spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
wrfl();
if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK)
schedule_delayed_work(&adapter->ptp_overflow_work,
IGB_SYSTIM_OVERFLOW_PERIOD);
} }
...@@ -2991,10 +2991,15 @@ static int ixgbe_get_ts_info(struct net_device *dev, ...@@ -2991,10 +2991,15 @@ static int ixgbe_get_ts_info(struct net_device *dev,
{ {
struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_adapter *adapter = netdev_priv(dev);
/* we always support timestamping disabled */
info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
switch (adapter->hw.mac.type) { switch (adapter->hw.mac.type) {
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a: case ixgbe_mac_x550em_a:
info->rx_filters |= BIT(HWTSTAMP_FILTER_ALL);
/* fallthrough */
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
info->so_timestamping = info->so_timestamping =
...@@ -3014,8 +3019,7 @@ static int ixgbe_get_ts_info(struct net_device *dev, ...@@ -3014,8 +3019,7 @@ static int ixgbe_get_ts_info(struct net_device *dev,
BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_OFF) |
BIT(HWTSTAMP_TX_ON); BIT(HWTSTAMP_TX_ON);
info->rx_filters = info->rx_filters |=
BIT(HWTSTAMP_FILTER_NONE) |
BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
BIT(HWTSTAMP_FILTER_PTP_V2_EVENT); BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
......
...@@ -8300,14 +8300,53 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) ...@@ -8300,14 +8300,53 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter, static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter,
struct tc_cls_u32_offload *cls) struct tc_cls_u32_offload *cls)
{ {
u32 hdl = cls->knode.handle;
u32 uhtid = TC_U32_USERHTID(cls->knode.handle); u32 uhtid = TC_U32_USERHTID(cls->knode.handle);
u32 loc; u32 loc = cls->knode.handle & 0xfffff;
int err; int err = 0, i, j;
struct ixgbe_jump_table *jump = NULL;
if (loc > IXGBE_MAX_HW_ENTRIES)
return -EINVAL;
if ((uhtid != 0x800) && (uhtid >= IXGBE_MAX_LINK_HANDLE)) if ((uhtid != 0x800) && (uhtid >= IXGBE_MAX_LINK_HANDLE))
return -EINVAL; return -EINVAL;
loc = cls->knode.handle & 0xfffff; /* Clear this filter in the link data it is associated with */
if (uhtid != 0x800) {
jump = adapter->jump_tables[uhtid];
if (!jump)
return -EINVAL;
if (!test_bit(loc - 1, jump->child_loc_map))
return -EINVAL;
clear_bit(loc - 1, jump->child_loc_map);
}
/* Check if the filter being deleted is a link */
for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) {
jump = adapter->jump_tables[i];
if (jump && jump->link_hdl == hdl) {
/* Delete filters in the hardware in the child hash
* table associated with this link
*/
for (j = 0; j < IXGBE_MAX_HW_ENTRIES; j++) {
if (!test_bit(j, jump->child_loc_map))
continue;
spin_lock(&adapter->fdir_perfect_lock);
err = ixgbe_update_ethtool_fdir_entry(adapter,
NULL,
j + 1);
spin_unlock(&adapter->fdir_perfect_lock);
clear_bit(j, jump->child_loc_map);
}
/* Remove resources for this link */
kfree(jump->input);
kfree(jump->mask);
kfree(jump);
adapter->jump_tables[i] = NULL;
return err;
}
}
spin_lock(&adapter->fdir_perfect_lock); spin_lock(&adapter->fdir_perfect_lock);
err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, loc); err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, loc);
...@@ -8541,6 +8580,18 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8541,6 +8580,18 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
if (!test_bit(link_uhtid - 1, &adapter->tables)) if (!test_bit(link_uhtid - 1, &adapter->tables))
return err; return err;
/* Multiple filters as links to the same hash table are not
* supported. To add a new filter with the same next header
* but different match/jump conditions, create a new hash table
* and link to it.
*/
if (adapter->jump_tables[link_uhtid] &&
(adapter->jump_tables[link_uhtid])->link_hdl) {
e_err(drv, "Link filter exists for link: %x\n",
link_uhtid);
return err;
}
for (i = 0; nexthdr[i].jump; i++) { for (i = 0; nexthdr[i].jump; i++) {
if (nexthdr[i].o != cls->knode.sel->offoff || if (nexthdr[i].o != cls->knode.sel->offoff ||
nexthdr[i].s != cls->knode.sel->offshift || nexthdr[i].s != cls->knode.sel->offshift ||
...@@ -8562,6 +8613,8 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8562,6 +8613,8 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
} }
jump->input = input; jump->input = input;
jump->mask = mask; jump->mask = mask;
jump->link_hdl = cls->knode.handle;
err = ixgbe_clsu32_build_input(input, mask, cls, err = ixgbe_clsu32_build_input(input, mask, cls,
field_ptr, &nexthdr[i]); field_ptr, &nexthdr[i]);
if (!err) { if (!err) {
...@@ -8589,6 +8642,20 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8589,6 +8642,20 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
if ((adapter->jump_tables[uhtid])->mask) if ((adapter->jump_tables[uhtid])->mask)
memcpy(mask, (adapter->jump_tables[uhtid])->mask, memcpy(mask, (adapter->jump_tables[uhtid])->mask,
sizeof(*mask)); sizeof(*mask));
/* Lookup in all child hash tables if this location is already
* filled with a filter
*/
for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) {
struct ixgbe_jump_table *link = adapter->jump_tables[i];
if (link && (test_bit(loc - 1, link->child_loc_map))) {
e_err(drv, "Filter exists in location: %x\n",
loc);
err = -EINVAL;
goto err_out;
}
}
} }
err = ixgbe_clsu32_build_input(input, mask, cls, field_ptr, NULL); err = ixgbe_clsu32_build_input(input, mask, cls, field_ptr, NULL);
if (err) if (err)
...@@ -8620,6 +8687,9 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8620,6 +8687,9 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx);
spin_unlock(&adapter->fdir_perfect_lock); spin_unlock(&adapter->fdir_perfect_lock);
if ((uhtid != 0x800) && (adapter->jump_tables[uhtid]))
set_bit(loc - 1, (adapter->jump_tables[uhtid])->child_loc_map);
kfree(mask); kfree(mask);
return err; return err;
err_out_w_lock: err_out_w_lock:
......
...@@ -42,8 +42,12 @@ struct ixgbe_jump_table { ...@@ -42,8 +42,12 @@ struct ixgbe_jump_table {
struct ixgbe_mat_field *mat; struct ixgbe_mat_field *mat;
struct ixgbe_fdir_filter *input; struct ixgbe_fdir_filter *input;
union ixgbe_atr_input *mask; union ixgbe_atr_input *mask;
u32 link_hdl;
unsigned long child_loc_map[32];
}; };
#define IXGBE_MAX_HW_ENTRIES 2045
static inline int ixgbe_mat_prgm_sip(struct ixgbe_fdir_filter *input, static inline int ixgbe_mat_prgm_sip(struct ixgbe_fdir_filter *input,
union ixgbe_atr_input *mask, union ixgbe_atr_input *mask,
u32 val, u32 m) u32 val, u32 m)
......
...@@ -954,6 +954,7 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter, ...@@ -954,6 +954,7 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
hw->mac.ops.set_mac_anti_spoofing(hw, false, vf); hw->mac.ops.set_mac_anti_spoofing(hw, false, vf);
hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
} }
} }
......
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