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_ETH_DEV_TO_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 < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
1333 : 0 : nic_dev->num_rq : RTE_ETHDEV_QUEUE_STAT_CNTRS;
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->q_ipackets[i] = rxq_stats.packets;
1338 : 0 : qstats->q_ibytes[i] = rxq_stats.bytes;
1339 : 0 : qstats->q_errors[i] = rxq_stats.rx_discards;
1340 : :
1341 : 0 : stats->ierrors += rxq_stats.errors;
1342 : 0 : rx_discards_pmd += rxq_stats.rx_discards;
1343 : 0 : dev->data->rx_mbuf_alloc_failed += rxq_stats.rx_nombuf;
1344 : : }
1345 : :
1346 : : /* tx queue stats */
1347 : 0 : q_num = (nic_dev->num_sq < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
1348 : 0 : nic_dev->num_sq : RTE_ETHDEV_QUEUE_STAT_CNTRS;
1349 [ # # ]: 0 : for (i = 0; i < q_num; i++) {
1350 : 0 : txq = nic_dev->txqs[i];
1351 : 0 : hinic_txq_get_stats(txq, &txq_stats);
1352 : 0 : qstats->q_opackets[i] = txq_stats.packets;
1353 : 0 : qstats->q_obytes[i] = txq_stats.bytes;
1354 : 0 : stats->oerrors += (txq_stats.tx_busy + txq_stats.off_errs);
1355 : : }
1356 : : } else {
1357 : : /* Still aggregate error stats even without qstats */
1358 [ # # ]: 0 : for (i = 0; i < nic_dev->num_rq; i++) {
1359 : 0 : rxq = nic_dev->rxqs[i];
1360 : 0 : hinic_rxq_get_stats(rxq, &rxq_stats);
1361 : 0 : stats->ierrors += rxq_stats.errors;
1362 : 0 : rx_discards_pmd += rxq_stats.rx_discards;
1363 : 0 : dev->data->rx_mbuf_alloc_failed += rxq_stats.rx_nombuf;
1364 : : }
1365 [ # # ]: 0 : for (i = 0; i < nic_dev->num_sq; i++) {
1366 : 0 : txq = nic_dev->txqs[i];
1367 : 0 : hinic_txq_get_stats(txq, &txq_stats);
1368 : 0 : stats->oerrors += (txq_stats.tx_busy + txq_stats.off_errs);
1369 : : }
1370 : : }
1371 : :
1372 : : /* vport stats */
1373 : 0 : stats->oerrors += vport_stats.tx_discard_vport;
1374 : :
1375 : 0 : stats->imissed = vport_stats.rx_discard_vport + rx_discards_pmd;
1376 : :
1377 : 0 : stats->ipackets = (vport_stats.rx_unicast_pkts_vport +
1378 : 0 : vport_stats.rx_multicast_pkts_vport +
1379 : 0 : vport_stats.rx_broadcast_pkts_vport -
1380 : : rx_discards_pmd);
1381 : :
1382 : 0 : stats->opackets = (vport_stats.tx_unicast_pkts_vport +
1383 : 0 : vport_stats.tx_multicast_pkts_vport +
1384 : 0 : vport_stats.tx_broadcast_pkts_vport);
1385 : :
1386 : 0 : stats->ibytes = (vport_stats.rx_unicast_bytes_vport +
1387 : 0 : vport_stats.rx_multicast_bytes_vport +
1388 : 0 : vport_stats.rx_broadcast_bytes_vport);
1389 : :
1390 : 0 : stats->obytes = (vport_stats.tx_unicast_bytes_vport +
1391 : 0 : vport_stats.tx_multicast_bytes_vport +
1392 : 0 : vport_stats.tx_broadcast_bytes_vport);
1393 : 0 : return 0;
1394 : : }
1395 : :
1396 : : /**
1397 : : * DPDK callback to clear device statistics.
1398 : : *
1399 : : * @param dev
1400 : : * Pointer to Ethernet device structure.
1401 : : */
1402 : 0 : static int hinic_dev_stats_reset(struct rte_eth_dev *dev)
1403 : : {
1404 : : int qid;
1405 : : struct hinic_rxq *rxq = NULL;
1406 : : struct hinic_txq *txq = NULL;
1407 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1408 : : int ret;
1409 : :
1410 : 0 : ret = hinic_clear_vport_stats(nic_dev->hwdev);
1411 [ # # ]: 0 : if (ret != 0)
1412 : : return ret;
1413 : :
1414 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_rq; qid++) {
1415 : 0 : rxq = nic_dev->rxqs[qid];
1416 : 0 : hinic_rxq_stats_reset(rxq);
1417 : : }
1418 : :
1419 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_sq; qid++) {
1420 : 0 : txq = nic_dev->txqs[qid];
1421 : 0 : hinic_txq_stats_reset(txq);
1422 : : }
1423 : :
1424 : : return 0;
1425 : : }
1426 : :
1427 : : /**
1428 : : * DPDK callback to clear device extended statistics.
1429 : : *
1430 : : * @param dev
1431 : : * Pointer to Ethernet device structure.
1432 : : */
1433 : 0 : static int hinic_dev_xstats_reset(struct rte_eth_dev *dev)
1434 : : {
1435 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1436 : : int ret;
1437 : :
1438 : 0 : ret = hinic_dev_stats_reset(dev);
1439 [ # # ]: 0 : if (ret != 0)
1440 : : return ret;
1441 : :
1442 [ # # ]: 0 : if (hinic_func_type(nic_dev->hwdev) != TYPE_VF) {
1443 : 0 : ret = hinic_clear_phy_port_stats(nic_dev->hwdev);
1444 [ # # ]: 0 : if (ret != 0)
1445 : 0 : return ret;
1446 : : }
1447 : :
1448 : : return 0;
1449 : : }
1450 : :
1451 : 0 : static void hinic_gen_random_mac_addr(struct rte_ether_addr *mac_addr)
1452 : : {
1453 : : uint64_t random_value;
1454 : :
1455 : : /* Set Organizationally Unique Identifier (OUI) prefix */
1456 : : mac_addr->addr_bytes[0] = 0x00;
1457 : 0 : mac_addr->addr_bytes[1] = 0x09;
1458 : 0 : mac_addr->addr_bytes[2] = 0xC0;
1459 : : /* Force indication of locally assigned MAC address. */
1460 : 0 : mac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;
1461 : : /* Generate the last 3 bytes of the MAC address with a random number. */
1462 : 0 : random_value = rte_rand();
1463 : 0 : memcpy(&mac_addr->addr_bytes[3], &random_value, 3);
1464 : 0 : }
1465 : :
1466 : : /**
1467 : : * Init mac_vlan table in NIC.
1468 : : *
1469 : : * @param dev
1470 : : * Pointer to Ethernet device structure.
1471 : : *
1472 : : * @return
1473 : : * 0 on success and stats is filled,
1474 : : * negative error value otherwise.
1475 : : */
1476 : 0 : static int hinic_init_mac_addr(struct rte_eth_dev *eth_dev)
1477 : : {
1478 : 0 : struct hinic_nic_dev *nic_dev =
1479 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
1480 : : uint8_t addr_bytes[RTE_ETHER_ADDR_LEN];
1481 : : u16 func_id = 0;
1482 : : int rc = 0;
1483 : :
1484 : 0 : rc = hinic_get_default_mac(nic_dev->hwdev, addr_bytes);
1485 [ # # ]: 0 : if (rc)
1486 : : return rc;
1487 : :
1488 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)addr_bytes,
1489 [ # # ]: 0 : ð_dev->data->mac_addrs[0]);
1490 [ # # ]: 0 : if (rte_is_zero_ether_addr(ð_dev->data->mac_addrs[0]))
1491 : 0 : hinic_gen_random_mac_addr(ð_dev->data->mac_addrs[0]);
1492 : :
1493 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1494 : 0 : rc = hinic_set_mac(nic_dev->hwdev,
1495 : 0 : eth_dev->data->mac_addrs[0].addr_bytes,
1496 : : 0, func_id);
1497 [ # # ]: 0 : if (rc && rc != HINIC_PF_SET_VF_ALREADY)
1498 : : return rc;
1499 : :
1500 : 0 : rte_ether_addr_copy(ð_dev->data->mac_addrs[0],
1501 : : &nic_dev->default_addr);
1502 : :
1503 : 0 : return 0;
1504 : : }
1505 : :
1506 : 0 : static void hinic_delete_mc_addr_list(struct hinic_nic_dev *nic_dev)
1507 : : {
1508 : : u16 func_id;
1509 : : u32 i;
1510 : :
1511 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1512 : :
1513 [ # # ]: 0 : for (i = 0; i < HINIC_MAX_MC_MAC_ADDRS; i++) {
1514 [ # # ]: 0 : if (rte_is_zero_ether_addr(&nic_dev->mc_list[i]))
1515 : : break;
1516 : :
1517 : 0 : hinic_del_mac(nic_dev->hwdev, nic_dev->mc_list[i].addr_bytes,
1518 : : 0, func_id);
1519 : 0 : memset(&nic_dev->mc_list[i], 0, sizeof(struct rte_ether_addr));
1520 : : }
1521 : 0 : }
1522 : :
1523 : : /**
1524 : : * Deinit mac_vlan table in NIC.
1525 : : *
1526 : : * @param dev
1527 : : * Pointer to Ethernet device structure.
1528 : : *
1529 : : * @return
1530 : : * 0 on success and stats is filled,
1531 : : * negative error value otherwise.
1532 : : */
1533 : 0 : static void hinic_deinit_mac_addr(struct rte_eth_dev *eth_dev)
1534 : : {
1535 : 0 : struct hinic_nic_dev *nic_dev =
1536 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
1537 : : u16 func_id = 0;
1538 : : int rc;
1539 : : int i;
1540 : :
1541 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1542 : :
1543 [ # # ]: 0 : for (i = 0; i < HINIC_MAX_UC_MAC_ADDRS; i++) {
1544 [ # # ]: 0 : if (rte_is_zero_ether_addr(ð_dev->data->mac_addrs[i]))
1545 : 0 : continue;
1546 : :
1547 : 0 : rc = hinic_del_mac(nic_dev->hwdev,
1548 : 0 : eth_dev->data->mac_addrs[i].addr_bytes,
1549 : : 0, func_id);
1550 [ # # ]: 0 : if (rc && rc != HINIC_PF_SET_VF_ALREADY)
1551 : 0 : PMD_DRV_LOG(ERR, "Delete mac table failed, dev_name: %s",
1552 : : eth_dev->data->name);
1553 : :
1554 : 0 : memset(ð_dev->data->mac_addrs[i], 0,
1555 : : sizeof(struct rte_ether_addr));
1556 : : }
1557 : :
1558 : : /* delete multicast mac addrs */
1559 : 0 : hinic_delete_mc_addr_list(nic_dev);
1560 : :
1561 : 0 : rte_free(nic_dev->mc_list);
1562 : :
1563 : 0 : }
1564 : :
1565 : 0 : static int hinic_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
1566 : : {
1567 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1568 : : int ret;
1569 : :
1570 : 0 : PMD_DRV_LOG(INFO, "Set port mtu, port_id: %d, mtu: %d, max_pkt_len: %d",
1571 : : dev->data->port_id, mtu, HINIC_MTU_TO_PKTLEN(mtu));
1572 : :
1573 : 0 : ret = hinic_set_port_mtu(nic_dev->hwdev, mtu);
1574 [ # # ]: 0 : if (ret) {
1575 : 0 : PMD_DRV_LOG(ERR, "Set port mtu failed, ret: %d", ret);
1576 : 0 : return ret;
1577 : : }
1578 : :
1579 : 0 : nic_dev->mtu_size = mtu;
1580 : :
1581 : 0 : return ret;
1582 : : }
1583 : :
1584 : : static void hinic_store_vlan_filter(struct hinic_nic_dev *nic_dev,
1585 : : u16 vlan_id, bool on)
1586 : : {
1587 : : u32 vid_idx, vid_bit;
1588 : :
1589 : 0 : vid_idx = HINIC_VFTA_IDX(vlan_id);
1590 : 0 : vid_bit = HINIC_VFTA_BIT(vlan_id);
1591 : :
1592 : 0 : if (on)
1593 : 0 : nic_dev->vfta[vid_idx] |= vid_bit;
1594 : : else
1595 : 0 : nic_dev->vfta[vid_idx] &= ~vid_bit;
1596 : : }
1597 : :
1598 : : static bool hinic_find_vlan_filter(struct hinic_nic_dev *nic_dev,
1599 : : uint16_t vlan_id)
1600 : : {
1601 : : u32 vid_idx, vid_bit;
1602 : :
1603 : 0 : vid_idx = HINIC_VFTA_IDX(vlan_id);
1604 : 0 : vid_bit = HINIC_VFTA_BIT(vlan_id);
1605 : :
1606 : 0 : return (nic_dev->vfta[vid_idx] & vid_bit) ? TRUE : FALSE;
1607 : : }
1608 : :
1609 : : /**
1610 : : * DPDK callback to set vlan filter.
1611 : : *
1612 : : * @param dev
1613 : : * Pointer to Ethernet device structure.
1614 : : * @param vlan_id
1615 : : * vlan id is used to filter vlan packets
1616 : : * @param enable
1617 : : * enable disable or enable vlan filter function
1618 : : */
1619 : 0 : static int hinic_vlan_filter_set(struct rte_eth_dev *dev,
1620 : : uint16_t vlan_id, int enable)
1621 : : {
1622 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1623 : : int err = 0;
1624 : : u16 func_id;
1625 : :
1626 [ # # ]: 0 : if (vlan_id > RTE_ETHER_MAX_VLAN_ID)
1627 : : return -EINVAL;
1628 : :
1629 [ # # ]: 0 : if (vlan_id == 0)
1630 : : return 0;
1631 : :
1632 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1633 : :
1634 [ # # ]: 0 : if (enable) {
1635 : : /* If vlanid is already set, just return */
1636 [ # # ]: 0 : if (hinic_find_vlan_filter(nic_dev, vlan_id)) {
1637 : 0 : PMD_DRV_LOG(INFO, "Vlan %u has been added, device: %s",
1638 : : vlan_id, nic_dev->proc_dev_name);
1639 : 0 : return 0;
1640 : : }
1641 : :
1642 : 0 : err = hinic_add_remove_vlan(nic_dev->hwdev, vlan_id,
1643 : : func_id, TRUE);
1644 : : } else {
1645 : : /* If vlanid can't be found, just return */
1646 [ # # ]: 0 : if (!hinic_find_vlan_filter(nic_dev, vlan_id)) {
1647 : 0 : PMD_DRV_LOG(INFO, "Vlan %u is not in the vlan filter list, device: %s",
1648 : : vlan_id, nic_dev->proc_dev_name);
1649 : 0 : return 0;
1650 : : }
1651 : :
1652 : 0 : err = hinic_add_remove_vlan(nic_dev->hwdev, vlan_id,
1653 : : func_id, FALSE);
1654 : : }
1655 : :
1656 [ # # ]: 0 : if (err) {
1657 [ # # ]: 0 : PMD_DRV_LOG(ERR, "%s vlan failed, func_id: %d, vlan_id: %d, err: %d",
1658 : : enable ? "Add" : "Remove", func_id, vlan_id, err);
1659 : 0 : return err;
1660 : : }
1661 : :
1662 [ # # ]: 0 : hinic_store_vlan_filter(nic_dev, vlan_id, enable);
1663 : :
1664 [ # # ]: 0 : PMD_DRV_LOG(INFO, "%s vlan %u succeed, device: %s",
1665 : : enable ? "Add" : "Remove", vlan_id, nic_dev->proc_dev_name);
1666 : 0 : return 0;
1667 : : }
1668 : :
1669 : : /**
1670 : : * DPDK callback to enable or disable vlan offload.
1671 : : *
1672 : : * @param dev
1673 : : * Pointer to Ethernet device structure.
1674 : : * @param mask
1675 : : * Definitions used for VLAN setting
1676 : : */
1677 : 0 : static int hinic_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1678 : : {
1679 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1680 : : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
1681 : : bool on;
1682 : : int err;
1683 : :
1684 : : /* Enable or disable VLAN filter */
1685 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
1686 : 0 : on = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) ?
1687 : 0 : TRUE : FALSE;
1688 : 0 : err = hinic_config_vlan_filter(nic_dev->hwdev, on);
1689 [ # # ]: 0 : if (err == HINIC_MGMT_CMD_UNSUPPORTED) {
1690 : 0 : PMD_DRV_LOG(WARNING,
1691 : : "Current matching version does not support vlan filter configuration, device: %s, port_id: %d",
1692 : : nic_dev->proc_dev_name, dev->data->port_id);
1693 [ # # ]: 0 : } else if (err) {
1694 [ # # ]: 0 : PMD_DRV_LOG(ERR, "Failed to %s vlan filter, device: %s, port_id: %d, err: %d",
1695 : : on ? "enable" : "disable",
1696 : : nic_dev->proc_dev_name,
1697 : : dev->data->port_id, err);
1698 : 0 : return err;
1699 : : }
1700 : :
1701 [ # # ]: 0 : PMD_DRV_LOG(INFO, "%s vlan filter succeed, device: %s, port_id: %d",
1702 : : on ? "Enable" : "Disable",
1703 : : nic_dev->proc_dev_name, dev->data->port_id);
1704 : : }
1705 : :
1706 : : /* Enable or disable VLAN stripping */
1707 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1708 : 0 : on = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) ?
1709 : 0 : TRUE : FALSE;
1710 : 0 : err = hinic_set_rx_vlan_offload(nic_dev->hwdev, on);
1711 [ # # ]: 0 : if (err) {
1712 [ # # ]: 0 : PMD_DRV_LOG(ERR, "Failed to %s vlan strip, device: %s, port_id: %d, err: %d",
1713 : : on ? "enable" : "disable",
1714 : : nic_dev->proc_dev_name,
1715 : : dev->data->port_id, err);
1716 : 0 : return err;
1717 : : }
1718 : :
1719 [ # # ]: 0 : PMD_DRV_LOG(INFO, "%s vlan strip succeed, device: %s, port_id: %d",
1720 : : on ? "Enable" : "Disable",
1721 : : nic_dev->proc_dev_name, dev->data->port_id);
1722 : : }
1723 : :
1724 : : return 0;
1725 : : }
1726 : :
1727 : 0 : static void hinic_remove_all_vlanid(struct rte_eth_dev *eth_dev)
1728 : : {
1729 : 0 : struct hinic_nic_dev *nic_dev =
1730 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
1731 : : u16 func_id;
1732 : : int i;
1733 : :
1734 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
1735 [ # # ]: 0 : for (i = 0; i <= RTE_ETHER_MAX_VLAN_ID; i++) {
1736 : : /* If can't find it, continue */
1737 [ # # ]: 0 : if (!hinic_find_vlan_filter(nic_dev, i))
1738 : 0 : continue;
1739 : :
1740 : 0 : (void)hinic_add_remove_vlan(nic_dev->hwdev, i, func_id, FALSE);
1741 : : hinic_store_vlan_filter(nic_dev, i, false);
1742 : : }
1743 : 0 : }
1744 : :
1745 : 0 : static int hinic_set_dev_allmulticast(struct hinic_nic_dev *nic_dev,
1746 : : bool enable)
1747 : : {
1748 : : u32 rx_mode_ctrl;
1749 : : int err;
1750 : :
1751 : 0 : err = hinic_mutex_lock(&nic_dev->rx_mode_mutex);
1752 [ # # ]: 0 : if (err)
1753 : : return err;
1754 : :
1755 : 0 : rx_mode_ctrl = nic_dev->rx_mode_status;
1756 : :
1757 [ # # ]: 0 : if (enable)
1758 : 0 : rx_mode_ctrl |= HINIC_RX_MODE_MC_ALL;
1759 : : else
1760 : 0 : rx_mode_ctrl &= (~HINIC_RX_MODE_MC_ALL);
1761 : :
1762 : 0 : err = hinic_config_rx_mode(nic_dev, rx_mode_ctrl);
1763 : :
1764 : : (void)hinic_mutex_unlock(&nic_dev->rx_mode_mutex);
1765 : :
1766 : 0 : return err;
1767 : : }
1768 : :
1769 : : /**
1770 : : * DPDK callback to enable allmulticast mode.
1771 : : *
1772 : : * @param dev
1773 : : * Pointer to Ethernet device structure.
1774 : : *
1775 : : * @return
1776 : : * 0 on success,
1777 : : * negative error value otherwise.
1778 : : */
1779 : 0 : static int hinic_dev_allmulticast_enable(struct rte_eth_dev *dev)
1780 : : {
1781 : : int ret = HINIC_OK;
1782 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1783 : :
1784 : 0 : ret = hinic_set_dev_allmulticast(nic_dev, true);
1785 [ # # ]: 0 : if (ret) {
1786 : 0 : PMD_DRV_LOG(ERR, "Enable allmulticast failed, error: %d", ret);
1787 : 0 : return ret;
1788 : : }
1789 : :
1790 : 0 : PMD_DRV_LOG(INFO, "Enable allmulticast succeed, nic_dev: %s, port_id: %d",
1791 : : nic_dev->proc_dev_name, dev->data->port_id);
1792 : 0 : return 0;
1793 : : }
1794 : :
1795 : : /**
1796 : : * DPDK callback to disable allmulticast mode.
1797 : : *
1798 : : * @param dev
1799 : : * Pointer to Ethernet device structure.
1800 : : *
1801 : : * @return
1802 : : * 0 on success,
1803 : : * negative error value otherwise.
1804 : : */
1805 : 0 : static int hinic_dev_allmulticast_disable(struct rte_eth_dev *dev)
1806 : : {
1807 : : int ret = HINIC_OK;
1808 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1809 : :
1810 : 0 : ret = hinic_set_dev_allmulticast(nic_dev, false);
1811 [ # # ]: 0 : if (ret) {
1812 : 0 : PMD_DRV_LOG(ERR, "Disable allmulticast failed, error: %d", ret);
1813 : 0 : return ret;
1814 : : }
1815 : :
1816 : 0 : PMD_DRV_LOG(INFO, "Disable allmulticast succeed, nic_dev: %s, port_id: %d",
1817 : : nic_dev->proc_dev_name, dev->data->port_id);
1818 : 0 : return 0;
1819 : : }
1820 : :
1821 : : /**
1822 : : * DPDK callback to enable promiscuous mode.
1823 : : *
1824 : : * @param dev
1825 : : * Pointer to Ethernet device structure.
1826 : : *
1827 : : * @return
1828 : : * 0 on success,
1829 : : * negative error value otherwise.
1830 : : */
1831 : 0 : static int hinic_dev_promiscuous_enable(struct rte_eth_dev *dev)
1832 : : {
1833 : : int rc = HINIC_OK;
1834 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1835 : :
1836 : 0 : PMD_DRV_LOG(INFO, "Enable promiscuous, nic_dev: %s, port_id: %d, promisc: %d",
1837 : : nic_dev->proc_dev_name, dev->data->port_id,
1838 : : dev->data->promiscuous);
1839 : :
1840 : 0 : rc = hinic_set_dev_promiscuous(nic_dev, true);
1841 [ # # ]: 0 : if (rc)
1842 : 0 : PMD_DRV_LOG(ERR, "Enable promiscuous failed");
1843 : :
1844 : 0 : return rc;
1845 : : }
1846 : :
1847 : : /**
1848 : : * DPDK callback to disable promiscuous mode.
1849 : : *
1850 : : * @param dev
1851 : : * Pointer to Ethernet device structure.
1852 : : *
1853 : : * @return
1854 : : * 0 on success,
1855 : : * negative error value otherwise.
1856 : : */
1857 : 0 : static int hinic_dev_promiscuous_disable(struct rte_eth_dev *dev)
1858 : : {
1859 : : int rc = HINIC_OK;
1860 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1861 : :
1862 : 0 : PMD_DRV_LOG(INFO, "Disable promiscuous, nic_dev: %s, port_id: %d, promisc: %d",
1863 : : nic_dev->proc_dev_name, dev->data->port_id,
1864 : : dev->data->promiscuous);
1865 : :
1866 : 0 : rc = hinic_set_dev_promiscuous(nic_dev, false);
1867 [ # # ]: 0 : if (rc)
1868 : 0 : PMD_DRV_LOG(ERR, "Disable promiscuous failed");
1869 : :
1870 : 0 : return rc;
1871 : : }
1872 : :
1873 : 0 : static int hinic_flow_ctrl_get(struct rte_eth_dev *dev,
1874 : : struct rte_eth_fc_conf *fc_conf)
1875 : : {
1876 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1877 : : struct nic_pause_config nic_pause;
1878 : : int err;
1879 : :
1880 : : memset(&nic_pause, 0, sizeof(nic_pause));
1881 : :
1882 : 0 : err = hinic_get_pause_info(nic_dev->hwdev, &nic_pause);
1883 [ # # ]: 0 : if (err)
1884 : : return err;
1885 : :
1886 [ # # # # ]: 0 : if (nic_dev->pause_set || !nic_pause.auto_neg) {
1887 : 0 : nic_pause.rx_pause = nic_dev->nic_pause.rx_pause;
1888 : 0 : nic_pause.tx_pause = nic_dev->nic_pause.tx_pause;
1889 : : }
1890 : :
1891 : 0 : fc_conf->autoneg = nic_pause.auto_neg;
1892 : :
1893 [ # # # # ]: 0 : if (nic_pause.tx_pause && nic_pause.rx_pause)
1894 : 0 : fc_conf->mode = RTE_ETH_FC_FULL;
1895 [ # # ]: 0 : else if (nic_pause.tx_pause)
1896 : 0 : fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
1897 [ # # ]: 0 : else if (nic_pause.rx_pause)
1898 : 0 : fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
1899 : : else
1900 : 0 : fc_conf->mode = RTE_ETH_FC_NONE;
1901 : :
1902 : : return 0;
1903 : : }
1904 : :
1905 : 0 : static int hinic_flow_ctrl_set(struct rte_eth_dev *dev,
1906 : : struct rte_eth_fc_conf *fc_conf)
1907 : : {
1908 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1909 : : struct nic_pause_config nic_pause;
1910 : : int err;
1911 : :
1912 : 0 : nic_pause.auto_neg = fc_conf->autoneg;
1913 : :
1914 [ # # ]: 0 : if (((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL) ||
1915 [ # # ]: 0 : (fc_conf->mode & RTE_ETH_FC_TX_PAUSE))
1916 : : nic_pause.tx_pause = true;
1917 : : else
1918 : : nic_pause.tx_pause = false;
1919 : :
1920 [ # # ]: 0 : if (((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL) ||
1921 [ # # ]: 0 : (fc_conf->mode & RTE_ETH_FC_RX_PAUSE))
1922 : : nic_pause.rx_pause = true;
1923 : : else
1924 : : nic_pause.rx_pause = false;
1925 : :
1926 : 0 : err = hinic_set_pause_config(nic_dev->hwdev, nic_pause);
1927 [ # # ]: 0 : if (err)
1928 : : return err;
1929 : :
1930 : 0 : nic_dev->pause_set = true;
1931 : 0 : nic_dev->nic_pause.auto_neg = nic_pause.auto_neg;
1932 : 0 : nic_dev->nic_pause.rx_pause = nic_pause.rx_pause;
1933 : 0 : nic_dev->nic_pause.tx_pause = nic_pause.tx_pause;
1934 : :
1935 [ # # # # : 0 : PMD_DRV_LOG(INFO, "Set pause options, tx: %s, rx: %s, auto: %s",
# # ]
1936 : : nic_pause.tx_pause ? "on" : "off",
1937 : : nic_pause.rx_pause ? "on" : "off",
1938 : : nic_pause.auto_neg ? "on" : "off");
1939 : :
1940 : 0 : return 0;
1941 : : }
1942 : :
1943 : : /**
1944 : : * DPDK callback to update the RSS hash key and RSS hash type.
1945 : : *
1946 : : * @param dev
1947 : : * Pointer to Ethernet device structure.
1948 : : * @param rss_conf
1949 : : * RSS configuration data.
1950 : : *
1951 : : * @return
1952 : : * 0 on success, negative error value otherwise.
1953 : : */
1954 : 0 : static int hinic_rss_hash_update(struct rte_eth_dev *dev,
1955 : : struct rte_eth_rss_conf *rss_conf)
1956 : : {
1957 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
1958 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
1959 : 0 : u8 hashkey[HINIC_RSS_KEY_SIZE] = {0};
1960 : 0 : u8 prio_tc[HINIC_DCB_UP_MAX] = {0};
1961 : 0 : u64 rss_hf = rss_conf->rss_hf;
1962 : 0 : struct nic_rss_type rss_type = {0};
1963 : : int err = 0;
1964 : :
1965 [ # # ]: 0 : if (!(nic_dev->flags & RTE_ETH_MQ_RX_RSS_FLAG)) {
1966 : 0 : PMD_DRV_LOG(WARNING, "RSS is not enabled");
1967 : 0 : return HINIC_OK;
1968 : : }
1969 : :
1970 [ # # ]: 0 : if (rss_conf->rss_key_len > HINIC_RSS_KEY_SIZE) {
1971 : 0 : PMD_DRV_LOG(ERR, "Invalid rss key, rss_key_len: %d",
1972 : : rss_conf->rss_key_len);
1973 : 0 : return HINIC_ERROR;
1974 : : }
1975 : :
1976 [ # # ]: 0 : if (rss_conf->rss_key) {
1977 : 0 : memcpy(hashkey, rss_conf->rss_key, rss_conf->rss_key_len);
1978 : 0 : err = hinic_rss_set_template_tbl(nic_dev->hwdev, tmpl_idx,
1979 : : hashkey);
1980 [ # # ]: 0 : if (err) {
1981 : 0 : PMD_DRV_LOG(ERR, "Set rss template table failed");
1982 : 0 : goto disable_rss;
1983 : : }
1984 : : }
1985 : :
1986 : 0 : rss_type.ipv4 = (rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4)) ? 1 : 0;
1987 : 0 : rss_type.tcp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0;
1988 : 0 : rss_type.ipv6 = (rss_hf & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6)) ? 1 : 0;
1989 : 0 : rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0;
1990 : 0 : rss_type.tcp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0;
1991 : 0 : rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0;
1992 : 0 : rss_type.udp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0;
1993 : 0 : rss_type.udp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0;
1994 : :
1995 : 0 : err = hinic_set_rss_type(nic_dev->hwdev, tmpl_idx, rss_type);
1996 [ # # ]: 0 : if (err) {
1997 : 0 : PMD_DRV_LOG(ERR, "Set rss type table failed");
1998 : 0 : goto disable_rss;
1999 : : }
2000 : :
2001 : : return 0;
2002 : :
2003 : 0 : disable_rss:
2004 : : memset(prio_tc, 0, sizeof(prio_tc));
2005 : 0 : (void)hinic_rss_cfg(nic_dev->hwdev, 0, tmpl_idx, 0, prio_tc);
2006 : 0 : return err;
2007 : : }
2008 : :
2009 : : /**
2010 : : * DPDK callback to get the RSS hash configuration.
2011 : : *
2012 : : * @param dev
2013 : : * Pointer to Ethernet device structure.
2014 : : * @param rss_conf
2015 : : * RSS configuration data.
2016 : : *
2017 : : * @return
2018 : : * 0 on success, negative error value otherwise.
2019 : : */
2020 : 0 : static int hinic_rss_conf_get(struct rte_eth_dev *dev,
2021 : : struct rte_eth_rss_conf *rss_conf)
2022 : : {
2023 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2024 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
2025 : 0 : u8 hashkey[HINIC_RSS_KEY_SIZE] = {0};
2026 : 0 : struct nic_rss_type rss_type = {0};
2027 : : int err;
2028 : :
2029 [ # # ]: 0 : if (!(nic_dev->flags & RTE_ETH_MQ_RX_RSS_FLAG)) {
2030 : 0 : PMD_DRV_LOG(WARNING, "RSS is not enabled");
2031 : 0 : return HINIC_ERROR;
2032 : : }
2033 : :
2034 : 0 : err = hinic_rss_get_template_tbl(nic_dev->hwdev, tmpl_idx, hashkey);
2035 [ # # ]: 0 : if (err)
2036 : : return err;
2037 : :
2038 [ # # ]: 0 : if (rss_conf->rss_key &&
2039 [ # # ]: 0 : rss_conf->rss_key_len >= HINIC_RSS_KEY_SIZE) {
2040 : : memcpy(rss_conf->rss_key, hashkey, sizeof(hashkey));
2041 : 0 : rss_conf->rss_key_len = sizeof(hashkey);
2042 : : }
2043 : :
2044 : 0 : err = hinic_get_rss_type(nic_dev->hwdev, tmpl_idx, &rss_type);
2045 [ # # ]: 0 : if (err)
2046 : : return err;
2047 : :
2048 : : rss_conf->rss_hf = 0;
2049 : 0 : rss_conf->rss_hf |= rss_type.ipv4 ?
2050 [ # # ]: 0 : (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4) : 0;
2051 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv4 ? RTE_ETH_RSS_NONFRAG_IPV4_TCP : 0;
2052 : 0 : rss_conf->rss_hf |= rss_type.ipv6 ?
2053 [ # # ]: 0 : (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6) : 0;
2054 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.ipv6_ext ? RTE_ETH_RSS_IPV6_EX : 0;
2055 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_TCP : 0;
2056 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.tcp_ipv6_ext ? RTE_ETH_RSS_IPV6_TCP_EX : 0;
2057 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.udp_ipv4 ? RTE_ETH_RSS_NONFRAG_IPV4_UDP : 0;
2058 [ # # ]: 0 : rss_conf->rss_hf |= rss_type.udp_ipv6 ? RTE_ETH_RSS_NONFRAG_IPV6_UDP : 0;
2059 : :
2060 : 0 : return HINIC_OK;
2061 : : }
2062 : :
2063 : : /**
2064 : : * DPDK callback to update the RSS redirection table.
2065 : : *
2066 : : * @param dev
2067 : : * Pointer to Ethernet device structure.
2068 : : * @param reta_conf
2069 : : * Pointer to RSS reta configuration data.
2070 : : * @param reta_size
2071 : : * Size of the RETA table.
2072 : : *
2073 : : * @return
2074 : : * 0 on success, negative error value otherwise.
2075 : : */
2076 : 0 : static int hinic_rss_indirtbl_update(struct rte_eth_dev *dev,
2077 : : struct rte_eth_rss_reta_entry64 *reta_conf,
2078 : : uint16_t reta_size)
2079 : : {
2080 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2081 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
2082 : 0 : u8 prio_tc[HINIC_DCB_UP_MAX] = {0};
2083 : 0 : u32 indirtbl[NIC_RSS_INDIR_SIZE] = {0};
2084 : : int err = 0;
2085 : : u16 i = 0;
2086 : : u16 idx, shift;
2087 : :
2088 [ # # ]: 0 : if (!(nic_dev->flags & RTE_ETH_MQ_RX_RSS_FLAG))
2089 : : return HINIC_OK;
2090 : :
2091 [ # # ]: 0 : if (reta_size != NIC_RSS_INDIR_SIZE) {
2092 : 0 : PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
2093 : 0 : return HINIC_ERROR;
2094 : : }
2095 : :
2096 : 0 : err = hinic_rss_get_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl);
2097 [ # # ]: 0 : if (err)
2098 : : return err;
2099 : :
2100 : : /* update rss indir_tbl */
2101 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
2102 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
2103 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
2104 : :
2105 [ # # ]: 0 : if (reta_conf[idx].reta[shift] >= nic_dev->num_rq) {
2106 : 0 : PMD_DRV_LOG(ERR, "Invalid reta entry, indirtbl[%d]: %d "
2107 : : "exceeds the maximum rxq num: %d", i,
2108 : : reta_conf[idx].reta[shift], nic_dev->num_rq);
2109 : 0 : return -EINVAL;
2110 : : }
2111 : :
2112 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
2113 : 0 : indirtbl[i] = reta_conf[idx].reta[shift];
2114 : : }
2115 : :
2116 : 0 : err = hinic_rss_set_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl);
2117 [ # # ]: 0 : if (err)
2118 : 0 : goto disable_rss;
2119 : :
2120 : 0 : nic_dev->rss_indir_flag = true;
2121 : :
2122 : 0 : return 0;
2123 : :
2124 : : disable_rss:
2125 : : memset(prio_tc, 0, sizeof(prio_tc));
2126 : 0 : (void)hinic_rss_cfg(nic_dev->hwdev, 0, tmpl_idx, 0, prio_tc);
2127 : :
2128 : 0 : return HINIC_ERROR;
2129 : : }
2130 : :
2131 : : /**
2132 : : * DPDK callback to get the RSS indirection table.
2133 : : *
2134 : : * @param dev
2135 : : * Pointer to Ethernet device structure.
2136 : : * @param reta_conf
2137 : : * Pointer to RSS reta configuration data.
2138 : : * @param reta_size
2139 : : * Size of the RETA table.
2140 : : *
2141 : : * @return
2142 : : * 0 on success, negative error value otherwise.
2143 : : */
2144 : 0 : static int hinic_rss_indirtbl_query(struct rte_eth_dev *dev,
2145 : : struct rte_eth_rss_reta_entry64 *reta_conf,
2146 : : uint16_t reta_size)
2147 : : {
2148 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2149 : 0 : u8 tmpl_idx = nic_dev->rss_tmpl_idx;
2150 : : int err = 0;
2151 : 0 : u32 indirtbl[NIC_RSS_INDIR_SIZE] = {0};
2152 : : u16 idx, shift;
2153 : : u16 i = 0;
2154 : :
2155 [ # # ]: 0 : if (reta_size != NIC_RSS_INDIR_SIZE) {
2156 : 0 : PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size);
2157 : 0 : return HINIC_ERROR;
2158 : : }
2159 : :
2160 : 0 : err = hinic_rss_get_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl);
2161 [ # # ]: 0 : if (err) {
2162 : 0 : PMD_DRV_LOG(ERR, "Get rss indirect table failed, error: %d",
2163 : : err);
2164 : 0 : return err;
2165 : : }
2166 : :
2167 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
2168 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
2169 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
2170 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
2171 : 0 : reta_conf[idx].reta[shift] = (uint16_t)indirtbl[i];
2172 : : }
2173 : :
2174 : : return HINIC_OK;
2175 : : }
2176 : :
2177 : : /**
2178 : : * DPDK callback to get extended device statistics.
2179 : : *
2180 : : * @param dev
2181 : : * Pointer to Ethernet device.
2182 : : * @param xstats
2183 : : * Pointer to rte extended stats table.
2184 : : * @param n
2185 : : * The size of the stats table.
2186 : : *
2187 : : * @return
2188 : : * Number of extended stats on success and stats is filled,
2189 : : * negative error value otherwise.
2190 : : */
2191 : 0 : static int hinic_dev_xstats_get(struct rte_eth_dev *dev,
2192 : : struct rte_eth_xstat *xstats,
2193 : : unsigned int n)
2194 : : {
2195 : : u16 qid = 0;
2196 : : u32 i;
2197 : : int err, count;
2198 : : struct hinic_nic_dev *nic_dev;
2199 : : struct hinic_phy_port_stats port_stats;
2200 : : struct hinic_vport_stats vport_stats;
2201 : : struct hinic_rxq *rxq = NULL;
2202 : : struct hinic_rxq_stats rxq_stats;
2203 : : struct hinic_txq *txq = NULL;
2204 : : struct hinic_txq_stats txq_stats;
2205 : :
2206 [ # # ]: 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2207 : : count = hinic_xstats_calc_num(nic_dev);
2208 [ # # ]: 0 : if ((int)n < count)
2209 : : return count;
2210 : :
2211 : : count = 0;
2212 : :
2213 : : /* Get stats from hinic_rxq_stats */
2214 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_rq; qid++) {
2215 : 0 : rxq = nic_dev->rxqs[qid];
2216 : 0 : hinic_rxq_get_stats(rxq, &rxq_stats);
2217 : :
2218 [ # # ]: 0 : for (i = 0; i < HINIC_RXQ_XSTATS_NUM; i++) {
2219 : 0 : xstats[count].value =
2220 : 0 : *(uint64_t *)(((char *)&rxq_stats) +
2221 : 0 : hinic_rxq_stats_strings[i].offset);
2222 : 0 : xstats[count].id = count;
2223 : 0 : count++;
2224 : : }
2225 : : }
2226 : :
2227 : : /* Get stats from hinic_txq_stats */
2228 [ # # ]: 0 : for (qid = 0; qid < nic_dev->num_sq; qid++) {
2229 : 0 : txq = nic_dev->txqs[qid];
2230 : 0 : hinic_txq_get_stats(txq, &txq_stats);
2231 : :
2232 [ # # ]: 0 : for (i = 0; i < HINIC_TXQ_XSTATS_NUM; i++) {
2233 : 0 : xstats[count].value =
2234 : 0 : *(uint64_t *)(((char *)&txq_stats) +
2235 : 0 : hinic_txq_stats_strings[i].offset);
2236 : 0 : xstats[count].id = count;
2237 : 0 : count++;
2238 : : }
2239 : : }
2240 : :
2241 : : /* Get stats from hinic_vport_stats */
2242 : 0 : err = hinic_get_vport_stats(nic_dev->hwdev, &vport_stats);
2243 [ # # ]: 0 : if (err)
2244 : : return err;
2245 : :
2246 [ # # ]: 0 : for (i = 0; i < HINIC_VPORT_XSTATS_NUM; i++) {
2247 : 0 : xstats[count].value =
2248 : 0 : *(uint64_t *)(((char *)&vport_stats) +
2249 : 0 : hinic_vport_stats_strings[i].offset);
2250 : 0 : xstats[count].id = count;
2251 : 0 : count++;
2252 : : }
2253 : :
2254 [ # # ]: 0 : if (HINIC_IS_VF(nic_dev->hwdev))
2255 : : return count;
2256 : :
2257 : : /* Get stats from hinic_phy_port_stats */
2258 : 0 : err = hinic_get_phy_port_stats(nic_dev->hwdev, &port_stats);
2259 [ # # ]: 0 : if (err)
2260 : : return err;
2261 : :
2262 [ # # ]: 0 : for (i = 0; i < HINIC_PHYPORT_XSTATS_NUM; i++) {
2263 : 0 : xstats[count].value = *(uint64_t *)(((char *)&port_stats) +
2264 : 0 : hinic_phyport_stats_strings[i].offset);
2265 : 0 : xstats[count].id = count;
2266 : 0 : count++;
2267 : : }
2268 : :
2269 : : return count;
2270 : : }
2271 : :
2272 : 0 : static void hinic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
2273 : : struct rte_eth_rxq_info *qinfo)
2274 : : {
2275 : 0 : struct hinic_rxq *rxq = dev->data->rx_queues[queue_id];
2276 : :
2277 : 0 : qinfo->mp = rxq->mb_pool;
2278 : 0 : qinfo->nb_desc = rxq->q_depth;
2279 : 0 : }
2280 : :
2281 : 0 : static void hinic_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
2282 : : struct rte_eth_txq_info *qinfo)
2283 : : {
2284 : 0 : struct hinic_txq *txq = dev->data->tx_queues[queue_id];
2285 : :
2286 : 0 : qinfo->nb_desc = txq->q_depth;
2287 : 0 : }
2288 : :
2289 : : /**
2290 : : * DPDK callback to retrieve names of extended device statistics
2291 : : *
2292 : : * @param dev
2293 : : * Pointer to Ethernet device structure.
2294 : : * @param xstats_names
2295 : : * Buffer to insert names into.
2296 : : *
2297 : : * @return
2298 : : * Number of xstats names.
2299 : : */
2300 : 0 : static int hinic_dev_xstats_get_names(struct rte_eth_dev *dev,
2301 : : struct rte_eth_xstat_name *xstats_names,
2302 : : __rte_unused unsigned int limit)
2303 : : {
2304 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2305 : : int count = 0;
2306 : : u16 i = 0, q_num;
2307 : :
2308 [ # # ]: 0 : if (xstats_names == NULL)
2309 : 0 : return hinic_xstats_calc_num(nic_dev);
2310 : :
2311 : : /* get pmd rxq stats */
2312 [ # # ]: 0 : for (q_num = 0; q_num < nic_dev->num_rq; q_num++) {
2313 [ # # ]: 0 : for (i = 0; i < HINIC_RXQ_XSTATS_NUM; i++) {
2314 : 0 : snprintf(xstats_names[count].name,
2315 : : sizeof(xstats_names[count].name),
2316 : : "rxq%d_%s_pmd",
2317 : 0 : q_num, hinic_rxq_stats_strings[i].name);
2318 : 0 : count++;
2319 : : }
2320 : : }
2321 : :
2322 : : /* get pmd txq stats */
2323 [ # # ]: 0 : for (q_num = 0; q_num < nic_dev->num_sq; q_num++) {
2324 [ # # ]: 0 : for (i = 0; i < HINIC_TXQ_XSTATS_NUM; i++) {
2325 : 0 : snprintf(xstats_names[count].name,
2326 : : sizeof(xstats_names[count].name),
2327 : : "txq%d_%s_pmd",
2328 : 0 : q_num, hinic_txq_stats_strings[i].name);
2329 : 0 : count++;
2330 : : }
2331 : : }
2332 : :
2333 : : /* get vport stats */
2334 [ # # ]: 0 : for (i = 0; i < HINIC_VPORT_XSTATS_NUM; i++) {
2335 : 0 : snprintf(xstats_names[count].name,
2336 : : sizeof(xstats_names[count].name),
2337 : 0 : "%s", hinic_vport_stats_strings[i].name);
2338 : 0 : count++;
2339 : : }
2340 : :
2341 [ # # ]: 0 : if (HINIC_IS_VF(nic_dev->hwdev))
2342 : : return count;
2343 : :
2344 : : /* get phy port stats */
2345 [ # # ]: 0 : for (i = 0; i < HINIC_PHYPORT_XSTATS_NUM; i++) {
2346 : 0 : snprintf(xstats_names[count].name,
2347 : : sizeof(xstats_names[count].name),
2348 : 0 : "%s", hinic_phyport_stats_strings[i].name);
2349 : 0 : count++;
2350 : : }
2351 : :
2352 : : return count;
2353 : : }
2354 : :
2355 : : /**
2356 : : * DPDK callback to set mac address
2357 : : *
2358 : : * @param dev
2359 : : * Pointer to Ethernet device structure.
2360 : : * @param addr
2361 : : * Pointer to mac address
2362 : : * @return
2363 : : * 0 on success, negative error value otherwise.
2364 : : */
2365 : 0 : static int hinic_set_mac_addr(struct rte_eth_dev *dev,
2366 : : struct rte_ether_addr *addr)
2367 : : {
2368 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2369 : : u16 func_id;
2370 : : int err;
2371 : :
2372 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2373 : 0 : err = hinic_update_mac(nic_dev->hwdev, nic_dev->default_addr.addr_bytes,
2374 : 0 : addr->addr_bytes, 0, func_id);
2375 [ # # ]: 0 : if (err)
2376 : : return err;
2377 : :
2378 : : rte_ether_addr_copy(addr, &nic_dev->default_addr);
2379 : :
2380 : 0 : PMD_DRV_LOG(INFO, "Set new mac address " RTE_ETHER_ADDR_PRT_FMT,
2381 : : RTE_ETHER_ADDR_BYTES(addr));
2382 : :
2383 : 0 : return 0;
2384 : : }
2385 : :
2386 : : /**
2387 : : * DPDK callback to remove a MAC address.
2388 : : *
2389 : : * @param dev
2390 : : * Pointer to Ethernet device structure.
2391 : : * @param index
2392 : : * MAC address index, should less than 128.
2393 : : */
2394 : 0 : static void hinic_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
2395 : : {
2396 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2397 : : u16 func_id;
2398 : : int ret;
2399 : :
2400 [ # # ]: 0 : if (index >= HINIC_MAX_UC_MAC_ADDRS) {
2401 : 0 : PMD_DRV_LOG(INFO, "Remove mac index(%u) is out of range",
2402 : : index);
2403 : 0 : return;
2404 : : }
2405 : :
2406 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2407 : 0 : ret = hinic_del_mac(nic_dev->hwdev,
2408 : 0 : dev->data->mac_addrs[index].addr_bytes, 0, func_id);
2409 [ # # ]: 0 : if (ret)
2410 : : return;
2411 : :
2412 : 0 : memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));
2413 : : }
2414 : :
2415 : : /**
2416 : : * DPDK callback to add a MAC address.
2417 : : *
2418 : : * @param dev
2419 : : * Pointer to Ethernet device structure.
2420 : : * @param mac_addr
2421 : : * Pointer to MAC address
2422 : : * @param index
2423 : : * MAC address index, should less than 128.
2424 : : * @param vmdq
2425 : : * VMDq pool index(not used).
2426 : : *
2427 : : * @return
2428 : : * 0 on success, negative error value otherwise.
2429 : : */
2430 : 0 : static int hinic_mac_addr_add(struct rte_eth_dev *dev,
2431 : : struct rte_ether_addr *mac_addr, uint32_t index,
2432 : : __rte_unused uint32_t vmdq)
2433 : : {
2434 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2435 : : unsigned int i;
2436 : : u16 func_id;
2437 : : int ret;
2438 : :
2439 [ # # ]: 0 : if (index >= HINIC_MAX_UC_MAC_ADDRS) {
2440 : 0 : PMD_DRV_LOG(INFO, "Add mac index(%u) is out of range", index);
2441 : 0 : return -EINVAL;
2442 : : }
2443 : :
2444 : : /* First, make sure this address isn't already configured. */
2445 [ # # ]: 0 : for (i = 0; (i != HINIC_MAX_UC_MAC_ADDRS); ++i) {
2446 : : /* Skip this index, it's going to be reconfigured. */
2447 [ # # ]: 0 : if (i == index)
2448 : 0 : continue;
2449 : :
2450 [ # # ]: 0 : if (memcmp(&dev->data->mac_addrs[i],
2451 : : mac_addr, sizeof(*mac_addr)))
2452 : 0 : continue;
2453 : :
2454 : 0 : PMD_DRV_LOG(INFO, "MAC address already configured");
2455 : 0 : return -EADDRINUSE;
2456 : : }
2457 : :
2458 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2459 : 0 : ret = hinic_set_mac(nic_dev->hwdev, mac_addr->addr_bytes, 0, func_id);
2460 [ # # ]: 0 : if (ret)
2461 : : return ret;
2462 : :
2463 : 0 : dev->data->mac_addrs[index] = *mac_addr;
2464 : 0 : return 0;
2465 : : }
2466 : :
2467 : : /**
2468 : : * DPDK callback to set multicast mac address
2469 : : *
2470 : : * @param dev
2471 : : * Pointer to Ethernet device structure.
2472 : : * @param mc_addr_set
2473 : : * Pointer to multicast mac address
2474 : : * @param nb_mc_addr
2475 : : * mc addr count
2476 : : * @return
2477 : : * 0 on success, negative error value otherwise.
2478 : : */
2479 : 0 : static int hinic_set_mc_addr_list(struct rte_eth_dev *dev,
2480 : : struct rte_ether_addr *mc_addr_set,
2481 : : uint32_t nb_mc_addr)
2482 : : {
2483 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2484 : : u16 func_id;
2485 : : int ret;
2486 : : u32 i;
2487 : :
2488 : 0 : func_id = hinic_global_func_id(nic_dev->hwdev);
2489 : :
2490 : : /* delete old multi_cast addrs firstly */
2491 : 0 : hinic_delete_mc_addr_list(nic_dev);
2492 : :
2493 [ # # ]: 0 : if (nb_mc_addr > HINIC_MAX_MC_MAC_ADDRS)
2494 : 0 : goto allmulti;
2495 : :
2496 [ # # ]: 0 : for (i = 0; i < nb_mc_addr; i++) {
2497 : 0 : ret = hinic_set_mac(nic_dev->hwdev, mc_addr_set[i].addr_bytes,
2498 : : 0, func_id);
2499 : : /* if add mc addr failed, set all multi_cast */
2500 [ # # ]: 0 : if (ret) {
2501 : 0 : hinic_delete_mc_addr_list(nic_dev);
2502 : 0 : goto allmulti;
2503 : : }
2504 : :
2505 : 0 : rte_ether_addr_copy(&mc_addr_set[i], &nic_dev->mc_list[i]);
2506 : : }
2507 : :
2508 : : return 0;
2509 : :
2510 : 0 : allmulti:
2511 : 0 : hinic_dev_allmulticast_enable(dev);
2512 : :
2513 : 0 : return 0;
2514 : : }
2515 : :
2516 : : /**
2517 : : * DPDK callback to get flow operations
2518 : : *
2519 : : * @param dev
2520 : : * Pointer to Ethernet device structure.
2521 : : * @param ops
2522 : : * Pointer to operation-specific structure.
2523 : : *
2524 : : * @return
2525 : : * 0 on success, negative error value otherwise.
2526 : : */
2527 : 0 : static int hinic_dev_flow_ops_get(struct rte_eth_dev *dev __rte_unused,
2528 : : const struct rte_flow_ops **ops)
2529 : : {
2530 : 0 : *ops = &hinic_flow_ops;
2531 : 0 : return 0;
2532 : : }
2533 : :
2534 : 0 : static int hinic_set_default_pause_feature(struct hinic_nic_dev *nic_dev)
2535 : : {
2536 : : struct nic_pause_config pause_config = {0};
2537 : : int err;
2538 : :
2539 : : pause_config.auto_neg = 0;
2540 : : pause_config.rx_pause = HINIC_DEFAUT_PAUSE_CONFIG;
2541 : : pause_config.tx_pause = HINIC_DEFAUT_PAUSE_CONFIG;
2542 : :
2543 : 0 : err = hinic_set_pause_config(nic_dev->hwdev, pause_config);
2544 [ # # ]: 0 : if (err)
2545 : : return err;
2546 : :
2547 : 0 : nic_dev->pause_set = true;
2548 : 0 : nic_dev->nic_pause.auto_neg = pause_config.auto_neg;
2549 : 0 : nic_dev->nic_pause.rx_pause = pause_config.rx_pause;
2550 : 0 : nic_dev->nic_pause.tx_pause = pause_config.tx_pause;
2551 : :
2552 : 0 : return 0;
2553 : : }
2554 : :
2555 : 0 : static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev)
2556 : : {
2557 : 0 : u8 up_tc[HINIC_DCB_UP_MAX] = {0};
2558 : 0 : u8 up_pgid[HINIC_DCB_UP_MAX] = {0};
2559 : 0 : u8 up_bw[HINIC_DCB_UP_MAX] = {0};
2560 : 0 : u8 pg_bw[HINIC_DCB_UP_MAX] = {0};
2561 : 0 : u8 up_strict[HINIC_DCB_UP_MAX] = {0};
2562 : : int i = 0;
2563 : :
2564 : 0 : pg_bw[0] = 100;
2565 [ # # ]: 0 : for (i = 0; i < HINIC_DCB_UP_MAX; i++)
2566 : 0 : up_bw[i] = 100;
2567 : :
2568 : 0 : return hinic_dcb_set_ets(nic_dev->hwdev, up_tc, pg_bw,
2569 : : up_pgid, up_bw, up_strict);
2570 : : }
2571 : :
2572 : 0 : static int hinic_pf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id)
2573 : : {
2574 : : u8 default_cos = 0;
2575 : : u8 valid_cos_bitmap;
2576 : : u8 i;
2577 : :
2578 : 0 : valid_cos_bitmap = hwdev->cfg_mgmt->svc_cap.valid_cos_bitmap;
2579 [ # # ]: 0 : if (!valid_cos_bitmap) {
2580 : 0 : PMD_DRV_LOG(ERR, "PF has none cos to support");
2581 : 0 : return -EFAULT;
2582 : : }
2583 : :
2584 [ # # ]: 0 : for (i = 0; i < NR_MAX_COS; i++) {
2585 [ # # ]: 0 : if (valid_cos_bitmap & BIT(i))
2586 : : default_cos = i; /* Find max cos id as default cos */
2587 : : }
2588 : :
2589 : 0 : *cos_id = default_cos;
2590 : :
2591 : 0 : return 0;
2592 : : }
2593 : :
2594 : 0 : static int hinic_init_default_cos(struct hinic_nic_dev *nic_dev)
2595 : : {
2596 : 0 : u8 cos_id = 0;
2597 : : int err;
2598 : :
2599 [ # # ]: 0 : if (!HINIC_IS_VF(nic_dev->hwdev)) {
2600 : 0 : err = hinic_pf_get_default_cos(nic_dev->hwdev, &cos_id);
2601 [ # # ]: 0 : if (err) {
2602 : 0 : PMD_DRV_LOG(ERR, "Get PF default cos failed, err: %d",
2603 : : err);
2604 : 0 : return HINIC_ERROR;
2605 : : }
2606 : : } else {
2607 : 0 : err = hinic_vf_get_default_cos(nic_dev->hwdev, &cos_id);
2608 [ # # ]: 0 : if (err) {
2609 : 0 : PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d",
2610 : : err);
2611 : 0 : return HINIC_ERROR;
2612 : : }
2613 : : }
2614 : :
2615 : 0 : nic_dev->default_cos = cos_id;
2616 : :
2617 : 0 : PMD_DRV_LOG(INFO, "Default cos %d", nic_dev->default_cos);
2618 : :
2619 : 0 : return 0;
2620 : : }
2621 : :
2622 : 0 : static int hinic_set_default_hw_feature(struct hinic_nic_dev *nic_dev)
2623 : : {
2624 : : int err;
2625 : :
2626 : 0 : err = hinic_init_default_cos(nic_dev);
2627 [ # # ]: 0 : if (err)
2628 : : return err;
2629 : :
2630 [ # # ]: 0 : if (hinic_func_type(nic_dev->hwdev) == TYPE_VF)
2631 : : return 0;
2632 : :
2633 : : /* Restore DCB configure to default status */
2634 : 0 : err = hinic_set_default_dcb_feature(nic_dev);
2635 [ # # ]: 0 : if (err)
2636 : : return err;
2637 : :
2638 : : /* Set pause enable, and up will disable pfc. */
2639 : 0 : err = hinic_set_default_pause_feature(nic_dev);
2640 [ # # ]: 0 : if (err)
2641 : : return err;
2642 : :
2643 : 0 : err = hinic_reset_port_link_cfg(nic_dev->hwdev);
2644 [ # # ]: 0 : if (err)
2645 : : return err;
2646 : :
2647 : 0 : err = hinic_set_link_status_follow(nic_dev->hwdev,
2648 : : HINIC_LINK_FOLLOW_PORT);
2649 [ # # ]: 0 : if (err == HINIC_MGMT_CMD_UNSUPPORTED)
2650 : 0 : PMD_DRV_LOG(WARNING, "Don't support to set link status follow phy port status");
2651 [ # # ]: 0 : else if (err)
2652 : : return err;
2653 : :
2654 : 0 : return hinic_set_anti_attack(nic_dev->hwdev, true);
2655 : : }
2656 : :
2657 : 0 : static int32_t hinic_card_workmode_check(struct hinic_nic_dev *nic_dev)
2658 : : {
2659 : 0 : struct hinic_board_info info = { 0 };
2660 : : int rc;
2661 : :
2662 [ # # ]: 0 : if (hinic_func_type(nic_dev->hwdev) == TYPE_VF)
2663 : : return 0;
2664 : :
2665 : 0 : rc = hinic_get_board_info(nic_dev->hwdev, &info);
2666 [ # # ]: 0 : if (rc)
2667 : : return rc;
2668 : :
2669 [ # # ]: 0 : return (info.service_mode == HINIC_SERVICE_MODE_NIC ? HINIC_OK :
2670 : : HINIC_ERROR);
2671 : : }
2672 : :
2673 : 0 : static int hinic_copy_mempool_init(struct hinic_nic_dev *nic_dev)
2674 : : {
2675 : 0 : nic_dev->cpy_mpool = rte_mempool_lookup(nic_dev->proc_dev_name);
2676 [ # # ]: 0 : if (nic_dev->cpy_mpool == NULL) {
2677 : 0 : nic_dev->cpy_mpool =
2678 : 0 : rte_pktmbuf_pool_create(nic_dev->proc_dev_name,
2679 : : HINIC_COPY_MEMPOOL_DEPTH,
2680 : : 0, 0,
2681 : : HINIC_COPY_MBUF_SIZE,
2682 : 0 : rte_socket_id());
2683 [ # # ]: 0 : if (!nic_dev->cpy_mpool) {
2684 : 0 : PMD_DRV_LOG(ERR, "Create copy mempool failed, errno: %d, dev_name: %s",
2685 : : rte_errno, nic_dev->proc_dev_name);
2686 : 0 : return -ENOMEM;
2687 : : }
2688 : : }
2689 : :
2690 : : return 0;
2691 : : }
2692 : :
2693 : : static void hinic_copy_mempool_uninit(struct hinic_nic_dev *nic_dev)
2694 : : {
2695 : 0 : rte_mempool_free(nic_dev->cpy_mpool);
2696 : 0 : }
2697 : :
2698 : 0 : static int hinic_init_sw_rxtxqs(struct hinic_nic_dev *nic_dev)
2699 : : {
2700 : : u32 txq_size;
2701 : : u32 rxq_size;
2702 : :
2703 : : /* allocate software txq array */
2704 : 0 : txq_size = nic_dev->nic_cap.max_sqs * sizeof(*nic_dev->txqs);
2705 : 0 : nic_dev->txqs = kzalloc_aligned(txq_size, GFP_KERNEL);
2706 [ # # ]: 0 : if (!nic_dev->txqs) {
2707 : 0 : PMD_DRV_LOG(ERR, "Allocate txqs failed");
2708 : 0 : return -ENOMEM;
2709 : : }
2710 : :
2711 : : /* allocate software rxq array */
2712 : 0 : rxq_size = nic_dev->nic_cap.max_rqs * sizeof(*nic_dev->rxqs);
2713 : 0 : nic_dev->rxqs = kzalloc_aligned(rxq_size, GFP_KERNEL);
2714 [ # # ]: 0 : if (!nic_dev->rxqs) {
2715 : : /* free txqs */
2716 : 0 : kfree(nic_dev->txqs);
2717 : 0 : nic_dev->txqs = NULL;
2718 : :
2719 : 0 : PMD_DRV_LOG(ERR, "Allocate rxqs failed");
2720 : 0 : return -ENOMEM;
2721 : : }
2722 : :
2723 : : return HINIC_OK;
2724 : : }
2725 : :
2726 : : static void hinic_deinit_sw_rxtxqs(struct hinic_nic_dev *nic_dev)
2727 : : {
2728 : 0 : kfree(nic_dev->txqs);
2729 : 0 : nic_dev->txqs = NULL;
2730 : :
2731 : 0 : kfree(nic_dev->rxqs);
2732 : 0 : nic_dev->rxqs = NULL;
2733 : 0 : }
2734 : :
2735 : 0 : static int hinic_nic_dev_create(struct rte_eth_dev *eth_dev)
2736 : : {
2737 : 0 : struct hinic_nic_dev *nic_dev =
2738 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
2739 : : int rc;
2740 : :
2741 : 0 : nic_dev->hwdev = rte_zmalloc("hinic_hwdev", sizeof(*nic_dev->hwdev),
2742 : : RTE_CACHE_LINE_SIZE);
2743 [ # # ]: 0 : if (!nic_dev->hwdev) {
2744 : 0 : PMD_DRV_LOG(ERR, "Allocate hinic hwdev memory failed, dev_name: %s",
2745 : : eth_dev->data->name);
2746 : 0 : return -ENOMEM;
2747 : : }
2748 : 0 : nic_dev->hwdev->pcidev_hdl = RTE_ETH_DEV_TO_PCI(eth_dev);
2749 : :
2750 : : /* init osdep*/
2751 : 0 : rc = hinic_osdep_init(nic_dev->hwdev);
2752 [ # # ]: 0 : if (rc) {
2753 : 0 : PMD_DRV_LOG(ERR, "Initialize os_dep failed, dev_name: %s",
2754 : : eth_dev->data->name);
2755 : 0 : goto init_osdep_fail;
2756 : : }
2757 : :
2758 : : /* init_hwif */
2759 : 0 : rc = hinic_hwif_res_init(nic_dev->hwdev);
2760 [ # # ]: 0 : if (rc) {
2761 : 0 : PMD_DRV_LOG(ERR, "Initialize hwif failed, dev_name: %s",
2762 : : eth_dev->data->name);
2763 : 0 : goto init_hwif_fail;
2764 : : }
2765 : :
2766 : : /* init_cfg_mgmt */
2767 : 0 : rc = init_cfg_mgmt(nic_dev->hwdev);
2768 [ # # ]: 0 : if (rc) {
2769 : 0 : PMD_DRV_LOG(ERR, "Initialize cfg_mgmt failed, dev_name: %s",
2770 : : eth_dev->data->name);
2771 : 0 : goto init_cfgmgnt_fail;
2772 : : }
2773 : :
2774 : : /* init_aeqs */
2775 : 0 : rc = hinic_comm_aeqs_init(nic_dev->hwdev);
2776 [ # # ]: 0 : if (rc) {
2777 : 0 : PMD_DRV_LOG(ERR, "Initialize aeqs failed, dev_name: %s",
2778 : : eth_dev->data->name);
2779 : 0 : goto init_aeqs_fail;
2780 : : }
2781 : :
2782 : : /* init_pf_to_mgnt */
2783 : 0 : rc = hinic_comm_pf_to_mgmt_init(nic_dev->hwdev);
2784 [ # # ]: 0 : if (rc) {
2785 : 0 : PMD_DRV_LOG(ERR, "Initialize pf_to_mgmt failed, dev_name: %s",
2786 : : eth_dev->data->name);
2787 : 0 : goto init_pf_to_mgmt_fail;
2788 : : }
2789 : :
2790 : : /* init mailbox */
2791 : 0 : rc = hinic_comm_func_to_func_init(nic_dev->hwdev);
2792 [ # # ]: 0 : if (rc) {
2793 : 0 : PMD_DRV_LOG(ERR, "Initialize func_to_func failed, dev_name: %s",
2794 : : eth_dev->data->name);
2795 : 0 : goto init_func_to_func_fail;
2796 : : }
2797 : :
2798 : 0 : rc = hinic_card_workmode_check(nic_dev);
2799 [ # # ]: 0 : if (rc) {
2800 : 0 : PMD_DRV_LOG(ERR, "Check card workmode failed, dev_name: %s",
2801 : : eth_dev->data->name);
2802 : 0 : goto workmode_check_fail;
2803 : : }
2804 : :
2805 : : /* do l2nic reset to make chip clear */
2806 : 0 : rc = hinic_l2nic_reset(nic_dev->hwdev);
2807 [ # # ]: 0 : if (rc) {
2808 : 0 : PMD_DRV_LOG(ERR, "Do l2nic reset failed, dev_name: %s",
2809 : : eth_dev->data->name);
2810 : 0 : goto l2nic_reset_fail;
2811 : : }
2812 : :
2813 : : /* init dma and aeq msix attribute table */
2814 : 0 : (void)hinic_init_attr_table(nic_dev->hwdev);
2815 : :
2816 : : /* init_cmdqs */
2817 : 0 : rc = hinic_comm_cmdqs_init(nic_dev->hwdev);
2818 [ # # ]: 0 : if (rc) {
2819 : 0 : PMD_DRV_LOG(ERR, "Initialize cmdq failed, dev_name: %s",
2820 : : eth_dev->data->name);
2821 : 0 : goto init_cmdq_fail;
2822 : : }
2823 : :
2824 : : /* set hardware state active */
2825 : 0 : rc = hinic_activate_hwdev_state(nic_dev->hwdev);
2826 [ # # ]: 0 : if (rc) {
2827 : 0 : PMD_DRV_LOG(ERR, "Initialize resources state failed, dev_name: %s",
2828 : : eth_dev->data->name);
2829 : 0 : goto init_resources_state_fail;
2830 : : }
2831 : :
2832 : : /* init_capability */
2833 : 0 : rc = hinic_init_capability(nic_dev->hwdev);
2834 [ # # ]: 0 : if (rc) {
2835 : 0 : PMD_DRV_LOG(ERR, "Initialize capability failed, dev_name: %s",
2836 : : eth_dev->data->name);
2837 : 0 : goto init_cap_fail;
2838 : : }
2839 : :
2840 : : /* get nic capability */
2841 [ # # ]: 0 : if (!hinic_support_nic(nic_dev->hwdev, &nic_dev->nic_cap)) {
2842 : 0 : PMD_DRV_LOG(ERR, "Hw doesn't support nic, dev_name: %s",
2843 : : eth_dev->data->name);
2844 : : rc = -EINVAL;
2845 : 0 : goto nic_check_fail;
2846 : : }
2847 : :
2848 : : /* init root cla and function table */
2849 : 0 : rc = hinic_init_nicio(nic_dev->hwdev);
2850 [ # # ]: 0 : if (rc) {
2851 : 0 : PMD_DRV_LOG(ERR, "Initialize nic_io failed, dev_name: %s",
2852 : : eth_dev->data->name);
2853 : 0 : goto init_nicio_fail;
2854 : : }
2855 : :
2856 : : /* init_software_txrxq */
2857 : 0 : rc = hinic_init_sw_rxtxqs(nic_dev);
2858 [ # # ]: 0 : if (rc) {
2859 : 0 : PMD_DRV_LOG(ERR, "Initialize sw_rxtxqs failed, dev_name: %s",
2860 : : eth_dev->data->name);
2861 : 0 : goto init_sw_rxtxqs_fail;
2862 : : }
2863 : :
2864 : 0 : rc = hinic_copy_mempool_init(nic_dev);
2865 [ # # ]: 0 : if (rc) {
2866 : 0 : PMD_DRV_LOG(ERR, "Create copy mempool failed, dev_name: %s",
2867 : : eth_dev->data->name);
2868 : 0 : goto init_mpool_fail;
2869 : : }
2870 : :
2871 : : /* set hardware feature to default status */
2872 : 0 : rc = hinic_set_default_hw_feature(nic_dev);
2873 [ # # ]: 0 : if (rc) {
2874 : 0 : PMD_DRV_LOG(ERR, "Initialize hardware default features failed, dev_name: %s",
2875 : : eth_dev->data->name);
2876 : 0 : goto set_default_hw_feature_fail;
2877 : : }
2878 : :
2879 : : return 0;
2880 : :
2881 : : set_default_hw_feature_fail:
2882 : : hinic_copy_mempool_uninit(nic_dev);
2883 : :
2884 : 0 : init_mpool_fail:
2885 : : hinic_deinit_sw_rxtxqs(nic_dev);
2886 : :
2887 : 0 : init_sw_rxtxqs_fail:
2888 : 0 : hinic_deinit_nicio(nic_dev->hwdev);
2889 : :
2890 : 0 : nic_check_fail:
2891 : 0 : init_nicio_fail:
2892 : 0 : init_cap_fail:
2893 : 0 : hinic_deactivate_hwdev_state(nic_dev->hwdev);
2894 : :
2895 : 0 : init_resources_state_fail:
2896 : 0 : hinic_comm_cmdqs_free(nic_dev->hwdev);
2897 : :
2898 : 0 : init_cmdq_fail:
2899 : 0 : l2nic_reset_fail:
2900 : 0 : workmode_check_fail:
2901 : 0 : hinic_comm_func_to_func_free(nic_dev->hwdev);
2902 : :
2903 : 0 : init_func_to_func_fail:
2904 : 0 : hinic_comm_pf_to_mgmt_free(nic_dev->hwdev);
2905 : :
2906 : 0 : init_pf_to_mgmt_fail:
2907 : 0 : hinic_comm_aeqs_free(nic_dev->hwdev);
2908 : :
2909 : 0 : init_aeqs_fail:
2910 : 0 : free_cfg_mgmt(nic_dev->hwdev);
2911 : :
2912 : 0 : init_cfgmgnt_fail:
2913 : 0 : hinic_hwif_res_free(nic_dev->hwdev);
2914 : :
2915 : 0 : init_hwif_fail:
2916 : 0 : hinic_osdep_deinit(nic_dev->hwdev);
2917 : :
2918 : 0 : init_osdep_fail:
2919 : 0 : rte_free(nic_dev->hwdev);
2920 : 0 : nic_dev->hwdev = NULL;
2921 : :
2922 : 0 : return rc;
2923 : : }
2924 : :
2925 : 0 : static void hinic_nic_dev_destroy(struct rte_eth_dev *eth_dev)
2926 : : {
2927 : 0 : struct hinic_nic_dev *nic_dev =
2928 : 0 : HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
2929 : :
2930 : 0 : (void)hinic_set_link_status_follow(nic_dev->hwdev,
2931 : : HINIC_LINK_FOLLOW_DEFAULT);
2932 : : hinic_copy_mempool_uninit(nic_dev);
2933 : : hinic_deinit_sw_rxtxqs(nic_dev);
2934 : 0 : hinic_deinit_nicio(nic_dev->hwdev);
2935 : 0 : hinic_deactivate_hwdev_state(nic_dev->hwdev);
2936 : 0 : hinic_comm_cmdqs_free(nic_dev->hwdev);
2937 : 0 : hinic_comm_func_to_func_free(nic_dev->hwdev);
2938 : 0 : hinic_comm_pf_to_mgmt_free(nic_dev->hwdev);
2939 : 0 : hinic_comm_aeqs_free(nic_dev->hwdev);
2940 : 0 : free_cfg_mgmt(nic_dev->hwdev);
2941 : 0 : hinic_hwif_res_free(nic_dev->hwdev);
2942 : 0 : hinic_osdep_deinit(nic_dev->hwdev);
2943 : 0 : rte_free(nic_dev->hwdev);
2944 : 0 : nic_dev->hwdev = NULL;
2945 : 0 : }
2946 : :
2947 : : /**
2948 : : * DPDK callback to close the device.
2949 : : *
2950 : : * @param dev
2951 : : * Pointer to Ethernet device structure.
2952 : : */
2953 : 0 : static int hinic_dev_close(struct rte_eth_dev *dev)
2954 : : {
2955 : 0 : struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
2956 : : int ret;
2957 : :
2958 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2959 : : return 0;
2960 : :
2961 [ # # ]: 0 : if (rte_bit_relaxed_test_and_set32(HINIC_DEV_CLOSE,
2962 : : &nic_dev->dev_status)) {
2963 : 0 : PMD_DRV_LOG(WARNING, "Device %s already closed",
2964 : : dev->data->name);
2965 : 0 : return 0;
2966 : : }
2967 : :
2968 : : /* stop device first */
2969 : 0 : ret = hinic_dev_stop(dev);
2970 : :
2971 : : /* rx_cqe, rx_info */
2972 : 0 : hinic_free_all_rx_resources(dev);
2973 : :
2974 : : /* tx_info */
2975 : 0 : hinic_free_all_tx_resources(dev);
2976 : :
2977 : : /* free wq, pi_dma_addr */
2978 : : hinic_free_all_rq(nic_dev);
2979 : :
2980 : : /* free wq, db_addr */
2981 : : hinic_free_all_sq(nic_dev);
2982 : :
2983 : : /* deinit mac vlan tbl */
2984 : 0 : hinic_deinit_mac_addr(dev);
2985 : 0 : hinic_remove_all_vlanid(dev);
2986 : :
2987 : : /* disable hardware and uio interrupt */
2988 : 0 : hinic_disable_interrupt(dev);
2989 : :
2990 : : /* destroy rx mode mutex */
2991 : 0 : hinic_mutex_destroy(&nic_dev->rx_mode_mutex);
2992 : :
2993 : : /* deinit nic hardware device */
2994 : 0 : hinic_nic_dev_destroy(dev);
2995 : :
2996 : 0 : return ret;
2997 : : }
2998 : :
2999 : : static const struct eth_dev_ops hinic_pmd_ops = {
3000 : : .dev_configure = hinic_dev_configure,
3001 : : .dev_infos_get = hinic_dev_infos_get,
3002 : : .fw_version_get = hinic_fw_version_get,
3003 : : .rx_queue_setup = hinic_rx_queue_setup,
3004 : : .tx_queue_setup = hinic_tx_queue_setup,
3005 : : .dev_start = hinic_dev_start,
3006 : : .dev_set_link_up = hinic_dev_set_link_up,
3007 : : .dev_set_link_down = hinic_dev_set_link_down,
3008 : : .link_update = hinic_link_update,
3009 : : .rx_queue_release = hinic_rx_queue_release,
3010 : : .tx_queue_release = hinic_tx_queue_release,
3011 : : .dev_stop = hinic_dev_stop,
3012 : : .dev_close = hinic_dev_close,
3013 : : .mtu_set = hinic_dev_set_mtu,
3014 : : .vlan_filter_set = hinic_vlan_filter_set,
3015 : : .vlan_offload_set = hinic_vlan_offload_set,
3016 : : .allmulticast_enable = hinic_dev_allmulticast_enable,
3017 : : .allmulticast_disable = hinic_dev_allmulticast_disable,
3018 : : .promiscuous_enable = hinic_dev_promiscuous_enable,
3019 : : .promiscuous_disable = hinic_dev_promiscuous_disable,
3020 : : .flow_ctrl_get = hinic_flow_ctrl_get,
3021 : : .flow_ctrl_set = hinic_flow_ctrl_set,
3022 : : .rss_hash_update = hinic_rss_hash_update,
3023 : : .rss_hash_conf_get = hinic_rss_conf_get,
3024 : : .reta_update = hinic_rss_indirtbl_update,
3025 : : .reta_query = hinic_rss_indirtbl_query,
3026 : : .stats_get = hinic_dev_stats_get,
3027 : : .stats_reset = hinic_dev_stats_reset,
3028 : : .xstats_get = hinic_dev_xstats_get,
3029 : : .xstats_reset = hinic_dev_xstats_reset,
3030 : : .xstats_get_names = hinic_dev_xstats_get_names,
3031 : : .rxq_info_get = hinic_rxq_info_get,
3032 : : .txq_info_get = hinic_txq_info_get,
3033 : : .mac_addr_set = hinic_set_mac_addr,
3034 : : .mac_addr_remove = hinic_mac_addr_remove,
3035 : : .mac_addr_add = hinic_mac_addr_add,
3036 : : .set_mc_addr_list = hinic_set_mc_addr_list,
3037 : : .flow_ops_get = hinic_dev_flow_ops_get,
3038 : : };
3039 : :
3040 : : static const struct eth_dev_ops hinic_pmd_vf_ops = {
3041 : : .dev_configure = hinic_dev_configure,
3042 : : .dev_infos_get = hinic_dev_infos_get,
3043 : : .fw_version_get = hinic_fw_version_get,
3044 : : .rx_queue_setup = hinic_rx_queue_setup,
3045 : : .tx_queue_setup = hinic_tx_queue_setup,
3046 : : .dev_start = hinic_dev_start,
3047 : : .link_update = hinic_link_update,
3048 : : .rx_queue_release = hinic_rx_queue_release,
3049 : : .tx_queue_release = hinic_tx_queue_release,
3050 : : .dev_stop = hinic_dev_stop,
3051 : : .dev_close = hinic_dev_close,
3052 : : .mtu_set = hinic_dev_set_mtu,
3053 : : .vlan_filter_set = hinic_vlan_filter_set,
3054 : : .vlan_offload_set = hinic_vlan_offload_set,
3055 : : .allmulticast_enable = hinic_dev_allmulticast_enable,
3056 : : .allmulticast_disable = hinic_dev_allmulticast_disable,
3057 : : .rss_hash_update = hinic_rss_hash_update,
3058 : : .rss_hash_conf_get = hinic_rss_conf_get,
3059 : : .reta_update = hinic_rss_indirtbl_update,
3060 : : .reta_query = hinic_rss_indirtbl_query,
3061 : : .stats_get = hinic_dev_stats_get,
3062 : : .stats_reset = hinic_dev_stats_reset,
3063 : : .xstats_get = hinic_dev_xstats_get,
3064 : : .xstats_reset = hinic_dev_xstats_reset,
3065 : : .xstats_get_names = hinic_dev_xstats_get_names,
3066 : : .rxq_info_get = hinic_rxq_info_get,
3067 : : .txq_info_get = hinic_txq_info_get,
3068 : : .mac_addr_set = hinic_set_mac_addr,
3069 : : .mac_addr_remove = hinic_mac_addr_remove,
3070 : : .mac_addr_add = hinic_mac_addr_add,
3071 : : .set_mc_addr_list = hinic_set_mc_addr_list,
3072 : : .flow_ops_get = hinic_dev_flow_ops_get,
3073 : : };
3074 : :
3075 : : static const struct eth_dev_ops hinic_dev_sec_ops = {
3076 : : .dev_infos_get = hinic_dev_infos_get,
3077 : : };
3078 : :
3079 : 0 : static int hinic_func_init(struct rte_eth_dev *eth_dev)
3080 : : {
3081 : : struct rte_pci_device *pci_dev;
3082 : : struct rte_ether_addr *eth_addr;
3083 : : struct hinic_nic_dev *nic_dev;
3084 : : struct hinic_filter_info *filter_info;
3085 : : struct hinic_tcam_info *tcam_info;
3086 : : u32 mac_size;
3087 : : int rc;
3088 : :
3089 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
3090 : :
3091 : : /* EAL is SECONDARY and eth_dev is already created */
3092 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
3093 : 0 : eth_dev->dev_ops = &hinic_dev_sec_ops;
3094 : 0 : PMD_DRV_LOG(INFO, "Initialize %s in secondary process",
3095 : : eth_dev->data->name);
3096 : :
3097 : 0 : return 0;
3098 : : }
3099 : :
3100 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
3101 : :
3102 : 0 : nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
3103 : : memset(nic_dev, 0, sizeof(*nic_dev));
3104 : :
3105 : 0 : snprintf(nic_dev->proc_dev_name,
3106 : : sizeof(nic_dev->proc_dev_name),
3107 : : "hinic-" PCI_PRI_FMT,
3108 : 0 : pci_dev->addr.domain, pci_dev->addr.bus,
3109 : 0 : pci_dev->addr.devid, pci_dev->addr.function);
3110 : :
3111 : : /* alloc mac_addrs */
3112 : : mac_size = HINIC_MAX_UC_MAC_ADDRS * sizeof(struct rte_ether_addr);
3113 : 0 : eth_addr = rte_zmalloc("hinic_mac", mac_size, 0);
3114 [ # # ]: 0 : if (!eth_addr) {
3115 : 0 : PMD_DRV_LOG(ERR, "Allocate ethernet addresses' memory failed, dev_name: %s",
3116 : : eth_dev->data->name);
3117 : : rc = -ENOMEM;
3118 : 0 : goto eth_addr_fail;
3119 : : }
3120 : 0 : eth_dev->data->mac_addrs = eth_addr;
3121 : :
3122 : : mac_size = HINIC_MAX_MC_MAC_ADDRS * sizeof(struct rte_ether_addr);
3123 : 0 : nic_dev->mc_list = rte_zmalloc("hinic_mc", mac_size, 0);
3124 [ # # ]: 0 : if (!nic_dev->mc_list) {
3125 : 0 : PMD_DRV_LOG(ERR, "Allocate mcast address' memory failed, dev_name: %s",
3126 : : eth_dev->data->name);
3127 : : rc = -ENOMEM;
3128 : 0 : goto mc_addr_fail;
3129 : : }
3130 : :
3131 : : /* create hardware nic_device */
3132 : 0 : rc = hinic_nic_dev_create(eth_dev);
3133 [ # # ]: 0 : if (rc) {
3134 : 0 : PMD_DRV_LOG(ERR, "Create nic device failed, dev_name: %s",
3135 : : eth_dev->data->name);
3136 : 0 : goto create_nic_dev_fail;
3137 : : }
3138 : :
3139 [ # # ]: 0 : if (HINIC_IS_VF(nic_dev->hwdev))
3140 : 0 : eth_dev->dev_ops = &hinic_pmd_vf_ops;
3141 : : else
3142 : 0 : eth_dev->dev_ops = &hinic_pmd_ops;
3143 : :
3144 : 0 : rc = hinic_init_mac_addr(eth_dev);
3145 [ # # ]: 0 : if (rc) {
3146 : 0 : PMD_DRV_LOG(ERR, "Initialize mac table failed, dev_name: %s",
3147 : : eth_dev->data->name);
3148 : 0 : goto init_mac_fail;
3149 : : }
3150 : :
3151 : : /* register callback func to eal lib */
3152 : 0 : rc = rte_intr_callback_register(pci_dev->intr_handle,
3153 : : hinic_dev_interrupt_handler,
3154 : : (void *)eth_dev);
3155 [ # # ]: 0 : if (rc) {
3156 : 0 : PMD_DRV_LOG(ERR, "Register rte interrupt callback failed, dev_name: %s",
3157 : : eth_dev->data->name);
3158 : 0 : goto reg_intr_cb_fail;
3159 : : }
3160 : :
3161 : : /* enable uio/vfio intr/eventfd mapping */
3162 : 0 : rc = rte_intr_enable(pci_dev->intr_handle);
3163 [ # # ]: 0 : if (rc) {
3164 : 0 : PMD_DRV_LOG(ERR, "Enable rte interrupt failed, dev_name: %s",
3165 : : eth_dev->data->name);
3166 : 0 : goto enable_intr_fail;
3167 : : }
3168 : : rte_bit_relaxed_set32(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
3169 : :
3170 : 0 : hinic_mutex_init(&nic_dev->rx_mode_mutex, NULL);
3171 : :
3172 : : /* initialize filter info */
3173 : 0 : filter_info = &nic_dev->filter;
3174 : 0 : tcam_info = &nic_dev->tcam;
3175 : : memset(filter_info, 0, sizeof(struct hinic_filter_info));
3176 : : memset(tcam_info, 0, sizeof(struct hinic_tcam_info));
3177 : : /* initialize 5tuple filter list */
3178 : 0 : TAILQ_INIT(&filter_info->fivetuple_list);
3179 : 0 : TAILQ_INIT(&tcam_info->tcam_list);
3180 : 0 : TAILQ_INIT(&nic_dev->filter_ntuple_list);
3181 : 0 : TAILQ_INIT(&nic_dev->filter_ethertype_list);
3182 : 0 : TAILQ_INIT(&nic_dev->filter_fdir_rule_list);
3183 : 0 : TAILQ_INIT(&nic_dev->hinic_flow_list);
3184 : :
3185 : : rte_bit_relaxed_set32(HINIC_DEV_INIT, &nic_dev->dev_status);
3186 : 0 : PMD_DRV_LOG(INFO, "Initialize %s in primary successfully",
3187 : : eth_dev->data->name);
3188 : :
3189 : 0 : return 0;
3190 : :
3191 : : enable_intr_fail:
3192 : 0 : (void)rte_intr_callback_unregister(pci_dev->intr_handle,
3193 : : hinic_dev_interrupt_handler,
3194 : : (void *)eth_dev);
3195 : :
3196 : 0 : reg_intr_cb_fail:
3197 : 0 : hinic_deinit_mac_addr(eth_dev);
3198 : :
3199 : 0 : init_mac_fail:
3200 : 0 : eth_dev->dev_ops = NULL;
3201 : 0 : hinic_nic_dev_destroy(eth_dev);
3202 : :
3203 : 0 : create_nic_dev_fail:
3204 : 0 : rte_free(nic_dev->mc_list);
3205 : 0 : nic_dev->mc_list = NULL;
3206 : :
3207 : 0 : mc_addr_fail:
3208 : 0 : rte_free(eth_addr);
3209 : 0 : eth_dev->data->mac_addrs = NULL;
3210 : :
3211 : 0 : eth_addr_fail:
3212 : 0 : PMD_DRV_LOG(ERR, "Initialize %s in primary failed",
3213 : : eth_dev->data->name);
3214 : 0 : return rc;
3215 : : }
3216 : :
3217 : 0 : static int hinic_dev_init(struct rte_eth_dev *eth_dev)
3218 : : {
3219 : : struct rte_pci_device *pci_dev;
3220 : :
3221 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
3222 : :
3223 [ # # ]: 0 : PMD_DRV_LOG(INFO, "Initializing pf hinic-" PCI_PRI_FMT " in %s process",
3224 : : pci_dev->addr.domain, pci_dev->addr.bus,
3225 : : pci_dev->addr.devid, pci_dev->addr.function,
3226 : : (rte_eal_process_type() == RTE_PROC_PRIMARY) ?
3227 : : "primary" : "secondary");
3228 : :
3229 : : /* rte_eth_dev rx_burst and tx_burst */
3230 : 0 : eth_dev->rx_pkt_burst = hinic_recv_pkts;
3231 : 0 : eth_dev->tx_pkt_burst = hinic_xmit_pkts;
3232 : :
3233 : 0 : return hinic_func_init(eth_dev);
3234 : : }
3235 : :
3236 : 0 : static int hinic_dev_uninit(struct rte_eth_dev *dev)
3237 : : {
3238 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
3239 : : return 0;
3240 : :
3241 : 0 : hinic_dev_close(dev);
3242 : :
3243 : 0 : return HINIC_OK;
3244 : : }
3245 : :
3246 : : static struct rte_pci_id pci_id_hinic_map[] = {
3247 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_PRD) },
3248 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_25GE) },
3249 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_100GE) },
3250 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_VF) },
3251 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_VF_HV) },
3252 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_1822_DUAL_25GE) },
3253 : : { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_1822_100GE) },
3254 : : {.vendor_id = 0},
3255 : : };
3256 : :
3257 : 0 : static int hinic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
3258 : : struct rte_pci_device *pci_dev)
3259 : : {
3260 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
3261 : : sizeof(struct hinic_nic_dev), hinic_dev_init);
3262 : : }
3263 : :
3264 : 0 : static int hinic_pci_remove(struct rte_pci_device *pci_dev)
3265 : : {
3266 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, hinic_dev_uninit);
3267 : : }
3268 : :
3269 : : static struct rte_pci_driver rte_hinic_pmd = {
3270 : : .id_table = pci_id_hinic_map,
3271 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
3272 : : .probe = hinic_pci_probe,
3273 : : .remove = hinic_pci_remove,
3274 : : };
3275 : :
3276 : 253 : RTE_PMD_REGISTER_PCI(net_hinic, rte_hinic_pmd);
3277 : : RTE_PMD_REGISTER_PCI_TABLE(net_hinic, pci_id_hinic_map);
3278 [ - + ]: 253 : RTE_LOG_REGISTER_DEFAULT(hinic_logtype, INFO);
|