diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2011-03-01 11:18:33 -0500 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2011-03-05 04:04:50 -0500 |
commit | 7a8fc77b3744e26ce1249d9ccb23e356d6010679 (patch) | |
tree | 42884ba3aaab6ec157e904be4f9d98ed358bcfbd /drivers/net | |
parent | 54405cde762408b00a445466a40da4f7f33a8479 (diff) |
r8169: convert to new VLAN model.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Reviewed-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Kconfig | 9 | ||||
-rw-r--r-- | drivers/net/r8169.c | 110 |
2 files changed, 49 insertions, 70 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f4b39274308a..8d0d16f93571 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2236,15 +2236,6 @@ config R8169 | |||
2236 | To compile this driver as a module, choose M here: the module | 2236 | To compile this driver as a module, choose M here: the module |
2237 | will be called r8169. This is recommended. | 2237 | will be called r8169. This is recommended. |
2238 | 2238 | ||
2239 | config R8169_VLAN | ||
2240 | bool "VLAN support" | ||
2241 | depends on R8169 && VLAN_8021Q | ||
2242 | ---help--- | ||
2243 | Say Y here for the r8169 driver to support the functions required | ||
2244 | by the kernel 802.1Q code. | ||
2245 | |||
2246 | If in doubt, say Y. | ||
2247 | |||
2248 | config SB1250_MAC | 2239 | config SB1250_MAC |
2249 | tristate "SB1250 Gigabit Ethernet support" | 2240 | tristate "SB1250 Gigabit Ethernet support" |
2250 | depends on SIBYTE_SB1xxx_SOC | 2241 | depends on SIBYTE_SB1xxx_SOC |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index d842d00d7abd..52e20d5c8e17 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -537,9 +537,6 @@ struct rtl8169_private { | |||
537 | u16 napi_event; | 537 | u16 napi_event; |
538 | u16 intr_mask; | 538 | u16 intr_mask; |
539 | int phy_1000_ctrl_reg; | 539 | int phy_1000_ctrl_reg; |
540 | #ifdef CONFIG_R8169_VLAN | ||
541 | struct vlan_group *vlgrp; | ||
542 | #endif | ||
543 | 540 | ||
544 | struct mdio_ops { | 541 | struct mdio_ops { |
545 | void (*write)(void __iomem *, int, int); | 542 | void (*write)(void __iomem *, int, int); |
@@ -1276,8 +1273,6 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) | |||
1276 | return 0; | 1273 | return 0; |
1277 | } | 1274 | } |
1278 | 1275 | ||
1279 | #ifdef CONFIG_R8169_VLAN | ||
1280 | |||
1281 | static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, | 1276 | static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, |
1282 | struct sk_buff *skb) | 1277 | struct sk_buff *skb) |
1283 | { | 1278 | { |
@@ -1285,64 +1280,37 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, | |||
1285 | TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; | 1280 | TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; |
1286 | } | 1281 | } |
1287 | 1282 | ||
1288 | static void rtl8169_vlan_rx_register(struct net_device *dev, | 1283 | #define NETIF_F_HW_VLAN_TX_RX (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX) |
1289 | struct vlan_group *grp) | 1284 | |
1285 | static void rtl8169_vlan_mode(struct net_device *dev) | ||
1290 | { | 1286 | { |
1291 | struct rtl8169_private *tp = netdev_priv(dev); | 1287 | struct rtl8169_private *tp = netdev_priv(dev); |
1292 | void __iomem *ioaddr = tp->mmio_addr; | 1288 | void __iomem *ioaddr = tp->mmio_addr; |
1293 | unsigned long flags; | 1289 | unsigned long flags; |
1294 | 1290 | ||
1295 | spin_lock_irqsave(&tp->lock, flags); | 1291 | spin_lock_irqsave(&tp->lock, flags); |
1296 | tp->vlgrp = grp; | 1292 | if (dev->features & NETIF_F_HW_VLAN_RX) |
1297 | /* | ||
1298 | * Do not disable RxVlan on 8110SCd. | ||
1299 | */ | ||
1300 | if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05)) | ||
1301 | tp->cp_cmd |= RxVlan; | 1293 | tp->cp_cmd |= RxVlan; |
1302 | else | 1294 | else |
1303 | tp->cp_cmd &= ~RxVlan; | 1295 | tp->cp_cmd &= ~RxVlan; |
1304 | RTL_W16(CPlusCmd, tp->cp_cmd); | 1296 | RTL_W16(CPlusCmd, tp->cp_cmd); |
1297 | /* PCI commit */ | ||
1305 | RTL_R16(CPlusCmd); | 1298 | RTL_R16(CPlusCmd); |
1306 | spin_unlock_irqrestore(&tp->lock, flags); | 1299 | spin_unlock_irqrestore(&tp->lock, flags); |
1300 | |||
1301 | dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX; | ||
1307 | } | 1302 | } |
1308 | 1303 | ||
1309 | static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, | 1304 | static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) |
1310 | struct sk_buff *skb, int polling) | ||
1311 | { | 1305 | { |
1312 | u32 opts2 = le32_to_cpu(desc->opts2); | 1306 | u32 opts2 = le32_to_cpu(desc->opts2); |
1313 | struct vlan_group *vlgrp = tp->vlgrp; | ||
1314 | int ret; | ||
1315 | 1307 | ||
1316 | if (vlgrp && (opts2 & RxVlanTag)) { | 1308 | if (opts2 & RxVlanTag) |
1317 | u16 vtag = swab16(opts2 & 0xffff); | 1309 | __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); |
1318 | 1310 | ||
1319 | if (likely(polling)) | ||
1320 | vlan_gro_receive(&tp->napi, vlgrp, vtag, skb); | ||
1321 | else | ||
1322 | __vlan_hwaccel_rx(skb, vlgrp, vtag, polling); | ||
1323 | ret = 0; | ||
1324 | } else | ||
1325 | ret = -1; | ||
1326 | desc->opts2 = 0; | 1311 | desc->opts2 = 0; |
1327 | return ret; | ||
1328 | } | ||
1329 | |||
1330 | #else /* !CONFIG_R8169_VLAN */ | ||
1331 | |||
1332 | static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, | ||
1333 | struct sk_buff *skb) | ||
1334 | { | ||
1335 | return 0; | ||
1336 | } | ||
1337 | |||
1338 | static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, | ||
1339 | struct sk_buff *skb, int polling) | ||
1340 | { | ||
1341 | return -1; | ||
1342 | } | 1312 | } |
1343 | 1313 | ||
1344 | #endif | ||
1345 | |||
1346 | static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) | 1314 | static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) |
1347 | { | 1315 | { |
1348 | struct rtl8169_private *tp = netdev_priv(dev); | 1316 | struct rtl8169_private *tp = netdev_priv(dev); |
@@ -1513,6 +1481,28 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) | |||
1513 | } | 1481 | } |
1514 | } | 1482 | } |
1515 | 1483 | ||
1484 | static int rtl8169_set_flags(struct net_device *dev, u32 data) | ||
1485 | { | ||
1486 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1487 | unsigned long old_feat = dev->features; | ||
1488 | int rc; | ||
1489 | |||
1490 | if ((tp->mac_version == RTL_GIGA_MAC_VER_05) && | ||
1491 | !(data & ETH_FLAG_RXVLAN)) { | ||
1492 | netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n"); | ||
1493 | return -EINVAL; | ||
1494 | } | ||
1495 | |||
1496 | rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN); | ||
1497 | if (rc) | ||
1498 | return rc; | ||
1499 | |||
1500 | if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) | ||
1501 | rtl8169_vlan_mode(dev); | ||
1502 | |||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1516 | static const struct ethtool_ops rtl8169_ethtool_ops = { | 1506 | static const struct ethtool_ops rtl8169_ethtool_ops = { |
1517 | .get_drvinfo = rtl8169_get_drvinfo, | 1507 | .get_drvinfo = rtl8169_get_drvinfo, |
1518 | .get_regs_len = rtl8169_get_regs_len, | 1508 | .get_regs_len = rtl8169_get_regs_len, |
@@ -1532,6 +1522,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { | |||
1532 | .get_strings = rtl8169_get_strings, | 1522 | .get_strings = rtl8169_get_strings, |
1533 | .get_sset_count = rtl8169_get_sset_count, | 1523 | .get_sset_count = rtl8169_get_sset_count, |
1534 | .get_ethtool_stats = rtl8169_get_ethtool_stats, | 1524 | .get_ethtool_stats = rtl8169_get_ethtool_stats, |
1525 | .set_flags = rtl8169_set_flags, | ||
1526 | .get_flags = ethtool_op_get_flags, | ||
1535 | }; | 1527 | }; |
1536 | 1528 | ||
1537 | static void rtl8169_get_mac_version(struct rtl8169_private *tp, | 1529 | static void rtl8169_get_mac_version(struct rtl8169_private *tp, |
@@ -2849,9 +2841,6 @@ static const struct net_device_ops rtl8169_netdev_ops = { | |||
2849 | .ndo_set_mac_address = rtl_set_mac_address, | 2841 | .ndo_set_mac_address = rtl_set_mac_address, |
2850 | .ndo_do_ioctl = rtl8169_ioctl, | 2842 | .ndo_do_ioctl = rtl8169_ioctl, |
2851 | .ndo_set_multicast_list = rtl_set_rx_mode, | 2843 | .ndo_set_multicast_list = rtl_set_rx_mode, |
2852 | #ifdef CONFIG_R8169_VLAN | ||
2853 | .ndo_vlan_rx_register = rtl8169_vlan_rx_register, | ||
2854 | #endif | ||
2855 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2844 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2856 | .ndo_poll_controller = rtl8169_netpoll, | 2845 | .ndo_poll_controller = rtl8169_netpoll, |
2857 | #endif | 2846 | #endif |
@@ -3145,6 +3134,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3145 | /* Identify chip attached to board */ | 3134 | /* Identify chip attached to board */ |
3146 | rtl8169_get_mac_version(tp, ioaddr); | 3135 | rtl8169_get_mac_version(tp, ioaddr); |
3147 | 3136 | ||
3137 | /* | ||
3138 | * Pretend we are using VLANs; This bypasses a nasty bug where | ||
3139 | * Interrupts stop flowing on high load on 8110SCd controllers. | ||
3140 | */ | ||
3141 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) | ||
3142 | tp->cp_cmd |= RxVlan; | ||
3143 | |||
3148 | rtl_init_mdio_ops(tp); | 3144 | rtl_init_mdio_ops(tp); |
3149 | rtl_init_pll_power_ops(tp); | 3145 | rtl_init_pll_power_ops(tp); |
3150 | 3146 | ||
@@ -3213,10 +3209,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3213 | 3209 | ||
3214 | netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT); | 3210 | netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT); |
3215 | 3211 | ||
3216 | #ifdef CONFIG_R8169_VLAN | 3212 | dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO; |
3217 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
3218 | #endif | ||
3219 | dev->features |= NETIF_F_GRO; | ||
3220 | 3213 | ||
3221 | tp->intr_mask = 0xffff; | 3214 | tp->intr_mask = 0xffff; |
3222 | tp->hw_start = cfg->hw_start; | 3215 | tp->hw_start = cfg->hw_start; |
@@ -3334,12 +3327,7 @@ static int rtl8169_open(struct net_device *dev) | |||
3334 | 3327 | ||
3335 | rtl8169_init_phy(dev, tp); | 3328 | rtl8169_init_phy(dev, tp); |
3336 | 3329 | ||
3337 | /* | 3330 | rtl8169_vlan_mode(dev); |
3338 | * Pretend we are using VLANs; This bypasses a nasty bug where | ||
3339 | * Interrupts stop flowing on high load on 8110SCd controllers. | ||
3340 | */ | ||
3341 | if (tp->mac_version == RTL_GIGA_MAC_VER_05) | ||
3342 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan); | ||
3343 | 3331 | ||
3344 | rtl_pll_power_up(tp); | 3332 | rtl_pll_power_up(tp); |
3345 | 3333 | ||
@@ -4689,12 +4677,12 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | |||
4689 | skb_put(skb, pkt_size); | 4677 | skb_put(skb, pkt_size); |
4690 | skb->protocol = eth_type_trans(skb, dev); | 4678 | skb->protocol = eth_type_trans(skb, dev); |
4691 | 4679 | ||
4692 | if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) { | 4680 | rtl8169_rx_vlan_tag(desc, skb); |
4693 | if (likely(polling)) | 4681 | |
4694 | napi_gro_receive(&tp->napi, skb); | 4682 | if (likely(polling)) |
4695 | else | 4683 | napi_gro_receive(&tp->napi, skb); |
4696 | netif_rx(skb); | 4684 | else |
4697 | } | 4685 | netif_rx(skb); |
4698 | 4686 | ||
4699 | dev->stats.rx_bytes += pkt_size; | 4687 | dev->stats.rx_bytes += pkt_size; |
4700 | dev->stats.rx_packets++; | 4688 | dev->stats.rx_packets++; |