diff options
author | Michael Chan <mchan@broadcom.com> | 2007-05-03 16:22:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-05-03 16:22:28 -0400 |
commit | 4666f87a82cf74b63737a7f55a8b3b057a7b83df (patch) | |
tree | 67cc362f70fa70bb8218e91e46e82d3bd5f7b57e | |
parent | 874bb672fdd939aec37ad3a06b50be4ff8b4feac (diff) |
[BNX2]: Add ipv6 TSO and checksum for 5709.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bnx2.c | 91 | ||||
-rw-r--r-- | drivers/net/bnx2.h | 4 |
2 files changed, 67 insertions, 28 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 89681b30b890..01977de759d8 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -4537,35 +4537,49 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4537 | u32 tcp_opt_len, ip_tcp_len; | 4537 | u32 tcp_opt_len, ip_tcp_len; |
4538 | struct iphdr *iph; | 4538 | struct iphdr *iph; |
4539 | 4539 | ||
4540 | if (skb_header_cloned(skb) && | ||
4541 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { | ||
4542 | dev_kfree_skb(skb); | ||
4543 | return NETDEV_TX_OK; | ||
4544 | } | ||
4545 | |||
4546 | vlan_tag_flags |= TX_BD_FLAGS_SW_LSO; | 4540 | vlan_tag_flags |= TX_BD_FLAGS_SW_LSO; |
4547 | 4541 | ||
4548 | tcp_opt_len = 0; | 4542 | tcp_opt_len = tcp_optlen(skb); |
4549 | if (tcp_hdr(skb)->doff > 5) | 4543 | |
4550 | tcp_opt_len = tcp_optlen(skb); | 4544 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { |
4545 | u32 tcp_off = skb_transport_offset(skb) - | ||
4546 | sizeof(struct ipv6hdr) - ETH_HLEN; | ||
4551 | 4547 | ||
4552 | ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); | 4548 | vlan_tag_flags |= ((tcp_opt_len >> 2) << 8) | |
4549 | TX_BD_FLAGS_SW_FLAGS; | ||
4550 | if (likely(tcp_off == 0)) | ||
4551 | vlan_tag_flags &= ~TX_BD_FLAGS_TCP6_OFF0_MSK; | ||
4552 | else { | ||
4553 | tcp_off >>= 3; | ||
4554 | vlan_tag_flags |= ((tcp_off & 0x3) << | ||
4555 | TX_BD_FLAGS_TCP6_OFF0_SHL) | | ||
4556 | ((tcp_off & 0x10) << | ||
4557 | TX_BD_FLAGS_TCP6_OFF4_SHL); | ||
4558 | mss |= (tcp_off & 0xc) << TX_BD_TCP6_OFF2_SHL; | ||
4559 | } | ||
4560 | } else { | ||
4561 | if (skb_header_cloned(skb) && | ||
4562 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { | ||
4563 | dev_kfree_skb(skb); | ||
4564 | return NETDEV_TX_OK; | ||
4565 | } | ||
4553 | 4566 | ||
4554 | iph = ip_hdr(skb); | 4567 | ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); |
4555 | iph->check = 0; | 4568 | |
4556 | iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); | 4569 | iph = ip_hdr(skb); |
4557 | tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, | 4570 | iph->check = 0; |
4558 | iph->daddr, 0, | 4571 | iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); |
4559 | IPPROTO_TCP, 0); | 4572 | tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, |
4560 | if (tcp_opt_len || (iph->ihl > 5)) { | 4573 | iph->daddr, 0, |
4561 | vlan_tag_flags |= ((iph->ihl - 5) + | 4574 | IPPROTO_TCP, |
4562 | (tcp_opt_len >> 2)) << 8; | 4575 | 0); |
4576 | if (tcp_opt_len || (iph->ihl > 5)) { | ||
4577 | vlan_tag_flags |= ((iph->ihl - 5) + | ||
4578 | (tcp_opt_len >> 2)) << 8; | ||
4579 | } | ||
4563 | } | 4580 | } |
4564 | } | 4581 | } else |
4565 | else | ||
4566 | { | ||
4567 | mss = 0; | 4582 | mss = 0; |
4568 | } | ||
4569 | 4583 | ||
4570 | mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); | 4584 | mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); |
4571 | 4585 | ||
@@ -5233,10 +5247,15 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data) | |||
5233 | static int | 5247 | static int |
5234 | bnx2_set_tso(struct net_device *dev, u32 data) | 5248 | bnx2_set_tso(struct net_device *dev, u32 data) |
5235 | { | 5249 | { |
5236 | if (data) | 5250 | struct bnx2 *bp = netdev_priv(dev); |
5251 | |||
5252 | if (data) { | ||
5237 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; | 5253 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; |
5238 | else | 5254 | if (CHIP_NUM(bp) == CHIP_NUM_5709) |
5239 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN); | 5255 | dev->features |= NETIF_F_TSO6; |
5256 | } else | ||
5257 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | | ||
5258 | NETIF_F_TSO_ECN); | ||
5240 | return 0; | 5259 | return 0; |
5241 | } | 5260 | } |
5242 | 5261 | ||
@@ -5534,6 +5553,17 @@ bnx2_phys_id(struct net_device *dev, u32 data) | |||
5534 | return 0; | 5553 | return 0; |
5535 | } | 5554 | } |
5536 | 5555 | ||
5556 | static int | ||
5557 | bnx2_set_tx_csum(struct net_device *dev, u32 data) | ||
5558 | { | ||
5559 | struct bnx2 *bp = netdev_priv(dev); | ||
5560 | |||
5561 | if (CHIP_NUM(bp) == CHIP_NUM_5709) | ||
5562 | return (ethtool_op_set_tx_hw_csum(dev, data)); | ||
5563 | else | ||
5564 | return (ethtool_op_set_tx_csum(dev, data)); | ||
5565 | } | ||
5566 | |||
5537 | static const struct ethtool_ops bnx2_ethtool_ops = { | 5567 | static const struct ethtool_ops bnx2_ethtool_ops = { |
5538 | .get_settings = bnx2_get_settings, | 5568 | .get_settings = bnx2_get_settings, |
5539 | .set_settings = bnx2_set_settings, | 5569 | .set_settings = bnx2_set_settings, |
@@ -5556,7 +5586,7 @@ static const struct ethtool_ops bnx2_ethtool_ops = { | |||
5556 | .get_rx_csum = bnx2_get_rx_csum, | 5586 | .get_rx_csum = bnx2_get_rx_csum, |
5557 | .set_rx_csum = bnx2_set_rx_csum, | 5587 | .set_rx_csum = bnx2_set_rx_csum, |
5558 | .get_tx_csum = ethtool_op_get_tx_csum, | 5588 | .get_tx_csum = ethtool_op_get_tx_csum, |
5559 | .set_tx_csum = ethtool_op_set_tx_csum, | 5589 | .set_tx_csum = bnx2_set_tx_csum, |
5560 | .get_sg = ethtool_op_get_sg, | 5590 | .get_sg = ethtool_op_get_sg, |
5561 | .set_sg = ethtool_op_set_sg, | 5591 | .set_sg = ethtool_op_set_sg, |
5562 | .get_tso = ethtool_op_get_tso, | 5592 | .get_tso = ethtool_op_get_tso, |
@@ -6094,11 +6124,16 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6094 | memcpy(dev->perm_addr, bp->mac_addr, 6); | 6124 | memcpy(dev->perm_addr, bp->mac_addr, 6); |
6095 | bp->name = board_info[ent->driver_data].name; | 6125 | bp->name = board_info[ent->driver_data].name; |
6096 | 6126 | ||
6097 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 6127 | if (CHIP_NUM(bp) == CHIP_NUM_5709) |
6128 | dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; | ||
6129 | else | ||
6130 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | ||
6098 | #ifdef BCM_VLAN | 6131 | #ifdef BCM_VLAN |
6099 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 6132 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
6100 | #endif | 6133 | #endif |
6101 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; | 6134 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; |
6135 | if (CHIP_NUM(bp) == CHIP_NUM_5709) | ||
6136 | dev->features |= NETIF_F_TSO6; | ||
6102 | 6137 | ||
6103 | if ((rc = register_netdev(dev))) { | 6138 | if ((rc = register_netdev(dev))) { |
6104 | dev_err(&pdev->dev, "Cannot register net device\n"); | 6139 | dev_err(&pdev->dev, "Cannot register net device\n"); |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 8e7b29a3f930..70fb639b6f52 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -24,8 +24,11 @@ struct tx_bd { | |||
24 | u32 tx_bd_haddr_hi; | 24 | u32 tx_bd_haddr_hi; |
25 | u32 tx_bd_haddr_lo; | 25 | u32 tx_bd_haddr_lo; |
26 | u32 tx_bd_mss_nbytes; | 26 | u32 tx_bd_mss_nbytes; |
27 | #define TX_BD_TCP6_OFF2_SHL (14) | ||
27 | u32 tx_bd_vlan_tag_flags; | 28 | u32 tx_bd_vlan_tag_flags; |
28 | #define TX_BD_FLAGS_CONN_FAULT (1<<0) | 29 | #define TX_BD_FLAGS_CONN_FAULT (1<<0) |
30 | #define TX_BD_FLAGS_TCP6_OFF0_MSK (3<<1) | ||
31 | #define TX_BD_FLAGS_TCP6_OFF0_SHL (1) | ||
29 | #define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) | 32 | #define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) |
30 | #define TX_BD_FLAGS_IP_CKSUM (1<<2) | 33 | #define TX_BD_FLAGS_IP_CKSUM (1<<2) |
31 | #define TX_BD_FLAGS_VLAN_TAG (1<<3) | 34 | #define TX_BD_FLAGS_VLAN_TAG (1<<3) |
@@ -34,6 +37,7 @@ struct tx_bd { | |||
34 | #define TX_BD_FLAGS_END (1<<6) | 37 | #define TX_BD_FLAGS_END (1<<6) |
35 | #define TX_BD_FLAGS_START (1<<7) | 38 | #define TX_BD_FLAGS_START (1<<7) |
36 | #define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) | 39 | #define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) |
40 | #define TX_BD_FLAGS_TCP6_OFF4_SHL (12) | ||
37 | #define TX_BD_FLAGS_SW_FLAGS (1<<13) | 41 | #define TX_BD_FLAGS_SW_FLAGS (1<<13) |
38 | #define TX_BD_FLAGS_SW_SNAP (1<<14) | 42 | #define TX_BD_FLAGS_SW_SNAP (1<<14) |
39 | #define TX_BD_FLAGS_SW_LSO (1<<15) | 43 | #define TX_BD_FLAGS_SW_LSO (1<<15) |