diff options
Diffstat (limited to 'drivers/net/enic/enic_main.c')
-rw-r--r-- | drivers/net/enic/enic_main.c | 79 |
1 files changed, 8 insertions, 71 deletions
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 |