aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2010-04-14 19:04:23 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-14 19:11:34 -0400
commit5f6c01819979afbfec7e0b15fe52371b8eed87e8 (patch)
treecc8c13c6e78f001225d8c6f9a6eaa7cabb3ca666 /drivers/net
parente743d31312d00932391b123dfac3324d2b9e8c81 (diff)
ixgbe: fix bug with vlan strip in promsic mode
The ixgbe driver was setting up 82598 hardware correctly, so that when promiscuous mode was enabled hardware stripping was turned off. But on 82599 the logic to disable/enable hardware stripping is different, and the code was not updated correctly when the hardware vlan stripping was enabled as default. This change comprises the creation of two new helper functions and calling them from the right locations to disable and enable hardware stripping of vlan tags at appropriate times. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c115
1 files changed, 72 insertions, 43 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 1b1419c6a3d6..a98ff0e76e86 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2482,12 +2482,74 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
2482 hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); 2482 hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false);
2483} 2483}
2484 2484
2485/**
2486 * ixgbe_vlan_filter_disable - helper to disable hw vlan filtering
2487 * @adapter: driver data
2488 */
2489static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
2490{
2491 struct ixgbe_hw *hw = &adapter->hw;
2492 u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
2493 int i, j;
2494
2495 switch (hw->mac.type) {
2496 case ixgbe_mac_82598EB:
2497 vlnctrl &= ~(IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE);
2498 vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
2499 IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
2500 break;
2501 case ixgbe_mac_82599EB:
2502 vlnctrl &= ~IXGBE_VLNCTRL_VFE;
2503 vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
2504 IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
2505 for (i = 0; i < adapter->num_rx_queues; i++) {
2506 j = adapter->rx_ring[i]->reg_idx;
2507 vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
2508 vlnctrl &= ~IXGBE_RXDCTL_VME;
2509 IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
2510 }
2511 break;
2512 default:
2513 break;
2514 }
2515}
2516
2517/**
2518 * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
2519 * @adapter: driver data
2520 */
2521static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
2522{
2523 struct ixgbe_hw *hw = &adapter->hw;
2524 u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
2525 int i, j;
2526
2527 switch (hw->mac.type) {
2528 case ixgbe_mac_82598EB:
2529 vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
2530 vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
2531 IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
2532 break;
2533 case ixgbe_mac_82599EB:
2534 vlnctrl |= IXGBE_VLNCTRL_VFE;
2535 vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
2536 IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
2537 for (i = 0; i < adapter->num_rx_queues; i++) {
2538 j = adapter->rx_ring[i]->reg_idx;
2539 vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
2540 vlnctrl |= IXGBE_RXDCTL_VME;
2541 IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
2542 }
2543 break;
2544 default:
2545 break;
2546 }
2547}
2548
2485static void ixgbe_vlan_rx_register(struct net_device *netdev, 2549static void ixgbe_vlan_rx_register(struct net_device *netdev,
2486 struct vlan_group *grp) 2550 struct vlan_group *grp)
2487{ 2551{
2488 struct ixgbe_adapter *adapter = netdev_priv(netdev); 2552 struct ixgbe_adapter *adapter = netdev_priv(netdev);
2489 u32 ctrl;
2490 int i, j;
2491 2553
2492 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 2554 if (!test_bit(__IXGBE_DOWN, &adapter->state))
2493 ixgbe_irq_disable(adapter); 2555 ixgbe_irq_disable(adapter);
@@ -2498,25 +2560,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
2498 * still receive traffic from a DCB-enabled host even if we're 2560 * still receive traffic from a DCB-enabled host even if we're
2499 * not in DCB mode. 2561 * not in DCB mode.
2500 */ 2562 */
2501 ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL); 2563 ixgbe_vlan_filter_enable(adapter);
2502
2503 /* Disable CFI check */
2504 ctrl &= ~IXGBE_VLNCTRL_CFIEN;
2505
2506 /* enable VLAN tag stripping */
2507 if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
2508 ctrl |= IXGBE_VLNCTRL_VME;
2509 } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
2510 for (i = 0; i < adapter->num_rx_queues; i++) {
2511 u32 ctrl;
2512 j = adapter->rx_ring[i]->reg_idx;
2513 ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(j));
2514 ctrl |= IXGBE_RXDCTL_VME;
2515 IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(j), ctrl);
2516 }
2517 }
2518
2519 IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
2520 2564
2521 ixgbe_vlan_rx_add_vid(netdev, 0); 2565 ixgbe_vlan_rx_add_vid(netdev, 0);
2522 2566
@@ -2551,17 +2595,17 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
2551{ 2595{
2552 struct ixgbe_adapter *adapter = netdev_priv(netdev); 2596 struct ixgbe_adapter *adapter = netdev_priv(netdev);
2553 struct ixgbe_hw *hw = &adapter->hw; 2597 struct ixgbe_hw *hw = &adapter->hw;
2554 u32 fctrl, vlnctrl; 2598 u32 fctrl;
2555 2599
2556 /* Check for Promiscuous and All Multicast modes */ 2600 /* Check for Promiscuous and All Multicast modes */
2557 2601
2558 fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 2602 fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
2559 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
2560 2603
2561 if (netdev->flags & IFF_PROMISC) { 2604 if (netdev->flags & IFF_PROMISC) {
2562 hw->addr_ctrl.user_set_promisc = 1; 2605 hw->addr_ctrl.user_set_promisc = 1;
2563 fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); 2606 fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
2564 vlnctrl &= ~IXGBE_VLNCTRL_VFE; 2607 /* don't hardware filter vlans in promisc mode */
2608 ixgbe_vlan_filter_disable(adapter);
2565 } else { 2609 } else {
2566 if (netdev->flags & IFF_ALLMULTI) { 2610 if (netdev->flags & IFF_ALLMULTI) {
2567 fctrl |= IXGBE_FCTRL_MPE; 2611 fctrl |= IXGBE_FCTRL_MPE;
@@ -2569,12 +2613,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
2569 } else { 2613 } else {
2570 fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); 2614 fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
2571 } 2615 }
2572 vlnctrl |= IXGBE_VLNCTRL_VFE; 2616 ixgbe_vlan_filter_enable(adapter);
2573 hw->addr_ctrl.user_set_promisc = 0; 2617 hw->addr_ctrl.user_set_promisc = 0;
2574 } 2618 }
2575 2619
2576 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 2620 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
2577 IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
2578 2621
2579 /* reprogram secondary unicast list */ 2622 /* reprogram secondary unicast list */
2580 hw->mac.ops.update_uc_addr_list(hw, netdev); 2623 hw->mac.ops.update_uc_addr_list(hw, netdev);
@@ -2641,7 +2684,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
2641static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) 2684static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
2642{ 2685{
2643 struct ixgbe_hw *hw = &adapter->hw; 2686 struct ixgbe_hw *hw = &adapter->hw;
2644 u32 txdctl, vlnctrl; 2687 u32 txdctl;
2645 int i, j; 2688 int i, j;
2646 2689
2647 ixgbe_dcb_check_config(&adapter->dcb_cfg); 2690 ixgbe_dcb_check_config(&adapter->dcb_cfg);
@@ -2659,22 +2702,8 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
2659 IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); 2702 IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
2660 } 2703 }
2661 /* Enable VLAN tag insert/strip */ 2704 /* Enable VLAN tag insert/strip */
2662 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); 2705 ixgbe_vlan_filter_enable(adapter);
2663 if (hw->mac.type == ixgbe_mac_82598EB) { 2706
2664 vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
2665 vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
2666 IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
2667 } else if (hw->mac.type == ixgbe_mac_82599EB) {
2668 vlnctrl |= IXGBE_VLNCTRL_VFE;
2669 vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
2670 IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
2671 for (i = 0; i < adapter->num_rx_queues; i++) {
2672 j = adapter->rx_ring[i]->reg_idx;
2673 vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
2674 vlnctrl |= IXGBE_RXDCTL_VME;
2675 IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
2676 }
2677 }
2678 hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); 2707 hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
2679} 2708}
2680 2709