diff options
Diffstat (limited to 'drivers/net/igb')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 33 | ||||
-rw-r--r-- | drivers/net/igb/e1000_82575.h | 5 | ||||
-rw-r--r-- | drivers/net/igb/e1000_regs.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/igb.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 47 |
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 | **/ | ||
1490 | void 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 |
250 | void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int); | ||
246 | void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool); | 251 | void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool); |
247 | void igb_vmdq_set_replication_pf(struct e1000_hw *, bool); | 252 | void igb_vmdq_set_replication_pf(struct e1000_hw *, bool); |
248 | u16 igb_rxpbs_adjust_82580(u32 data); | 253 | u16 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 | ||
3369 | static 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 | |||
3389 | static 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 */ |
3371 | static void igb_update_phy_info(unsigned long data) | 3410 | static 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); |