Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2025 Huawei Technologies Co., Ltd
3 : : */
4 : : #include <ethdev_pci.h>
5 : : #include <eal_interrupts.h>
6 : :
7 : : #include "base/hinic3_compat.h"
8 : : #include "base/hinic3_csr.h"
9 : : #include "base/hinic3_wq.h"
10 : : #include "base/hinic3_eqs.h"
11 : : #include "base/hinic3_cmdq.h"
12 : : #include "base/hinic3_hwdev.h"
13 : : #include "base/hinic3_hwif.h"
14 : : #include "base/hinic3_hw_cfg.h"
15 : : #include "base/hinic3_hw_comm.h"
16 : : #include "base/hinic3_nic_cfg.h"
17 : : #include "base/hinic3_nic_event.h"
18 : : #include "htn_adapt/hinic3_htn_cmdq.h"
19 : : #include "stn_adapt/hinic3_stn_cmdq.h"
20 : : #include "hinic3_nic_io.h"
21 : : #include "hinic3_tx.h"
22 : : #include "hinic3_rx.h"
23 : : #include "hinic3_ethdev.h"
24 : :
25 : : #define HINIC3_MIN_RX_BUF_SIZE 1024
26 : :
27 : : #define HINIC3_DEFAULT_BURST_SIZE 32
28 : : #define HINIC3_DEFAULT_NB_QUEUES 1
29 : : #define HINIC3_DEFAULT_RING_SIZE 1024
30 : : #define HINIC3_MAX_LRO_SIZE 65536
31 : :
32 : : #define HINIC3_DEFAULT_RX_FREE_THRESH 32u
33 : : #define HINIC3_DEFAULT_TX_FREE_THRESH 32u
34 : :
35 : : #define HINIC3_RX_WAIT_CYCLE_THRESH 150
36 : :
37 : : /**
38 : : * Get the 32-bit VFTA bit mask for the lower 5 bits of the VLAN ID.
39 : : *
40 : : * Vlan_id is a 12 bit number. The VFTA array is actually a 4096 bit array,
41 : : * 128 of 32bit elements. 2^5 = 32. The val of lower 5 bits specifies the bit
42 : : * in the 32bit element. The higher 7 bit val specifies VFTA array index.
43 : : */
44 : : #define HINIC3_VFTA_BIT(vlan_id) (1 << ((vlan_id) & 0x1F))
45 : : /**
46 : : * Get the VFTA index from the upper 7 bits of the VLAN ID.
47 : : */
48 : : #define HINIC3_VFTA_IDX(vlan_id) ((vlan_id) >> 5)
49 : :
50 : : #define HINIC3_LRO_DEFAULT_TIME_LIMIT 16
51 : : #define HINIC3_LRO_UNIT_WQE_SIZE 1024 /**< Bytes. */
52 : :
53 : : #define HINIC3_MAX_RX_PKT_LEN(rxmod) ((rxmod).mtu)
54 : : int hinic3_logtype; /**< Driver-specific log messages type. */
55 : :
56 : : /**
57 : : * The different receive modes for the NIC.
58 : : *
59 : : * The receive modes are represented as bit flags that control how the
60 : : * NIC handles various types of network traffic.
61 : : */
62 : : enum hinic3_rx_mod {
63 : : /* Enable unicast receive mode. */
64 : : HINIC3_RX_MODE_UC = 1 << 0,
65 : : /* Enable multicast receive mode. */
66 : : HINIC3_RX_MODE_MC = 1 << 1,
67 : : /* Enable broadcast receive mode. */
68 : : HINIC3_RX_MODE_BC = 1 << 2,
69 : : /* Enable receive mode for all multicast addresses. */
70 : : HINIC3_RX_MODE_MC_ALL = 1 << 3,
71 : : /* Enable promiscuous mode, receiving all packets. */
72 : : HINIC3_RX_MODE_PROMISC = 1 << 4,
73 : : };
74 : :
75 : : #define HINIC3_DEFAULT_RX_MODE \
76 : : (HINIC3_RX_MODE_UC | HINIC3_RX_MODE_MC | HINIC3_RX_MODE_BC)
77 : :
78 : : struct hinic3_xstats_name_off {
79 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
80 : : uint32_t offset;
81 : : };
82 : :
83 : : #define HINIC3_FUNC_STAT(_stat_item) \
84 : : { \
85 : : .name = #_stat_item, \
86 : : .offset = offsetof(struct hinic3_vport_stats, _stat_item), \
87 : : }
88 : :
89 : : static const struct hinic3_xstats_name_off hinic3_vport_stats_strings[] = {
90 : : HINIC3_FUNC_STAT(tx_unicast_pkts_vport),
91 : : HINIC3_FUNC_STAT(tx_unicast_bytes_vport),
92 : : HINIC3_FUNC_STAT(tx_multicast_pkts_vport),
93 : : HINIC3_FUNC_STAT(tx_multicast_bytes_vport),
94 : : HINIC3_FUNC_STAT(tx_broadcast_pkts_vport),
95 : : HINIC3_FUNC_STAT(tx_broadcast_bytes_vport),
96 : :
97 : : HINIC3_FUNC_STAT(rx_unicast_pkts_vport),
98 : : HINIC3_FUNC_STAT(rx_unicast_bytes_vport),
99 : : HINIC3_FUNC_STAT(rx_multicast_pkts_vport),
100 : : HINIC3_FUNC_STAT(rx_multicast_bytes_vport),
101 : : HINIC3_FUNC_STAT(rx_broadcast_pkts_vport),
102 : : HINIC3_FUNC_STAT(rx_broadcast_bytes_vport),
103 : :
104 : : HINIC3_FUNC_STAT(tx_discard_vport),
105 : : HINIC3_FUNC_STAT(rx_discard_vport),
106 : : HINIC3_FUNC_STAT(tx_err_vport),
107 : : HINIC3_FUNC_STAT(rx_err_vport),
108 : : };
109 : :
110 : : #define HINIC3_VPORT_XSTATS_NUM RTE_DIM(hinic3_vport_stats_strings)
111 : :
112 : : #define HINIC3_PORT_STAT(_stat_item) \
113 : : { \
114 : : .name = #_stat_item, \
115 : : .offset = offsetof(struct mag_phy_port_stats, _stat_item), \
116 : : }
117 : :
118 : : static const struct hinic3_xstats_name_off hinic3_phyport_stats_strings[] = {
119 : : HINIC3_PORT_STAT(mac_tx_fragment_pkt_num),
120 : : HINIC3_PORT_STAT(mac_tx_undersize_pkt_num),
121 : : HINIC3_PORT_STAT(mac_tx_undermin_pkt_num),
122 : : HINIC3_PORT_STAT(mac_tx_64_oct_pkt_num),
123 : : HINIC3_PORT_STAT(mac_tx_65_127_oct_pkt_num),
124 : : HINIC3_PORT_STAT(mac_tx_128_255_oct_pkt_num),
125 : : HINIC3_PORT_STAT(mac_tx_256_511_oct_pkt_num),
126 : : HINIC3_PORT_STAT(mac_tx_512_1023_oct_pkt_num),
127 : : HINIC3_PORT_STAT(mac_tx_1024_1518_oct_pkt_num),
128 : : HINIC3_PORT_STAT(mac_tx_1519_2047_oct_pkt_num),
129 : : HINIC3_PORT_STAT(mac_tx_2048_4095_oct_pkt_num),
130 : : HINIC3_PORT_STAT(mac_tx_4096_8191_oct_pkt_num),
131 : : HINIC3_PORT_STAT(mac_tx_8192_9216_oct_pkt_num),
132 : : HINIC3_PORT_STAT(mac_tx_9217_12287_oct_pkt_num),
133 : : HINIC3_PORT_STAT(mac_tx_12288_16383_oct_pkt_num),
134 : : HINIC3_PORT_STAT(mac_tx_1519_max_bad_pkt_num),
135 : : HINIC3_PORT_STAT(mac_tx_1519_max_good_pkt_num),
136 : : HINIC3_PORT_STAT(mac_tx_oversize_pkt_num),
137 : : HINIC3_PORT_STAT(mac_tx_jabber_pkt_num),
138 : : HINIC3_PORT_STAT(mac_tx_bad_pkt_num),
139 : : HINIC3_PORT_STAT(mac_tx_bad_oct_num),
140 : : HINIC3_PORT_STAT(mac_tx_good_pkt_num),
141 : : HINIC3_PORT_STAT(mac_tx_good_oct_num),
142 : : HINIC3_PORT_STAT(mac_tx_total_pkt_num),
143 : : HINIC3_PORT_STAT(mac_tx_total_oct_num),
144 : : HINIC3_PORT_STAT(mac_tx_uni_pkt_num),
145 : : HINIC3_PORT_STAT(mac_tx_multi_pkt_num),
146 : : HINIC3_PORT_STAT(mac_tx_broad_pkt_num),
147 : : HINIC3_PORT_STAT(mac_tx_pause_num),
148 : : HINIC3_PORT_STAT(mac_tx_pfc_pkt_num),
149 : : HINIC3_PORT_STAT(mac_tx_pfc_pri0_pkt_num),
150 : : HINIC3_PORT_STAT(mac_tx_pfc_pri1_pkt_num),
151 : : HINIC3_PORT_STAT(mac_tx_pfc_pri2_pkt_num),
152 : : HINIC3_PORT_STAT(mac_tx_pfc_pri3_pkt_num),
153 : : HINIC3_PORT_STAT(mac_tx_pfc_pri4_pkt_num),
154 : : HINIC3_PORT_STAT(mac_tx_pfc_pri5_pkt_num),
155 : : HINIC3_PORT_STAT(mac_tx_pfc_pri6_pkt_num),
156 : : HINIC3_PORT_STAT(mac_tx_pfc_pri7_pkt_num),
157 : : HINIC3_PORT_STAT(mac_tx_control_pkt_num),
158 : : HINIC3_PORT_STAT(mac_tx_err_all_pkt_num),
159 : : HINIC3_PORT_STAT(mac_tx_from_app_good_pkt_num),
160 : : HINIC3_PORT_STAT(mac_tx_from_app_bad_pkt_num),
161 : :
162 : : HINIC3_PORT_STAT(mac_rx_fragment_pkt_num),
163 : : HINIC3_PORT_STAT(mac_rx_undersize_pkt_num),
164 : : HINIC3_PORT_STAT(mac_rx_undermin_pkt_num),
165 : : HINIC3_PORT_STAT(mac_rx_64_oct_pkt_num),
166 : : HINIC3_PORT_STAT(mac_rx_65_127_oct_pkt_num),
167 : : HINIC3_PORT_STAT(mac_rx_128_255_oct_pkt_num),
168 : : HINIC3_PORT_STAT(mac_rx_256_511_oct_pkt_num),
169 : : HINIC3_PORT_STAT(mac_rx_512_1023_oct_pkt_num),
170 : : HINIC3_PORT_STAT(mac_rx_1024_1518_oct_pkt_num),
171 : : HINIC3_PORT_STAT(mac_rx_1519_2047_oct_pkt_num),
172 : : HINIC3_PORT_STAT(mac_rx_2048_4095_oct_pkt_num),
173 : : HINIC3_PORT_STAT(mac_rx_4096_8191_oct_pkt_num),
174 : : HINIC3_PORT_STAT(mac_rx_8192_9216_oct_pkt_num),
175 : : HINIC3_PORT_STAT(mac_rx_9217_12287_oct_pkt_num),
176 : : HINIC3_PORT_STAT(mac_rx_12288_16383_oct_pkt_num),
177 : : HINIC3_PORT_STAT(mac_rx_1519_max_bad_pkt_num),
178 : : HINIC3_PORT_STAT(mac_rx_1519_max_good_pkt_num),
179 : : HINIC3_PORT_STAT(mac_rx_oversize_pkt_num),
180 : : HINIC3_PORT_STAT(mac_rx_jabber_pkt_num),
181 : : HINIC3_PORT_STAT(mac_rx_bad_pkt_num),
182 : : HINIC3_PORT_STAT(mac_rx_bad_oct_num),
183 : : HINIC3_PORT_STAT(mac_rx_good_pkt_num),
184 : : HINIC3_PORT_STAT(mac_rx_good_oct_num),
185 : : HINIC3_PORT_STAT(mac_rx_total_pkt_num),
186 : : HINIC3_PORT_STAT(mac_rx_total_oct_num),
187 : : HINIC3_PORT_STAT(mac_rx_uni_pkt_num),
188 : : HINIC3_PORT_STAT(mac_rx_multi_pkt_num),
189 : : HINIC3_PORT_STAT(mac_rx_broad_pkt_num),
190 : : HINIC3_PORT_STAT(mac_rx_pause_num),
191 : : HINIC3_PORT_STAT(mac_rx_pfc_pkt_num),
192 : : HINIC3_PORT_STAT(mac_rx_pfc_pri0_pkt_num),
193 : : HINIC3_PORT_STAT(mac_rx_pfc_pri1_pkt_num),
194 : : HINIC3_PORT_STAT(mac_rx_pfc_pri2_pkt_num),
195 : : HINIC3_PORT_STAT(mac_rx_pfc_pri3_pkt_num),
196 : : HINIC3_PORT_STAT(mac_rx_pfc_pri4_pkt_num),
197 : : HINIC3_PORT_STAT(mac_rx_pfc_pri5_pkt_num),
198 : : HINIC3_PORT_STAT(mac_rx_pfc_pri6_pkt_num),
199 : : HINIC3_PORT_STAT(mac_rx_pfc_pri7_pkt_num),
200 : : HINIC3_PORT_STAT(mac_rx_control_pkt_num),
201 : : HINIC3_PORT_STAT(mac_rx_sym_err_pkt_num),
202 : : HINIC3_PORT_STAT(mac_rx_fcs_err_pkt_num),
203 : : HINIC3_PORT_STAT(mac_rx_send_app_good_pkt_num),
204 : : HINIC3_PORT_STAT(mac_rx_send_app_bad_pkt_num),
205 : : HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
206 : : };
207 : :
208 : : #define HINIC3_PHYPORT_XSTATS_NUM RTE_DIM(hinic3_phyport_stats_strings)
209 : :
210 : : #define HINIC3_RXQ_STAT(_stat_item) \
211 : : { \
212 : : .name = #_stat_item, \
213 : : .offset = offsetof(struct hinic3_rxq_stats, _stat_item), \
214 : : }
215 : :
216 : : /**
217 : : * The name and offset field of RXQ statistic items.
218 : : *
219 : : * The inclusion of additional statistics depends on the compilation flags:
220 : : * - `HINIC3_XSTAT_RXBUF_INFO` enables buffer-related stats.
221 : : * - `HINIC3_XSTAT_PROF_RX` enables performance timing stats.
222 : : * - `HINIC3_XSTAT_MBUF_USE` enables memory buffer usage stats.
223 : : */
224 : : static const struct hinic3_xstats_name_off hinic3_rxq_stats_strings[] = {
225 : : HINIC3_RXQ_STAT(rx_nombuf),
226 : : HINIC3_RXQ_STAT(burst_pkts),
227 : : HINIC3_RXQ_STAT(errors),
228 : : HINIC3_RXQ_STAT(csum_errors),
229 : : HINIC3_RXQ_STAT(other_errors),
230 : : HINIC3_RXQ_STAT(empty),
231 : :
232 : : #ifdef HINIC3_XSTAT_RXBUF_INFO
233 : : HINIC3_RXQ_STAT(rx_mbuf),
234 : : HINIC3_RXQ_STAT(rx_avail),
235 : : HINIC3_RXQ_STAT(rx_hole),
236 : : #endif
237 : :
238 : : #ifdef HINIC3_XSTAT_PROF_RX
239 : : HINIC3_RXQ_STAT(app_tsc),
240 : : HINIC3_RXQ_STAT(pmd_tsc),
241 : : #endif
242 : :
243 : : #ifdef HINIC3_XSTAT_MBUF_USE
244 : : HINIC3_RXQ_STAT(rx_alloc_mbuf_bytes),
245 : : HINIC3_RXQ_STAT(rx_free_mbuf_bytes),
246 : : HINIC3_RXQ_STAT(rx_left_mbuf_bytes),
247 : : #endif
248 : : };
249 : :
250 : : #define HINIC3_RXQ_XSTATS_NUM RTE_DIM(hinic3_rxq_stats_strings)
251 : :
252 : : #define HINIC3_TXQ_STAT(_stat_item) \
253 : : { \
254 : : .name = #_stat_item, \
255 : : .offset = offsetof(struct hinic3_txq_stats, _stat_item), \
256 : : }
257 : :
258 : : /**
259 : : * The name and offset field of TXQ statistic items.
260 : : *
261 : : * The inclusion of additional statistics depends on the compilation flags:
262 : : * - `HINIC3_XSTAT_PROF_TX` enables performance timing stats.
263 : : * - `HINIC3_XSTAT_MBUF_USE` enables memory buffer usage stats.
264 : : */
265 : : static const struct hinic3_xstats_name_off hinic3_txq_stats_strings[] = {
266 : : HINIC3_TXQ_STAT(tx_busy),
267 : : HINIC3_TXQ_STAT(offload_errors),
268 : : HINIC3_TXQ_STAT(burst_pkts),
269 : : HINIC3_TXQ_STAT(sge_len0),
270 : : HINIC3_TXQ_STAT(mbuf_null),
271 : :
272 : : #ifdef HINIC3_XSTAT_PROF_TX
273 : : HINIC3_TXQ_STAT(app_tsc),
274 : : HINIC3_TXQ_STAT(pmd_tsc),
275 : : #endif
276 : :
277 : : #ifdef HINIC3_XSTAT_MBUF_USE
278 : : HINIC3_TXQ_STAT(tx_left_mbuf_bytes),
279 : : #endif
280 : : };
281 : :
282 : : #define HINIC3_TXQ_XSTATS_NUM RTE_DIM(hinic3_txq_stats_strings)
283 : :
284 : : static uint32_t
285 : : hinic3_xstats_calc_num(struct hinic3_nic_dev *nic_dev)
286 : : {
287 [ # # ]: 0 : if (HINIC3_IS_VF(nic_dev->hwdev)) {
288 : : return (HINIC3_VPORT_XSTATS_NUM +
289 : 0 : HINIC3_RXQ_XSTATS_NUM * nic_dev->num_rqs +
290 : 0 : HINIC3_TXQ_XSTATS_NUM * nic_dev->num_sqs);
291 : : } else {
292 : : return (HINIC3_VPORT_XSTATS_NUM + HINIC3_PHYPORT_XSTATS_NUM +
293 : 0 : HINIC3_RXQ_XSTATS_NUM * nic_dev->num_rqs +
294 : 0 : HINIC3_TXQ_XSTATS_NUM * nic_dev->num_sqs);
295 : : }
296 : : }
297 : :
298 : : #define HINIC3_MAX_QUEUE_DEPTH 16384
299 : : #define HINIC3_MIN_QUEUE_DEPTH 128
300 : : #define HINIC3_TXD_ALIGN 1
301 : : #define HINIC3_RXD_ALIGN 1
302 : :
303 : : static const struct rte_eth_desc_lim hinic3_rx_desc_lim = {
304 : : .nb_max = HINIC3_MAX_QUEUE_DEPTH,
305 : : .nb_min = HINIC3_MIN_QUEUE_DEPTH,
306 : : .nb_align = HINIC3_RXD_ALIGN,
307 : : };
308 : :
309 : : static const struct rte_eth_desc_lim hinic3_tx_desc_lim = {
310 : : .nb_max = HINIC3_MAX_QUEUE_DEPTH,
311 : : .nb_min = HINIC3_MIN_QUEUE_DEPTH,
312 : : .nb_align = HINIC3_TXD_ALIGN,
313 : : };
314 : :
315 : : /*
316 : : * Init mac_vlan table in hardwares.
317 : : *
318 : : * @param[in] eth_dev
319 : : * Pointer to ethernet device structure.
320 : : *
321 : : * @return
322 : : * 0 on success, non-zero on failure.
323 : : */
324 : : static int
325 : 0 : hinic3_init_mac_table(struct rte_eth_dev *eth_dev)
326 : : {
327 : 0 : struct hinic3_nic_dev *nic_dev =
328 : 0 : HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
329 : : uint8_t addr_bytes[RTE_ETHER_ADDR_LEN];
330 : : uint16_t func_id = 0;
331 : : int err = 0;
332 : :
333 : 0 : err = hinic3_get_default_mac(nic_dev->hwdev, addr_bytes,
334 : : RTE_ETHER_ADDR_LEN);
335 [ # # ]: 0 : if (err)
336 : : return err;
337 : :
338 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)addr_bytes,
339 [ # # ]: 0 : ð_dev->data->mac_addrs[0]);
340 [ # # # # ]: 0 : if (rte_is_zero_ether_addr(ð_dev->data->mac_addrs[0]) ||
341 : : rte_is_broadcast_ether_addr(ð_dev->data->mac_addrs[0]))
342 : 0 : rte_eth_random_addr(eth_dev->data->mac_addrs[0].addr_bytes);
343 : :
344 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
345 : 0 : err = hinic3_set_mac(nic_dev->hwdev,
346 : 0 : eth_dev->data->mac_addrs[0].addr_bytes, 0, func_id);
347 [ # # ]: 0 : if (err && err != HINIC3_PF_SET_VF_ALREADY)
348 : : return err;
349 : :
350 : 0 : rte_ether_addr_copy(ð_dev->data->mac_addrs[0],
351 : : &nic_dev->default_addr);
352 : :
353 : 0 : return 0;
354 : : }
355 : :
356 : : /**
357 : : * Delete all multicast MAC addresses from the NIC device.
358 : : *
359 : : * This function iterates over the list of multicast MAC addresses and removes
360 : : * each address from the NIC device by calling `hinic3_del_mac`. After each
361 : : * deletion, the address is reset to zero.
362 : : *
363 : : * @param[in] nic_dev
364 : : * Pointer to NIC device structure.
365 : : */
366 : : static void
367 : 0 : hinic3_delete_mc_addr_list(struct hinic3_nic_dev *nic_dev)
368 : : {
369 : : uint16_t func_id;
370 : : uint32_t i;
371 : :
372 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
373 : :
374 [ # # ]: 0 : for (i = 0; i < HINIC3_MAX_MC_MAC_ADDRS; i++) {
375 [ # # ]: 0 : if (rte_is_zero_ether_addr(&nic_dev->mc_list[i]))
376 : : break;
377 : :
378 : 0 : hinic3_del_mac(nic_dev->hwdev, nic_dev->mc_list[i].addr_bytes, 0, func_id);
379 : 0 : memset(&nic_dev->mc_list[i], 0, sizeof(struct rte_ether_addr));
380 : : }
381 : 0 : }
382 : :
383 : : /**
384 : : * Deinit mac_vlan table in hardware.
385 : : *
386 : : * @param[in] eth_dev
387 : : * Pointer to ethernet device structure.
388 : : */
389 : : static void
390 : 0 : hinic3_deinit_mac_addr(struct rte_eth_dev *eth_dev)
391 : : {
392 : 0 : struct hinic3_nic_dev *nic_dev =
393 : 0 : HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
394 : : uint16_t func_id = 0;
395 : : int err;
396 : : int i;
397 : :
398 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
399 : :
400 [ # # ]: 0 : for (i = 0; i < HINIC3_MAX_UC_MAC_ADDRS; i++) {
401 [ # # ]: 0 : if (rte_is_zero_ether_addr(ð_dev->data->mac_addrs[i]))
402 : 0 : continue;
403 : :
404 : 0 : err = hinic3_del_mac(nic_dev->hwdev,
405 : 0 : eth_dev->data->mac_addrs[i].addr_bytes, 0, func_id);
406 [ # # ]: 0 : if (err && err != HINIC3_PF_SET_VF_ALREADY)
407 : 0 : PMD_DRV_LOG(ERR,
408 : : "Delete mac table failed, dev_name: %s",
409 : : eth_dev->data->name);
410 : :
411 : 0 : memset(ð_dev->data->mac_addrs[i], 0,
412 : : sizeof(struct rte_ether_addr));
413 : : }
414 : :
415 : : /* Delete multicast mac addrs. */
416 : 0 : hinic3_delete_mc_addr_list(nic_dev);
417 : 0 : }
418 : :
419 : : /**
420 : : * Check the valid CoS bitmap to determine the available CoS IDs and set
421 : : * the default CoS ID to the highest valid one.
422 : : *
423 : : * @param[in] hwdev
424 : : * Pointer to hardware device structure.
425 : : * @param[out] cos_id
426 : : * Pointer to store the default CoS ID.
427 : : *
428 : : * @return
429 : : * 0 on success, non-zero on failure.
430 : : */
431 : : static int
432 : 0 : hinic3_pf_get_default_cos(struct hinic3_hwdev *hwdev, uint8_t *cos_id)
433 : : {
434 : 0 : struct hinic3_nic_dev *nic_dev = hwdev->dev_handle;
435 : : uint8_t default_cos = 0;
436 : : uint8_t valid_cos_bitmap;
437 : : uint8_t cos_num_max;
438 : : uint8_t i;
439 : :
440 : 0 : valid_cos_bitmap = hwdev->cfg_mgmt->svc_cap.cos_valid_bitmap;
441 [ # # ]: 0 : if (!valid_cos_bitmap) {
442 : 0 : PMD_DRV_LOG(ERR, "PF has none cos to support");
443 : 0 : return -EFAULT;
444 : : }
445 : :
446 [ # # ]: 0 : cos_num_max = nic_dev->feature_cap & NIC_F_HTN_CMDQ ?
447 : : HINIC3_COS_NUM_MAX_HTN : HINIC3_COS_NUM_MAX;
448 : :
449 [ # # ]: 0 : for (i = 0; i < cos_num_max; i++) {
450 [ # # ]: 0 : if (valid_cos_bitmap & RTE_BIT32(i))
451 : : /* Find max cos id as default cos. */
452 : : default_cos = i;
453 : : }
454 : :
455 : 0 : *cos_id = default_cos;
456 : :
457 : 0 : return 0;
458 : : }
459 : :
460 : : static int
461 : 0 : hinic3_init_default_cos(struct hinic3_nic_dev *nic_dev)
462 : : {
463 : 0 : uint8_t cos_id = 0;
464 : : int err;
465 : :
466 [ # # ]: 0 : if (!HINIC3_IS_VF(nic_dev->hwdev)) {
467 : 0 : err = hinic3_pf_get_default_cos(nic_dev->hwdev, &cos_id);
468 [ # # ]: 0 : if (err) {
469 : 0 : PMD_DRV_LOG(ERR, "Get PF default cos failed, err: %d", err);
470 : 0 : return err;
471 : : }
472 : : } else {
473 : 0 : err = hinic3_vf_get_default_cos(nic_dev->hwdev, &cos_id);
474 [ # # ]: 0 : if (err) {
475 : 0 : PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d", err);
476 : 0 : return err;
477 : : }
478 : : }
479 : :
480 : 0 : nic_dev->default_cos = cos_id;
481 : 0 : PMD_DRV_LOG(DEBUG, "Default cos %d", nic_dev->default_cos);
482 : 0 : return 0;
483 : : }
484 : :
485 : : /**
486 : : * Initialize Class of Service (CoS). For PF devices, it also sync the link
487 : : * status with the physical port.
488 : : *
489 : : * @param[in] nic_dev
490 : : * Pointer to NIC device structure.
491 : : *
492 : : * @return
493 : : * 0 on success, non-zero on failure.
494 : : */
495 : : static int
496 : 0 : hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
497 : : {
498 : : int err;
499 : :
500 : 0 : err = hinic3_init_default_cos(nic_dev);
501 [ # # ]: 0 : if (err)
502 : : return err;
503 : :
504 [ # # ]: 0 : if (hinic3_func_type(nic_dev->hwdev) == TYPE_VF)
505 : : return 0;
506 : :
507 : 0 : err = hinic3_set_link_status_follow(nic_dev->hwdev,
508 : : HINIC3_LINK_FOLLOW_PORT);
509 [ # # ]: 0 : if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
510 : 0 : PMD_DRV_LOG(WARNING, "Don't support to set link status follow phy port status");
511 [ # # ]: 0 : else if (err)
512 : 0 : return err;
513 : :
514 : : return 0;
515 : : }
516 : :
517 : : static int
518 : 0 : hinic3_init_sw_rxtxqs(struct hinic3_nic_dev *nic_dev)
519 : : {
520 : : uint32_t txq_size;
521 : : uint32_t rxq_size;
522 : :
523 : : /* Allocate software txq array. */
524 : 0 : txq_size = nic_dev->max_sqs * sizeof(*nic_dev->txqs);
525 : 0 : nic_dev->txqs =
526 : 0 : rte_zmalloc("hinic3_txqs", txq_size, RTE_CACHE_LINE_SIZE);
527 [ # # ]: 0 : if (!nic_dev->txqs) {
528 : 0 : PMD_DRV_LOG(ERR, "Allocate txqs failed");
529 : 0 : return -ENOMEM;
530 : : }
531 : :
532 : : /* Allocate software rxq array. */
533 : 0 : rxq_size = nic_dev->max_rqs * sizeof(*nic_dev->rxqs);
534 : 0 : nic_dev->rxqs =
535 : 0 : rte_zmalloc("hinic3_rxqs", rxq_size, RTE_CACHE_LINE_SIZE);
536 [ # # ]: 0 : if (!nic_dev->rxqs) {
537 : : /* Free txqs. */
538 : 0 : rte_free(nic_dev->txqs);
539 : 0 : nic_dev->txqs = NULL;
540 : :
541 : 0 : PMD_DRV_LOG(ERR, "Allocate rxqs failed");
542 : 0 : return -ENOMEM;
543 : : }
544 : :
545 : : return 0;
546 : : }
547 : :
548 : : static void
549 : : hinic3_deinit_sw_rxtxqs(struct hinic3_nic_dev *nic_dev)
550 : : {
551 : 0 : rte_free(nic_dev->txqs);
552 : 0 : nic_dev->txqs = NULL;
553 : :
554 : 0 : rte_free(nic_dev->rxqs);
555 : 0 : nic_dev->rxqs = NULL;
556 : 0 : }
557 : :
558 : : /**
559 : : * Look up or creates a memory pool for storing packet buffers used in copy
560 : : * operations.
561 : : *
562 : : * @param[in] nic_dev
563 : : * Pointer to NIC device structure.
564 : : *
565 : : * @return
566 : : * 0 on success, non-zero on failure.
567 : : * `-ENOMEM`: Memory pool creation fails.
568 : : */
569 : : static int
570 : 0 : hinic3_copy_mempool_init(struct hinic3_nic_dev *nic_dev)
571 : : {
572 : 0 : nic_dev->cpy_mpool = rte_mempool_lookup(HINCI3_CPY_MEMPOOL_NAME);
573 [ # # ]: 0 : if (nic_dev->cpy_mpool == NULL) {
574 : 0 : nic_dev->cpy_mpool = rte_pktmbuf_pool_create(HINCI3_CPY_MEMPOOL_NAME,
575 : : HINIC3_COPY_MEMPOOL_DEPTH, HINIC3_COPY_MEMPOOL_CACHE,
576 : 0 : 0, HINIC3_COPY_MBUF_SIZE, rte_socket_id());
577 [ # # ]: 0 : if (nic_dev->cpy_mpool == NULL) {
578 : 0 : PMD_DRV_LOG(ERR,
579 : : "Create copy mempool failed, errno: %d, dev_name: %s",
580 : : rte_errno, HINCI3_CPY_MEMPOOL_NAME);
581 : 0 : return -ENOMEM;
582 : : }
583 : : }
584 : :
585 : : return 0;
586 : : }
587 : :
588 : : /**
589 : : * Clear the reference to the copy memory pool without freeing it.
590 : : *
591 : : * @param[in] nic_dev
592 : : * Pointer to NIC device structure.
593 : : */
594 : : static void
595 : : hinic3_copy_mempool_uninit(struct hinic3_nic_dev *nic_dev)
596 : : {
597 : 0 : nic_dev->cpy_mpool = NULL;
598 : 0 : }
599 : :
600 : : /**
601 : : * Interrupt handler triggered by NIC for handling specific event.
602 : : *
603 : : * @param[in] param
604 : : * The address of parameter (struct rte_eth_dev *) registered before.
605 : : */
606 : : static void
607 : 0 : hinic3_dev_interrupt_handler(void *param)
608 : : {
609 : : struct rte_eth_dev *dev = param;
610 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
611 : :
612 [ # # ]: 0 : if (!hinic3_get_bit(HINIC3_DEV_INTR_EN, &nic_dev->dev_status)) {
613 : 0 : PMD_DRV_LOG(WARNING,
614 : : "Intr is disabled, ignore intr event, dev_name: %s, port_id: %d",
615 : : nic_dev->dev_name, dev->data->port_id);
616 : 0 : return;
617 : : }
618 : :
619 : : /* Aeq0 msg handler. */
620 : 0 : hinic3_dev_handle_aeq_event(nic_dev->hwdev, param);
621 : : }
622 : :
623 : : /**
624 : : * Do the config for TX/Rx queues, include queue number, mtu size and RSS.
625 : : *
626 : : * @param[in] dev
627 : : * Pointer to ethernet device structure.
628 : : *
629 : : * @return
630 : : * 0 on success, non-zero on failure.
631 : : */
632 : : static int
633 : 0 : hinic3_dev_configure(struct rte_eth_dev *dev)
634 : : {
635 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
636 : :
637 : 0 : nic_dev->num_sqs = dev->data->nb_tx_queues;
638 : 0 : nic_dev->num_rqs = dev->data->nb_rx_queues;
639 : :
640 : 0 : nic_dev->mtu_size =
641 : 0 : (uint16_t)HINIC3_PKTLEN_TO_MTU(HINIC3_MAX_RX_PKT_LEN(dev->data->dev_conf.rxmode));
642 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
643 : 0 : dev->data->dev_conf.rxmode.offloads |=
644 : : RTE_ETH_RX_OFFLOAD_RSS_HASH;
645 : :
646 : : /* Clear fdir filter. */
647 : 0 : hinic3_free_fdir_filter(dev);
648 : :
649 : 0 : return 0;
650 : : }
651 : :
652 : : static void
653 : 0 : hinic3_dev_tnl_tso_support(struct rte_eth_dev_info *info, struct hinic3_nic_dev *nic_dev)
654 : : {
655 [ # # ]: 0 : if (HINIC3_SUPPORT_GENEVE_OFFLOAD(nic_dev))
656 : 0 : info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
657 [ # # ]: 0 : if (HINIC3_SUPPORT_IPXIP_OFFLOAD(nic_dev))
658 : 0 : info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO;
659 : 0 : }
660 : :
661 : : /**
662 : : * Get information about the device.
663 : : *
664 : : * @param[in] dev
665 : : * Pointer to ethernet device structure.
666 : : * @param[out] info
667 : : * Info structure for ethernet device.
668 : : *
669 : : * @return
670 : : * 0 on success, non-zero on failure.
671 : : */
672 : : static int
673 : 0 : hinic3_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
674 : : {
675 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
676 : :
677 : 0 : info->max_rx_queues = nic_dev->max_rqs;
678 : 0 : info->max_tx_queues = nic_dev->max_sqs;
679 : 0 : info->min_rx_bufsize = HINIC3_MIN_RX_BUF_SIZE;
680 : 0 : info->max_rx_pktlen = HINIC3_MAX_JUMBO_FRAME_SIZE;
681 : 0 : info->max_mac_addrs = HINIC3_MAX_UC_MAC_ADDRS;
682 : 0 : info->min_mtu = HINIC3_MIN_MTU_SIZE;
683 : 0 : info->max_mtu = HINIC3_MAX_MTU_SIZE;
684 : 0 : info->max_lro_pkt_size = HINIC3_MAX_LRO_SIZE;
685 : :
686 : 0 : info->rx_queue_offload_capa = 0;
687 : 0 : info->rx_offload_capa =
688 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP | RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
689 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
690 : : RTE_ETH_RX_OFFLOAD_SCTP_CKSUM | RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
691 : : RTE_ETH_RX_OFFLOAD_SCATTER | RTE_ETH_RX_OFFLOAD_TCP_LRO |
692 : : RTE_ETH_RX_OFFLOAD_RSS_HASH;
693 : :
694 : 0 : info->tx_queue_offload_capa = 0;
695 : 0 : info->tx_offload_capa =
696 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT | RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
697 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM | RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
698 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
699 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
700 : : RTE_ETH_TX_OFFLOAD_TCP_TSO | RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
701 [ # # ]: 0 : if (nic_dev->feature_cap & NIC_F_HTN_CMDQ)
702 : 0 : hinic3_dev_tnl_tso_support(info, nic_dev);
703 : :
704 : 0 : info->hash_key_size = HINIC3_RSS_KEY_SIZE;
705 : 0 : info->reta_size = HINIC3_RSS_INDIR_SIZE;
706 : 0 : info->flow_type_rss_offloads = HINIC3_RSS_OFFLOAD_ALL;
707 : :
708 : 0 : info->rx_desc_lim = hinic3_rx_desc_lim;
709 : 0 : info->tx_desc_lim = hinic3_tx_desc_lim;
710 : :
711 : : /* Driver-preferred rx/tx parameters. */
712 : 0 : info->default_rxportconf.burst_size = HINIC3_DEFAULT_BURST_SIZE;
713 : 0 : info->default_txportconf.burst_size = HINIC3_DEFAULT_BURST_SIZE;
714 : 0 : info->default_rxportconf.nb_queues = HINIC3_DEFAULT_NB_QUEUES;
715 : 0 : info->default_txportconf.nb_queues = HINIC3_DEFAULT_NB_QUEUES;
716 : 0 : info->default_rxportconf.ring_size = HINIC3_DEFAULT_RING_SIZE;
717 : 0 : info->default_txportconf.ring_size = HINIC3_DEFAULT_RING_SIZE;
718 : :
719 : 0 : return 0;
720 : : }
721 : :
722 : : static int
723 : 0 : hinic3_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
724 : : {
725 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
726 : 0 : char mgmt_ver[MGMT_VERSION_MAX_LEN] = {0};
727 : : int err;
728 : :
729 : 0 : err = hinic3_get_mgmt_version(nic_dev->hwdev, mgmt_ver,
730 : : HINIC3_MGMT_VERSION_MAX_LEN);
731 [ # # ]: 0 : if (err) {
732 : 0 : PMD_DRV_LOG(ERR, "Get fw version failed");
733 : 0 : return -EIO;
734 : : }
735 : :
736 [ # # ]: 0 : if (fw_size < strlen(mgmt_ver) + 1)
737 : 0 : return (strlen(mgmt_ver) + 1);
738 : :
739 : : strlcpy(fw_version, mgmt_ver, fw_size);
740 : :
741 : 0 : return 0;
742 : : }
743 : :
744 : : /**
745 : : * Set ethernet device link state up.
746 : : *
747 : : * @param[in] dev
748 : : * Pointer to ethernet device structure.
749 : : *
750 : : * @return
751 : : * 0 on success, non-zero on failure.
752 : : */
753 : : static int
754 : 0 : hinic3_dev_set_link_up(struct rte_eth_dev *dev)
755 : : {
756 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
757 : : int err;
758 : :
759 : : /*
760 : : * Vport enable will set function valid in mpu.
761 : : * So dev start status need to be checked before vport enable.
762 : : */
763 [ # # ]: 0 : if (hinic3_get_bit(HINIC3_DEV_START, &nic_dev->dev_status)) {
764 : 0 : err = hinic3_set_vport_enable(nic_dev->hwdev, true);
765 [ # # ]: 0 : if (err) {
766 : 0 : PMD_DRV_LOG(ERR, "Enable vport failed, dev_name: %s",
767 : : nic_dev->dev_name);
768 : 0 : return err;
769 : : }
770 : : }
771 : :
772 : : /* Link status follow phy port status, mpu will open pma. */
773 : 0 : err = hinic3_set_port_enable(nic_dev->hwdev, true);
774 [ # # ]: 0 : if (err) {
775 : 0 : PMD_DRV_LOG(ERR,
776 : : "Set MAC link up failed, dev_name: %s, port_id: %d",
777 : : nic_dev->dev_name, dev->data->port_id);
778 : 0 : return err;
779 : : }
780 : :
781 : : return 0;
782 : : }
783 : :
784 : : /**
785 : : * Set ethernet device link state down.
786 : : *
787 : : * @param[in] dev
788 : : * Pointer to ethernet device structure.
789 : : *
790 : : * @return
791 : : * 0 on success, non-zero on failure.
792 : : */
793 : : static int
794 : 0 : hinic3_dev_set_link_down(struct rte_eth_dev *dev)
795 : : {
796 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
797 : : int err;
798 : :
799 : 0 : err = hinic3_set_vport_enable(nic_dev->hwdev, false);
800 [ # # ]: 0 : if (err) {
801 : 0 : PMD_DRV_LOG(ERR, "Disable vport failed, dev_name: %s",
802 : : nic_dev->dev_name);
803 : 0 : return err;
804 : : }
805 : :
806 : : /* Link status follow phy port status, mpu will close pma. */
807 : 0 : err = hinic3_set_port_enable(nic_dev->hwdev, false);
808 [ # # ]: 0 : if (err) {
809 : 0 : PMD_DRV_LOG(ERR,
810 : : "Set MAC link down failed, dev_name: %s, port_id: %d",
811 : : nic_dev->dev_name, dev->data->port_id);
812 : 0 : return err;
813 : : }
814 : :
815 : : return 0;
816 : : }
817 : :
818 : : /**
819 : : * Get device physical link information.
820 : : *
821 : : * @param[in] dev
822 : : * Pointer to ethernet device structure.
823 : : * @param[in] wait_to_complete
824 : : * Wait for request completion.
825 : : *
826 : : * @return
827 : : * 0 : Link status changed
828 : : * -1 : Link status not changed.
829 : : */
830 : : static int
831 : 0 : hinic3_link_update(struct rte_eth_dev *dev, int wait_to_complete)
832 : : {
833 : : #define CHECK_INTERVAL 10 /**< 10ms. */
834 : : #define MAX_REPEAT_TIME 100 /**< 1s (100 * 10ms) in total. */
835 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
836 : : struct rte_eth_link link;
837 : : uint8_t link_state;
838 : : unsigned int rep_cnt = MAX_REPEAT_TIME;
839 : : int ret;
840 : :
841 : : memset(&link, 0, sizeof(link));
842 : : do {
843 : : /* Get link status information from hardware. */
844 : 0 : ret = hinic3_get_link_state(nic_dev->hwdev, &link_state);
845 [ # # ]: 0 : if (ret) {
846 : 0 : link.link_status = RTE_ETH_LINK_DOWN;
847 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
848 : 0 : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
849 : 0 : link.link_autoneg = RTE_ETH_LINK_FIXED;
850 : 0 : goto out;
851 : : }
852 : :
853 : 0 : hinic3_get_link_port_info(nic_dev->hwdev, link_state, &link);
854 : :
855 [ # # # # ]: 0 : if (!wait_to_complete || link.link_status)
856 : : break;
857 : :
858 : : rte_delay_ms(CHECK_INTERVAL);
859 [ # # ]: 0 : } while (rep_cnt--);
860 : :
861 [ # # ]: 0 : out:
862 : 0 : return rte_eth_linkstatus_set(dev, &link);
863 : : }
864 : :
865 : : /**
866 : : * Reset all RX queues (RXQs).
867 : : *
868 : : * @param[in] dev
869 : : * Pointer to ethernet device structure.
870 : : */
871 : : static void
872 : : hinic3_reset_rx_queue(struct rte_eth_dev *dev)
873 : : {
874 : : struct hinic3_rxq *rxq = NULL;
875 : : struct hinic3_nic_dev *nic_dev;
876 : : int q_id = 0;
877 : :
878 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
879 : :
880 [ # # ]: 0 : for (q_id = 0; q_id < nic_dev->num_rqs; q_id++) {
881 : 0 : rxq = nic_dev->rxqs[q_id];
882 : :
883 : 0 : rxq->cons_idx = 0;
884 : 0 : rxq->prod_idx = 0;
885 : 0 : rxq->delta = rxq->q_depth;
886 : 0 : rxq->next_to_update = 0;
887 : : }
888 : : }
889 : :
890 : : /**
891 : : * Reset all TX queues (TXQs).
892 : : *
893 : : * @param[in] dev
894 : : * Pointer to ethernet device structure.
895 : : */
896 : : static void
897 : : hinic3_reset_tx_queue(struct rte_eth_dev *dev)
898 : : {
899 : : struct hinic3_nic_dev *nic_dev;
900 : : struct hinic3_txq *txq = NULL;
901 : : int q_id = 0;
902 : :
903 : : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
904 : :
905 [ # # ]: 0 : for (q_id = 0; q_id < nic_dev->num_sqs; q_id++) {
906 : 0 : txq = nic_dev->txqs[q_id];
907 : :
908 : 0 : txq->cons_idx = 0;
909 : 0 : txq->prod_idx = 0;
910 : 0 : txq->owner = 1;
911 : :
912 : : /* Clear hardware ci. */
913 : 0 : *txq->ci_vaddr_base = 0;
914 : : }
915 : : }
916 : :
917 : : /**
918 : : * Create the receive queue.
919 : : *
920 : : * @param[in] dev
921 : : * Pointer to ethernet device structure.
922 : : * @param[in] qid
923 : : * Receive queue index.
924 : : * @param[in] nb_desc
925 : : * Number of descriptors for receive queue.
926 : : * @param[in] socket_id
927 : : * Socket index on which memory must be allocated.
928 : : * @param[in] rx_conf
929 : : * Thresholds parameters (unused_).
930 : : * @param[in] mp
931 : : * Memory pool for buffer allocations.
932 : : *
933 : : * @return
934 : : * 0 on success, non-zero on failure.
935 : : */
936 : : static int
937 : 0 : hinic3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qid, uint16_t nb_desc,
938 : : unsigned int socket_id, const struct rte_eth_rxconf *rx_conf,
939 : : struct rte_mempool *mp)
940 : : {
941 : : struct hinic3_nic_dev *nic_dev;
942 : : struct hinic3_rxq *rxq = NULL;
943 : : const struct rte_memzone *rq_mz = NULL;
944 : : const struct rte_memzone *cqe_mz = NULL;
945 : : const struct rte_memzone *ci_mz = NULL;
946 : : const struct rte_memzone *pi_mz = NULL;
947 : : uint16_t rq_depth, rx_free_thresh;
948 : : uint32_t queue_buf_size;
949 : 0 : void *db_addr = NULL;
950 : : int wqe_count;
951 : : uint32_t buf_size;
952 : : uint32_t rx_buf_size;
953 : : int err;
954 : :
955 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
956 : :
957 : : /* Queue depth must be equal to queue 0 */
958 [ # # # # ]: 0 : if (qid != 0 && nb_desc != nic_dev->rxqs[0]->q_depth) {
959 : 0 : PMD_DRV_LOG(WARNING, "rxq%u depth:%u is not equal to queue0 depth:%u.",
960 : : qid, nb_desc, nic_dev->rxqs[0]->q_depth);
961 : 0 : nb_desc = nic_dev->rxqs[0]->q_depth;
962 : : }
963 : :
964 : : /* Queue depth must be power of 2, otherwise will be aligned up. */
965 [ # # ]: 0 : rq_depth = (nb_desc & (nb_desc - 1))
966 : 0 : ? ((uint16_t)(1U << (rte_log2_u32(nb_desc) + 1))) : nb_desc;
967 : :
968 : : /*
969 : : * Validate number of receive descriptors.
970 : : * It must not exceed hardware maximum and minimum.
971 : : */
972 [ # # ]: 0 : if (rq_depth > HINIC3_MAX_QUEUE_DEPTH ||
973 : : rq_depth < HINIC3_MIN_QUEUE_DEPTH) {
974 : 0 : PMD_DRV_LOG(ERR,
975 : : "RX queue depth is out of range from %d to %d",
976 : : HINIC3_MIN_QUEUE_DEPTH, HINIC3_MAX_QUEUE_DEPTH);
977 : 0 : PMD_DRV_LOG(ERR,
978 : : "nb_desc: %d, q_depth: %d, port: %d queue: %d",
979 : : nb_desc, rq_depth, dev->data->port_id, qid);
980 : 0 : return -EINVAL;
981 : : }
982 : :
983 : : /*
984 : : * The RX descriptor ring will be cleaned after rxq->rx_free_thresh
985 : : * descriptors are used or if the number of descriptors required
986 : : * to transmit a packet is greater than the number of free RX
987 : : * descriptors.
988 : : * The following constraints must be satisfied:
989 : : * - rx_free_thresh must be greater than 0.
990 : : * - rx_free_thresh must be less than the size of the ring minus 1.
991 : : * When set to zero use default values.
992 : : */
993 [ # # ]: 0 : rx_free_thresh = rx_conf->rx_free_thresh
994 : : ? rx_conf->rx_free_thresh : HINIC3_DEFAULT_RX_FREE_THRESH;
995 [ # # ]: 0 : if (rx_free_thresh >= (rq_depth - 1)) {
996 : 0 : PMD_DRV_LOG(ERR,
997 : : "rx_free_thresh must be less than the number of RX descriptors minus 1, rx_free_thresh: %d port: %d queue: %d)",
998 : : rx_free_thresh, dev->data->port_id, qid);
999 : 0 : return -EINVAL;
1000 : : }
1001 : :
1002 : 0 : rxq = rte_zmalloc_socket("hinic3_rq", sizeof(struct hinic3_rxq),
1003 : : RTE_CACHE_LINE_SIZE, socket_id);
1004 [ # # ]: 0 : if (!rxq) {
1005 : 0 : PMD_DRV_LOG(ERR, "Allocate rxq[%d] failed, dev_name: %s", qid,
1006 : : dev->data->name);
1007 : :
1008 : 0 : return -ENOMEM;
1009 : : }
1010 : :
1011 : : /* Init rq parameters. */
1012 : 0 : rxq->nic_dev = nic_dev;
1013 : 0 : nic_dev->rxqs[qid] = rxq;
1014 : 0 : rxq->mb_pool = mp;
1015 : 0 : rxq->q_id = qid;
1016 : 0 : rxq->q_depth = rq_depth;
1017 : 0 : rxq->q_mask = rq_depth - 1;
1018 : 0 : rxq->delta = rq_depth;
1019 : 0 : rxq->rx_free_thresh = rx_free_thresh;
1020 : 0 : rxq->rxinfo_align_end = rxq->q_depth - rxq->rx_free_thresh;
1021 : 0 : rxq->port_id = dev->data->port_id;
1022 : 0 : rxq->wait_time_cycle = HINIC3_RX_WAIT_CYCLE_THRESH;
1023 [ # # ]: 0 : rxq->rx_deferred_start = rx_conf->rx_deferred_start;
1024 : : /* If buf_len used for function table, need to translated. */
1025 : 0 : rx_buf_size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
1026 : 0 : err = hinic3_convert_rx_buf_size(rx_buf_size, &buf_size);
1027 [ # # ]: 0 : if (err) {
1028 : 0 : PMD_DRV_LOG(ERR, "Adjust buf size failed, dev_name: %s",
1029 : : dev->data->name);
1030 : 0 : goto adjust_bufsize_fail;
1031 : : }
1032 : :
1033 : : /* If NIC support compact CQE, use compact wqe as default. */
1034 [ # # ]: 0 : if (HINIC3_SUPPORT_RX_HW_COMPACT_CQE(nic_dev)) {
1035 : 0 : rxq->wqe_type = HINIC3_COMPACT_RQ_WQE;
1036 : : } else {
1037 [ # # ]: 0 : if (buf_size >= HINIC3_RX_BUF_SIZE_4K &&
1038 : : buf_size < HINIC3_RX_BUF_SIZE_16K)
1039 : 0 : rxq->wqe_type = HINIC3_EXTEND_RQ_WQE;
1040 : : else
1041 : 0 : rxq->wqe_type = HINIC3_NORMAL_RQ_WQE;
1042 : : }
1043 : :
1044 : 0 : rxq->wqebb_shift = HINIC3_RQ_WQEBB_SHIFT + rxq->wqe_type;
1045 : 0 : rxq->wqebb_size = (uint16_t)RTE_BIT32(rxq->wqebb_shift);
1046 : :
1047 : 0 : rxq->buf_len = (uint16_t)buf_size;
1048 [ # # ]: 0 : rxq->rx_buff_shift = rte_log2_u32(rxq->buf_len);
1049 : :
1050 : 0 : pi_mz = hinic3_dma_zone_reserve(dev, "hinic3_rq_pi", qid, RTE_PGSIZE_4K,
1051 : : RTE_CACHE_LINE_SIZE, socket_id);
1052 [ # # ]: 0 : if (!pi_mz) {
1053 : 0 : PMD_DRV_LOG(ERR, "Allocate rxq[%d] pi_mz failed, dev_name: %s",
1054 : : qid, dev->data->name);
1055 : : err = -ENOMEM;
1056 : 0 : goto alloc_pi_mz_fail;
1057 : : }
1058 : 0 : rxq->pi_mz = pi_mz;
1059 : 0 : rxq->pi_dma_addr = pi_mz->iova;
1060 : 0 : rxq->pi_virt_addr = pi_mz->addr;
1061 : :
1062 : 0 : err = hinic3_alloc_db_addr(nic_dev->hwdev, &db_addr, HINIC3_DB_TYPE_RQ);
1063 [ # # ]: 0 : if (err) {
1064 : 0 : PMD_DRV_LOG(ERR, "Alloc rq doorbell addr failed");
1065 : 0 : goto alloc_db_err_fail;
1066 : : }
1067 : 0 : rxq->db_addr = db_addr;
1068 : :
1069 : 0 : queue_buf_size = RTE_BIT32(rxq->wqebb_shift) * rq_depth;
1070 : 0 : rq_mz = hinic3_dma_zone_reserve(dev, "hinic3_rq_mz", qid,
1071 : : queue_buf_size, RTE_PGSIZE_256K, socket_id);
1072 [ # # ]: 0 : if (!rq_mz) {
1073 : 0 : PMD_DRV_LOG(ERR, "Allocate rxq[%d] rq_mz failed, dev_name: %s",
1074 : : qid, dev->data->name);
1075 : : err = -ENOMEM;
1076 : 0 : goto alloc_rq_mz_fail;
1077 : : }
1078 : :
1079 : 0 : memset(rq_mz->addr, 0, queue_buf_size);
1080 : 0 : rxq->rq_mz = rq_mz;
1081 : 0 : rxq->queue_buf_paddr = rq_mz->iova;
1082 : 0 : rxq->queue_buf_vaddr = rq_mz->addr;
1083 : :
1084 : 0 : rxq->rx_info = rte_zmalloc_socket("rx_info",
1085 : : rq_depth * sizeof(*rxq->rx_info),
1086 : : RTE_CACHE_LINE_SIZE, socket_id);
1087 [ # # ]: 0 : if (!rxq->rx_info) {
1088 : 0 : PMD_DRV_LOG(ERR, "Allocate rx_info failed, dev_name: %s",
1089 : : dev->data->name);
1090 : : err = -ENOMEM;
1091 : 0 : goto alloc_rx_info_fail;
1092 : : }
1093 : :
1094 [ # # ]: 0 : if (HINIC3_SUPPORT_RX_HW_COMPACT_CQE(nic_dev)) {
1095 : 0 : ci_mz = hinic3_dma_zone_reserve(dev, "hinic3_ci_mz", qid,
1096 : : sizeof(*rxq->rq_ci),
1097 : : RTE_CACHE_LINE_SIZE, (int)socket_id);
1098 : :
1099 [ # # ]: 0 : if (!ci_mz) {
1100 : 0 : PMD_DRV_LOG(ERR, "Allocate ci mem zone failed, dev_name: %s",
1101 : : dev->data->name);
1102 : : err = -ENOMEM;
1103 : 0 : goto alloc_cqe_ci_mz_fail;
1104 : : }
1105 : :
1106 : 0 : memset(ci_mz->addr, 0, sizeof(*rxq->rq_ci));
1107 : 0 : rxq->ci_mz = ci_mz;
1108 : 0 : rxq->rq_ci = (struct hinic3_rq_ci_wb *)ci_mz->addr;
1109 : 0 : rxq->rq_ci_paddr = ci_mz->iova;
1110 : : } else {
1111 : 0 : cqe_mz = hinic3_dma_zone_reserve(dev, "hinic3_cqe_mz", qid,
1112 : : rq_depth * sizeof(*rxq->rx_cqe),
1113 : : RTE_CACHE_LINE_SIZE, socket_id);
1114 [ # # ]: 0 : if (!cqe_mz) {
1115 : 0 : PMD_DRV_LOG(ERR, "Allocate cqe mem zone failed, dev_name: %s",
1116 : : dev->data->name);
1117 : : err = -ENOMEM;
1118 : 0 : goto alloc_cqe_ci_mz_fail;
1119 : : }
1120 : 0 : memset(cqe_mz->addr, 0, rq_depth * sizeof(*rxq->rx_cqe));
1121 : 0 : rxq->cqe_mz = cqe_mz;
1122 : 0 : rxq->cqe_start_paddr = cqe_mz->iova;
1123 : 0 : rxq->cqe_start_vaddr = cqe_mz->addr;
1124 : 0 : rxq->rx_cqe = (struct hinic3_rq_cqe *)rxq->cqe_start_vaddr;
1125 : :
1126 : 0 : wqe_count = hinic3_rx_fill_wqe(rxq);
1127 [ # # ]: 0 : if (wqe_count != rq_depth) {
1128 : 0 : PMD_DRV_LOG(ERR, "Fill rx wqe failed, wqe_count: %d, dev_name: %s",
1129 : : wqe_count, dev->data->name);
1130 : : err = -ENOMEM;
1131 : 0 : hinic3_memzone_free(cqe_mz);
1132 : 0 : goto alloc_cqe_ci_mz_fail;
1133 : : }
1134 : : }
1135 : 0 : dev->data->rx_queues[qid] = rxq;
1136 : :
1137 : 0 : return 0;
1138 : :
1139 : 0 : alloc_cqe_ci_mz_fail:
1140 : 0 : rte_free(rxq->rx_info);
1141 : :
1142 : 0 : alloc_rx_info_fail:
1143 : 0 : hinic3_memzone_free(rxq->rq_mz);
1144 : :
1145 : 0 : alloc_rq_mz_fail:
1146 : 0 : alloc_db_err_fail:
1147 : 0 : hinic3_memzone_free(rxq->pi_mz);
1148 : :
1149 : 0 : alloc_pi_mz_fail:
1150 : 0 : adjust_bufsize_fail:
1151 : 0 : rte_free(rxq);
1152 : 0 : nic_dev->rxqs[qid] = NULL;
1153 : :
1154 : 0 : return err;
1155 : : }
1156 : :
1157 : : /**
1158 : : * Create the transmit queue.
1159 : : *
1160 : : * @param[in] dev
1161 : : * Pointer to ethernet device structure.
1162 : : * @param[in] queue_idx
1163 : : * Transmit queue index.
1164 : : * @param[in] nb_desc
1165 : : * Number of descriptors for transmit queue.
1166 : : * @param[in] socket_id
1167 : : * Socket index on which memory must be allocated.
1168 : : * @param[in] tx_conf
1169 : : * Tx queue configuration parameters (unused_).
1170 : : *
1171 : : * @return
1172 : : * 0 on success, non-zero on failure.
1173 : : */
1174 : : static int
1175 : 0 : hinic3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qid, uint16_t nb_desc,
1176 : : unsigned int socket_id, const struct rte_eth_txconf *tx_conf)
1177 : : {
1178 : : struct hinic3_nic_dev *nic_dev;
1179 : : struct hinic3_hwdev *hwdev;
1180 : : struct hinic3_txq *txq = NULL;
1181 : : const struct rte_memzone *sq_mz = NULL;
1182 : : const struct rte_memzone *ci_mz = NULL;
1183 : 0 : void *db_addr = NULL;
1184 : : uint16_t sq_depth, tx_free_thresh;
1185 : : uint32_t queue_buf_size;
1186 : : int err;
1187 : :
1188 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1189 : 0 : hwdev = nic_dev->hwdev;
1190 : :
1191 : : /* Queue depth must be power of 2, otherwise will be aligned up. */
1192 [ # # ]: 0 : sq_depth = (nb_desc & (nb_desc - 1))
1193 : 0 : ? ((uint16_t)(1U << (rte_log2_u32(nb_desc) + 1))) : nb_desc;
1194 : :
1195 : : /*
1196 : : * Validate number of transmit descriptors.
1197 : : * It must not exceed hardware maximum and minimum.
1198 : : */
1199 [ # # ]: 0 : if (sq_depth > HINIC3_MAX_QUEUE_DEPTH ||
1200 : : sq_depth < HINIC3_MIN_QUEUE_DEPTH) {
1201 : 0 : PMD_DRV_LOG(ERR,
1202 : : "TX queue depth is out of range from %d to %d",
1203 : : HINIC3_MIN_QUEUE_DEPTH, HINIC3_MAX_QUEUE_DEPTH);
1204 : 0 : PMD_DRV_LOG(ERR,
1205 : : "nb_desc: %d, q_depth: %d, port: %d queue: %d",
1206 : : nb_desc, sq_depth, dev->data->port_id, qid);
1207 : 0 : return -EINVAL;
1208 : : }
1209 : :
1210 : : /*
1211 : : * The TX descriptor ring will be cleaned after txq->tx_free_thresh
1212 : : * descriptors are used or if the number of descriptors required
1213 : : * to transmit a packet is greater than the number of free TX
1214 : : * descriptors.
1215 : : * The following constraints must be satisfied:
1216 : : * - tx_free_thresh must be greater than 0.
1217 : : * - tx_free_thresh must be less than the size of the ring minus 1.
1218 : : * When set to zero use default values.
1219 : : */
1220 [ # # ]: 0 : tx_free_thresh = tx_conf->tx_free_thresh
1221 : : ? tx_conf->tx_free_thresh : HINIC3_DEFAULT_TX_FREE_THRESH;
1222 [ # # ]: 0 : if (tx_free_thresh >= (sq_depth - 1)) {
1223 : 0 : PMD_DRV_LOG(ERR,
1224 : : "tx_free_thresh must be less than the number of tx descriptors minus 1, tx_free_thresh: %d port: %d queue: %d",
1225 : : tx_free_thresh, dev->data->port_id, qid);
1226 : 0 : return -EINVAL;
1227 : : }
1228 : :
1229 : 0 : txq = rte_zmalloc_socket("hinic3_tx_queue", sizeof(struct hinic3_txq),
1230 : : RTE_CACHE_LINE_SIZE, socket_id);
1231 [ # # ]: 0 : if (!txq) {
1232 : 0 : PMD_DRV_LOG(ERR, "Allocate txq[%d] failed, dev_name: %s", qid,
1233 : : dev->data->name);
1234 : 0 : return -ENOMEM;
1235 : : }
1236 : 0 : nic_dev->txqs[qid] = txq;
1237 : 0 : txq->nic_dev = nic_dev;
1238 : 0 : txq->q_id = qid;
1239 : 0 : txq->q_depth = sq_depth;
1240 : 0 : txq->q_mask = sq_depth - 1;
1241 : 0 : txq->wqebb_shift = HINIC3_SQ_WQEBB_SHIFT;
1242 : 0 : txq->wqebb_size = (uint16_t)RTE_BIT32(txq->wqebb_shift);
1243 : 0 : txq->tx_free_thresh = tx_free_thresh;
1244 : 0 : txq->owner = 1;
1245 : 0 : txq->cos = nic_dev->default_cos;
1246 : 0 : txq->tx_deferred_start = tx_conf->tx_deferred_start;
1247 : 0 : txq->tx_wqe_compact_task = HINIC3_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev);
1248 : :
1249 : 0 : ci_mz = hinic3_dma_zone_reserve(dev, "hinic3_sq_ci", qid,
1250 : : HINIC3_CI_Q_ADDR_SIZE,
1251 : : HINIC3_CI_Q_ADDR_SIZE, socket_id);
1252 [ # # ]: 0 : if (!ci_mz) {
1253 : 0 : PMD_DRV_LOG(ERR, "Allocate txq[%d] ci_mz failed, dev_name: %s",
1254 : : qid, dev->data->name);
1255 : : err = -ENOMEM;
1256 : 0 : goto alloc_ci_mz_fail;
1257 : : }
1258 : 0 : txq->ci_mz = ci_mz;
1259 : 0 : txq->ci_dma_base = ci_mz->iova;
1260 : 0 : txq->ci_vaddr_base = (volatile uint16_t *)ci_mz->addr;
1261 : :
1262 : 0 : queue_buf_size = RTE_BIT32(txq->wqebb_shift) * sq_depth;
1263 : 0 : sq_mz = hinic3_dma_zone_reserve(dev, "hinic3_sq_mz", qid,
1264 : : queue_buf_size, RTE_PGSIZE_256K, socket_id);
1265 [ # # ]: 0 : if (!sq_mz) {
1266 : 0 : PMD_DRV_LOG(ERR, "Allocate txq[%d] sq_mz failed, dev_name: %s",
1267 : : qid, dev->data->name);
1268 : : err = -ENOMEM;
1269 : 0 : goto alloc_sq_mz_fail;
1270 : : }
1271 : 0 : memset(sq_mz->addr, 0, queue_buf_size);
1272 : 0 : txq->sq_mz = sq_mz;
1273 : 0 : txq->queue_buf_paddr = sq_mz->iova;
1274 : 0 : txq->queue_buf_vaddr = sq_mz->addr;
1275 : 0 : txq->sq_head_addr = (uint64_t)txq->queue_buf_vaddr;
1276 : 0 : txq->sq_bot_sge_addr = txq->sq_head_addr + queue_buf_size;
1277 : :
1278 : 0 : err = hinic3_alloc_db_addr(hwdev, &db_addr, HINIC3_DB_TYPE_SQ);
1279 [ # # ]: 0 : if (err) {
1280 : 0 : PMD_DRV_LOG(ERR, "Alloc sq doorbell addr failed");
1281 : 0 : goto alloc_db_err_fail;
1282 : : }
1283 : 0 : txq->db_addr = db_addr;
1284 : :
1285 : 0 : txq->tx_info = rte_zmalloc_socket("tx_info",
1286 : : sq_depth * sizeof(*txq->tx_info),
1287 : : RTE_CACHE_LINE_SIZE, socket_id);
1288 [ # # ]: 0 : if (!txq->tx_info) {
1289 : 0 : PMD_DRV_LOG(ERR, "Allocate tx_info failed, dev_name: %s",
1290 : : dev->data->name);
1291 : : err = -ENOMEM;
1292 : 0 : goto alloc_tx_info_fail;
1293 : : }
1294 : :
1295 : 0 : dev->data->tx_queues[qid] = txq;
1296 : :
1297 : 0 : return 0;
1298 : :
1299 : : alloc_tx_info_fail:
1300 : 0 : alloc_db_err_fail:
1301 : 0 : hinic3_memzone_free(txq->sq_mz);
1302 : :
1303 : 0 : alloc_sq_mz_fail:
1304 : 0 : hinic3_memzone_free(txq->ci_mz);
1305 : :
1306 : 0 : alloc_ci_mz_fail:
1307 : 0 : rte_free(txq);
1308 : 0 : return err;
1309 : : }
1310 : :
1311 : : static void
1312 : 0 : hinic3_rx_queue_release(struct rte_eth_dev *dev, uint16_t queue_id)
1313 : : {
1314 : 0 : struct hinic3_rxq *rxq = dev->data->rx_queues[queue_id];
1315 : 0 : struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
1316 : :
1317 : 0 : PMD_DRV_LOG(DEBUG, "%s rxq_idx:%d queue release.",
1318 : : rxq->nic_dev->dev_name, rxq->q_id);
1319 : :
1320 : 0 : hinic3_free_rxq_mbufs(rxq);
1321 : :
1322 [ # # ]: 0 : if (HINIC3_SUPPORT_RX_HW_COMPACT_CQE(nic_dev))
1323 : 0 : hinic3_memzone_free(rxq->ci_mz);
1324 : : else
1325 : 0 : hinic3_memzone_free(rxq->cqe_mz);
1326 : :
1327 : 0 : rte_free(rxq->rx_info);
1328 : 0 : rxq->rx_info = NULL;
1329 : :
1330 : 0 : hinic3_memzone_free(rxq->rq_mz);
1331 : :
1332 : 0 : hinic3_memzone_free(rxq->pi_mz);
1333 : :
1334 : 0 : nic_dev->rxqs[rxq->q_id] = NULL;
1335 : 0 : rte_free(rxq);
1336 : 0 : }
1337 : :
1338 : : static void
1339 : 0 : hinic3_tx_queue_release(struct rte_eth_dev *dev, uint16_t queue_id)
1340 : : {
1341 : 0 : struct hinic3_txq *txq = dev->data->tx_queues[queue_id];
1342 : 0 : struct hinic3_nic_dev *nic_dev = txq->nic_dev;
1343 : :
1344 : 0 : PMD_DRV_LOG(DEBUG, "%s txq_idx:%d queue release.",
1345 : : txq->nic_dev->dev_name, txq->q_id);
1346 : :
1347 : 0 : hinic3_free_txq_mbufs(txq);
1348 : :
1349 : 0 : rte_free(txq->tx_info);
1350 : 0 : txq->tx_info = NULL;
1351 : :
1352 : 0 : hinic3_memzone_free(txq->sq_mz);
1353 : :
1354 : 0 : hinic3_memzone_free(txq->ci_mz);
1355 : :
1356 : 0 : nic_dev->txqs[txq->q_id] = NULL;
1357 : 0 : rte_free(txq);
1358 : 0 : }
1359 : :
1360 : : /**
1361 : : * Start RXQ and enables flow director (fdir) filter for RXQ.
1362 : : *
1363 : : * @param[in] dev
1364 : : * Pointer to ethernet device structure.
1365 : : * @param[in] rq_id
1366 : : * RX queue ID to be started.
1367 : : *
1368 : : * @return
1369 : : * 0 on success, non-zero on failure.
1370 : : */
1371 : : static int
1372 : 0 : hinic3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rq_id)
1373 : : {
1374 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1375 : 0 : struct hinic3_rxq *rxq = dev->data->rx_queues[rq_id];
1376 : : int rc;
1377 : :
1378 : : rxq = dev->data->rx_queues[rq_id];
1379 : :
1380 : 0 : rc = hinic3_start_rq(dev, rxq);
1381 [ # # ]: 0 : if (rc) {
1382 : 0 : PMD_DRV_LOG(ERR,
1383 : : "Start rx queue failed, eth_dev:%s, queue_idx:%d",
1384 : : dev->data->name, rq_id);
1385 : 0 : return rc;
1386 : : }
1387 : :
1388 [ # # ]: 0 : if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) == 0) {
1389 : 0 : rc = hinic3_enable_rxq_fdir_filter(dev, rq_id, true);
1390 [ # # ]: 0 : if (rc) {
1391 : 0 : PMD_DRV_LOG(ERR, "Failed to enable rq : %d fdir filter.", rq_id);
1392 : 0 : return rc;
1393 : : }
1394 : : }
1395 : :
1396 : 0 : dev->data->rx_queue_state[rq_id] = RTE_ETH_QUEUE_STATE_STARTED;
1397 : :
1398 : 0 : return 0;
1399 : : }
1400 : :
1401 : : /**
1402 : : * Stop RXQ and disable flow director (fdir) filter for RXQ.
1403 : : *
1404 : : * @param[in] dev
1405 : : * Pointer to ethernet device structure.
1406 : : * @param[in] rq_id
1407 : : * RX queue ID to be stopped.
1408 : : *
1409 : : * @return
1410 : : * 0 on success, non-zero on failure.
1411 : : */
1412 : : static int
1413 : 0 : hinic3_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rq_id)
1414 : : {
1415 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1416 : 0 : struct hinic3_rxq *rxq = dev->data->rx_queues[rq_id];
1417 : : int rc;
1418 : :
1419 : 0 : rc = hinic3_stop_rq(dev, rxq);
1420 [ # # ]: 0 : if (rc) {
1421 : 0 : PMD_DRV_LOG(ERR,
1422 : : "Stop rx queue failed, eth_dev:%s, queue_idx:%d",
1423 : : dev->data->name, rq_id);
1424 : 0 : return rc;
1425 : : }
1426 : :
1427 [ # # ]: 0 : if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) == 0) {
1428 : 0 : rc = hinic3_enable_rxq_fdir_filter(dev, rq_id, false);
1429 [ # # ]: 0 : if (rc) {
1430 : 0 : PMD_DRV_LOG(ERR, "Failed to disable rq : %d fdir filter.", rq_id);
1431 : 0 : return rc;
1432 : : }
1433 : : }
1434 : :
1435 : 0 : dev->data->rx_queue_state[rq_id] = RTE_ETH_QUEUE_STATE_STOPPED;
1436 : :
1437 : 0 : return 0;
1438 : : }
1439 : :
1440 : : static int
1441 : 0 : hinic3_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t sq_id)
1442 : : {
1443 : 0 : struct hinic3_txq *txq = dev->data->tx_queues[sq_id];
1444 : :
1445 : 0 : PMD_DRV_LOG(DEBUG, "Start tx queue, eth_dev:%s, queue_idx:%d",
1446 : : dev->data->name, sq_id);
1447 : :
1448 : 0 : HINIC3_SET_TXQ_STARTED(txq);
1449 : 0 : dev->data->tx_queue_state[sq_id] = RTE_ETH_QUEUE_STATE_STARTED;
1450 : :
1451 : 0 : return 0;
1452 : : }
1453 : :
1454 : : static int
1455 : 0 : hinic3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t sq_id)
1456 : : {
1457 : 0 : struct hinic3_txq *txq = dev->data->tx_queues[sq_id];
1458 : : int rc;
1459 : :
1460 : 0 : rc = hinic3_stop_sq(txq);
1461 [ # # ]: 0 : if (rc) {
1462 : 0 : PMD_DRV_LOG(ERR,
1463 : : "Stop tx queue failed, eth_dev:%s, queue_idx:%d",
1464 : : dev->data->name, sq_id);
1465 : 0 : return rc;
1466 : : }
1467 : :
1468 : 0 : HINIC3_SET_TXQ_STOPPED(txq);
1469 : 0 : dev->data->tx_queue_state[sq_id] = RTE_ETH_QUEUE_STATE_STOPPED;
1470 : :
1471 : 0 : return 0;
1472 : : }
1473 : :
1474 : : int
1475 : 0 : hinic3_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
1476 : : {
1477 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1478 : 0 : struct rte_intr_handle *intr_handle = PCI_DEV_TO_INTR_HANDLE(pci_dev);
1479 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1480 : : uint16_t msix_intr;
1481 : :
1482 [ # # # # ]: 0 : if (!rte_intr_dp_is_en(intr_handle) || !intr_handle->intr_vec)
1483 : : return 0;
1484 : :
1485 : 0 : msix_intr = (uint16_t)intr_handle->intr_vec[queue_id];
1486 : 0 : hinic3_set_msix_auto_mask_state(nic_dev->hwdev, msix_intr,
1487 : : HINIC3_SET_MSIX_AUTO_MASK);
1488 : 0 : hinic3_set_msix_state(nic_dev->hwdev, msix_intr, HINIC3_MSIX_ENABLE);
1489 : :
1490 : 0 : return 0;
1491 : : }
1492 : :
1493 : : int
1494 : 0 : hinic3_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
1495 : : {
1496 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1497 : 0 : struct rte_intr_handle *intr_handle = PCI_DEV_TO_INTR_HANDLE(pci_dev);
1498 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1499 : : uint16_t msix_intr;
1500 : :
1501 [ # # # # ]: 0 : if (!rte_intr_dp_is_en(intr_handle) || !intr_handle->intr_vec)
1502 : : return 0;
1503 : :
1504 : 0 : msix_intr = (uint16_t)intr_handle->intr_vec[queue_id];
1505 : 0 : hinic3_set_msix_auto_mask_state(nic_dev->hwdev, msix_intr,
1506 : : HINIC3_CLR_MSIX_AUTO_MASK);
1507 : 0 : hinic3_set_msix_state(nic_dev->hwdev, msix_intr, HINIC3_MSIX_DISABLE);
1508 : 0 : hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev, msix_intr,
1509 : : MSIX_RESEND_TIMER_CLEAR);
1510 : :
1511 : 0 : return 0;
1512 : : }
1513 : :
1514 : : static int
1515 : 0 : hinic3_set_lro(struct hinic3_nic_dev *nic_dev, struct rte_eth_conf *dev_conf)
1516 : : {
1517 : : bool lro_en;
1518 : : int max_lro_size, lro_max_pkt_len;
1519 : : int err;
1520 : :
1521 : : /* Config lro. */
1522 : 0 : lro_en = dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO ? true
1523 : 0 : : false;
1524 : 0 : max_lro_size = (int)(dev_conf->rxmode.max_lro_pkt_size);
1525 : : /* `max_lro_size` is divisible by `HINIC3_LRO_UNIT_WQE_SIZE`. */
1526 : : lro_max_pkt_len = max_lro_size / HINIC3_LRO_UNIT_WQE_SIZE
1527 [ # # ]: 0 : ? max_lro_size / HINIC3_LRO_UNIT_WQE_SIZE : 1;
1528 : :
1529 : 0 : PMD_DRV_LOG(DEBUG,
1530 : : "max_lro_size: %d, rx_buff_len: %d, lro_max_pkt_len: %d",
1531 : : max_lro_size, nic_dev->rx_buff_len, lro_max_pkt_len);
1532 : 0 : PMD_DRV_LOG(DEBUG, "max_rx_pkt_len: %d",
1533 : : HINIC3_MAX_RX_PKT_LEN(dev_conf->rxmode));
1534 : 0 : err = hinic3_set_rx_lro_state(nic_dev->hwdev, lro_en,
1535 : : HINIC3_LRO_DEFAULT_TIME_LIMIT, lro_max_pkt_len);
1536 [ # # ]: 0 : if (err)
1537 : 0 : PMD_DRV_LOG(ERR, "Set lro state failed, err: %d", err);
1538 : 0 : return err;
1539 : : }
1540 : :
1541 : : static int
1542 : 0 : hinic3_set_vlan(struct rte_eth_dev *dev, struct rte_eth_conf *dev_conf)
1543 : : {
1544 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1545 : : bool vlan_filter, vlan_strip;
1546 : : int err;
1547 : :
1548 : : /* Config vlan filter. */
1549 : 0 : vlan_filter = dev_conf->rxmode.offloads &
1550 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
1551 : :
1552 : 0 : err = hinic3_set_vlan_filter(nic_dev->hwdev, vlan_filter);
1553 [ # # ]: 0 : if (err) {
1554 : 0 : PMD_DRV_LOG(ERR,
1555 : : "Config vlan filter failed, device: %s, port_id: %d, err: %d",
1556 : : nic_dev->dev_name, dev->data->port_id, err);
1557 : 0 : return err;
1558 : : }
1559 : :
1560 : : /* Config vlan stripping. */
1561 : 0 : vlan_strip = dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1562 : :
1563 : 0 : err = hinic3_set_rx_vlan_offload(nic_dev->hwdev, vlan_strip);
1564 [ # # ]: 0 : if (err) {
1565 : 0 : PMD_DRV_LOG(ERR,
1566 : : "Config vlan strip failed, device: %s, port_id: %d, err: %d",
1567 : : nic_dev->dev_name, dev->data->port_id, err);
1568 : : }
1569 : :
1570 : : return err;
1571 : : }
1572 : :
1573 : : /**
1574 : : * Configure RX mode, checksum offload, LRO, RSS, VLAN and initialize the RXQ
1575 : : * list.
1576 : : *
1577 : : * @param[in] dev
1578 : : * Pointer to ethernet device structure.
1579 : : *
1580 : : * @return
1581 : : * 0 on success, non-zero on failure.
1582 : : */
1583 : : static int
1584 : 0 : hinic3_set_rxtx_configure(struct rte_eth_dev *dev)
1585 : : {
1586 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1587 : 0 : struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
1588 : : struct rte_eth_rss_conf *rss_conf = NULL;
1589 : : int err;
1590 : :
1591 : : /* Config rx mode. */
1592 : 0 : err = hinic3_set_rx_mode(nic_dev->hwdev, HINIC3_DEFAULT_RX_MODE);
1593 [ # # ]: 0 : if (err) {
1594 : 0 : PMD_DRV_LOG(ERR, "Set rx_mode: 0x%x failed",
1595 : : HINIC3_DEFAULT_RX_MODE);
1596 : 0 : return err;
1597 : : }
1598 : 0 : nic_dev->rx_mode = HINIC3_DEFAULT_RX_MODE;
1599 : :
1600 : : /* Config rx checksum offload. */
1601 [ # # ]: 0 : if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM)
1602 : 0 : nic_dev->rx_csum_en = HINIC3_DEFAULT_RX_CSUM_OFFLOAD;
1603 : :
1604 : 0 : err = hinic3_set_lro(nic_dev, dev_conf);
1605 [ # # ]: 0 : if (err) {
1606 : 0 : PMD_DRV_LOG(ERR, "Set lro failed");
1607 : 0 : return err;
1608 : : }
1609 : : /* Config RSS. */
1610 [ # # ]: 0 : if ((dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) &&
1611 [ # # ]: 0 : nic_dev->num_rqs > 1) {
1612 : 0 : rss_conf = &dev_conf->rx_adv_conf.rss_conf;
1613 : 0 : err = hinic3_update_rss_config(dev, rss_conf);
1614 [ # # ]: 0 : if (err) {
1615 : 0 : PMD_DRV_LOG(ERR, "Set rss config failed, err: %d", err);
1616 : 0 : return err;
1617 : : }
1618 : : }
1619 : :
1620 : 0 : err = hinic3_set_vlan(dev, dev_conf);
1621 [ # # ]: 0 : if (err) {
1622 : 0 : PMD_DRV_LOG(ERR, "Set vlan failed, err: %d", err);
1623 : 0 : return err;
1624 : : }
1625 : :
1626 : 0 : hinic3_init_rx_queue_list(nic_dev);
1627 : :
1628 : 0 : return 0;
1629 : : }
1630 : :
1631 : : /**
1632 : : * Disable RX mode and RSS, and free associated resources.
1633 : : *
1634 : : * @param[in] dev
1635 : : * Pointer to ethernet device structure.
1636 : : */
1637 : : static void
1638 : 0 : hinic3_remove_rxtx_configure(struct rte_eth_dev *dev)
1639 : : {
1640 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1641 : 0 : uint8_t prio_tc[HINIC3_DCB_UP_MAX] = {0};
1642 : :
1643 : 0 : hinic3_set_rx_mode(nic_dev->hwdev, 0);
1644 : :
1645 [ # # ]: 0 : if (nic_dev->rss_state == HINIC3_RSS_ENABLE) {
1646 : 0 : hinic3_rss_cfg(nic_dev->hwdev, HINIC3_RSS_DISABLE, 0, prio_tc);
1647 : 0 : hinic3_rss_template_free(nic_dev->hwdev);
1648 : 0 : nic_dev->rss_state = HINIC3_RSS_DISABLE;
1649 : : }
1650 : 0 : }
1651 : :
1652 : : static bool
1653 : : hinic3_find_vlan_filter(struct hinic3_nic_dev *nic_dev, uint16_t vlan_id)
1654 : : {
1655 : : uint32_t vid_idx, vid_bit;
1656 : :
1657 : 0 : vid_idx = HINIC3_VFTA_IDX(vlan_id);
1658 : 0 : vid_bit = HINIC3_VFTA_BIT(vlan_id);
1659 : :
1660 : 0 : return (nic_dev->vfta[vid_idx] & vid_bit) ? true : false;
1661 : : }
1662 : :
1663 : : static void
1664 : : hinic3_store_vlan_filter(struct hinic3_nic_dev *nic_dev, uint16_t vlan_id, bool on)
1665 : : {
1666 : : uint32_t vid_idx, vid_bit;
1667 : :
1668 : 0 : vid_idx = HINIC3_VFTA_IDX(vlan_id);
1669 : 0 : vid_bit = HINIC3_VFTA_BIT(vlan_id);
1670 : :
1671 : 0 : if (on)
1672 : 0 : nic_dev->vfta[vid_idx] |= vid_bit;
1673 : : else
1674 : 0 : nic_dev->vfta[vid_idx] &= ~vid_bit;
1675 : : }
1676 : :
1677 : : static void
1678 : 0 : hinic3_remove_all_vlanid(struct rte_eth_dev *dev)
1679 : : {
1680 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1681 : : int vlan_id;
1682 : : uint16_t func_id;
1683 : :
1684 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
1685 : :
1686 [ # # ]: 0 : for (vlan_id = 1; vlan_id < RTE_ETHER_MAX_VLAN_ID; vlan_id++) {
1687 [ # # ]: 0 : if (hinic3_find_vlan_filter(nic_dev, vlan_id)) {
1688 : 0 : hinic3_del_vlan(nic_dev->hwdev, vlan_id, func_id);
1689 : : hinic3_store_vlan_filter(nic_dev, vlan_id, false);
1690 : : }
1691 : : }
1692 : 0 : }
1693 : :
1694 : : static void
1695 : 0 : hinic3_disable_interrupt(struct rte_eth_dev *dev)
1696 : : {
1697 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1698 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1699 : :
1700 [ # # ]: 0 : if (!hinic3_get_bit(HINIC3_DEV_INIT, &nic_dev->dev_status))
1701 : : return;
1702 : :
1703 : : /* Disable rte interrupt. */
1704 : 0 : rte_intr_disable(PCI_DEV_TO_INTR_HANDLE(pci_dev));
1705 : 0 : rte_intr_callback_unregister(PCI_DEV_TO_INTR_HANDLE(pci_dev),
1706 : : hinic3_dev_interrupt_handler, (void *)dev);
1707 : : }
1708 : :
1709 : : static void
1710 : 0 : hinic3_enable_interrupt(struct rte_eth_dev *dev)
1711 : : {
1712 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1713 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1714 : :
1715 [ # # ]: 0 : if (!hinic3_get_bit(HINIC3_DEV_INIT, &nic_dev->dev_status))
1716 : : return;
1717 : :
1718 : : /* Enable rte interrupt. */
1719 : 0 : rte_intr_enable(PCI_DEV_TO_INTR_HANDLE(pci_dev));
1720 : 0 : rte_intr_callback_register(PCI_DEV_TO_INTR_HANDLE(pci_dev),
1721 : : hinic3_dev_interrupt_handler, (void *)dev);
1722 : : }
1723 : :
1724 : : #define HINIC3_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
1725 : :
1726 : : /** Dp interrupt msix attribute. */
1727 : : #define HINIC3_TXRX_MSIX_PENDING_LIMIT 2
1728 : : #define HINIC3_TXRX_MSIX_COALESCE_TIMER 2
1729 : : #define HINIC3_TXRX_MSIX_RESEND_TIMER_CFG 7
1730 : :
1731 : : static int
1732 : 0 : hinic3_init_rxq_msix_attr(void *hwdev, uint16_t msix_index)
1733 : : {
1734 : 0 : struct interrupt_info info = {0};
1735 : : int err;
1736 : :
1737 : : info.lli_set = 0;
1738 : 0 : info.interrupt_coalesce_set = 1;
1739 : 0 : info.pending_limt = HINIC3_TXRX_MSIX_PENDING_LIMIT;
1740 : 0 : info.coalesce_timer_cfg = HINIC3_TXRX_MSIX_COALESCE_TIMER;
1741 : 0 : info.resend_timer_cfg = HINIC3_TXRX_MSIX_RESEND_TIMER_CFG;
1742 : 0 : info.msix_index = msix_index;
1743 : 0 : err = hinic3_set_interrupt_cfg(hwdev, info);
1744 [ # # ]: 0 : if (err) {
1745 : 0 : PMD_DRV_LOG(ERR, "Set msix attr failed, msix_index %d",
1746 : : msix_index);
1747 : 0 : return -EFAULT;
1748 : : }
1749 : :
1750 : : return 0;
1751 : : }
1752 : :
1753 : : static void
1754 : 0 : hinic3_deinit_rxq_intr(struct rte_eth_dev *dev)
1755 : : {
1756 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
1757 : :
1758 : 0 : rte_intr_efd_disable(intr_handle);
1759 [ # # ]: 0 : if (intr_handle->intr_vec) {
1760 : 0 : rte_free(intr_handle->intr_vec);
1761 : 0 : intr_handle->intr_vec = NULL;
1762 : : }
1763 : 0 : }
1764 : :
1765 : : /**
1766 : : * Initialize RX queue interrupts by enabling MSI-X, allocate interrupt vectors,
1767 : : * and configure interrupt attributes for each RX queue.
1768 : : *
1769 : : * @param[in] dev
1770 : : * Pointer to ethernet device structure.
1771 : : *
1772 : : * @return
1773 : : * 0 on success, negative error code on failure.
1774 : : * - -ENOTSUP if MSI-X interrupts are not supported.
1775 : : * - Error code if enabling event file descriptors fails.
1776 : : * - -ENOMEM if allocating interrupt vectors fails.
1777 : : */
1778 : : static int
1779 : 0 : hinic3_init_rxq_intr(struct rte_eth_dev *dev)
1780 : : {
1781 : : struct rte_intr_handle *intr_handle = NULL;
1782 : : struct hinic3_nic_dev *nic_dev = NULL;
1783 : : struct hinic3_rxq *rxq = NULL;
1784 : : uint32_t nb_rx_queues, i;
1785 : : int err;
1786 : :
1787 : 0 : intr_handle = dev->intr_handle;
1788 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1789 [ # # ]: 0 : if (!dev->data->dev_conf.intr_conf.rxq)
1790 : : return 0;
1791 : :
1792 [ # # ]: 0 : if (!rte_intr_cap_multiple(intr_handle)) {
1793 : 0 : PMD_DRV_LOG(ERR, "Rx queue interrupts require MSI-X interrupts (vfio-pci driver)");
1794 : 0 : return -ENOTSUP;
1795 : : }
1796 : :
1797 : 0 : nb_rx_queues = dev->data->nb_rx_queues;
1798 : 0 : err = rte_intr_efd_enable(intr_handle, nb_rx_queues);
1799 [ # # ]: 0 : if (err) {
1800 : 0 : PMD_DRV_LOG(ERR,
1801 : : "Failed to enable event fds for Rx queue interrupts");
1802 : 0 : return err;
1803 : : }
1804 : :
1805 : 0 : intr_handle->intr_vec =
1806 : 0 : rte_zmalloc("hinic_intr_vec", nb_rx_queues * sizeof(int), 0);
1807 [ # # ]: 0 : if (intr_handle->intr_vec == NULL) {
1808 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate intr_vec");
1809 : 0 : rte_intr_efd_disable(intr_handle);
1810 : 0 : return -ENOMEM;
1811 : : }
1812 : 0 : intr_handle->vec_list_size = nb_rx_queues;
1813 [ # # ]: 0 : for (i = 0; i < nb_rx_queues; i++)
1814 : 0 : intr_handle->intr_vec[i] = (int)(i + HINIC3_RX_VEC_START);
1815 : :
1816 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1817 : 0 : rxq = dev->data->rx_queues[i];
1818 : 0 : rxq->dp_intr_en = 1;
1819 : 0 : rxq->msix_entry_idx = (uint16_t)intr_handle->intr_vec[i];
1820 : :
1821 : 0 : err = hinic3_init_rxq_msix_attr(nic_dev->hwdev,
1822 : : rxq->msix_entry_idx);
1823 [ # # ]: 0 : if (err) {
1824 : 0 : hinic3_deinit_rxq_intr(dev);
1825 : 0 : return err;
1826 : : }
1827 : : }
1828 : :
1829 : : return 0;
1830 : : }
1831 : :
1832 : : static void
1833 : 0 : hinic3_disable_queue_intr(struct rte_eth_dev *dev)
1834 : : {
1835 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1836 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
1837 : : int msix_intr;
1838 : : int i;
1839 : :
1840 [ # # ]: 0 : if (intr_handle->intr_vec == NULL)
1841 : : return;
1842 : :
1843 [ # # ]: 0 : for (i = 0; i < nic_dev->num_rqs; i++) {
1844 : 0 : msix_intr = intr_handle->intr_vec[i];
1845 : 0 : hinic3_set_msix_state(nic_dev->hwdev, msix_intr,
1846 : : HINIC3_MSIX_DISABLE);
1847 : 0 : hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev,
1848 : : msix_intr,
1849 : : MSIX_RESEND_TIMER_CLEAR);
1850 : : }
1851 : : }
1852 : :
1853 : : /**
1854 : : * Start the device.
1855 : : *
1856 : : * Initialize function table, TXQ and TXQ context, configure RX offload, and
1857 : : * enable vport and port to prepare receiving packets.
1858 : : *
1859 : : * @param[in] eth_dev
1860 : : * Pointer to ethernet device structure.
1861 : : *
1862 : : * @return
1863 : : * 0 on success, non-zero on failure.
1864 : : */
1865 : : static int
1866 : 0 : hinic3_dev_start(struct rte_eth_dev *eth_dev)
1867 : : {
1868 : : struct hinic3_nic_dev *nic_dev = NULL;
1869 : : uint64_t nic_features;
1870 : : struct hinic3_rxq *rxq = NULL;
1871 : : int i;
1872 : : int err;
1873 : :
1874 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
1875 : 0 : err = hinic3_copy_mempool_init(nic_dev);
1876 [ # # ]: 0 : if (err) {
1877 : 0 : PMD_DRV_LOG(ERR, "Create copy mempool failed, dev_name: %s",
1878 : : eth_dev->data->name);
1879 : 0 : goto init_mpool_fail;
1880 : : }
1881 : 0 : hinic3_update_msix_info(nic_dev->hwdev->hwif);
1882 : 0 : hinic3_disable_interrupt(eth_dev);
1883 : 0 : err = hinic3_init_rxq_intr(eth_dev);
1884 [ # # ]: 0 : if (err) {
1885 : 0 : PMD_DRV_LOG(ERR, "Init rxq intr fail, eth_dev:%s",
1886 : : eth_dev->data->name);
1887 : 0 : goto init_rxq_intr_fail;
1888 : : }
1889 : :
1890 : 0 : hinic3_get_func_rx_buf_size(nic_dev);
1891 : 0 : err = hinic3_init_function_table(nic_dev->hwdev, nic_dev->rx_buff_len);
1892 [ # # ]: 0 : if (err) {
1893 : 0 : PMD_DRV_LOG(ERR, "Init function table failed, dev_name: %s",
1894 : : eth_dev->data->name);
1895 : 0 : goto init_func_tbl_fail;
1896 : : }
1897 : :
1898 : 0 : nic_features = hinic3_get_driver_feature(nic_dev);
1899 : : /*
1900 : : * You can update the features supported by the driver according to the
1901 : : * scenario here.
1902 : : */
1903 : 0 : nic_features &= DEFAULT_DRV_FEATURE;
1904 : 0 : hinic3_update_driver_feature(nic_dev, nic_features);
1905 : :
1906 : 0 : err = hinic3_set_feature_to_hw(nic_dev->hwdev, &nic_dev->feature_cap, 1);
1907 [ # # ]: 0 : if (err) {
1908 : 0 : PMD_DRV_LOG(ERR,
1909 : : "Failed to set nic features to hardware, err %d",
1910 : : err);
1911 : 0 : goto get_feature_err;
1912 : : }
1913 : :
1914 : : /* Reset rx and tx queue. */
1915 : : hinic3_reset_rx_queue(eth_dev);
1916 : : hinic3_reset_tx_queue(eth_dev);
1917 : :
1918 : : /* Init txq and rxq context. */
1919 : 0 : err = hinic3_init_qp_ctxts(nic_dev);
1920 [ # # ]: 0 : if (err) {
1921 : 0 : PMD_DRV_LOG(ERR, "Init qp context failed, dev_name: %s",
1922 : : eth_dev->data->name);
1923 : 0 : goto init_qp_fail;
1924 : : }
1925 : :
1926 : : /* Set default mtu. */
1927 : 0 : err = hinic3_set_port_mtu(nic_dev->hwdev, nic_dev->mtu_size);
1928 [ # # ]: 0 : if (err) {
1929 : 0 : PMD_DRV_LOG(ERR, "Set mtu_size[%d] failed, dev_name: %s",
1930 : : nic_dev->mtu_size, eth_dev->data->name);
1931 : 0 : goto set_mtu_fail;
1932 : : }
1933 : 0 : eth_dev->data->mtu = nic_dev->mtu_size;
1934 : :
1935 : : /* Set rx configuration: rss/checksum/rxmode/lro. */
1936 : 0 : err = hinic3_set_rxtx_configure(eth_dev);
1937 [ # # ]: 0 : if (err) {
1938 : 0 : PMD_DRV_LOG(ERR, "Set rx config failed, dev_name: %s",
1939 : : eth_dev->data->name);
1940 : 0 : goto set_rxtx_config_fail;
1941 : : }
1942 : :
1943 : : /* Enable dev interrupt. */
1944 : 0 : hinic3_enable_interrupt(eth_dev);
1945 : 0 : err = hinic3_start_all_rqs(eth_dev);
1946 [ # # ]: 0 : if (err) {
1947 : 0 : PMD_DRV_LOG(ERR, "Set rx config failed, dev_name: %s",
1948 : : eth_dev->data->name);
1949 : 0 : goto start_rqs_fail;
1950 : : }
1951 : :
1952 : 0 : hinic3_start_all_sqs(eth_dev);
1953 : :
1954 : : /* Open virtual port and ready to start packet receiving. */
1955 : 0 : err = hinic3_set_vport_enable(nic_dev->hwdev, true);
1956 [ # # ]: 0 : if (err) {
1957 : 0 : PMD_DRV_LOG(ERR, "Enable vport failed, dev_name: %s",
1958 : : eth_dev->data->name);
1959 : 0 : goto en_vport_fail;
1960 : : }
1961 : :
1962 : : /* Open physical port and start packet receiving. */
1963 : 0 : err = hinic3_set_port_enable(nic_dev->hwdev, true);
1964 [ # # ]: 0 : if (err) {
1965 : 0 : PMD_DRV_LOG(ERR, "Enable physical port failed, dev_name: %s",
1966 : : eth_dev->data->name);
1967 : 0 : goto en_port_fail;
1968 : : }
1969 : :
1970 : : /* Update eth_dev link status. */
1971 [ # # ]: 0 : if (eth_dev->data->dev_conf.intr_conf.lsc != 0)
1972 : 0 : hinic3_link_update(eth_dev, 0);
1973 : :
1974 : 0 : hinic3_set_bit(HINIC3_DEV_START, &nic_dev->dev_status);
1975 : :
1976 : 0 : return 0;
1977 : :
1978 : : en_port_fail:
1979 : 0 : hinic3_set_vport_enable(nic_dev->hwdev, false);
1980 : :
1981 : 0 : en_vport_fail:
1982 : : /* Flush tx && rx chip resources in case of setting vport fake fail. */
1983 : 0 : hinic3_flush_qps_res(nic_dev->hwdev);
1984 : : rte_delay_ms(DEV_START_DELAY_MS);
1985 [ # # ]: 0 : for (i = 0; i < nic_dev->num_rqs; i++) {
1986 : 0 : rxq = nic_dev->rxqs[i];
1987 : 0 : hinic3_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id);
1988 : 0 : hinic3_free_rxq_mbufs(rxq);
1989 : 0 : hinic3_dev_rx_queue_intr_disable(eth_dev, rxq->q_id);
1990 : 0 : eth_dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1991 : 0 : eth_dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1992 : : }
1993 : 0 : start_rqs_fail:
1994 : 0 : hinic3_remove_rxtx_configure(eth_dev);
1995 : :
1996 : 0 : set_rxtx_config_fail:
1997 : 0 : set_mtu_fail:
1998 : 0 : hinic3_free_qp_ctxts(nic_dev->hwdev);
1999 : :
2000 : 0 : init_qp_fail:
2001 : 0 : get_feature_err:
2002 : 0 : init_func_tbl_fail:
2003 : 0 : hinic3_deinit_rxq_intr(eth_dev);
2004 : 0 : init_rxq_intr_fail:
2005 : : hinic3_copy_mempool_uninit(nic_dev);
2006 : : init_mpool_fail:
2007 : : return err;
2008 : : }
2009 : :
2010 : : /**
2011 : : * Stop the device.
2012 : : *
2013 : : * Stop phy port and vport, flush pending io request, clean context configure
2014 : : * and free io resource.
2015 : : *
2016 : : * @param[in] dev
2017 : : * Pointer to ethernet device structure.
2018 : : */
2019 : : static int
2020 : 0 : hinic3_dev_stop(struct rte_eth_dev *dev)
2021 : : {
2022 : : struct hinic3_nic_dev *nic_dev;
2023 : : struct rte_eth_link link;
2024 : : int err;
2025 : :
2026 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2027 [ # # ]: 0 : if (!hinic3_test_and_clear_bit(HINIC3_DEV_START,
2028 [ # # ]: 0 : &nic_dev->dev_status)) {
2029 : 0 : PMD_DRV_LOG(INFO, "Device %s already stopped",
2030 : : nic_dev->dev_name);
2031 : 0 : return 0;
2032 : : }
2033 : :
2034 : : /* Stop phy port and vport. */
2035 : 0 : err = hinic3_set_port_enable(nic_dev->hwdev, false);
2036 [ # # ]: 0 : if (err)
2037 : 0 : PMD_DRV_LOG(WARNING,
2038 : : "Disable phy port failed, error: %d, dev_name: %s, port_id: %d",
2039 : : err, dev->data->name, dev->data->port_id);
2040 : :
2041 : 0 : err = hinic3_set_vport_enable(nic_dev->hwdev, false);
2042 [ # # ]: 0 : if (err)
2043 : 0 : PMD_DRV_LOG(WARNING,
2044 : : "Disable vport failed, error: %d, dev_name: %s, port_id: %d",
2045 : : err, dev->data->name, dev->data->port_id);
2046 : :
2047 : : /* Clear recorded link status. */
2048 : : memset(&link, 0, sizeof(link));
2049 : 0 : rte_eth_linkstatus_set(dev, &link);
2050 : :
2051 : : /* Disable dp interrupt. */
2052 : 0 : hinic3_disable_queue_intr(dev);
2053 : 0 : hinic3_deinit_rxq_intr(dev);
2054 : :
2055 : : /* Flush pending io request. */
2056 : 0 : hinic3_flush_txqs(nic_dev);
2057 : :
2058 : : /* After set vport disable 100ms, no packets will be send to host. */
2059 : : rte_delay_ms(DEV_STOP_DELAY_MS);
2060 : :
2061 : 0 : hinic3_flush_qps_res(nic_dev->hwdev);
2062 : :
2063 : : /* Clean RSS table and rx_mode. */
2064 : 0 : hinic3_remove_rxtx_configure(dev);
2065 : :
2066 : : /* Clean root context. */
2067 : 0 : hinic3_free_qp_ctxts(nic_dev->hwdev);
2068 : :
2069 : : /* Free all tx and rx mbufs. */
2070 : 0 : hinic3_free_all_txq_mbufs(nic_dev);
2071 : 0 : hinic3_free_all_rxq_mbufs(nic_dev);
2072 : :
2073 : : /* Free mempool. */
2074 : : hinic3_copy_mempool_uninit(nic_dev);
2075 : 0 : return 0;
2076 : : }
2077 : :
2078 : : static void
2079 : 0 : hinic3_dev_release(struct rte_eth_dev *eth_dev)
2080 : : {
2081 : 0 : struct hinic3_nic_dev *nic_dev =
2082 : 0 : HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
2083 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
2084 : : int qid;
2085 : :
2086 : : /* Release io resource. */
2087 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_sqs; qid++)
2088 : 0 : hinic3_tx_queue_release(eth_dev, qid);
2089 : :
2090 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_rqs; qid++)
2091 : 0 : hinic3_rx_queue_release(eth_dev, qid);
2092 : :
2093 : : hinic3_deinit_sw_rxtxqs(nic_dev);
2094 : :
2095 : 0 : hinic3_deinit_mac_addr(eth_dev);
2096 : 0 : rte_free(nic_dev->mc_list);
2097 : :
2098 : 0 : hinic3_remove_all_vlanid(eth_dev);
2099 : :
2100 : 0 : hinic3_clear_bit(HINIC3_DEV_INTR_EN, &nic_dev->dev_status);
2101 : 0 : hinic3_set_msix_state(nic_dev->hwdev, 0, HINIC3_MSIX_DISABLE);
2102 : 0 : rte_intr_disable(PCI_DEV_TO_INTR_HANDLE(pci_dev));
2103 : 0 : rte_intr_callback_unregister(PCI_DEV_TO_INTR_HANDLE(pci_dev),
2104 : : hinic3_dev_interrupt_handler,
2105 : : (void *)eth_dev);
2106 : :
2107 : 0 : hinic3_free_nic_hwdev(nic_dev->hwdev);
2108 : 0 : hinic3_free_hwdev(nic_dev->hwdev);
2109 : :
2110 : 0 : rte_free(nic_dev->hwdev);
2111 : 0 : nic_dev->hwdev = NULL;
2112 : 0 : }
2113 : :
2114 : : /**
2115 : : * Close the device.
2116 : : *
2117 : : * @param[in] dev
2118 : : * Pointer to ethernet device structure.
2119 : : *
2120 : : * @return
2121 : : * 0 on success, non-zero on failure.
2122 : : */
2123 : : static int
2124 : 0 : hinic3_dev_close(struct rte_eth_dev *eth_dev)
2125 : : {
2126 : 0 : struct hinic3_nic_dev *nic_dev =
2127 : 0 : HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
2128 : : int ret;
2129 : :
2130 [ # # ]: 0 : if (hinic3_test_and_set_bit(HINIC3_DEV_CLOSE, &nic_dev->dev_status)) {
2131 : 0 : PMD_DRV_LOG(WARNING, "Device %s already closed",
2132 : : nic_dev->dev_name);
2133 : 0 : return 0;
2134 : : }
2135 : :
2136 : 0 : ret = hinic3_dev_stop(eth_dev);
2137 : :
2138 : 0 : hinic3_dev_release(eth_dev);
2139 : 0 : return ret;
2140 : : }
2141 : :
2142 : : #define MIN_RX_BUFFER_SIZE 256
2143 : : #define MIN_RX_BUFFER_SIZE_SMALL_MODE 1518
2144 : :
2145 : : static int
2146 : 0 : hinic3_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
2147 : : {
2148 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2149 : : int err = 0;
2150 : :
2151 : 0 : PMD_DRV_LOG(DEBUG, "Set port mtu, port_id: %d, mtu: %d, max_pkt_len: %d",
2152 : : dev->data->port_id, mtu, HINIC3_MTU_TO_PKTLEN(mtu));
2153 : :
2154 : 0 : err = hinic3_set_port_mtu(nic_dev->hwdev, mtu);
2155 [ # # ]: 0 : if (err) {
2156 : 0 : PMD_DRV_LOG(ERR, "Set port mtu failed, err: %d", err);
2157 : 0 : return err;
2158 : : }
2159 : :
2160 : : /* Update max frame size. */
2161 : 0 : HINIC3_MAX_RX_PKT_LEN(dev->data->dev_conf.rxmode) = HINIC3_MTU_TO_PKTLEN(mtu);
2162 : 0 : nic_dev->mtu_size = mtu;
2163 : 0 : return err;
2164 : : }
2165 : :
2166 : : /**
2167 : : * Add or delete vlan id.
2168 : : *
2169 : : * @param[in] dev
2170 : : * Pointer to ethernet device structure.
2171 : : * @param[in] vlan_id
2172 : : * Vlan id is used to filter vlan packets.
2173 : : * @param[in] enable
2174 : : * Disable or enable vlan filter function.
2175 : : *
2176 : : * @return
2177 : : * 0 on success, non-zero on failure.
2178 : : */
2179 : : static int
2180 : 0 : hinic3_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int enable)
2181 : : {
2182 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2183 : : int err = 0;
2184 : : uint16_t func_id;
2185 : :
2186 [ # # ]: 0 : if (vlan_id == 0)
2187 : : return 0;
2188 : :
2189 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
2190 : :
2191 [ # # ]: 0 : if (enable) {
2192 : : /* If vlanid is already set, just return. */
2193 [ # # ]: 0 : if (hinic3_find_vlan_filter(nic_dev, vlan_id)) {
2194 : 0 : PMD_DRV_LOG(WARNING, "Vlan %u has been added, device: %s",
2195 : : vlan_id, nic_dev->dev_name);
2196 : 0 : return 0;
2197 : : }
2198 : :
2199 : 0 : err = hinic3_add_vlan(nic_dev->hwdev, vlan_id, func_id);
2200 : : } else {
2201 : : /* If vlanid can't be found, just return. */
2202 [ # # ]: 0 : if (!hinic3_find_vlan_filter(nic_dev, vlan_id)) {
2203 : 0 : PMD_DRV_LOG(WARNING,
2204 : : "Vlan %u is not in the vlan filter list, device: %s",
2205 : : vlan_id, nic_dev->dev_name);
2206 : 0 : return 0;
2207 : : }
2208 : :
2209 : 0 : err = hinic3_del_vlan(nic_dev->hwdev, vlan_id, func_id);
2210 : : }
2211 : :
2212 [ # # ]: 0 : if (err) {
2213 [ # # ]: 0 : PMD_DRV_LOG(ERR,
2214 : : "%s vlan failed, func_id: %d, vlan_id: %d, err: %d",
2215 : : enable ? "Add" : "Remove", func_id, vlan_id, err);
2216 : 0 : return err;
2217 : : }
2218 : :
2219 [ # # ]: 0 : hinic3_store_vlan_filter(nic_dev, vlan_id, enable);
2220 : :
2221 [ # # ]: 0 : PMD_DRV_LOG(DEBUG, "%s vlan %u succeed, device: %s",
2222 : : enable ? "Add" : "Remove", vlan_id, nic_dev->dev_name);
2223 : :
2224 : 0 : return 0;
2225 : : }
2226 : :
2227 : : /**
2228 : : * Enable or disable vlan offload.
2229 : : *
2230 : : * @param[in] dev
2231 : : * Pointer to ethernet device structure.
2232 : : * @param[in] mask
2233 : : * Definitions used for VLAN setting, vlan filter of vlan strip.
2234 : : *
2235 : : * @return
2236 : : * 0 on success, non-zero on failure.
2237 : : */
2238 : : static int
2239 : 0 : hinic3_vlan_offload_set(struct rte_eth_dev *dev, int mask)
2240 : : {
2241 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2242 : : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
2243 : : bool on;
2244 : : int err;
2245 : :
2246 : : /* Enable or disable VLAN filter. */
2247 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
2248 : 0 : on = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) ? true : false;
2249 : 0 : err = hinic3_set_vlan_filter(nic_dev->hwdev, on);
2250 [ # # ]: 0 : if (err) {
2251 [ # # ]: 0 : PMD_DRV_LOG(ERR,
2252 : : "%s vlan filter failed, device: %s, port_id: %d",
2253 : : on ? "Enable" : "Disable", nic_dev->dev_name,
2254 : : dev->data->port_id);
2255 : 0 : return err;
2256 : : }
2257 [ # # ]: 0 : PMD_DRV_LOG(DEBUG,
2258 : : "%s vlan filter succeed, device: %s, port_id: %d",
2259 : : on ? "Enable" : "Disable", nic_dev->dev_name,
2260 : : dev->data->port_id);
2261 : : }
2262 : :
2263 : : /* Enable or disable VLAN stripping. */
2264 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
2265 : 0 : on = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) ? true : false;
2266 : 0 : err = hinic3_set_rx_vlan_offload(nic_dev->hwdev, on);
2267 [ # # ]: 0 : if (err) {
2268 [ # # ]: 0 : PMD_DRV_LOG(ERR,
2269 : : "%s vlan strip failed, device: %s, port_id: %d",
2270 : : on ? "Enable" : "Disable", nic_dev->dev_name,
2271 : : dev->data->port_id);
2272 : 0 : return err;
2273 : : }
2274 : :
2275 [ # # ]: 0 : PMD_DRV_LOG(DEBUG,
2276 : : "%s vlan strip succeed, device: %s, port_id: %d",
2277 : : on ? "Enable" : "Disable", nic_dev->dev_name,
2278 : : dev->data->port_id);
2279 : : }
2280 : : return 0;
2281 : : }
2282 : :
2283 : : /**
2284 : : * Enable allmulticast mode.
2285 : : *
2286 : : * @param[in] dev
2287 : : * Pointer to ethernet device structure.
2288 : : *
2289 : : * @return
2290 : : * 0 on success, non-zero on failure.
2291 : : */
2292 : : static int
2293 : 0 : hinic3_dev_allmulticast_enable(struct rte_eth_dev *dev)
2294 : : {
2295 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2296 : 0 : uint32_t rx_mode = nic_dev->rx_mode | HINIC3_RX_MODE_MC_ALL;
2297 : : int err;
2298 : :
2299 : 0 : err = hinic3_set_rx_mode(nic_dev->hwdev, rx_mode);
2300 [ # # ]: 0 : if (err) {
2301 : 0 : PMD_DRV_LOG(ERR, "Enable allmulticast failed, error: %d", err);
2302 : 0 : return err;
2303 : : }
2304 : :
2305 : 0 : nic_dev->rx_mode = rx_mode;
2306 : :
2307 : 0 : PMD_DRV_LOG(DEBUG,
2308 : : "Enable allmulticast succeed, nic_dev: %s, port_id: %d",
2309 : : nic_dev->dev_name, dev->data->port_id);
2310 : 0 : return 0;
2311 : : }
2312 : :
2313 : : /**
2314 : : * Disable allmulticast mode.
2315 : : *
2316 : : * @param[in] dev
2317 : : * Pointer to ethernet device structure.
2318 : : *
2319 : : * @return
2320 : : * 0 on success, non-zero on failure.
2321 : : */
2322 : : static int
2323 : 0 : hinic3_dev_allmulticast_disable(struct rte_eth_dev *dev)
2324 : : {
2325 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2326 : 0 : uint32_t rx_mode = nic_dev->rx_mode & (~HINIC3_RX_MODE_MC_ALL);
2327 : : int err;
2328 : :
2329 : 0 : err = hinic3_set_rx_mode(nic_dev->hwdev, rx_mode);
2330 [ # # ]: 0 : if (err) {
2331 : 0 : PMD_DRV_LOG(ERR, "Disable allmulticast failed, error: %d", err);
2332 : 0 : return err;
2333 : : }
2334 : :
2335 : 0 : nic_dev->rx_mode = rx_mode;
2336 : :
2337 : 0 : PMD_DRV_LOG(DEBUG,
2338 : : "Disable allmulticast succeed, nic_dev: %s, port_id: %d",
2339 : : nic_dev->dev_name, dev->data->port_id);
2340 : 0 : return 0;
2341 : : }
2342 : :
2343 : : /**
2344 : : * Enable promiscuous mode.
2345 : : *
2346 : : * @param[in] dev
2347 : : * Pointer to ethernet device structure.
2348 : : *
2349 : : * @return
2350 : : * 0 on success, non-zero on failure.
2351 : : */
2352 : : static int
2353 : 0 : hinic3_dev_promiscuous_enable(struct rte_eth_dev *dev)
2354 : : {
2355 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2356 : : uint32_t rx_mode;
2357 : : int err;
2358 : :
2359 [ # # ]: 0 : if (!(nic_dev->feature_cap & NIC_F_PROMISC)) {
2360 : 0 : PMD_DRV_LOG(ERR, "nic_dev: %s, port_id: %d, do not support vf promisc: %" PRIu64 "",
2361 : : nic_dev->dev_name, dev->data->port_id, nic_dev->feature_cap);
2362 : 0 : return -ENOTSUP;
2363 : : }
2364 : :
2365 : 0 : rx_mode = nic_dev->rx_mode | HINIC3_RX_MODE_PROMISC;
2366 : :
2367 : 0 : err = hinic3_set_rx_mode(nic_dev->hwdev, rx_mode);
2368 [ # # ]: 0 : if (err) {
2369 : 0 : PMD_DRV_LOG(ERR, "Enable promiscuous failed");
2370 : 0 : return err;
2371 : : }
2372 : :
2373 : 0 : nic_dev->rx_mode = rx_mode;
2374 : :
2375 : 0 : PMD_DRV_LOG(DEBUG,
2376 : : "Enable promiscuous, nic_dev: %s, port_id: %d, promisc: %d",
2377 : : nic_dev->dev_name, dev->data->port_id,
2378 : : dev->data->promiscuous);
2379 : 0 : return 0;
2380 : : }
2381 : :
2382 : : /**
2383 : : * Disable promiscuous mode.
2384 : : *
2385 : : * @param[in] dev
2386 : : * Pointer to ethernet device structure.
2387 : : *
2388 : : * @return
2389 : : * 0 on success, non-zero on failure.
2390 : : */
2391 : : static int
2392 : 0 : hinic3_dev_promiscuous_disable(struct rte_eth_dev *dev)
2393 : : {
2394 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2395 : : uint32_t rx_mode;
2396 : : int err;
2397 : :
2398 : 0 : rx_mode = nic_dev->rx_mode & (~HINIC3_RX_MODE_PROMISC);
2399 : :
2400 : 0 : err = hinic3_set_rx_mode(nic_dev->hwdev, rx_mode);
2401 [ # # ]: 0 : if (err) {
2402 : 0 : PMD_DRV_LOG(ERR, "Disable promiscuous failed");
2403 : 0 : return err;
2404 : : }
2405 : :
2406 : 0 : nic_dev->rx_mode = rx_mode;
2407 : :
2408 : 0 : PMD_DRV_LOG(DEBUG,
2409 : : "Disable promiscuous, nic_dev: %s, port_id: %d, promisc: %d",
2410 : : nic_dev->dev_name, dev->data->port_id, dev->data->promiscuous);
2411 : 0 : return 0;
2412 : : }
2413 : :
2414 : : /**
2415 : : * Get flow control configuration, including auto-negotiation and RX/TX pause
2416 : : * settings.
2417 : : *
2418 : : * @param[in] dev
2419 : : * Pointer to ethernet device structure.
2420 : : *
2421 : : * @param[out] fc_conf
2422 : : * The flow control configuration to be filled.
2423 : : *
2424 : : * @return
2425 : : * 0 on success, non-zero on failure.
2426 : : */
2427 : : static int
2428 : 0 : hinic3_dev_flow_ctrl_get(struct rte_eth_dev *dev,
2429 : : struct rte_eth_fc_conf *fc_conf)
2430 : : {
2431 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2432 : : struct nic_pause_config nic_pause;
2433 : : int err;
2434 : :
2435 : : memset(&nic_pause, 0, sizeof(nic_pause));
2436 : 0 : err = hinic3_get_pause_info(nic_dev->hwdev, &nic_pause);
2437 [ # # ]: 0 : if (err)
2438 : : return err;
2439 [ # # # # ]: 0 : if (nic_dev->pause_set || !nic_pause.auto_neg) {
2440 : 0 : nic_pause.rx_pause = nic_dev->nic_pause.rx_pause;
2441 : 0 : nic_pause.tx_pause = nic_dev->nic_pause.tx_pause;
2442 : : }
2443 : :
2444 : 0 : fc_conf->autoneg = nic_pause.auto_neg;
2445 : :
2446 [ # # # # ]: 0 : if (nic_pause.tx_pause && nic_pause.rx_pause)
2447 : 0 : fc_conf->mode = RTE_ETH_FC_FULL;
2448 [ # # ]: 0 : else if (nic_pause.tx_pause)
2449 : 0 : fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
2450 [ # # ]: 0 : else if (nic_pause.rx_pause)
2451 : 0 : fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
2452 : : else
2453 : 0 : fc_conf->mode = RTE_ETH_FC_NONE;
2454 : :
2455 : : return 0;
2456 : : }
2457 : :
2458 : : static int
2459 : 0 : hinic3_dev_flow_ctrl_set(struct rte_eth_dev *dev,
2460 : : struct rte_eth_fc_conf *fc_conf)
2461 : : {
2462 [ # # ]: 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2463 : : struct nic_pause_config nic_pause;
2464 : : int err;
2465 : :
2466 : : memset(&nic_pause, 0, sizeof(nic_pause));
2467 [ # # ]: 0 : if ((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL ||
2468 [ # # ]: 0 : (fc_conf->mode & RTE_ETH_FC_TX_PAUSE))
2469 : 0 : nic_pause.tx_pause = true;
2470 : :
2471 [ # # ]: 0 : if ((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL ||
2472 [ # # ]: 0 : (fc_conf->mode & RTE_ETH_FC_RX_PAUSE))
2473 : 0 : nic_pause.rx_pause = true;
2474 : :
2475 : 0 : err = hinic3_set_pause_info(nic_dev->hwdev, nic_pause);
2476 [ # # ]: 0 : if (err)
2477 : : return err;
2478 : 0 : nic_dev->pause_set = true;
2479 : 0 : nic_dev->nic_pause.rx_pause = nic_pause.rx_pause;
2480 : 0 : nic_dev->nic_pause.tx_pause = nic_pause.tx_pause;
2481 : :
2482 [ # # # # ]: 0 : PMD_DRV_LOG(INFO,
2483 : : "Just support set tx or rx pause info, tx: %s, rx: %s",
2484 : : nic_pause.tx_pause ? "on" : "off",
2485 : : nic_pause.rx_pause ? "on" : "off");
2486 : 0 : return 0;
2487 : : }
2488 : :
2489 : : /**
2490 : : * Update the RSS hash key and RSS hash type.
2491 : : *
2492 : : * @param[in] dev
2493 : : * Pointer to ethernet device structure.
2494 : : * @param[in] rss_conf
2495 : : * RSS configuration data.
2496 : : *
2497 : : * @return
2498 : : * 0 on success, non-zero on failure.
2499 : : */
2500 : : static int
2501 : 0 : hinic3_rss_hash_update(struct rte_eth_dev *dev,
2502 : : struct rte_eth_rss_conf *rss_conf)
2503 : : {
2504 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2505 : 0 : struct hinic3_rss_type rss_type = {0};
2506 : 0 : uint64_t rss_hf = rss_conf->rss_hf;
2507 : : int err = 0;
2508 : :
2509 [ # # ]: 0 : if (nic_dev->rss_state == HINIC3_RSS_DISABLE) {
2510 [ # # ]: 0 : if (rss_hf != 0)
2511 : : return -EINVAL;
2512 : :
2513 : 0 : PMD_DRV_LOG(INFO, "RSS is not enabled");
2514 : 0 : return 0;
2515 : : }
2516 : :
2517 [ # # ]: 0 : if (rss_conf->rss_key_len > HINIC3_RSS_KEY_SIZE) {
2518 : 0 : PMD_DRV_LOG(ERR, "Invalid RSS key, rss_key_len: %d",
2519 : : rss_conf->rss_key_len);
2520 : 0 : return -EINVAL;
2521 : : }
2522 : :
2523 [ # # ]: 0 : if (rss_conf->rss_key) {
2524 : 0 : err = hinic3_rss_set_hash_key(nic_dev->hwdev, rss_conf->rss_key,
2525 : : HINIC3_RSS_KEY_SIZE);
2526 [ # # ]: 0 : if (err) {
2527 : 0 : PMD_DRV_LOG(ERR, "Set RSS hash key failed");
2528 : 0 : return err;
2529 : : }
2530 : 0 : memcpy((void *)nic_dev->rss_key, (void *)rss_conf->rss_key,
2531 : 0 : (size_t)rss_conf->rss_key_len);
2532 : : }
2533 : :
2534 : 0 : rss_type.ipv4 = (rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
2535 : 0 : RTE_ETH_RSS_NONFRAG_IPV4_OTHER)) ? 1 : 0;
2536 : 0 : rss_type.tcp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0;
2537 : 0 : rss_type.ipv6 = (rss_hf & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
2538 : 0 : RTE_ETH_RSS_NONFRAG_IPV6_OTHER)) ? 1 : 0;
2539 : 0 : rss_type.tcp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0;
2540 : 0 : rss_type.udp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0;
2541 : 0 : rss_type.udp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0;
2542 : :
2543 [ # # ]: 0 : if (nic_dev->feature_cap & NIC_F_HTN_CMDQ) {
2544 : 0 : rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0;
2545 : 0 : rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0;
2546 : : } else {
2547 : : rss_type.ipv6_ext = 0;
2548 : : rss_type.tcp_ipv6_ext = 0;
2549 : : }
2550 : :
2551 : 0 : err = hinic3_set_rss_type(nic_dev->hwdev, rss_type);
2552 [ # # ]: 0 : if (err)
2553 : 0 : PMD_DRV_LOG(ERR, "Set RSS type failed");
2554 : :
2555 : : return err;
2556 : : }
2557 : :
2558 : : /**
2559 : : * Get the RSS hash configuration.
2560 : : *
2561 : : * @param[in] dev
2562 : : * Pointer to ethernet device structure.
2563 : : * @param[out] rss_conf
2564 : : * RSS configuration data.
2565 : : *
2566 : : * @return
2567 : : * 0 on success, non-zero on failure.
2568 : : */
2569 : : static int
2570 : 0 : hinic3_rss_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf)
2571 : : {
2572 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2573 : 0 : struct hinic3_rss_type rss_type = {0};
2574 : : int err;
2575 : :
2576 [ # # ]: 0 : if (!rss_conf)
2577 : : return -EINVAL;
2578 : :
2579 [ # # ]: 0 : if (nic_dev->rss_state == HINIC3_RSS_DISABLE) {
2580 : 0 : rss_conf->rss_hf = 0;
2581 : 0 : PMD_DRV_LOG(INFO, "RSS is not enabled");
2582 : 0 : return 0;
2583 : : }
2584 : :
2585 [ # # # # ]: 0 : if (rss_conf->rss_key && rss_conf->rss_key_len >= HINIC3_RSS_KEY_SIZE) {
2586 : : /*
2587 : : * Get RSS key from driver to reduce the frequency of the MPU
2588 : : * accessing the RSS memory.
2589 : : */
2590 : 0 : rss_conf->rss_key_len = sizeof(nic_dev->rss_key);
2591 : 0 : memcpy((void *)rss_conf->rss_key, (void *)nic_dev->rss_key,
2592 : : (size_t)rss_conf->rss_key_len);
2593 : : }
2594 : :
2595 : 0 : err = hinic3_get_rss_type(nic_dev->hwdev, &rss_type);
2596 [ # # ]: 0 : if (err)
2597 : : return err;
2598 : :
2599 : : rss_conf->rss_hf = 0;
2600 : : rss_conf->rss_hf |=
2601 : 0 : rss_type.ipv4 ? (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
2602 [ # # ]: 0 : RTE_ETH_RSS_NONFRAG_IPV4_OTHER) : 0;
2603 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv4 ? RTE_ETH_RSS_NONFRAG_IPV4_TCP : 0;
2604 : 0 : rss_conf->rss_hf |=
2605 : 0 : rss_type.ipv6 ? (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
2606 [ # # ]: 0 : RTE_ETH_RSS_NONFRAG_IPV6_OTHER) : 0;
2607 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_TCP : 0;
2608 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.udp_ipv4 ? RTE_ETH_RSS_NONFRAG_IPV4_UDP : 0;
2609 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.udp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_UDP : 0;
2610 [ # # ]: 0 : if (nic_dev->feature_cap & NIC_F_HTN_CMDQ) {
2611 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.ipv6_ext ? RTE_ETH_RSS_IPV6_EX : 0;
2612 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv6_ext ? RTE_ETH_RSS_IPV6_TCP_EX : 0;
2613 : : }
2614 : :
2615 : : return 0;
2616 : : }
2617 : :
2618 : : /**
2619 : : * Get the RETA indirection table.
2620 : : *
2621 : : * @param[in] dev
2622 : : * Pointer to ethernet device structure.
2623 : : * @param[out] reta_conf
2624 : : * Pointer to RETA configuration structure array.
2625 : : * @param[in] reta_size
2626 : : * Size of the RETA table.
2627 : : *
2628 : : * @return
2629 : : * 0 on success, non-zero on failure.
2630 : : */
2631 : : static int
2632 : 0 : hinic3_rss_reta_query(struct rte_eth_dev *dev,
2633 : : struct rte_eth_rss_reta_entry64 *reta_conf,
2634 : : uint16_t reta_size)
2635 : : {
2636 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2637 : 0 : uint32_t indirtbl[HINIC3_RSS_INDIR_SIZE] = {0};
2638 : : uint16_t idx, shift;
2639 : : uint16_t i;
2640 : : int err;
2641 : :
2642 [ # # ]: 0 : if (nic_dev->rss_state == HINIC3_RSS_DISABLE) {
2643 : 0 : PMD_DRV_LOG(INFO, "RSS is not enabled");
2644 : 0 : return 0;
2645 : : }
2646 : :
2647 [ # # ]: 0 : if (reta_size != HINIC3_RSS_INDIR_SIZE) {
2648 : 0 : PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
2649 : 0 : return -EINVAL;
2650 : : }
2651 : :
2652 : 0 : err = hinic3_rss_get_indir_tbl(nic_dev->hwdev, indirtbl);
2653 [ # # ]: 0 : if (err) {
2654 : 0 : PMD_DRV_LOG(ERR, "Get RSS retas table failed, error: %d", err);
2655 : 0 : return err;
2656 : : }
2657 : :
2658 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
2659 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
2660 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
2661 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
2662 : 0 : reta_conf[idx].reta[shift] = (uint16_t)indirtbl[i];
2663 : : }
2664 : :
2665 : : return 0;
2666 : : }
2667 : :
2668 : : /**
2669 : : * Update the RETA indirection table.
2670 : : *
2671 : : * @param[in] dev
2672 : : * Pointer to ethernet device structure.
2673 : : * @param[in] reta_conf
2674 : : * Pointer to RETA configuration structure array.
2675 : : * @param[in] reta_size
2676 : : * Size of the RETA table.
2677 : : *
2678 : : * @return
2679 : : * 0 on success, non-zero on failure.
2680 : : */
2681 : : static int
2682 : 0 : hinic3_rss_reta_update(struct rte_eth_dev *dev,
2683 : : struct rte_eth_rss_reta_entry64 *reta_conf,
2684 : : uint16_t reta_size)
2685 : : {
2686 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2687 : 0 : uint32_t indirtbl[HINIC3_RSS_INDIR_SIZE] = {0};
2688 : : uint16_t idx, shift;
2689 : : uint16_t i;
2690 : : int err;
2691 : :
2692 [ # # ]: 0 : if (nic_dev->rss_state == HINIC3_RSS_DISABLE)
2693 : : return 0;
2694 : :
2695 [ # # ]: 0 : if (reta_size != HINIC3_RSS_INDIR_SIZE) {
2696 : 0 : PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
2697 : 0 : return -EINVAL;
2698 : : }
2699 : :
2700 : 0 : err = hinic3_rss_get_indir_tbl(nic_dev->hwdev, indirtbl);
2701 [ # # ]: 0 : if (err)
2702 : : return err;
2703 : :
2704 : : /* Update RSS reta table. */
2705 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
2706 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
2707 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
2708 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
2709 : 0 : indirtbl[i] = reta_conf[idx].reta[shift];
2710 : : }
2711 : :
2712 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
2713 [ # # ]: 0 : if (indirtbl[i] >= nic_dev->num_rqs) {
2714 : 0 : PMD_DRV_LOG(ERR,
2715 : : "Invalid reta entry, index: %d, num_rqs: %d",
2716 : : indirtbl[i], nic_dev->num_rqs);
2717 : 0 : return -EFAULT;
2718 : : }
2719 : : }
2720 : :
2721 : 0 : err = hinic3_rss_set_indir_tbl(nic_dev->hwdev, indirtbl);
2722 [ # # ]: 0 : if (err)
2723 : 0 : PMD_DRV_LOG(ERR, "Set RSS reta table failed");
2724 : :
2725 : : return err;
2726 : : }
2727 : :
2728 : : /**
2729 : : * Get device generic statistics.
2730 : : *
2731 : : * @param[in] dev
2732 : : * Pointer to ethernet device structure.
2733 : : * @param[out] stats
2734 : : * Stats structure output buffer.
2735 : : *
2736 : : * @return
2737 : : * 0 on success, non-zero on failure.
2738 : : */
2739 : : static int
2740 : 0 : hinic3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
2741 : : struct eth_queue_stats *qstats)
2742 : : {
2743 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2744 : : struct hinic3_vport_stats vport_stats;
2745 : : uint64_t rx_discards_pmd = 0;
2746 : : int err;
2747 : :
2748 : 0 : err = hinic3_get_vport_stats(nic_dev->hwdev, &vport_stats);
2749 [ # # ]: 0 : if (err) {
2750 : 0 : PMD_DRV_LOG(ERR, "Get vport stats from fw failed, nic_dev: %s",
2751 : : nic_dev->dev_name);
2752 : 0 : return err;
2753 : : }
2754 : :
2755 : : /* Rx queue stats. */
2756 [ # # ]: 0 : for (uint32_t i = 0; i < nic_dev->num_rqs; i++) {
2757 : 0 : struct hinic3_rxq *rxq = nic_dev->rxqs[i];
2758 : : #ifdef HINIC3_XSTAT_MBUF_USE
2759 : : rxq->rxq_stats.rx_left_mbuf_bytes =
2760 : : rxq->rxq_stats.rx_alloc_mbuf_bytes -
2761 : : rxq->rxq_stats.rx_free_mbuf_bytes;
2762 : : #endif
2763 : 0 : rxq->rxq_stats.errors = rxq->rxq_stats.csum_errors +
2764 : 0 : rxq->rxq_stats.other_errors;
2765 : :
2766 [ # # ]: 0 : if (qstats && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
2767 : 0 : qstats->q_ipackets[i] = rxq->rxq_stats.packets;
2768 : 0 : qstats->q_ibytes[i] = rxq->rxq_stats.bytes;
2769 : 0 : qstats->q_errors[i] = rxq->rxq_stats.errors;
2770 : : }
2771 : 0 : stats->ierrors += rxq->rxq_stats.errors;
2772 : 0 : rx_discards_pmd += rxq->rxq_stats.dropped;
2773 : 0 : dev->data->rx_mbuf_alloc_failed += rxq->rxq_stats.rx_nombuf;
2774 : : }
2775 : :
2776 : : /* Tx queue stats. */
2777 [ # # ]: 0 : for (uint32_t i = 0; i < nic_dev->num_sqs; i++) {
2778 : 0 : struct hinic3_txq *txq = nic_dev->txqs[i];
2779 : 0 : stats->oerrors += (txq->txq_stats.tx_busy + txq->txq_stats.offload_errors);
2780 [ # # ]: 0 : if (qstats && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
2781 : 0 : qstats->q_opackets[i] = txq->txq_stats.packets;
2782 : 0 : qstats->q_obytes[i] = txq->txq_stats.bytes;
2783 : : }
2784 : : }
2785 : :
2786 : : /* Vport stats. */
2787 : 0 : stats->oerrors += vport_stats.tx_discard_vport;
2788 : :
2789 : 0 : stats->imissed = vport_stats.rx_discard_vport + rx_discards_pmd;
2790 : :
2791 : 0 : stats->ipackets = vport_stats.rx_unicast_pkts_vport +
2792 : 0 : vport_stats.rx_multicast_pkts_vport +
2793 : 0 : vport_stats.rx_broadcast_pkts_vport;
2794 : :
2795 : 0 : stats->opackets = vport_stats.tx_unicast_pkts_vport +
2796 : 0 : vport_stats.tx_multicast_pkts_vport +
2797 : 0 : vport_stats.tx_broadcast_pkts_vport;
2798 : :
2799 : 0 : stats->ibytes = vport_stats.rx_unicast_bytes_vport +
2800 : 0 : vport_stats.rx_multicast_bytes_vport +
2801 : 0 : vport_stats.rx_broadcast_bytes_vport;
2802 : :
2803 : 0 : stats->obytes = vport_stats.tx_unicast_bytes_vport +
2804 : 0 : vport_stats.tx_multicast_bytes_vport +
2805 : 0 : vport_stats.tx_broadcast_bytes_vport;
2806 : 0 : return 0;
2807 : : }
2808 : :
2809 : : /**
2810 : : * Clear device generic statistics.
2811 : : *
2812 : : * @param[in] dev
2813 : : * Pointer to ethernet device structure.
2814 : : *
2815 : : * @return
2816 : : * 0 on success, non-zero on failure.
2817 : : */
2818 : : static int
2819 : 0 : hinic3_dev_stats_reset(struct rte_eth_dev *dev)
2820 : : {
2821 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2822 : : struct hinic3_rxq *rxq = NULL;
2823 : : struct hinic3_txq *txq = NULL;
2824 : : int qid;
2825 : : int err;
2826 : :
2827 : 0 : dev->data->rx_mbuf_alloc_failed = 0;
2828 : :
2829 : 0 : err = hinic3_clear_vport_stats(nic_dev->hwdev);
2830 [ # # ]: 0 : if (err)
2831 : : return err;
2832 : :
2833 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_rqs; qid++) {
2834 : 0 : rxq = nic_dev->rxqs[qid];
2835 : 0 : memset(&rxq->rxq_stats, 0, sizeof(struct hinic3_rxq_stats));
2836 : : }
2837 : :
2838 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_sqs; qid++) {
2839 : 0 : txq = nic_dev->txqs[qid];
2840 : 0 : memset(&txq->txq_stats, 0, sizeof(struct hinic3_txq_stats));
2841 : : }
2842 : :
2843 : : return 0;
2844 : : }
2845 : :
2846 : : /**
2847 : : * Get device extended statistics.
2848 : : *
2849 : : * @param[in] dev
2850 : : * Pointer to ethernet device structure.
2851 : : * @param[out] xstats
2852 : : * Pointer to rte extended stats table.
2853 : : * @param[in] n
2854 : : * The size of the stats table.
2855 : : *
2856 : : * @return
2857 : : * positive: Number of extended stats on success and stats is filled.
2858 : : * negative: Failure.
2859 : : */
2860 : : static int
2861 : 0 : hinic3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
2862 : : unsigned int n)
2863 : : {
2864 : : struct hinic3_nic_dev *nic_dev;
2865 : : struct mag_phy_port_stats port_stats;
2866 : : struct hinic3_vport_stats vport_stats;
2867 : : struct hinic3_rxq *rxq = NULL;
2868 : : struct hinic3_rxq_stats rxq_stats;
2869 : : struct hinic3_txq *txq = NULL;
2870 : : struct hinic3_txq_stats txq_stats;
2871 : : uint16_t qid;
2872 : : uint32_t i, count;
2873 : : int err;
2874 : :
2875 [ # # ]: 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2876 : : count = hinic3_xstats_calc_num(nic_dev);
2877 [ # # ]: 0 : if (n < count)
2878 : 0 : return count;
2879 : :
2880 : : count = 0;
2881 : :
2882 : : /* Get stats from rxq stats structure. */
2883 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_rqs; qid++) {
2884 : 0 : rxq = nic_dev->rxqs[qid];
2885 : :
2886 : : #ifdef HINIC3_XSTAT_RXBUF_INFO
2887 : : hinic3_get_stats(rxq);
2888 : : #endif
2889 : :
2890 : : #ifdef HINIC3_XSTAT_MBUF_USE
2891 : : rxq->rxq_stats.rx_left_mbuf_bytes =
2892 : : rxq->rxq_stats.rx_alloc_mbuf_bytes -
2893 : : rxq->rxq_stats.rx_free_mbuf_bytes;
2894 : : #endif
2895 : 0 : rxq->rxq_stats.errors = rxq->rxq_stats.csum_errors +
2896 : 0 : rxq->rxq_stats.other_errors;
2897 : :
2898 : 0 : rxq_stats = rxq->rxq_stats;
2899 : :
2900 [ # # ]: 0 : for (i = 0; i < HINIC3_RXQ_XSTATS_NUM; i++) {
2901 : 0 : xstats[count].value = *(uint64_t *)(((char *)&rxq_stats) +
2902 : 0 : hinic3_rxq_stats_strings[i].offset);
2903 : 0 : xstats[count].id = count;
2904 : 0 : count++;
2905 : : }
2906 : : }
2907 : :
2908 : : /* Get stats from txq stats structure. */
2909 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_sqs; qid++) {
2910 : 0 : txq = nic_dev->txqs[qid];
2911 : 0 : txq_stats = txq->txq_stats;
2912 : :
2913 [ # # ]: 0 : for (i = 0; i < HINIC3_TXQ_XSTATS_NUM; i++) {
2914 : 0 : xstats[count].value = *(uint64_t *)(((char *)&txq_stats) +
2915 : 0 : hinic3_txq_stats_strings[i].offset);
2916 : 0 : xstats[count].id = count;
2917 : 0 : count++;
2918 : : }
2919 : : }
2920 : :
2921 : : /* Get stats from vport stats structure. */
2922 : 0 : err = hinic3_get_vport_stats(nic_dev->hwdev, &vport_stats);
2923 [ # # ]: 0 : if (err)
2924 : : return err;
2925 : :
2926 [ # # ]: 0 : for (i = 0; i < HINIC3_VPORT_XSTATS_NUM; i++) {
2927 : 0 : xstats[count].value =
2928 : 0 : *(uint64_t *)(((char *)&vport_stats) +
2929 : 0 : hinic3_vport_stats_strings[i].offset);
2930 : 0 : xstats[count].id = count;
2931 : 0 : count++;
2932 : : }
2933 : :
2934 [ # # ]: 0 : if (HINIC3_IS_VF(nic_dev->hwdev))
2935 : 0 : return count;
2936 : :
2937 : : /* Get stats from phy port stats structure. */
2938 : 0 : err = hinic3_get_phy_port_stats(nic_dev->hwdev, &port_stats);
2939 [ # # ]: 0 : if (err)
2940 : : return err;
2941 : :
2942 [ # # ]: 0 : for (i = 0; i < HINIC3_PHYPORT_XSTATS_NUM; i++) {
2943 : 0 : xstats[count].value =
2944 : 0 : *(uint64_t *)(((char *)&port_stats) +
2945 : 0 : hinic3_phyport_stats_strings[i].offset);
2946 : 0 : xstats[count].id = count;
2947 : 0 : count++;
2948 : : }
2949 : :
2950 : 0 : return count;
2951 : : }
2952 : :
2953 : : /**
2954 : : * Clear device extended statistics.
2955 : : *
2956 : : * @param[in] dev
2957 : : * Pointer to ethernet device structure.
2958 : : *
2959 : : * @return
2960 : : * 0 on success, non-zero on failure.
2961 : : */
2962 : : static int
2963 : 0 : hinic3_dev_xstats_reset(struct rte_eth_dev *dev)
2964 : : {
2965 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2966 : : int err;
2967 : :
2968 : 0 : err = hinic3_dev_stats_reset(dev);
2969 [ # # ]: 0 : if (err)
2970 : : return err;
2971 : :
2972 [ # # ]: 0 : if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF) {
2973 : 0 : err = hinic3_clear_phy_port_stats(nic_dev->hwdev);
2974 [ # # ]: 0 : if (err)
2975 : 0 : return err;
2976 : : }
2977 : :
2978 : : return 0;
2979 : : }
2980 : :
2981 : : /**
2982 : : * Retrieve names of extended device statistics.
2983 : : *
2984 : : * @param[in] dev
2985 : : * Pointer to ethernet device structure.
2986 : : * @param[out] xstats_names
2987 : : * Buffer to insert names into.
2988 : : *
2989 : : * @return
2990 : : * Number of xstats names.
2991 : : */
2992 : : static int
2993 : 0 : hinic3_dev_xstats_get_names(struct rte_eth_dev *dev,
2994 : : struct rte_eth_xstat_name *xstats_names,
2995 : : __rte_unused unsigned int limit)
2996 : : {
2997 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2998 : : int count = 0;
2999 : : uint16_t i, q_num;
3000 : :
3001 [ # # ]: 0 : if (xstats_names == NULL)
3002 : 0 : return hinic3_xstats_calc_num(nic_dev);
3003 : :
3004 : : /* Get pmd rxq stats name. */
3005 [ # # ]: 0 : for (q_num = 0; q_num < nic_dev->num_rqs; q_num++) {
3006 [ # # ]: 0 : for (i = 0; i < HINIC3_RXQ_XSTATS_NUM; i++) {
3007 : 0 : snprintf(xstats_names[count].name,
3008 : : sizeof(xstats_names[count].name),
3009 : : "rxq%d_%s_pmd", q_num,
3010 : 0 : hinic3_rxq_stats_strings[i].name);
3011 : 0 : count++;
3012 : : }
3013 : : }
3014 : :
3015 : : /* Get pmd txq stats name. */
3016 [ # # ]: 0 : for (q_num = 0; q_num < nic_dev->num_sqs; q_num++) {
3017 [ # # ]: 0 : for (i = 0; i < HINIC3_TXQ_XSTATS_NUM; i++) {
3018 : 0 : snprintf(xstats_names[count].name,
3019 : : sizeof(xstats_names[count].name),
3020 : : "txq%d_%s_pmd", q_num,
3021 : 0 : hinic3_txq_stats_strings[i].name);
3022 : 0 : count++;
3023 : : }
3024 : : }
3025 : :
3026 : : /* Get vport stats name. */
3027 [ # # ]: 0 : for (i = 0; i < HINIC3_VPORT_XSTATS_NUM; i++) {
3028 : 0 : strlcpy(xstats_names[count].name,
3029 : : hinic3_vport_stats_strings[i].name,
3030 : : sizeof(xstats_names[count].name));
3031 : 0 : count++;
3032 : : }
3033 : :
3034 [ # # ]: 0 : if (HINIC3_IS_VF(nic_dev->hwdev))
3035 : : return count;
3036 : :
3037 : : /* Get phy port stats name. */
3038 [ # # ]: 0 : for (i = 0; i < HINIC3_PHYPORT_XSTATS_NUM; i++) {
3039 : 0 : strlcpy(xstats_names[count].name,
3040 : : hinic3_phyport_stats_strings[i].name,
3041 : : sizeof(xstats_names[count].name));
3042 : 0 : count++;
3043 : : }
3044 : :
3045 : : return count;
3046 : : }
3047 : :
3048 : : static void
3049 : 0 : hinic3_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
3050 : : struct rte_eth_rxq_info *qinfo)
3051 : : {
3052 : 0 : struct hinic3_rxq *rxq = dev->data->rx_queues[queue_id];
3053 : :
3054 : 0 : qinfo->mp = rxq->mb_pool;
3055 : 0 : qinfo->nb_desc = rxq->q_depth;
3056 : 0 : qinfo->rx_buf_size = rxq->buf_len;
3057 : 0 : qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
3058 : 0 : qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
3059 : 0 : qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
3060 : 0 : }
3061 : :
3062 : : static void
3063 : 0 : hinic3_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
3064 : : struct rte_eth_txq_info *qinfo)
3065 : : {
3066 : 0 : struct hinic3_txq *txq = dev->data->tx_queues[queue_id];
3067 : :
3068 : 0 : qinfo->nb_desc = txq->q_depth;
3069 : 0 : qinfo->conf.offloads = dev->data->dev_conf.txmode.offloads;
3070 : 0 : qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
3071 : 0 : qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
3072 : 0 : }
3073 : :
3074 : : /**
3075 : : * Update MAC address.
3076 : : *
3077 : : * @param[in] dev
3078 : : * Pointer to ethernet device structure.
3079 : : * @param[in] addr
3080 : : * Pointer to MAC address.
3081 : : *
3082 : : * @return
3083 : : * 0 on success, non-zero on failure.
3084 : : */
3085 : : static int
3086 : 0 : hinic3_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
3087 : : {
3088 [ # # ]: 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
3089 : : char mac_addr[RTE_ETHER_ADDR_FMT_SIZE];
3090 : : uint16_t func_id;
3091 : : int err;
3092 : :
3093 : : if (!rte_is_valid_assigned_ether_addr(addr)) {
3094 : 0 : rte_ether_format_addr(mac_addr, RTE_ETHER_ADDR_FMT_SIZE, addr);
3095 : 0 : PMD_DRV_LOG(ERR, "Set invalid MAC address %s", mac_addr);
3096 : 0 : return -EINVAL;
3097 : : }
3098 : :
3099 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
3100 : 0 : err = hinic3_update_mac(nic_dev->hwdev,
3101 : 0 : nic_dev->default_addr.addr_bytes,
3102 : 0 : addr->addr_bytes, 0, func_id);
3103 [ # # ]: 0 : if (err)
3104 : : return err;
3105 : :
3106 : : rte_ether_addr_copy(addr, &nic_dev->default_addr);
3107 : 0 : rte_ether_format_addr(mac_addr, RTE_ETHER_ADDR_FMT_SIZE,
3108 : 0 : &nic_dev->default_addr);
3109 : :
3110 : 0 : PMD_DRV_LOG(DEBUG, "Set new MAC address %s", mac_addr);
3111 : 0 : return 0;
3112 : : }
3113 : :
3114 : : /**
3115 : : * Remove a MAC address.
3116 : : *
3117 : : * @param[in] dev
3118 : : * Pointer to ethernet device structure.
3119 : : * @param[in] index
3120 : : * MAC address index.
3121 : : */
3122 : : static void
3123 : 0 : hinic3_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
3124 : : {
3125 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
3126 : : uint16_t func_id;
3127 : : int err;
3128 : :
3129 [ # # ]: 0 : if (index >= HINIC3_MAX_UC_MAC_ADDRS) {
3130 : 0 : PMD_DRV_LOG(ERR, "Remove MAC index(%u) is out of range", index);
3131 : 0 : return;
3132 : : }
3133 : :
3134 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
3135 : 0 : err = hinic3_del_mac(nic_dev->hwdev,
3136 : 0 : dev->data->mac_addrs[index].addr_bytes, 0, func_id);
3137 [ # # ]: 0 : if (err)
3138 : 0 : PMD_DRV_LOG(ERR, "Remove MAC index(%u) failed", index);
3139 : : }
3140 : :
3141 : : /**
3142 : : * Add a MAC address.
3143 : : *
3144 : : * @param[in] dev
3145 : : * Pointer to ethernet device structure.
3146 : : * @param[in] mac_addr
3147 : : * MAC address to register.
3148 : : * @param[in] index
3149 : : * MAC address index.
3150 : : * @param[in] vmdq
3151 : : * VMDq pool index to associate address with (unused_).
3152 : : *
3153 : : * @return
3154 : : * 0 on success, non-zero on failure.
3155 : : */
3156 : : static int
3157 : 0 : hinic3_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
3158 : : uint32_t index, __rte_unused uint32_t vmdq)
3159 : : {
3160 [ # # ]: 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
3161 : : unsigned int i;
3162 : : uint16_t func_id;
3163 : : int err;
3164 : :
3165 : : if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
3166 : 0 : PMD_DRV_LOG(ERR, "Add invalid MAC address");
3167 : 0 : return -EINVAL;
3168 : : }
3169 : :
3170 [ # # ]: 0 : if (index >= HINIC3_MAX_UC_MAC_ADDRS) {
3171 : 0 : PMD_DRV_LOG(ERR, "Add MAC index(%u) is out of range", index);
3172 : 0 : return -EINVAL;
3173 : : }
3174 : :
3175 : : /* Make sure this address doesn't already be configured. */
3176 [ # # ]: 0 : for (i = 0; i < HINIC3_MAX_UC_MAC_ADDRS; i++) {
3177 [ # # ]: 0 : if (rte_is_same_ether_addr(mac_addr,
3178 [ # # ]: 0 : &dev->data->mac_addrs[i])) {
3179 : 0 : PMD_DRV_LOG(ERR, "MAC address is already configured");
3180 : 0 : return -EADDRINUSE;
3181 : : }
3182 : : }
3183 : :
3184 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
3185 : 0 : err = hinic3_set_mac(nic_dev->hwdev, mac_addr->addr_bytes, 0, func_id);
3186 [ # # ]: 0 : if (err)
3187 : 0 : return err;
3188 : :
3189 : : return 0;
3190 : : }
3191 : :
3192 : : /**
3193 : : * Set multicast MAC address.
3194 : : *
3195 : : * @param[in] dev
3196 : : * Pointer to ethernet device structure.
3197 : : * @param[in] mc_addr_set
3198 : : * Pointer to multicast MAC address.
3199 : : * @param[in] nb_mc_addr
3200 : : * The number of multicast MAC address to set.
3201 : : *
3202 : : * @return
3203 : : * 0 on success, non-zero on failure.
3204 : : */
3205 : : static int
3206 : 0 : hinic3_set_mc_addr_list(struct rte_eth_dev *dev,
3207 : : struct rte_ether_addr *mc_addr_set, uint32_t nb_mc_addr)
3208 : : {
3209 : 0 : struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
3210 : : char mac_addr[RTE_ETHER_ADDR_FMT_SIZE];
3211 : : uint16_t func_id;
3212 : : int err;
3213 : : uint32_t i;
3214 : :
3215 : 0 : func_id = hinic3_global_func_id(nic_dev->hwdev);
3216 : :
3217 : : /* Delete old multi_cast addrs firstly. */
3218 : 0 : hinic3_delete_mc_addr_list(nic_dev);
3219 : :
3220 [ # # ]: 0 : if (nb_mc_addr > HINIC3_MAX_MC_MAC_ADDRS)
3221 : : return -EINVAL;
3222 : :
3223 [ # # ]: 0 : for (i = 0; i < nb_mc_addr; i++) {
3224 [ # # ]: 0 : if (!rte_is_multicast_ether_addr(&mc_addr_set[i])) {
3225 : 0 : rte_ether_format_addr(mac_addr, RTE_ETHER_ADDR_FMT_SIZE, &mc_addr_set[i]);
3226 : 0 : PMD_DRV_LOG(ERR, "Set mc MAC addr failed, addr(%s) invalid", mac_addr);
3227 : 0 : return -EINVAL;
3228 : : }
3229 : : }
3230 : :
3231 [ # # ]: 0 : for (i = 0; i < nb_mc_addr; i++) {
3232 : 0 : err = hinic3_set_mac(nic_dev->hwdev, mc_addr_set[i].addr_bytes, 0, func_id);
3233 [ # # ]: 0 : if (err) {
3234 : 0 : hinic3_delete_mc_addr_list(nic_dev);
3235 : 0 : return err;
3236 : : }
3237 : :
3238 : 0 : rte_ether_addr_copy(&mc_addr_set[i], &nic_dev->mc_list[i]);
3239 : : }
3240 : :
3241 : : return 0;
3242 : : }
3243 : :
3244 : : /**
3245 : : * Manage flow director filter operations.
3246 : : *
3247 : : * @param[in] dev
3248 : : * Pointer to ethernet device structure.
3249 : : * @param[in] filter_type
3250 : : * Filter type.
3251 : : * @param[in] filter_op
3252 : : * Operation to perform.
3253 : : * @param[in] arg
3254 : : * Pointer to operation-specific structure.
3255 : : *
3256 : : * @return
3257 : : * 0 on success, non-zero on failure.
3258 : : */
3259 : : static int
3260 : 0 : hinic3_dev_filter_ctrl(struct rte_eth_dev *dev, const struct rte_flow_ops **arg)
3261 : : {
3262 : : RTE_SET_USED(dev);
3263 : 0 : *arg = &hinic3_flow_ops;
3264 : 0 : return 0;
3265 : : }
3266 : :
3267 : : static const struct eth_dev_ops hinic3_pmd_ops = {
3268 : : .dev_configure = hinic3_dev_configure,
3269 : : .dev_infos_get = hinic3_dev_infos_get,
3270 : : .fw_version_get = hinic3_fw_version_get,
3271 : : .dev_set_link_up = hinic3_dev_set_link_up,
3272 : : .dev_set_link_down = hinic3_dev_set_link_down,
3273 : : .link_update = hinic3_link_update,
3274 : : .rx_queue_setup = hinic3_rx_queue_setup,
3275 : : .tx_queue_setup = hinic3_tx_queue_setup,
3276 : : .rx_queue_release = hinic3_rx_queue_release,
3277 : : .tx_queue_release = hinic3_tx_queue_release,
3278 : : .rx_queue_start = hinic3_dev_rx_queue_start,
3279 : : .rx_queue_stop = hinic3_dev_rx_queue_stop,
3280 : : .tx_queue_start = hinic3_dev_tx_queue_start,
3281 : : .tx_queue_stop = hinic3_dev_tx_queue_stop,
3282 : : .rx_queue_intr_enable = hinic3_dev_rx_queue_intr_enable,
3283 : : .rx_queue_intr_disable = hinic3_dev_rx_queue_intr_disable,
3284 : : .dev_start = hinic3_dev_start,
3285 : : .dev_stop = hinic3_dev_stop,
3286 : : .dev_close = hinic3_dev_close,
3287 : : .mtu_set = hinic3_dev_set_mtu,
3288 : : .vlan_filter_set = hinic3_vlan_filter_set,
3289 : : .vlan_offload_set = hinic3_vlan_offload_set,
3290 : : .allmulticast_enable = hinic3_dev_allmulticast_enable,
3291 : : .allmulticast_disable = hinic3_dev_allmulticast_disable,
3292 : : .promiscuous_enable = hinic3_dev_promiscuous_enable,
3293 : : .promiscuous_disable = hinic3_dev_promiscuous_disable,
3294 : : .flow_ctrl_get = hinic3_dev_flow_ctrl_get,
3295 : : .flow_ctrl_set = hinic3_dev_flow_ctrl_set,
3296 : : .rss_hash_update = hinic3_rss_hash_update,
3297 : : .rss_hash_conf_get = hinic3_rss_conf_get,
3298 : : .reta_update = hinic3_rss_reta_update,
3299 : : .reta_query = hinic3_rss_reta_query,
3300 : :
3301 : : .stats_get = hinic3_dev_stats_get,
3302 : : .stats_reset = hinic3_dev_stats_reset,
3303 : : .xstats_get = hinic3_dev_xstats_get,
3304 : : .xstats_reset = hinic3_dev_xstats_reset,
3305 : : .xstats_get_names = hinic3_dev_xstats_get_names,
3306 : : .rxq_info_get = hinic3_rxq_info_get,
3307 : : .txq_info_get = hinic3_txq_info_get,
3308 : : .mac_addr_set = hinic3_set_mac_addr,
3309 : : .mac_addr_remove = hinic3_mac_addr_remove,
3310 : : .mac_addr_add = hinic3_mac_addr_add,
3311 : : .set_mc_addr_list = hinic3_set_mc_addr_list,
3312 : : .flow_ops_get = hinic3_dev_filter_ctrl,
3313 : : };
3314 : :
3315 : : static const struct eth_dev_ops hinic3_pmd_vf_ops = {
3316 : : .dev_configure = hinic3_dev_configure,
3317 : : .dev_infos_get = hinic3_dev_infos_get,
3318 : : .fw_version_get = hinic3_fw_version_get,
3319 : : .rx_queue_setup = hinic3_rx_queue_setup,
3320 : : .tx_queue_setup = hinic3_tx_queue_setup,
3321 : : .rx_queue_intr_enable = hinic3_dev_rx_queue_intr_enable,
3322 : : .rx_queue_intr_disable = hinic3_dev_rx_queue_intr_disable,
3323 : :
3324 : : .rx_queue_start = hinic3_dev_rx_queue_start,
3325 : : .rx_queue_stop = hinic3_dev_rx_queue_stop,
3326 : : .tx_queue_start = hinic3_dev_tx_queue_start,
3327 : : .tx_queue_stop = hinic3_dev_tx_queue_stop,
3328 : :
3329 : : .dev_start = hinic3_dev_start,
3330 : : .link_update = hinic3_link_update,
3331 : : .rx_queue_release = hinic3_rx_queue_release,
3332 : : .tx_queue_release = hinic3_tx_queue_release,
3333 : : .dev_stop = hinic3_dev_stop,
3334 : : .dev_close = hinic3_dev_close,
3335 : : .mtu_set = hinic3_dev_set_mtu,
3336 : : .vlan_filter_set = hinic3_vlan_filter_set,
3337 : : .vlan_offload_set = hinic3_vlan_offload_set,
3338 : : .allmulticast_enable = hinic3_dev_allmulticast_enable,
3339 : : .allmulticast_disable = hinic3_dev_allmulticast_disable,
3340 : : .rss_hash_update = hinic3_rss_hash_update,
3341 : : .rss_hash_conf_get = hinic3_rss_conf_get,
3342 : : .reta_update = hinic3_rss_reta_update,
3343 : : .reta_query = hinic3_rss_reta_query,
3344 : :
3345 : : .stats_get = hinic3_dev_stats_get,
3346 : : .stats_reset = hinic3_dev_stats_reset,
3347 : : .xstats_get = hinic3_dev_xstats_get,
3348 : : .xstats_reset = hinic3_dev_xstats_reset,
3349 : : .xstats_get_names = hinic3_dev_xstats_get_names,
3350 : : .rxq_info_get = hinic3_rxq_info_get,
3351 : : .txq_info_get = hinic3_txq_info_get,
3352 : : .mac_addr_set = hinic3_set_mac_addr,
3353 : : .mac_addr_remove = hinic3_mac_addr_remove,
3354 : : .mac_addr_add = hinic3_mac_addr_add,
3355 : : .set_mc_addr_list = hinic3_set_mc_addr_list,
3356 : : .flow_ops_get = hinic3_dev_filter_ctrl,
3357 : : };
3358 : :
3359 : 0 : static void hinic3_nic_tx_rx_ops_init(struct hinic3_nic_dev *nic_dev)
3360 : : {
3361 [ # # ]: 0 : if (HINIC3_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev))
3362 : 0 : nic_dev->tx_ops->nic_tx_set_wqe_offload = hinic3_tx_set_compact_task_offload;
3363 : : else
3364 : 0 : nic_dev->tx_ops->nic_tx_set_wqe_offload = hinic3_tx_set_normal_task_offload;
3365 : :
3366 [ # # ]: 0 : if (HINIC3_SUPPORT_RX_HW_COMPACT_CQE(nic_dev)) {
3367 : 0 : nic_dev->rx_ops->nic_rx_get_cqe_info = hinic3_rx_get_compact_cqe_info;
3368 : 0 : nic_dev->rx_ops->nic_rx_cqe_done = hinic3_rx_integrated_cqe_done;
3369 : 0 : nic_dev->rx_ops->nic_rx_poll_rq_empty = hinic3_poll_integrated_cqe_rq_empty;
3370 : : } else {
3371 : 0 : nic_dev->rx_ops->nic_rx_get_cqe_info = hinic3_rx_get_cqe_info;
3372 : 0 : nic_dev->rx_ops->nic_rx_cqe_done = hinic3_rx_separate_cqe_done;
3373 : 0 : nic_dev->rx_ops->nic_rx_poll_rq_empty = hinic3_poll_rq_empty;
3374 : : }
3375 : 0 : }
3376 : :
3377 : : /**
3378 : : * Initialize the network function, including hardware configuration, memory
3379 : : * allocation for data structures, MAC address setup, and interrupt enabling.
3380 : : * It also registers interrupt callbacks and sets default hardware features.
3381 : : * If any step fails, appropriate cleanup is performed.
3382 : : *
3383 : : * @param[out] eth_dev
3384 : : * Pointer to ethernet device structure.
3385 : : *
3386 : : * @return
3387 : : * 0 on success, non-zero on failure.
3388 : : */
3389 : : static int
3390 : 0 : hinic3_func_init(struct rte_eth_dev *eth_dev)
3391 : : {
3392 : : struct hinic3_tcam_info *tcam_info = NULL;
3393 : : struct hinic3_nic_dev *nic_dev = NULL;
3394 : : struct rte_pci_device *pci_dev = NULL;
3395 : : int err;
3396 : :
3397 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
3398 : :
3399 : : /* EAL is secondary and eth_dev is already created. */
3400 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
3401 : 0 : PMD_DRV_LOG(INFO, "Initialize %s in secondary process",
3402 : : eth_dev->data->name);
3403 : :
3404 : 0 : return 0;
3405 : : }
3406 : :
3407 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
3408 : : memset(nic_dev, 0, sizeof(*nic_dev));
3409 : 0 : snprintf(nic_dev->dev_name, sizeof(nic_dev->dev_name),
3410 : : "dbdf-%.4x:%.2x:%.2x.%x", pci_dev->addr.domain,
3411 : 0 : pci_dev->addr.bus, pci_dev->addr.devid,
3412 : 0 : pci_dev->addr.function);
3413 : :
3414 : : /* Alloc mac_addrs. */
3415 : 0 : eth_dev->data->mac_addrs = rte_zmalloc("hinic3_mac",
3416 : : HINIC3_MAX_UC_MAC_ADDRS * sizeof(struct rte_ether_addr), 0);
3417 [ # # ]: 0 : if (!eth_dev->data->mac_addrs) {
3418 : 0 : PMD_DRV_LOG(ERR, "Allocate MAC addresses failed, dev_name: %s",
3419 : : eth_dev->data->name);
3420 : : err = -ENOMEM;
3421 : 0 : goto alloc_eth_addr_fail;
3422 : : }
3423 : :
3424 : 0 : nic_dev->cmdq_ops = rte_zmalloc("cmdq_ops", sizeof(struct hinic3_nic_cmdq_ops), 0);
3425 [ # # ]: 0 : if (!nic_dev->cmdq_ops) {
3426 : 0 : PMD_DRV_LOG(ERR, "Allocate cmdq_ops memory failed");
3427 : : err = -ENOMEM;
3428 : 0 : goto alloc_cmdq_ops_fail;
3429 : : }
3430 : :
3431 : 0 : nic_dev->rx_ops = rte_zmalloc("rx_ops", sizeof(struct hinic3_nic_rx_ops), 0);
3432 [ # # ]: 0 : if (!nic_dev->rx_ops) {
3433 : 0 : PMD_DRV_LOG(ERR, "Allocate rx_ops memory failed");
3434 : : err = -ENOMEM;
3435 : 0 : goto alloc_rx_ops_fail;
3436 : : }
3437 : :
3438 : 0 : nic_dev->tx_ops = rte_zmalloc("tx_ops", sizeof(struct hinic3_nic_tx_ops), 0);
3439 [ # # ]: 0 : if (!nic_dev->tx_ops) {
3440 : 0 : PMD_DRV_LOG(ERR, "Allocate tx_ops memory failed");
3441 : : err = -ENOMEM;
3442 : 0 : goto alloc_tx_ops_fail;
3443 : : }
3444 : :
3445 : 0 : nic_dev->mc_list = rte_zmalloc("hinic3_mc",
3446 : : HINIC3_MAX_MC_MAC_ADDRS * sizeof(struct rte_ether_addr), 0);
3447 [ # # ]: 0 : if (!nic_dev->mc_list) {
3448 : 0 : PMD_DRV_LOG(ERR, "Allocate MAC addresses failed, dev_name: %s",
3449 : : eth_dev->data->name);
3450 : : err = -ENOMEM;
3451 : 0 : goto alloc_mc_list_fail;
3452 : : }
3453 : :
3454 : : /* Create hardware device. */
3455 : 0 : nic_dev->hwdev = rte_zmalloc("hinic3_hwdev", sizeof(*nic_dev->hwdev),
3456 : : RTE_CACHE_LINE_SIZE);
3457 [ # # ]: 0 : if (!nic_dev->hwdev) {
3458 : 0 : PMD_DRV_LOG(ERR, "Allocate hwdev memory failed, dev_name: %s",
3459 : : eth_dev->data->name);
3460 : : err = -ENOMEM;
3461 : 0 : goto alloc_hwdev_mem_fail;
3462 : : }
3463 : 0 : nic_dev->hwdev->pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
3464 : 0 : nic_dev->hwdev->dev_handle = nic_dev;
3465 : 0 : nic_dev->hwdev->eth_dev = eth_dev;
3466 : 0 : nic_dev->hwdev->port_id = eth_dev->data->port_id;
3467 : :
3468 : 0 : err = hinic3_init_hwdev(nic_dev->hwdev);
3469 [ # # ]: 0 : if (err) {
3470 : 0 : PMD_DRV_LOG(ERR, "Init chip hwdev failed, dev_name: %s",
3471 : : eth_dev->data->name);
3472 : 0 : goto init_hwdev_fail;
3473 : : }
3474 : :
3475 : 0 : nic_dev->max_sqs = hinic3_func_max_sqs(nic_dev->hwdev);
3476 : 0 : nic_dev->max_rqs = hinic3_func_max_rqs(nic_dev->hwdev);
3477 : :
3478 [ # # ]: 0 : if (HINIC3_FUNC_TYPE(nic_dev->hwdev) == TYPE_VF)
3479 : 0 : eth_dev->dev_ops = &hinic3_pmd_vf_ops;
3480 : : else
3481 : 0 : eth_dev->dev_ops = &hinic3_pmd_ops;
3482 : :
3483 : 0 : err = hinic3_init_nic_hwdev(nic_dev->hwdev);
3484 [ # # ]: 0 : if (err) {
3485 : 0 : PMD_DRV_LOG(ERR, "Init nic hwdev failed, dev_name: %s",
3486 : : eth_dev->data->name);
3487 : 0 : goto init_nic_hwdev_fail;
3488 : : }
3489 : :
3490 : 0 : err = hinic3_get_feature_from_hw(nic_dev->hwdev, &nic_dev->feature_cap, 1);
3491 [ # # ]: 0 : if (err) {
3492 : 0 : PMD_DRV_LOG(ERR,
3493 : : "Get nic feature from hardware failed, dev_name: %s",
3494 : : eth_dev->data->name);
3495 : 0 : goto get_cap_fail;
3496 : : }
3497 : :
3498 [ # # ]: 0 : if (!(nic_dev->feature_cap & NIC_F_HTN_CMDQ))
3499 : 0 : nic_dev->cmdq_ops = hinic3_nic_cmdq_get_stn_ops();
3500 : : else
3501 : 0 : nic_dev->cmdq_ops = hinic3_nic_cmdq_get_htn_ops();
3502 : :
3503 : 0 : hinic3_nic_tx_rx_ops_init(nic_dev);
3504 : :
3505 : 0 : err = hinic3_init_sw_rxtxqs(nic_dev);
3506 [ # # ]: 0 : if (err) {
3507 : 0 : PMD_DRV_LOG(ERR, "Init sw rxqs or txqs failed, dev_name: %s",
3508 : : eth_dev->data->name);
3509 : 0 : goto init_sw_rxtxqs_fail;
3510 : : }
3511 : :
3512 : 0 : err = hinic3_init_mac_table(eth_dev);
3513 [ # # ]: 0 : if (err) {
3514 : 0 : PMD_DRV_LOG(ERR, "Init mac table failed, dev_name: %s",
3515 : : eth_dev->data->name);
3516 : 0 : goto init_mac_table_fail;
3517 : : }
3518 : :
3519 : : /* Set hardware feature to default status. */
3520 : 0 : err = hinic3_set_default_hw_feature(nic_dev);
3521 [ # # ]: 0 : if (err) {
3522 : 0 : PMD_DRV_LOG(ERR, "Set hw default features failed, dev_name: %s",
3523 : : eth_dev->data->name);
3524 : 0 : goto set_default_feature_fail;
3525 : : }
3526 : :
3527 : : /* Register callback func to eal lib. */
3528 : 0 : err = rte_intr_callback_register(PCI_DEV_TO_INTR_HANDLE(pci_dev),
3529 : : hinic3_dev_interrupt_handler,
3530 : : (void *)eth_dev);
3531 [ # # ]: 0 : if (err) {
3532 : 0 : PMD_DRV_LOG(ERR, "Register intr callback failed, dev_name: %s",
3533 : : eth_dev->data->name);
3534 : 0 : goto reg_intr_cb_fail;
3535 : : }
3536 : :
3537 : : /* Enable uio/vfio intr/eventfd mapping. */
3538 : 0 : err = rte_intr_enable(PCI_DEV_TO_INTR_HANDLE(pci_dev));
3539 [ # # ]: 0 : if (err) {
3540 : 0 : PMD_DRV_LOG(ERR, "Enable rte interrupt failed, dev_name: %s",
3541 : : eth_dev->data->name);
3542 : 0 : goto enable_intr_fail;
3543 : : }
3544 : 0 : tcam_info = &nic_dev->tcam;
3545 : : memset(tcam_info, 0, sizeof(struct hinic3_tcam_info));
3546 : 0 : TAILQ_INIT(&tcam_info->tcam_list);
3547 : 0 : TAILQ_INIT(&tcam_info->tcam_dynamic_info.tcam_dynamic_list);
3548 : 0 : TAILQ_INIT(&nic_dev->filter_ethertype_list);
3549 : 0 : TAILQ_INIT(&nic_dev->filter_fdir_rule_list);
3550 : :
3551 : 0 : hinic3_set_bit(HINIC3_DEV_INTR_EN, &nic_dev->dev_status);
3552 : :
3553 : : hinic3_set_bit(HINIC3_DEV_INIT, &nic_dev->dev_status);
3554 : 0 : PMD_DRV_LOG(DEBUG, "Initialize %s in primary succeed",
3555 : : eth_dev->data->name);
3556 : :
3557 : : /**
3558 : : * Queue xstats filled automatically by ethdev layer.
3559 : : */
3560 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
3561 : :
3562 : 0 : return 0;
3563 : :
3564 : : enable_intr_fail:
3565 : 0 : rte_intr_callback_unregister(PCI_DEV_TO_INTR_HANDLE(pci_dev),
3566 : : hinic3_dev_interrupt_handler,
3567 : : (void *)eth_dev);
3568 : :
3569 : 0 : reg_intr_cb_fail:
3570 : 0 : set_default_feature_fail:
3571 : 0 : hinic3_deinit_mac_addr(eth_dev);
3572 : :
3573 : 0 : init_mac_table_fail:
3574 : : hinic3_deinit_sw_rxtxqs(nic_dev);
3575 : :
3576 : 0 : init_sw_rxtxqs_fail:
3577 : 0 : hinic3_free_nic_hwdev(nic_dev->hwdev);
3578 : :
3579 : 0 : get_cap_fail:
3580 : 0 : init_nic_hwdev_fail:
3581 : 0 : hinic3_free_hwdev(nic_dev->hwdev);
3582 : 0 : eth_dev->dev_ops = NULL;
3583 : :
3584 : 0 : init_hwdev_fail:
3585 : 0 : rte_free(nic_dev->hwdev);
3586 : 0 : nic_dev->hwdev = NULL;
3587 : :
3588 : 0 : alloc_hwdev_mem_fail:
3589 : 0 : rte_free(nic_dev->mc_list);
3590 : 0 : nic_dev->mc_list = NULL;
3591 : :
3592 : 0 : alloc_mc_list_fail:
3593 : 0 : rte_free(nic_dev->tx_ops);
3594 : 0 : nic_dev->tx_ops = NULL;
3595 : :
3596 : 0 : alloc_tx_ops_fail:
3597 : 0 : rte_free(nic_dev->rx_ops);
3598 : 0 : nic_dev->rx_ops = NULL;
3599 : :
3600 : 0 : alloc_rx_ops_fail:
3601 : 0 : rte_free(nic_dev->cmdq_ops);
3602 : 0 : nic_dev->cmdq_ops = NULL;
3603 : :
3604 : 0 : alloc_cmdq_ops_fail:
3605 : 0 : rte_free(eth_dev->data->mac_addrs);
3606 : 0 : eth_dev->data->mac_addrs = NULL;
3607 : :
3608 : 0 : alloc_eth_addr_fail:
3609 : 0 : PMD_DRV_LOG(ERR, "Initialize %s in primary failed",
3610 : : eth_dev->data->name);
3611 : 0 : return err;
3612 : : }
3613 : :
3614 : : static int
3615 : 0 : hinic3_dev_init(struct rte_eth_dev *eth_dev)
3616 : : {
3617 : : struct rte_pci_device *pci_dev;
3618 : :
3619 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
3620 : :
3621 [ # # ]: 0 : PMD_DRV_LOG(INFO, "Initializing %.4x:%.2x:%.2x.%x in %s process",
3622 : : pci_dev->addr.domain, pci_dev->addr.bus,
3623 : : pci_dev->addr.devid, pci_dev->addr.function,
3624 : : (rte_eal_process_type() == RTE_PROC_PRIMARY) ? "primary"
3625 : : : "secondary");
3626 : :
3627 : 0 : PMD_DRV_LOG(DEBUG, "Network Interface pmd driver version: %s",
3628 : : HINIC3_PMD_DRV_VERSION);
3629 : :
3630 : 0 : eth_dev->rx_pkt_burst = hinic3_recv_pkts;
3631 : 0 : eth_dev->tx_pkt_burst = hinic3_xmit_pkts;
3632 : :
3633 : 0 : return hinic3_func_init(eth_dev);
3634 : : }
3635 : :
3636 : : static int
3637 : 0 : hinic3_dev_uninit(struct rte_eth_dev *dev)
3638 : : {
3639 : : struct hinic3_nic_dev *nic_dev;
3640 : :
3641 : 0 : nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
3642 : 0 : hinic3_clear_bit(HINIC3_DEV_INIT, &nic_dev->dev_status);
3643 : :
3644 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
3645 : : return 0;
3646 : :
3647 : 0 : return hinic3_dev_close(dev);
3648 : : }
3649 : :
3650 : : static const struct rte_pci_id pci_id_hinic3_map[] = {
3651 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HINIC3_DEV_ID_SP620)},
3652 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HINIC3_DEV_ID_VF_SP620)},
3653 : :
3654 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HINIC3_DEV_ID_SP230)},
3655 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HINIC3_DEV_ID_VF_SP230)},
3656 : :
3657 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HINIC3_DEV_ID_SP920)},
3658 : :
3659 : : {.vendor_id = 0},
3660 : : };
3661 : :
3662 : : static int
3663 : 0 : hinic3_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
3664 : : struct rte_pci_device *pci_dev)
3665 : : {
3666 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
3667 : : sizeof(struct hinic3_nic_dev), hinic3_dev_init);
3668 : : }
3669 : :
3670 : : static int
3671 : 0 : hinic3_pci_remove(struct rte_pci_device *pci_dev)
3672 : : {
3673 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, hinic3_dev_uninit);
3674 : : }
3675 : :
3676 : : static struct rte_pci_driver rte_hinic3_pmd = {
3677 : : .id_table = pci_id_hinic3_map,
3678 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
3679 : : .probe = hinic3_pci_probe,
3680 : : .remove = hinic3_pci_remove,
3681 : : };
3682 : :
3683 : 276 : RTE_PMD_REGISTER_PCI(net_hinic3, rte_hinic3_pmd);
3684 : : RTE_PMD_REGISTER_PCI_TABLE(net_hinic3, pci_id_hinic3_map);
3685 : :
3686 : 276 : RTE_INIT(hinic3_init_log)
3687 : : {
3688 : 276 : hinic3_logtype = rte_log_register("pmd.net.hinic3");
3689 [ + - ]: 276 : if (hinic3_logtype >= 0)
3690 : 276 : rte_log_set_level(hinic3_logtype, RTE_LOG_INFO);
3691 : 276 : }
|