aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-08-23 00:47:36 -0400
committerDavid S. Miller <davem@davemloft.net>2018-08-23 00:47:36 -0400
commit58ce660f911c9fae146a94245efb04b4af6f02a9 (patch)
tree276d8ca08182631f8b91e4fc9e803a3cc95fce6e
parent12a7f8696b85aaff3a76cd12a15b101b2af65404 (diff)
parent339379a2fb13decd1802b403370cc3cdf21d819f (diff)
Merge branch 'hns-fixes'
Huazhong Tan says: ==================== net: hns: bug fixes & optimization for HNS driver This patchset presents some bug fixes found out when CONFIG_ARM64_64K_PAGES enable and an optimization for HNS driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hnae.h6
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_enet.c108
2 files changed, 7 insertions, 107 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h
index fa5b30f547f6..cad52bd331f7 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -220,10 +220,10 @@ struct hnae_desc_cb {
220 220
221 /* priv data for the desc, e.g. skb when use with ip stack*/ 221 /* priv data for the desc, e.g. skb when use with ip stack*/
222 void *priv; 222 void *priv;
223 u16 page_offset; 223 u32 page_offset;
224 u16 reuse_flag; 224 u32 length; /* length of the buffer */
225 225
226 u16 length; /* length of the buffer */ 226 u16 reuse_flag;
227 227
228 /* desc type, used by the ring user to mark the type of the priv data */ 228 /* desc type, used by the ring user to mark the type of the priv data */
229 u16 type; 229 u16 type;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 9f2b552aee33..02a0ba20fad5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -406,113 +406,13 @@ out_net_tx_busy:
406 return NETDEV_TX_BUSY; 406 return NETDEV_TX_BUSY;
407} 407}
408 408
409/**
410 * hns_nic_get_headlen - determine size of header for RSC/LRO/GRO/FCOE
411 * @data: pointer to the start of the headers
412 * @max: total length of section to find headers in
413 *
414 * This function is meant to determine the length of headers that will
415 * be recognized by hardware for LRO, GRO, and RSC offloads. The main
416 * motivation of doing this is to only perform one pull for IPv4 TCP
417 * packets so that we can do basic things like calculating the gso_size
418 * based on the average data per packet.
419 **/
420static unsigned int hns_nic_get_headlen(unsigned char *data, u32 flag,
421 unsigned int max_size)
422{
423 unsigned char *network;
424 u8 hlen;
425
426 /* this should never happen, but better safe than sorry */
427 if (max_size < ETH_HLEN)
428 return max_size;
429
430 /* initialize network frame pointer */
431 network = data;
432
433 /* set first protocol and move network header forward */
434 network += ETH_HLEN;
435
436 /* handle any vlan tag if present */
437 if (hnae_get_field(flag, HNS_RXD_VLAN_M, HNS_RXD_VLAN_S)
438 == HNS_RX_FLAG_VLAN_PRESENT) {
439 if ((typeof(max_size))(network - data) > (max_size - VLAN_HLEN))
440 return max_size;
441
442 network += VLAN_HLEN;
443 }
444
445 /* handle L3 protocols */
446 if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
447 == HNS_RX_FLAG_L3ID_IPV4) {
448 if ((typeof(max_size))(network - data) >
449 (max_size - sizeof(struct iphdr)))
450 return max_size;
451
452 /* access ihl as a u8 to avoid unaligned access on ia64 */
453 hlen = (network[0] & 0x0F) << 2;
454
455 /* verify hlen meets minimum size requirements */
456 if (hlen < sizeof(struct iphdr))
457 return network - data;
458
459 /* record next protocol if header is present */
460 } else if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
461 == HNS_RX_FLAG_L3ID_IPV6) {
462 if ((typeof(max_size))(network - data) >
463 (max_size - sizeof(struct ipv6hdr)))
464 return max_size;
465
466 /* record next protocol */
467 hlen = sizeof(struct ipv6hdr);
468 } else {
469 return network - data;
470 }
471
472 /* relocate pointer to start of L4 header */
473 network += hlen;
474
475 /* finally sort out TCP/UDP */
476 if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
477 == HNS_RX_FLAG_L4ID_TCP) {
478 if ((typeof(max_size))(network - data) >
479 (max_size - sizeof(struct tcphdr)))
480 return max_size;
481
482 /* access doff as a u8 to avoid unaligned access on ia64 */
483 hlen = (network[12] & 0xF0) >> 2;
484
485 /* verify hlen meets minimum size requirements */
486 if (hlen < sizeof(struct tcphdr))
487 return network - data;
488
489 network += hlen;
490 } else if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
491 == HNS_RX_FLAG_L4ID_UDP) {
492 if ((typeof(max_size))(network - data) >
493 (max_size - sizeof(struct udphdr)))
494 return max_size;
495
496 network += sizeof(struct udphdr);
497 }
498
499 /* If everything has gone correctly network should be the
500 * data section of the packet and will be the end of the header.
501 * If not then it probably represents the end of the last recognized
502 * header.
503 */
504 if ((typeof(max_size))(network - data) < max_size)
505 return network - data;
506 else
507 return max_size;
508}
509
510static void hns_nic_reuse_page(struct sk_buff *skb, int i, 409static void hns_nic_reuse_page(struct sk_buff *skb, int i,
511 struct hnae_ring *ring, int pull_len, 410 struct hnae_ring *ring, int pull_len,
512 struct hnae_desc_cb *desc_cb) 411 struct hnae_desc_cb *desc_cb)
513{ 412{
514 struct hnae_desc *desc; 413 struct hnae_desc *desc;
515 int truesize, size; 414 u32 truesize;
415 int size;
516 int last_offset; 416 int last_offset;
517 bool twobufs; 417 bool twobufs;
518 418
@@ -530,7 +430,7 @@ static void hns_nic_reuse_page(struct sk_buff *skb, int i,
530 } 430 }
531 431
532 skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len, 432 skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len,
533 size - pull_len, truesize - pull_len); 433 size - pull_len, truesize);
534 434
535 /* avoid re-using remote pages,flag default unreuse */ 435 /* avoid re-using remote pages,flag default unreuse */
536 if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id())) 436 if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id()))
@@ -695,7 +595,7 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
695 } else { 595 } else {
696 ring->stats.seg_pkt_cnt++; 596 ring->stats.seg_pkt_cnt++;
697 597
698 pull_len = hns_nic_get_headlen(va, bnum_flag, HNS_RX_HEAD_SIZE); 598 pull_len = eth_get_headlen(va, HNS_RX_HEAD_SIZE);
699 memcpy(__skb_put(skb, pull_len), va, 599 memcpy(__skb_put(skb, pull_len), va,
700 ALIGN(pull_len, sizeof(long))); 600 ALIGN(pull_len, sizeof(long)));
701 601