diff options
author | hayeswang <hayeswang@realtek.com> | 2014-09-11 22:43:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-13 16:49:09 -0400 |
commit | c55542983e572bcac813fd9a393e725e158074be (patch) | |
tree | 7310679ae1e94ecfdb33a2626c7679296f869ebd | |
parent | f19f916d64e7a0af743bbfc7d1594db08c712f9f (diff) |
r8152: support VLAN
Support hw VLAN for tx and rx. And enable them by default.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/r8152.c | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 2130c757b37e..94032199800d 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -506,6 +506,7 @@ struct rx_desc { | |||
506 | #define IPF (1 << 23) /* IP checksum fail */ | 506 | #define IPF (1 << 23) /* IP checksum fail */ |
507 | #define UDPF (1 << 22) /* UDP checksum fail */ | 507 | #define UDPF (1 << 22) /* UDP checksum fail */ |
508 | #define TCPF (1 << 21) /* TCP checksum fail */ | 508 | #define TCPF (1 << 21) /* TCP checksum fail */ |
509 | #define RX_VLAN_TAG (1 << 16) | ||
509 | 510 | ||
510 | __le32 opts4; | 511 | __le32 opts4; |
511 | __le32 opts5; | 512 | __le32 opts5; |
@@ -531,6 +532,7 @@ struct tx_desc { | |||
531 | #define MSS_MAX 0x7ffU | 532 | #define MSS_MAX 0x7ffU |
532 | #define TCPHO_SHIFT 17 | 533 | #define TCPHO_SHIFT 17 |
533 | #define TCPHO_MAX 0x7ffU | 534 | #define TCPHO_MAX 0x7ffU |
535 | #define TX_VLAN_TAG (1 << 16) | ||
534 | }; | 536 | }; |
535 | 537 | ||
536 | struct r8152; | 538 | struct r8152; |
@@ -1423,6 +1425,25 @@ static int msdn_giant_send_check(struct sk_buff *skb) | |||
1423 | return ret; | 1425 | return ret; |
1424 | } | 1426 | } |
1425 | 1427 | ||
1428 | static inline void rtl_tx_vlan_tag(struct tx_desc *desc, struct sk_buff *skb) | ||
1429 | { | ||
1430 | if (vlan_tx_tag_present(skb)) { | ||
1431 | u32 opts2; | ||
1432 | |||
1433 | opts2 = TX_VLAN_TAG | swab16(vlan_tx_tag_get(skb)); | ||
1434 | desc->opts2 |= cpu_to_le32(opts2); | ||
1435 | } | ||
1436 | } | ||
1437 | |||
1438 | static inline void rtl_rx_vlan_tag(struct rx_desc *desc, struct sk_buff *skb) | ||
1439 | { | ||
1440 | u32 opts2 = le32_to_cpu(desc->opts2); | ||
1441 | |||
1442 | if (opts2 & RX_VLAN_TAG) | ||
1443 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), | ||
1444 | swab16(opts2 & 0xffff)); | ||
1445 | } | ||
1446 | |||
1426 | static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, | 1447 | static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, |
1427 | struct sk_buff *skb, u32 len, u32 transport_offset) | 1448 | struct sk_buff *skb, u32 len, u32 transport_offset) |
1428 | { | 1449 | { |
@@ -1550,6 +1571,8 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) | |||
1550 | continue; | 1571 | continue; |
1551 | } | 1572 | } |
1552 | 1573 | ||
1574 | rtl_tx_vlan_tag(tx_desc, skb); | ||
1575 | |||
1553 | tx_data += sizeof(*tx_desc); | 1576 | tx_data += sizeof(*tx_desc); |
1554 | 1577 | ||
1555 | len = skb->len; | 1578 | len = skb->len; |
@@ -1691,6 +1714,7 @@ static void rx_bottom(struct r8152 *tp) | |||
1691 | memcpy(skb->data, rx_data, pkt_len); | 1714 | memcpy(skb->data, rx_data, pkt_len); |
1692 | skb_put(skb, pkt_len); | 1715 | skb_put(skb, pkt_len); |
1693 | skb->protocol = eth_type_trans(skb, netdev); | 1716 | skb->protocol = eth_type_trans(skb, netdev); |
1717 | rtl_rx_vlan_tag(rx_desc, skb); | ||
1694 | netif_receive_skb(skb); | 1718 | netif_receive_skb(skb); |
1695 | stats->rx_packets++; | 1719 | stats->rx_packets++; |
1696 | stats->rx_bytes += pkt_len; | 1720 | stats->rx_bytes += pkt_len; |
@@ -2082,6 +2106,34 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable) | |||
2082 | ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data); | 2106 | ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data); |
2083 | } | 2107 | } |
2084 | 2108 | ||
2109 | static void rtl_rx_vlan_en(struct r8152 *tp, bool enable) | ||
2110 | { | ||
2111 | u32 ocp_data; | ||
2112 | |||
2113 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); | ||
2114 | if (enable) | ||
2115 | ocp_data |= CPCR_RX_VLAN; | ||
2116 | else | ||
2117 | ocp_data &= ~CPCR_RX_VLAN; | ||
2118 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); | ||
2119 | } | ||
2120 | |||
2121 | static int rtl8152_set_features(struct net_device *dev, | ||
2122 | netdev_features_t features) | ||
2123 | { | ||
2124 | netdev_features_t changed = features ^ dev->features; | ||
2125 | struct r8152 *tp = netdev_priv(dev); | ||
2126 | |||
2127 | if (changed & NETIF_F_HW_VLAN_CTAG_RX) { | ||
2128 | if (features & NETIF_F_HW_VLAN_CTAG_RX) | ||
2129 | rtl_rx_vlan_en(tp, true); | ||
2130 | else | ||
2131 | rtl_rx_vlan_en(tp, false); | ||
2132 | } | ||
2133 | |||
2134 | return 0; | ||
2135 | } | ||
2136 | |||
2085 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) | 2137 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) |
2086 | 2138 | ||
2087 | static u32 __rtl_get_wol(struct r8152 *tp) | 2139 | static u32 __rtl_get_wol(struct r8152 *tp) |
@@ -2330,9 +2382,7 @@ static void r8152b_exit_oob(struct r8152 *tp) | |||
2330 | ocp_write_dword(tp, MCU_TYPE_USB, USB_TX_DMA, | 2382 | ocp_write_dword(tp, MCU_TYPE_USB, USB_TX_DMA, |
2331 | TEST_MODE_DISABLE | TX_SIZE_ADJUST1); | 2383 | TEST_MODE_DISABLE | TX_SIZE_ADJUST1); |
2332 | 2384 | ||
2333 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); | 2385 | rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); |
2334 | ocp_data &= ~CPCR_RX_VLAN; | ||
2335 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); | ||
2336 | 2386 | ||
2337 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); | 2387 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); |
2338 | 2388 | ||
@@ -2376,9 +2426,7 @@ static void r8152b_enter_oob(struct r8152 *tp) | |||
2376 | 2426 | ||
2377 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); | 2427 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); |
2378 | 2428 | ||
2379 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); | 2429 | rtl_rx_vlan_en(tp, true); |
2380 | ocp_data |= CPCR_RX_VLAN; | ||
2381 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); | ||
2382 | 2430 | ||
2383 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); | 2431 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); |
2384 | ocp_data |= ALDPS_PROXY_MODE; | 2432 | ocp_data |= ALDPS_PROXY_MODE; |
@@ -2532,9 +2580,7 @@ static void r8153_first_init(struct r8152 *tp) | |||
2532 | usleep_range(1000, 2000); | 2580 | usleep_range(1000, 2000); |
2533 | } | 2581 | } |
2534 | 2582 | ||
2535 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); | 2583 | rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); |
2536 | ocp_data &= ~CPCR_RX_VLAN; | ||
2537 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); | ||
2538 | 2584 | ||
2539 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS); | 2585 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS); |
2540 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); | 2586 | ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); |
@@ -2593,9 +2639,7 @@ static void r8153_enter_oob(struct r8152 *tp) | |||
2593 | ocp_data &= ~TEREDO_WAKE_MASK; | 2639 | ocp_data &= ~TEREDO_WAKE_MASK; |
2594 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data); | 2640 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data); |
2595 | 2641 | ||
2596 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); | 2642 | rtl_rx_vlan_en(tp, true); |
2597 | ocp_data |= CPCR_RX_VLAN; | ||
2598 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); | ||
2599 | 2643 | ||
2600 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); | 2644 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); |
2601 | ocp_data |= ALDPS_PROXY_MODE; | 2645 | ocp_data |= ALDPS_PROXY_MODE; |
@@ -3330,6 +3374,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { | |||
3330 | .ndo_do_ioctl = rtl8152_ioctl, | 3374 | .ndo_do_ioctl = rtl8152_ioctl, |
3331 | .ndo_start_xmit = rtl8152_start_xmit, | 3375 | .ndo_start_xmit = rtl8152_start_xmit, |
3332 | .ndo_tx_timeout = rtl8152_tx_timeout, | 3376 | .ndo_tx_timeout = rtl8152_tx_timeout, |
3377 | .ndo_set_features = rtl8152_set_features, | ||
3333 | .ndo_set_rx_mode = rtl8152_set_rx_mode, | 3378 | .ndo_set_rx_mode = rtl8152_set_rx_mode, |
3334 | .ndo_set_mac_address = rtl8152_set_mac_address, | 3379 | .ndo_set_mac_address = rtl8152_set_mac_address, |
3335 | .ndo_change_mtu = rtl8152_change_mtu, | 3380 | .ndo_change_mtu = rtl8152_change_mtu, |
@@ -3484,10 +3529,16 @@ static int rtl8152_probe(struct usb_interface *intf, | |||
3484 | 3529 | ||
3485 | netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | | 3530 | netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | |
3486 | NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM | | 3531 | NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM | |
3487 | NETIF_F_TSO6; | 3532 | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_RX | |
3533 | NETIF_F_HW_VLAN_CTAG_TX; | ||
3488 | netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | | 3534 | netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | |
3489 | NETIF_F_TSO | NETIF_F_FRAGLIST | | 3535 | NETIF_F_TSO | NETIF_F_FRAGLIST | |
3490 | NETIF_F_IPV6_CSUM | NETIF_F_TSO6; | 3536 | NETIF_F_IPV6_CSUM | NETIF_F_TSO6 | |
3537 | NETIF_F_HW_VLAN_CTAG_RX | | ||
3538 | NETIF_F_HW_VLAN_CTAG_TX; | ||
3539 | netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | | ||
3540 | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | | ||
3541 | NETIF_F_IPV6_CSUM | NETIF_F_TSO6; | ||
3491 | 3542 | ||
3492 | netdev->ethtool_ops = &ops; | 3543 | netdev->ethtool_ops = &ops; |
3493 | netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); | 3544 | netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); |