4 * Copyright(c) Broadcom Limited.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Broadcom Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <rte_memzone.h>
38 #include "bnxt_hwrm.h"
39 #include "bnxt_ring.h"
45 #include "hsi_struct_def_dpdk.h"
48 * Generic ring handling
51 void bnxt_free_ring(struct bnxt_ring
*ring
)
53 if (ring
->vmem_size
&& *ring
->vmem
) {
54 memset((char *)*ring
->vmem
, 0, ring
->vmem_size
);
57 rte_memzone_free((const struct rte_memzone
*)ring
->mem_zone
);
64 void bnxt_init_ring_grps(struct bnxt
*bp
)
68 for (i
= 0; i
< bp
->max_ring_grps
; i
++)
69 memset(&bp
->grp_info
[i
], (uint8_t)HWRM_NA_SIGNATURE
,
70 sizeof(struct bnxt_ring_grp_info
));
74 * Allocates a completion ring with vmem and stats optionally also allocating
75 * a TX and/or RX ring. Passing NULL as tx_ring_info and/or rx_ring_info
76 * to not allocate them.
78 * Order in the allocation is:
79 * stats - Always non-zero length
80 * cp vmem - Always zero-length, supported for the bnxt_ring abstraction
81 * tx vmem - Only non-zero length if tx_ring_info is not NULL
82 * rx vmem - Only non-zero length if rx_ring_info is not NULL
83 * cp bd ring - Always non-zero length
84 * tx bd ring - Only non-zero length if tx_ring_info is not NULL
85 * rx bd ring - Only non-zero length if rx_ring_info is not NULL
87 int bnxt_alloc_rings(struct bnxt
*bp
, uint16_t qidx
,
88 struct bnxt_tx_ring_info
*tx_ring_info
,
89 struct bnxt_rx_ring_info
*rx_ring_info
,
90 struct bnxt_cp_ring_info
*cp_ring_info
,
93 struct bnxt_ring
*cp_ring
= cp_ring_info
->cp_ring_struct
;
94 struct bnxt_ring
*tx_ring
;
95 struct bnxt_ring
*rx_ring
;
96 struct rte_pci_device
*pdev
= bp
->pdev
;
97 const struct rte_memzone
*mz
= NULL
;
98 char mz_name
[RTE_MEMZONE_NAMESIZE
];
100 int stats_len
= (tx_ring_info
|| rx_ring_info
) ?
101 RTE_CACHE_LINE_ROUNDUP(sizeof(struct ctx_hw_stats64
)) : 0;
103 int cp_vmem_start
= stats_len
;
104 int cp_vmem_len
= RTE_CACHE_LINE_ROUNDUP(cp_ring
->vmem_size
);
106 int tx_vmem_start
= cp_vmem_start
+ cp_vmem_len
;
108 tx_ring_info
? RTE_CACHE_LINE_ROUNDUP(tx_ring_info
->
109 tx_ring_struct
->vmem_size
) : 0;
111 int rx_vmem_start
= tx_vmem_start
+ tx_vmem_len
;
112 int rx_vmem_len
= rx_ring_info
?
113 RTE_CACHE_LINE_ROUNDUP(rx_ring_info
->
114 rx_ring_struct
->vmem_size
) : 0;
116 int cp_ring_start
= rx_vmem_start
+ rx_vmem_len
;
117 int cp_ring_len
= RTE_CACHE_LINE_ROUNDUP(cp_ring
->ring_size
*
118 sizeof(struct cmpl_base
));
120 int tx_ring_start
= cp_ring_start
+ cp_ring_len
;
121 int tx_ring_len
= tx_ring_info
?
122 RTE_CACHE_LINE_ROUNDUP(tx_ring_info
->tx_ring_struct
->ring_size
*
123 sizeof(struct tx_bd_long
)) : 0;
125 int rx_ring_start
= tx_ring_start
+ tx_ring_len
;
126 int rx_ring_len
= rx_ring_info
?
127 RTE_CACHE_LINE_ROUNDUP(rx_ring_info
->rx_ring_struct
->ring_size
*
128 sizeof(struct rx_prod_pkt_bd
)) : 0;
130 int total_alloc_len
= rx_ring_start
+ rx_ring_len
;
132 snprintf(mz_name
, RTE_MEMZONE_NAMESIZE
,
133 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev
->addr
.domain
,
134 pdev
->addr
.bus
, pdev
->addr
.devid
, pdev
->addr
.function
, qidx
,
136 mz_name
[RTE_MEMZONE_NAMESIZE
- 1] = 0;
137 mz
= rte_memzone_lookup(mz_name
);
139 mz
= rte_memzone_reserve(mz_name
, total_alloc_len
,
142 RTE_MEMZONE_SIZE_HINT_ONLY
);
146 memset(mz
->addr
, 0, mz
->len
);
149 tx_ring
= tx_ring_info
->tx_ring_struct
;
151 tx_ring
->bd
= ((char *)mz
->addr
+ tx_ring_start
);
152 tx_ring_info
->tx_desc_ring
= (struct tx_bd_long
*)tx_ring
->bd
;
153 tx_ring
->bd_dma
= mz
->phys_addr
+ tx_ring_start
;
154 tx_ring_info
->tx_desc_mapping
= tx_ring
->bd_dma
;
155 tx_ring
->mem_zone
= (const void *)mz
;
159 if (tx_ring
->vmem_size
) {
161 (void **)((char *)mz
->addr
+ tx_vmem_start
);
162 tx_ring_info
->tx_buf_ring
=
163 (struct bnxt_sw_tx_bd
*)tx_ring
->vmem
;
168 rx_ring
= rx_ring_info
->rx_ring_struct
;
170 rx_ring
->bd
= ((char *)mz
->addr
+ rx_ring_start
);
171 rx_ring_info
->rx_desc_ring
=
172 (struct rx_prod_pkt_bd
*)rx_ring
->bd
;
173 rx_ring
->bd_dma
= mz
->phys_addr
+ rx_ring_start
;
174 rx_ring_info
->rx_desc_mapping
= rx_ring
->bd_dma
;
175 rx_ring
->mem_zone
= (const void *)mz
;
179 if (rx_ring
->vmem_size
) {
181 (void **)((char *)mz
->addr
+ rx_vmem_start
);
182 rx_ring_info
->rx_buf_ring
=
183 (struct bnxt_sw_rx_bd
*)rx_ring
->vmem
;
187 cp_ring
->bd
= ((char *)mz
->addr
+ cp_ring_start
);
188 cp_ring
->bd_dma
= mz
->phys_addr
+ cp_ring_start
;
189 cp_ring_info
->cp_desc_ring
= cp_ring
->bd
;
190 cp_ring_info
->cp_desc_mapping
= cp_ring
->bd_dma
;
191 cp_ring
->mem_zone
= (const void *)mz
;
195 if (cp_ring
->vmem_size
)
196 *cp_ring
->vmem
= ((char *)mz
->addr
+ stats_len
);
198 cp_ring_info
->hw_stats
= mz
->addr
;
199 cp_ring_info
->hw_stats_map
= mz
->phys_addr
;
201 cp_ring_info
->hw_stats_ctx_id
= HWRM_NA_SIGNATURE
;
206 * [0] = default completion ring
207 * [1 -> +rx_cp_nr_rings] = rx_cp, rx rings
208 * [1+rx_cp_nr_rings + 1 -> +tx_cp_nr_rings] = tx_cp, tx rings
210 int bnxt_alloc_hwrm_rings(struct bnxt
*bp
)
215 /* Default completion ring */
217 struct bnxt_cp_ring_info
*cpr
= bp
->def_cp_ring
;
218 struct bnxt_ring
*cp_ring
= cpr
->cp_ring_struct
;
220 rc
= bnxt_hwrm_ring_alloc(bp
, cp_ring
,
221 HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL
,
222 0, HWRM_NA_SIGNATURE
);
226 (char *)bp
->eth_dev
->pci_dev
->mem_resource
[2].addr
;
227 B_CP_DIS_DB(cpr
, cpr
->cp_raw_cons
);
228 bp
->grp_info
[0].cp_fw_ring_id
= cp_ring
->fw_ring_id
;
231 for (i
= 0; i
< bp
->rx_cp_nr_rings
; i
++) {
232 struct bnxt_rx_queue
*rxq
= bp
->rx_queues
[i
];
233 struct bnxt_cp_ring_info
*cpr
= rxq
->cp_ring
;
234 struct bnxt_ring
*cp_ring
= cpr
->cp_ring_struct
;
235 struct bnxt_rx_ring_info
*rxr
= rxq
->rx_ring
;
236 struct bnxt_ring
*ring
= rxr
->rx_ring_struct
;
237 unsigned int idx
= i
+ 1;
240 rc
= bnxt_hwrm_ring_alloc(bp
, cp_ring
,
241 HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL
,
242 idx
, HWRM_NA_SIGNATURE
);
246 (char *)bp
->eth_dev
->pci_dev
->mem_resource
[2].addr
+
248 bp
->grp_info
[idx
].cp_fw_ring_id
= cp_ring
->fw_ring_id
;
249 B_CP_DIS_DB(cpr
, cpr
->cp_raw_cons
);
252 rc
= bnxt_hwrm_ring_alloc(bp
, ring
,
253 HWRM_RING_ALLOC_INPUT_RING_TYPE_RX
,
254 idx
, cpr
->hw_stats_ctx_id
);
259 (char *)bp
->eth_dev
->pci_dev
->mem_resource
[2].addr
+
261 bp
->grp_info
[idx
].rx_fw_ring_id
= ring
->fw_ring_id
;
262 B_RX_DB(rxr
->rx_doorbell
, rxr
->rx_prod
);
263 if (bnxt_init_one_rx_ring(rxq
)) {
264 RTE_LOG(ERR
, PMD
, "bnxt_init_one_rx_ring failed!");
265 bnxt_rx_queue_release_op(rxq
);
268 B_RX_DB(rxr
->rx_doorbell
, rxr
->rx_prod
);
271 for (i
= 0; i
< bp
->tx_cp_nr_rings
; i
++) {
272 struct bnxt_tx_queue
*txq
= bp
->tx_queues
[i
];
273 struct bnxt_cp_ring_info
*cpr
= txq
->cp_ring
;
274 struct bnxt_ring
*cp_ring
= cpr
->cp_ring_struct
;
275 struct bnxt_tx_ring_info
*txr
= txq
->tx_ring
;
276 struct bnxt_ring
*ring
= txr
->tx_ring_struct
;
277 unsigned int idx
= 1 + bp
->rx_cp_nr_rings
+ i
;
280 rc
= bnxt_hwrm_ring_alloc(bp
, cp_ring
,
281 HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL
,
282 idx
, HWRM_NA_SIGNATURE
);
287 (char *)bp
->eth_dev
->pci_dev
->mem_resource
[2].addr
+
289 bp
->grp_info
[idx
].cp_fw_ring_id
= cp_ring
->fw_ring_id
;
290 B_CP_DIS_DB(cpr
, cpr
->cp_raw_cons
);
293 rc
= bnxt_hwrm_ring_alloc(bp
, ring
,
294 HWRM_RING_ALLOC_INPUT_RING_TYPE_TX
,
295 idx
, cpr
->hw_stats_ctx_id
);
300 (char *)bp
->eth_dev
->pci_dev
->mem_resource
[2].addr
+