aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2010-01-02 05:37:44 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-06 23:30:35 -0500
commit635267130855e91f4681df5e4d26ca9ce908447f (patch)
tree331cdcf32a98583818dcf2abd372ced41aa56216 /drivers
parent4f848c0a9c265cb3457fbf842dbffd28e82a44fd (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')
-rw-r--r--drivers/net/qlge/qlge_main.c53
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. */
1437static 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. */
1437static void ql_process_mac_rx_page(struct ql_adapter *qdev, 1482static 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.