aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/tx.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-09-01 07:48:23 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-03 09:53:47 -0400
commit740847dab16b1a410a0f833df2bf21c8ed8265f3 (patch)
tree33441779d365692200870438d5d97d6a92f494ad /drivers/net/sfc/tx.c
parentdacccc741164edf95fb13dbf5eedb96fb94f7290 (diff)
sfc: Enable TSO for 802.1q VLAN devices
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc/tx.c')
-rw-r--r--drivers/net/sfc/tx.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index 0e9889ca68fc..a3a3eddd30b9 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -105,7 +105,7 @@ struct efx_tso_header {
105}; 105};
106 106
107static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, 107static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
108 const struct sk_buff *skb); 108 struct sk_buff *skb);
109static void efx_fini_tso(struct efx_tx_queue *tx_queue); 109static void efx_fini_tso(struct efx_tx_queue *tx_queue);
110static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, 110static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue,
111 struct efx_tso_header *tsoh); 111 struct efx_tso_header *tsoh);
@@ -139,7 +139,7 @@ static void efx_tsoh_free(struct efx_tx_queue *tx_queue,
139 * You must hold netif_tx_lock() to call this function. 139 * You must hold netif_tx_lock() to call this function.
140 */ 140 */
141static int efx_enqueue_skb(struct efx_tx_queue *tx_queue, 141static int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
142 const struct sk_buff *skb) 142 struct sk_buff *skb)
143{ 143{
144 struct efx_nic *efx = tx_queue->efx; 144 struct efx_nic *efx = tx_queue->efx;
145 struct pci_dev *pci_dev = efx->pci_dev; 145 struct pci_dev *pci_dev = efx->pci_dev;
@@ -578,11 +578,24 @@ struct tso_state {
578 * Verify that our various assumptions about sk_buffs and the conditions 578 * Verify that our various assumptions about sk_buffs and the conditions
579 * under which TSO will be attempted hold true. 579 * under which TSO will be attempted hold true.
580 */ 580 */
581static void efx_tso_check_safe(const struct sk_buff *skb) 581static void efx_tso_check_safe(struct sk_buff *skb)
582{ 582{
583 EFX_BUG_ON_PARANOID(skb->protocol != htons(ETH_P_IP)); 583 __be16 protocol = skb->protocol;
584
584 EFX_BUG_ON_PARANOID(((struct ethhdr *)skb->data)->h_proto != 585 EFX_BUG_ON_PARANOID(((struct ethhdr *)skb->data)->h_proto !=
585 skb->protocol); 586 protocol);
587 if (protocol == htons(ETH_P_8021Q)) {
588 /* Find the encapsulated protocol; reset network header
589 * and transport header based on that. */
590 struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
591 protocol = veh->h_vlan_encapsulated_proto;
592 skb_set_network_header(skb, sizeof(*veh));
593 if (protocol == htons(ETH_P_IP))
594 skb_set_transport_header(skb, sizeof(*veh) +
595 4 * ip_hdr(skb)->ihl);
596 }
597
598 EFX_BUG_ON_PARANOID(protocol != htons(ETH_P_IP));
586 EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP); 599 EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP);
587 EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data) 600 EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data)
588 + (tcp_hdr(skb)->doff << 2u)) > 601 + (tcp_hdr(skb)->doff << 2u)) >
@@ -1020,7 +1033,7 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
1020 * %NETDEV_TX_OK or %NETDEV_TX_BUSY. 1033 * %NETDEV_TX_OK or %NETDEV_TX_BUSY.
1021 */ 1034 */
1022static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, 1035static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
1023 const struct sk_buff *skb) 1036 struct sk_buff *skb)
1024{ 1037{
1025 struct efx_nic *efx = tx_queue->efx; 1038 struct efx_nic *efx = tx_queue->efx;
1026 int frag_i, rc, rc2 = NETDEV_TX_OK; 1039 int frag_i, rc, rc2 = NETDEV_TX_OK;