diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 267 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 33 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 |
5 files changed, 171 insertions, 169 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 4b90b518d6a6..0f7b7a463eba 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -293,8 +293,13 @@ enum { | |||
293 | #define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp)) | 293 | #define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp)) |
294 | 294 | ||
295 | /* fast path */ | 295 | /* fast path */ |
296 | /* | ||
297 | * This driver uses new build_skb() API : | ||
298 | * RX ring buffer contains pointer to kmalloc() data only, | ||
299 | * skb are built only after Hardware filled the frame. | ||
300 | */ | ||
296 | struct sw_rx_bd { | 301 | struct sw_rx_bd { |
297 | struct sk_buff *skb; | 302 | u8 *data; |
298 | DEFINE_DMA_UNMAP_ADDR(mapping); | 303 | DEFINE_DMA_UNMAP_ADDR(mapping); |
299 | }; | 304 | }; |
300 | 305 | ||
@@ -424,8 +429,8 @@ union host_hc_status_block { | |||
424 | 429 | ||
425 | struct bnx2x_agg_info { | 430 | struct bnx2x_agg_info { |
426 | /* | 431 | /* |
427 | * First aggregation buffer is an skb, the following - are pages. | 432 | * First aggregation buffer is a data buffer, the following - are pages. |
428 | * We will preallocate the skbs for each aggregation when | 433 | * We will preallocate the data buffer for each aggregation when |
429 | * we open the interface and will replace the BD at the consumer | 434 | * we open the interface and will replace the BD at the consumer |
430 | * with this one when we receive the TPA_START CQE in order to | 435 | * with this one when we receive the TPA_START CQE in order to |
431 | * keep the Rx BD ring consistent. | 436 | * keep the Rx BD ring consistent. |
@@ -439,6 +444,7 @@ struct bnx2x_agg_info { | |||
439 | u16 parsing_flags; | 444 | u16 parsing_flags; |
440 | u16 vlan_tag; | 445 | u16 vlan_tag; |
441 | u16 len_on_bd; | 446 | u16 len_on_bd; |
447 | u32 rxhash; | ||
442 | }; | 448 | }; |
443 | 449 | ||
444 | #define Q_STATS_OFFSET32(stat_name) \ | 450 | #define Q_STATS_OFFSET32(stat_name) \ |
@@ -1187,10 +1193,20 @@ struct bnx2x { | |||
1187 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 | 1193 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 |
1188 | 1194 | ||
1189 | /* Max supported alignment is 256 (8 shift) */ | 1195 | /* Max supported alignment is 256 (8 shift) */ |
1190 | #define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \ | 1196 | #define BNX2X_RX_ALIGN_SHIFT min(8, L1_CACHE_SHIFT) |
1191 | L1_CACHE_SHIFT : 8) | 1197 | |
1192 | /* FW use 2 Cache lines Alignment for start packet and size */ | 1198 | /* FW uses 2 Cache lines Alignment for start packet and size |
1193 | #define BNX2X_FW_RX_ALIGN (2 << BNX2X_RX_ALIGN_SHIFT) | 1199 | * |
1200 | * We assume skb_build() uses sizeof(struct skb_shared_info) bytes | ||
1201 | * at the end of skb->data, to avoid wasting a full cache line. | ||
1202 | * This reduces memory use (skb->truesize). | ||
1203 | */ | ||
1204 | #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) | ||
1205 | |||
1206 | #define BNX2X_FW_RX_ALIGN_END \ | ||
1207 | max(1UL << BNX2X_RX_ALIGN_SHIFT, \ | ||
1208 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | ||
1209 | |||
1194 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) | 1210 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) |
1195 | 1211 | ||
1196 | struct host_sp_status_block *def_status_blk; | 1212 | struct host_sp_status_block *def_status_blk; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 13dad9230dbc..0d60b9e633ad 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -294,8 +294,21 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, | |||
294 | fp->last_max_sge, fp->rx_sge_prod); | 294 | fp->last_max_sge, fp->rx_sge_prod); |
295 | } | 295 | } |
296 | 296 | ||
297 | /* Set Toeplitz hash value in the skb using the value from the | ||
298 | * CQE (calculated by HW). | ||
299 | */ | ||
300 | static u32 bnx2x_get_rxhash(const struct bnx2x *bp, | ||
301 | const struct eth_fast_path_rx_cqe *cqe) | ||
302 | { | ||
303 | /* Set Toeplitz hash from CQE */ | ||
304 | if ((bp->dev->features & NETIF_F_RXHASH) && | ||
305 | (cqe->status_flags & ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) | ||
306 | return le32_to_cpu(cqe->rss_hash_result); | ||
307 | return 0; | ||
308 | } | ||
309 | |||
297 | static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | 310 | static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, |
298 | struct sk_buff *skb, u16 cons, u16 prod, | 311 | u16 cons, u16 prod, |
299 | struct eth_fast_path_rx_cqe *cqe) | 312 | struct eth_fast_path_rx_cqe *cqe) |
300 | { | 313 | { |
301 | struct bnx2x *bp = fp->bp; | 314 | struct bnx2x *bp = fp->bp; |
@@ -310,9 +323,9 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
310 | if (tpa_info->tpa_state != BNX2X_TPA_STOP) | 323 | if (tpa_info->tpa_state != BNX2X_TPA_STOP) |
311 | BNX2X_ERR("start of bin not in stop [%d]\n", queue); | 324 | BNX2X_ERR("start of bin not in stop [%d]\n", queue); |
312 | 325 | ||
313 | /* Try to map an empty skb from the aggregation info */ | 326 | /* Try to map an empty data buffer from the aggregation info */ |
314 | mapping = dma_map_single(&bp->pdev->dev, | 327 | mapping = dma_map_single(&bp->pdev->dev, |
315 | first_buf->skb->data, | 328 | first_buf->data + NET_SKB_PAD, |
316 | fp->rx_buf_size, DMA_FROM_DEVICE); | 329 | fp->rx_buf_size, DMA_FROM_DEVICE); |
317 | /* | 330 | /* |
318 | * ...if it fails - move the skb from the consumer to the producer | 331 | * ...if it fails - move the skb from the consumer to the producer |
@@ -322,15 +335,15 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
322 | 335 | ||
323 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { | 336 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { |
324 | /* Move the BD from the consumer to the producer */ | 337 | /* Move the BD from the consumer to the producer */ |
325 | bnx2x_reuse_rx_skb(fp, cons, prod); | 338 | bnx2x_reuse_rx_data(fp, cons, prod); |
326 | tpa_info->tpa_state = BNX2X_TPA_ERROR; | 339 | tpa_info->tpa_state = BNX2X_TPA_ERROR; |
327 | return; | 340 | return; |
328 | } | 341 | } |
329 | 342 | ||
330 | /* move empty skb from pool to prod */ | 343 | /* move empty data from pool to prod */ |
331 | prod_rx_buf->skb = first_buf->skb; | 344 | prod_rx_buf->data = first_buf->data; |
332 | dma_unmap_addr_set(prod_rx_buf, mapping, mapping); | 345 | dma_unmap_addr_set(prod_rx_buf, mapping, mapping); |
333 | /* point prod_bd to new skb */ | 346 | /* point prod_bd to new data */ |
334 | prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); | 347 | prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); |
335 | prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); | 348 | prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); |
336 | 349 | ||
@@ -344,6 +357,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
344 | tpa_info->tpa_state = BNX2X_TPA_START; | 357 | tpa_info->tpa_state = BNX2X_TPA_START; |
345 | tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd); | 358 | tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd); |
346 | tpa_info->placement_offset = cqe->placement_offset; | 359 | tpa_info->placement_offset = cqe->placement_offset; |
360 | tpa_info->rxhash = bnx2x_get_rxhash(bp, cqe); | ||
347 | 361 | ||
348 | #ifdef BNX2X_STOP_ON_ERROR | 362 | #ifdef BNX2X_STOP_ON_ERROR |
349 | fp->tpa_queue_used |= (1 << queue); | 363 | fp->tpa_queue_used |= (1 << queue); |
@@ -471,11 +485,12 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
471 | { | 485 | { |
472 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; | 486 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; |
473 | struct sw_rx_bd *rx_buf = &tpa_info->first_buf; | 487 | struct sw_rx_bd *rx_buf = &tpa_info->first_buf; |
474 | u8 pad = tpa_info->placement_offset; | 488 | u32 pad = tpa_info->placement_offset; |
475 | u16 len = tpa_info->len_on_bd; | 489 | u16 len = tpa_info->len_on_bd; |
476 | struct sk_buff *skb = rx_buf->skb; | 490 | struct sk_buff *skb = NULL; |
491 | u8 *data = rx_buf->data; | ||
477 | /* alloc new skb */ | 492 | /* alloc new skb */ |
478 | struct sk_buff *new_skb; | 493 | u8 *new_data; |
479 | u8 old_tpa_state = tpa_info->tpa_state; | 494 | u8 old_tpa_state = tpa_info->tpa_state; |
480 | 495 | ||
481 | tpa_info->tpa_state = BNX2X_TPA_STOP; | 496 | tpa_info->tpa_state = BNX2X_TPA_STOP; |
@@ -486,18 +501,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
486 | if (old_tpa_state == BNX2X_TPA_ERROR) | 501 | if (old_tpa_state == BNX2X_TPA_ERROR) |
487 | goto drop; | 502 | goto drop; |
488 | 503 | ||
489 | /* Try to allocate the new skb */ | 504 | /* Try to allocate the new data */ |
490 | new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); | 505 | new_data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC); |
491 | 506 | ||
492 | /* Unmap skb in the pool anyway, as we are going to change | 507 | /* Unmap skb in the pool anyway, as we are going to change |
493 | pool entry status to BNX2X_TPA_STOP even if new skb allocation | 508 | pool entry status to BNX2X_TPA_STOP even if new skb allocation |
494 | fails. */ | 509 | fails. */ |
495 | dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), | 510 | dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), |
496 | fp->rx_buf_size, DMA_FROM_DEVICE); | 511 | fp->rx_buf_size, DMA_FROM_DEVICE); |
512 | if (likely(new_data)) | ||
513 | skb = build_skb(data); | ||
497 | 514 | ||
498 | if (likely(new_skb)) { | 515 | if (likely(skb)) { |
499 | prefetch(skb); | ||
500 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | ||
501 | 516 | ||
502 | #ifdef BNX2X_STOP_ON_ERROR | 517 | #ifdef BNX2X_STOP_ON_ERROR |
503 | if (pad + len > fp->rx_buf_size) { | 518 | if (pad + len > fp->rx_buf_size) { |
@@ -509,8 +524,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
509 | } | 524 | } |
510 | #endif | 525 | #endif |
511 | 526 | ||
512 | skb_reserve(skb, pad); | 527 | skb_reserve(skb, pad + NET_SKB_PAD); |
513 | skb_put(skb, len); | 528 | skb_put(skb, len); |
529 | skb->rxhash = tpa_info->rxhash; | ||
514 | 530 | ||
515 | skb->protocol = eth_type_trans(skb, bp->dev); | 531 | skb->protocol = eth_type_trans(skb, bp->dev); |
516 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 532 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -526,8 +542,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
526 | } | 542 | } |
527 | 543 | ||
528 | 544 | ||
529 | /* put new skb in bin */ | 545 | /* put new data in bin */ |
530 | rx_buf->skb = new_skb; | 546 | rx_buf->data = new_data; |
531 | 547 | ||
532 | return; | 548 | return; |
533 | } | 549 | } |
@@ -539,19 +555,6 @@ drop: | |||
539 | fp->eth_q_stats.rx_skb_alloc_failed++; | 555 | fp->eth_q_stats.rx_skb_alloc_failed++; |
540 | } | 556 | } |
541 | 557 | ||
542 | /* Set Toeplitz hash value in the skb using the value from the | ||
543 | * CQE (calculated by HW). | ||
544 | */ | ||
545 | static inline void bnx2x_set_skb_rxhash(struct bnx2x *bp, union eth_rx_cqe *cqe, | ||
546 | struct sk_buff *skb) | ||
547 | { | ||
548 | /* Set Toeplitz hash from CQE */ | ||
549 | if ((bp->dev->features & NETIF_F_RXHASH) && | ||
550 | (cqe->fast_path_cqe.status_flags & | ||
551 | ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) | ||
552 | skb->rxhash = | ||
553 | le32_to_cpu(cqe->fast_path_cqe.rss_hash_result); | ||
554 | } | ||
555 | 558 | ||
556 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | 559 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) |
557 | { | 560 | { |
@@ -594,6 +597,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
594 | u8 cqe_fp_flags; | 597 | u8 cqe_fp_flags; |
595 | enum eth_rx_cqe_type cqe_fp_type; | 598 | enum eth_rx_cqe_type cqe_fp_type; |
596 | u16 len, pad; | 599 | u16 len, pad; |
600 | u8 *data; | ||
597 | 601 | ||
598 | #ifdef BNX2X_STOP_ON_ERROR | 602 | #ifdef BNX2X_STOP_ON_ERROR |
599 | if (unlikely(bp->panic)) | 603 | if (unlikely(bp->panic)) |
@@ -604,13 +608,6 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
604 | bd_prod = RX_BD(bd_prod); | 608 | bd_prod = RX_BD(bd_prod); |
605 | bd_cons = RX_BD(bd_cons); | 609 | bd_cons = RX_BD(bd_cons); |
606 | 610 | ||
607 | /* Prefetch the page containing the BD descriptor | ||
608 | at producer's index. It will be needed when new skb is | ||
609 | allocated */ | ||
610 | prefetch((void *)(PAGE_ALIGN((unsigned long) | ||
611 | (&fp->rx_desc_ring[bd_prod])) - | ||
612 | PAGE_SIZE + 1)); | ||
613 | |||
614 | cqe = &fp->rx_comp_ring[comp_ring_cons]; | 611 | cqe = &fp->rx_comp_ring[comp_ring_cons]; |
615 | cqe_fp = &cqe->fast_path_cqe; | 612 | cqe_fp = &cqe->fast_path_cqe; |
616 | cqe_fp_flags = cqe_fp->type_error_flags; | 613 | cqe_fp_flags = cqe_fp->type_error_flags; |
@@ -626,125 +623,110 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
626 | if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) { | 623 | if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) { |
627 | bnx2x_sp_event(fp, cqe); | 624 | bnx2x_sp_event(fp, cqe); |
628 | goto next_cqe; | 625 | goto next_cqe; |
626 | } | ||
627 | rx_buf = &fp->rx_buf_ring[bd_cons]; | ||
628 | data = rx_buf->data; | ||
629 | 629 | ||
630 | /* this is an rx packet */ | 630 | if (!CQE_TYPE_FAST(cqe_fp_type)) { |
631 | } else { | ||
632 | rx_buf = &fp->rx_buf_ring[bd_cons]; | ||
633 | skb = rx_buf->skb; | ||
634 | prefetch(skb); | ||
635 | |||
636 | if (!CQE_TYPE_FAST(cqe_fp_type)) { | ||
637 | #ifdef BNX2X_STOP_ON_ERROR | 631 | #ifdef BNX2X_STOP_ON_ERROR |
638 | /* sanity check */ | 632 | /* sanity check */ |
639 | if (fp->disable_tpa && | 633 | if (fp->disable_tpa && |
640 | (CQE_TYPE_START(cqe_fp_type) || | 634 | (CQE_TYPE_START(cqe_fp_type) || |
641 | CQE_TYPE_STOP(cqe_fp_type))) | 635 | CQE_TYPE_STOP(cqe_fp_type))) |
642 | BNX2X_ERR("START/STOP packet while " | 636 | BNX2X_ERR("START/STOP packet while " |
643 | "disable_tpa type %x\n", | 637 | "disable_tpa type %x\n", |
644 | CQE_TYPE(cqe_fp_type)); | 638 | CQE_TYPE(cqe_fp_type)); |
645 | #endif | 639 | #endif |
646 | 640 | ||
647 | if (CQE_TYPE_START(cqe_fp_type)) { | 641 | if (CQE_TYPE_START(cqe_fp_type)) { |
648 | u16 queue = cqe_fp->queue_index; | 642 | u16 queue = cqe_fp->queue_index; |
649 | DP(NETIF_MSG_RX_STATUS, | 643 | DP(NETIF_MSG_RX_STATUS, |
650 | "calling tpa_start on queue %d\n", | 644 | "calling tpa_start on queue %d\n", |
651 | queue); | 645 | queue); |
652 | |||
653 | bnx2x_tpa_start(fp, queue, skb, | ||
654 | bd_cons, bd_prod, | ||
655 | cqe_fp); | ||
656 | |||
657 | /* Set Toeplitz hash for LRO skb */ | ||
658 | bnx2x_set_skb_rxhash(bp, cqe, skb); | ||
659 | |||
660 | goto next_rx; | ||
661 | |||
662 | } else { | ||
663 | u16 queue = | ||
664 | cqe->end_agg_cqe.queue_index; | ||
665 | DP(NETIF_MSG_RX_STATUS, | ||
666 | "calling tpa_stop on queue %d\n", | ||
667 | queue); | ||
668 | 646 | ||
669 | bnx2x_tpa_stop(bp, fp, queue, | 647 | bnx2x_tpa_start(fp, queue, |
670 | &cqe->end_agg_cqe, | 648 | bd_cons, bd_prod, |
671 | comp_ring_cons); | 649 | cqe_fp); |
650 | goto next_rx; | ||
651 | } else { | ||
652 | u16 queue = | ||
653 | cqe->end_agg_cqe.queue_index; | ||
654 | DP(NETIF_MSG_RX_STATUS, | ||
655 | "calling tpa_stop on queue %d\n", | ||
656 | queue); | ||
657 | |||
658 | bnx2x_tpa_stop(bp, fp, queue, | ||
659 | &cqe->end_agg_cqe, | ||
660 | comp_ring_cons); | ||
672 | #ifdef BNX2X_STOP_ON_ERROR | 661 | #ifdef BNX2X_STOP_ON_ERROR |
673 | if (bp->panic) | 662 | if (bp->panic) |
674 | return 0; | 663 | return 0; |
675 | #endif | 664 | #endif |
676 | 665 | ||
677 | bnx2x_update_sge_prod(fp, cqe_fp); | 666 | bnx2x_update_sge_prod(fp, cqe_fp); |
678 | goto next_cqe; | 667 | goto next_cqe; |
679 | } | ||
680 | } | 668 | } |
681 | /* non TPA */ | 669 | } |
682 | len = le16_to_cpu(cqe_fp->pkt_len); | 670 | /* non TPA */ |
683 | pad = cqe_fp->placement_offset; | 671 | len = le16_to_cpu(cqe_fp->pkt_len); |
684 | dma_sync_single_for_cpu(&bp->pdev->dev, | 672 | pad = cqe_fp->placement_offset; |
673 | dma_sync_single_for_cpu(&bp->pdev->dev, | ||
685 | dma_unmap_addr(rx_buf, mapping), | 674 | dma_unmap_addr(rx_buf, mapping), |
686 | pad + RX_COPY_THRESH, | 675 | pad + RX_COPY_THRESH, |
687 | DMA_FROM_DEVICE); | 676 | DMA_FROM_DEVICE); |
688 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | 677 | pad += NET_SKB_PAD; |
678 | prefetch(data + pad); /* speedup eth_type_trans() */ | ||
679 | /* is this an error packet? */ | ||
680 | if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { | ||
681 | DP(NETIF_MSG_RX_ERR, | ||
682 | "ERROR flags %x rx packet %u\n", | ||
683 | cqe_fp_flags, sw_comp_cons); | ||
684 | fp->eth_q_stats.rx_err_discard_pkt++; | ||
685 | goto reuse_rx; | ||
686 | } | ||
689 | 687 | ||
690 | /* is this an error packet? */ | 688 | /* Since we don't have a jumbo ring |
691 | if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { | 689 | * copy small packets if mtu > 1500 |
690 | */ | ||
691 | if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && | ||
692 | (len <= RX_COPY_THRESH)) { | ||
693 | skb = netdev_alloc_skb_ip_align(bp->dev, len); | ||
694 | if (skb == NULL) { | ||
692 | DP(NETIF_MSG_RX_ERR, | 695 | DP(NETIF_MSG_RX_ERR, |
693 | "ERROR flags %x rx packet %u\n", | 696 | "ERROR packet dropped because of alloc failure\n"); |
694 | cqe_fp_flags, sw_comp_cons); | 697 | fp->eth_q_stats.rx_skb_alloc_failed++; |
695 | fp->eth_q_stats.rx_err_discard_pkt++; | ||
696 | goto reuse_rx; | 698 | goto reuse_rx; |
697 | } | 699 | } |
698 | 700 | memcpy(skb->data, data + pad, len); | |
699 | /* Since we don't have a jumbo ring | 701 | bnx2x_reuse_rx_data(fp, bd_cons, bd_prod); |
700 | * copy small packets if mtu > 1500 | 702 | } else { |
701 | */ | 703 | if (likely(bnx2x_alloc_rx_data(bp, fp, bd_prod) == 0)) { |
702 | if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && | ||
703 | (len <= RX_COPY_THRESH)) { | ||
704 | struct sk_buff *new_skb; | ||
705 | |||
706 | new_skb = netdev_alloc_skb(bp->dev, len + pad); | ||
707 | if (new_skb == NULL) { | ||
708 | DP(NETIF_MSG_RX_ERR, | ||
709 | "ERROR packet dropped " | ||
710 | "because of alloc failure\n"); | ||
711 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
712 | goto reuse_rx; | ||
713 | } | ||
714 | |||
715 | /* aligned copy */ | ||
716 | skb_copy_from_linear_data_offset(skb, pad, | ||
717 | new_skb->data + pad, len); | ||
718 | skb_reserve(new_skb, pad); | ||
719 | skb_put(new_skb, len); | ||
720 | |||
721 | bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); | ||
722 | |||
723 | skb = new_skb; | ||
724 | |||
725 | } else | ||
726 | if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) { | ||
727 | dma_unmap_single(&bp->pdev->dev, | 704 | dma_unmap_single(&bp->pdev->dev, |
728 | dma_unmap_addr(rx_buf, mapping), | 705 | dma_unmap_addr(rx_buf, mapping), |
729 | fp->rx_buf_size, | 706 | fp->rx_buf_size, |
730 | DMA_FROM_DEVICE); | 707 | DMA_FROM_DEVICE); |
708 | skb = build_skb(data); | ||
709 | if (unlikely(!skb)) { | ||
710 | kfree(data); | ||
711 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
712 | goto next_rx; | ||
713 | } | ||
731 | skb_reserve(skb, pad); | 714 | skb_reserve(skb, pad); |
732 | skb_put(skb, len); | ||
733 | |||
734 | } else { | 715 | } else { |
735 | DP(NETIF_MSG_RX_ERR, | 716 | DP(NETIF_MSG_RX_ERR, |
736 | "ERROR packet dropped because " | 717 | "ERROR packet dropped because " |
737 | "of alloc failure\n"); | 718 | "of alloc failure\n"); |
738 | fp->eth_q_stats.rx_skb_alloc_failed++; | 719 | fp->eth_q_stats.rx_skb_alloc_failed++; |
739 | reuse_rx: | 720 | reuse_rx: |
740 | bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); | 721 | bnx2x_reuse_rx_data(fp, bd_cons, bd_prod); |
741 | goto next_rx; | 722 | goto next_rx; |
742 | } | 723 | } |
743 | 724 | ||
725 | skb_put(skb, len); | ||
744 | skb->protocol = eth_type_trans(skb, bp->dev); | 726 | skb->protocol = eth_type_trans(skb, bp->dev); |
745 | 727 | ||
746 | /* Set Toeplitz hash for a none-LRO skb */ | 728 | /* Set Toeplitz hash for a none-LRO skb */ |
747 | bnx2x_set_skb_rxhash(bp, cqe, skb); | 729 | skb->rxhash = bnx2x_get_rxhash(bp, cqe_fp); |
748 | 730 | ||
749 | skb_checksum_none_assert(skb); | 731 | skb_checksum_none_assert(skb); |
750 | 732 | ||
@@ -767,7 +749,7 @@ reuse_rx: | |||
767 | 749 | ||
768 | 750 | ||
769 | next_rx: | 751 | next_rx: |
770 | rx_buf->skb = NULL; | 752 | rx_buf->data = NULL; |
771 | 753 | ||
772 | bd_cons = NEXT_RX_IDX(bd_cons); | 754 | bd_cons = NEXT_RX_IDX(bd_cons); |
773 | bd_prod = NEXT_RX_IDX(bd_prod); | 755 | bd_prod = NEXT_RX_IDX(bd_prod); |
@@ -1013,9 +995,9 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
1013 | struct sw_rx_bd *first_buf = | 995 | struct sw_rx_bd *first_buf = |
1014 | &tpa_info->first_buf; | 996 | &tpa_info->first_buf; |
1015 | 997 | ||
1016 | first_buf->skb = netdev_alloc_skb(bp->dev, | 998 | first_buf->data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, |
1017 | fp->rx_buf_size); | 999 | GFP_ATOMIC); |
1018 | if (!first_buf->skb) { | 1000 | if (!first_buf->data) { |
1019 | BNX2X_ERR("Failed to allocate TPA " | 1001 | BNX2X_ERR("Failed to allocate TPA " |
1020 | "skb pool for queue[%d] - " | 1002 | "skb pool for queue[%d] - " |
1021 | "disabling TPA on this " | 1003 | "disabling TPA on this " |
@@ -1118,16 +1100,16 @@ static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp) | |||
1118 | 1100 | ||
1119 | for (i = 0; i < NUM_RX_BD; i++) { | 1101 | for (i = 0; i < NUM_RX_BD; i++) { |
1120 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; | 1102 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; |
1121 | struct sk_buff *skb = rx_buf->skb; | 1103 | u8 *data = rx_buf->data; |
1122 | 1104 | ||
1123 | if (skb == NULL) | 1105 | if (data == NULL) |
1124 | continue; | 1106 | continue; |
1125 | dma_unmap_single(&bp->pdev->dev, | 1107 | dma_unmap_single(&bp->pdev->dev, |
1126 | dma_unmap_addr(rx_buf, mapping), | 1108 | dma_unmap_addr(rx_buf, mapping), |
1127 | fp->rx_buf_size, DMA_FROM_DEVICE); | 1109 | fp->rx_buf_size, DMA_FROM_DEVICE); |
1128 | 1110 | ||
1129 | rx_buf->skb = NULL; | 1111 | rx_buf->data = NULL; |
1130 | dev_kfree_skb(skb); | 1112 | kfree(data); |
1131 | } | 1113 | } |
1132 | } | 1114 | } |
1133 | 1115 | ||
@@ -1509,6 +1491,7 @@ static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) | |||
1509 | 1491 | ||
1510 | for_each_queue(bp, i) { | 1492 | for_each_queue(bp, i) { |
1511 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 1493 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
1494 | u32 mtu; | ||
1512 | 1495 | ||
1513 | /* Always use a mini-jumbo MTU for the FCoE L2 ring */ | 1496 | /* Always use a mini-jumbo MTU for the FCoE L2 ring */ |
1514 | if (IS_FCOE_IDX(i)) | 1497 | if (IS_FCOE_IDX(i)) |
@@ -1518,13 +1501,15 @@ static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) | |||
1518 | * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer | 1501 | * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer |
1519 | * overrun attack. | 1502 | * overrun attack. |
1520 | */ | 1503 | */ |
1521 | fp->rx_buf_size = | 1504 | mtu = BNX2X_FCOE_MINI_JUMBO_MTU; |
1522 | BNX2X_FCOE_MINI_JUMBO_MTU + ETH_OVREHEAD + | ||
1523 | BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; | ||
1524 | else | 1505 | else |
1525 | fp->rx_buf_size = | 1506 | mtu = bp->dev->mtu; |
1526 | bp->dev->mtu + ETH_OVREHEAD + | 1507 | fp->rx_buf_size = BNX2X_FW_RX_ALIGN_START + |
1527 | BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; | 1508 | IP_HEADER_ALIGNMENT_PADDING + |
1509 | ETH_OVREHEAD + | ||
1510 | mtu + | ||
1511 | BNX2X_FW_RX_ALIGN_END; | ||
1512 | /* Note : rx_buf_size doesnt take into account NET_SKB_PAD */ | ||
1528 | } | 1513 | } |
1529 | } | 1514 | } |
1530 | 1515 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 260226d09916..41eb17e7720f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -910,26 +910,27 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, | |||
910 | return 0; | 910 | return 0; |
911 | } | 911 | } |
912 | 912 | ||
913 | static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, | 913 | static inline int bnx2x_alloc_rx_data(struct bnx2x *bp, |
914 | struct bnx2x_fastpath *fp, u16 index) | 914 | struct bnx2x_fastpath *fp, u16 index) |
915 | { | 915 | { |
916 | struct sk_buff *skb; | 916 | u8 *data; |
917 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index]; | 917 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index]; |
918 | struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; | 918 | struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; |
919 | dma_addr_t mapping; | 919 | dma_addr_t mapping; |
920 | 920 | ||
921 | skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); | 921 | data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC); |
922 | if (unlikely(skb == NULL)) | 922 | if (unlikely(data == NULL)) |
923 | return -ENOMEM; | 923 | return -ENOMEM; |
924 | 924 | ||
925 | mapping = dma_map_single(&bp->pdev->dev, skb->data, fp->rx_buf_size, | 925 | mapping = dma_map_single(&bp->pdev->dev, data + NET_SKB_PAD, |
926 | fp->rx_buf_size, | ||
926 | DMA_FROM_DEVICE); | 927 | DMA_FROM_DEVICE); |
927 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { | 928 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { |
928 | dev_kfree_skb_any(skb); | 929 | kfree(data); |
929 | return -ENOMEM; | 930 | return -ENOMEM; |
930 | } | 931 | } |
931 | 932 | ||
932 | rx_buf->skb = skb; | 933 | rx_buf->data = data; |
933 | dma_unmap_addr_set(rx_buf, mapping, mapping); | 934 | dma_unmap_addr_set(rx_buf, mapping, mapping); |
934 | 935 | ||
935 | rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); | 936 | rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); |
@@ -938,12 +939,12 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, | |||
938 | return 0; | 939 | return 0; |
939 | } | 940 | } |
940 | 941 | ||
941 | /* note that we are not allocating a new skb, | 942 | /* note that we are not allocating a new buffer, |
942 | * we are just moving one from cons to prod | 943 | * we are just moving one from cons to prod |
943 | * we are not creating a new mapping, | 944 | * we are not creating a new mapping, |
944 | * so there is no need to check for dma_mapping_error(). | 945 | * so there is no need to check for dma_mapping_error(). |
945 | */ | 946 | */ |
946 | static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, | 947 | static inline void bnx2x_reuse_rx_data(struct bnx2x_fastpath *fp, |
947 | u16 cons, u16 prod) | 948 | u16 cons, u16 prod) |
948 | { | 949 | { |
949 | struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; | 950 | struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; |
@@ -953,7 +954,7 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, | |||
953 | 954 | ||
954 | dma_unmap_addr_set(prod_rx_buf, mapping, | 955 | dma_unmap_addr_set(prod_rx_buf, mapping, |
955 | dma_unmap_addr(cons_rx_buf, mapping)); | 956 | dma_unmap_addr(cons_rx_buf, mapping)); |
956 | prod_rx_buf->skb = cons_rx_buf->skb; | 957 | prod_rx_buf->data = cons_rx_buf->data; |
957 | *prod_bd = *cons_bd; | 958 | *prod_bd = *cons_bd; |
958 | } | 959 | } |
959 | 960 | ||
@@ -1029,9 +1030,9 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, | |||
1029 | for (i = 0; i < last; i++) { | 1030 | for (i = 0; i < last; i++) { |
1030 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[i]; | 1031 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[i]; |
1031 | struct sw_rx_bd *first_buf = &tpa_info->first_buf; | 1032 | struct sw_rx_bd *first_buf = &tpa_info->first_buf; |
1032 | struct sk_buff *skb = first_buf->skb; | 1033 | u8 *data = first_buf->data; |
1033 | 1034 | ||
1034 | if (skb == NULL) { | 1035 | if (data == NULL) { |
1035 | DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i); | 1036 | DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i); |
1036 | continue; | 1037 | continue; |
1037 | } | 1038 | } |
@@ -1039,8 +1040,8 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, | |||
1039 | dma_unmap_single(&bp->pdev->dev, | 1040 | dma_unmap_single(&bp->pdev->dev, |
1040 | dma_unmap_addr(first_buf, mapping), | 1041 | dma_unmap_addr(first_buf, mapping), |
1041 | fp->rx_buf_size, DMA_FROM_DEVICE); | 1042 | fp->rx_buf_size, DMA_FROM_DEVICE); |
1042 | dev_kfree_skb(skb); | 1043 | kfree(data); |
1043 | first_buf->skb = NULL; | 1044 | first_buf->data = NULL; |
1044 | } | 1045 | } |
1045 | } | 1046 | } |
1046 | 1047 | ||
@@ -1148,7 +1149,7 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, | |||
1148 | * fp->eth_q_stats.rx_skb_alloc_failed = 0 | 1149 | * fp->eth_q_stats.rx_skb_alloc_failed = 0 |
1149 | */ | 1150 | */ |
1150 | for (i = 0; i < rx_ring_size; i++) { | 1151 | for (i = 0; i < rx_ring_size; i++) { |
1151 | if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { | 1152 | if (bnx2x_alloc_rx_data(bp, fp, ring_prod) < 0) { |
1152 | fp->eth_q_stats.rx_skb_alloc_failed++; | 1153 | fp->eth_q_stats.rx_skb_alloc_failed++; |
1153 | continue; | 1154 | continue; |
1154 | } | 1155 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index f6402fac26fd..ec318711f483 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -1740,6 +1740,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) | |||
1740 | struct sw_rx_bd *rx_buf; | 1740 | struct sw_rx_bd *rx_buf; |
1741 | u16 len; | 1741 | u16 len; |
1742 | int rc = -ENODEV; | 1742 | int rc = -ENODEV; |
1743 | u8 *data; | ||
1743 | 1744 | ||
1744 | /* check the loopback mode */ | 1745 | /* check the loopback mode */ |
1745 | switch (loopback_mode) { | 1746 | switch (loopback_mode) { |
@@ -1865,10 +1866,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) | |||
1865 | dma_sync_single_for_cpu(&bp->pdev->dev, | 1866 | dma_sync_single_for_cpu(&bp->pdev->dev, |
1866 | dma_unmap_addr(rx_buf, mapping), | 1867 | dma_unmap_addr(rx_buf, mapping), |
1867 | fp_rx->rx_buf_size, DMA_FROM_DEVICE); | 1868 | fp_rx->rx_buf_size, DMA_FROM_DEVICE); |
1868 | skb = rx_buf->skb; | 1869 | data = rx_buf->data + NET_SKB_PAD + cqe->fast_path_cqe.placement_offset; |
1869 | skb_reserve(skb, cqe->fast_path_cqe.placement_offset); | ||
1870 | for (i = ETH_HLEN; i < pkt_size; i++) | 1870 | for (i = ETH_HLEN; i < pkt_size; i++) |
1871 | if (*(skb->data + i) != (unsigned char) (i & 0xff)) | 1871 | if (*(data + i) != (unsigned char) (i & 0xff)) |
1872 | goto test_loopback_rx_exit; | 1872 | goto test_loopback_rx_exit; |
1873 | 1873 | ||
1874 | rc = 0; | 1874 | rc = 0; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 33ff60d9fec8..80fb9b532711 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -2789,8 +2789,8 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp, | |||
2789 | /* This should be a maximum number of data bytes that may be | 2789 | /* This should be a maximum number of data bytes that may be |
2790 | * placed on the BD (not including paddings). | 2790 | * placed on the BD (not including paddings). |
2791 | */ | 2791 | */ |
2792 | rxq_init->buf_sz = fp->rx_buf_size - BNX2X_FW_RX_ALIGN - | 2792 | rxq_init->buf_sz = fp->rx_buf_size - BNX2X_FW_RX_ALIGN_START - |
2793 | IP_HEADER_ALIGNMENT_PADDING; | 2793 | BNX2X_FW_RX_ALIGN_END - IP_HEADER_ALIGNMENT_PADDING; |
2794 | 2794 | ||
2795 | rxq_init->cl_qzone_id = fp->cl_qzone_id; | 2795 | rxq_init->cl_qzone_id = fp->cl_qzone_id; |
2796 | rxq_init->tpa_agg_sz = tpa_agg_size; | 2796 | rxq_init->tpa_agg_sz = tpa_agg_size; |