diff options
author | David Dillow <dave@thedillows.org> | 2010-10-24 06:20:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-24 19:25:40 -0400 |
commit | fd59cba4f0d80a6dc4cc7372f03af905b1758e03 (patch) | |
tree | 705f9bdee4fc0d8d2b805990f26db2e63b9a1aef /drivers/net/typhoon.c | |
parent | 154ccd82e1b871ca012e781e01566128754d8c5f (diff) |
typhoon: update to new VLAN acceleration model
Also correct the byteswapping as we keep the TCI in host order.
Signed-off-by: David Dillow <dave@thedillows.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/typhoon.c')
-rw-r--r-- | drivers/net/typhoon.c | 88 |
1 files changed, 25 insertions, 63 deletions
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 5957d4ecd86b..b550da008a03 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
@@ -24,10 +24,6 @@ | |||
24 | 3XP Processor. It has been tested on x86 and sparc64. | 24 | 3XP Processor. It has been tested on x86 and sparc64. |
25 | 25 | ||
26 | KNOWN ISSUES: | 26 | KNOWN ISSUES: |
27 | *) The current firmware always strips the VLAN tag off, even if | ||
28 | we tell it not to. You should filter VLANs at the switch | ||
29 | as a workaround (good practice in any event) until we can | ||
30 | get this fixed. | ||
31 | *) Cannot DMA Rx packets to a 2 byte aligned address. Also firmware | 27 | *) Cannot DMA Rx packets to a 2 byte aligned address. Also firmware |
32 | issue. Hopefully 3Com will fix it. | 28 | issue. Hopefully 3Com will fix it. |
33 | *) Waiting for a command response takes 8ms due to non-preemptable | 29 | *) Waiting for a command response takes 8ms due to non-preemptable |
@@ -280,8 +276,6 @@ struct typhoon { | |||
280 | struct pci_dev * pdev; | 276 | struct pci_dev * pdev; |
281 | struct net_device * dev; | 277 | struct net_device * dev; |
282 | struct napi_struct napi; | 278 | struct napi_struct napi; |
283 | spinlock_t state_lock; | ||
284 | struct vlan_group * vlgrp; | ||
285 | struct basic_ring rxHiRing; | 279 | struct basic_ring rxHiRing; |
286 | struct basic_ring rxBuffRing; | 280 | struct basic_ring rxBuffRing; |
287 | struct rxbuff_ent rxbuffers[RXENT_ENTRIES]; | 281 | struct rxbuff_ent rxbuffers[RXENT_ENTRIES]; |
@@ -695,44 +689,6 @@ out: | |||
695 | return err; | 689 | return err; |
696 | } | 690 | } |
697 | 691 | ||
698 | static void | ||
699 | typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | ||
700 | { | ||
701 | struct typhoon *tp = netdev_priv(dev); | ||
702 | struct cmd_desc xp_cmd; | ||
703 | int err; | ||
704 | |||
705 | spin_lock_bh(&tp->state_lock); | ||
706 | if(!tp->vlgrp != !grp) { | ||
707 | /* We've either been turned on for the first time, or we've | ||
708 | * been turned off. Update the 3XP. | ||
709 | */ | ||
710 | if(grp) | ||
711 | tp->offload |= TYPHOON_OFFLOAD_VLAN; | ||
712 | else | ||
713 | tp->offload &= ~TYPHOON_OFFLOAD_VLAN; | ||
714 | |||
715 | /* If the interface is up, the runtime is running -- and we | ||
716 | * must be up for the vlan core to call us. | ||
717 | * | ||
718 | * Do the command outside of the spin lock, as it is slow. | ||
719 | */ | ||
720 | INIT_COMMAND_WITH_RESPONSE(&xp_cmd, | ||
721 | TYPHOON_CMD_SET_OFFLOAD_TASKS); | ||
722 | xp_cmd.parm2 = tp->offload; | ||
723 | xp_cmd.parm3 = tp->offload; | ||
724 | spin_unlock_bh(&tp->state_lock); | ||
725 | err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); | ||
726 | if(err < 0) | ||
727 | netdev_err(tp->dev, "vlan offload error %d\n", -err); | ||
728 | spin_lock_bh(&tp->state_lock); | ||
729 | } | ||
730 | |||
731 | /* now make the change visible */ | ||
732 | tp->vlgrp = grp; | ||
733 | spin_unlock_bh(&tp->state_lock); | ||
734 | } | ||
735 | |||
736 | static inline void | 692 | static inline void |
737 | typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing, | 693 | typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing, |
738 | u32 ring_dma) | 694 | u32 ring_dma) |
@@ -818,7 +774,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) | |||
818 | first_txd->processFlags |= | 774 | first_txd->processFlags |= |
819 | TYPHOON_TX_PF_INSERT_VLAN | TYPHOON_TX_PF_VLAN_PRIORITY; | 775 | TYPHOON_TX_PF_INSERT_VLAN | TYPHOON_TX_PF_VLAN_PRIORITY; |
820 | first_txd->processFlags |= | 776 | first_txd->processFlags |= |
821 | cpu_to_le32(ntohs(vlan_tx_tag_get(skb)) << | 777 | cpu_to_le32(htons(vlan_tx_tag_get(skb)) << |
822 | TYPHOON_TX_PF_VLAN_TAG_SHIFT); | 778 | TYPHOON_TX_PF_VLAN_TAG_SHIFT); |
823 | } | 779 | } |
824 | 780 | ||
@@ -1198,6 +1154,20 @@ typhoon_get_rx_csum(struct net_device *dev) | |||
1198 | return 1; | 1154 | return 1; |
1199 | } | 1155 | } |
1200 | 1156 | ||
1157 | static int | ||
1158 | typhoon_set_flags(struct net_device *dev, u32 data) | ||
1159 | { | ||
1160 | /* There's no way to turn off the RX VLAN offloading and stripping | ||
1161 | * on the current 3XP firmware -- it does not respect the offload | ||
1162 | * settings -- so we only allow the user to toggle the TX processing. | ||
1163 | */ | ||
1164 | if (!(data & ETH_FLAG_RXVLAN)) | ||
1165 | return -EINVAL; | ||
1166 | |||
1167 | return ethtool_op_set_flags(dev, data, | ||
1168 | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); | ||
1169 | } | ||
1170 | |||
1201 | static void | 1171 | static void |
1202 | typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | 1172 | typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) |
1203 | { | 1173 | { |
@@ -1224,6 +1194,8 @@ static const struct ethtool_ops typhoon_ethtool_ops = { | |||
1224 | .set_sg = ethtool_op_set_sg, | 1194 | .set_sg = ethtool_op_set_sg, |
1225 | .set_tso = ethtool_op_set_tso, | 1195 | .set_tso = ethtool_op_set_tso, |
1226 | .get_ringparam = typhoon_get_ringparam, | 1196 | .get_ringparam = typhoon_get_ringparam, |
1197 | .set_flags = typhoon_set_flags, | ||
1198 | .get_flags = ethtool_op_get_flags, | ||
1227 | }; | 1199 | }; |
1228 | 1200 | ||
1229 | static int | 1201 | static int |
@@ -1309,9 +1281,9 @@ typhoon_init_interface(struct typhoon *tp) | |||
1309 | 1281 | ||
1310 | tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; | 1282 | tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; |
1311 | tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; | 1283 | tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; |
1284 | tp->offload |= TYPHOON_OFFLOAD_VLAN; | ||
1312 | 1285 | ||
1313 | spin_lock_init(&tp->command_lock); | 1286 | spin_lock_init(&tp->command_lock); |
1314 | spin_lock_init(&tp->state_lock); | ||
1315 | 1287 | ||
1316 | /* Force the writes to the shared memory area out before continuing. */ | 1288 | /* Force the writes to the shared memory area out before continuing. */ |
1317 | wmb(); | 1289 | wmb(); |
@@ -1762,13 +1734,10 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read | |||
1762 | } else | 1734 | } else |
1763 | skb_checksum_none_assert(new_skb); | 1735 | skb_checksum_none_assert(new_skb); |
1764 | 1736 | ||
1765 | spin_lock(&tp->state_lock); | 1737 | if (rx->rxStatus & TYPHOON_RX_VLAN) |
1766 | if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN) | 1738 | __vlan_hwaccel_put_tag(new_skb, |
1767 | vlan_hwaccel_receive_skb(new_skb, tp->vlgrp, | 1739 | ntohl(rx->vlanTag) & 0xffff); |
1768 | ntohl(rx->vlanTag) & 0xffff); | 1740 | netif_receive_skb(new_skb); |
1769 | else | ||
1770 | netif_receive_skb(new_skb); | ||
1771 | spin_unlock(&tp->state_lock); | ||
1772 | 1741 | ||
1773 | received++; | 1742 | received++; |
1774 | budget--; | 1743 | budget--; |
@@ -1989,11 +1958,9 @@ typhoon_start_runtime(struct typhoon *tp) | |||
1989 | goto error_out; | 1958 | goto error_out; |
1990 | 1959 | ||
1991 | INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS); | 1960 | INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS); |
1992 | spin_lock_bh(&tp->state_lock); | ||
1993 | xp_cmd.parm2 = tp->offload; | 1961 | xp_cmd.parm2 = tp->offload; |
1994 | xp_cmd.parm3 = tp->offload; | 1962 | xp_cmd.parm3 = tp->offload; |
1995 | err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); | 1963 | err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); |
1996 | spin_unlock_bh(&tp->state_lock); | ||
1997 | if(err < 0) | 1964 | if(err < 0) |
1998 | goto error_out; | 1965 | goto error_out; |
1999 | 1966 | ||
@@ -2231,13 +2198,9 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2231 | if(!netif_running(dev)) | 2198 | if(!netif_running(dev)) |
2232 | return 0; | 2199 | return 0; |
2233 | 2200 | ||
2234 | spin_lock_bh(&tp->state_lock); | 2201 | /* TYPHOON_OFFLOAD_VLAN is always on now, so this doesn't work */ |
2235 | if(tp->vlgrp && tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) { | 2202 | if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) |
2236 | spin_unlock_bh(&tp->state_lock); | 2203 | netdev_warn(dev, "cannot do WAKE_MAGIC with VLAN offloading\n"); |
2237 | netdev_err(dev, "cannot do WAKE_MAGIC with VLANS\n"); | ||
2238 | return -EBUSY; | ||
2239 | } | ||
2240 | spin_unlock_bh(&tp->state_lock); | ||
2241 | 2204 | ||
2242 | netif_device_detach(dev); | 2205 | netif_device_detach(dev); |
2243 | 2206 | ||
@@ -2338,7 +2301,6 @@ static const struct net_device_ops typhoon_netdev_ops = { | |||
2338 | .ndo_validate_addr = eth_validate_addr, | 2301 | .ndo_validate_addr = eth_validate_addr, |
2339 | .ndo_set_mac_address = typhoon_set_mac_address, | 2302 | .ndo_set_mac_address = typhoon_set_mac_address, |
2340 | .ndo_change_mtu = eth_change_mtu, | 2303 | .ndo_change_mtu = eth_change_mtu, |
2341 | .ndo_vlan_rx_register = typhoon_vlan_rx_register, | ||
2342 | }; | 2304 | }; |
2343 | 2305 | ||
2344 | static int __devinit | 2306 | static int __devinit |