diff options
author | Dmitry Kravkov <dmitry@broadcom.com> | 2011-05-04 19:50:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-05 13:44:34 -0400 |
commit | b3b83c3f3c640b239f1f1dfc49c0ecafbc074fdb (patch) | |
tree | 46efa0dc1b979290770004f9ea6c89089685490b | |
parent | 426b92415074d6d268c7aac4561efecd3785d0b1 (diff) |
bnx2x: improve memory handling, low memory recovery flows
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 3 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 402 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.h | 128 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 3 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 189 |
5 files changed, 449 insertions, 276 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 1a005a484be..498a1003d04 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -473,7 +473,8 @@ struct bnx2x_fastpath { | |||
473 | #define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS) | 473 | #define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS) |
474 | #define MAX_RX_BD (NUM_RX_BD - 1) | 474 | #define MAX_RX_BD (NUM_RX_BD - 1) |
475 | #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) | 475 | #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) |
476 | #define MIN_RX_AVAIL 128 | 476 | #define MIN_RX_SIZE_TPA 72 |
477 | #define MIN_RX_SIZE_NONTPA 10 | ||
477 | #define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL | 478 | #define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL |
478 | #define INIT_RX_RING_SIZE MAX_RX_AVAIL | 479 | #define INIT_RX_RING_SIZE MAX_RX_AVAIL |
479 | #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ | 480 | #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 8853ae2a042..218a7ad7cdd 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
@@ -27,6 +27,49 @@ | |||
27 | 27 | ||
28 | static int bnx2x_setup_irqs(struct bnx2x *bp); | 28 | static int bnx2x_setup_irqs(struct bnx2x *bp); |
29 | 29 | ||
30 | /** | ||
31 | * bnx2x_bz_fp - zero content of the fastpath structure. | ||
32 | * | ||
33 | * @bp: driver handle | ||
34 | * @index: fastpath index to be zeroed | ||
35 | * | ||
36 | * Makes sure the contents of the bp->fp[index].napi is kept | ||
37 | * intact. | ||
38 | */ | ||
39 | static inline void bnx2x_bz_fp(struct bnx2x *bp, int index) | ||
40 | { | ||
41 | struct bnx2x_fastpath *fp = &bp->fp[index]; | ||
42 | struct napi_struct orig_napi = fp->napi; | ||
43 | /* bzero bnx2x_fastpath contents */ | ||
44 | memset(fp, 0, sizeof(*fp)); | ||
45 | |||
46 | /* Restore the NAPI object as it has been already initialized */ | ||
47 | fp->napi = orig_napi; | ||
48 | } | ||
49 | |||
50 | /** | ||
51 | * bnx2x_move_fp - move content of the fastpath structure. | ||
52 | * | ||
53 | * @bp: driver handle | ||
54 | * @from: source FP index | ||
55 | * @to: destination FP index | ||
56 | * | ||
57 | * Makes sure the contents of the bp->fp[to].napi is kept | ||
58 | * intact. | ||
59 | */ | ||
60 | static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) | ||
61 | { | ||
62 | struct bnx2x_fastpath *from_fp = &bp->fp[from]; | ||
63 | struct bnx2x_fastpath *to_fp = &bp->fp[to]; | ||
64 | struct napi_struct orig_napi = to_fp->napi; | ||
65 | /* Move bnx2x_fastpath contents */ | ||
66 | memcpy(to_fp, from_fp, sizeof(*to_fp)); | ||
67 | to_fp->index = to; | ||
68 | |||
69 | /* Restore the NAPI object as it has been already initialized */ | ||
70 | to_fp->napi = orig_napi; | ||
71 | } | ||
72 | |||
30 | /* free skb in the packet ring at pos idx | 73 | /* free skb in the packet ring at pos idx |
31 | * return idx of last bd freed | 74 | * return idx of last bd freed |
32 | */ | 75 | */ |
@@ -881,55 +924,6 @@ void __bnx2x_link_report(struct bnx2x *bp) | |||
881 | } | 924 | } |
882 | } | 925 | } |
883 | 926 | ||
884 | /* Returns the number of actually allocated BDs */ | ||
885 | static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, | ||
886 | int rx_ring_size) | ||
887 | { | ||
888 | struct bnx2x *bp = fp->bp; | ||
889 | u16 ring_prod, cqe_ring_prod; | ||
890 | int i; | ||
891 | |||
892 | fp->rx_comp_cons = 0; | ||
893 | cqe_ring_prod = ring_prod = 0; | ||
894 | for (i = 0; i < rx_ring_size; i++) { | ||
895 | if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { | ||
896 | BNX2X_ERR("was only able to allocate " | ||
897 | "%d rx skbs on queue[%d]\n", i, fp->index); | ||
898 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
899 | break; | ||
900 | } | ||
901 | ring_prod = NEXT_RX_IDX(ring_prod); | ||
902 | cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); | ||
903 | WARN_ON(ring_prod <= i); | ||
904 | } | ||
905 | |||
906 | fp->rx_bd_prod = ring_prod; | ||
907 | /* Limit the CQE producer by the CQE ring size */ | ||
908 | fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, | ||
909 | cqe_ring_prod); | ||
910 | fp->rx_pkt = fp->rx_calls = 0; | ||
911 | |||
912 | return i; | ||
913 | } | ||
914 | |||
915 | static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp) | ||
916 | { | ||
917 | struct bnx2x *bp = fp->bp; | ||
918 | int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : | ||
919 | MAX_RX_AVAIL/bp->num_queues; | ||
920 | |||
921 | rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); | ||
922 | |||
923 | bnx2x_alloc_rx_bds(fp, rx_ring_size); | ||
924 | |||
925 | /* Warning! | ||
926 | * this will generate an interrupt (to the TSTORM) | ||
927 | * must only be done after chip is initialized | ||
928 | */ | ||
929 | bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, | ||
930 | fp->rx_sge_prod); | ||
931 | } | ||
932 | |||
933 | void bnx2x_init_rx_rings(struct bnx2x *bp) | 927 | void bnx2x_init_rx_rings(struct bnx2x *bp) |
934 | { | 928 | { |
935 | int func = BP_FUNC(bp); | 929 | int func = BP_FUNC(bp); |
@@ -938,6 +932,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
938 | u16 ring_prod; | 932 | u16 ring_prod; |
939 | int i, j; | 933 | int i, j; |
940 | 934 | ||
935 | /* Allocate TPA resources */ | ||
941 | for_each_rx_queue(bp, j) { | 936 | for_each_rx_queue(bp, j) { |
942 | struct bnx2x_fastpath *fp = &bp->fp[j]; | 937 | struct bnx2x_fastpath *fp = &bp->fp[j]; |
943 | 938 | ||
@@ -945,6 +940,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
945 | "mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size); | 940 | "mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size); |
946 | 941 | ||
947 | if (!fp->disable_tpa) { | 942 | if (!fp->disable_tpa) { |
943 | /* Fill the per-aggregation pool */ | ||
948 | for (i = 0; i < max_agg_queues; i++) { | 944 | for (i = 0; i < max_agg_queues; i++) { |
949 | fp->tpa_pool[i].skb = | 945 | fp->tpa_pool[i].skb = |
950 | netdev_alloc_skb(bp->dev, fp->rx_buf_size); | 946 | netdev_alloc_skb(bp->dev, fp->rx_buf_size); |
@@ -999,13 +995,13 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
999 | 995 | ||
1000 | fp->rx_bd_cons = 0; | 996 | fp->rx_bd_cons = 0; |
1001 | 997 | ||
1002 | bnx2x_set_next_page_rx_bd(fp); | 998 | /* Activate BD ring */ |
1003 | 999 | /* Warning! | |
1004 | /* CQ ring */ | 1000 | * this will generate an interrupt (to the TSTORM) |
1005 | bnx2x_set_next_page_rx_cq(fp); | 1001 | * must only be done after chip is initialized |
1006 | 1002 | */ | |
1007 | /* Allocate BDs and initialize BD ring */ | 1003 | bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, |
1008 | bnx2x_alloc_rx_bd_ring(fp); | 1004 | fp->rx_sge_prod); |
1009 | 1005 | ||
1010 | if (j != 0) | 1006 | if (j != 0) |
1011 | continue; | 1007 | continue; |
@@ -1039,27 +1035,40 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp) | |||
1039 | } | 1035 | } |
1040 | } | 1036 | } |
1041 | 1037 | ||
1038 | static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp) | ||
1039 | { | ||
1040 | struct bnx2x *bp = fp->bp; | ||
1041 | int i; | ||
1042 | |||
1043 | /* ring wasn't allocated */ | ||
1044 | if (fp->rx_buf_ring == NULL) | ||
1045 | return; | ||
1046 | |||
1047 | for (i = 0; i < NUM_RX_BD; i++) { | ||
1048 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; | ||
1049 | struct sk_buff *skb = rx_buf->skb; | ||
1050 | |||
1051 | if (skb == NULL) | ||
1052 | continue; | ||
1053 | |||
1054 | dma_unmap_single(&bp->pdev->dev, | ||
1055 | dma_unmap_addr(rx_buf, mapping), | ||
1056 | fp->rx_buf_size, DMA_FROM_DEVICE); | ||
1057 | |||
1058 | rx_buf->skb = NULL; | ||
1059 | dev_kfree_skb(skb); | ||
1060 | } | ||
1061 | } | ||
1062 | |||
1042 | static void bnx2x_free_rx_skbs(struct bnx2x *bp) | 1063 | static void bnx2x_free_rx_skbs(struct bnx2x *bp) |
1043 | { | 1064 | { |
1044 | int i, j; | 1065 | int j; |
1045 | 1066 | ||
1046 | for_each_rx_queue(bp, j) { | 1067 | for_each_rx_queue(bp, j) { |
1047 | struct bnx2x_fastpath *fp = &bp->fp[j]; | 1068 | struct bnx2x_fastpath *fp = &bp->fp[j]; |
1048 | 1069 | ||
1049 | for (i = 0; i < NUM_RX_BD; i++) { | 1070 | bnx2x_free_rx_bds(fp); |
1050 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; | ||
1051 | struct sk_buff *skb = rx_buf->skb; | ||
1052 | 1071 | ||
1053 | if (skb == NULL) | ||
1054 | continue; | ||
1055 | |||
1056 | dma_unmap_single(&bp->pdev->dev, | ||
1057 | dma_unmap_addr(rx_buf, mapping), | ||
1058 | fp->rx_buf_size, DMA_FROM_DEVICE); | ||
1059 | |||
1060 | rx_buf->skb = NULL; | ||
1061 | dev_kfree_skb(skb); | ||
1062 | } | ||
1063 | if (!fp->disable_tpa) | 1072 | if (!fp->disable_tpa) |
1064 | bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ? | 1073 | bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ? |
1065 | ETH_MAX_AGGREGATION_QUEUES_E1 : | 1074 | ETH_MAX_AGGREGATION_QUEUES_E1 : |
@@ -1435,26 +1444,37 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
1435 | /* must be called before memory allocation and HW init */ | 1444 | /* must be called before memory allocation and HW init */ |
1436 | bnx2x_ilt_set_info(bp); | 1445 | bnx2x_ilt_set_info(bp); |
1437 | 1446 | ||
1447 | /* zero fastpath structures preserving invariants like napi which are | ||
1448 | * allocated only once | ||
1449 | */ | ||
1450 | for_each_queue(bp, i) | ||
1451 | bnx2x_bz_fp(bp, i); | ||
1452 | |||
1438 | /* Set the receive queues buffer size */ | 1453 | /* Set the receive queues buffer size */ |
1439 | bnx2x_set_rx_buf_size(bp); | 1454 | bnx2x_set_rx_buf_size(bp); |
1440 | 1455 | ||
1456 | for_each_queue(bp, i) | ||
1457 | bnx2x_fp(bp, i, disable_tpa) = | ||
1458 | ((bp->flags & TPA_ENABLE_FLAG) == 0); | ||
1459 | |||
1460 | #ifdef BCM_CNIC | ||
1461 | /* We don't want TPA on FCoE L2 ring */ | ||
1462 | bnx2x_fcoe(bp, disable_tpa) = 1; | ||
1463 | #endif | ||
1464 | |||
1441 | if (bnx2x_alloc_mem(bp)) | 1465 | if (bnx2x_alloc_mem(bp)) |
1442 | return -ENOMEM; | 1466 | return -ENOMEM; |
1443 | 1467 | ||
1468 | /* As long as bnx2x_alloc_mem() may possibly update | ||
1469 | * bp->num_queues, bnx2x_set_real_num_queues() should always | ||
1470 | * come after it. | ||
1471 | */ | ||
1444 | rc = bnx2x_set_real_num_queues(bp); | 1472 | rc = bnx2x_set_real_num_queues(bp); |
1445 | if (rc) { | 1473 | if (rc) { |
1446 | BNX2X_ERR("Unable to set real_num_queues\n"); | 1474 | BNX2X_ERR("Unable to set real_num_queues\n"); |
1447 | goto load_error0; | 1475 | goto load_error0; |
1448 | } | 1476 | } |
1449 | 1477 | ||
1450 | for_each_queue(bp, i) | ||
1451 | bnx2x_fp(bp, i, disable_tpa) = | ||
1452 | ((bp->flags & TPA_ENABLE_FLAG) == 0); | ||
1453 | |||
1454 | #ifdef BCM_CNIC | ||
1455 | /* We don't want TPA on FCoE L2 ring */ | ||
1456 | bnx2x_fcoe(bp, disable_tpa) = 1; | ||
1457 | #endif | ||
1458 | bnx2x_napi_enable(bp); | 1478 | bnx2x_napi_enable(bp); |
1459 | 1479 | ||
1460 | /* Send LOAD_REQUEST command to MCP | 1480 | /* Send LOAD_REQUEST command to MCP |
@@ -2480,6 +2500,232 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) | |||
2480 | return 0; | 2500 | return 0; |
2481 | } | 2501 | } |
2482 | 2502 | ||
2503 | static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) | ||
2504 | { | ||
2505 | union host_hc_status_block *sb = &bnx2x_fp(bp, fp_index, status_blk); | ||
2506 | struct bnx2x_fastpath *fp = &bp->fp[fp_index]; | ||
2507 | |||
2508 | /* Common */ | ||
2509 | #ifdef BCM_CNIC | ||
2510 | if (IS_FCOE_IDX(fp_index)) { | ||
2511 | memset(sb, 0, sizeof(union host_hc_status_block)); | ||
2512 | fp->status_blk_mapping = 0; | ||
2513 | |||
2514 | } else { | ||
2515 | #endif | ||
2516 | /* status blocks */ | ||
2517 | if (CHIP_IS_E2(bp)) | ||
2518 | BNX2X_PCI_FREE(sb->e2_sb, | ||
2519 | bnx2x_fp(bp, fp_index, | ||
2520 | status_blk_mapping), | ||
2521 | sizeof(struct host_hc_status_block_e2)); | ||
2522 | else | ||
2523 | BNX2X_PCI_FREE(sb->e1x_sb, | ||
2524 | bnx2x_fp(bp, fp_index, | ||
2525 | status_blk_mapping), | ||
2526 | sizeof(struct host_hc_status_block_e1x)); | ||
2527 | #ifdef BCM_CNIC | ||
2528 | } | ||
2529 | #endif | ||
2530 | /* Rx */ | ||
2531 | if (!skip_rx_queue(bp, fp_index)) { | ||
2532 | bnx2x_free_rx_bds(fp); | ||
2533 | |||
2534 | /* fastpath rx rings: rx_buf rx_desc rx_comp */ | ||
2535 | BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_buf_ring)); | ||
2536 | BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_desc_ring), | ||
2537 | bnx2x_fp(bp, fp_index, rx_desc_mapping), | ||
2538 | sizeof(struct eth_rx_bd) * NUM_RX_BD); | ||
2539 | |||
2540 | BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_comp_ring), | ||
2541 | bnx2x_fp(bp, fp_index, rx_comp_mapping), | ||
2542 | sizeof(struct eth_fast_path_rx_cqe) * | ||
2543 | NUM_RCQ_BD); | ||
2544 | |||
2545 | /* SGE ring */ | ||
2546 | BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_page_ring)); | ||
2547 | BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_sge_ring), | ||
2548 | bnx2x_fp(bp, fp_index, rx_sge_mapping), | ||
2549 | BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); | ||
2550 | } | ||
2551 | |||
2552 | /* Tx */ | ||
2553 | if (!skip_tx_queue(bp, fp_index)) { | ||
2554 | /* fastpath tx rings: tx_buf tx_desc */ | ||
2555 | BNX2X_FREE(bnx2x_fp(bp, fp_index, tx_buf_ring)); | ||
2556 | BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, tx_desc_ring), | ||
2557 | bnx2x_fp(bp, fp_index, tx_desc_mapping), | ||
2558 | sizeof(union eth_tx_bd_types) * NUM_TX_BD); | ||
2559 | } | ||
2560 | /* end of fastpath */ | ||
2561 | } | ||
2562 | |||
2563 | void bnx2x_free_fp_mem(struct bnx2x *bp) | ||
2564 | { | ||
2565 | int i; | ||
2566 | for_each_queue(bp, i) | ||
2567 | bnx2x_free_fp_mem_at(bp, i); | ||
2568 | } | ||
2569 | |||
2570 | static inline void set_sb_shortcuts(struct bnx2x *bp, int index) | ||
2571 | { | ||
2572 | union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk); | ||
2573 | if (CHIP_IS_E2(bp)) { | ||
2574 | bnx2x_fp(bp, index, sb_index_values) = | ||
2575 | (__le16 *)status_blk.e2_sb->sb.index_values; | ||
2576 | bnx2x_fp(bp, index, sb_running_index) = | ||
2577 | (__le16 *)status_blk.e2_sb->sb.running_index; | ||
2578 | } else { | ||
2579 | bnx2x_fp(bp, index, sb_index_values) = | ||
2580 | (__le16 *)status_blk.e1x_sb->sb.index_values; | ||
2581 | bnx2x_fp(bp, index, sb_running_index) = | ||
2582 | (__le16 *)status_blk.e1x_sb->sb.running_index; | ||
2583 | } | ||
2584 | } | ||
2585 | |||
2586 | static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) | ||
2587 | { | ||
2588 | union host_hc_status_block *sb; | ||
2589 | struct bnx2x_fastpath *fp = &bp->fp[index]; | ||
2590 | int ring_size = 0; | ||
2591 | |||
2592 | /* if rx_ring_size specified - use it */ | ||
2593 | int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : | ||
2594 | MAX_RX_AVAIL/bp->num_queues; | ||
2595 | |||
2596 | /* allocate at least number of buffers required by FW */ | ||
2597 | rx_ring_size = max_t(int, fp->disable_tpa ? MIN_RX_SIZE_NONTPA : | ||
2598 | MIN_RX_SIZE_TPA, | ||
2599 | rx_ring_size); | ||
2600 | |||
2601 | bnx2x_fp(bp, index, bp) = bp; | ||
2602 | bnx2x_fp(bp, index, index) = index; | ||
2603 | |||
2604 | /* Common */ | ||
2605 | sb = &bnx2x_fp(bp, index, status_blk); | ||
2606 | #ifdef BCM_CNIC | ||
2607 | if (!IS_FCOE_IDX(index)) { | ||
2608 | #endif | ||
2609 | /* status blocks */ | ||
2610 | if (CHIP_IS_E2(bp)) | ||
2611 | BNX2X_PCI_ALLOC(sb->e2_sb, | ||
2612 | &bnx2x_fp(bp, index, status_blk_mapping), | ||
2613 | sizeof(struct host_hc_status_block_e2)); | ||
2614 | else | ||
2615 | BNX2X_PCI_ALLOC(sb->e1x_sb, | ||
2616 | &bnx2x_fp(bp, index, status_blk_mapping), | ||
2617 | sizeof(struct host_hc_status_block_e1x)); | ||
2618 | #ifdef BCM_CNIC | ||
2619 | } | ||
2620 | #endif | ||
2621 | set_sb_shortcuts(bp, index); | ||
2622 | |||
2623 | /* Tx */ | ||
2624 | if (!skip_tx_queue(bp, index)) { | ||
2625 | /* fastpath tx rings: tx_buf tx_desc */ | ||
2626 | BNX2X_ALLOC(bnx2x_fp(bp, index, tx_buf_ring), | ||
2627 | sizeof(struct sw_tx_bd) * NUM_TX_BD); | ||
2628 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, tx_desc_ring), | ||
2629 | &bnx2x_fp(bp, index, tx_desc_mapping), | ||
2630 | sizeof(union eth_tx_bd_types) * NUM_TX_BD); | ||
2631 | } | ||
2632 | |||
2633 | /* Rx */ | ||
2634 | if (!skip_rx_queue(bp, index)) { | ||
2635 | /* fastpath rx rings: rx_buf rx_desc rx_comp */ | ||
2636 | BNX2X_ALLOC(bnx2x_fp(bp, index, rx_buf_ring), | ||
2637 | sizeof(struct sw_rx_bd) * NUM_RX_BD); | ||
2638 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_desc_ring), | ||
2639 | &bnx2x_fp(bp, index, rx_desc_mapping), | ||
2640 | sizeof(struct eth_rx_bd) * NUM_RX_BD); | ||
2641 | |||
2642 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_comp_ring), | ||
2643 | &bnx2x_fp(bp, index, rx_comp_mapping), | ||
2644 | sizeof(struct eth_fast_path_rx_cqe) * | ||
2645 | NUM_RCQ_BD); | ||
2646 | |||
2647 | /* SGE ring */ | ||
2648 | BNX2X_ALLOC(bnx2x_fp(bp, index, rx_page_ring), | ||
2649 | sizeof(struct sw_rx_page) * NUM_RX_SGE); | ||
2650 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_sge_ring), | ||
2651 | &bnx2x_fp(bp, index, rx_sge_mapping), | ||
2652 | BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); | ||
2653 | /* RX BD ring */ | ||
2654 | bnx2x_set_next_page_rx_bd(fp); | ||
2655 | |||
2656 | /* CQ ring */ | ||
2657 | bnx2x_set_next_page_rx_cq(fp); | ||
2658 | |||
2659 | /* BDs */ | ||
2660 | ring_size = bnx2x_alloc_rx_bds(fp, rx_ring_size); | ||
2661 | if (ring_size < rx_ring_size) | ||
2662 | goto alloc_mem_err; | ||
2663 | } | ||
2664 | |||
2665 | return 0; | ||
2666 | |||
2667 | /* handles low memory cases */ | ||
2668 | alloc_mem_err: | ||
2669 | BNX2X_ERR("Unable to allocate full memory for queue %d (size %d)\n", | ||
2670 | index, ring_size); | ||
2671 | /* FW will drop all packets if queue is not big enough, | ||
2672 | * In these cases we disable the queue | ||
2673 | * Min size diferent for TPA and non-TPA queues | ||
2674 | */ | ||
2675 | if (ring_size < (fp->disable_tpa ? | ||
2676 | MIN_RX_SIZE_TPA : MIN_RX_SIZE_NONTPA)) { | ||
2677 | /* release memory allocated for this queue */ | ||
2678 | bnx2x_free_fp_mem_at(bp, index); | ||
2679 | return -ENOMEM; | ||
2680 | } | ||
2681 | return 0; | ||
2682 | } | ||
2683 | |||
2684 | int bnx2x_alloc_fp_mem(struct bnx2x *bp) | ||
2685 | { | ||
2686 | int i; | ||
2687 | |||
2688 | /** | ||
2689 | * 1. Allocate FP for leading - fatal if error | ||
2690 | * 2. {CNIC} Allocate FCoE FP - fatal if error | ||
2691 | * 3. Allocate RSS - fix number of queues if error | ||
2692 | */ | ||
2693 | |||
2694 | /* leading */ | ||
2695 | if (bnx2x_alloc_fp_mem_at(bp, 0)) | ||
2696 | return -ENOMEM; | ||
2697 | #ifdef BCM_CNIC | ||
2698 | /* FCoE */ | ||
2699 | if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX)) | ||
2700 | return -ENOMEM; | ||
2701 | #endif | ||
2702 | /* RSS */ | ||
2703 | for_each_nondefault_eth_queue(bp, i) | ||
2704 | if (bnx2x_alloc_fp_mem_at(bp, i)) | ||
2705 | break; | ||
2706 | |||
2707 | /* handle memory failures */ | ||
2708 | if (i != BNX2X_NUM_ETH_QUEUES(bp)) { | ||
2709 | int delta = BNX2X_NUM_ETH_QUEUES(bp) - i; | ||
2710 | |||
2711 | WARN_ON(delta < 0); | ||
2712 | #ifdef BCM_CNIC | ||
2713 | /** | ||
2714 | * move non eth FPs next to last eth FP | ||
2715 | * must be done in that order | ||
2716 | * FCOE_IDX < FWD_IDX < OOO_IDX | ||
2717 | */ | ||
2718 | |||
2719 | /* move FCoE fp */ | ||
2720 | bnx2x_move_fp(bp, FCOE_IDX, FCOE_IDX - delta); | ||
2721 | #endif | ||
2722 | bp->num_queues -= delta; | ||
2723 | BNX2X_ERR("Adjusted num of queues from %d to %d\n", | ||
2724 | bp->num_queues + delta, bp->num_queues); | ||
2725 | } | ||
2726 | |||
2727 | return 0; | ||
2728 | } | ||
2483 | 2729 | ||
2484 | static int bnx2x_setup_irqs(struct bnx2x *bp) | 2730 | static int bnx2x_setup_irqs(struct bnx2x *bp) |
2485 | { | 2731 | { |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 007f29495c2..68b79a1082c 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h | |||
@@ -25,6 +25,39 @@ | |||
25 | 25 | ||
26 | extern int num_queues; | 26 | extern int num_queues; |
27 | 27 | ||
28 | /************************ Macros ********************************/ | ||
29 | #define BNX2X_PCI_FREE(x, y, size) \ | ||
30 | do { \ | ||
31 | if (x) { \ | ||
32 | dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \ | ||
33 | x = NULL; \ | ||
34 | y = 0; \ | ||
35 | } \ | ||
36 | } while (0) | ||
37 | |||
38 | #define BNX2X_FREE(x) \ | ||
39 | do { \ | ||
40 | if (x) { \ | ||
41 | kfree((void *)x); \ | ||
42 | x = NULL; \ | ||
43 | } \ | ||
44 | } while (0) | ||
45 | |||
46 | #define BNX2X_PCI_ALLOC(x, y, size) \ | ||
47 | do { \ | ||
48 | x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ | ||
49 | if (x == NULL) \ | ||
50 | goto alloc_mem_err; \ | ||
51 | memset((void *)x, 0, size); \ | ||
52 | } while (0) | ||
53 | |||
54 | #define BNX2X_ALLOC(x, size) \ | ||
55 | do { \ | ||
56 | x = kzalloc(size, GFP_KERNEL); \ | ||
57 | if (x == NULL) \ | ||
58 | goto alloc_mem_err; \ | ||
59 | } while (0) | ||
60 | |||
28 | /*********************** Interfaces **************************** | 61 | /*********************** Interfaces **************************** |
29 | * Functions that need to be implemented by each driver version | 62 | * Functions that need to be implemented by each driver version |
30 | */ | 63 | */ |
@@ -378,6 +411,9 @@ int bnx2x_resume(struct pci_dev *pdev); | |||
378 | /* Release IRQ vectors */ | 411 | /* Release IRQ vectors */ |
379 | void bnx2x_free_irq(struct bnx2x *bp); | 412 | void bnx2x_free_irq(struct bnx2x *bp); |
380 | 413 | ||
414 | void bnx2x_free_fp_mem(struct bnx2x *bp); | ||
415 | int bnx2x_alloc_fp_mem(struct bnx2x *bp); | ||
416 | |||
381 | void bnx2x_init_rx_rings(struct bnx2x *bp); | 417 | void bnx2x_init_rx_rings(struct bnx2x *bp); |
382 | void bnx2x_free_skbs(struct bnx2x *bp); | 418 | void bnx2x_free_skbs(struct bnx2x *bp); |
383 | void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); | 419 | void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); |
@@ -884,6 +920,9 @@ static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, | |||
884 | { | 920 | { |
885 | int i; | 921 | int i; |
886 | 922 | ||
923 | if (fp->disable_tpa) | ||
924 | return; | ||
925 | |||
887 | for (i = 0; i < last; i++) | 926 | for (i = 0; i < last; i++) |
888 | bnx2x_free_rx_sge(bp, fp, i); | 927 | bnx2x_free_rx_sge(bp, fp, i); |
889 | } | 928 | } |
@@ -912,36 +951,39 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, | |||
912 | } | 951 | } |
913 | } | 952 | } |
914 | 953 | ||
915 | 954 | static inline void bnx2x_init_tx_ring_one(struct bnx2x_fastpath *fp) | |
916 | static inline void bnx2x_init_tx_rings(struct bnx2x *bp) | ||
917 | { | 955 | { |
918 | int i, j; | 956 | int i; |
919 | 957 | ||
920 | for_each_tx_queue(bp, j) { | 958 | for (i = 1; i <= NUM_TX_RINGS; i++) { |
921 | struct bnx2x_fastpath *fp = &bp->fp[j]; | 959 | struct eth_tx_next_bd *tx_next_bd = |
960 | &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd; | ||
922 | 961 | ||
923 | for (i = 1; i <= NUM_TX_RINGS; i++) { | 962 | tx_next_bd->addr_hi = |
924 | struct eth_tx_next_bd *tx_next_bd = | 963 | cpu_to_le32(U64_HI(fp->tx_desc_mapping + |
925 | &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd; | 964 | BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); |
965 | tx_next_bd->addr_lo = | ||
966 | cpu_to_le32(U64_LO(fp->tx_desc_mapping + | ||
967 | BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); | ||
968 | } | ||
926 | 969 | ||
927 | tx_next_bd->addr_hi = | 970 | SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1); |
928 | cpu_to_le32(U64_HI(fp->tx_desc_mapping + | 971 | fp->tx_db.data.zero_fill1 = 0; |
929 | BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); | 972 | fp->tx_db.data.prod = 0; |
930 | tx_next_bd->addr_lo = | ||
931 | cpu_to_le32(U64_LO(fp->tx_desc_mapping + | ||
932 | BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); | ||
933 | } | ||
934 | 973 | ||
935 | SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1); | 974 | fp->tx_pkt_prod = 0; |
936 | fp->tx_db.data.zero_fill1 = 0; | 975 | fp->tx_pkt_cons = 0; |
937 | fp->tx_db.data.prod = 0; | 976 | fp->tx_bd_prod = 0; |
977 | fp->tx_bd_cons = 0; | ||
978 | fp->tx_pkt = 0; | ||
979 | } | ||
938 | 980 | ||
939 | fp->tx_pkt_prod = 0; | 981 | static inline void bnx2x_init_tx_rings(struct bnx2x *bp) |
940 | fp->tx_pkt_cons = 0; | 982 | { |
941 | fp->tx_bd_prod = 0; | 983 | int i; |
942 | fp->tx_bd_cons = 0; | 984 | |
943 | fp->tx_pkt = 0; | 985 | for_each_tx_queue(bp, i) |
944 | } | 986 | bnx2x_init_tx_ring_one(&bp->fp[i]); |
945 | } | 987 | } |
946 | 988 | ||
947 | static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) | 989 | static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) |
@@ -996,6 +1038,44 @@ static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp) | |||
996 | } | 1038 | } |
997 | } | 1039 | } |
998 | 1040 | ||
1041 | /* Returns the number of actually allocated BDs */ | ||
1042 | static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, | ||
1043 | int rx_ring_size) | ||
1044 | { | ||
1045 | struct bnx2x *bp = fp->bp; | ||
1046 | u16 ring_prod, cqe_ring_prod; | ||
1047 | int i; | ||
1048 | |||
1049 | fp->rx_comp_cons = 0; | ||
1050 | cqe_ring_prod = ring_prod = 0; | ||
1051 | |||
1052 | /* This routine is called only during fo init so | ||
1053 | * fp->eth_q_stats.rx_skb_alloc_failed = 0 | ||
1054 | */ | ||
1055 | for (i = 0; i < rx_ring_size; i++) { | ||
1056 | if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { | ||
1057 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
1058 | continue; | ||
1059 | } | ||
1060 | ring_prod = NEXT_RX_IDX(ring_prod); | ||
1061 | cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); | ||
1062 | WARN_ON(ring_prod <= (i - fp->eth_q_stats.rx_skb_alloc_failed)); | ||
1063 | } | ||
1064 | |||
1065 | if (fp->eth_q_stats.rx_skb_alloc_failed) | ||
1066 | BNX2X_ERR("was only able to allocate " | ||
1067 | "%d rx skbs on queue[%d]\n", | ||
1068 | (i - fp->eth_q_stats.rx_skb_alloc_failed), fp->index); | ||
1069 | |||
1070 | fp->rx_bd_prod = ring_prod; | ||
1071 | /* Limit the CQE producer by the CQE ring size */ | ||
1072 | fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, | ||
1073 | cqe_ring_prod); | ||
1074 | fp->rx_pkt = fp->rx_calls = 0; | ||
1075 | |||
1076 | return i - fp->eth_q_stats.rx_skb_alloc_failed; | ||
1077 | } | ||
1078 | |||
999 | #ifdef BCM_CNIC | 1079 | #ifdef BCM_CNIC |
1000 | static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) | 1080 | static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) |
1001 | { | 1081 | { |
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 4f42c314986..7556fde2329 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c | |||
@@ -1220,7 +1220,8 @@ static int bnx2x_set_ringparam(struct net_device *dev, | |||
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | if ((ering->rx_pending > MAX_RX_AVAIL) || | 1222 | if ((ering->rx_pending > MAX_RX_AVAIL) || |
1223 | (ering->rx_pending < MIN_RX_AVAIL) || | 1223 | (ering->rx_pending < (bp->disable_tpa ? MIN_RX_SIZE_NONTPA : |
1224 | MIN_RX_SIZE_TPA)) || | ||
1224 | (ering->tx_pending > MAX_TX_AVAIL) || | 1225 | (ering->tx_pending > MAX_TX_AVAIL) || |
1225 | (ering->tx_pending <= MAX_SKB_FRAGS + 4)) | 1226 | (ering->tx_pending <= MAX_SKB_FRAGS + 4)) |
1226 | return -EINVAL; | 1227 | return -EINVAL; |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 660c9456026..4be5480ecc5 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -4447,7 +4447,7 @@ static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx) | |||
4447 | 4447 | ||
4448 | fp->state = BNX2X_FP_STATE_CLOSED; | 4448 | fp->state = BNX2X_FP_STATE_CLOSED; |
4449 | 4449 | ||
4450 | fp->index = fp->cid = fp_idx; | 4450 | fp->cid = fp_idx; |
4451 | fp->cl_id = BP_L_ID(bp) + fp_idx; | 4451 | fp->cl_id = BP_L_ID(bp) + fp_idx; |
4452 | fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE; | 4452 | fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE; |
4453 | fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; | 4453 | fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; |
@@ -4559,9 +4559,11 @@ gunzip_nomem1: | |||
4559 | 4559 | ||
4560 | static void bnx2x_gunzip_end(struct bnx2x *bp) | 4560 | static void bnx2x_gunzip_end(struct bnx2x *bp) |
4561 | { | 4561 | { |
4562 | kfree(bp->strm->workspace); | 4562 | if (bp->strm) { |
4563 | kfree(bp->strm); | 4563 | kfree(bp->strm->workspace); |
4564 | bp->strm = NULL; | 4564 | kfree(bp->strm); |
4565 | bp->strm = NULL; | ||
4566 | } | ||
4565 | 4567 | ||
4566 | if (bp->gunzip_buf) { | 4568 | if (bp->gunzip_buf) { |
4567 | dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf, | 4569 | dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf, |
@@ -5869,9 +5871,6 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) | |||
5869 | 5871 | ||
5870 | bp->dmae_ready = 0; | 5872 | bp->dmae_ready = 0; |
5871 | spin_lock_init(&bp->dmae_lock); | 5873 | spin_lock_init(&bp->dmae_lock); |
5872 | rc = bnx2x_gunzip_init(bp); | ||
5873 | if (rc) | ||
5874 | return rc; | ||
5875 | 5874 | ||
5876 | switch (load_code) { | 5875 | switch (load_code) { |
5877 | case FW_MSG_CODE_DRV_LOAD_COMMON: | 5876 | case FW_MSG_CODE_DRV_LOAD_COMMON: |
@@ -5915,80 +5914,10 @@ init_hw_err: | |||
5915 | 5914 | ||
5916 | void bnx2x_free_mem(struct bnx2x *bp) | 5915 | void bnx2x_free_mem(struct bnx2x *bp) |
5917 | { | 5916 | { |
5918 | 5917 | bnx2x_gunzip_end(bp); | |
5919 | #define BNX2X_PCI_FREE(x, y, size) \ | ||
5920 | do { \ | ||
5921 | if (x) { \ | ||
5922 | dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \ | ||
5923 | x = NULL; \ | ||
5924 | y = 0; \ | ||
5925 | } \ | ||
5926 | } while (0) | ||
5927 | |||
5928 | #define BNX2X_FREE(x) \ | ||
5929 | do { \ | ||
5930 | if (x) { \ | ||
5931 | kfree((void *)x); \ | ||
5932 | x = NULL; \ | ||
5933 | } \ | ||
5934 | } while (0) | ||
5935 | |||
5936 | int i; | ||
5937 | 5918 | ||
5938 | /* fastpath */ | 5919 | /* fastpath */ |
5939 | /* Common */ | 5920 | bnx2x_free_fp_mem(bp); |
5940 | for_each_queue(bp, i) { | ||
5941 | #ifdef BCM_CNIC | ||
5942 | /* FCoE client uses default status block */ | ||
5943 | if (IS_FCOE_IDX(i)) { | ||
5944 | union host_hc_status_block *sb = | ||
5945 | &bnx2x_fp(bp, i, status_blk); | ||
5946 | memset(sb, 0, sizeof(union host_hc_status_block)); | ||
5947 | bnx2x_fp(bp, i, status_blk_mapping) = 0; | ||
5948 | } else { | ||
5949 | #endif | ||
5950 | /* status blocks */ | ||
5951 | if (CHIP_IS_E2(bp)) | ||
5952 | BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb), | ||
5953 | bnx2x_fp(bp, i, status_blk_mapping), | ||
5954 | sizeof(struct host_hc_status_block_e2)); | ||
5955 | else | ||
5956 | BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), | ||
5957 | bnx2x_fp(bp, i, status_blk_mapping), | ||
5958 | sizeof(struct host_hc_status_block_e1x)); | ||
5959 | #ifdef BCM_CNIC | ||
5960 | } | ||
5961 | #endif | ||
5962 | } | ||
5963 | /* Rx */ | ||
5964 | for_each_rx_queue(bp, i) { | ||
5965 | |||
5966 | /* fastpath rx rings: rx_buf rx_desc rx_comp */ | ||
5967 | BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring)); | ||
5968 | BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring), | ||
5969 | bnx2x_fp(bp, i, rx_desc_mapping), | ||
5970 | sizeof(struct eth_rx_bd) * NUM_RX_BD); | ||
5971 | |||
5972 | BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring), | ||
5973 | bnx2x_fp(bp, i, rx_comp_mapping), | ||
5974 | sizeof(struct eth_fast_path_rx_cqe) * | ||
5975 | NUM_RCQ_BD); | ||
5976 | |||
5977 | /* SGE ring */ | ||
5978 | BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring)); | ||
5979 | BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring), | ||
5980 | bnx2x_fp(bp, i, rx_sge_mapping), | ||
5981 | BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); | ||
5982 | } | ||
5983 | /* Tx */ | ||
5984 | for_each_tx_queue(bp, i) { | ||
5985 | |||
5986 | /* fastpath tx rings: tx_buf tx_desc */ | ||
5987 | BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring)); | ||
5988 | BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring), | ||
5989 | bnx2x_fp(bp, i, tx_desc_mapping), | ||
5990 | sizeof(union eth_tx_bd_types) * NUM_TX_BD); | ||
5991 | } | ||
5992 | /* end of fastpath */ | 5921 | /* end of fastpath */ |
5993 | 5922 | ||
5994 | BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, | 5923 | BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, |
@@ -6021,101 +5950,13 @@ void bnx2x_free_mem(struct bnx2x *bp) | |||
6021 | BCM_PAGE_SIZE * NUM_EQ_PAGES); | 5950 | BCM_PAGE_SIZE * NUM_EQ_PAGES); |
6022 | 5951 | ||
6023 | BNX2X_FREE(bp->rx_indir_table); | 5952 | BNX2X_FREE(bp->rx_indir_table); |
6024 | |||
6025 | #undef BNX2X_PCI_FREE | ||
6026 | #undef BNX2X_KFREE | ||
6027 | } | 5953 | } |
6028 | 5954 | ||
6029 | static inline void set_sb_shortcuts(struct bnx2x *bp, int index) | ||
6030 | { | ||
6031 | union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk); | ||
6032 | if (CHIP_IS_E2(bp)) { | ||
6033 | bnx2x_fp(bp, index, sb_index_values) = | ||
6034 | (__le16 *)status_blk.e2_sb->sb.index_values; | ||
6035 | bnx2x_fp(bp, index, sb_running_index) = | ||
6036 | (__le16 *)status_blk.e2_sb->sb.running_index; | ||
6037 | } else { | ||
6038 | bnx2x_fp(bp, index, sb_index_values) = | ||
6039 | (__le16 *)status_blk.e1x_sb->sb.index_values; | ||
6040 | bnx2x_fp(bp, index, sb_running_index) = | ||
6041 | (__le16 *)status_blk.e1x_sb->sb.running_index; | ||
6042 | } | ||
6043 | } | ||
6044 | 5955 | ||
6045 | int bnx2x_alloc_mem(struct bnx2x *bp) | 5956 | int bnx2x_alloc_mem(struct bnx2x *bp) |
6046 | { | 5957 | { |
6047 | #define BNX2X_PCI_ALLOC(x, y, size) \ | 5958 | if (bnx2x_gunzip_init(bp)) |
6048 | do { \ | 5959 | return -ENOMEM; |
6049 | x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ | ||
6050 | if (x == NULL) \ | ||
6051 | goto alloc_mem_err; \ | ||
6052 | memset(x, 0, size); \ | ||
6053 | } while (0) | ||
6054 | |||
6055 | #define BNX2X_ALLOC(x, size) \ | ||
6056 | do { \ | ||
6057 | x = kzalloc(size, GFP_KERNEL); \ | ||
6058 | if (x == NULL) \ | ||
6059 | goto alloc_mem_err; \ | ||
6060 | } while (0) | ||
6061 | |||
6062 | int i; | ||
6063 | |||
6064 | /* fastpath */ | ||
6065 | /* Common */ | ||
6066 | for_each_queue(bp, i) { | ||
6067 | union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk); | ||
6068 | bnx2x_fp(bp, i, bp) = bp; | ||
6069 | /* status blocks */ | ||
6070 | #ifdef BCM_CNIC | ||
6071 | if (!IS_FCOE_IDX(i)) { | ||
6072 | #endif | ||
6073 | if (CHIP_IS_E2(bp)) | ||
6074 | BNX2X_PCI_ALLOC(sb->e2_sb, | ||
6075 | &bnx2x_fp(bp, i, status_blk_mapping), | ||
6076 | sizeof(struct host_hc_status_block_e2)); | ||
6077 | else | ||
6078 | BNX2X_PCI_ALLOC(sb->e1x_sb, | ||
6079 | &bnx2x_fp(bp, i, status_blk_mapping), | ||
6080 | sizeof(struct host_hc_status_block_e1x)); | ||
6081 | #ifdef BCM_CNIC | ||
6082 | } | ||
6083 | #endif | ||
6084 | set_sb_shortcuts(bp, i); | ||
6085 | } | ||
6086 | /* Rx */ | ||
6087 | for_each_queue(bp, i) { | ||
6088 | |||
6089 | /* fastpath rx rings: rx_buf rx_desc rx_comp */ | ||
6090 | BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring), | ||
6091 | sizeof(struct sw_rx_bd) * NUM_RX_BD); | ||
6092 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring), | ||
6093 | &bnx2x_fp(bp, i, rx_desc_mapping), | ||
6094 | sizeof(struct eth_rx_bd) * NUM_RX_BD); | ||
6095 | |||
6096 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring), | ||
6097 | &bnx2x_fp(bp, i, rx_comp_mapping), | ||
6098 | sizeof(struct eth_fast_path_rx_cqe) * | ||
6099 | NUM_RCQ_BD); | ||
6100 | |||
6101 | /* SGE ring */ | ||
6102 | BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring), | ||
6103 | sizeof(struct sw_rx_page) * NUM_RX_SGE); | ||
6104 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring), | ||
6105 | &bnx2x_fp(bp, i, rx_sge_mapping), | ||
6106 | BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); | ||
6107 | } | ||
6108 | /* Tx */ | ||
6109 | for_each_queue(bp, i) { | ||
6110 | |||
6111 | /* fastpath tx rings: tx_buf tx_desc */ | ||
6112 | BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring), | ||
6113 | sizeof(struct sw_tx_bd) * NUM_TX_BD); | ||
6114 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring), | ||
6115 | &bnx2x_fp(bp, i, tx_desc_mapping), | ||
6116 | sizeof(union eth_tx_bd_types) * NUM_TX_BD); | ||
6117 | } | ||
6118 | /* end of fastpath */ | ||
6119 | 5960 | ||
6120 | #ifdef BCM_CNIC | 5961 | #ifdef BCM_CNIC |
6121 | if (CHIP_IS_E2(bp)) | 5962 | if (CHIP_IS_E2(bp)) |
@@ -6155,14 +5996,18 @@ int bnx2x_alloc_mem(struct bnx2x *bp) | |||
6155 | 5996 | ||
6156 | BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) * | 5997 | BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) * |
6157 | TSTORM_INDIRECTION_TABLE_SIZE); | 5998 | TSTORM_INDIRECTION_TABLE_SIZE); |
5999 | |||
6000 | /* fastpath */ | ||
6001 | /* need to be done at the end, since it's self adjusting to amount | ||
6002 | * of memory available for RSS queues | ||
6003 | */ | ||
6004 | if (bnx2x_alloc_fp_mem(bp)) | ||
6005 | goto alloc_mem_err; | ||
6158 | return 0; | 6006 | return 0; |
6159 | 6007 | ||
6160 | alloc_mem_err: | 6008 | alloc_mem_err: |
6161 | bnx2x_free_mem(bp); | 6009 | bnx2x_free_mem(bp); |
6162 | return -ENOMEM; | 6010 | return -ENOMEM; |
6163 | |||
6164 | #undef BNX2X_PCI_ALLOC | ||
6165 | #undef BNX2X_ALLOC | ||
6166 | } | 6011 | } |
6167 | 6012 | ||
6168 | /* | 6013 | /* |