aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/igb')
-rw-r--r--drivers/net/igb/e1000_82575.c33
-rw-r--r--drivers/net/igb/e1000_82575.h5
-rw-r--r--drivers/net/igb/e1000_regs.h1
-rw-r--r--drivers/net/igb/igb.h1
-rw-r--r--drivers/net/igb/igb_main.c47
5 files changed, 87 insertions, 0 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 50f6e9649845..0a2368fa6bc6 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1480,6 +1480,39 @@ out:
1480} 1480}
1481 1481
1482/** 1482/**
1483 * igb_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing
1484 * @hw: pointer to the hardware struct
1485 * @enable: state to enter, either enabled or disabled
1486 * @pf: Physical Function pool - do not set anti-spoofing for the PF
1487 *
1488 * enables/disables L2 switch anti-spoofing functionality.
1489 **/
1490void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
1491{
1492 u32 dtxswc;
1493
1494 switch (hw->mac.type) {
1495 case e1000_82576:
1496 case e1000_i350:
1497 dtxswc = rd32(E1000_DTXSWC);
1498 if (enable) {
1499 dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
1500 E1000_DTXSWC_VLAN_SPOOF_MASK);
1501 /* The PF can spoof - it has to in order to
1502 * support emulation mode NICs */
1503 dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
1504 } else {
1505 dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
1506 E1000_DTXSWC_VLAN_SPOOF_MASK);
1507 }
1508 wr32(E1000_DTXSWC, dtxswc);
1509 break;
1510 default:
1511 break;
1512 }
1513}
1514
1515/**
1483 * igb_vmdq_set_loopback_pf - enable or disable vmdq loopback 1516 * igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
1484 * @hw: pointer to the hardware struct 1517 * @hw: pointer to the hardware struct
1485 * @enable: state to enter, either enabled or disabled 1518 * @enable: state to enter, either enabled or disabled
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index cbd1e1259e4d..1d01af2472e7 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -194,6 +194,10 @@ struct e1000_adv_tx_context_desc {
194#define E1000_NVM_APME_82575 0x0400 194#define E1000_NVM_APME_82575 0x0400
195#define MAX_NUM_VFS 8 195#define MAX_NUM_VFS 8
196 196
197#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
198#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
199#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
200#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
197#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */ 201#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
198 202
199/* Easy defines for setting default pool, would normally be left a zero */ 203/* Easy defines for setting default pool, would normally be left a zero */
@@ -243,6 +247,7 @@ struct e1000_adv_tx_context_desc {
243 247
244/* RX packet buffer size defines */ 248/* RX packet buffer size defines */
245#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F 249#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
250void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int);
246void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool); 251void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
247void igb_vmdq_set_replication_pf(struct e1000_hw *, bool); 252void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
248u16 igb_rxpbs_adjust_82580(u32 data); 253u16 igb_rxpbs_adjust_82580(u32 data);
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index abb7333a1fbf..8ac83c5190d5 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -301,6 +301,7 @@
301#define E1000_VFTE 0x00C90 /* VF Transmit Enables */ 301#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
302#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */ 302#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
303#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */ 303#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
304#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */
304#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */ 305#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
305#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */ 306#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
306#define E1000_IOVTCL 0x05BBC /* IOV Control Register */ 307#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index edab9c442399..92a4ef09e55c 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -324,6 +324,7 @@ struct igb_adapter {
324 unsigned int vfs_allocated_count; 324 unsigned int vfs_allocated_count;
325 struct vf_data_storage *vf_data; 325 struct vf_data_storage *vf_data;
326 u32 rss_queues; 326 u32 rss_queues;
327 u32 wvbr;
327}; 328};
328 329
329#define IGB_FLAG_HAS_MSI (1 << 0) 330#define IGB_FLAG_HAS_MSI (1 << 0)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index a364ae69ab37..58c665b7513d 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3366,6 +3366,45 @@ static void igb_set_rx_mode(struct net_device *netdev)
3366 igb_restore_vf_multicasts(adapter); 3366 igb_restore_vf_multicasts(adapter);
3367} 3367}
3368 3368
3369static void igb_check_wvbr(struct igb_adapter *adapter)
3370{
3371 struct e1000_hw *hw = &adapter->hw;
3372 u32 wvbr = 0;
3373
3374 switch (hw->mac.type) {
3375 case e1000_82576:
3376 case e1000_i350:
3377 if (!(wvbr = rd32(E1000_WVBR)))
3378 return;
3379 break;
3380 default:
3381 break;
3382 }
3383
3384 adapter->wvbr |= wvbr;
3385}
3386
3387#define IGB_STAGGERED_QUEUE_OFFSET 8
3388
3389static void igb_spoof_check(struct igb_adapter *adapter)
3390{
3391 int j;
3392
3393 if (!adapter->wvbr)
3394 return;
3395
3396 for(j = 0; j < adapter->vfs_allocated_count; j++) {
3397 if (adapter->wvbr & (1 << j) ||
3398 adapter->wvbr & (1 << (j + IGB_STAGGERED_QUEUE_OFFSET))) {
3399 dev_warn(&adapter->pdev->dev,
3400 "Spoof event(s) detected on VF %d\n", j);
3401 adapter->wvbr &=
3402 ~((1 << j) |
3403 (1 << (j + IGB_STAGGERED_QUEUE_OFFSET)));
3404 }
3405 }
3406}
3407
3369/* Need to wait a few seconds after link up to get diagnostic information from 3408/* Need to wait a few seconds after link up to get diagnostic information from
3370 * the phy */ 3409 * the phy */
3371static void igb_update_phy_info(unsigned long data) 3410static void igb_update_phy_info(unsigned long data)
@@ -3525,6 +3564,8 @@ static void igb_watchdog_task(struct work_struct *work)
3525 wr32(E1000_ICS, E1000_ICS_RXDMT0); 3564 wr32(E1000_ICS, E1000_ICS_RXDMT0);
3526 } 3565 }
3527 3566
3567 igb_spoof_check(adapter);
3568
3528 /* Reset the timer */ 3569 /* Reset the timer */
3529 if (!test_bit(__IGB_DOWN, &adapter->state)) 3570 if (!test_bit(__IGB_DOWN, &adapter->state))
3530 mod_timer(&adapter->watchdog_timer, 3571 mod_timer(&adapter->watchdog_timer,
@@ -4521,6 +4562,10 @@ static irqreturn_t igb_msix_other(int irq, void *data)
4521 if (icr & E1000_ICR_DOUTSYNC) { 4562 if (icr & E1000_ICR_DOUTSYNC) {
4522 /* HW is reporting DMA is out of sync */ 4563 /* HW is reporting DMA is out of sync */
4523 adapter->stats.doosync++; 4564 adapter->stats.doosync++;
4565 /* The DMA Out of Sync is also indication of a spoof event
4566 * in IOV mode. Check the Wrong VM Behavior register to
4567 * see if it is really a spoof event. */
4568 igb_check_wvbr(adapter);
4524 } 4569 }
4525 4570
4526 /* Check for a mailbox event */ 4571 /* Check for a mailbox event */
@@ -6595,6 +6640,8 @@ static void igb_vmm_control(struct igb_adapter *adapter)
6595 if (adapter->vfs_allocated_count) { 6640 if (adapter->vfs_allocated_count) {
6596 igb_vmdq_set_loopback_pf(hw, true); 6641 igb_vmdq_set_loopback_pf(hw, true);
6597 igb_vmdq_set_replication_pf(hw, true); 6642 igb_vmdq_set_replication_pf(hw, true);
6643 igb_vmdq_set_anti_spoofing_pf(hw, true,
6644 adapter->vfs_allocated_count);
6598 } else { 6645 } else {
6599 igb_vmdq_set_loopback_pf(hw, false); 6646 igb_vmdq_set_loopback_pf(hw, false);
6600 igb_vmdq_set_replication_pf(hw, false); 6647 igb_vmdq_set_replication_pf(hw, false);