diff options
author | Vasanthy Kolluri <vkolluri@cisco.com> | 2010-06-24 06:49:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-25 23:45:00 -0400 |
commit | 88132f55d74fdd97a7d459007b2bbb59e850f8c0 (patch) | |
tree | 440a621ab075be307e2cf4964c8e44ad27675458 /drivers/net/enic | |
parent | 72b8a169dbfa74e7d1d08b97435e61e711d7be0e (diff) |
enic: Feature Add: Replace LRO with GRO
enic now uses the GRO mechanism instead of LRO to pass skbs to upper
layers.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/enic')
-rw-r--r-- | drivers/net/enic/enic.h | 9 | ||||
-rw-r--r-- | drivers/net/enic/enic_main.c | 79 |
2 files changed, 9 insertions, 79 deletions
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 45e86d1e5b1b..81c2adeaa9b8 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h | |||
@@ -20,8 +20,6 @@ | |||
20 | #ifndef _ENIC_H_ | 20 | #ifndef _ENIC_H_ |
21 | #define _ENIC_H_ | 21 | #define _ENIC_H_ |
22 | 22 | ||
23 | #include <linux/inet_lro.h> | ||
24 | |||
25 | #include "vnic_enet.h" | 23 | #include "vnic_enet.h" |
26 | #include "vnic_dev.h" | 24 | #include "vnic_dev.h" |
27 | #include "vnic_wq.h" | 25 | #include "vnic_wq.h" |
@@ -34,13 +32,10 @@ | |||
34 | 32 | ||
35 | #define DRV_NAME "enic" | 33 | #define DRV_NAME "enic" |
36 | #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" | 34 | #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" |
37 | #define DRV_VERSION "1.3.1.1-pp" | 35 | #define DRV_VERSION "1.4.1.1" |
38 | #define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc" | 36 | #define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc" |
39 | #define PFX DRV_NAME ": " | 37 | #define PFX DRV_NAME ": " |
40 | 38 | ||
41 | #define ENIC_LRO_MAX_DESC 8 | ||
42 | #define ENIC_LRO_MAX_AGGR 64 | ||
43 | |||
44 | #define ENIC_BARS_MAX 6 | 39 | #define ENIC_BARS_MAX 6 |
45 | 40 | ||
46 | #define ENIC_WQ_MAX 8 | 41 | #define ENIC_WQ_MAX 8 |
@@ -124,8 +119,6 @@ struct enic { | |||
124 | u64 rq_truncated_pkts; | 119 | u64 rq_truncated_pkts; |
125 | u64 rq_bad_fcs; | 120 | u64 rq_bad_fcs; |
126 | struct napi_struct napi; | 121 | struct napi_struct napi; |
127 | struct net_lro_mgr lro_mgr; | ||
128 | struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC]; | ||
129 | 122 | ||
130 | /* interrupt resource cache line section */ | 123 | /* interrupt resource cache line section */ |
131 | ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; | 124 | ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; |
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index bc7d6b96de3d..c2b848f58c29 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -1287,51 +1287,6 @@ static int enic_set_rq_alloc_buf(struct enic *enic) | |||
1287 | return 0; | 1287 | return 0; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | static int enic_get_skb_header(struct sk_buff *skb, void **iphdr, | ||
1291 | void **tcph, u64 *hdr_flags, void *priv) | ||
1292 | { | ||
1293 | struct cq_enet_rq_desc *cq_desc = priv; | ||
1294 | unsigned int ip_len; | ||
1295 | struct iphdr *iph; | ||
1296 | |||
1297 | u8 type, color, eop, sop, ingress_port, vlan_stripped; | ||
1298 | u8 fcoe, fcoe_sof, fcoe_fc_crc_ok, fcoe_enc_error, fcoe_eof; | ||
1299 | u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; | ||
1300 | u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc; | ||
1301 | u8 packet_error; | ||
1302 | u16 q_number, completed_index, bytes_written, vlan, checksum; | ||
1303 | u32 rss_hash; | ||
1304 | |||
1305 | cq_enet_rq_desc_dec(cq_desc, | ||
1306 | &type, &color, &q_number, &completed_index, | ||
1307 | &ingress_port, &fcoe, &eop, &sop, &rss_type, | ||
1308 | &csum_not_calc, &rss_hash, &bytes_written, | ||
1309 | &packet_error, &vlan_stripped, &vlan, &checksum, | ||
1310 | &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error, | ||
1311 | &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp, | ||
1312 | &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment, | ||
1313 | &fcs_ok); | ||
1314 | |||
1315 | if (!(ipv4 && tcp && !ipv4_fragment)) | ||
1316 | return -1; | ||
1317 | |||
1318 | skb_reset_network_header(skb); | ||
1319 | iph = ip_hdr(skb); | ||
1320 | |||
1321 | ip_len = ip_hdrlen(skb); | ||
1322 | skb_set_transport_header(skb, ip_len); | ||
1323 | |||
1324 | /* check if ip header and tcp header are complete */ | ||
1325 | if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb)) | ||
1326 | return -1; | ||
1327 | |||
1328 | *hdr_flags = LRO_IPV4 | LRO_TCP; | ||
1329 | *tcph = tcp_hdr(skb); | ||
1330 | *iphdr = iph; | ||
1331 | |||
1332 | return 0; | ||
1333 | } | ||
1334 | |||
1335 | static void enic_rq_indicate_buf(struct vnic_rq *rq, | 1290 | static void enic_rq_indicate_buf(struct vnic_rq *rq, |
1336 | struct cq_desc *cq_desc, struct vnic_rq_buf *buf, | 1291 | struct cq_desc *cq_desc, struct vnic_rq_buf *buf, |
1337 | int skipped, void *opaque) | 1292 | int skipped, void *opaque) |
@@ -1397,18 +1352,17 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
1397 | 1352 | ||
1398 | if (enic->vlan_group && vlan_stripped) { | 1353 | if (enic->vlan_group && vlan_stripped) { |
1399 | 1354 | ||
1400 | if ((netdev->features & NETIF_F_LRO) && ipv4) | 1355 | if (netdev->features & NETIF_F_GRO) |
1401 | lro_vlan_hwaccel_receive_skb(&enic->lro_mgr, | 1356 | vlan_gro_receive(&enic->napi, enic->vlan_group, |
1402 | skb, enic->vlan_group, | 1357 | vlan, skb); |
1403 | vlan, cq_desc); | ||
1404 | else | 1358 | else |
1405 | vlan_hwaccel_receive_skb(skb, | 1359 | vlan_hwaccel_receive_skb(skb, |
1406 | enic->vlan_group, vlan); | 1360 | enic->vlan_group, vlan); |
1407 | 1361 | ||
1408 | } else { | 1362 | } else { |
1409 | 1363 | ||
1410 | if ((netdev->features & NETIF_F_LRO) && ipv4) | 1364 | if (netdev->features & NETIF_F_GRO) |
1411 | lro_receive_skb(&enic->lro_mgr, skb, cq_desc); | 1365 | napi_gro_receive(&enic->napi, skb); |
1412 | else | 1366 | else |
1413 | netif_receive_skb(skb); | 1367 | netif_receive_skb(skb); |
1414 | 1368 | ||
@@ -1438,7 +1392,6 @@ static int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, | |||
1438 | static int enic_poll(struct napi_struct *napi, int budget) | 1392 | static int enic_poll(struct napi_struct *napi, int budget) |
1439 | { | 1393 | { |
1440 | struct enic *enic = container_of(napi, struct enic, napi); | 1394 | struct enic *enic = container_of(napi, struct enic, napi); |
1441 | struct net_device *netdev = enic->netdev; | ||
1442 | unsigned int rq_work_to_do = budget; | 1395 | unsigned int rq_work_to_do = budget; |
1443 | unsigned int wq_work_to_do = -1; /* no limit */ | 1396 | unsigned int wq_work_to_do = -1; /* no limit */ |
1444 | unsigned int work_done, rq_work_done, wq_work_done; | 1397 | unsigned int work_done, rq_work_done, wq_work_done; |
@@ -1478,12 +1431,9 @@ static int enic_poll(struct napi_struct *napi, int budget) | |||
1478 | if (rq_work_done < rq_work_to_do) { | 1431 | if (rq_work_done < rq_work_to_do) { |
1479 | 1432 | ||
1480 | /* Some work done, but not enough to stay in polling, | 1433 | /* Some work done, but not enough to stay in polling, |
1481 | * flush all LROs and exit polling | 1434 | * exit polling |
1482 | */ | 1435 | */ |
1483 | 1436 | ||
1484 | if (netdev->features & NETIF_F_LRO) | ||
1485 | lro_flush_all(&enic->lro_mgr); | ||
1486 | |||
1487 | napi_complete(napi); | 1437 | napi_complete(napi); |
1488 | vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); | 1438 | vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); |
1489 | } | 1439 | } |
@@ -1494,7 +1444,6 @@ static int enic_poll(struct napi_struct *napi, int budget) | |||
1494 | static int enic_poll_msix(struct napi_struct *napi, int budget) | 1444 | static int enic_poll_msix(struct napi_struct *napi, int budget) |
1495 | { | 1445 | { |
1496 | struct enic *enic = container_of(napi, struct enic, napi); | 1446 | struct enic *enic = container_of(napi, struct enic, napi); |
1497 | struct net_device *netdev = enic->netdev; | ||
1498 | unsigned int work_to_do = budget; | 1447 | unsigned int work_to_do = budget; |
1499 | unsigned int work_done; | 1448 | unsigned int work_done; |
1500 | int err; | 1449 | int err; |
@@ -1528,12 +1477,9 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) | |||
1528 | if (work_done < work_to_do) { | 1477 | if (work_done < work_to_do) { |
1529 | 1478 | ||
1530 | /* Some work done, but not enough to stay in polling, | 1479 | /* Some work done, but not enough to stay in polling, |
1531 | * flush all LROs and exit polling | 1480 | * exit polling |
1532 | */ | 1481 | */ |
1533 | 1482 | ||
1534 | if (netdev->features & NETIF_F_LRO) | ||
1535 | lro_flush_all(&enic->lro_mgr); | ||
1536 | |||
1537 | napi_complete(napi); | 1483 | napi_complete(napi); |
1538 | vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); | 1484 | vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); |
1539 | } | 1485 | } |
@@ -2378,21 +2324,12 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2378 | netdev->features |= NETIF_F_TSO | | 2324 | netdev->features |= NETIF_F_TSO | |
2379 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; | 2325 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; |
2380 | if (ENIC_SETTING(enic, LRO)) | 2326 | if (ENIC_SETTING(enic, LRO)) |
2381 | netdev->features |= NETIF_F_LRO; | 2327 | netdev->features |= NETIF_F_GRO; |
2382 | if (using_dac) | 2328 | if (using_dac) |
2383 | netdev->features |= NETIF_F_HIGHDMA; | 2329 | netdev->features |= NETIF_F_HIGHDMA; |
2384 | 2330 | ||
2385 | enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); | 2331 | enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); |
2386 | 2332 | ||
2387 | enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR; | ||
2388 | enic->lro_mgr.max_desc = ENIC_LRO_MAX_DESC; | ||
2389 | enic->lro_mgr.lro_arr = enic->lro_desc; | ||
2390 | enic->lro_mgr.get_skb_header = enic_get_skb_header; | ||
2391 | enic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; | ||
2392 | enic->lro_mgr.dev = netdev; | ||
2393 | enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE; | ||
2394 | enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; | ||
2395 | |||
2396 | err = register_netdev(netdev); | 2333 | err = register_netdev(netdev); |
2397 | if (err) { | 2334 | if (err) { |
2398 | printk(KERN_ERR PFX | 2335 | printk(KERN_ERR PFX |