Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Huawei Technologies Co., Ltd
3 : : */
4 : :
5 : : #include <rte_pci.h>
6 : : #include <bus_pci_driver.h>
7 : : #include <ethdev_pci.h>
8 : : #include <ethdev_driver.h>
9 : : #include <rte_mbuf.h>
10 : : #include <rte_malloc.h>
11 : : #include <rte_memcpy.h>
12 : : #include <rte_mempool.h>
13 : : #include <rte_errno.h>
14 : : #include <rte_ether.h>
15 : :
16 : : #include "base/hinic_compat.h"
17 : : #include "base/hinic_pmd_hwdev.h"
18 : : #include "base/hinic_pmd_hwif.h"
19 : : #include "base/hinic_pmd_wq.h"
20 : : #include "base/hinic_pmd_cfg.h"
21 : : #include "base/hinic_pmd_mgmt.h"
22 : : #include "base/hinic_pmd_cmdq.h"
23 : : #include "base/hinic_pmd_niccfg.h"
24 : : #include "base/hinic_pmd_nicio.h"
25 : : #include "base/hinic_pmd_mbox.h"
26 : : #include "hinic_pmd_ethdev.h"
27 : : #include "hinic_pmd_tx.h"
28 : : #include "hinic_pmd_rx.h"
29 : :
30 : : /* Vendor ID used by Huawei devices */
31 : : #define HINIC_HUAWEI_VENDOR_ID 0x19E5
32 : :
33 : : /* Hinic devices */
34 : : #define HINIC_DEV_ID_PRD 0x1822
35 : : #define HINIC_DEV_ID_VF 0x375E
36 : : #define HINIC_DEV_ID_VF_HV 0x379E
37 : :
38 : : /* Mezz card for Blade Server */
39 : : #define HINIC_DEV_ID_MEZZ_25GE 0x0210
40 : : #define HINIC_DEV_ID_MEZZ_100GE 0x0205
41 : :
42 : : /* 2*25G and 2*100G card */
43 : : #define HINIC_DEV_ID_1822_DUAL_25GE 0x0206
44 : : #define HINIC_DEV_ID_1822_100GE 0x0200
45 : :
46 : : #define HINIC_SERVICE_MODE_NIC 2
47 : :
48 : : #define HINIC_INTR_CB_UNREG_MAX_RETRIES 10
49 : :
50 : : #define DEFAULT_BASE_COS 4
51 : : #define NR_MAX_COS 8
52 : :
53 : : #define HINIC_MIN_RX_BUF_SIZE 1024
54 : : #define HINIC_MAX_UC_MAC_ADDRS 128
55 : : #define HINIC_MAX_MC_MAC_ADDRS 2048
56 : :
57 : : #define HINIC_DEFAULT_BURST_SIZE 32
58 : : #define HINIC_DEFAULT_NB_QUEUES 1
59 : : #define HINIC_DEFAULT_RING_SIZE 1024
60 : : #define HINIC_MAX_LRO_SIZE 65536
61 : :
62 : : /*
63 : : * vlan_id is a 12 bit number.
64 : : * The VFTA array is actually a 4096 bit array, 128 of 32bit elements.
65 : : * 2^5 = 32. The val of lower 5 bits specifies the bit in the 32bit element.
66 : : * The higher 7 bit val specifies VFTA array index.
67 : : */
68 : : #define HINIC_VFTA_BIT(vlan_id) (1 << ((vlan_id) & 0x1F))
69 : : #define HINIC_VFTA_IDX(vlan_id) ((vlan_id) >> 5)
70 : :
71 : : #define HINIC_VLAN_FILTER_EN (1U << 0)
72 : :
73 : : /* lro numer limit for one packet */
74 : : #define HINIC_LRO_WQE_NUM_DEFAULT 8
75 : :
76 : : struct hinic_xstats_name_off {
77 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
78 : : u32 offset;
79 : : };
80 : :
81 : : #define HINIC_FUNC_STAT(_stat_item) { \
82 : : .name = #_stat_item, \
83 : : .offset = offsetof(struct hinic_vport_stats, _stat_item) \
84 : : }
85 : :
86 : : #define HINIC_PORT_STAT(_stat_item) { \
87 : : .name = #_stat_item, \
88 : : .offset = offsetof(struct hinic_phy_port_stats, _stat_item) \
89 : : }
90 : :
91 : : static const struct hinic_xstats_name_off hinic_vport_stats_strings[] = {
92 : : HINIC_FUNC_STAT(tx_unicast_pkts_vport),
93 : : HINIC_FUNC_STAT(tx_unicast_bytes_vport),
94 : : HINIC_FUNC_STAT(tx_multicast_pkts_vport),
95 : : HINIC_FUNC_STAT(tx_multicast_bytes_vport),
96 : : HINIC_FUNC_STAT(tx_broadcast_pkts_vport),
97 : : HINIC_FUNC_STAT(tx_broadcast_bytes_vport),
98 : :
99 : : HINIC_FUNC_STAT(rx_unicast_pkts_vport),
100 : : HINIC_FUNC_STAT(rx_unicast_bytes_vport),
101 : : HINIC_FUNC_STAT(rx_multicast_pkts_vport),
102 : : HINIC_FUNC_STAT(rx_multicast_bytes_vport),
103 : : HINIC_FUNC_STAT(rx_broadcast_pkts_vport),
104 : : HINIC_FUNC_STAT(rx_broadcast_bytes_vport),
105 : :
106 : : HINIC_FUNC_STAT(tx_discard_vport),
107 : : HINIC_FUNC_STAT(rx_discard_vport),
108 : : HINIC_FUNC_STAT(tx_err_vport),
109 : : HINIC_FUNC_STAT(rx_err_vport),
110 : : };
111 : :
112 : : #define HINIC_VPORT_XSTATS_NUM (sizeof(hinic_vport_stats_strings) / \
113 : : sizeof(hinic_vport_stats_strings[0]))
114 : :
115 : : static const struct hinic_xstats_name_off hinic_phyport_stats_strings[] = {
116 : : HINIC_PORT_STAT(mac_rx_total_pkt_num),
117 : : HINIC_PORT_STAT(mac_rx_total_oct_num),
118 : : HINIC_PORT_STAT(mac_rx_bad_pkt_num),
119 : : HINIC_PORT_STAT(mac_rx_bad_oct_num),
120 : : HINIC_PORT_STAT(mac_rx_good_pkt_num),
121 : : HINIC_PORT_STAT(mac_rx_good_oct_num),
122 : : HINIC_PORT_STAT(mac_rx_uni_pkt_num),
123 : : HINIC_PORT_STAT(mac_rx_multi_pkt_num),
124 : : HINIC_PORT_STAT(mac_rx_broad_pkt_num),
125 : : HINIC_PORT_STAT(mac_tx_total_pkt_num),
126 : : HINIC_PORT_STAT(mac_tx_total_oct_num),
127 : : HINIC_PORT_STAT(mac_tx_bad_pkt_num),
128 : : HINIC_PORT_STAT(mac_tx_bad_oct_num),
129 : : HINIC_PORT_STAT(mac_tx_good_pkt_num),
130 : : HINIC_PORT_STAT(mac_tx_good_oct_num),
131 : : HINIC_PORT_STAT(mac_tx_uni_pkt_num),
132 : : HINIC_PORT_STAT(mac_tx_multi_pkt_num),
133 : : HINIC_PORT_STAT(mac_tx_broad_pkt_num),
134 : : HINIC_PORT_STAT(mac_rx_fragment_pkt_num),
135 : : HINIC_PORT_STAT(mac_rx_undersize_pkt_num),
136 : : HINIC_PORT_STAT(mac_rx_undermin_pkt_num),
137 : : HINIC_PORT_STAT(mac_rx_64_oct_pkt_num),
138 : : HINIC_PORT_STAT(mac_rx_65_127_oct_pkt_num),
139 : : HINIC_PORT_STAT(mac_rx_128_255_oct_pkt_num),
140 : : HINIC_PORT_STAT(mac_rx_256_511_oct_pkt_num),
141 : : HINIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num),
142 : : HINIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num),
143 : : HINIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num),
144 : : HINIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num),
145 : : HINIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num),
146 : : HINIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num),
147 : : HINIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num),
148 : : HINIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num),
149 : : HINIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num),
150 : : HINIC_PORT_STAT(mac_rx_1519_max_good_pkt_num),
151 : : HINIC_PORT_STAT(mac_rx_oversize_pkt_num),
152 : : HINIC_PORT_STAT(mac_rx_jabber_pkt_num),
153 : : HINIC_PORT_STAT(mac_rx_mac_pause_num),
154 : : HINIC_PORT_STAT(mac_rx_pfc_pkt_num),
155 : : HINIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num),
156 : : HINIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num),
157 : : HINIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num),
158 : : HINIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num),
159 : : HINIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num),
160 : : HINIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num),
161 : : HINIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num),
162 : : HINIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num),
163 : : HINIC_PORT_STAT(mac_rx_mac_control_pkt_num),
164 : : HINIC_PORT_STAT(mac_rx_sym_err_pkt_num),
165 : : HINIC_PORT_STAT(mac_rx_fcs_err_pkt_num),
166 : : HINIC_PORT_STAT(mac_rx_send_app_good_pkt_num),
167 : : HINIC_PORT_STAT(mac_rx_send_app_bad_pkt_num),
168 : : HINIC_PORT_STAT(mac_tx_fragment_pkt_num),
169 : : HINIC_PORT_STAT(mac_tx_undersize_pkt_num),
170 : : HINIC_PORT_STAT(mac_tx_undermin_pkt_num),
171 : : HINIC_PORT_STAT(mac_tx_64_oct_pkt_num),
172 : : HINIC_PORT_STAT(mac_tx_65_127_oct_pkt_num),
173 : : HINIC_PORT_STAT(mac_tx_128_255_oct_pkt_num),
174 : : HINIC_PORT_STAT(mac_tx_256_511_oct_pkt_num),
175 : : HINIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num),
176 : : HINIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num),
177 : : HINIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num),
178 : : HINIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num),
179 : : HINIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num),
180 : : HINIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num),
181 : : HINIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num),
182 : : HINIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num),
183 : : HINIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num),
184 : : HINIC_PORT_STAT(mac_tx_1519_max_good_pkt_num),
185 : : HINIC_PORT_STAT(mac_tx_oversize_pkt_num),
186 : : HINIC_PORT_STAT(mac_trans_jabber_pkt_num),
187 : : HINIC_PORT_STAT(mac_tx_mac_pause_num),
188 : : HINIC_PORT_STAT(mac_tx_pfc_pkt_num),
189 : : HINIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num),
190 : : HINIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num),
191 : : HINIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num),
192 : : HINIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num),
193 : : HINIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num),
194 : : HINIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num),
195 : : HINIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num),
196 : : HINIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num),
197 : : HINIC_PORT_STAT(mac_tx_mac_control_pkt_num),
198 : : HINIC_PORT_STAT(mac_tx_err_all_pkt_num),
199 : : HINIC_PORT_STAT(mac_tx_from_app_good_pkt_num),
200 : : HINIC_PORT_STAT(mac_tx_from_app_bad_pkt_num),
201 : : };
202 : :
203 : : #define HINIC_PHYPORT_XSTATS_NUM (sizeof(hinic_phyport_stats_strings) / \
204 : : sizeof(hinic_phyport_stats_strings[0]))
205 : :
206 : : static const struct hinic_xstats_name_off hinic_rxq_stats_strings[] = {
207 : : {"rx_nombuf", offsetof(struct hinic_rxq_stats, rx_nombuf)},
208 : : {"burst_pkt", offsetof(struct hinic_rxq_stats, burst_pkts)},
209 : : };
210 : :
211 : : #define HINIC_RXQ_XSTATS_NUM (sizeof(hinic_rxq_stats_strings) / \
212 : : sizeof(hinic_rxq_stats_strings[0]))
213 : :
214 : : static const struct hinic_xstats_name_off hinic_txq_stats_strings[] = {
215 : : {"tx_busy", offsetof(struct hinic_txq_stats, tx_busy)},
216 : : {"offload_errors", offsetof(struct hinic_txq_stats, off_errs)},
217 : : {"copy_pkts", offsetof(struct hinic_txq_stats, cpy_pkts)},
218 : : {"rl_drop", offsetof(struct hinic_txq_stats, rl_drop)},
219 : : {"burst_pkts", offsetof(struct hinic_txq_stats, burst_pkts)},
220 : : {"sge_len0", offsetof(struct hinic_txq_stats, sge_len0)},
221 : : {"mbuf_null", offsetof(struct hinic_txq_stats, mbuf_null)},
222 : : };
223 : :
224 : : #define HINIC_TXQ_XSTATS_NUM (sizeof(hinic_txq_stats_strings) / \
225 : : sizeof(hinic_txq_stats_strings[0]))
226 : :
227 : : static int hinic_xstats_calc_num(struct hinic_nic_dev *nic_dev)
228 : : {
229 [ # # ]: 0 : if (HINIC_IS_VF(nic_dev->hwdev)) {
230 : 0 : return (HINIC_VPORT_XSTATS_NUM +
231 : 0 : HINIC_RXQ_XSTATS_NUM * nic_dev->num_rq +
232 : 0 : HINIC_TXQ_XSTATS_NUM * nic_dev->num_sq);
233 : : } else {
234 : : return (HINIC_VPORT_XSTATS_NUM +
235 : : HINIC_PHYPORT_XSTATS_NUM +
236 : 0 : HINIC_RXQ_XSTATS_NUM * nic_dev->num_rq +
237 : 0 : HINIC_TXQ_XSTATS_NUM * nic_dev->num_sq);
238 : : }
239 : : }
240 : :
241 : : static const struct rte_eth_desc_lim hinic_rx_desc_lim = {
242 : : .nb_max = HINIC_MAX_QUEUE_DEPTH,
243 : : .nb_min = HINIC_MIN_QUEUE_DEPTH,
244 : : .nb_align = HINIC_RXD_ALIGN,
245 : : };
246 : :
247 : : static const struct rte_eth_desc_lim hinic_tx_desc_lim = {
248 : : .nb_max = HINIC_MAX_QUEUE_DEPTH,
249 : : .nb_min = HINIC_MIN_QUEUE_DEPTH,
250 : : .nb_align = HINIC_TXD_ALIGN,
251 : : };
252 : :
253 : : static int hinic_vlan_offload_set(struct rte_eth_dev *dev, int mask);
254 : :
255 : : /**
256 : : * Interrupt handler triggered by NIC for handling
257 : : * specific event.
258 : : *
259 : : * @param: The address of parameter (struct rte_eth_dev *) registered before.
260 : : */
261 : 0 : static void hinic_dev_interrupt_handler(void *param)
262 : : {
263 : : struct rte_eth_dev *dev = param;
264 [ # # ]: 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
265 : :
266 [ # # ]: 0 : if (!rte_bit_relaxed_get32(HINIC_DEV_INTR_EN, &nic_dev->dev_status)) {
267 : 0 : PMD_DRV_LOG(WARNING, "Device's interrupt is disabled, ignore interrupt event, dev_name: %s, port_id: %d",
268 : : nic_dev->proc_dev_name, dev->data->port_id);
269 : 0 : return;
270 : : }
271 : :
272 : : /* aeq0 msg handler */
273 : 0 : hinic_dev_handle_aeq_event(nic_dev->hwdev, param);
274 : : }
275 : :
276 : : /**
277 : : * Ethernet device configuration.
278 : : *
279 : : * Prepare the driver for a given number of TX and RX queues, mtu size
280 : : * and configure RSS.
281 : : *
282 : : * @param dev
283 : : * Pointer to Ethernet device structure.
284 : : *
285 : : * @return
286 : : * 0 on success, negative error value otherwise.
287 : : */
288 : 0 : static int hinic_dev_configure(struct rte_eth_dev *dev)
289 : : {
290 : : struct hinic_nic_dev *nic_dev;
291 : : struct hinic_nic_io *nic_io;
292 : : int err;
293 : :
294 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
295 : 0 : nic_io = nic_dev->hwdev->nic_io;
296 : :
297 : 0 : nic_dev->num_sq = dev->data->nb_tx_queues;
298 : 0 : nic_dev->num_rq = dev->data->nb_rx_queues;
299 : :
300 : 0 : nic_io->num_sqs = dev->data->nb_tx_queues;
301 : 0 : nic_io->num_rqs = dev->data->nb_rx_queues;
302 : :
303 : : /* queue pair is max_num(sq, rq) */
304 : 0 : nic_dev->num_qps = (nic_dev->num_sq > nic_dev->num_rq) ?
305 : 0 : nic_dev->num_sq : nic_dev->num_rq;
306 : 0 : nic_io->num_qps = nic_dev->num_qps;
307 : :
308 [ # # ]: 0 : if (nic_dev->num_qps > nic_io->max_qps) {
309 : 0 : PMD_DRV_LOG(ERR,
310 : : "Queue number out of range, get queue_num:%d, max_queue_num:%d",
311 : : nic_dev->num_qps, nic_io->max_qps);
312 : 0 : return -EINVAL;
313 : : }
314 : :
315 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
316 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
317 : :
318 : : /* mtu size is 256~9600 */
319 : 0 : if (HINIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) <
320 [ # # ]: 0 : HINIC_MIN_FRAME_SIZE ||
321 : : HINIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu) >
322 : : HINIC_MAX_JUMBO_FRAME_SIZE) {
323 : 0 : PMD_DRV_LOG(ERR,
324 : : "Packet length out of range, get packet length:%d, "
325 : : "expect between %d and %d",
326 : : HINIC_MTU_TO_PKTLEN(dev->data->dev_conf.rxmode.mtu),
327 : : HINIC_MIN_FRAME_SIZE, HINIC_MAX_JUMBO_FRAME_SIZE);
328 : 0 : return -EINVAL;
329 : : }
330 : :
331 : 0 : nic_dev->mtu_size = dev->data->dev_conf.rxmode.mtu;
332 : :
333 : : /* rss template */
334 : 0 : err = hinic_config_mq_mode(dev, TRUE);
335 [ # # ]: 0 : if (err) {
336 : 0 : PMD_DRV_LOG(ERR, "Config multi-queue failed");
337 : 0 : return err;
338 : : }
339 : :
340 : : /* init VLAN offload */
341 : 0 : err = hinic_vlan_offload_set(dev,
342 : : RTE_ETH_VLAN_STRIP_MASK | RTE_ETH_VLAN_FILTER_MASK);
343 [ # # ]: 0 : if (err) {
344 : 0 : PMD_DRV_LOG(ERR, "Initialize vlan filter and strip failed");
345 : 0 : (void)hinic_config_mq_mode(dev, FALSE);
346 : 0 : return err;
347 : : }
348 : :
349 : : /* clear fdir filter flag in function table */
350 : 0 : hinic_free_fdir_filter(nic_dev);
351 : :
352 : 0 : return HINIC_OK;
353 : : }
354 : :
355 : : /**
356 : : * DPDK callback to create the receive queue.
357 : : *
358 : : * @param dev
359 : : * Pointer to Ethernet device structure.
360 : : * @param queue_idx
361 : : * RX queue index.
362 : : * @param nb_desc
363 : : * Number of descriptors for receive queue.
364 : : * @param socket_id
365 : : * NUMA socket on which memory must be allocated.
366 : : * @param rx_conf
367 : : * Thresholds parameters (unused_).
368 : : * @param mp
369 : : * Memory pool for buffer allocations.
370 : : *
371 : : * @return
372 : : * 0 on success, negative error value otherwise.
373 : : */
374 : 0 : static int hinic_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
375 : : uint16_t nb_desc, unsigned int socket_id,
376 : : __rte_unused const struct rte_eth_rxconf *rx_conf,
377 : : struct rte_mempool *mp)
378 : : {
379 : : int rc;
380 : : struct hinic_nic_dev *nic_dev;
381 : : struct hinic_hwdev *hwdev;
382 : : struct hinic_rxq *rxq;
383 : : u16 rq_depth, rx_free_thresh;
384 : : u32 buf_size;
385 : :
386 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
387 : 0 : hwdev = nic_dev->hwdev;
388 : :
389 : : /* queue depth must be power of 2, otherwise will be aligned up */
390 [ # # ]: 0 : rq_depth = (nb_desc & (nb_desc - 1)) ?
391 : 0 : ((u16)(1U << (ilog2(nb_desc) + 1))) : nb_desc;
392 : :
393 : : /*
394 : : * Validate number of receive descriptors.
395 : : * It must not exceed hardware maximum and minimum.
396 : : */
397 [ # # ]: 0 : if (rq_depth > HINIC_MAX_QUEUE_DEPTH ||
398 : : rq_depth < HINIC_MIN_QUEUE_DEPTH) {
399 : 0 : PMD_DRV_LOG(ERR, "RX queue depth is out of range from %d to %d, (nb_desc=%d, q_depth=%d, port=%d queue=%d)",
400 : : HINIC_MIN_QUEUE_DEPTH, HINIC_MAX_QUEUE_DEPTH,
401 : : (int)nb_desc, (int)rq_depth,
402 : : (int)dev->data->port_id, (int)queue_idx);
403 : 0 : return -EINVAL;
404 : : }
405 : :
406 : : /*
407 : : * The RX descriptor ring will be cleaned after rxq->rx_free_thresh
408 : : * descriptors are used or if the number of descriptors required
409 : : * to transmit a packet is greater than the number of free RX
410 : : * descriptors.
411 : : * The following constraints must be satisfied:
412 : : * rx_free_thresh must be greater than 0.
413 : : * rx_free_thresh must be less than the size of the ring minus 1.
414 : : * When set to zero use default values.
415 : : */
416 [ # # ]: 0 : rx_free_thresh = (u16)((rx_conf->rx_free_thresh) ?
417 : : rx_conf->rx_free_thresh : HINIC_DEFAULT_RX_FREE_THRESH);
418 [ # # ]: 0 : if (rx_free_thresh >= (rq_depth - 1)) {
419 : 0 : PMD_DRV_LOG(ERR, "rx_free_thresh must be less than the number of RX descriptors minus 1. (rx_free_thresh=%u port=%d queue=%d)",
420 : : (unsigned int)rx_free_thresh,
421 : : (int)dev->data->port_id,
422 : : (int)queue_idx);
423 : 0 : return -EINVAL;
424 : : }
425 : :
426 : 0 : rxq = rte_zmalloc_socket("hinic_rx_queue", sizeof(struct hinic_rxq),
427 : : RTE_CACHE_LINE_SIZE, socket_id);
428 [ # # ]: 0 : if (!rxq) {
429 : 0 : PMD_DRV_LOG(ERR, "Allocate rxq[%d] failed, dev_name: %s",
430 : : queue_idx, dev->data->name);
431 : 0 : return -ENOMEM;
432 : : }
433 : 0 : nic_dev->rxqs[queue_idx] = rxq;
434 : :
435 : : /* alloc rx sq hw wqe page */
436 : 0 : rc = hinic_create_rq(hwdev, queue_idx, rq_depth, socket_id);
437 [ # # ]: 0 : if (rc) {
438 : 0 : PMD_DRV_LOG(ERR, "Create rxq[%d] failed, dev_name: %s, rq_depth: %d",
439 : : queue_idx, dev->data->name, rq_depth);
440 : 0 : goto ceate_rq_fail;
441 : : }
442 : :
443 : : /* mbuf pool must be assigned before setup rx resources */
444 [ # # ]: 0 : rxq->mb_pool = mp;
445 : :
446 : : rc =
447 : 0 : hinic_convert_rx_buf_size(rte_pktmbuf_data_room_size(rxq->mb_pool) -
448 : : RTE_PKTMBUF_HEADROOM, &buf_size);
449 [ # # ]: 0 : if (rc) {
450 : 0 : PMD_DRV_LOG(ERR, "Adjust buf size failed, dev_name: %s",
451 : : dev->data->name);
452 : 0 : goto adjust_bufsize_fail;
453 : : }
454 : :
455 : : /* rx queue info, rearm control */
456 : 0 : rxq->wq = &hwdev->nic_io->rq_wq[queue_idx];
457 : 0 : rxq->pi_virt_addr = hwdev->nic_io->qps[queue_idx].rq.pi_virt_addr;
458 : 0 : rxq->nic_dev = nic_dev;
459 : 0 : rxq->q_id = queue_idx;
460 : 0 : rxq->q_depth = rq_depth;
461 : 0 : rxq->buf_len = (u16)buf_size;
462 : 0 : rxq->rx_free_thresh = rx_free_thresh;
463 : 0 : rxq->socket_id = socket_id;
464 : :
465 : : /* the last point cant do mbuf rearm in bulk */
466 : 0 : rxq->rxinfo_align_end = rxq->q_depth - rxq->rx_free_thresh;
467 : :
468 : : /* device port identifier */
469 : 0 : rxq->port_id = dev->data->port_id;
470 : :
471 : : /* alloc rx_cqe and prepare rq_wqe */
472 : 0 : rc = hinic_setup_rx_resources(rxq);
473 [ # # ]: 0 : if (rc) {
474 : 0 : PMD_DRV_LOG(ERR, "Setup rxq[%d] rx_resources failed, dev_name: %s",
475 : : queue_idx, dev->data->name);
476 : 0 : goto setup_rx_res_err;
477 : : }
478 : :
479 : : /* record nic_dev rxq in rte_eth rx_queues */
480 : 0 : dev->data->rx_queues[queue_idx] = rxq;
481 : :
482 : 0 : return 0;
483 : :
484 : : setup_rx_res_err:
485 : 0 : adjust_bufsize_fail:
486 : 0 : hinic_destroy_rq(hwdev, queue_idx);
487 : :
488 : 0 : ceate_rq_fail:
489 : 0 : rte_free(rxq);
490 : :
491 : 0 : return rc;
492 : : }
493 : :
494 : 0 : static void hinic_reset_rx_queue(struct rte_eth_dev *dev)
495 : : {
496 : : struct hinic_rxq *rxq;
497 : : struct hinic_nic_dev *nic_dev;
498 : : int q_id = 0;
499 : :
500 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
501 : :
502 [ # # ]: 0 : for (q_id = 0; q_id < nic_dev->num_rq; q_id++) {
503 : 0 : rxq = dev->data->rx_queues[q_id];
504 : :
505 : 0 : rxq->wq->cons_idx = 0;
506 : 0 : rxq->wq->prod_idx = 0;
507 : 0 : rxq->wq->delta = rxq->q_depth;
508 : 0 : rxq->wq->mask = rxq->q_depth - 1;
509 : :
510 : : /* alloc mbuf to rq */
511 : 0 : hinic_rx_alloc_pkts(rxq);
512 : : }
513 : 0 : }
514 : :
515 : : /**
516 : : * DPDK callback to configure the transmit queue.
517 : : *
518 : : * @param dev
519 : : * Pointer to Ethernet device structure.
520 : : * @param queue_idx
521 : : * Transmit queue index.
522 : : * @param nb_desc
523 : : * Number of descriptors for transmit queue.
524 : : * @param socket_id
525 : : * NUMA socket on which memory must be allocated.
526 : : * @param tx_conf
527 : : * Tx queue configuration parameters.
528 : : *
529 : : * @return
530 : : * 0 on success, negative error value otherwise.
531 : : */
532 : 0 : static int hinic_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
533 : : uint16_t nb_desc, unsigned int socket_id,
534 : : __rte_unused const struct rte_eth_txconf *tx_conf)
535 : : {
536 : : int rc;
537 : : struct hinic_nic_dev *nic_dev;
538 : : struct hinic_hwdev *hwdev;
539 : : struct hinic_txq *txq;
540 : : u16 sq_depth, tx_free_thresh;
541 : :
542 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
543 : 0 : hwdev = nic_dev->hwdev;
544 : :
545 : : /* queue depth must be power of 2, otherwise will be aligned up */
546 [ # # ]: 0 : sq_depth = (nb_desc & (nb_desc - 1)) ?
547 : 0 : ((u16)(1U << (ilog2(nb_desc) + 1))) : nb_desc;
548 : :
549 : : /*
550 : : * Validate number of transmit descriptors.
551 : : * It must not exceed hardware maximum and minimum.
552 : : */
553 [ # # ]: 0 : if (sq_depth > HINIC_MAX_QUEUE_DEPTH ||
554 : : sq_depth < HINIC_MIN_QUEUE_DEPTH) {
555 : 0 : PMD_DRV_LOG(ERR, "TX queue depth is out of range from %d to %d, (nb_desc=%d, q_depth=%d, port=%d queue=%d)",
556 : : HINIC_MIN_QUEUE_DEPTH, HINIC_MAX_QUEUE_DEPTH,
557 : : (int)nb_desc, (int)sq_depth,
558 : : (int)dev->data->port_id, (int)queue_idx);
559 : 0 : return -EINVAL;
560 : : }
561 : :
562 : : /*
563 : : * The TX descriptor ring will be cleaned after txq->tx_free_thresh
564 : : * descriptors are used or if the number of descriptors required
565 : : * to transmit a packet is greater than the number of free TX
566 : : * descriptors.
567 : : * The following constraints must be satisfied:
568 : : * tx_free_thresh must be greater than 0.
569 : : * tx_free_thresh must be less than the size of the ring minus 1.
570 : : * When set to zero use default values.
571 : : */
572 [ # # ]: 0 : tx_free_thresh = (u16)((tx_conf->tx_free_thresh) ?
573 : : tx_conf->tx_free_thresh : HINIC_DEFAULT_TX_FREE_THRESH);
574 [ # # ]: 0 : if (tx_free_thresh >= (sq_depth - 1)) {
575 : 0 : PMD_DRV_LOG(ERR, "tx_free_thresh must be less than the number of TX descriptors minus 1. (tx_free_thresh=%u port=%d queue=%d)",
576 : : (unsigned int)tx_free_thresh, (int)dev->data->port_id,
577 : : (int)queue_idx);
578 : 0 : return -EINVAL;
579 : : }
580 : :
581 : 0 : txq = rte_zmalloc_socket("hinic_tx_queue", sizeof(struct hinic_txq),
582 : : RTE_CACHE_LINE_SIZE, socket_id);
583 [ # # ]: 0 : if (!txq) {
584 : 0 : PMD_DRV_LOG(ERR, "Allocate txq[%d] failed, dev_name: %s",
585 : : queue_idx, dev->data->name);
586 : 0 : return -ENOMEM;
587 : : }
588 : 0 : nic_dev->txqs[queue_idx] = txq;
589 : :
590 : : /* alloc tx sq hw wqepage */
591 : 0 : rc = hinic_create_sq(hwdev, queue_idx, sq_depth, socket_id);
592 [ # # ]: 0 : if (rc) {
593 : 0 : PMD_DRV_LOG(ERR, "Create txq[%d] failed, dev_name: %s, sq_depth: %d",
594 : : queue_idx, dev->data->name, sq_depth);
595 : 0 : goto create_sq_fail;
596 : : }
597 : :
598 : 0 : txq->q_id = queue_idx;
599 : 0 : txq->q_depth = sq_depth;
600 : 0 : txq->port_id = dev->data->port_id;
601 : 0 : txq->tx_free_thresh = tx_free_thresh;
602 : 0 : txq->nic_dev = nic_dev;
603 : 0 : txq->wq = &hwdev->nic_io->sq_wq[queue_idx];
604 : 0 : txq->sq = &hwdev->nic_io->qps[queue_idx].sq;
605 : 0 : txq->cons_idx_addr = hwdev->nic_io->qps[queue_idx].sq.cons_idx_addr;
606 : 0 : txq->sq_head_addr = HINIC_GET_WQ_HEAD(txq);
607 : 0 : txq->sq_bot_sge_addr = HINIC_GET_WQ_TAIL(txq) -
608 : : sizeof(struct hinic_sq_bufdesc);
609 : 0 : txq->cos = nic_dev->default_cos;
610 : 0 : txq->socket_id = socket_id;
611 : :
612 : : /* alloc software txinfo */
613 : 0 : rc = hinic_setup_tx_resources(txq);
614 [ # # ]: 0 : if (rc) {
615 : 0 : PMD_DRV_LOG(ERR, "Setup txq[%d] tx_resources failed, dev_name: %s",
616 : : queue_idx, dev->data->name);
617 : 0 : goto setup_tx_res_fail;
618 : : }
619 : :
620 : : /* record nic_dev txq in rte_eth tx_queues */
621 : 0 : dev->data->tx_queues[queue_idx] = txq;
622 : :
623 : 0 : return HINIC_OK;
624 : :
625 : : setup_tx_res_fail:
626 : 0 : hinic_destroy_sq(hwdev, queue_idx);
627 : :
628 : 0 : create_sq_fail:
629 : 0 : rte_free(txq);
630 : :
631 : 0 : return rc;
632 : : }
633 : :
634 : 0 : static void hinic_reset_tx_queue(struct rte_eth_dev *dev)
635 : : {
636 : : struct hinic_nic_dev *nic_dev;
637 : : struct hinic_txq *txq;
638 : : struct hinic_nic_io *nic_io;
639 : : struct hinic_hwdev *hwdev;
640 : : volatile u32 *ci_addr;
641 : : int q_id = 0;
642 : :
643 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
644 : 0 : hwdev = nic_dev->hwdev;
645 : 0 : nic_io = hwdev->nic_io;
646 : :
647 [ # # ]: 0 : for (q_id = 0; q_id < nic_dev->num_sq; q_id++) {
648 : 0 : txq = dev->data->tx_queues[q_id];
649 : :
650 : 0 : txq->wq->cons_idx = 0;
651 : 0 : txq->wq->prod_idx = 0;
652 : 0 : txq->wq->delta = txq->q_depth;
653 : 0 : txq->wq->mask = txq->q_depth - 1;
654 : :
655 : : /* clear hardware ci */
656 : 0 : ci_addr = (volatile u32 *)HINIC_CI_VADDR(nic_io->ci_vaddr_base,
657 : : q_id);
658 : 0 : *ci_addr = 0;
659 : : }
660 : 0 : }
661 : :
662 : : /**
663 : : * Get link speed from NIC.
664 : : *
665 : : * @param dev
666 : : * Pointer to Ethernet device structure.
667 : : * @param speed_capa
668 : : * Pointer to link speed structure.
669 : : */
670 : 0 : static void hinic_get_speed_capa(struct rte_eth_dev *dev, uint32_t *speed_capa)
671 : : {
672 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
673 : : u32 supported_link, advertised_link;
674 : : int err;
675 : :
676 : : #define HINIC_LINK_MODE_SUPPORT_1G (1U << HINIC_GE_BASE_KX)
677 : :
678 : : #define HINIC_LINK_MODE_SUPPORT_10G (1U << HINIC_10GE_BASE_KR)
679 : :
680 : : #define HINIC_LINK_MODE_SUPPORT_25G ((1U << HINIC_25GE_BASE_KR_S) | \
681 : : (1U << HINIC_25GE_BASE_CR_S) | \
682 : : (1U << HINIC_25GE_BASE_KR) | \
683 : : (1U << HINIC_25GE_BASE_CR))
684 : :
685 : : #define HINIC_LINK_MODE_SUPPORT_40G ((1U << HINIC_40GE_BASE_KR4) | \
686 : : (1U << HINIC_40GE_BASE_CR4))
687 : :
688 : : #define HINIC_LINK_MODE_SUPPORT_100G ((1U << HINIC_100GE_BASE_KR4) | \
689 : : (1U << HINIC_100GE_BASE_CR4))
690 : :
691 : 0 : err = hinic_get_link_mode(nic_dev->hwdev,
692 : : &supported_link, &advertised_link);
693 [ # # # # ]: 0 : if (err || supported_link == HINIC_SUPPORTED_UNKNOWN ||
694 [ # # ]: 0 : advertised_link == HINIC_SUPPORTED_UNKNOWN) {
695 : 0 : PMD_DRV_LOG(WARNING, "Get speed capability info failed, device: %s, port_id: %u",
696 : : nic_dev->proc_dev_name, dev->data->port_id);
697 : : } else {
698 : 0 : *speed_capa = 0;
699 [ # # ]: 0 : if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_1G))
700 : 0 : *speed_capa |= RTE_ETH_LINK_SPEED_1G;
701 [ # # ]: 0 : if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_10G))
702 : 0 : *speed_capa |= RTE_ETH_LINK_SPEED_10G;
703 [ # # ]: 0 : if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_25G))
704 : 0 : *speed_capa |= RTE_ETH_LINK_SPEED_25G;
705 [ # # ]: 0 : if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_40G))
706 : 0 : *speed_capa |= RTE_ETH_LINK_SPEED_40G;
707 [ # # ]: 0 : if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_100G))
708 : 0 : *speed_capa |= RTE_ETH_LINK_SPEED_100G;
709 : : }
710 : 0 : }
711 : :
712 : : /**
713 : : * DPDK callback to get information about the device.
714 : : *
715 : : * @param dev
716 : : * Pointer to Ethernet device structure.
717 : : * @param info
718 : : * Pointer to Info structure output buffer.
719 : : */
720 : : static int
721 : 0 : hinic_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
722 : : {
723 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
724 : :
725 : 0 : info->max_rx_queues = nic_dev->nic_cap.max_rqs;
726 : 0 : info->max_tx_queues = nic_dev->nic_cap.max_sqs;
727 : 0 : info->min_rx_bufsize = HINIC_MIN_RX_BUF_SIZE;
728 : 0 : info->max_rx_pktlen = HINIC_MAX_JUMBO_FRAME_SIZE;
729 : 0 : info->max_mac_addrs = HINIC_MAX_UC_MAC_ADDRS;
730 : 0 : info->min_mtu = HINIC_MIN_MTU_SIZE;
731 : 0 : info->max_mtu = HINIC_MAX_MTU_SIZE;
732 : 0 : info->max_lro_pkt_size = HINIC_MAX_LRO_SIZE;
733 : :
734 : 0 : hinic_get_speed_capa(dev, &info->speed_capa);
735 : 0 : info->rx_queue_offload_capa = 0;
736 : 0 : info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
737 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
738 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
739 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
740 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
741 : : RTE_ETH_RX_OFFLOAD_SCATTER |
742 : : RTE_ETH_RX_OFFLOAD_TCP_LRO |
743 : : RTE_ETH_RX_OFFLOAD_RSS_HASH;
744 : :
745 : 0 : info->tx_queue_offload_capa = 0;
746 : 0 : info->tx_offload_capa = RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
747 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
748 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
749 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
750 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
751 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
752 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
753 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
754 : :
755 : 0 : info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
756 : :
757 : 0 : info->hash_key_size = HINIC_RSS_KEY_SIZE;
758 : 0 : info->reta_size = HINIC_RSS_INDIR_SIZE;
759 : 0 : info->flow_type_rss_offloads = HINIC_RSS_OFFLOAD_ALL;
760 : 0 : info->rx_desc_lim = hinic_rx_desc_lim;
761 : 0 : info->tx_desc_lim = hinic_tx_desc_lim;
762 : :
763 : : /* Driver-preferred Rx/Tx parameters */
764 : 0 : info->default_rxportconf.burst_size = HINIC_DEFAULT_BURST_SIZE;
765 : 0 : info->default_txportconf.burst_size = HINIC_DEFAULT_BURST_SIZE;
766 : 0 : info->default_rxportconf.nb_queues = HINIC_DEFAULT_NB_QUEUES;
767 : 0 : info->default_txportconf.nb_queues = HINIC_DEFAULT_NB_QUEUES;
768 : 0 : info->default_rxportconf.ring_size = HINIC_DEFAULT_RING_SIZE;
769 : 0 : info->default_txportconf.ring_size = HINIC_DEFAULT_RING_SIZE;
770 : :
771 : 0 : return 0;
772 : : }
773 : :
774 : 0 : static int hinic_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
775 : : size_t fw_size)
776 : : {
777 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
778 : 0 : char fw_ver[HINIC_MGMT_VERSION_MAX_LEN] = {0};
779 : : int err;
780 : :
781 : 0 : err = hinic_get_mgmt_version(nic_dev->hwdev, fw_ver);
782 [ # # ]: 0 : if (err) {
783 : 0 : PMD_DRV_LOG(ERR, "Failed to get fw version");
784 : 0 : return -EINVAL;
785 : : }
786 : :
787 [ # # ]: 0 : if (fw_size < strlen(fw_ver) + 1)
788 : 0 : return (strlen(fw_ver) + 1);
789 : :
790 : : snprintf(fw_version, fw_size, "%s", fw_ver);
791 : :
792 : 0 : return 0;
793 : : }
794 : :
795 : 0 : static int hinic_config_rx_mode(struct hinic_nic_dev *nic_dev, u32 rx_mode_ctrl)
796 : : {
797 : : int err;
798 : :
799 : 0 : err = hinic_set_rx_mode(nic_dev->hwdev, rx_mode_ctrl);
800 [ # # ]: 0 : if (err) {
801 : 0 : PMD_DRV_LOG(ERR, "Failed to set rx mode");
802 : 0 : return -EINVAL;
803 : : }
804 : 0 : nic_dev->rx_mode_status = rx_mode_ctrl;
805 : :
806 : 0 : return 0;
807 : : }
808 : :
809 : 0 : static int hinic_rxtx_configure(struct rte_eth_dev *dev)
810 : : {
811 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
812 : : int err;
813 : :
814 : : /* rx configure, if rss enable, need to init default configuration */
815 : 0 : err = hinic_rx_configure(dev);
816 [ # # ]: 0 : if (err) {
817 : 0 : PMD_DRV_LOG(ERR, "Configure rss failed");
818 : 0 : return err;
819 : : }
820 : :
821 : : /* rx mode init */
822 : 0 : err = hinic_config_rx_mode(nic_dev, HINIC_DEFAULT_RX_MODE);
823 [ # # ]: 0 : if (err) {
824 : 0 : PMD_DRV_LOG(ERR, "Configure rx_mode:0x%x failed",
825 : : HINIC_DEFAULT_RX_MODE);
826 : 0 : goto set_rx_mode_fail;
827 : : }
828 : :
829 : : return HINIC_OK;
830 : :
831 : : set_rx_mode_fail:
832 : 0 : hinic_rx_remove_configure(dev);
833 : :
834 : 0 : return err;
835 : : }
836 : :
837 : 0 : static void hinic_remove_rxtx_configure(struct rte_eth_dev *dev)
838 : : {
839 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
840 : :
841 : 0 : (void)hinic_config_rx_mode(nic_dev, 0);
842 : 0 : hinic_rx_remove_configure(dev);
843 : 0 : }
844 : :
845 : 0 : static int hinic_priv_get_dev_link_status(struct hinic_nic_dev *nic_dev,
846 : : struct rte_eth_link *link)
847 : : {
848 : : int rc;
849 : 0 : u8 port_link_status = 0;
850 : : struct nic_port_info port_link_info;
851 : 0 : struct hinic_hwdev *nic_hwdev = nic_dev->hwdev;
852 : 0 : uint32_t port_speed[LINK_SPEED_MAX] = {RTE_ETH_SPEED_NUM_10M,
853 : : RTE_ETH_SPEED_NUM_100M, RTE_ETH_SPEED_NUM_1G,
854 : : RTE_ETH_SPEED_NUM_10G, RTE_ETH_SPEED_NUM_25G,
855 : : RTE_ETH_SPEED_NUM_40G, RTE_ETH_SPEED_NUM_100G};
856 : :
857 : 0 : rc = hinic_get_link_status(nic_hwdev, &port_link_status);
858 [ # # ]: 0 : if (rc)
859 : : return rc;
860 : :
861 [ # # ]: 0 : if (!port_link_status) {
862 : 0 : link->link_status = RTE_ETH_LINK_DOWN;
863 : 0 : link->link_speed = 0;
864 : 0 : link->link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
865 : 0 : link->link_autoneg = RTE_ETH_LINK_FIXED;
866 : 0 : return HINIC_OK;
867 : : }
868 : :
869 : : memset(&port_link_info, 0, sizeof(port_link_info));
870 : 0 : rc = hinic_get_port_info(nic_hwdev, &port_link_info);
871 [ # # ]: 0 : if (rc)
872 : : return rc;
873 : :
874 : 0 : link->link_speed = port_speed[port_link_info.speed % LINK_SPEED_MAX];
875 : 0 : link->link_duplex = port_link_info.duplex;
876 : 0 : link->link_autoneg = port_link_info.autoneg_state;
877 : 0 : link->link_status = port_link_status;
878 : :
879 : 0 : return HINIC_OK;
880 : : }
881 : :
882 : : /**
883 : : * DPDK callback to retrieve physical link information.
884 : : *
885 : : * @param dev
886 : : * Pointer to Ethernet device structure.
887 : : * @param wait_to_complete
888 : : * Wait for request completion.
889 : : *
890 : : * @return
891 : : * 0 link status changed, -1 link status not changed
892 : : */
893 : 0 : static int hinic_link_update(struct rte_eth_dev *dev, int wait_to_complete)
894 : : {
895 : : #define CHECK_INTERVAL 10 /* 10ms */
896 : : #define MAX_REPEAT_TIME 100 /* 1s (100 * 10ms) in total */
897 : : int rc = HINIC_OK;
898 : : struct rte_eth_link link;
899 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
900 : : unsigned int rep_cnt = MAX_REPEAT_TIME;
901 : :
902 : : memset(&link, 0, sizeof(link));
903 : : do {
904 : : /* Get link status information from hardware */
905 : 0 : rc = hinic_priv_get_dev_link_status(nic_dev, &link);
906 [ # # ]: 0 : if (rc != HINIC_OK) {
907 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
908 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
909 : 0 : PMD_DRV_LOG(ERR, "Get link status failed");
910 : 0 : goto out;
911 : : }
912 : :
913 [ # # # # ]: 0 : if (!wait_to_complete || link.link_status)
914 : : break;
915 : :
916 : : rte_delay_ms(CHECK_INTERVAL);
917 [ # # ]: 0 : } while (rep_cnt--);
918 : :
919 [ # # ]: 0 : out:
920 : : rc = rte_eth_linkstatus_set(dev, &link);
921 : 0 : return rc;
922 : : }
923 : :
924 : : /**
925 : : * DPDK callback to bring the link UP.
926 : : *
927 : : * @param dev
928 : : * Pointer to Ethernet device structure.
929 : : *
930 : : * @return
931 : : * 0 on success, negative errno value on failure.
932 : : */
933 : 0 : static int hinic_dev_set_link_up(struct rte_eth_dev *dev)
934 : : {
935 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
936 : : int ret;
937 : :
938 : : /* link status follow phy port status, up will open pma */
939 : 0 : ret = hinic_set_port_enable(nic_dev->hwdev, true);
940 [ # # ]: 0 : if (ret)
941 : 0 : PMD_DRV_LOG(ERR, "Set mac link up failed, dev_name: %s, port_id: %d",
942 : : nic_dev->proc_dev_name, dev->data->port_id);
943 : :
944 : 0 : return ret;
945 : : }
946 : :
947 : : /**
948 : : * DPDK callback to bring the link DOWN.
949 : : *
950 : : * @param dev
951 : : * Pointer to Ethernet device structure.
952 : : *
953 : : * @return
954 : : * 0 on success, negative errno value on failure.
955 : : */
956 : 0 : static int hinic_dev_set_link_down(struct rte_eth_dev *dev)
957 : : {
958 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
959 : : int ret;
960 : :
961 : : /* link status follow phy port status, up will close pma */
962 : 0 : ret = hinic_set_port_enable(nic_dev->hwdev, false);
963 [ # # ]: 0 : if (ret)
964 : 0 : PMD_DRV_LOG(ERR, "Set mac link down failed, dev_name: %s, port_id: %d",
965 : : nic_dev->proc_dev_name, dev->data->port_id);
966 : :
967 : 0 : return ret;
968 : : }
969 : :
970 : : /**
971 : : * DPDK callback to start the device.
972 : : *
973 : : * @param dev
974 : : * Pointer to Ethernet device structure.
975 : : *
976 : : * @return
977 : : * 0 on success, negative errno value on failure.
978 : : */
979 : 0 : static int hinic_dev_start(struct rte_eth_dev *dev)
980 : : {
981 : : int rc;
982 : : char *name;
983 : : struct hinic_nic_dev *nic_dev;
984 : : uint16_t i;
985 : :
986 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
987 : 0 : name = dev->data->name;
988 : :
989 : : /* reset rx and tx queue */
990 : 0 : hinic_reset_rx_queue(dev);
991 : 0 : hinic_reset_tx_queue(dev);
992 : :
993 : : /* get func rx buf size */
994 : 0 : hinic_get_func_rx_buf_size(nic_dev);
995 : :
996 : : /* init txq and rxq context */
997 : 0 : rc = hinic_init_qp_ctxts(nic_dev->hwdev);
998 [ # # ]: 0 : if (rc) {
999 : 0 : PMD_DRV_LOG(ERR, "Initialize qp context failed, dev_name: %s",
1000 : : name);
1001 : 0 : goto init_qp_fail;
1002 : : }
1003 : :
1004 : : /* rss template */
1005 : 0 : rc = hinic_config_mq_mode(dev, TRUE);
1006 [ # # ]: 0 : if (rc) {
1007 : 0 : PMD_DRV_LOG(ERR, "Configure mq mode failed, dev_name: %s",
1008 : : name);
1009 : 0 : goto cfg_mq_mode_fail;
1010 : : }
1011 : :
1012 : : /* set default mtu */
1013 : 0 : rc = hinic_set_port_mtu(nic_dev->hwdev, nic_dev->mtu_size);
1014 [ # # ]: 0 : if (rc) {
1015 : 0 : PMD_DRV_LOG(ERR, "Set mtu_size[%d] failed, dev_name: %s",
1016 : : nic_dev->mtu_size, name);
1017 : 0 : goto set_mtu_fail;
1018 : : }
1019 : :
1020 : : /* configure rss rx_mode and other rx or tx default feature */
1021 : 0 : rc = hinic_rxtx_configure(dev);
1022 [ # # ]: 0 : if (rc) {
1023 : 0 : PMD_DRV_LOG(ERR, "Configure tx and rx failed, dev_name: %s",
1024 : : name);
1025 : 0 : goto cfg_rxtx_fail;
1026 : : }
1027 : :
1028 : : /* reactive pf status, so that uP report asyn event */
1029 : 0 : hinic_set_pf_status(nic_dev->hwdev->hwif, HINIC_PF_STATUS_ACTIVE_FLAG);
1030 : :
1031 : : /* open virtual port and ready to start packet receiving */
1032 : 0 : rc = hinic_set_vport_enable(nic_dev->hwdev, true);
1033 [ # # ]: 0 : if (rc) {
1034 : 0 : PMD_DRV_LOG(ERR, "Enable vport failed, dev_name:%s", name);
1035 : 0 : goto en_vport_fail;
1036 : : }
1037 : :
1038 : : /* open physical port and start packet receiving */
1039 : 0 : rc = hinic_set_port_enable(nic_dev->hwdev, true);
1040 [ # # ]: 0 : if (rc) {
1041 : 0 : PMD_DRV_LOG(ERR, "Enable physical port failed, dev_name: %s",
1042 : : name);
1043 : 0 : goto en_port_fail;
1044 : : }
1045 : :
1046 : : /* update eth_dev link status */
1047 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.lsc != 0)
1048 : 0 : (void)hinic_link_update(dev, 0);
1049 : :
1050 : : rte_bit_relaxed_set32(HINIC_DEV_START, &nic_dev->dev_status);
1051 : :
1052 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
1053 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
1054 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
1055 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
1056 : :
1057 : : return 0;
1058 : :
1059 : : en_port_fail:
1060 : 0 : (void)hinic_set_vport_enable(nic_dev->hwdev, false);
1061 : :
1062 : 0 : en_vport_fail:
1063 : 0 : hinic_set_pf_status(nic_dev->hwdev->hwif, HINIC_PF_STATUS_INIT);
1064 : :
1065 : : /* Flush tx && rx chip resources in case of set vport fake fail */
1066 : 0 : (void)hinic_flush_qp_res(nic_dev->hwdev);
1067 : : rte_delay_ms(100);
1068 : :
1069 : 0 : hinic_remove_rxtx_configure(dev);
1070 : :
1071 : 0 : cfg_rxtx_fail:
1072 : 0 : set_mtu_fail:
1073 : 0 : cfg_mq_mode_fail:
1074 : 0 : hinic_free_qp_ctxts(nic_dev->hwdev);
1075 : :
1076 : 0 : init_qp_fail:
1077 : 0 : hinic_free_all_rx_mbuf(dev);
1078 : 0 : hinic_free_all_tx_mbuf(dev);
1079 : :
1080 : 0 : return rc;
1081 : : }
1082 : :
1083 : : /**
1084 : : * DPDK callback to release the receive queue.
1085 : : *
1086 : : * @param dev
1087 : : * Pointer to Ethernet device structure.
1088 : : * @param qid
1089 : : * Receive queue index.
1090 : : */
1091 : 0 : static void hinic_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
1092 : : {
1093 : 0 : struct hinic_rxq *rxq = dev->data->rx_queues[qid];
1094 : : struct hinic_nic_dev *nic_dev;
1095 : :
1096 [ # # ]: 0 : if (!rxq) {
1097 : 0 : PMD_DRV_LOG(WARNING, "Rxq is null when release");
1098 : 0 : return;
1099 : : }
1100 : 0 : nic_dev = rxq->nic_dev;
1101 : :
1102 : : /* free rxq_pkt mbuf */
1103 : 0 : hinic_free_all_rx_mbufs(rxq);
1104 : :
1105 : : /* free rxq_cqe, rxq_info */
1106 : 0 : hinic_free_rx_resources(rxq);
1107 : :
1108 : : /* free root rq wq */
1109 : 0 : hinic_destroy_rq(nic_dev->hwdev, rxq->q_id);
1110 : :
1111 : 0 : nic_dev->rxqs[rxq->q_id] = NULL;
1112 : :
1113 : : /* free rxq */
1114 : 0 : rte_free(rxq);
1115 : : }
1116 : :
1117 : : /**
1118 : : * DPDK callback to release the transmit queue.
1119 : : *
1120 : : * @param dev
1121 : : * Pointer to Ethernet device structure.
1122 : : * @param qid
1123 : : * Transmit queue index.
1124 : : */
1125 : 0 : static void hinic_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
1126 : : {
1127 : 0 : struct hinic_txq *txq = dev->data->tx_queues[qid];
1128 : : struct hinic_nic_dev *nic_dev;
1129 : :
1130 [ # # ]: 0 : if (!txq) {
1131 : 0 : PMD_DRV_LOG(WARNING, "Txq is null when release");
1132 : 0 : return;
1133 : : }
1134 : 0 : nic_dev = txq->nic_dev;
1135 : :
1136 : : /* free txq_pkt mbuf */
1137 : 0 : hinic_free_all_tx_mbufs(txq);
1138 : :
1139 : : /* free txq_info */
1140 : 0 : hinic_free_tx_resources(txq);
1141 : :
1142 : : /* free root sq wq */
1143 : 0 : hinic_destroy_sq(nic_dev->hwdev, txq->q_id);
1144 : 0 : nic_dev->txqs[txq->q_id] = NULL;
1145 : :
1146 : : /* free txq */
1147 : 0 : rte_free(txq);
1148 : : }
1149 : :
1150 : : static void hinic_free_all_rq(struct hinic_nic_dev *nic_dev)
1151 : : {
1152 : : u16 q_id;
1153 : :
1154 [ # # ]: 0 : for (q_id = 0; q_id < nic_dev->num_rq; q_id++)
1155 : 0 : hinic_destroy_rq(nic_dev->hwdev, q_id);
1156 : : }
1157 : :
1158 : : static void hinic_free_all_sq(struct hinic_nic_dev *nic_dev)
1159 : : {
1160 : : u16 q_id;
1161 : :
1162 [ # # ]: 0 : for (q_id = 0; q_id < nic_dev->num_sq; q_id++)
1163 : 0 : hinic_destroy_sq(nic_dev->hwdev, q_id);
1164 : : }
1165 : :
1166 : : /**
1167 : : * DPDK callback to stop the device.
1168 : : *
1169 : : * @param dev
1170 : : * Pointer to Ethernet device structure.
1171 : : */
1172 : 0 : static int hinic_dev_stop(struct rte_eth_dev *dev)
1173 : : {
1174 : : int rc;
1175 : : char *name;
1176 : : uint16_t port_id;
1177 : : struct hinic_nic_dev *nic_dev;
1178 : : struct rte_eth_link link;
1179 : : uint16_t i;
1180 : :
1181 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1182 : 0 : name = dev->data->name;
1183 : 0 : port_id = dev->data->port_id;
1184 : :
1185 [ # # ]: 0 : dev->data->dev_started = 0;
1186 : :
1187 [ # # ]: 0 : if (!rte_bit_relaxed_test_and_clear32(HINIC_DEV_START,
1188 : : &nic_dev->dev_status)) {
1189 : 0 : PMD_DRV_LOG(INFO, "Device %s already stopped", name);
1190 : 0 : return 0;
1191 : : }
1192 : :
1193 : : /* just stop phy port and vport */
1194 : 0 : rc = hinic_set_port_enable(nic_dev->hwdev, false);
1195 [ # # ]: 0 : if (rc)
1196 : 0 : PMD_DRV_LOG(WARNING, "Disable phy port failed, error: %d, dev_name: %s, port_id: %d",
1197 : : rc, name, port_id);
1198 : :
1199 : 0 : rc = hinic_set_vport_enable(nic_dev->hwdev, false);
1200 [ # # ]: 0 : if (rc)
1201 : 0 : PMD_DRV_LOG(WARNING, "Disable vport failed, error: %d, dev_name: %s, port_id: %d",
1202 : : rc, name, port_id);
1203 : :
1204 : : /* Clear recorded link status */
1205 : : memset(&link, 0, sizeof(link));
1206 : 0 : (void)rte_eth_linkstatus_set(dev, &link);
1207 : :
1208 : : /* flush pending io request */
1209 : 0 : rc = hinic_rx_tx_flush(nic_dev->hwdev);
1210 [ # # ]: 0 : if (rc)
1211 : 0 : PMD_DRV_LOG(WARNING, "Flush pending io failed, error: %d, dev_name: %s, port_id: %d",
1212 : : rc, name, port_id);
1213 : :
1214 : : /* clean rss table and rx_mode */
1215 : 0 : hinic_remove_rxtx_configure(dev);
1216 : :
1217 : : /* clean root context */
1218 : 0 : hinic_free_qp_ctxts(nic_dev->hwdev);
1219 : :
1220 : 0 : hinic_destroy_fdir_filter(dev);
1221 : :
1222 : : /* free mbuf */
1223 : 0 : hinic_free_all_rx_mbuf(dev);
1224 : 0 : hinic_free_all_tx_mbuf(dev);
1225 : :
1226 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
1227 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1228 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
1229 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1230 : :
1231 : : return 0;
1232 : : }
1233 : :
1234 : 0 : static void hinic_disable_interrupt(struct rte_eth_dev *dev)
1235 : : {
1236 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1237 : 0 : struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
1238 : : int ret, retries = 0;
1239 : :
1240 : : rte_bit_relaxed_clear32(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
1241 : :
1242 : : /* disable msix interrupt in hardware */
1243 : 0 : hinic_set_msix_state(nic_dev->hwdev, 0, HINIC_MSIX_DISABLE);
1244 : :
1245 : : /* disable rte interrupt */
1246 : 0 : ret = rte_intr_disable(pci_dev->intr_handle);
1247 [ # # ]: 0 : if (ret)
1248 : 0 : PMD_DRV_LOG(ERR, "Disable intr failed: %d", ret);
1249 : :
1250 : : do {
1251 : : ret =
1252 : 0 : rte_intr_callback_unregister(pci_dev->intr_handle,
1253 : : hinic_dev_interrupt_handler, dev);
1254 [ # # ]: 0 : if (ret >= 0) {
1255 : : break;
1256 [ # # ]: 0 : } else if (ret == -EAGAIN) {
1257 : : rte_delay_ms(100);
1258 : 0 : retries++;
1259 : : } else {
1260 : 0 : PMD_DRV_LOG(ERR, "intr callback unregister failed: %d",
1261 : : ret);
1262 : 0 : break;
1263 : : }
1264 [ # # ]: 0 : } while (retries < HINIC_INTR_CB_UNREG_MAX_RETRIES);
1265 : :
1266 [ # # ]: 0 : if (retries == HINIC_INTR_CB_UNREG_MAX_RETRIES)
1267 : 0 : PMD_DRV_LOG(ERR, "Unregister intr callback failed after %d retries",
1268 : : retries);
1269 : :
1270 : : rte_bit_relaxed_clear32(HINIC_DEV_INIT, &nic_dev->dev_status);
1271 : 0 : }
1272 : :
1273 : 0 : static int hinic_set_dev_promiscuous(struct hinic_nic_dev *nic_dev, bool enable)
1274 : : {
1275 : : u32 rx_mode_ctrl;
1276 : : int err;
1277 : :
1278 : 0 : err = hinic_mutex_lock(&nic_dev->rx_mode_mutex);
1279 [ # # ]: 0 : if (err)
1280 : : return err;
1281 : :
1282 : 0 : rx_mode_ctrl = nic_dev->rx_mode_status;
1283 : :
1284 [ # # ]: 0 : if (enable)
1285 : 0 : rx_mode_ctrl |= HINIC_RX_MODE_PROMISC;
1286 : : else
1287 : 0 : rx_mode_ctrl &= (~HINIC_RX_MODE_PROMISC);
1288 : :
1289 : 0 : err = hinic_config_rx_mode(nic_dev, rx_mode_ctrl);
1290 : :
1291 : : (void)hinic_mutex_unlock(&nic_dev->rx_mode_mutex);
1292 : :
1293 : 0 : return err;
1294 : : }
1295 : :
1296 : : /**
1297 : : * DPDK callback to get device statistics.
1298 : : *
1299 : : * @param dev
1300 : : * Pointer to Ethernet device structure.
1301 : : * @param stats
1302 : : * Stats structure output buffer.
1303 : : *
1304 : : * @return
1305 : : * 0 on success and stats is filled,
1306 : : * negative error value otherwise.
1307 : : */
1308 : : static int
1309 : 0 : hinic_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
1310 : : struct eth_queue_stats *qstats)
1311 : : {
1312 : : int i, err, q_num;
1313 : : u64 rx_discards_pmd = 0;
1314 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1315 : : struct hinic_vport_stats vport_stats;
1316 : : struct hinic_rxq *rxq = NULL;
1317 : : struct hinic_rxq_stats rxq_stats;
1318 : : struct hinic_txq *txq = NULL;
1319 : : struct hinic_txq_stats txq_stats;
1320 : :
1321 : 0 : err = hinic_get_vport_stats(nic_dev->hwdev, &vport_stats);
1322 [ # # ]: 0 : if (err) {
1323 : 0 : PMD_DRV_LOG(ERR, "Get vport stats from fw failed, nic_dev: %s",
1324 : : nic_dev->proc_dev_name);
1325 : 0 : return err;
1326 : : }
1327 : :
1328 : 0 : dev->data->rx_mbuf_alloc_failed = 0;
1329 : :
1330 : : /* rx queue stats */
1331 [ # # ]: 0 : if (qstats) {
1332 : 0 : q_num = (nic_dev->num_rq < dev->data->nb_rx_queues) ?
1333 : 0 : nic_dev->num_rq : dev->data->nb_rx_queues;
1334 [ # # ]: 0 : for (i = 0; i < q_num; i++) {
1335 : 0 : rxq = nic_dev->rxqs[i];
1336 : 0 : hinic_rxq_get_stats(rxq, &rxq_stats);
1337 : 0 : qstats[i].q_ipackets = rxq_stats.packets;
1338 : 0 : qstats[i].q_ibytes = rxq_stats.bytes;
1339 : :
1340 : 0 : stats->ierrors += rxq_stats.errors;
1341 : 0 : rx_discards_pmd += rxq_stats.rx_discards;
1342 : 0 : dev->data->rx_mbuf_alloc_failed += rxq_stats.rx_nombuf;
1343 : : }
1344 : :
1345 : : /* tx queue stats */
1346 : 0 : q_num = (nic_dev->num_sq < dev->data->nb_tx_queues) ?
1347 : 0 : nic_dev->num_sq : dev->data->nb_tx_queues;
1348 [ # # ]: 0 : for (i = 0; i < q_num; i++) {
1349 : 0 : txq = nic_dev->txqs[i];
1350 : 0 : hinic_txq_get_stats(txq, &txq_stats);
1351 : 0 : qstats[i].q_opackets = txq_stats.packets;
1352 : 0 : qstats[i].q_obytes = txq_stats.bytes;
1353 : 0 : stats->oerrors += (txq_stats.tx_busy + txq_stats.off_errs);
1354 : : }
1355 : : } else {
1356 : : /* Still aggregate error stats even without qstats */
1357 [ # # ]: 0 : for (i = 0; i < nic_dev->num_rq; i++) {
1358 : 0 : rxq = nic_dev->rxqs[i];
1359 : 0 : hinic_rxq_get_stats(rxq, &rxq_stats);
1360 : 0 : stats->ierrors += rxq_stats.errors;
1361 : 0 : rx_discards_pmd += rxq_stats.rx_discards;
1362 : 0 : dev->data->rx_mbuf_alloc_failed += rxq_stats.rx_nombuf;
1363 : : }
1364 [ # # ]: 0 : for (i = 0; i < nic_dev->num_sq; i++) {
1365 : 0 : txq = nic_dev->txqs[i];
1366 : 0 : hinic_txq_get_stats(txq, &txq_stats);
1367 : 0 : stats->oerrors += (txq_stats.tx_busy + txq_stats.off_errs);
1368 : : }
1369 : : }
1370 : :
1371 : : /* vport stats */
1372 : 0 : stats->oerrors += vport_stats.tx_discard_vport;
1373 : :
1374 : 0 : stats->imissed = vport_stats.rx_discard_vport + rx_discards_pmd;
1375 : :
1376 : 0 : stats->ipackets = (vport_stats.rx_unicast_pkts_vport +
1377 : 0 : vport_stats.rx_multicast_pkts_vport +
1378 : 0 : vport_stats.rx_broadcast_pkts_vport -
1379 : : rx_discards_pmd);
1380 : :
1381 : 0 : stats->opackets = (vport_stats.tx_unicast_pkts_vport +
1382 : 0 : vport_stats.tx_multicast_pkts_vport +
1383 : 0 : vport_stats.tx_broadcast_pkts_vport);
1384 : :
1385 : 0 : stats->ibytes = (vport_stats.rx_unicast_bytes_vport +
1386 : 0 : vport_stats.rx_multicast_bytes_vport +
1387 : 0 : vport_stats.rx_broadcast_bytes_vport);
1388 : :
1389 : 0 : stats->obytes = (vport_stats.tx_unicast_bytes_vport +
1390 : 0 : vport_stats.tx_multicast_bytes_vport +
1391 : 0 : vport_stats.tx_broadcast_bytes_vport);
1392 : 0 : return 0;
1393 : : }
1394 : :
1395 : : /**
1396 : : * DPDK callback to clear device statistics.
1397 : : *
1398 : : * @param dev
1399 : : * Pointer to Ethernet device structure.
1400 : : */
1401 : 0 : static int hinic_dev_stats_reset(struct rte_eth_dev *dev)
1402 : : {
1403 : : int qid;
1404 : : struct hinic_rxq *rxq = NULL;
1405 : : struct hinic_txq *txq = NULL;
1406 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1407 : : int ret;
1408 : :
1409 : 0 : ret = hinic_clear_vport_stats(nic_dev->hwdev);
1410 [ # # ]: 0 : if (ret != 0)
1411 : : return ret;
1412 : :
1413 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_rq; qid++) {
1414 : 0 : rxq = nic_dev->rxqs[qid];
1415 : 0 : hinic_rxq_stats_reset(rxq);
1416 : : }
1417 : :
1418 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_sq; qid++) {
1419 : 0 : txq = nic_dev->txqs[qid];
1420 : 0 : hinic_txq_stats_reset(txq);
1421 : : }
1422 : :
1423 : : return 0;
1424 : : }
1425 : :
1426 : : /**
1427 : : * DPDK callback to clear device extended statistics.
1428 : : *
1429 : : * @param dev
1430 : : * Pointer to Ethernet device structure.
1431 : : */
1432 : 0 : static int hinic_dev_xstats_reset(struct rte_eth_dev *dev)
1433 : : {
1434 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1435 : : int ret;
1436 : :
1437 : 0 : ret = hinic_dev_stats_reset(dev);
1438 [ # # ]: 0 : if (ret != 0)
1439 : : return ret;
1440 : :
1441 [ # # ]: 0 : if (hinic_func_type(nic_dev->hwdev) != TYPE_VF) {
1442 : 0 : ret = hinic_clear_phy_port_stats(nic_dev->hwdev);
1443 [ # # ]: 0 : if (ret != 0)
1444 : 0 : return ret;
1445 : : }
1446 : :
1447 : : return 0;
1448 : : }
1449 : :
1450 : 0 : static void hinic_gen_random_mac_addr(struct rte_ether_addr *mac_addr)
1451 : : {
1452 : : uint64_t random_value;
1453 : :
1454 : : /* Set Organizationally Unique Identifier (OUI) prefix */
1455 : : mac_addr->addr_bytes[0] = 0x00;
1456 : 0 : mac_addr->addr_bytes[1] = 0x09;
1457 : 0 : mac_addr->addr_bytes[2] = 0xC0;
1458 : : /* Force indication of locally assigned MAC address. */
1459 : 0 : mac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;
1460 : : /* Generate the last 3 bytes of the MAC address with a random number. */
1461 : 0 : random_value = rte_rand();
1462 : 0 : memcpy(&mac_addr->addr_bytes[3], &random_value, 3);
1463 : 0 : }
1464 : :
1465 : : /**
1466 : : * Init mac_vlan table in NIC.
1467 : : *
1468 : : * @param dev
1469 : : * Pointer to Ethernet device structure.
1470 : : *
1471 : : * @return
1472 : : * 0 on success and stats is filled,
1473 : : * negative error value otherwise.
1474 : : */
1475 : 0 : static int hinic_init_mac_addr(struct rte_eth_dev *eth_dev)
1476 : : {
1477 : 0 : struct hinic_nic_dev *nic_dev =
1478 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
1479 : : uint8_t addr_bytes[RTE_ETHER_ADDR_LEN];
1480 : : u16 func_id = 0;
1481 : : int rc = 0;
1482 : :
1483 : 0 : rc = hinic_get_default_mac(nic_dev->hwdev, addr_bytes);
1484 [ # # ]: 0 : if (rc)
1485 : : return rc;
1486 : :
1487 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)addr_bytes,
1488 [ # # ]: 0 : ð_dev->data->mac_addrs[0]);
1489 [ # # ]: 0 : if (rte_is_zero_ether_addr(ð_dev->data->mac_addrs[0]))
1490 : 0 : hinic_gen_random_mac_addr(ð_dev->data->mac_addrs[0]);
1491 : :
1492 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1493 : 0 : rc = hinic_set_mac(nic_dev->hwdev,
1494 : 0 : eth_dev->data->mac_addrs[0].addr_bytes,
1495 : : 0, func_id);
1496 [ # # ]: 0 : if (rc && rc != HINIC_PF_SET_VF_ALREADY)
1497 : : return rc;
1498 : :
1499 : 0 : rte_ether_addr_copy(ð_dev->data->mac_addrs[0],
1500 : : &nic_dev->default_addr);
1501 : :
1502 : 0 : return 0;
1503 : : }
1504 : :
1505 : 0 : static void hinic_delete_mc_addr_list(struct hinic_nic_dev *nic_dev)
1506 : : {
1507 : : u16 func_id;
1508 : : u32 i;
1509 : :
1510 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1511 : :
1512 [ # # ]: 0 : for (i = 0; i < HINIC_MAX_MC_MAC_ADDRS; i++) {
1513 [ # # ]: 0 : if (rte_is_zero_ether_addr(&nic_dev->mc_list[i]))
1514 : : break;
1515 : :
1516 : 0 : hinic_del_mac(nic_dev->hwdev, nic_dev->mc_list[i].addr_bytes,
1517 : : 0, func_id);
1518 : 0 : memset(&nic_dev->mc_list[i], 0, sizeof(struct rte_ether_addr));
1519 : : }
1520 : 0 : }
1521 : :
1522 : : /**
1523 : : * Deinit mac_vlan table in NIC.
1524 : : *
1525 : : * @param dev
1526 : : * Pointer to Ethernet device structure.
1527 : : *
1528 : : * @return
1529 : : * 0 on success and stats is filled,
1530 : : * negative error value otherwise.
1531 : : */
1532 : 0 : static void hinic_deinit_mac_addr(struct rte_eth_dev *eth_dev)
1533 : : {
1534 : 0 : struct hinic_nic_dev *nic_dev =
1535 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
1536 : : u16 func_id = 0;
1537 : : int rc;
1538 : : int i;
1539 : :
1540 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1541 : :
1542 [ # # ]: 0 : for (i = 0; i < HINIC_MAX_UC_MAC_ADDRS; i++) {
1543 [ # # ]: 0 : if (rte_is_zero_ether_addr(ð_dev->data->mac_addrs[i]))
1544 : 0 : continue;
1545 : :
1546 : 0 : rc = hinic_del_mac(nic_dev->hwdev,
1547 : 0 : eth_dev->data->mac_addrs[i].addr_bytes,
1548 : : 0, func_id);
1549 [ # # ]: 0 : if (rc && rc != HINIC_PF_SET_VF_ALREADY)
1550 : 0 : PMD_DRV_LOG(ERR, "Delete mac table failed, dev_name: %s",
1551 : : eth_dev->data->name);
1552 : :
1553 : 0 : memset(ð_dev->data->mac_addrs[i], 0,
1554 : : sizeof(struct rte_ether_addr));
1555 : : }
1556 : :
1557 : : /* delete multicast mac addrs */
1558 : 0 : hinic_delete_mc_addr_list(nic_dev);
1559 : :
1560 : 0 : rte_free(nic_dev->mc_list);
1561 : :
1562 : 0 : }
1563 : :
1564 : 0 : static int hinic_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
1565 : : {
1566 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1567 : : int ret;
1568 : :
1569 : 0 : PMD_DRV_LOG(INFO, "Set port mtu, port_id: %d, mtu: %d, max_pkt_len: %d",
1570 : : dev->data->port_id, mtu, HINIC_MTU_TO_PKTLEN(mtu));
1571 : :
1572 : 0 : ret = hinic_set_port_mtu(nic_dev->hwdev, mtu);
1573 [ # # ]: 0 : if (ret) {
1574 : 0 : PMD_DRV_LOG(ERR, "Set port mtu failed, ret: %d", ret);
1575 : 0 : return ret;
1576 : : }
1577 : :
1578 : 0 : nic_dev->mtu_size = mtu;
1579 : :
1580 : 0 : return ret;
1581 : : }
1582 : :
1583 : : static void hinic_store_vlan_filter(struct hinic_nic_dev *nic_dev,
1584 : : u16 vlan_id, bool on)
1585 : : {
1586 : : u32 vid_idx, vid_bit;
1587 : :
1588 : 0 : vid_idx = HINIC_VFTA_IDX(vlan_id);
1589 : 0 : vid_bit = HINIC_VFTA_BIT(vlan_id);
1590 : :
1591 : 0 : if (on)
1592 : 0 : nic_dev->vfta[vid_idx] |= vid_bit;
1593 : : else
1594 : 0 : nic_dev->vfta[vid_idx] &= ~vid_bit;
1595 : : }
1596 : :
1597 : : static bool hinic_find_vlan_filter(struct hinic_nic_dev *nic_dev,
1598 : : uint16_t vlan_id)
1599 : : {
1600 : : u32 vid_idx, vid_bit;
1601 : :
1602 : 0 : vid_idx = HINIC_VFTA_IDX(vlan_id);
1603 : 0 : vid_bit = HINIC_VFTA_BIT(vlan_id);
1604 : :
1605 : 0 : return (nic_dev->vfta[vid_idx] & vid_bit) ? TRUE : FALSE;
1606 : : }
1607 : :
1608 : : /**
1609 : : * DPDK callback to set vlan filter.
1610 : : *
1611 : : * @param dev
1612 : : * Pointer to Ethernet device structure.
1613 : : * @param vlan_id
1614 : : * vlan id is used to filter vlan packets
1615 : : * @param enable
1616 : : * enable disable or enable vlan filter function
1617 : : */
1618 : 0 : static int hinic_vlan_filter_set(struct rte_eth_dev *dev,
1619 : : uint16_t vlan_id, int enable)
1620 : : {
1621 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1622 : : int err = 0;
1623 : : u16 func_id;
1624 : :
1625 [ # # ]: 0 : if (vlan_id > RTE_ETHER_MAX_VLAN_ID)
1626 : : return -EINVAL;
1627 : :
1628 [ # # ]: 0 : if (vlan_id == 0)
1629 : : return 0;
1630 : :
1631 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1632 : :
1633 [ # # ]: 0 : if (enable) {
1634 : : /* If vlanid is already set, just return */
1635 [ # # ]: 0 : if (hinic_find_vlan_filter(nic_dev, vlan_id)) {
1636 : 0 : PMD_DRV_LOG(INFO, "Vlan %u has been added, device: %s",
1637 : : vlan_id, nic_dev->proc_dev_name);
1638 : 0 : return 0;
1639 : : }
1640 : :
1641 : 0 : err = hinic_add_remove_vlan(nic_dev->hwdev, vlan_id,
1642 : : func_id, TRUE);
1643 : : } else {
1644 : : /* If vlanid can't be found, just return */
1645 [ # # ]: 0 : if (!hinic_find_vlan_filter(nic_dev, vlan_id)) {
1646 : 0 : PMD_DRV_LOG(INFO, "Vlan %u is not in the vlan filter list, device: %s",
1647 : : vlan_id, nic_dev->proc_dev_name);
1648 : 0 : return 0;
1649 : : }
1650 : :
1651 : 0 : err = hinic_add_remove_vlan(nic_dev->hwdev, vlan_id,
1652 : : func_id, FALSE);
1653 : : }
1654 : :
1655 [ # # ]: 0 : if (err) {
1656 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s vlan failed, func_id: %d, vlan_id: %d, err: %d",
1657 : : enable ? "Add" : "Remove", func_id, vlan_id, err);
1658 : 0 : return err;
1659 : : }
1660 : :
1661 [ # # ]: 0 : hinic_store_vlan_filter(nic_dev, vlan_id, enable);
1662 : :
1663 [ # # ]: 0 : PMD_DRV_LOG(INFO, "%s vlan %u succeed, device: %s",
1664 : : enable ? "Add" : "Remove", vlan_id, nic_dev->proc_dev_name);
1665 : 0 : return 0;
1666 : : }
1667 : :
1668 : : /**
1669 : : * DPDK callback to enable or disable vlan offload.
1670 : : *
1671 : : * @param dev
1672 : : * Pointer to Ethernet device structure.
1673 : : * @param mask
1674 : : * Definitions used for VLAN setting
1675 : : */
1676 : 0 : static int hinic_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1677 : : {
1678 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1679 : : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
1680 : : bool on;
1681 : : int err;
1682 : :
1683 : : /* Enable or disable VLAN filter */
1684 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
1685 : 0 : on = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) ?
1686 : 0 : TRUE : FALSE;
1687 : 0 : err = hinic_config_vlan_filter(nic_dev->hwdev, on);
1688 [ # # ]: 0 : if (err == HINIC_MGMT_CMD_UNSUPPORTED) {
1689 : 0 : PMD_DRV_LOG(WARNING,
1690 : : "Current matching version does not support vlan filter configuration, device: %s, port_id: %d",
1691 : : nic_dev->proc_dev_name, dev->data->port_id);
1692 [ # # ]: 0 : } else if (err) {
1693 [ # # ]: 0 : PMD_DRV_LOG(ERR, "Failed to %s vlan filter, device: %s, port_id: %d, err: %d",
1694 : : on ? "enable" : "disable",
1695 : : nic_dev->proc_dev_name,
1696 : : dev->data->port_id, err);
1697 : 0 : return err;
1698 : : }
1699 : :
1700 [ # # ]: 0 : PMD_DRV_LOG(INFO, "%s vlan filter succeed, device: %s, port_id: %d",
1701 : : on ? "Enable" : "Disable",
1702 : : nic_dev->proc_dev_name, dev->data->port_id);
1703 : : }
1704 : :
1705 : : /* Enable or disable VLAN stripping */
1706 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1707 : 0 : on = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) ?
1708 : 0 : TRUE : FALSE;
1709 : 0 : err = hinic_set_rx_vlan_offload(nic_dev->hwdev, on);
1710 [ # # ]: 0 : if (err) {
1711 [ # # ]: 0 : PMD_DRV_LOG(ERR, "Failed to %s vlan strip, device: %s, port_id: %d, err: %d",
1712 : : on ? "enable" : "disable",
1713 : : nic_dev->proc_dev_name,
1714 : : dev->data->port_id, err);
1715 : 0 : return err;
1716 : : }
1717 : :
1718 [ # # ]: 0 : PMD_DRV_LOG(INFO, "%s vlan strip succeed, device: %s, port_id: %d",
1719 : : on ? "Enable" : "Disable",
1720 : : nic_dev->proc_dev_name, dev->data->port_id);
1721 : : }
1722 : :
1723 : : return 0;
1724 : : }
1725 : :
1726 : 0 : static void hinic_remove_all_vlanid(struct rte_eth_dev *eth_dev)
1727 : : {
1728 : 0 : struct hinic_nic_dev *nic_dev =
1729 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
1730 : : u16 func_id;
1731 : : int i;
1732 : :
1733 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1734 [ # # ]: 0 : for (i = 0; i <= RTE_ETHER_MAX_VLAN_ID; i++) {
1735 : : /* If can't find it, continue */
1736 [ # # ]: 0 : if (!hinic_find_vlan_filter(nic_dev, i))
1737 : 0 : continue;
1738 : :
1739 : 0 : (void)hinic_add_remove_vlan(nic_dev->hwdev, i, func_id, FALSE);
1740 : : hinic_store_vlan_filter(nic_dev, i, false);
1741 : : }
1742 : 0 : }
1743 : :
1744 : 0 : static int hinic_set_dev_allmulticast(struct hinic_nic_dev *nic_dev,
1745 : : bool enable)
1746 : : {
1747 : : u32 rx_mode_ctrl;
1748 : : int err;
1749 : :
1750 : 0 : err = hinic_mutex_lock(&nic_dev->rx_mode_mutex);
1751 [ # # ]: 0 : if (err)
1752 : : return err;
1753 : :
1754 : 0 : rx_mode_ctrl = nic_dev->rx_mode_status;
1755 : :
1756 [ # # ]: 0 : if (enable)
1757 : 0 : rx_mode_ctrl |= HINIC_RX_MODE_MC_ALL;
1758 : : else
1759 : 0 : rx_mode_ctrl &= (~HINIC_RX_MODE_MC_ALL);
1760 : :
1761 : 0 : err = hinic_config_rx_mode(nic_dev, rx_mode_ctrl);
1762 : :
1763 : : (void)hinic_mutex_unlock(&nic_dev->rx_mode_mutex);
1764 : :
1765 : 0 : return err;
1766 : : }
1767 : :
1768 : : /**
1769 : : * DPDK callback to enable allmulticast mode.
1770 : : *
1771 : : * @param dev
1772 : : * Pointer to Ethernet device structure.
1773 : : *
1774 : : * @return
1775 : : * 0 on success,
1776 : : * negative error value otherwise.
1777 : : */
1778 : 0 : static int hinic_dev_allmulticast_enable(struct rte_eth_dev *dev)
1779 : : {
1780 : : int ret = HINIC_OK;
1781 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1782 : :
1783 : 0 : ret = hinic_set_dev_allmulticast(nic_dev, true);
1784 [ # # ]: 0 : if (ret) {
1785 : 0 : PMD_DRV_LOG(ERR, "Enable allmulticast failed, error: %d", ret);
1786 : 0 : return ret;
1787 : : }
1788 : :
1789 : 0 : PMD_DRV_LOG(INFO, "Enable allmulticast succeed, nic_dev: %s, port_id: %d",
1790 : : nic_dev->proc_dev_name, dev->data->port_id);
1791 : 0 : return 0;
1792 : : }
1793 : :
1794 : : /**
1795 : : * DPDK callback to disable allmulticast mode.
1796 : : *
1797 : : * @param dev
1798 : : * Pointer to Ethernet device structure.
1799 : : *
1800 : : * @return
1801 : : * 0 on success,
1802 : : * negative error value otherwise.
1803 : : */
1804 : 0 : static int hinic_dev_allmulticast_disable(struct rte_eth_dev *dev)
1805 : : {
1806 : : int ret = HINIC_OK;
1807 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1808 : :
1809 : 0 : ret = hinic_set_dev_allmulticast(nic_dev, false);
1810 [ # # ]: 0 : if (ret) {
1811 : 0 : PMD_DRV_LOG(ERR, "Disable allmulticast failed, error: %d", ret);
1812 : 0 : return ret;
1813 : : }
1814 : :
1815 : 0 : PMD_DRV_LOG(INFO, "Disable allmulticast succeed, nic_dev: %s, port_id: %d",
1816 : : nic_dev->proc_dev_name, dev->data->port_id);
1817 : 0 : return 0;
1818 : : }
1819 : :
1820 : : /**
1821 : : * DPDK callback to enable promiscuous mode.
1822 : : *
1823 : : * @param dev
1824 : : * Pointer to Ethernet device structure.
1825 : : *
1826 : : * @return
1827 : : * 0 on success,
1828 : : * negative error value otherwise.
1829 : : */
1830 : 0 : static int hinic_dev_promiscuous_enable(struct rte_eth_dev *dev)
1831 : : {
1832 : : int rc = HINIC_OK;
1833 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1834 : :
1835 : 0 : PMD_DRV_LOG(INFO, "Enable promiscuous, nic_dev: %s, port_id: %d, promisc: %d",
1836 : : nic_dev->proc_dev_name, dev->data->port_id,
1837 : : dev->data->promiscuous);
1838 : :
1839 : 0 : rc = hinic_set_dev_promiscuous(nic_dev, true);
1840 [ # # ]: 0 : if (rc)
1841 : 0 : PMD_DRV_LOG(ERR, "Enable promiscuous failed");
1842 : :
1843 : 0 : return rc;
1844 : : }
1845 : :
1846 : : /**
1847 : : * DPDK callback to disable promiscuous mode.
1848 : : *
1849 : : * @param dev
1850 : : * Pointer to Ethernet device structure.
1851 : : *
1852 : : * @return
1853 : : * 0 on success,
1854 : : * negative error value otherwise.
1855 : : */
1856 : 0 : static int hinic_dev_promiscuous_disable(struct rte_eth_dev *dev)
1857 : : {
1858 : : int rc = HINIC_OK;
1859 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1860 : :
1861 : 0 : PMD_DRV_LOG(INFO, "Disable promiscuous, nic_dev: %s, port_id: %d, promisc: %d",
1862 : : nic_dev->proc_dev_name, dev->data->port_id,
1863 : : dev->data->promiscuous);
1864 : :
1865 : 0 : rc = hinic_set_dev_promiscuous(nic_dev, false);
1866 [ # # ]: 0 : if (rc)
1867 : 0 : PMD_DRV_LOG(ERR, "Disable promiscuous failed");
1868 : :
1869 : 0 : return rc;
1870 : : }
1871 : :
1872 : 0 : static int hinic_flow_ctrl_get(struct rte_eth_dev *dev,
1873 : : struct rte_eth_fc_conf *fc_conf)
1874 : : {
1875 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1876 : : struct nic_pause_config nic_pause;
1877 : : int err;
1878 : :
1879 : : memset(&nic_pause, 0, sizeof(nic_pause));
1880 : :
1881 : 0 : err = hinic_get_pause_info(nic_dev->hwdev, &nic_pause);
1882 [ # # ]: 0 : if (err)
1883 : : return err;
1884 : :
1885 [ # # # # ]: 0 : if (nic_dev->pause_set || !nic_pause.auto_neg) {
1886 : 0 : nic_pause.rx_pause = nic_dev->nic_pause.rx_pause;
1887 : 0 : nic_pause.tx_pause = nic_dev->nic_pause.tx_pause;
1888 : : }
1889 : :
1890 : 0 : fc_conf->autoneg = nic_pause.auto_neg;
1891 : :
1892 [ # # # # ]: 0 : if (nic_pause.tx_pause && nic_pause.rx_pause)
1893 : 0 : fc_conf->mode = RTE_ETH_FC_FULL;
1894 [ # # ]: 0 : else if (nic_pause.tx_pause)
1895 : 0 : fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
1896 [ # # ]: 0 : else if (nic_pause.rx_pause)
1897 : 0 : fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
1898 : : else
1899 : 0 : fc_conf->mode = RTE_ETH_FC_NONE;
1900 : :
1901 : : return 0;
1902 : : }
1903 : :
1904 : 0 : static int hinic_flow_ctrl_set(struct rte_eth_dev *dev,
1905 : : struct rte_eth_fc_conf *fc_conf)
1906 : : {
1907 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1908 : : struct nic_pause_config nic_pause;
1909 : : int err;
1910 : :
1911 : 0 : nic_pause.auto_neg = fc_conf->autoneg;
1912 : :
1913 [ # # ]: 0 : if (((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL) ||
1914 [ # # ]: 0 : (fc_conf->mode & RTE_ETH_FC_TX_PAUSE))
1915 : : nic_pause.tx_pause = true;
1916 : : else
1917 : : nic_pause.tx_pause = false;
1918 : :
1919 [ # # ]: 0 : if (((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL) ||
1920 [ # # ]: 0 : (fc_conf->mode & RTE_ETH_FC_RX_PAUSE))
1921 : : nic_pause.rx_pause = true;
1922 : : else
1923 : : nic_pause.rx_pause = false;
1924 : :
1925 : 0 : err = hinic_set_pause_config(nic_dev->hwdev, nic_pause);
1926 [ # # ]: 0 : if (err)
1927 : : return err;
1928 : :
1929 : 0 : nic_dev->pause_set = true;
1930 : 0 : nic_dev->nic_pause.auto_neg = nic_pause.auto_neg;
1931 : 0 : nic_dev->nic_pause.rx_pause = nic_pause.rx_pause;
1932 : 0 : nic_dev->nic_pause.tx_pause = nic_pause.tx_pause;
1933 : :
1934 [ # # # # : 0 : PMD_DRV_LOG(INFO, "Set pause options, tx: %s, rx: %s, auto: %s",
# # ]
1935 : : nic_pause.tx_pause ? "on" : "off",
1936 : : nic_pause.rx_pause ? "on" : "off",
1937 : : nic_pause.auto_neg ? "on" : "off");
1938 : :
1939 : 0 : return 0;
1940 : : }
1941 : :
1942 : : /**
1943 : : * DPDK callback to update the RSS hash key and RSS hash type.
1944 : : *
1945 : : * @param dev
1946 : : * Pointer to Ethernet device structure.
1947 : : * @param rss_conf
1948 : : * RSS configuration data.
1949 : : *
1950 : : * @return
1951 : : * 0 on success, negative error value otherwise.
1952 : : */
1953 : 0 : static int hinic_rss_hash_update(struct rte_eth_dev *dev,
1954 : : struct rte_eth_rss_conf *rss_conf)
1955 : : {
1956 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1957 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
1958 : 0 : u8 hashkey[HINIC_RSS_KEY_SIZE] = {0};
1959 : 0 : u8 prio_tc[HINIC_DCB_UP_MAX] = {0};
1960 : 0 : u64 rss_hf = rss_conf->rss_hf;
1961 : 0 : struct nic_rss_type rss_type = {0};
1962 : : int err = 0;
1963 : :
1964 [ # # ]: 0 : if (!(nic_dev->flags & RTE_ETH_MQ_RX_RSS_FLAG)) {
1965 : 0 : PMD_DRV_LOG(WARNING, "RSS is not enabled");
1966 : 0 : return HINIC_OK;
1967 : : }
1968 : :
1969 [ # # ]: 0 : if (rss_conf->rss_key_len > HINIC_RSS_KEY_SIZE) {
1970 : 0 : PMD_DRV_LOG(ERR, "Invalid rss key, rss_key_len: %d",
1971 : : rss_conf->rss_key_len);
1972 : 0 : return HINIC_ERROR;
1973 : : }
1974 : :
1975 [ # # ]: 0 : if (rss_conf->rss_key) {
1976 : 0 : memcpy(hashkey, rss_conf->rss_key, rss_conf->rss_key_len);
1977 : 0 : err = hinic_rss_set_template_tbl(nic_dev->hwdev, tmpl_idx,
1978 : : hashkey);
1979 [ # # ]: 0 : if (err) {
1980 : 0 : PMD_DRV_LOG(ERR, "Set rss template table failed");
1981 : 0 : goto disable_rss;
1982 : : }
1983 : : }
1984 : :
1985 : 0 : rss_type.ipv4 = (rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4)) ? 1 : 0;
1986 : 0 : rss_type.tcp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0;
1987 : 0 : rss_type.ipv6 = (rss_hf & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6)) ? 1 : 0;
1988 : 0 : rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0;
1989 : 0 : rss_type.tcp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0;
1990 : 0 : rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0;
1991 : 0 : rss_type.udp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0;
1992 : 0 : rss_type.udp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0;
1993 : :
1994 : 0 : err = hinic_set_rss_type(nic_dev->hwdev, tmpl_idx, rss_type);
1995 [ # # ]: 0 : if (err) {
1996 : 0 : PMD_DRV_LOG(ERR, "Set rss type table failed");
1997 : 0 : goto disable_rss;
1998 : : }
1999 : :
2000 : : return 0;
2001 : :
2002 : 0 : disable_rss:
2003 : : memset(prio_tc, 0, sizeof(prio_tc));
2004 : 0 : (void)hinic_rss_cfg(nic_dev->hwdev, 0, tmpl_idx, 0, prio_tc);
2005 : 0 : return err;
2006 : : }
2007 : :
2008 : : /**
2009 : : * DPDK callback to get the RSS hash configuration.
2010 : : *
2011 : : * @param dev
2012 : : * Pointer to Ethernet device structure.
2013 : : * @param rss_conf
2014 : : * RSS configuration data.
2015 : : *
2016 : : * @return
2017 : : * 0 on success, negative error value otherwise.
2018 : : */
2019 : 0 : static int hinic_rss_conf_get(struct rte_eth_dev *dev,
2020 : : struct rte_eth_rss_conf *rss_conf)
2021 : : {
2022 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2023 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
2024 : 0 : u8 hashkey[HINIC_RSS_KEY_SIZE] = {0};
2025 : 0 : struct nic_rss_type rss_type = {0};
2026 : : int err;
2027 : :
2028 [ # # ]: 0 : if (!(nic_dev->flags & RTE_ETH_MQ_RX_RSS_FLAG)) {
2029 : 0 : PMD_DRV_LOG(WARNING, "RSS is not enabled");
2030 : 0 : return HINIC_ERROR;
2031 : : }
2032 : :
2033 : 0 : err = hinic_rss_get_template_tbl(nic_dev->hwdev, tmpl_idx, hashkey);
2034 [ # # ]: 0 : if (err)
2035 : : return err;
2036 : :
2037 [ # # ]: 0 : if (rss_conf->rss_key &&
2038 [ # # ]: 0 : rss_conf->rss_key_len >= HINIC_RSS_KEY_SIZE) {
2039 : : memcpy(rss_conf->rss_key, hashkey, sizeof(hashkey));
2040 : 0 : rss_conf->rss_key_len = sizeof(hashkey);
2041 : : }
2042 : :
2043 : 0 : err = hinic_get_rss_type(nic_dev->hwdev, tmpl_idx, &rss_type);
2044 [ # # ]: 0 : if (err)
2045 : : return err;
2046 : :
2047 : : rss_conf->rss_hf = 0;
2048 : 0 : rss_conf->rss_hf |= rss_type.ipv4 ?
2049 [ # # ]: 0 : (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4) : 0;
2050 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv4 ? RTE_ETH_RSS_NONFRAG_IPV4_TCP : 0;
2051 : 0 : rss_conf->rss_hf |= rss_type.ipv6 ?
2052 [ # # ]: 0 : (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6) : 0;
2053 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.ipv6_ext ? RTE_ETH_RSS_IPV6_EX : 0;
2054 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_TCP : 0;
2055 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv6_ext ? RTE_ETH_RSS_IPV6_TCP_EX : 0;
2056 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.udp_ipv4 ? RTE_ETH_RSS_NONFRAG_IPV4_UDP : 0;
2057 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.udp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_UDP : 0;
2058 : :
2059 : 0 : return HINIC_OK;
2060 : : }
2061 : :
2062 : : /**
2063 : : * DPDK callback to update the RSS redirection table.
2064 : : *
2065 : : * @param dev
2066 : : * Pointer to Ethernet device structure.
2067 : : * @param reta_conf
2068 : : * Pointer to RSS reta configuration data.
2069 : : * @param reta_size
2070 : : * Size of the RETA table.
2071 : : *
2072 : : * @return
2073 : : * 0 on success, negative error value otherwise.
2074 : : */
2075 : 0 : static int hinic_rss_indirtbl_update(struct rte_eth_dev *dev,
2076 : : struct rte_eth_rss_reta_entry64 *reta_conf,
2077 : : uint16_t reta_size)
2078 : : {
2079 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2080 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
2081 : 0 : u8 prio_tc[HINIC_DCB_UP_MAX] = {0};
2082 : 0 : u32 indirtbl[NIC_RSS_INDIR_SIZE] = {0};
2083 : : int err = 0;
2084 : : u16 i = 0;
2085 : : u16 idx, shift;
2086 : :
2087 [ # # ]: 0 : if (!(nic_dev->flags & RTE_ETH_MQ_RX_RSS_FLAG))
2088 : : return HINIC_OK;
2089 : :
2090 [ # # ]: 0 : if (reta_size != NIC_RSS_INDIR_SIZE) {
2091 : 0 : PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
2092 : 0 : return HINIC_ERROR;
2093 : : }
2094 : :
2095 : 0 : err = hinic_rss_get_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl);
2096 [ # # ]: 0 : if (err)
2097 : : return err;
2098 : :
2099 : : /* update rss indir_tbl */
2100 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
2101 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
2102 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
2103 : :
2104 [ # # ]: 0 : if (reta_conf[idx].reta[shift] >= nic_dev->num_rq) {
2105 : 0 : PMD_DRV_LOG(ERR, "Invalid reta entry, indirtbl[%d]: %d "
2106 : : "exceeds the maximum rxq num: %d", i,
2107 : : reta_conf[idx].reta[shift], nic_dev->num_rq);
2108 : 0 : return -EINVAL;
2109 : : }
2110 : :
2111 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
2112 : 0 : indirtbl[i] = reta_conf[idx].reta[shift];
2113 : : }
2114 : :
2115 : 0 : err = hinic_rss_set_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl);
2116 [ # # ]: 0 : if (err)
2117 : 0 : goto disable_rss;
2118 : :
2119 : 0 : nic_dev->rss_indir_flag = true;
2120 : :
2121 : 0 : return 0;
2122 : :
2123 : : disable_rss:
2124 : : memset(prio_tc, 0, sizeof(prio_tc));
2125 : 0 : (void)hinic_rss_cfg(nic_dev->hwdev, 0, tmpl_idx, 0, prio_tc);
2126 : :
2127 : 0 : return HINIC_ERROR;
2128 : : }
2129 : :
2130 : : /**
2131 : : * DPDK callback to get the RSS indirection table.
2132 : : *
2133 : : * @param dev
2134 : : * Pointer to Ethernet device structure.
2135 : : * @param reta_conf
2136 : : * Pointer to RSS reta configuration data.
2137 : : * @param reta_size
2138 : : * Size of the RETA table.
2139 : : *
2140 : : * @return
2141 : : * 0 on success, negative error value otherwise.
2142 : : */
2143 : 0 : static int hinic_rss_indirtbl_query(struct rte_eth_dev *dev,
2144 : : struct rte_eth_rss_reta_entry64 *reta_conf,
2145 : : uint16_t reta_size)
2146 : : {
2147 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2148 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
2149 : : int err = 0;
2150 : 0 : u32 indirtbl[NIC_RSS_INDIR_SIZE] = {0};
2151 : : u16 idx, shift;
2152 : : u16 i = 0;
2153 : :
2154 [ # # ]: 0 : if (reta_size != NIC_RSS_INDIR_SIZE) {
2155 : 0 : PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
2156 : 0 : return HINIC_ERROR;
2157 : : }
2158 : :
2159 : 0 : err = hinic_rss_get_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl);
2160 [ # # ]: 0 : if (err) {
2161 : 0 : PMD_DRV_LOG(ERR, "Get rss indirect table failed, error: %d",
2162 : : err);
2163 : 0 : return err;
2164 : : }
2165 : :
2166 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
2167 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
2168 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
2169 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
2170 : 0 : reta_conf[idx].reta[shift] = (uint16_t)indirtbl[i];
2171 : : }
2172 : :
2173 : : return HINIC_OK;
2174 : : }
2175 : :
2176 : : /**
2177 : : * DPDK callback to get extended device statistics.
2178 : : *
2179 : : * @param dev
2180 : : * Pointer to Ethernet device.
2181 : : * @param xstats
2182 : : * Pointer to rte extended stats table.
2183 : : * @param n
2184 : : * The size of the stats table.
2185 : : *
2186 : : * @return
2187 : : * Number of extended stats on success and stats is filled,
2188 : : * negative error value otherwise.
2189 : : */
2190 : 0 : static int hinic_dev_xstats_get(struct rte_eth_dev *dev,
2191 : : struct rte_eth_xstat *xstats,
2192 : : unsigned int n)
2193 : : {
2194 : : u16 qid = 0;
2195 : : u32 i;
2196 : : int err, count;
2197 : : struct hinic_nic_dev *nic_dev;
2198 : : struct hinic_phy_port_stats port_stats;
2199 : : struct hinic_vport_stats vport_stats;
2200 : : struct hinic_rxq *rxq = NULL;
2201 : : struct hinic_rxq_stats rxq_stats;
2202 : : struct hinic_txq *txq = NULL;
2203 : : struct hinic_txq_stats txq_stats;
2204 : :
2205 [ # # ]: 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2206 : : count = hinic_xstats_calc_num(nic_dev);
2207 [ # # ]: 0 : if ((int)n < count)
2208 : : return count;
2209 : :
2210 : : count = 0;
2211 : :
2212 : : /* Get stats from hinic_rxq_stats */
2213 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_rq; qid++) {
2214 : 0 : rxq = nic_dev->rxqs[qid];
2215 : 0 : hinic_rxq_get_stats(rxq, &rxq_stats);
2216 : :
2217 [ # # ]: 0 : for (i = 0; i < HINIC_RXQ_XSTATS_NUM; i++) {
2218 : 0 : xstats[count].value =
2219 : 0 : *(uint64_t *)(((char *)&rxq_stats) +
2220 : 0 : hinic_rxq_stats_strings[i].offset);
2221 : 0 : xstats[count].id = count;
2222 : 0 : count++;
2223 : : }
2224 : : }
2225 : :
2226 : : /* Get stats from hinic_txq_stats */
2227 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_sq; qid++) {
2228 : 0 : txq = nic_dev->txqs[qid];
2229 : 0 : hinic_txq_get_stats(txq, &txq_stats);
2230 : :
2231 [ # # ]: 0 : for (i = 0; i < HINIC_TXQ_XSTATS_NUM; i++) {
2232 : 0 : xstats[count].value =
2233 : 0 : *(uint64_t *)(((char *)&txq_stats) +
2234 : 0 : hinic_txq_stats_strings[i].offset);
2235 : 0 : xstats[count].id = count;
2236 : 0 : count++;
2237 : : }
2238 : : }
2239 : :
2240 : : /* Get stats from hinic_vport_stats */
2241 : 0 : err = hinic_get_vport_stats(nic_dev->hwdev, &vport_stats);
2242 [ # # ]: 0 : if (err)
2243 : : return err;
2244 : :
2245 [ # # ]: 0 : for (i = 0; i < HINIC_VPORT_XSTATS_NUM; i++) {
2246 : 0 : xstats[count].value =
2247 : 0 : *(uint64_t *)(((char *)&vport_stats) +
2248 : 0 : hinic_vport_stats_strings[i].offset);
2249 : 0 : xstats[count].id = count;
2250 : 0 : count++;
2251 : : }
2252 : :
2253 [ # # ]: 0 : if (HINIC_IS_VF(nic_dev->hwdev))
2254 : : return count;
2255 : :
2256 : : /* Get stats from hinic_phy_port_stats */
2257 : 0 : err = hinic_get_phy_port_stats(nic_dev->hwdev, &port_stats);
2258 [ # # ]: 0 : if (err)
2259 : : return err;
2260 : :
2261 [ # # ]: 0 : for (i = 0; i < HINIC_PHYPORT_XSTATS_NUM; i++) {
2262 : 0 : xstats[count].value = *(uint64_t *)(((char *)&port_stats) +
2263 : 0 : hinic_phyport_stats_strings[i].offset);
2264 : 0 : xstats[count].id = count;
2265 : 0 : count++;
2266 : : }
2267 : :
2268 : : return count;
2269 : : }
2270 : :
2271 : 0 : static void hinic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
2272 : : struct rte_eth_rxq_info *qinfo)
2273 : : {
2274 : 0 : struct hinic_rxq *rxq = dev->data->rx_queues[queue_id];
2275 : :
2276 : 0 : qinfo->mp = rxq->mb_pool;
2277 : 0 : qinfo->nb_desc = rxq->q_depth;
2278 : 0 : }
2279 : :
2280 : 0 : static void hinic_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
2281 : : struct rte_eth_txq_info *qinfo)
2282 : : {
2283 : 0 : struct hinic_txq *txq = dev->data->tx_queues[queue_id];
2284 : :
2285 : 0 : qinfo->nb_desc = txq->q_depth;
2286 : 0 : }
2287 : :
2288 : : /**
2289 : : * DPDK callback to retrieve names of extended device statistics
2290 : : *
2291 : : * @param dev
2292 : : * Pointer to Ethernet device structure.
2293 : : * @param xstats_names
2294 : : * Buffer to insert names into.
2295 : : *
2296 : : * @return
2297 : : * Number of xstats names.
2298 : : */
2299 : 0 : static int hinic_dev_xstats_get_names(struct rte_eth_dev *dev,
2300 : : struct rte_eth_xstat_name *xstats_names,
2301 : : __rte_unused unsigned int limit)
2302 : : {
2303 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2304 : : int count = 0;
2305 : : u16 i = 0, q_num;
2306 : :
2307 [ # # ]: 0 : if (xstats_names == NULL)
2308 : 0 : return hinic_xstats_calc_num(nic_dev);
2309 : :
2310 : : /* get pmd rxq stats */
2311 [ # # ]: 0 : for (q_num = 0; q_num < nic_dev->num_rq; q_num++) {
2312 [ # # ]: 0 : for (i = 0; i < HINIC_RXQ_XSTATS_NUM; i++) {
2313 : 0 : snprintf(xstats_names[count].name,
2314 : : sizeof(xstats_names[count].name),
2315 : : "rxq%d_%s_pmd",
2316 : 0 : q_num, hinic_rxq_stats_strings[i].name);
2317 : 0 : count++;
2318 : : }
2319 : : }
2320 : :
2321 : : /* get pmd txq stats */
2322 [ # # ]: 0 : for (q_num = 0; q_num < nic_dev->num_sq; q_num++) {
2323 [ # # ]: 0 : for (i = 0; i < HINIC_TXQ_XSTATS_NUM; i++) {
2324 : 0 : snprintf(xstats_names[count].name,
2325 : : sizeof(xstats_names[count].name),
2326 : : "txq%d_%s_pmd",
2327 : 0 : q_num, hinic_txq_stats_strings[i].name);
2328 : 0 : count++;
2329 : : }
2330 : : }
2331 : :
2332 : : /* get vport stats */
2333 [ # # ]: 0 : for (i = 0; i < HINIC_VPORT_XSTATS_NUM; i++) {
2334 : 0 : snprintf(xstats_names[count].name,
2335 : : sizeof(xstats_names[count].name),
2336 : 0 : "%s", hinic_vport_stats_strings[i].name);
2337 : 0 : count++;
2338 : : }
2339 : :
2340 [ # # ]: 0 : if (HINIC_IS_VF(nic_dev->hwdev))
2341 : : return count;
2342 : :
2343 : : /* get phy port stats */
2344 [ # # ]: 0 : for (i = 0; i < HINIC_PHYPORT_XSTATS_NUM; i++) {
2345 : 0 : snprintf(xstats_names[count].name,
2346 : : sizeof(xstats_names[count].name),
2347 : 0 : "%s", hinic_phyport_stats_strings[i].name);
2348 : 0 : count++;
2349 : : }
2350 : :
2351 : : return count;
2352 : : }
2353 : :
2354 : : /**
2355 : : * DPDK callback to set mac address
2356 : : *
2357 : : * @param dev
2358 : : * Pointer to Ethernet device structure.
2359 : : * @param addr
2360 : : * Pointer to mac address
2361 : : * @return
2362 : : * 0 on success, negative error value otherwise.
2363 : : */
2364 : 0 : static int hinic_set_mac_addr(struct rte_eth_dev *dev,
2365 : : struct rte_ether_addr *addr)
2366 : : {
2367 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2368 : : u16 func_id;
2369 : : int err;
2370 : :
2371 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2372 : 0 : err = hinic_update_mac(nic_dev->hwdev, nic_dev->default_addr.addr_bytes,
2373 : 0 : addr->addr_bytes, 0, func_id);
2374 [ # # ]: 0 : if (err)
2375 : : return err;
2376 : :
2377 : : rte_ether_addr_copy(addr, &nic_dev->default_addr);
2378 : :
2379 : 0 : PMD_DRV_LOG(INFO, "Set new mac address " RTE_ETHER_ADDR_PRT_FMT,
2380 : : RTE_ETHER_ADDR_BYTES(addr));
2381 : :
2382 : 0 : return 0;
2383 : : }
2384 : :
2385 : : /**
2386 : : * DPDK callback to remove a MAC address.
2387 : : *
2388 : : * @param dev
2389 : : * Pointer to Ethernet device structure.
2390 : : * @param index
2391 : : * MAC address index, should less than 128.
2392 : : */
2393 : 0 : static void hinic_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
2394 : : {
2395 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2396 : : u16 func_id;
2397 : : int ret;
2398 : :
2399 [ # # ]: 0 : if (index >= HINIC_MAX_UC_MAC_ADDRS) {
2400 : 0 : PMD_DRV_LOG(INFO, "Remove mac index(%u) is out of range",
2401 : : index);
2402 : 0 : return;
2403 : : }
2404 : :
2405 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2406 : 0 : ret = hinic_del_mac(nic_dev->hwdev,
2407 : 0 : dev->data->mac_addrs[index].addr_bytes, 0, func_id);
2408 [ # # ]: 0 : if (ret)
2409 : : return;
2410 : :
2411 : 0 : memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));
2412 : : }
2413 : :
2414 : : /**
2415 : : * DPDK callback to add a MAC address.
2416 : : *
2417 : : * @param dev
2418 : : * Pointer to Ethernet device structure.
2419 : : * @param mac_addr
2420 : : * Pointer to MAC address
2421 : : * @param index
2422 : : * MAC address index, should less than 128.
2423 : : * @param vmdq
2424 : : * VMDq pool index(not used).
2425 : : *
2426 : : * @return
2427 : : * 0 on success, negative error value otherwise.
2428 : : */
2429 : 0 : static int hinic_mac_addr_add(struct rte_eth_dev *dev,
2430 : : struct rte_ether_addr *mac_addr, uint32_t index,
2431 : : __rte_unused uint32_t vmdq)
2432 : : {
2433 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2434 : : unsigned int i;
2435 : : u16 func_id;
2436 : : int ret;
2437 : :
2438 [ # # ]: 0 : if (index >= HINIC_MAX_UC_MAC_ADDRS) {
2439 : 0 : PMD_DRV_LOG(INFO, "Add mac index(%u) is out of range", index);
2440 : 0 : return -EINVAL;
2441 : : }
2442 : :
2443 : : /* First, make sure this address isn't already configured. */
2444 [ # # ]: 0 : for (i = 0; (i != HINIC_MAX_UC_MAC_ADDRS); ++i) {
2445 : : /* Skip this index, it's going to be reconfigured. */
2446 [ # # ]: 0 : if (i == index)
2447 : 0 : continue;
2448 : :
2449 [ # # ]: 0 : if (memcmp(&dev->data->mac_addrs[i],
2450 : : mac_addr, sizeof(*mac_addr)))
2451 : 0 : continue;
2452 : :
2453 : 0 : PMD_DRV_LOG(INFO, "MAC address already configured");
2454 : 0 : return -EADDRINUSE;
2455 : : }
2456 : :
2457 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2458 : 0 : ret = hinic_set_mac(nic_dev->hwdev, mac_addr->addr_bytes, 0, func_id);
2459 [ # # ]: 0 : if (ret)
2460 : : return ret;
2461 : :
2462 : 0 : dev->data->mac_addrs[index] = *mac_addr;
2463 : 0 : return 0;
2464 : : }
2465 : :
2466 : : /**
2467 : : * DPDK callback to set multicast mac address
2468 : : *
2469 : : * @param dev
2470 : : * Pointer to Ethernet device structure.
2471 : : * @param mc_addr_set
2472 : : * Pointer to multicast mac address
2473 : : * @param nb_mc_addr
2474 : : * mc addr count
2475 : : * @return
2476 : : * 0 on success, negative error value otherwise.
2477 : : */
2478 : 0 : static int hinic_set_mc_addr_list(struct rte_eth_dev *dev,
2479 : : struct rte_ether_addr *mc_addr_set,
2480 : : uint32_t nb_mc_addr)
2481 : : {
2482 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2483 : : u16 func_id;
2484 : : int ret;
2485 : : u32 i;
2486 : :
2487 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2488 : :
2489 : : /* delete old multi_cast addrs firstly */
2490 : 0 : hinic_delete_mc_addr_list(nic_dev);
2491 : :
2492 [ # # ]: 0 : if (nb_mc_addr > HINIC_MAX_MC_MAC_ADDRS)
2493 : 0 : goto allmulti;
2494 : :
2495 [ # # ]: 0 : for (i = 0; i < nb_mc_addr; i++) {
2496 : 0 : ret = hinic_set_mac(nic_dev->hwdev, mc_addr_set[i].addr_bytes,
2497 : : 0, func_id);
2498 : : /* if add mc addr failed, set all multi_cast */
2499 [ # # ]: 0 : if (ret) {
2500 : 0 : hinic_delete_mc_addr_list(nic_dev);
2501 : 0 : goto allmulti;
2502 : : }
2503 : :
2504 : 0 : rte_ether_addr_copy(&mc_addr_set[i], &nic_dev->mc_list[i]);
2505 : : }
2506 : :
2507 : : return 0;
2508 : :
2509 : 0 : allmulti:
2510 : 0 : hinic_dev_allmulticast_enable(dev);
2511 : :
2512 : 0 : return 0;
2513 : : }
2514 : :
2515 : : /**
2516 : : * DPDK callback to get flow operations
2517 : : *
2518 : : * @param dev
2519 : : * Pointer to Ethernet device structure.
2520 : : * @param ops
2521 : : * Pointer to operation-specific structure.
2522 : : *
2523 : : * @return
2524 : : * 0 on success, negative error value otherwise.
2525 : : */
2526 : 0 : static int hinic_dev_flow_ops_get(struct rte_eth_dev *dev __rte_unused,
2527 : : const struct rte_flow_ops **ops)
2528 : : {
2529 : 0 : *ops = &hinic_flow_ops;
2530 : 0 : return 0;
2531 : : }
2532 : :
2533 : 0 : static int hinic_set_default_pause_feature(struct hinic_nic_dev *nic_dev)
2534 : : {
2535 : : struct nic_pause_config pause_config = {0};
2536 : : int err;
2537 : :
2538 : : pause_config.auto_neg = 0;
2539 : : pause_config.rx_pause = HINIC_DEFAUT_PAUSE_CONFIG;
2540 : : pause_config.tx_pause = HINIC_DEFAUT_PAUSE_CONFIG;
2541 : :
2542 : 0 : err = hinic_set_pause_config(nic_dev->hwdev, pause_config);
2543 [ # # ]: 0 : if (err)
2544 : : return err;
2545 : :
2546 : 0 : nic_dev->pause_set = true;
2547 : 0 : nic_dev->nic_pause.auto_neg = pause_config.auto_neg;
2548 : 0 : nic_dev->nic_pause.rx_pause = pause_config.rx_pause;
2549 : 0 : nic_dev->nic_pause.tx_pause = pause_config.tx_pause;
2550 : :
2551 : 0 : return 0;
2552 : : }
2553 : :
2554 : 0 : static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev)
2555 : : {
2556 : 0 : u8 up_tc[HINIC_DCB_UP_MAX] = {0};
2557 : 0 : u8 up_pgid[HINIC_DCB_UP_MAX] = {0};
2558 : 0 : u8 up_bw[HINIC_DCB_UP_MAX] = {0};
2559 : 0 : u8 pg_bw[HINIC_DCB_UP_MAX] = {0};
2560 : 0 : u8 up_strict[HINIC_DCB_UP_MAX] = {0};
2561 : : int i = 0;
2562 : :
2563 : 0 : pg_bw[0] = 100;
2564 [ # # ]: 0 : for (i = 0; i < HINIC_DCB_UP_MAX; i++)
2565 : 0 : up_bw[i] = 100;
2566 : :
2567 : 0 : return hinic_dcb_set_ets(nic_dev->hwdev, up_tc, pg_bw,
2568 : : up_pgid, up_bw, up_strict);
2569 : : }
2570 : :
2571 : 0 : static int hinic_pf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id)
2572 : : {
2573 : : u8 default_cos = 0;
2574 : : u8 valid_cos_bitmap;
2575 : : u8 i;
2576 : :
2577 : 0 : valid_cos_bitmap = hwdev->cfg_mgmt->svc_cap.valid_cos_bitmap;
2578 [ # # ]: 0 : if (!valid_cos_bitmap) {
2579 : 0 : PMD_DRV_LOG(ERR, "PF has none cos to support");
2580 : 0 : return -EFAULT;
2581 : : }
2582 : :
2583 [ # # ]: 0 : for (i = 0; i < NR_MAX_COS; i++) {
2584 [ # # ]: 0 : if (valid_cos_bitmap & BIT(i))
2585 : : default_cos = i; /* Find max cos id as default cos */
2586 : : }
2587 : :
2588 : 0 : *cos_id = default_cos;
2589 : :
2590 : 0 : return 0;
2591 : : }
2592 : :
2593 : 0 : static int hinic_init_default_cos(struct hinic_nic_dev *nic_dev)
2594 : : {
2595 : 0 : u8 cos_id = 0;
2596 : : int err;
2597 : :
2598 [ # # ]: 0 : if (!HINIC_IS_VF(nic_dev->hwdev)) {
2599 : 0 : err = hinic_pf_get_default_cos(nic_dev->hwdev, &cos_id);
2600 [ # # ]: 0 : if (err) {
2601 : 0 : PMD_DRV_LOG(ERR, "Get PF default cos failed, err: %d",
2602 : : err);
2603 : 0 : return HINIC_ERROR;
2604 : : }
2605 : : } else {
2606 : 0 : err = hinic_vf_get_default_cos(nic_dev->hwdev, &cos_id);
2607 [ # # ]: 0 : if (err) {
2608 : 0 : PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d",
2609 : : err);
2610 : 0 : return HINIC_ERROR;
2611 : : }
2612 : : }
2613 : :
2614 : 0 : nic_dev->default_cos = cos_id;
2615 : :
2616 : 0 : PMD_DRV_LOG(INFO, "Default cos %d", nic_dev->default_cos);
2617 : :
2618 : 0 : return 0;
2619 : : }
2620 : :
2621 : 0 : static int hinic_set_default_hw_feature(struct hinic_nic_dev *nic_dev)
2622 : : {
2623 : : int err;
2624 : :
2625 : 0 : err = hinic_init_default_cos(nic_dev);
2626 [ # # ]: 0 : if (err)
2627 : : return err;
2628 : :
2629 [ # # ]: 0 : if (hinic_func_type(nic_dev->hwdev) == TYPE_VF)
2630 : : return 0;
2631 : :
2632 : : /* Restore DCB configure to default status */
2633 : 0 : err = hinic_set_default_dcb_feature(nic_dev);
2634 [ # # ]: 0 : if (err)
2635 : : return err;
2636 : :
2637 : : /* Set pause enable, and up will disable pfc. */
2638 : 0 : err = hinic_set_default_pause_feature(nic_dev);
2639 [ # # ]: 0 : if (err)
2640 : : return err;
2641 : :
2642 : 0 : err = hinic_reset_port_link_cfg(nic_dev->hwdev);
2643 [ # # ]: 0 : if (err)
2644 : : return err;
2645 : :
2646 : 0 : err = hinic_set_link_status_follow(nic_dev->hwdev,
2647 : : HINIC_LINK_FOLLOW_PORT);
2648 [ # # ]: 0 : if (err == HINIC_MGMT_CMD_UNSUPPORTED)
2649 : 0 : PMD_DRV_LOG(WARNING, "Don't support to set link status follow phy port status");
2650 [ # # ]: 0 : else if (err)
2651 : : return err;
2652 : :
2653 : 0 : return hinic_set_anti_attack(nic_dev->hwdev, true);
2654 : : }
2655 : :
2656 : 0 : static int32_t hinic_card_workmode_check(struct hinic_nic_dev *nic_dev)
2657 : : {
2658 : 0 : struct hinic_board_info info = { 0 };
2659 : : int rc;
2660 : :
2661 [ # # ]: 0 : if (hinic_func_type(nic_dev->hwdev) == TYPE_VF)
2662 : : return 0;
2663 : :
2664 : 0 : rc = hinic_get_board_info(nic_dev->hwdev, &info);
2665 [ # # ]: 0 : if (rc)
2666 : : return rc;
2667 : :
2668 [ # # ]: 0 : return (info.service_mode == HINIC_SERVICE_MODE_NIC ? HINIC_OK :
2669 : : HINIC_ERROR);
2670 : : }
2671 : :
2672 : 0 : static int hinic_copy_mempool_init(struct hinic_nic_dev *nic_dev)
2673 : : {
2674 : 0 : nic_dev->cpy_mpool = rte_mempool_lookup(nic_dev->proc_dev_name);
2675 [ # # ]: 0 : if (nic_dev->cpy_mpool == NULL) {
2676 : 0 : nic_dev->cpy_mpool =
2677 : 0 : rte_pktmbuf_pool_create(nic_dev->proc_dev_name,
2678 : : HINIC_COPY_MEMPOOL_DEPTH,
2679 : : 0, 0,
2680 : : HINIC_COPY_MBUF_SIZE,
2681 : 0 : rte_socket_id());
2682 [ # # ]: 0 : if (!nic_dev->cpy_mpool) {
2683 : 0 : PMD_DRV_LOG(ERR, "Create copy mempool failed, errno: %d, dev_name: %s",
2684 : : rte_errno, nic_dev->proc_dev_name);
2685 : 0 : return -ENOMEM;
2686 : : }
2687 : : }
2688 : :
2689 : : return 0;
2690 : : }
2691 : :
2692 : : static void hinic_copy_mempool_uninit(struct hinic_nic_dev *nic_dev)
2693 : : {
2694 : 0 : rte_mempool_free(nic_dev->cpy_mpool);
2695 : 0 : }
2696 : :
2697 : 0 : static int hinic_init_sw_rxtxqs(struct hinic_nic_dev *nic_dev)
2698 : : {
2699 : : u32 txq_size;
2700 : : u32 rxq_size;
2701 : :
2702 : : /* allocate software txq array */
2703 : 0 : txq_size = nic_dev->nic_cap.max_sqs * sizeof(*nic_dev->txqs);
2704 : 0 : nic_dev->txqs = kzalloc_aligned(txq_size, GFP_KERNEL);
2705 [ # # ]: 0 : if (!nic_dev->txqs) {
2706 : 0 : PMD_DRV_LOG(ERR, "Allocate txqs failed");
2707 : 0 : return -ENOMEM;
2708 : : }
2709 : :
2710 : : /* allocate software rxq array */
2711 : 0 : rxq_size = nic_dev->nic_cap.max_rqs * sizeof(*nic_dev->rxqs);
2712 : 0 : nic_dev->rxqs = kzalloc_aligned(rxq_size, GFP_KERNEL);
2713 [ # # ]: 0 : if (!nic_dev->rxqs) {
2714 : : /* free txqs */
2715 : 0 : kfree(nic_dev->txqs);
2716 : 0 : nic_dev->txqs = NULL;
2717 : :
2718 : 0 : PMD_DRV_LOG(ERR, "Allocate rxqs failed");
2719 : 0 : return -ENOMEM;
2720 : : }
2721 : :
2722 : : return HINIC_OK;
2723 : : }
2724 : :
2725 : : static void hinic_deinit_sw_rxtxqs(struct hinic_nic_dev *nic_dev)
2726 : : {
2727 : 0 : kfree(nic_dev->txqs);
2728 : 0 : nic_dev->txqs = NULL;
2729 : :
2730 : 0 : kfree(nic_dev->rxqs);
2731 : 0 : nic_dev->rxqs = NULL;
2732 : 0 : }
2733 : :
2734 : 0 : static int hinic_nic_dev_create(struct rte_eth_dev *eth_dev)
2735 : : {
2736 : 0 : struct hinic_nic_dev *nic_dev =
2737 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
2738 : : int rc;
2739 : :
2740 : 0 : nic_dev->hwdev = rte_zmalloc("hinic_hwdev", sizeof(*nic_dev->hwdev),
2741 : : RTE_CACHE_LINE_SIZE);
2742 [ # # ]: 0 : if (!nic_dev->hwdev) {
2743 : 0 : PMD_DRV_LOG(ERR, "Allocate hinic hwdev memory failed, dev_name: %s",
2744 : : eth_dev->data->name);
2745 : 0 : return -ENOMEM;
2746 : : }
2747 : 0 : nic_dev->hwdev->pcidev_hdl = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *nic_dev->hwdev->pcidev_hdl);
2748 : :
2749 : : /* init osdep*/
2750 : 0 : rc = hinic_osdep_init(nic_dev->hwdev);
2751 [ # # ]: 0 : if (rc) {
2752 : 0 : PMD_DRV_LOG(ERR, "Initialize os_dep failed, dev_name: %s",
2753 : : eth_dev->data->name);
2754 : 0 : goto init_osdep_fail;
2755 : : }
2756 : :
2757 : : /* init_hwif */
2758 : 0 : rc = hinic_hwif_res_init(nic_dev->hwdev);
2759 [ # # ]: 0 : if (rc) {
2760 : 0 : PMD_DRV_LOG(ERR, "Initialize hwif failed, dev_name: %s",
2761 : : eth_dev->data->name);
2762 : 0 : goto init_hwif_fail;
2763 : : }
2764 : :
2765 : : /* init_cfg_mgmt */
2766 : 0 : rc = init_cfg_mgmt(nic_dev->hwdev);
2767 [ # # ]: 0 : if (rc) {
2768 : 0 : PMD_DRV_LOG(ERR, "Initialize cfg_mgmt failed, dev_name: %s",
2769 : : eth_dev->data->name);
2770 : 0 : goto init_cfgmgnt_fail;
2771 : : }
2772 : :
2773 : : /* init_aeqs */
2774 : 0 : rc = hinic_comm_aeqs_init(nic_dev->hwdev);
2775 [ # # ]: 0 : if (rc) {
2776 : 0 : PMD_DRV_LOG(ERR, "Initialize aeqs failed, dev_name: %s",
2777 : : eth_dev->data->name);
2778 : 0 : goto init_aeqs_fail;
2779 : : }
2780 : :
2781 : : /* init_pf_to_mgnt */
2782 : 0 : rc = hinic_comm_pf_to_mgmt_init(nic_dev->hwdev);
2783 [ # # ]: 0 : if (rc) {
2784 : 0 : PMD_DRV_LOG(ERR, "Initialize pf_to_mgmt failed, dev_name: %s",
2785 : : eth_dev->data->name);
2786 : 0 : goto init_pf_to_mgmt_fail;
2787 : : }
2788 : :
2789 : : /* init mailbox */
2790 : 0 : rc = hinic_comm_func_to_func_init(nic_dev->hwdev);
2791 [ # # ]: 0 : if (rc) {
2792 : 0 : PMD_DRV_LOG(ERR, "Initialize func_to_func failed, dev_name: %s",
2793 : : eth_dev->data->name);
2794 : 0 : goto init_func_to_func_fail;
2795 : : }
2796 : :
2797 : 0 : rc = hinic_card_workmode_check(nic_dev);
2798 [ # # ]: 0 : if (rc) {
2799 : 0 : PMD_DRV_LOG(ERR, "Check card workmode failed, dev_name: %s",
2800 : : eth_dev->data->name);
2801 : 0 : goto workmode_check_fail;
2802 : : }
2803 : :
2804 : : /* do l2nic reset to make chip clear */
2805 : 0 : rc = hinic_l2nic_reset(nic_dev->hwdev);
2806 [ # # ]: 0 : if (rc) {
2807 : 0 : PMD_DRV_LOG(ERR, "Do l2nic reset failed, dev_name: %s",
2808 : : eth_dev->data->name);
2809 : 0 : goto l2nic_reset_fail;
2810 : : }
2811 : :
2812 : : /* init dma and aeq msix attribute table */
2813 : 0 : (void)hinic_init_attr_table(nic_dev->hwdev);
2814 : :
2815 : : /* init_cmdqs */
2816 : 0 : rc = hinic_comm_cmdqs_init(nic_dev->hwdev);
2817 [ # # ]: 0 : if (rc) {
2818 : 0 : PMD_DRV_LOG(ERR, "Initialize cmdq failed, dev_name: %s",
2819 : : eth_dev->data->name);
2820 : 0 : goto init_cmdq_fail;
2821 : : }
2822 : :
2823 : : /* set hardware state active */
2824 : 0 : rc = hinic_activate_hwdev_state(nic_dev->hwdev);
2825 [ # # ]: 0 : if (rc) {
2826 : 0 : PMD_DRV_LOG(ERR, "Initialize resources state failed, dev_name: %s",
2827 : : eth_dev->data->name);
2828 : 0 : goto init_resources_state_fail;
2829 : : }
2830 : :
2831 : : /* init_capability */
2832 : 0 : rc = hinic_init_capability(nic_dev->hwdev);
2833 [ # # ]: 0 : if (rc) {
2834 : 0 : PMD_DRV_LOG(ERR, "Initialize capability failed, dev_name: %s",
2835 : : eth_dev->data->name);
2836 : 0 : goto init_cap_fail;
2837 : : }
2838 : :
2839 : : /* get nic capability */
2840 [ # # ]: 0 : if (!hinic_support_nic(nic_dev->hwdev, &nic_dev->nic_cap)) {
2841 : 0 : PMD_DRV_LOG(ERR, "Hw doesn't support nic, dev_name: %s",
2842 : : eth_dev->data->name);
2843 : : rc = -EINVAL;
2844 : 0 : goto nic_check_fail;
2845 : : }
2846 : :
2847 : : /* init root cla and function table */
2848 : 0 : rc = hinic_init_nicio(nic_dev->hwdev);
2849 [ # # ]: 0 : if (rc) {
2850 : 0 : PMD_DRV_LOG(ERR, "Initialize nic_io failed, dev_name: %s",
2851 : : eth_dev->data->name);
2852 : 0 : goto init_nicio_fail;
2853 : : }
2854 : :
2855 : : /* init_software_txrxq */
2856 : 0 : rc = hinic_init_sw_rxtxqs(nic_dev);
2857 [ # # ]: 0 : if (rc) {
2858 : 0 : PMD_DRV_LOG(ERR, "Initialize sw_rxtxqs failed, dev_name: %s",
2859 : : eth_dev->data->name);
2860 : 0 : goto init_sw_rxtxqs_fail;
2861 : : }
2862 : :
2863 : 0 : rc = hinic_copy_mempool_init(nic_dev);
2864 [ # # ]: 0 : if (rc) {
2865 : 0 : PMD_DRV_LOG(ERR, "Create copy mempool failed, dev_name: %s",
2866 : : eth_dev->data->name);
2867 : 0 : goto init_mpool_fail;
2868 : : }
2869 : :
2870 : : /* set hardware feature to default status */
2871 : 0 : rc = hinic_set_default_hw_feature(nic_dev);
2872 [ # # ]: 0 : if (rc) {
2873 : 0 : PMD_DRV_LOG(ERR, "Initialize hardware default features failed, dev_name: %s",
2874 : : eth_dev->data->name);
2875 : 0 : goto set_default_hw_feature_fail;
2876 : : }
2877 : :
2878 : : return 0;
2879 : :
2880 : : set_default_hw_feature_fail:
2881 : : hinic_copy_mempool_uninit(nic_dev);
2882 : :
2883 : 0 : init_mpool_fail:
2884 : : hinic_deinit_sw_rxtxqs(nic_dev);
2885 : :
2886 : 0 : init_sw_rxtxqs_fail:
2887 : 0 : hinic_deinit_nicio(nic_dev->hwdev);
2888 : :
2889 : 0 : nic_check_fail:
2890 : 0 : init_nicio_fail:
2891 : 0 : init_cap_fail:
2892 : 0 : hinic_deactivate_hwdev_state(nic_dev->hwdev);
2893 : :
2894 : 0 : init_resources_state_fail:
2895 : 0 : hinic_comm_cmdqs_free(nic_dev->hwdev);
2896 : :
2897 : 0 : init_cmdq_fail:
2898 : 0 : l2nic_reset_fail:
2899 : 0 : workmode_check_fail:
2900 : 0 : hinic_comm_func_to_func_free(nic_dev->hwdev);
2901 : :
2902 : 0 : init_func_to_func_fail:
2903 : 0 : hinic_comm_pf_to_mgmt_free(nic_dev->hwdev);
2904 : :
2905 : 0 : init_pf_to_mgmt_fail:
2906 : 0 : hinic_comm_aeqs_free(nic_dev->hwdev);
2907 : :
2908 : 0 : init_aeqs_fail:
2909 : 0 : free_cfg_mgmt(nic_dev->hwdev);
2910 : :
2911 : 0 : init_cfgmgnt_fail:
2912 : 0 : hinic_hwif_res_free(nic_dev->hwdev);
2913 : :
2914 : 0 : init_hwif_fail:
2915 : 0 : hinic_osdep_deinit(nic_dev->hwdev);
2916 : :
2917 : 0 : init_osdep_fail:
2918 : 0 : rte_free(nic_dev->hwdev);
2919 : 0 : nic_dev->hwdev = NULL;
2920 : :
2921 : 0 : return rc;
2922 : : }
2923 : :
2924 : 0 : static void hinic_nic_dev_destroy(struct rte_eth_dev *eth_dev)
2925 : : {
2926 : 0 : struct hinic_nic_dev *nic_dev =
2927 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
2928 : :
2929 : 0 : (void)hinic_set_link_status_follow(nic_dev->hwdev,
2930 : : HINIC_LINK_FOLLOW_DEFAULT);
2931 : : hinic_copy_mempool_uninit(nic_dev);
2932 : : hinic_deinit_sw_rxtxqs(nic_dev);
2933 : 0 : hinic_deinit_nicio(nic_dev->hwdev);
2934 : 0 : hinic_deactivate_hwdev_state(nic_dev->hwdev);
2935 : 0 : hinic_comm_cmdqs_free(nic_dev->hwdev);
2936 : 0 : hinic_comm_func_to_func_free(nic_dev->hwdev);
2937 : 0 : hinic_comm_pf_to_mgmt_free(nic_dev->hwdev);
2938 : 0 : hinic_comm_aeqs_free(nic_dev->hwdev);
2939 : 0 : free_cfg_mgmt(nic_dev->hwdev);
2940 : 0 : hinic_hwif_res_free(nic_dev->hwdev);
2941 : 0 : hinic_osdep_deinit(nic_dev->hwdev);
2942 : 0 : rte_free(nic_dev->hwdev);
2943 : 0 : nic_dev->hwdev = NULL;
2944 : 0 : }
2945 : :
2946 : : /**
2947 : : * DPDK callback to close the device.
2948 : : *
2949 : : * @param dev
2950 : : * Pointer to Ethernet device structure.
2951 : : */
2952 : 0 : static int hinic_dev_close(struct rte_eth_dev *dev)
2953 : : {
2954 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2955 : : int ret;
2956 : :
2957 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2958 : : return 0;
2959 : :
2960 [ # # ]: 0 : if (rte_bit_relaxed_test_and_set32(HINIC_DEV_CLOSE,
2961 : : &nic_dev->dev_status)) {
2962 : 0 : PMD_DRV_LOG(WARNING, "Device %s already closed",
2963 : : dev->data->name);
2964 : 0 : return 0;
2965 : : }
2966 : :
2967 : : /* stop device first */
2968 : 0 : ret = hinic_dev_stop(dev);
2969 : :
2970 : : /* rx_cqe, rx_info */
2971 : 0 : hinic_free_all_rx_resources(dev);
2972 : :
2973 : : /* tx_info */
2974 : 0 : hinic_free_all_tx_resources(dev);
2975 : :
2976 : : /* free wq, pi_dma_addr */
2977 : : hinic_free_all_rq(nic_dev);
2978 : :
2979 : : /* free wq, db_addr */
2980 : : hinic_free_all_sq(nic_dev);
2981 : :
2982 : : /* deinit mac vlan tbl */
2983 : 0 : hinic_deinit_mac_addr(dev);
2984 : 0 : hinic_remove_all_vlanid(dev);
2985 : :
2986 : : /* disable hardware and uio interrupt */
2987 : 0 : hinic_disable_interrupt(dev);
2988 : :
2989 : : /* destroy rx mode mutex */
2990 : 0 : hinic_mutex_destroy(&nic_dev->rx_mode_mutex);
2991 : :
2992 : : /* deinit nic hardware device */
2993 : 0 : hinic_nic_dev_destroy(dev);
2994 : :
2995 : 0 : return ret;
2996 : : }
2997 : :
2998 : : static const struct eth_dev_ops hinic_pmd_ops = {
2999 : : .dev_configure = hinic_dev_configure,
3000 : : .dev_infos_get = hinic_dev_infos_get,
3001 : : .fw_version_get = hinic_fw_version_get,
3002 : : .rx_queue_setup = hinic_rx_queue_setup,
3003 : : .tx_queue_setup = hinic_tx_queue_setup,
3004 : : .dev_start = hinic_dev_start,
3005 : : .dev_set_link_up = hinic_dev_set_link_up,
3006 : : .dev_set_link_down = hinic_dev_set_link_down,
3007 : : .link_update = hinic_link_update,
3008 : : .rx_queue_release = hinic_rx_queue_release,
3009 : : .tx_queue_release = hinic_tx_queue_release,
3010 : : .dev_stop = hinic_dev_stop,
3011 : : .dev_close = hinic_dev_close,
3012 : : .mtu_set = hinic_dev_set_mtu,
3013 : : .vlan_filter_set = hinic_vlan_filter_set,
3014 : : .vlan_offload_set = hinic_vlan_offload_set,
3015 : : .allmulticast_enable = hinic_dev_allmulticast_enable,
3016 : : .allmulticast_disable = hinic_dev_allmulticast_disable,
3017 : : .promiscuous_enable = hinic_dev_promiscuous_enable,
3018 : : .promiscuous_disable = hinic_dev_promiscuous_disable,
3019 : : .flow_ctrl_get = hinic_flow_ctrl_get,
3020 : : .flow_ctrl_set = hinic_flow_ctrl_set,
3021 : : .rss_hash_update = hinic_rss_hash_update,
3022 : : .rss_hash_conf_get = hinic_rss_conf_get,
3023 : : .reta_update = hinic_rss_indirtbl_update,
3024 : : .reta_query = hinic_rss_indirtbl_query,
3025 : : .stats_get = hinic_dev_stats_get,
3026 : : .stats_reset = hinic_dev_stats_reset,
3027 : : .xstats_get = hinic_dev_xstats_get,
3028 : : .xstats_reset = hinic_dev_xstats_reset,
3029 : : .xstats_get_names = hinic_dev_xstats_get_names,
3030 : : .rxq_info_get = hinic_rxq_info_get,
3031 : : .txq_info_get = hinic_txq_info_get,
3032 : : .mac_addr_set = hinic_set_mac_addr,
3033 : : .mac_addr_remove = hinic_mac_addr_remove,
3034 : : .mac_addr_add = hinic_mac_addr_add,
3035 : : .set_mc_addr_list = hinic_set_mc_addr_list,
3036 : : .flow_ops_get = hinic_dev_flow_ops_get,
3037 : : };
3038 : :
3039 : : static const struct eth_dev_ops hinic_pmd_vf_ops = {
3040 : : .dev_configure = hinic_dev_configure,
3041 : : .dev_infos_get = hinic_dev_infos_get,
3042 : : .fw_version_get = hinic_fw_version_get,
3043 : : .rx_queue_setup = hinic_rx_queue_setup,
3044 : : .tx_queue_setup = hinic_tx_queue_setup,
3045 : : .dev_start = hinic_dev_start,
3046 : : .link_update = hinic_link_update,
3047 : : .rx_queue_release = hinic_rx_queue_release,
3048 : : .tx_queue_release = hinic_tx_queue_release,
3049 : : .dev_stop = hinic_dev_stop,
3050 : : .dev_close = hinic_dev_close,
3051 : : .mtu_set = hinic_dev_set_mtu,
3052 : : .vlan_filter_set = hinic_vlan_filter_set,
3053 : : .vlan_offload_set = hinic_vlan_offload_set,
3054 : : .allmulticast_enable = hinic_dev_allmulticast_enable,
3055 : : .allmulticast_disable = hinic_dev_allmulticast_disable,
3056 : : .rss_hash_update = hinic_rss_hash_update,
3057 : : .rss_hash_conf_get = hinic_rss_conf_get,
3058 : : .reta_update = hinic_rss_indirtbl_update,
3059 : : .reta_query = hinic_rss_indirtbl_query,
3060 : : .stats_get = hinic_dev_stats_get,
3061 : : .stats_reset = hinic_dev_stats_reset,
3062 : : .xstats_get = hinic_dev_xstats_get,
3063 : : .xstats_reset = hinic_dev_xstats_reset,
3064 : : .xstats_get_names = hinic_dev_xstats_get_names,
3065 : : .rxq_info_get = hinic_rxq_info_get,
3066 : : .txq_info_get = hinic_txq_info_get,
3067 : : .mac_addr_set = hinic_set_mac_addr,
3068 : : .mac_addr_remove = hinic_mac_addr_remove,
3069 : : .mac_addr_add = hinic_mac_addr_add,
3070 : : .set_mc_addr_list = hinic_set_mc_addr_list,
3071 : : .flow_ops_get = hinic_dev_flow_ops_get,
3072 : : };
3073 : :
3074 : : static const struct eth_dev_ops hinic_dev_sec_ops = {
3075 : : .dev_infos_get = hinic_dev_infos_get,
3076 : : };
3077 : :
3078 : 0 : static int hinic_func_init(struct rte_eth_dev *eth_dev)
3079 : : {
3080 : : struct rte_pci_device *pci_dev;
3081 : : struct rte_ether_addr *eth_addr;
3082 : : struct hinic_nic_dev *nic_dev;
3083 : : struct hinic_filter_info *filter_info;
3084 : : struct hinic_tcam_info *tcam_info;
3085 : : u32 mac_size;
3086 : : int rc;
3087 : :
3088 : 0 : pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
3089 : :
3090 : : /* EAL is SECONDARY and eth_dev is already created */
3091 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
3092 : 0 : eth_dev->dev_ops = &hinic_dev_sec_ops;
3093 : 0 : PMD_DRV_LOG(INFO, "Initialize %s in secondary process",
3094 : : eth_dev->data->name);
3095 : :
3096 : 0 : return 0;
3097 : : }
3098 : :
3099 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
3100 : :
3101 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
3102 : : memset(nic_dev, 0, sizeof(*nic_dev));
3103 : :
3104 : 0 : snprintf(nic_dev->proc_dev_name,
3105 : : sizeof(nic_dev->proc_dev_name),
3106 : : "hinic-" PCI_PRI_FMT,
3107 : 0 : pci_dev->addr.domain, pci_dev->addr.bus,
3108 : 0 : pci_dev->addr.devid, pci_dev->addr.function);
3109 : :
3110 : : /* alloc mac_addrs */
3111 : : mac_size = HINIC_MAX_UC_MAC_ADDRS * sizeof(struct rte_ether_addr);
3112 : 0 : eth_addr = rte_zmalloc("hinic_mac", mac_size, 0);
3113 [ # # ]: 0 : if (!eth_addr) {
3114 : 0 : PMD_DRV_LOG(ERR, "Allocate ethernet addresses' memory failed, dev_name: %s",
3115 : : eth_dev->data->name);
3116 : : rc = -ENOMEM;
3117 : 0 : goto eth_addr_fail;
3118 : : }
3119 : 0 : eth_dev->data->mac_addrs = eth_addr;
3120 : :
3121 : : mac_size = HINIC_MAX_MC_MAC_ADDRS * sizeof(struct rte_ether_addr);
3122 : 0 : nic_dev->mc_list = rte_zmalloc("hinic_mc", mac_size, 0);
3123 [ # # ]: 0 : if (!nic_dev->mc_list) {
3124 : 0 : PMD_DRV_LOG(ERR, "Allocate mcast address' memory failed, dev_name: %s",
3125 : : eth_dev->data->name);
3126 : : rc = -ENOMEM;
3127 : 0 : goto mc_addr_fail;
3128 : : }
3129 : :
3130 : : /* create hardware nic_device */
3131 : 0 : rc = hinic_nic_dev_create(eth_dev);
3132 [ # # ]: 0 : if (rc) {
3133 : 0 : PMD_DRV_LOG(ERR, "Create nic device failed, dev_name: %s",
3134 : : eth_dev->data->name);
3135 : 0 : goto create_nic_dev_fail;
3136 : : }
3137 : :
3138 [ # # ]: 0 : if (HINIC_IS_VF(nic_dev->hwdev))
3139 : 0 : eth_dev->dev_ops = &hinic_pmd_vf_ops;
3140 : : else
3141 : 0 : eth_dev->dev_ops = &hinic_pmd_ops;
3142 : :
3143 : 0 : rc = hinic_init_mac_addr(eth_dev);
3144 [ # # ]: 0 : if (rc) {
3145 : 0 : PMD_DRV_LOG(ERR, "Initialize mac table failed, dev_name: %s",
3146 : : eth_dev->data->name);
3147 : 0 : goto init_mac_fail;
3148 : : }
3149 : :
3150 : : /* register callback func to eal lib */
3151 : 0 : rc = rte_intr_callback_register(pci_dev->intr_handle,
3152 : : hinic_dev_interrupt_handler,
3153 : : (void *)eth_dev);
3154 [ # # ]: 0 : if (rc) {
3155 : 0 : PMD_DRV_LOG(ERR, "Register rte interrupt callback failed, dev_name: %s",
3156 : : eth_dev->data->name);
3157 : 0 : goto reg_intr_cb_fail;
3158 : : }
3159 : :
3160 : : /* enable uio/vfio intr/eventfd mapping */
3161 : 0 : rc = rte_intr_enable(pci_dev->intr_handle);
3162 [ # # ]: 0 : if (rc) {
3163 : 0 : PMD_DRV_LOG(ERR, "Enable rte interrupt failed, dev_name: %s",
3164 : : eth_dev->data->name);
3165 : 0 : goto enable_intr_fail;
3166 : : }
3167 : : rte_bit_relaxed_set32(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
3168 : :
3169 : 0 : hinic_mutex_init(&nic_dev->rx_mode_mutex, NULL);
3170 : :
3171 : : /* initialize filter info */
3172 : 0 : filter_info = &nic_dev->filter;
3173 : 0 : tcam_info = &nic_dev->tcam;
3174 : : memset(filter_info, 0, sizeof(struct hinic_filter_info));
3175 : : memset(tcam_info, 0, sizeof(struct hinic_tcam_info));
3176 : : /* initialize 5tuple filter list */
3177 : 0 : TAILQ_INIT(&filter_info->fivetuple_list);
3178 : 0 : TAILQ_INIT(&tcam_info->tcam_list);
3179 : 0 : TAILQ_INIT(&nic_dev->filter_ntuple_list);
3180 : 0 : TAILQ_INIT(&nic_dev->filter_ethertype_list);
3181 : 0 : TAILQ_INIT(&nic_dev->filter_fdir_rule_list);
3182 : 0 : TAILQ_INIT(&nic_dev->hinic_flow_list);
3183 : :
3184 : : rte_bit_relaxed_set32(HINIC_DEV_INIT, &nic_dev->dev_status);
3185 : 0 : PMD_DRV_LOG(INFO, "Initialize %s in primary successfully",
3186 : : eth_dev->data->name);
3187 : :
3188 : 0 : return 0;
3189 : :
3190 : : enable_intr_fail:
3191 : 0 : (void)rte_intr_callback_unregister(pci_dev->intr_handle,
3192 : : hinic_dev_interrupt_handler,
3193 : : (void *)eth_dev);
3194 : :
3195 : 0 : reg_intr_cb_fail:
3196 : 0 : hinic_deinit_mac_addr(eth_dev);
3197 : :
3198 : 0 : init_mac_fail:
3199 : 0 : eth_dev->dev_ops = NULL;
3200 : 0 : hinic_nic_dev_destroy(eth_dev);
3201 : :
3202 : 0 : create_nic_dev_fail:
3203 : 0 : rte_free(nic_dev->mc_list);
3204 : 0 : nic_dev->mc_list = NULL;
3205 : :
3206 : 0 : mc_addr_fail:
3207 : 0 : rte_free(eth_addr);
3208 : 0 : eth_dev->data->mac_addrs = NULL;
3209 : :
3210 : 0 : eth_addr_fail:
3211 : 0 : PMD_DRV_LOG(ERR, "Initialize %s in primary failed",
3212 : : eth_dev->data->name);
3213 : 0 : return rc;
3214 : : }
3215 : :
3216 : 0 : static int hinic_dev_init(struct rte_eth_dev *eth_dev)
3217 : : {
3218 : : struct rte_pci_device *pci_dev;
3219 : :
3220 : 0 : pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
3221 : :
3222 [ # # ]: 0 : PMD_DRV_LOG(INFO, "Initializing pf hinic-" PCI_PRI_FMT " in %s process",
3223 : : pci_dev->addr.domain, pci_dev->addr.bus,
3224 : : pci_dev->addr.devid, pci_dev->addr.function,
3225 : : (rte_eal_process_type() == RTE_PROC_PRIMARY) ?
3226 : : "primary" : "secondary");
3227 : :
3228 : : /* rte_eth_dev rx_burst and tx_burst */
3229 : 0 : eth_dev->rx_pkt_burst = hinic_recv_pkts;
3230 : 0 : eth_dev->tx_pkt_burst = hinic_xmit_pkts;
3231 : :
3232 : 0 : return hinic_func_init(eth_dev);
3233 : : }
3234 : :
3235 : 0 : static int hinic_dev_uninit(struct rte_eth_dev *dev)
3236 : : {
3237 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
3238 : : return 0;
3239 : :
3240 : 0 : hinic_dev_close(dev);
3241 : :
3242 : 0 : return HINIC_OK;
3243 : : }
3244 : :
3245 : : static struct rte_pci_id pci_id_hinic_map[] = {
3246 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_PRD) },
3247 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_25GE) },
3248 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_100GE) },
3249 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_VF) },
3250 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_VF_HV) },
3251 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_1822_DUAL_25GE) },
3252 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_1822_100GE) },
3253 : : {.vendor_id = 0},
3254 : : };
3255 : :
3256 : 0 : static int hinic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
3257 : : struct rte_pci_device *pci_dev)
3258 : : {
3259 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
3260 : : sizeof(struct hinic_nic_dev), hinic_dev_init);
3261 : : }
3262 : :
3263 : 0 : static int hinic_pci_remove(struct rte_pci_device *pci_dev)
3264 : : {
3265 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, hinic_dev_uninit);
3266 : : }
3267 : :
3268 : : static struct rte_pci_driver rte_hinic_pmd = {
3269 : : .id_table = pci_id_hinic_map,
3270 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
3271 : : .probe = hinic_pci_probe,
3272 : : .remove = hinic_pci_remove,
3273 : : };
3274 : :
3275 : 302 : RTE_PMD_REGISTER_PCI(net_hinic, rte_hinic_pmd);
3276 : : RTE_PMD_REGISTER_PCI_TABLE(net_hinic, pci_id_hinic_map);
3277 [ - + ]: 302 : RTE_LOG_REGISTER_DEFAULT(hinic_logtype, INFO);
|