diff options
-rw-r--r-- | drivers/net/sky2.c | 117 | ||||
-rw-r--r-- | drivers/net/sky2.h | 6 |
2 files changed, 52 insertions, 71 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index b56109294758..7d85a38377a1 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -46,10 +46,6 @@ | |||
46 | 46 | ||
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
50 | #define SKY2_VLAN_TAG_USED 1 | ||
51 | #endif | ||
52 | |||
53 | #include "sky2.h" | 49 | #include "sky2.h" |
54 | 50 | ||
55 | #define DRV_NAME "sky2" | 51 | #define DRV_NAME "sky2" |
@@ -1326,39 +1322,34 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1326 | return err; | 1322 | return err; |
1327 | } | 1323 | } |
1328 | 1324 | ||
1329 | #ifdef SKY2_VLAN_TAG_USED | 1325 | #define NETIF_F_ALL_VLAN (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX) |
1330 | static void sky2_set_vlan_mode(struct sky2_hw *hw, u16 port, bool onoff) | ||
1331 | { | ||
1332 | if (onoff) { | ||
1333 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | ||
1334 | RX_VLAN_STRIP_ON); | ||
1335 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
1336 | TX_VLAN_TAG_ON); | ||
1337 | } else { | ||
1338 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | ||
1339 | RX_VLAN_STRIP_OFF); | ||
1340 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
1341 | TX_VLAN_TAG_OFF); | ||
1342 | } | ||
1343 | } | ||
1344 | 1326 | ||
1345 | static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | 1327 | static void sky2_vlan_mode(struct net_device *dev) |
1346 | { | 1328 | { |
1347 | struct sky2_port *sky2 = netdev_priv(dev); | 1329 | struct sky2_port *sky2 = netdev_priv(dev); |
1348 | struct sky2_hw *hw = sky2->hw; | 1330 | struct sky2_hw *hw = sky2->hw; |
1349 | u16 port = sky2->port; | 1331 | u16 port = sky2->port; |
1350 | 1332 | ||
1351 | netif_tx_lock_bh(dev); | 1333 | if (dev->features & NETIF_F_HW_VLAN_RX) |
1352 | napi_disable(&hw->napi); | 1334 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
1335 | RX_VLAN_STRIP_ON); | ||
1336 | else | ||
1337 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | ||
1338 | RX_VLAN_STRIP_OFF); | ||
1353 | 1339 | ||
1354 | sky2->vlgrp = grp; | 1340 | dev->vlan_features = dev->features &~ NETIF_F_ALL_VLAN; |
1355 | sky2_set_vlan_mode(hw, port, grp != NULL); | 1341 | if (dev->features & NETIF_F_HW_VLAN_TX) |
1342 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
1343 | TX_VLAN_TAG_ON); | ||
1344 | else { | ||
1345 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
1346 | TX_VLAN_TAG_OFF); | ||
1356 | 1347 | ||
1357 | sky2_read32(hw, B0_Y2_SP_LISR); | 1348 | /* Can't do transmit offload of vlan without hw vlan */ |
1358 | napi_enable(&hw->napi); | 1349 | dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_SG |
1359 | netif_tx_unlock_bh(dev); | 1350 | | NETIF_F_ALL_CSUM); |
1351 | } | ||
1360 | } | 1352 | } |
1361 | #endif | ||
1362 | 1353 | ||
1363 | /* Amount of required worst case padding in rx buffer */ | 1354 | /* Amount of required worst case padding in rx buffer */ |
1364 | static inline unsigned sky2_rx_pad(const struct sky2_hw *hw) | 1355 | static inline unsigned sky2_rx_pad(const struct sky2_hw *hw) |
@@ -1635,9 +1626,7 @@ static void sky2_hw_up(struct sky2_port *sky2) | |||
1635 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1626 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1636 | sky2->tx_ring_size - 1); | 1627 | sky2->tx_ring_size - 1); |
1637 | 1628 | ||
1638 | #ifdef SKY2_VLAN_TAG_USED | 1629 | sky2_vlan_mode(sky2->netdev); |
1639 | sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); | ||
1640 | #endif | ||
1641 | 1630 | ||
1642 | sky2_rx_start(sky2); | 1631 | sky2_rx_start(sky2); |
1643 | } | 1632 | } |
@@ -1780,7 +1769,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, | |||
1780 | } | 1769 | } |
1781 | 1770 | ||
1782 | ctrl = 0; | 1771 | ctrl = 0; |
1783 | #ifdef SKY2_VLAN_TAG_USED | 1772 | |
1784 | /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ | 1773 | /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ |
1785 | if (vlan_tx_tag_present(skb)) { | 1774 | if (vlan_tx_tag_present(skb)) { |
1786 | if (!le) { | 1775 | if (!le) { |
@@ -1792,7 +1781,6 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, | |||
1792 | le->length = cpu_to_be16(vlan_tx_tag_get(skb)); | 1781 | le->length = cpu_to_be16(vlan_tx_tag_get(skb)); |
1793 | ctrl |= INS_VLAN; | 1782 | ctrl |= INS_VLAN; |
1794 | } | 1783 | } |
1795 | #endif | ||
1796 | 1784 | ||
1797 | /* Handle TCP checksum offload */ | 1785 | /* Handle TCP checksum offload */ |
1798 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1786 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
@@ -2432,11 +2420,8 @@ static struct sk_buff *sky2_receive(struct net_device *dev, | |||
2432 | struct sk_buff *skb = NULL; | 2420 | struct sk_buff *skb = NULL; |
2433 | u16 count = (status & GMR_FS_LEN) >> 16; | 2421 | u16 count = (status & GMR_FS_LEN) >> 16; |
2434 | 2422 | ||
2435 | #ifdef SKY2_VLAN_TAG_USED | 2423 | if (status & GMR_FS_VLAN) |
2436 | /* Account for vlan tag */ | 2424 | count -= VLAN_HLEN; /* Account for vlan tag */ |
2437 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) | ||
2438 | count -= VLAN_HLEN; | ||
2439 | #endif | ||
2440 | 2425 | ||
2441 | netif_printk(sky2, rx_status, KERN_DEBUG, dev, | 2426 | netif_printk(sky2, rx_status, KERN_DEBUG, dev, |
2442 | "rx slot %u status 0x%x len %d\n", | 2427 | "rx slot %u status 0x%x len %d\n", |
@@ -2504,17 +2489,9 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) | |||
2504 | static inline void sky2_skb_rx(const struct sky2_port *sky2, | 2489 | static inline void sky2_skb_rx(const struct sky2_port *sky2, |
2505 | u32 status, struct sk_buff *skb) | 2490 | u32 status, struct sk_buff *skb) |
2506 | { | 2491 | { |
2507 | #ifdef SKY2_VLAN_TAG_USED | 2492 | if (status & GMR_FS_VLAN) |
2508 | u16 vlan_tag = be16_to_cpu(sky2->rx_tag); | 2493 | __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag)); |
2509 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) { | 2494 | |
2510 | if (skb->ip_summed == CHECKSUM_NONE) | ||
2511 | vlan_hwaccel_receive_skb(skb, sky2->vlgrp, vlan_tag); | ||
2512 | else | ||
2513 | vlan_gro_receive(&sky2->hw->napi, sky2->vlgrp, | ||
2514 | vlan_tag, skb); | ||
2515 | return; | ||
2516 | } | ||
2517 | #endif | ||
2518 | if (skb->ip_summed == CHECKSUM_NONE) | 2495 | if (skb->ip_summed == CHECKSUM_NONE) |
2519 | netif_receive_skb(skb); | 2496 | netif_receive_skb(skb); |
2520 | else | 2497 | else |
@@ -2631,7 +2608,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2631 | goto exit_loop; | 2608 | goto exit_loop; |
2632 | break; | 2609 | break; |
2633 | 2610 | ||
2634 | #ifdef SKY2_VLAN_TAG_USED | ||
2635 | case OP_RXVLAN: | 2611 | case OP_RXVLAN: |
2636 | sky2->rx_tag = length; | 2612 | sky2->rx_tag = length; |
2637 | break; | 2613 | break; |
@@ -2639,7 +2615,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2639 | case OP_RXCHKSVLAN: | 2615 | case OP_RXCHKSVLAN: |
2640 | sky2->rx_tag = length; | 2616 | sky2->rx_tag = length; |
2641 | /* fall through */ | 2617 | /* fall through */ |
2642 | #endif | ||
2643 | case OP_RXCHKS: | 2618 | case OP_RXCHKS: |
2644 | if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM)) | 2619 | if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM)) |
2645 | sky2_rx_checksum(sky2, status); | 2620 | sky2_rx_checksum(sky2, status); |
@@ -3042,6 +3017,10 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
3042 | | SKY2_HW_NEW_LE | 3017 | | SKY2_HW_NEW_LE |
3043 | | SKY2_HW_AUTO_TX_SUM | 3018 | | SKY2_HW_AUTO_TX_SUM |
3044 | | SKY2_HW_ADV_POWER_CTL; | 3019 | | SKY2_HW_ADV_POWER_CTL; |
3020 | |||
3021 | /* The workaround for status conflicts VLAN tag detection. */ | ||
3022 | if (hw->chip_rev == CHIP_REV_YU_FE2_A0) | ||
3023 | hw->flags |= SKY2_HW_VLAN_BROKEN; | ||
3045 | break; | 3024 | break; |
3046 | 3025 | ||
3047 | case CHIP_ID_YUKON_SUPR: | 3026 | case CHIP_ID_YUKON_SUPR: |
@@ -4237,15 +4216,28 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom | |||
4237 | static int sky2_set_flags(struct net_device *dev, u32 data) | 4216 | static int sky2_set_flags(struct net_device *dev, u32 data) |
4238 | { | 4217 | { |
4239 | struct sky2_port *sky2 = netdev_priv(dev); | 4218 | struct sky2_port *sky2 = netdev_priv(dev); |
4240 | u32 supported = | 4219 | unsigned long old_feat = dev->features; |
4241 | (sky2->hw->flags & SKY2_HW_RSS_BROKEN) ? 0 : ETH_FLAG_RXHASH; | 4220 | u32 supported = 0; |
4242 | int rc; | 4221 | int rc; |
4243 | 4222 | ||
4223 | if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN)) | ||
4224 | supported |= ETH_FLAG_RXHASH; | ||
4225 | |||
4226 | if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN)) | ||
4227 | supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN; | ||
4228 | |||
4229 | printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n", | ||
4230 | supported, data); | ||
4231 | |||
4244 | rc = ethtool_op_set_flags(dev, data, supported); | 4232 | rc = ethtool_op_set_flags(dev, data, supported); |
4245 | if (rc) | 4233 | if (rc) |
4246 | return rc; | 4234 | return rc; |
4247 | 4235 | ||
4248 | rx_set_rss(dev); | 4236 | if ((old_feat ^ dev->features) & NETIF_F_RXHASH) |
4237 | rx_set_rss(dev); | ||
4238 | |||
4239 | if ((old_feat ^ dev->features) & NETIF_F_ALL_VLAN) | ||
4240 | sky2_vlan_mode(dev); | ||
4249 | 4241 | ||
4250 | return 0; | 4242 | return 0; |
4251 | } | 4243 | } |
@@ -4281,6 +4273,7 @@ static const struct ethtool_ops sky2_ethtool_ops = { | |||
4281 | .get_sset_count = sky2_get_sset_count, | 4273 | .get_sset_count = sky2_get_sset_count, |
4282 | .get_ethtool_stats = sky2_get_ethtool_stats, | 4274 | .get_ethtool_stats = sky2_get_ethtool_stats, |
4283 | .set_flags = sky2_set_flags, | 4275 | .set_flags = sky2_set_flags, |
4276 | .get_flags = ethtool_op_get_flags, | ||
4284 | }; | 4277 | }; |
4285 | 4278 | ||
4286 | #ifdef CONFIG_SKY2_DEBUG | 4279 | #ifdef CONFIG_SKY2_DEBUG |
@@ -4562,9 +4555,6 @@ static const struct net_device_ops sky2_netdev_ops[2] = { | |||
4562 | .ndo_change_mtu = sky2_change_mtu, | 4555 | .ndo_change_mtu = sky2_change_mtu, |
4563 | .ndo_tx_timeout = sky2_tx_timeout, | 4556 | .ndo_tx_timeout = sky2_tx_timeout, |
4564 | .ndo_get_stats64 = sky2_get_stats, | 4557 | .ndo_get_stats64 = sky2_get_stats, |
4565 | #ifdef SKY2_VLAN_TAG_USED | ||
4566 | .ndo_vlan_rx_register = sky2_vlan_rx_register, | ||
4567 | #endif | ||
4568 | #ifdef CONFIG_NET_POLL_CONTROLLER | 4558 | #ifdef CONFIG_NET_POLL_CONTROLLER |
4569 | .ndo_poll_controller = sky2_netpoll, | 4559 | .ndo_poll_controller = sky2_netpoll, |
4570 | #endif | 4560 | #endif |
@@ -4580,9 +4570,6 @@ static const struct net_device_ops sky2_netdev_ops[2] = { | |||
4580 | .ndo_change_mtu = sky2_change_mtu, | 4570 | .ndo_change_mtu = sky2_change_mtu, |
4581 | .ndo_tx_timeout = sky2_tx_timeout, | 4571 | .ndo_tx_timeout = sky2_tx_timeout, |
4582 | .ndo_get_stats64 = sky2_get_stats, | 4572 | .ndo_get_stats64 = sky2_get_stats, |
4583 | #ifdef SKY2_VLAN_TAG_USED | ||
4584 | .ndo_vlan_rx_register = sky2_vlan_rx_register, | ||
4585 | #endif | ||
4586 | }, | 4573 | }, |
4587 | }; | 4574 | }; |
4588 | 4575 | ||
@@ -4633,7 +4620,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
4633 | sky2->port = port; | 4620 | sky2->port = port; |
4634 | 4621 | ||
4635 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | 4622 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
4636 | | NETIF_F_TSO | NETIF_F_GRO; | 4623 | | NETIF_F_TSO | NETIF_F_GRO; |
4624 | |||
4637 | if (highmem) | 4625 | if (highmem) |
4638 | dev->features |= NETIF_F_HIGHDMA; | 4626 | dev->features |= NETIF_F_HIGHDMA; |
4639 | 4627 | ||
@@ -4641,13 +4629,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
4641 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) | 4629 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) |
4642 | dev->features |= NETIF_F_RXHASH; | 4630 | dev->features |= NETIF_F_RXHASH; |
4643 | 4631 | ||
4644 | #ifdef SKY2_VLAN_TAG_USED | 4632 | if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) |
4645 | /* The workaround for FE+ status conflicts with VLAN tag detection. */ | ||
4646 | if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && | ||
4647 | sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) { | ||
4648 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 4633 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
4649 | } | ||
4650 | #endif | ||
4651 | 4634 | ||
4652 | /* read the mac address */ | 4635 | /* read the mac address */ |
4653 | memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); | 4636 | memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 80bdc404f1ea..6861b0e8db9a 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -2236,11 +2236,8 @@ struct sky2_port { | |||
2236 | u16 rx_pending; | 2236 | u16 rx_pending; |
2237 | u16 rx_data_size; | 2237 | u16 rx_data_size; |
2238 | u16 rx_nfrags; | 2238 | u16 rx_nfrags; |
2239 | |||
2240 | #ifdef SKY2_VLAN_TAG_USED | ||
2241 | u16 rx_tag; | 2239 | u16 rx_tag; |
2242 | struct vlan_group *vlgrp; | 2240 | |
2243 | #endif | ||
2244 | struct { | 2241 | struct { |
2245 | unsigned long last; | 2242 | unsigned long last; |
2246 | u32 mac_rp; | 2243 | u32 mac_rp; |
@@ -2284,6 +2281,7 @@ struct sky2_hw { | |||
2284 | #define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */ | 2281 | #define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */ |
2285 | #define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */ | 2282 | #define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */ |
2286 | #define SKY2_HW_RSS_BROKEN 0x00000100 | 2283 | #define SKY2_HW_RSS_BROKEN 0x00000100 |
2284 | #define SKY2_HW_VLAN_BROKEN 0x00000200 | ||
2287 | 2285 | ||
2288 | u8 chip_id; | 2286 | u8 chip_id; |
2289 | u8 chip_rev; | 2287 | u8 chip_rev; |