diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2010-01-02 05:37:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-06 23:30:35 -0500 |
commit | 635267130855e91f4681df5e4d26ca9ce908447f (patch) | |
tree | 331cdcf32a98583818dcf2abd372ced41aa56216 /drivers/net | |
parent | 4f848c0a9c265cb3457fbf842dbffd28e82a44fd (diff) |
qlge: Add napi gro frags interface.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 109bd0abe9b4..e9d6481ed9eb 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -1434,6 +1434,51 @@ map_error: | |||
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | /* Process an inbound completion from an rx ring. */ | 1436 | /* Process an inbound completion from an rx ring. */ |
1437 | static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev, | ||
1438 | struct rx_ring *rx_ring, | ||
1439 | struct ib_mac_iocb_rsp *ib_mac_rsp, | ||
1440 | u32 length, | ||
1441 | u16 vlan_id) | ||
1442 | { | ||
1443 | struct sk_buff *skb; | ||
1444 | struct bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring); | ||
1445 | struct skb_frag_struct *rx_frag; | ||
1446 | int nr_frags; | ||
1447 | struct napi_struct *napi = &rx_ring->napi; | ||
1448 | |||
1449 | napi->dev = qdev->ndev; | ||
1450 | |||
1451 | skb = napi_get_frags(napi); | ||
1452 | if (!skb) { | ||
1453 | QPRINTK(qdev, DRV, ERR, "Couldn't get an skb, exiting.\n"); | ||
1454 | rx_ring->rx_dropped++; | ||
1455 | put_page(lbq_desc->p.pg_chunk.page); | ||
1456 | return; | ||
1457 | } | ||
1458 | prefetch(lbq_desc->p.pg_chunk.va); | ||
1459 | rx_frag = skb_shinfo(skb)->frags; | ||
1460 | nr_frags = skb_shinfo(skb)->nr_frags; | ||
1461 | rx_frag += nr_frags; | ||
1462 | rx_frag->page = lbq_desc->p.pg_chunk.page; | ||
1463 | rx_frag->page_offset = lbq_desc->p.pg_chunk.offset; | ||
1464 | rx_frag->size = length; | ||
1465 | |||
1466 | skb->len += length; | ||
1467 | skb->data_len += length; | ||
1468 | skb->truesize += length; | ||
1469 | skb_shinfo(skb)->nr_frags++; | ||
1470 | |||
1471 | rx_ring->rx_packets++; | ||
1472 | rx_ring->rx_bytes += length; | ||
1473 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1474 | skb_record_rx_queue(skb, rx_ring->cq_id); | ||
1475 | if (qdev->vlgrp && (vlan_id != 0xffff)) | ||
1476 | vlan_gro_frags(&rx_ring->napi, qdev->vlgrp, vlan_id); | ||
1477 | else | ||
1478 | napi_gro_frags(napi); | ||
1479 | } | ||
1480 | |||
1481 | /* Process an inbound completion from an rx ring. */ | ||
1437 | static void ql_process_mac_rx_page(struct ql_adapter *qdev, | 1482 | static void ql_process_mac_rx_page(struct ql_adapter *qdev, |
1438 | struct rx_ring *rx_ring, | 1483 | struct rx_ring *rx_ring, |
1439 | struct ib_mac_iocb_rsp *ib_mac_rsp, | 1484 | struct ib_mac_iocb_rsp *ib_mac_rsp, |
@@ -1980,6 +2025,14 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev, | |||
1980 | */ | 2025 | */ |
1981 | ql_process_mac_rx_skb(qdev, rx_ring, ib_mac_rsp, | 2026 | ql_process_mac_rx_skb(qdev, rx_ring, ib_mac_rsp, |
1982 | length, vlan_id); | 2027 | length, vlan_id); |
2028 | } else if ((ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) && | ||
2029 | !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK) && | ||
2030 | (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T)) { | ||
2031 | /* TCP packet in a page chunk that's been checksummed. | ||
2032 | * Tack it on to our GRO skb and let it go. | ||
2033 | */ | ||
2034 | ql_process_mac_rx_gro_page(qdev, rx_ring, ib_mac_rsp, | ||
2035 | length, vlan_id); | ||
1983 | } else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) { | 2036 | } else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) { |
1984 | /* Non-TCP packet in a page chunk. Allocate an | 2037 | /* Non-TCP packet in a page chunk. Allocate an |
1985 | * skb, tack it on frags, and send it up. | 2038 | * skb, tack it on frags, and send it up. |