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