Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

atl1c: do vlan cleanup

- unify vlan and nonvlan rx path
- kill adapter->vlgrp and atl1c_vlan_rx_register
- allow to turn on/off rx/tx vlan accel via ethtool (set_features)

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jiri Pirko and committed by
David S. Miller
46facce9 c8d9e6dd

+46 -29
-1
drivers/net/atl1c/atl1c.h
··· 555 555 struct atl1c_adapter { 556 556 struct net_device *netdev; 557 557 struct pci_dev *pdev; 558 - struct vlan_group *vlgrp; 559 558 struct napi_struct napi; 560 559 struct atl1c_hw hw; 561 560 struct atl1c_hw_stats hw_stats;
+46 -28
drivers/net/atl1c/atl1c_main.c
··· 411 411 } 412 412 } 413 413 414 - static void atl1c_vlan_rx_register(struct net_device *netdev, 415 - struct vlan_group *grp) 414 + static void __atl1c_vlan_mode(u32 features, u32 *mac_ctrl_data) 415 + { 416 + if (features & NETIF_F_HW_VLAN_RX) { 417 + /* enable VLAN tag insert/strip */ 418 + *mac_ctrl_data |= MAC_CTRL_RMV_VLAN; 419 + } else { 420 + /* disable VLAN tag insert/strip */ 421 + *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; 422 + } 423 + } 424 + 425 + static void atl1c_vlan_mode(struct net_device *netdev, u32 features) 416 426 { 417 427 struct atl1c_adapter *adapter = netdev_priv(netdev); 418 428 struct pci_dev *pdev = adapter->pdev; 419 429 u32 mac_ctrl_data = 0; 420 430 421 431 if (netif_msg_pktdata(adapter)) 422 - dev_dbg(&pdev->dev, "atl1c_vlan_rx_register\n"); 432 + dev_dbg(&pdev->dev, "atl1c_vlan_mode\n"); 423 433 424 434 atl1c_irq_disable(adapter); 425 - 426 - adapter->vlgrp = grp; 427 435 AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data); 428 - 429 - if (grp) { 430 - /* enable VLAN tag insert/strip */ 431 - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; 432 - } else { 433 - /* disable VLAN tag insert/strip */ 434 - mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; 435 - } 436 - 436 + __atl1c_vlan_mode(features, &mac_ctrl_data); 437 437 AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); 438 438 atl1c_irq_enable(adapter); 439 439 } ··· 443 443 struct pci_dev *pdev = adapter->pdev; 444 444 445 445 if (netif_msg_pktdata(adapter)) 446 - dev_dbg(&pdev->dev, "atl1c_restore_vlan !"); 447 - atl1c_vlan_rx_register(adapter->netdev, adapter->vlgrp); 446 + dev_dbg(&pdev->dev, "atl1c_restore_vlan\n"); 447 + atl1c_vlan_mode(adapter->netdev, adapter->netdev->features); 448 448 } 449 + 449 450 /* 450 451 * atl1c_set_mac - Change the Ethernet Address of the NIC 451 452 * @netdev: network interface device structure ··· 484 483 485 484 static u32 atl1c_fix_features(struct net_device *netdev, u32 features) 486 485 { 486 + /* 487 + * Since there is no support for separate rx/tx vlan accel 488 + * enable/disable make sure tx flag is always in same state as rx. 489 + */ 490 + if (features & NETIF_F_HW_VLAN_RX) 491 + features |= NETIF_F_HW_VLAN_TX; 492 + else 493 + features &= ~NETIF_F_HW_VLAN_TX; 494 + 487 495 if (netdev->mtu > MAX_TSO_FRAME_SIZE) 488 496 features &= ~(NETIF_F_TSO | NETIF_F_TSO6); 489 497 490 498 return features; 499 + } 500 + 501 + static int atl1c_set_features(struct net_device *netdev, u32 features) 502 + { 503 + u32 changed = netdev->features ^ features; 504 + 505 + if (changed & NETIF_F_HW_VLAN_RX) 506 + atl1c_vlan_mode(netdev, features); 507 + 508 + return 0; 491 509 } 492 510 493 511 /* ··· 1453 1433 mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) << 1454 1434 MAC_CTRL_PRMLEN_SHIFT); 1455 1435 1456 - if (adapter->vlgrp) 1457 - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; 1436 + __atl1c_vlan_mode(netdev->features, &mac_ctrl_data); 1458 1437 1459 1438 mac_ctrl_data |= MAC_CTRL_BC_EN; 1460 1439 if (netdev->flags & IFF_PROMISC) ··· 1897 1878 skb_put(skb, length - ETH_FCS_LEN); 1898 1879 skb->protocol = eth_type_trans(skb, netdev); 1899 1880 atl1c_rx_checksum(adapter, skb, rrs); 1900 - if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) { 1881 + if (rrs->word3 & RRS_VLAN_INS) { 1901 1882 u16 vlan; 1902 1883 1903 1884 AT_TAG_TO_VLAN(rrs->vlan_tag, vlan); 1904 1885 vlan = le16_to_cpu(vlan); 1905 - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan); 1906 - } else 1907 - netif_receive_skb(skb); 1886 + __vlan_hwaccel_put_tag(skb, vlan); 1887 + } 1888 + netif_receive_skb(skb); 1908 1889 1909 1890 (*work_done)++; 1910 1891 count++; ··· 2526 2507 /* clear phy interrupt */ 2527 2508 atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data); 2528 2509 /* Config MAC Ctrl register */ 2529 - if (adapter->vlgrp) 2530 - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; 2510 + __atl1c_vlan_mode(netdev->features, &mac_ctrl_data); 2531 2511 2532 2512 /* magic packet maybe Broadcast&multicast&Unicast frame */ 2533 2513 if (wufc & AT_WUFC_MAG) ··· 2599 2581 .ndo_stop = atl1c_close, 2600 2582 .ndo_validate_addr = eth_validate_addr, 2601 2583 .ndo_start_xmit = atl1c_xmit_frame, 2602 - .ndo_set_mac_address = atl1c_set_mac_addr, 2584 + .ndo_set_mac_address = atl1c_set_mac_addr, 2603 2585 .ndo_set_multicast_list = atl1c_set_multi, 2604 2586 .ndo_change_mtu = atl1c_change_mtu, 2605 2587 .ndo_fix_features = atl1c_fix_features, 2588 + .ndo_set_features = atl1c_set_features, 2606 2589 .ndo_do_ioctl = atl1c_ioctl, 2607 2590 .ndo_tx_timeout = atl1c_tx_timeout, 2608 2591 .ndo_get_stats = atl1c_get_stats, 2609 - .ndo_vlan_rx_register = atl1c_vlan_rx_register, 2610 2592 #ifdef CONFIG_NET_POLL_CONTROLLER 2611 2593 .ndo_poll_controller = atl1c_netpoll, 2612 2594 #endif ··· 2625 2607 /* TODO: add when ready */ 2626 2608 netdev->hw_features = NETIF_F_SG | 2627 2609 NETIF_F_HW_CSUM | 2628 - NETIF_F_HW_VLAN_TX | 2610 + NETIF_F_HW_VLAN_RX | 2629 2611 NETIF_F_TSO | 2630 2612 NETIF_F_TSO6; 2631 2613 netdev->features = netdev->hw_features | 2632 - NETIF_F_HW_VLAN_RX; 2614 + NETIF_F_HW_VLAN_TX; 2633 2615 return 0; 2634 2616 } 2635 2617