diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-01-26 15:34:57 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-26 15:34:57 -0500 |
commit | cdff1036492ac97b4213aeab2546914a633a7de7 (patch) | |
tree | 2c5bff4315f05d6e7f1f7287859a9ccc8fe79f3a /drivers/net/netxen | |
parent | 3121a48d87a580f369eeb26aa0a075142274a353 (diff) |
netxen: fix vlan tso/checksum offload
o set netdev->vlan_features appropriately.
o fix tso descriptor initialization for vlan case.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index d854f07ef4d3..645d384fe87e 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -735,17 +735,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
735 | 735 | ||
736 | SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); | 736 | SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); |
737 | 737 | ||
738 | /* ScatterGather support */ | 738 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); |
739 | netdev->features = NETIF_F_SG; | 739 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); |
740 | netdev->features |= NETIF_F_IP_CSUM; | 740 | |
741 | netdev->features |= NETIF_F_TSO; | ||
742 | if (NX_IS_REVISION_P3(revision_id)) { | 741 | if (NX_IS_REVISION_P3(revision_id)) { |
743 | netdev->features |= NETIF_F_IPV6_CSUM; | 742 | netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); |
744 | netdev->features |= NETIF_F_TSO6; | 743 | netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); |
745 | } | 744 | } |
746 | 745 | ||
747 | if (adapter->pci_using_dac) | 746 | if (adapter->pci_using_dac) { |
748 | netdev->features |= NETIF_F_HIGHDMA; | 747 | netdev->features |= NETIF_F_HIGHDMA; |
748 | netdev->vlan_features |= NETIF_F_HIGHDMA; | ||
749 | } | ||
749 | 750 | ||
750 | /* | 751 | /* |
751 | * Set the CRB window to invalid. If any register in window 0 is | 752 | * Set the CRB window to invalid. If any register in window 0 is |
@@ -1166,6 +1167,14 @@ static bool netxen_tso_check(struct net_device *netdev, | |||
1166 | { | 1167 | { |
1167 | bool tso = false; | 1168 | bool tso = false; |
1168 | u8 opcode = TX_ETHER_PKT; | 1169 | u8 opcode = TX_ETHER_PKT; |
1170 | __be16 protocol = skb->protocol; | ||
1171 | u16 flags = 0; | ||
1172 | |||
1173 | if (protocol == __constant_htons(ETH_P_8021Q)) { | ||
1174 | struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data; | ||
1175 | protocol = vh->h_vlan_encapsulated_proto; | ||
1176 | flags = FLAGS_VLAN_TAGGED; | ||
1177 | } | ||
1169 | 1178 | ||
1170 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && | 1179 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && |
1171 | skb_shinfo(skb)->gso_size > 0) { | 1180 | skb_shinfo(skb)->gso_size > 0) { |
@@ -1174,21 +1183,21 @@ static bool netxen_tso_check(struct net_device *netdev, | |||
1174 | desc->total_hdr_length = | 1183 | desc->total_hdr_length = |
1175 | skb_transport_offset(skb) + tcp_hdrlen(skb); | 1184 | skb_transport_offset(skb) + tcp_hdrlen(skb); |
1176 | 1185 | ||
1177 | opcode = (skb->protocol == htons(ETH_P_IPV6)) ? | 1186 | opcode = (protocol == __constant_htons(ETH_P_IPV6)) ? |
1178 | TX_TCP_LSO6 : TX_TCP_LSO; | 1187 | TX_TCP_LSO6 : TX_TCP_LSO; |
1179 | tso = true; | 1188 | tso = true; |
1180 | 1189 | ||
1181 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1190 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
1182 | u8 l4proto; | 1191 | u8 l4proto; |
1183 | 1192 | ||
1184 | if (skb->protocol == htons(ETH_P_IP)) { | 1193 | if (protocol == __constant_htons(ETH_P_IP)) { |
1185 | l4proto = ip_hdr(skb)->protocol; | 1194 | l4proto = ip_hdr(skb)->protocol; |
1186 | 1195 | ||
1187 | if (l4proto == IPPROTO_TCP) | 1196 | if (l4proto == IPPROTO_TCP) |
1188 | opcode = TX_TCP_PKT; | 1197 | opcode = TX_TCP_PKT; |
1189 | else if(l4proto == IPPROTO_UDP) | 1198 | else if(l4proto == IPPROTO_UDP) |
1190 | opcode = TX_UDP_PKT; | 1199 | opcode = TX_UDP_PKT; |
1191 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 1200 | } else if (protocol == __constant_htons(ETH_P_IPV6)) { |
1192 | l4proto = ipv6_hdr(skb)->nexthdr; | 1201 | l4proto = ipv6_hdr(skb)->nexthdr; |
1193 | 1202 | ||
1194 | if (l4proto == IPPROTO_TCP) | 1203 | if (l4proto == IPPROTO_TCP) |
@@ -1199,7 +1208,7 @@ static bool netxen_tso_check(struct net_device *netdev, | |||
1199 | } | 1208 | } |
1200 | desc->tcp_hdr_offset = skb_transport_offset(skb); | 1209 | desc->tcp_hdr_offset = skb_transport_offset(skb); |
1201 | desc->ip_hdr_offset = skb_network_offset(skb); | 1210 | desc->ip_hdr_offset = skb_network_offset(skb); |
1202 | netxen_set_tx_flags_opcode(desc, 0, opcode); | 1211 | netxen_set_tx_flags_opcode(desc, flags, opcode); |
1203 | return tso; | 1212 | return tso; |
1204 | } | 1213 | } |
1205 | 1214 | ||