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