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