Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2020 Intel Corporation
3 : : */
4 : :
5 : : #include <errno.h>
6 : : #include <stdbool.h>
7 : : #include <sys/queue.h>
8 : : #include <sys/types.h>
9 : : #include <unistd.h>
10 : :
11 : : #include <rte_interrupts.h>
12 : : #include <rte_debug.h>
13 : : #include <rte_pci.h>
14 : : #include <rte_eal.h>
15 : : #include <rte_ether.h>
16 : : #include <ethdev_pci.h>
17 : : #include <rte_kvargs.h>
18 : : #include <rte_malloc.h>
19 : : #include <rte_memzone.h>
20 : : #include <dev_driver.h>
21 : :
22 : : #include <iavf_devids.h>
23 : :
24 : : #include "ice_generic_flow.h"
25 : : #include "ice_dcf_ethdev.h"
26 : : #include "ice_rxtx.h"
27 : :
28 : : #define DCF_NUM_MACADDR_MAX 64
29 : :
30 : : static int dcf_add_del_mc_addr_list(struct ice_dcf_hw *hw,
31 : : struct rte_ether_addr *mc_addrs,
32 : : uint32_t mc_addrs_num, bool add);
33 : :
34 : : static int
35 : : ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
36 : : struct rte_eth_udp_tunnel *udp_tunnel);
37 : : static int
38 : : ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
39 : : struct rte_eth_udp_tunnel *udp_tunnel);
40 : :
41 : : static int
42 : : ice_dcf_dev_init(struct rte_eth_dev *eth_dev);
43 : :
44 : : static int
45 : : ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev);
46 : :
47 : : static int
48 : : ice_dcf_cap_check_handler(__rte_unused const char *key,
49 : : const char *value, __rte_unused void *opaque);
50 : :
51 : : static int
52 : : ice_dcf_engine_disabled_handler(__rte_unused const char *key,
53 : : const char *value, __rte_unused void *opaque);
54 : :
55 : : struct ice_devarg {
56 : : enum ice_dcf_devrarg type;
57 : : const char *key;
58 : : int (*handler)(__rte_unused const char *key,
59 : : const char *value, __rte_unused void *opaque);
60 : : };
61 : :
62 : : static const struct ice_devarg ice_devargs_table[] = {
63 : : {ICE_DCF_DEVARG_CAP, "cap", ice_dcf_cap_check_handler},
64 : : {ICE_DCF_DEVARG_ACL, "acl", ice_dcf_engine_disabled_handler},
65 : : };
66 : :
67 : : struct rte_ice_dcf_xstats_name_off {
68 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
69 : : unsigned int offset;
70 : : };
71 : :
72 : : static const struct rte_ice_dcf_xstats_name_off rte_ice_dcf_stats_strings[] = {
73 : : {"rx_bytes", offsetof(struct ice_dcf_eth_stats, rx_bytes)},
74 : : {"rx_unicast_packets", offsetof(struct ice_dcf_eth_stats, rx_unicast)},
75 : : {"rx_multicast_packets", offsetof(struct ice_dcf_eth_stats, rx_multicast)},
76 : : {"rx_broadcast_packets", offsetof(struct ice_dcf_eth_stats, rx_broadcast)},
77 : : {"rx_dropped_packets", offsetof(struct ice_dcf_eth_stats, rx_discards)},
78 : : {"rx_unknown_protocol_packets", offsetof(struct ice_dcf_eth_stats,
79 : : rx_unknown_protocol)},
80 : : {"tx_bytes", offsetof(struct ice_dcf_eth_stats, tx_bytes)},
81 : : {"tx_unicast_packets", offsetof(struct ice_dcf_eth_stats, tx_unicast)},
82 : : {"tx_multicast_packets", offsetof(struct ice_dcf_eth_stats, tx_multicast)},
83 : : {"tx_broadcast_packets", offsetof(struct ice_dcf_eth_stats, tx_broadcast)},
84 : : {"tx_dropped_packets", offsetof(struct ice_dcf_eth_stats, tx_discards)},
85 : : {"tx_error_packets", offsetof(struct ice_dcf_eth_stats, tx_errors)},
86 : : };
87 : :
88 : : #define ICE_DCF_NB_XSTATS (sizeof(rte_ice_dcf_stats_strings) / \
89 : : sizeof(rte_ice_dcf_stats_strings[0]))
90 : :
91 : : static uint16_t
92 : 0 : ice_dcf_recv_pkts(__rte_unused void *rx_queue,
93 : : __rte_unused struct rte_mbuf **bufs,
94 : : __rte_unused uint16_t nb_pkts)
95 : : {
96 : 0 : return 0;
97 : : }
98 : :
99 : : static uint16_t
100 : 0 : ice_dcf_xmit_pkts(__rte_unused void *tx_queue,
101 : : __rte_unused struct rte_mbuf **bufs,
102 : : __rte_unused uint16_t nb_pkts)
103 : : {
104 : 0 : return 0;
105 : : }
106 : :
107 : : static int
108 : 0 : ice_dcf_init_rxq(struct rte_eth_dev *dev, struct ice_rx_queue *rxq)
109 : : {
110 : 0 : struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
111 : : struct rte_eth_dev_data *dev_data = dev->data;
112 : : struct iavf_hw *hw = &dcf_ad->real_hw.avf;
113 : : uint16_t buf_size, max_pkt_len;
114 : :
115 [ # # ]: 0 : buf_size = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM;
116 : 0 : rxq->rx_hdr_len = 0;
117 : 0 : rxq->rx_buf_len = RTE_ALIGN_FLOOR(buf_size, (1 << ICE_RLAN_CTX_DBUF_S));
118 : 0 : rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, ICE_RX_MAX_DATA_BUF_SIZE);
119 : 0 : max_pkt_len = RTE_MIN(ICE_SUPPORT_CHAIN_NUM * rxq->rx_buf_len,
120 : : dev->data->mtu + ICE_ETH_OVERHEAD);
121 : :
122 : : /* Check maximum packet length is set correctly. */
123 [ # # ]: 0 : if (max_pkt_len <= RTE_ETHER_MIN_LEN ||
124 : : max_pkt_len > ICE_FRAME_SIZE_MAX) {
125 : 0 : PMD_DRV_LOG(ERR, "maximum packet length must be "
126 : : "larger than %u and smaller than %u",
127 : : (uint32_t)RTE_ETHER_MIN_LEN,
128 : : (uint32_t)ICE_FRAME_SIZE_MAX);
129 : 0 : return -EINVAL;
130 : : }
131 : :
132 : 0 : rxq->max_pkt_len = max_pkt_len;
133 [ # # ]: 0 : if ((dev_data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER) ||
134 [ # # ]: 0 : (rxq->max_pkt_len + 2 * RTE_VLAN_HLEN) > buf_size) {
135 : 0 : dev_data->scattered_rx = 1;
136 : : }
137 : 0 : rxq->qrx_tail = hw->hw_addr + IAVF_QRX_TAIL1(rxq->queue_id);
138 : 0 : IAVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
139 : 0 : IAVF_WRITE_FLUSH(hw);
140 : :
141 : 0 : return 0;
142 : : }
143 : :
144 : : static int
145 : 0 : ice_dcf_init_rx_queues(struct rte_eth_dev *dev)
146 : : {
147 : 0 : struct ice_rx_queue **rxq =
148 : 0 : (struct ice_rx_queue **)dev->data->rx_queues;
149 : : int i, ret;
150 : :
151 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
152 [ # # # # ]: 0 : if (!rxq[i] || !rxq[i]->q_set)
153 : 0 : continue;
154 : 0 : ret = ice_dcf_init_rxq(dev, rxq[i]);
155 [ # # ]: 0 : if (ret)
156 : 0 : return ret;
157 : : }
158 : :
159 : 0 : ice_set_rx_function(dev);
160 : 0 : ice_set_tx_function(dev);
161 : :
162 : 0 : return 0;
163 : : }
164 : :
165 : : #define IAVF_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
166 : : #define IAVF_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
167 : :
168 : : #define IAVF_ITR_INDEX_DEFAULT 0
169 : : #define IAVF_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
170 : : #define IAVF_QUEUE_ITR_INTERVAL_MAX 8160 /* 8160 us */
171 : :
172 : : static inline uint16_t
173 : : iavf_calc_itr_interval(int16_t interval)
174 : : {
175 : : if (interval < 0 || interval > IAVF_QUEUE_ITR_INTERVAL_MAX)
176 : : interval = IAVF_QUEUE_ITR_INTERVAL_DEFAULT;
177 : :
178 : : /* Convert to hardware count, as writing each 1 represents 2 us */
179 : : return interval / 2;
180 : : }
181 : :
182 : : static int
183 : 0 : ice_dcf_config_rx_queues_irqs(struct rte_eth_dev *dev,
184 : : struct rte_intr_handle *intr_handle)
185 : : {
186 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
187 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
188 : : uint16_t interval, i;
189 : : int vec;
190 : :
191 [ # # ]: 0 : if (rte_intr_cap_multiple(intr_handle) &&
192 [ # # ]: 0 : dev->data->dev_conf.intr_conf.rxq) {
193 [ # # ]: 0 : if (rte_intr_efd_enable(intr_handle, dev->data->nb_rx_queues))
194 : : return -1;
195 : : }
196 : :
197 [ # # ]: 0 : if (rte_intr_dp_is_en(intr_handle)) {
198 [ # # ]: 0 : if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
199 : 0 : dev->data->nb_rx_queues)) {
200 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d rx intr_vec",
201 : : dev->data->nb_rx_queues);
202 : 0 : return -1;
203 : : }
204 : : }
205 : :
206 [ # # # # ]: 0 : if (!dev->data->dev_conf.intr_conf.rxq ||
207 : 0 : !rte_intr_dp_is_en(intr_handle)) {
208 : : /* Rx interrupt disabled, Map interrupt only for writeback */
209 : 0 : hw->nb_msix = 1;
210 [ # # ]: 0 : if (hw->vf_res->vf_cap_flags &
211 : : VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
212 : : /* If WB_ON_ITR supports, enable it */
213 : 0 : hw->msix_base = IAVF_RX_VEC_START;
214 : : /* Set the ITR for index zero, to 2us to make sure that
215 : : * we leave time for aggregation to occur, but don't
216 : : * increase latency dramatically.
217 : : */
218 : 0 : IAVF_WRITE_REG(&hw->avf,
219 : : IAVF_VFINT_DYN_CTLN1(hw->msix_base - 1),
220 : : (0 << IAVF_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) |
221 : : IAVF_VFINT_DYN_CTLN1_WB_ON_ITR_MASK |
222 : : (2UL << IAVF_VFINT_DYN_CTLN1_INTERVAL_SHIFT));
223 : : } else {
224 : : /* If no WB_ON_ITR offload flags, need to set
225 : : * interrupt for descriptor write back.
226 : : */
227 : 0 : hw->msix_base = IAVF_MISC_VEC_ID;
228 : :
229 : : /* set ITR to max */
230 : : interval =
231 : : iavf_calc_itr_interval(IAVF_QUEUE_ITR_INTERVAL_MAX);
232 : 0 : IAVF_WRITE_REG(&hw->avf, IAVF_VFINT_DYN_CTL01,
233 : : IAVF_VFINT_DYN_CTL01_INTENA_MASK |
234 : : (IAVF_ITR_INDEX_DEFAULT <<
235 : : IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT) |
236 : : (interval <<
237 : : IAVF_VFINT_DYN_CTL01_INTERVAL_SHIFT));
238 : : }
239 : 0 : IAVF_WRITE_FLUSH(&hw->avf);
240 : : /* map all queues to the same interrupt */
241 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
242 : 0 : hw->rxq_map[hw->msix_base] |= 1 << i;
243 : : } else {
244 [ # # ]: 0 : if (!rte_intr_allow_others(intr_handle)) {
245 : 0 : hw->nb_msix = 1;
246 : 0 : hw->msix_base = IAVF_MISC_VEC_ID;
247 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
248 : 0 : hw->rxq_map[hw->msix_base] |= 1 << i;
249 : 0 : rte_intr_vec_list_index_set(intr_handle,
250 : : i, IAVF_MISC_VEC_ID);
251 : : }
252 : 0 : PMD_DRV_LOG(DEBUG,
253 : : "vector %u are mapping to all Rx queues",
254 : : hw->msix_base);
255 : : } else {
256 : : /* If Rx interrupt is required, and we can use
257 : : * multi interrupts, then the vec is from 1
258 : : */
259 : 0 : hw->nb_msix = RTE_MIN(hw->vf_res->max_vectors,
260 : : rte_intr_nb_efd_get(intr_handle));
261 : 0 : hw->msix_base = IAVF_MISC_VEC_ID;
262 : : vec = IAVF_MISC_VEC_ID;
263 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
264 : 0 : hw->rxq_map[vec] |= 1 << i;
265 : 0 : rte_intr_vec_list_index_set(intr_handle,
266 : : i, vec++);
267 [ # # ]: 0 : if (vec >= hw->nb_msix)
268 : : vec = IAVF_RX_VEC_START;
269 : : }
270 : 0 : PMD_DRV_LOG(DEBUG,
271 : : "%u vectors are mapping to %u Rx queues",
272 : : hw->nb_msix, dev->data->nb_rx_queues);
273 : : }
274 : : }
275 : :
276 [ # # ]: 0 : if (ice_dcf_config_irq_map(hw)) {
277 : 0 : PMD_DRV_LOG(ERR, "config interrupt mapping failed");
278 : 0 : return -1;
279 : : }
280 : : return 0;
281 : : }
282 : :
283 : : static int
284 : 0 : alloc_rxq_mbufs(struct ice_rx_queue *rxq)
285 : : {
286 : : volatile union ice_rx_flex_desc *rxd;
287 : : struct rte_mbuf *mbuf = NULL;
288 : : uint64_t dma_addr;
289 : : uint16_t i;
290 : :
291 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
292 : 0 : mbuf = rte_mbuf_raw_alloc(rxq->mp);
293 [ # # ]: 0 : if (unlikely(!mbuf)) {
294 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate mbuf for RX");
295 : 0 : return -ENOMEM;
296 : : }
297 : :
298 : : rte_mbuf_refcnt_set(mbuf, 1);
299 : 0 : mbuf->next = NULL;
300 : 0 : mbuf->data_off = RTE_PKTMBUF_HEADROOM;
301 : 0 : mbuf->nb_segs = 1;
302 : 0 : mbuf->port = rxq->port_id;
303 : :
304 : : dma_addr =
305 : : rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
306 : :
307 : 0 : rxd = &rxq->rx_ring[i];
308 : 0 : rxd->read.pkt_addr = dma_addr;
309 : 0 : rxd->read.hdr_addr = 0;
310 : : #ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC
311 : 0 : rxd->read.rsvd1 = 0;
312 : 0 : rxd->read.rsvd2 = 0;
313 : : #endif
314 : :
315 : 0 : rxq->sw_ring[i].mbuf = (void *)mbuf;
316 : : }
317 : :
318 : : return 0;
319 : : }
320 : :
321 : : static int
322 : 0 : ice_dcf_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
323 : : {
324 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
325 : : struct iavf_hw *hw = &ad->real_hw.avf;
326 : : struct ice_rx_queue *rxq;
327 : : int err = 0;
328 : :
329 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
330 : : return -EINVAL;
331 : :
332 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
333 : :
334 : 0 : err = alloc_rxq_mbufs(rxq);
335 [ # # ]: 0 : if (err) {
336 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate RX queue mbuf");
337 : 0 : return err;
338 : : }
339 : :
340 : : rte_wmb();
341 : :
342 : : /* Init the RX tail register. */
343 : 0 : IAVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
344 : 0 : IAVF_WRITE_FLUSH(hw);
345 : :
346 : : /* Ready to switch the queue on */
347 : 0 : err = ice_dcf_switch_queue(&ad->real_hw, rx_queue_id, true, true);
348 [ # # ]: 0 : if (err) {
349 : 0 : PMD_DRV_LOG(ERR, "Failed to switch RX queue %u on",
350 : : rx_queue_id);
351 : 0 : return err;
352 : : }
353 : :
354 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
355 : :
356 : 0 : return 0;
357 : : }
358 : :
359 : : static inline void
360 : 0 : reset_rx_queue(struct ice_rx_queue *rxq)
361 : : {
362 : : uint16_t len;
363 : : uint32_t i;
364 : :
365 [ # # ]: 0 : if (!rxq)
366 : : return;
367 : :
368 : 0 : len = rxq->nb_rx_desc + ICE_RX_MAX_BURST;
369 : :
370 [ # # ]: 0 : for (i = 0; i < len * sizeof(union ice_rx_flex_desc); i++)
371 : 0 : ((volatile char *)rxq->rx_ring)[i] = 0;
372 : :
373 : 0 : memset(&rxq->fake_mbuf, 0x0, sizeof(rxq->fake_mbuf));
374 : :
375 [ # # ]: 0 : for (i = 0; i < ICE_RX_MAX_BURST; i++)
376 : 0 : rxq->sw_ring[rxq->nb_rx_desc + i].mbuf = &rxq->fake_mbuf;
377 : :
378 : : /* for rx bulk */
379 : 0 : rxq->rx_nb_avail = 0;
380 : 0 : rxq->rx_next_avail = 0;
381 : 0 : rxq->rx_free_trigger = (uint16_t)(rxq->rx_free_thresh - 1);
382 : :
383 : 0 : rxq->rx_tail = 0;
384 : 0 : rxq->nb_rx_hold = 0;
385 : 0 : rxq->pkt_first_seg = NULL;
386 : 0 : rxq->pkt_last_seg = NULL;
387 : : }
388 : :
389 : : static inline void
390 : 0 : reset_tx_queue(struct ice_tx_queue *txq)
391 : : {
392 : : struct ice_tx_entry *txe;
393 : : uint32_t i, size;
394 : : uint16_t prev;
395 : :
396 [ # # ]: 0 : if (!txq) {
397 : 0 : PMD_DRV_LOG(DEBUG, "Pointer to txq is NULL");
398 : 0 : return;
399 : : }
400 : :
401 : 0 : txe = txq->sw_ring;
402 : 0 : size = sizeof(struct ice_tx_desc) * txq->nb_tx_desc;
403 [ # # ]: 0 : for (i = 0; i < size; i++)
404 : 0 : ((volatile char *)txq->tx_ring)[i] = 0;
405 : :
406 : 0 : prev = (uint16_t)(txq->nb_tx_desc - 1);
407 [ # # ]: 0 : for (i = 0; i < txq->nb_tx_desc; i++) {
408 : 0 : txq->tx_ring[i].cmd_type_offset_bsz =
409 : : rte_cpu_to_le_64(IAVF_TX_DESC_DTYPE_DESC_DONE);
410 : 0 : txe[i].mbuf = NULL;
411 : 0 : txe[i].last_id = i;
412 : 0 : txe[prev].next_id = i;
413 : : prev = i;
414 : : }
415 : :
416 : 0 : txq->tx_tail = 0;
417 : 0 : txq->nb_tx_used = 0;
418 : :
419 : 0 : txq->last_desc_cleaned = txq->nb_tx_desc - 1;
420 : 0 : txq->nb_tx_free = txq->nb_tx_desc - 1;
421 : :
422 : 0 : txq->tx_next_dd = txq->tx_rs_thresh - 1;
423 : 0 : txq->tx_next_rs = txq->tx_rs_thresh - 1;
424 : : }
425 : :
426 : : static int
427 : 0 : ice_dcf_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
428 : : {
429 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
430 : 0 : struct ice_dcf_hw *hw = &ad->real_hw;
431 : : struct ice_rx_queue *rxq;
432 : : int err;
433 : :
434 [ # # ]: 0 : if (rx_queue_id >= dev->data->nb_rx_queues)
435 : : return -EINVAL;
436 : :
437 : 0 : err = ice_dcf_switch_queue(hw, rx_queue_id, true, false);
438 [ # # ]: 0 : if (err) {
439 : 0 : PMD_DRV_LOG(ERR, "Failed to switch RX queue %u off",
440 : : rx_queue_id);
441 : 0 : return err;
442 : : }
443 : :
444 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
445 : 0 : rxq->rx_rel_mbufs(rxq);
446 : 0 : reset_rx_queue(rxq);
447 : 0 : dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
448 : :
449 : 0 : return 0;
450 : : }
451 : :
452 : : static int
453 : 0 : ice_dcf_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
454 : : {
455 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
456 : : struct iavf_hw *hw = &ad->real_hw.avf;
457 : : struct ice_tx_queue *txq;
458 : : int err = 0;
459 : :
460 [ # # ]: 0 : if (tx_queue_id >= dev->data->nb_tx_queues)
461 : : return -EINVAL;
462 : :
463 : 0 : txq = dev->data->tx_queues[tx_queue_id];
464 : :
465 : : /* Init the RX tail register. */
466 : 0 : txq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(tx_queue_id);
467 : : IAVF_PCI_REG_WRITE(txq->qtx_tail, 0);
468 : 0 : IAVF_WRITE_FLUSH(hw);
469 : :
470 : : /* Ready to switch the queue on */
471 : 0 : err = ice_dcf_switch_queue(&ad->real_hw, tx_queue_id, false, true);
472 : :
473 [ # # ]: 0 : if (err) {
474 : 0 : PMD_DRV_LOG(ERR, "Failed to switch TX queue %u on",
475 : : tx_queue_id);
476 : 0 : return err;
477 : : }
478 : :
479 : 0 : dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
480 : :
481 : 0 : return 0;
482 : : }
483 : :
484 : : static int
485 : 0 : ice_dcf_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
486 : : {
487 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
488 : 0 : struct ice_dcf_hw *hw = &ad->real_hw;
489 : : struct ice_tx_queue *txq;
490 : : int err;
491 : :
492 [ # # ]: 0 : if (tx_queue_id >= dev->data->nb_tx_queues)
493 : : return -EINVAL;
494 : :
495 : 0 : err = ice_dcf_switch_queue(hw, tx_queue_id, false, false);
496 [ # # ]: 0 : if (err) {
497 : 0 : PMD_DRV_LOG(ERR, "Failed to switch TX queue %u off",
498 : : tx_queue_id);
499 : 0 : return err;
500 : : }
501 : :
502 : 0 : txq = dev->data->tx_queues[tx_queue_id];
503 : 0 : txq->tx_rel_mbufs(txq);
504 : 0 : reset_tx_queue(txq);
505 : 0 : dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
506 : :
507 : 0 : return 0;
508 : : }
509 : :
510 : : static int
511 : 0 : ice_dcf_start_queues(struct rte_eth_dev *dev)
512 : : {
513 : : struct ice_rx_queue *rxq;
514 : : struct ice_tx_queue *txq;
515 : : int nb_rxq = 0;
516 : : int nb_txq, i;
517 : :
518 [ # # ]: 0 : for (nb_txq = 0; nb_txq < dev->data->nb_tx_queues; nb_txq++) {
519 : 0 : txq = dev->data->tx_queues[nb_txq];
520 [ # # ]: 0 : if (txq->tx_deferred_start)
521 : 0 : continue;
522 [ # # ]: 0 : if (ice_dcf_tx_queue_start(dev, nb_txq) != 0) {
523 : 0 : PMD_DRV_LOG(ERR, "Fail to start queue %u", nb_txq);
524 : 0 : goto tx_err;
525 : : }
526 : : }
527 : :
528 [ # # ]: 0 : for (nb_rxq = 0; nb_rxq < dev->data->nb_rx_queues; nb_rxq++) {
529 : 0 : rxq = dev->data->rx_queues[nb_rxq];
530 [ # # ]: 0 : if (rxq->rx_deferred_start)
531 : 0 : continue;
532 [ # # ]: 0 : if (ice_dcf_rx_queue_start(dev, nb_rxq) != 0) {
533 : 0 : PMD_DRV_LOG(ERR, "Fail to start queue %u", nb_rxq);
534 : 0 : goto rx_err;
535 : : }
536 : : }
537 : :
538 : : return 0;
539 : :
540 : : /* stop the started queues if failed to start all queues */
541 : : rx_err:
542 [ # # ]: 0 : for (i = 0; i < nb_rxq; i++)
543 : 0 : ice_dcf_rx_queue_stop(dev, i);
544 : 0 : tx_err:
545 [ # # ]: 0 : for (i = 0; i < nb_txq; i++)
546 : 0 : ice_dcf_tx_queue_stop(dev, i);
547 : :
548 : : return -1;
549 : : }
550 : :
551 : : static int
552 : 0 : ice_dcf_dev_start(struct rte_eth_dev *dev)
553 : : {
554 : 0 : struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
555 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
556 : : struct ice_adapter *ad = &dcf_ad->parent;
557 : 0 : struct ice_dcf_hw *hw = &dcf_ad->real_hw;
558 : : int ret;
559 : :
560 [ # # ]: 0 : if (hw->resetting) {
561 : 0 : PMD_DRV_LOG(ERR,
562 : : "The DCF has been reset by PF, please reinit first");
563 : 0 : return -EIO;
564 : : }
565 : :
566 [ # # # # ]: 0 : if (hw->tm_conf.root && !hw->tm_conf.committed) {
567 : 0 : PMD_DRV_LOG(ERR,
568 : : "please call hierarchy_commit() before starting the port");
569 : 0 : return -EIO;
570 : : }
571 : :
572 : 0 : ad->pf.adapter_stopped = 0;
573 : :
574 : 0 : hw->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
575 : : dev->data->nb_tx_queues);
576 : :
577 : 0 : ret = ice_dcf_init_rx_queues(dev);
578 [ # # ]: 0 : if (ret) {
579 : 0 : PMD_DRV_LOG(ERR, "Fail to init queues");
580 : 0 : return ret;
581 : : }
582 : :
583 [ # # ]: 0 : if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
584 : 0 : ret = ice_dcf_init_rss(hw);
585 [ # # ]: 0 : if (ret) {
586 : 0 : PMD_DRV_LOG(ERR, "Failed to configure RSS");
587 : 0 : return ret;
588 : : }
589 : : }
590 : :
591 : 0 : ret = ice_dcf_configure_queues(hw);
592 [ # # ]: 0 : if (ret) {
593 : 0 : PMD_DRV_LOG(ERR, "Fail to config queues");
594 : 0 : return ret;
595 : : }
596 : :
597 : 0 : ret = ice_dcf_config_rx_queues_irqs(dev, intr_handle);
598 [ # # ]: 0 : if (ret) {
599 : 0 : PMD_DRV_LOG(ERR, "Fail to config rx queues' irqs");
600 : 0 : return ret;
601 : : }
602 : :
603 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.rxq != 0) {
604 : 0 : rte_intr_disable(intr_handle);
605 : 0 : rte_intr_enable(intr_handle);
606 : : }
607 : :
608 : 0 : ret = ice_dcf_start_queues(dev);
609 [ # # ]: 0 : if (ret) {
610 : 0 : PMD_DRV_LOG(ERR, "Failed to enable queues");
611 : 0 : return ret;
612 : : }
613 : :
614 : 0 : ret = ice_dcf_add_del_all_mac_addr(hw, hw->eth_dev->data->mac_addrs,
615 : : true, VIRTCHNL_ETHER_ADDR_PRIMARY);
616 [ # # ]: 0 : if (ret) {
617 : 0 : PMD_DRV_LOG(ERR, "Failed to add mac addr");
618 : 0 : return ret;
619 : : }
620 : :
621 [ # # ]: 0 : if (dcf_ad->mc_addrs_num) {
622 : : /* flush previous addresses */
623 : 0 : ret = dcf_add_del_mc_addr_list(hw, dcf_ad->mc_addrs,
624 : : dcf_ad->mc_addrs_num, true);
625 [ # # ]: 0 : if (ret)
626 : : return ret;
627 : : }
628 : :
629 : :
630 : 0 : dev->data->dev_link.link_status = RTE_ETH_LINK_UP;
631 : :
632 : 0 : return 0;
633 : : }
634 : :
635 : : static void
636 : 0 : ice_dcf_stop_queues(struct rte_eth_dev *dev)
637 : : {
638 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
639 : 0 : struct ice_dcf_hw *hw = &ad->real_hw;
640 : : struct ice_rx_queue *rxq;
641 : : struct ice_tx_queue *txq;
642 : : int ret, i;
643 : :
644 : : /* Stop All queues */
645 : 0 : ret = ice_dcf_disable_queues(hw);
646 [ # # ]: 0 : if (ret)
647 : 0 : PMD_DRV_LOG(WARNING, "Fail to stop queues");
648 : :
649 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
650 : 0 : txq = dev->data->tx_queues[i];
651 [ # # ]: 0 : if (!txq)
652 : 0 : continue;
653 : 0 : txq->tx_rel_mbufs(txq);
654 : 0 : reset_tx_queue(txq);
655 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
656 : : }
657 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
658 : 0 : rxq = dev->data->rx_queues[i];
659 [ # # ]: 0 : if (!rxq)
660 : 0 : continue;
661 : 0 : rxq->rx_rel_mbufs(rxq);
662 : 0 : reset_rx_queue(rxq);
663 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
664 : : }
665 : 0 : }
666 : :
667 : : static int
668 : 0 : ice_dcf_dev_stop(struct rte_eth_dev *dev)
669 : : {
670 : 0 : struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
671 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
672 : : struct ice_adapter *ad = &dcf_ad->parent;
673 : :
674 [ # # ]: 0 : if (ad->pf.adapter_stopped == 1) {
675 : 0 : PMD_DRV_LOG(DEBUG, "Port is already stopped");
676 : 0 : return 0;
677 : : }
678 : :
679 : : /* Stop the VF representors for this device */
680 : 0 : ice_dcf_vf_repr_stop_all(dcf_ad);
681 : :
682 : 0 : ice_dcf_stop_queues(dev);
683 : :
684 : 0 : rte_intr_efd_disable(intr_handle);
685 : 0 : rte_intr_vec_list_free(intr_handle);
686 : :
687 : 0 : ice_dcf_add_del_all_mac_addr(&dcf_ad->real_hw,
688 : 0 : dcf_ad->real_hw.eth_dev->data->mac_addrs,
689 : : false, VIRTCHNL_ETHER_ADDR_PRIMARY);
690 : :
691 [ # # ]: 0 : if (dcf_ad->mc_addrs_num)
692 : : /* flush previous addresses */
693 : 0 : (void)dcf_add_del_mc_addr_list(&dcf_ad->real_hw,
694 : 0 : dcf_ad->mc_addrs,
695 : : dcf_ad->mc_addrs_num, false);
696 : :
697 : 0 : dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
698 : 0 : ad->pf.adapter_stopped = 1;
699 : :
700 : 0 : return 0;
701 : : }
702 : :
703 : : static int
704 : 0 : ice_dcf_dev_configure(struct rte_eth_dev *dev)
705 : : {
706 : 0 : struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
707 : : struct ice_adapter *ad = &dcf_ad->parent;
708 : :
709 : 0 : ad->rx_bulk_alloc_allowed = true;
710 : 0 : ad->tx_simple_allowed = true;
711 : :
712 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
713 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
714 : :
715 : 0 : return 0;
716 : : }
717 : :
718 : : static int
719 : 0 : ice_dcf_dev_info_get(struct rte_eth_dev *dev,
720 : : struct rte_eth_dev_info *dev_info)
721 : : {
722 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
723 : : struct ice_dcf_hw *hw = &adapter->real_hw;
724 : :
725 : 0 : dev_info->max_mac_addrs = DCF_NUM_MACADDR_MAX;
726 : 0 : dev_info->max_rx_queues = hw->vsi_res->num_queue_pairs;
727 : 0 : dev_info->max_tx_queues = hw->vsi_res->num_queue_pairs;
728 : 0 : dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN;
729 : 0 : dev_info->max_rx_pktlen = ICE_FRAME_SIZE_MAX;
730 : 0 : dev_info->hash_key_size = hw->vf_res->rss_key_size;
731 : 0 : dev_info->reta_size = hw->vf_res->rss_lut_size;
732 : 0 : dev_info->flow_type_rss_offloads = ICE_RSS_OFFLOAD_ALL;
733 : 0 : dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
734 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - ICE_ETH_OVERHEAD;
735 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
736 : :
737 : 0 : dev_info->rx_offload_capa =
738 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
739 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
740 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
741 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
742 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
743 : : RTE_ETH_RX_OFFLOAD_SCATTER |
744 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
745 : : RTE_ETH_RX_OFFLOAD_RSS_HASH;
746 : 0 : dev_info->tx_offload_capa =
747 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
748 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
749 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
750 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
751 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
752 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
753 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM |
754 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
755 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
756 : : RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
757 : : RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
758 : : RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO |
759 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
760 : :
761 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
762 : : .rx_thresh = {
763 : : .pthresh = ICE_DEFAULT_RX_PTHRESH,
764 : : .hthresh = ICE_DEFAULT_RX_HTHRESH,
765 : : .wthresh = ICE_DEFAULT_RX_WTHRESH,
766 : : },
767 : : .rx_free_thresh = ICE_DEFAULT_RX_FREE_THRESH,
768 : : .rx_drop_en = 0,
769 : : .offloads = 0,
770 : : };
771 : :
772 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
773 : : .tx_thresh = {
774 : : .pthresh = ICE_DEFAULT_TX_PTHRESH,
775 : : .hthresh = ICE_DEFAULT_TX_HTHRESH,
776 : : .wthresh = ICE_DEFAULT_TX_WTHRESH,
777 : : },
778 : : .tx_free_thresh = ICE_DEFAULT_TX_FREE_THRESH,
779 : : .tx_rs_thresh = ICE_DEFAULT_TX_RSBIT_THRESH,
780 : : .offloads = 0,
781 : : };
782 : :
783 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
784 : : .nb_max = ICE_MAX_RING_DESC,
785 : : .nb_min = ICE_MIN_RING_DESC,
786 : : .nb_align = ICE_ALIGN_RING_DESC,
787 : : };
788 : :
789 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
790 : : .nb_max = ICE_MAX_RING_DESC,
791 : : .nb_min = ICE_MIN_RING_DESC,
792 : : .nb_align = ICE_ALIGN_RING_DESC,
793 : : };
794 : :
795 : 0 : return 0;
796 : : }
797 : :
798 : : static int
799 : 0 : dcf_config_promisc(struct ice_dcf_adapter *adapter,
800 : : bool enable_unicast,
801 : : bool enable_multicast)
802 : : {
803 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
804 : : struct virtchnl_promisc_info promisc;
805 : : struct dcf_virtchnl_cmd args;
806 : : int err;
807 : :
808 : 0 : promisc.flags = 0;
809 : 0 : promisc.vsi_id = hw->vsi_res->vsi_id;
810 : :
811 [ # # ]: 0 : if (enable_unicast)
812 : 0 : promisc.flags |= FLAG_VF_UNICAST_PROMISC;
813 : :
814 [ # # ]: 0 : if (enable_multicast)
815 : 0 : promisc.flags |= FLAG_VF_MULTICAST_PROMISC;
816 : :
817 : : memset(&args, 0, sizeof(args));
818 : 0 : args.v_op = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
819 : 0 : args.req_msg = (uint8_t *)&promisc;
820 : 0 : args.req_msglen = sizeof(promisc);
821 : :
822 : 0 : err = ice_dcf_execute_virtchnl_cmd(hw, &args);
823 [ # # ]: 0 : if (err) {
824 : 0 : PMD_DRV_LOG(ERR,
825 : : "fail to execute command VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE");
826 : 0 : return err;
827 : : }
828 : :
829 : 0 : adapter->promisc_unicast_enabled = enable_unicast;
830 : 0 : adapter->promisc_multicast_enabled = enable_multicast;
831 : 0 : return 0;
832 : : }
833 : :
834 : : static int
835 : 0 : ice_dcf_dev_promiscuous_enable(__rte_unused struct rte_eth_dev *dev)
836 : : {
837 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
838 : :
839 [ # # ]: 0 : if (adapter->promisc_unicast_enabled) {
840 : 0 : PMD_DRV_LOG(INFO, "promiscuous has been enabled");
841 : 0 : return 0;
842 : : }
843 : :
844 : 0 : return dcf_config_promisc(adapter, true,
845 : 0 : adapter->promisc_multicast_enabled);
846 : : }
847 : :
848 : : static int
849 : 0 : ice_dcf_dev_promiscuous_disable(__rte_unused struct rte_eth_dev *dev)
850 : : {
851 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
852 : :
853 [ # # ]: 0 : if (!adapter->promisc_unicast_enabled) {
854 : 0 : PMD_DRV_LOG(INFO, "promiscuous has been disabled");
855 : 0 : return 0;
856 : : }
857 : :
858 : 0 : return dcf_config_promisc(adapter, false,
859 : 0 : adapter->promisc_multicast_enabled);
860 : : }
861 : :
862 : : static int
863 : 0 : ice_dcf_dev_allmulticast_enable(__rte_unused struct rte_eth_dev *dev)
864 : : {
865 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
866 : :
867 [ # # ]: 0 : if (adapter->promisc_multicast_enabled) {
868 : 0 : PMD_DRV_LOG(INFO, "allmulticast has been enabled");
869 : 0 : return 0;
870 : : }
871 : :
872 : 0 : return dcf_config_promisc(adapter, adapter->promisc_unicast_enabled,
873 : : true);
874 : : }
875 : :
876 : : static int
877 : 0 : ice_dcf_dev_allmulticast_disable(__rte_unused struct rte_eth_dev *dev)
878 : : {
879 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
880 : :
881 [ # # ]: 0 : if (!adapter->promisc_multicast_enabled) {
882 : 0 : PMD_DRV_LOG(INFO, "allmulticast has been disabled");
883 : 0 : return 0;
884 : : }
885 : :
886 : 0 : return dcf_config_promisc(adapter, adapter->promisc_unicast_enabled,
887 : : false);
888 : : }
889 : :
890 : : static int
891 : 0 : dcf_dev_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr,
892 : : __rte_unused uint32_t index,
893 : : __rte_unused uint32_t pool)
894 : : {
895 [ # # ]: 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
896 : : int err;
897 : :
898 [ # # ]: 0 : if (rte_is_zero_ether_addr(addr)) {
899 : 0 : PMD_DRV_LOG(ERR, "Invalid Ethernet Address");
900 : 0 : return -EINVAL;
901 : : }
902 : :
903 : 0 : err = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, addr, true,
904 : : VIRTCHNL_ETHER_ADDR_EXTRA);
905 [ # # ]: 0 : if (err) {
906 : 0 : PMD_DRV_LOG(ERR, "fail to add MAC address");
907 : 0 : return err;
908 : : }
909 : :
910 : : return 0;
911 : : }
912 : :
913 : : static void
914 : 0 : dcf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index)
915 : : {
916 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
917 : 0 : struct rte_ether_addr *addr = &dev->data->mac_addrs[index];
918 : : int err;
919 : :
920 : 0 : err = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, addr, false,
921 : : VIRTCHNL_ETHER_ADDR_EXTRA);
922 [ # # ]: 0 : if (err)
923 : 0 : PMD_DRV_LOG(ERR, "fail to remove MAC address");
924 : 0 : }
925 : :
926 : : static int
927 : 0 : dcf_add_del_mc_addr_list(struct ice_dcf_hw *hw,
928 : : struct rte_ether_addr *mc_addrs,
929 : : uint32_t mc_addrs_num, bool add)
930 : : {
931 : : struct virtchnl_ether_addr_list *list;
932 : : struct dcf_virtchnl_cmd args;
933 : : uint32_t i;
934 : : int len, err = 0;
935 : :
936 : : len = sizeof(struct virtchnl_ether_addr_list);
937 : 0 : len += sizeof(struct virtchnl_ether_addr) * mc_addrs_num;
938 : :
939 : 0 : list = rte_zmalloc(NULL, len, 0);
940 [ # # ]: 0 : if (!list) {
941 : 0 : PMD_DRV_LOG(ERR, "fail to allocate memory");
942 : 0 : return -ENOMEM;
943 : : }
944 : :
945 [ # # ]: 0 : for (i = 0; i < mc_addrs_num; i++) {
946 : 0 : memcpy(list->list[i].addr, mc_addrs[i].addr_bytes,
947 : : sizeof(list->list[i].addr));
948 : 0 : list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA;
949 : : }
950 : :
951 : 0 : list->vsi_id = hw->vsi_res->vsi_id;
952 [ # # ]: 0 : list->num_elements = mc_addrs_num;
953 : :
954 : : memset(&args, 0, sizeof(args));
955 [ # # ]: 0 : args.v_op = add ? VIRTCHNL_OP_ADD_ETH_ADDR :
956 : : VIRTCHNL_OP_DEL_ETH_ADDR;
957 : 0 : args.req_msg = (uint8_t *)list;
958 : 0 : args.req_msglen = len;
959 : 0 : err = ice_dcf_execute_virtchnl_cmd(hw, &args);
960 [ # # ]: 0 : if (err)
961 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
962 : : add ? "OP_ADD_ETHER_ADDRESS" :
963 : : "OP_DEL_ETHER_ADDRESS");
964 : 0 : rte_free(list);
965 : 0 : return err;
966 : : }
967 : :
968 : : static int
969 : 0 : dcf_set_mc_addr_list(struct rte_eth_dev *dev,
970 : : struct rte_ether_addr *mc_addrs,
971 : : uint32_t mc_addrs_num)
972 : : {
973 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
974 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
975 : : uint32_t i;
976 : : int ret;
977 : :
978 : :
979 [ # # ]: 0 : if (mc_addrs_num > DCF_NUM_MACADDR_MAX) {
980 : 0 : PMD_DRV_LOG(ERR,
981 : : "can't add more than a limited number (%u) of addresses.",
982 : : (uint32_t)DCF_NUM_MACADDR_MAX);
983 : 0 : return -EINVAL;
984 : : }
985 : :
986 [ # # ]: 0 : for (i = 0; i < mc_addrs_num; i++) {
987 [ # # ]: 0 : if (!rte_is_multicast_ether_addr(&mc_addrs[i])) {
988 : : const uint8_t *mac = mc_addrs[i].addr_bytes;
989 : :
990 : 0 : PMD_DRV_LOG(ERR,
991 : : "Invalid mac: %02x:%02x:%02x:%02x:%02x:%02x",
992 : : mac[0], mac[1], mac[2], mac[3], mac[4],
993 : : mac[5]);
994 : 0 : return -EINVAL;
995 : : }
996 : : }
997 : :
998 [ # # ]: 0 : if (adapter->mc_addrs_num) {
999 : : /* flush previous addresses */
1000 : 0 : ret = dcf_add_del_mc_addr_list(hw, adapter->mc_addrs,
1001 : : adapter->mc_addrs_num, false);
1002 [ # # ]: 0 : if (ret)
1003 : : return ret;
1004 : : }
1005 [ # # ]: 0 : if (!mc_addrs_num) {
1006 : 0 : adapter->mc_addrs_num = 0;
1007 : 0 : return 0;
1008 : : }
1009 : :
1010 : : /* add new ones */
1011 : 0 : ret = dcf_add_del_mc_addr_list(hw, mc_addrs, mc_addrs_num, true);
1012 [ # # ]: 0 : if (ret) {
1013 : : /* if adding mac address list fails, should add the
1014 : : * previous addresses back.
1015 : : */
1016 [ # # ]: 0 : if (adapter->mc_addrs_num)
1017 : 0 : (void)dcf_add_del_mc_addr_list(hw, adapter->mc_addrs,
1018 : : adapter->mc_addrs_num,
1019 : : true);
1020 : 0 : return ret;
1021 : : }
1022 : 0 : adapter->mc_addrs_num = mc_addrs_num;
1023 : 0 : memcpy(adapter->mc_addrs,
1024 : : mc_addrs, mc_addrs_num * sizeof(*mc_addrs));
1025 : :
1026 : 0 : return 0;
1027 : : }
1028 : :
1029 : : static int
1030 : 0 : dcf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
1031 : : struct rte_ether_addr *mac_addr)
1032 : : {
1033 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1034 : : struct ice_dcf_hw *hw = &adapter->real_hw;
1035 : : struct rte_ether_addr *old_addr;
1036 : : int ret;
1037 : :
1038 [ # # ]: 0 : old_addr = hw->eth_dev->data->mac_addrs;
1039 [ # # ]: 0 : if (rte_is_same_ether_addr(old_addr, mac_addr))
1040 : : return 0;
1041 : :
1042 : 0 : ret = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, old_addr, false,
1043 : : VIRTCHNL_ETHER_ADDR_PRIMARY);
1044 [ # # ]: 0 : if (ret)
1045 : 0 : PMD_DRV_LOG(ERR, "Fail to delete old MAC:"
1046 : : " %02X:%02X:%02X:%02X:%02X:%02X",
1047 : : old_addr->addr_bytes[0],
1048 : : old_addr->addr_bytes[1],
1049 : : old_addr->addr_bytes[2],
1050 : : old_addr->addr_bytes[3],
1051 : : old_addr->addr_bytes[4],
1052 : : old_addr->addr_bytes[5]);
1053 : :
1054 : 0 : ret = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, mac_addr, true,
1055 : : VIRTCHNL_ETHER_ADDR_PRIMARY);
1056 [ # # ]: 0 : if (ret)
1057 : 0 : PMD_DRV_LOG(ERR, "Fail to add new MAC:"
1058 : : " %02X:%02X:%02X:%02X:%02X:%02X",
1059 : : mac_addr->addr_bytes[0],
1060 : : mac_addr->addr_bytes[1],
1061 : : mac_addr->addr_bytes[2],
1062 : : mac_addr->addr_bytes[3],
1063 : : mac_addr->addr_bytes[4],
1064 : : mac_addr->addr_bytes[5]);
1065 : :
1066 [ # # ]: 0 : if (ret)
1067 : : return -EIO;
1068 : :
1069 : 0 : rte_ether_addr_copy(mac_addr, hw->eth_dev->data->mac_addrs);
1070 : 0 : return 0;
1071 : : }
1072 : :
1073 : : static int
1074 : 0 : dcf_add_del_vlan_v2(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)
1075 : : {
1076 : : struct virtchnl_vlan_supported_caps *supported_caps =
1077 : : &hw->vlan_v2_caps.filtering.filtering_support;
1078 : : struct virtchnl_vlan *vlan_setting;
1079 : : struct virtchnl_vlan_filter_list_v2 vlan_filter;
1080 : : struct dcf_virtchnl_cmd args;
1081 : : uint32_t filtering_caps;
1082 : : int err;
1083 : :
1084 [ # # ]: 0 : if (supported_caps->outer) {
1085 : : filtering_caps = supported_caps->outer;
1086 : : vlan_setting = &vlan_filter.filters[0].outer;
1087 : : } else {
1088 : 0 : filtering_caps = supported_caps->inner;
1089 : : vlan_setting = &vlan_filter.filters[0].inner;
1090 : : }
1091 : :
1092 [ # # ]: 0 : if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100))
1093 : : return -ENOTSUP;
1094 : :
1095 : : memset(&vlan_filter, 0, sizeof(vlan_filter));
1096 : 0 : vlan_filter.vport_id = hw->vsi_res->vsi_id;
1097 : 0 : vlan_filter.num_elements = 1;
1098 : 0 : vlan_setting->tpid = RTE_ETHER_TYPE_VLAN;
1099 : 0 : vlan_setting->tci = vlanid;
1100 : :
1101 : : memset(&args, 0, sizeof(args));
1102 [ # # ]: 0 : args.v_op = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2;
1103 : 0 : args.req_msg = (uint8_t *)&vlan_filter;
1104 : 0 : args.req_msglen = sizeof(vlan_filter);
1105 : 0 : err = ice_dcf_execute_virtchnl_cmd(hw, &args);
1106 [ # # ]: 0 : if (err)
1107 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
1108 : : add ? "OP_ADD_VLAN_V2" : "OP_DEL_VLAN_V2");
1109 : :
1110 : : return err;
1111 : : }
1112 : :
1113 : : static int
1114 : 0 : dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)
1115 : : {
1116 : : struct virtchnl_vlan_filter_list *vlan_list;
1117 : : uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) +
1118 : : sizeof(uint16_t)];
1119 : : struct dcf_virtchnl_cmd args;
1120 : : int err;
1121 : :
1122 : : vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer;
1123 : 0 : vlan_list->vsi_id = hw->vsi_res->vsi_id;
1124 : 0 : vlan_list->num_elements = 1;
1125 [ # # ]: 0 : vlan_list->vlan_id[0] = vlanid;
1126 : :
1127 : : memset(&args, 0, sizeof(args));
1128 [ # # ]: 0 : args.v_op = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN;
1129 : 0 : args.req_msg = cmd_buffer;
1130 : 0 : args.req_msglen = sizeof(cmd_buffer);
1131 : 0 : err = ice_dcf_execute_virtchnl_cmd(hw, &args);
1132 [ # # ]: 0 : if (err)
1133 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
1134 : : add ? "OP_ADD_VLAN" : "OP_DEL_VLAN");
1135 : :
1136 : 0 : return err;
1137 : : }
1138 : :
1139 : : static int
1140 : 0 : dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1141 : : {
1142 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1143 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
1144 : : int err;
1145 : :
1146 [ # # ]: 0 : if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
1147 : 0 : err = dcf_add_del_vlan_v2(hw, vlan_id, on);
1148 [ # # ]: 0 : if (err)
1149 : : return -EIO;
1150 : 0 : return 0;
1151 : : }
1152 : :
1153 [ # # ]: 0 : if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
1154 : : return -ENOTSUP;
1155 : :
1156 : 0 : err = dcf_add_del_vlan(hw, vlan_id, on);
1157 [ # # ]: 0 : if (err)
1158 : 0 : return -EIO;
1159 : : return 0;
1160 : : }
1161 : :
1162 : : static void
1163 : 0 : dcf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable)
1164 : : {
1165 : 0 : struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf;
1166 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1167 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
1168 : : uint32_t i, j;
1169 : : uint64_t ids;
1170 : :
1171 [ # # ]: 0 : for (i = 0; i < RTE_DIM(vfc->ids); i++) {
1172 [ # # ]: 0 : if (vfc->ids[i] == 0)
1173 : 0 : continue;
1174 : :
1175 : : ids = vfc->ids[i];
1176 [ # # ]: 0 : for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) {
1177 [ # # ]: 0 : if (ids & 1)
1178 : 0 : dcf_add_del_vlan_v2(hw, 64 * i + j, enable);
1179 : : }
1180 : : }
1181 : 0 : }
1182 : :
1183 : : static int
1184 : 0 : dcf_config_vlan_strip_v2(struct ice_dcf_hw *hw, bool enable)
1185 : : {
1186 : : struct virtchnl_vlan_supported_caps *stripping_caps =
1187 : : &hw->vlan_v2_caps.offloads.stripping_support;
1188 : : struct virtchnl_vlan_setting vlan_strip;
1189 : : struct dcf_virtchnl_cmd args;
1190 : : uint32_t *ethertype;
1191 : : int ret;
1192 : :
1193 [ # # # # ]: 0 : if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
1194 : : (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE))
1195 : : ethertype = &vlan_strip.outer_ethertype_setting;
1196 [ # # # # ]: 0 : else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
1197 : : (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE))
1198 : : ethertype = &vlan_strip.inner_ethertype_setting;
1199 : : else
1200 : : return -ENOTSUP;
1201 : :
1202 : : memset(&vlan_strip, 0, sizeof(vlan_strip));
1203 : 0 : vlan_strip.vport_id = hw->vsi_res->vsi_id;
1204 : 0 : *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
1205 : :
1206 : : memset(&args, 0, sizeof(args));
1207 [ # # ]: 0 : args.v_op = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
1208 : : VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
1209 : 0 : args.req_msg = (uint8_t *)&vlan_strip;
1210 : 0 : args.req_msglen = sizeof(vlan_strip);
1211 : 0 : ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
1212 [ # # ]: 0 : if (ret)
1213 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
1214 : : enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
1215 : : "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
1216 : :
1217 : : return ret;
1218 : : }
1219 : :
1220 : : static int
1221 : 0 : dcf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask)
1222 : : {
1223 : 0 : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
1224 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1225 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
1226 : : bool enable;
1227 : : int err;
1228 : :
1229 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
1230 : 0 : enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER);
1231 : :
1232 : 0 : dcf_iterate_vlan_filters_v2(dev, enable);
1233 : : }
1234 : :
1235 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1236 : 0 : enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
1237 : :
1238 : 0 : err = dcf_config_vlan_strip_v2(hw, enable);
1239 : : /* If not support, the stripping is already disabled by PF */
1240 [ # # ]: 0 : if (err == -ENOTSUP && !enable)
1241 : : err = 0;
1242 [ # # ]: 0 : if (err)
1243 : 0 : return -EIO;
1244 : : }
1245 : :
1246 : : return 0;
1247 : : }
1248 : :
1249 : : static int
1250 : 0 : dcf_enable_vlan_strip(struct ice_dcf_hw *hw)
1251 : : {
1252 : : struct dcf_virtchnl_cmd args;
1253 : : int ret;
1254 : :
1255 : : memset(&args, 0, sizeof(args));
1256 : 0 : args.v_op = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
1257 : 0 : ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
1258 [ # # ]: 0 : if (ret)
1259 : 0 : PMD_DRV_LOG(ERR,
1260 : : "Failed to execute command of OP_ENABLE_VLAN_STRIPPING");
1261 : :
1262 : 0 : return ret;
1263 : : }
1264 : :
1265 : : static int
1266 : 0 : dcf_disable_vlan_strip(struct ice_dcf_hw *hw)
1267 : : {
1268 : : struct dcf_virtchnl_cmd args;
1269 : : int ret;
1270 : :
1271 : : memset(&args, 0, sizeof(args));
1272 : 0 : args.v_op = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
1273 : 0 : ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
1274 [ # # ]: 0 : if (ret)
1275 : 0 : PMD_DRV_LOG(ERR,
1276 : : "Failed to execute command of OP_DISABLE_VLAN_STRIPPING");
1277 : :
1278 : 0 : return ret;
1279 : : }
1280 : :
1281 : : static int
1282 : 0 : dcf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1283 : : {
1284 : 0 : struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
1285 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1286 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
1287 : : int err;
1288 : :
1289 [ # # ]: 0 : if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
1290 : 0 : return dcf_dev_vlan_offload_set_v2(dev, mask);
1291 : :
1292 [ # # ]: 0 : if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
1293 : : return -ENOTSUP;
1294 : :
1295 : : /* Vlan stripping setting */
1296 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1297 : : /* Enable or disable VLAN stripping */
1298 [ # # ]: 0 : if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1299 : 0 : err = dcf_enable_vlan_strip(hw);
1300 : : else
1301 : 0 : err = dcf_disable_vlan_strip(hw);
1302 : :
1303 [ # # ]: 0 : if (err)
1304 : 0 : return -EIO;
1305 : : }
1306 : : return 0;
1307 : : }
1308 : :
1309 : : static int
1310 : 0 : ice_dcf_dev_flow_ops_get(struct rte_eth_dev *dev,
1311 : : const struct rte_flow_ops **ops)
1312 : : {
1313 [ # # ]: 0 : if (!dev)
1314 : : return -EINVAL;
1315 : :
1316 : 0 : *ops = &ice_flow_ops;
1317 : 0 : return 0;
1318 : : }
1319 : :
1320 : : static int
1321 : 0 : ice_dcf_dev_rss_reta_update(struct rte_eth_dev *dev,
1322 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1323 : : uint16_t reta_size)
1324 : : {
1325 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1326 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
1327 : : uint8_t *lut;
1328 : : uint16_t i, idx, shift;
1329 : : int ret;
1330 : :
1331 [ # # ]: 0 : if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1332 : : return -ENOTSUP;
1333 : :
1334 [ # # ]: 0 : if (reta_size != hw->vf_res->rss_lut_size) {
1335 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
1336 : : "(%d) doesn't match the number of hardware can "
1337 : : "support (%d)", reta_size, hw->vf_res->rss_lut_size);
1338 : 0 : return -EINVAL;
1339 : : }
1340 : :
1341 : 0 : lut = rte_zmalloc("rss_lut", reta_size, 0);
1342 [ # # ]: 0 : if (!lut) {
1343 : 0 : PMD_DRV_LOG(ERR, "No memory can be allocated");
1344 : 0 : return -ENOMEM;
1345 : : }
1346 : : /* store the old lut table temporarily */
1347 [ # # ]: 0 : rte_memcpy(lut, hw->rss_lut, reta_size);
1348 : :
1349 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
1350 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1351 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1352 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
1353 : 0 : lut[i] = reta_conf[idx].reta[shift];
1354 : : }
1355 : :
1356 [ # # ]: 0 : rte_memcpy(hw->rss_lut, lut, reta_size);
1357 : : /* send virtchnnl ops to configure rss*/
1358 : 0 : ret = ice_dcf_configure_rss_lut(hw);
1359 [ # # ]: 0 : if (ret) /* revert back */
1360 [ # # ]: 0 : rte_memcpy(hw->rss_lut, lut, reta_size);
1361 : 0 : rte_free(lut);
1362 : :
1363 : 0 : return ret;
1364 : : }
1365 : :
1366 : : static int
1367 : 0 : ice_dcf_dev_rss_reta_query(struct rte_eth_dev *dev,
1368 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1369 : : uint16_t reta_size)
1370 : : {
1371 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1372 : : struct ice_dcf_hw *hw = &adapter->real_hw;
1373 : : uint16_t i, idx, shift;
1374 : :
1375 [ # # ]: 0 : if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1376 : : return -ENOTSUP;
1377 : :
1378 [ # # ]: 0 : if (reta_size != hw->vf_res->rss_lut_size) {
1379 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
1380 : : "(%d) doesn't match the number of hardware can "
1381 : : "support (%d)", reta_size, hw->vf_res->rss_lut_size);
1382 : 0 : return -EINVAL;
1383 : : }
1384 : :
1385 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
1386 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1387 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1388 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
1389 : 0 : reta_conf[idx].reta[shift] = hw->rss_lut[i];
1390 : : }
1391 : :
1392 : : return 0;
1393 : : }
1394 : :
1395 : : static int
1396 : 0 : ice_dcf_dev_rss_hash_update(struct rte_eth_dev *dev,
1397 : : struct rte_eth_rss_conf *rss_conf)
1398 : : {
1399 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1400 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
1401 : : int ret;
1402 : :
1403 [ # # ]: 0 : if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1404 : : return -ENOTSUP;
1405 : :
1406 : : /* HENA setting, it is enabled by default, no change */
1407 [ # # # # ]: 0 : if (!rss_conf->rss_key || rss_conf->rss_key_len == 0) {
1408 : 0 : PMD_DRV_LOG(DEBUG, "No key to be configured");
1409 : 0 : return 0;
1410 [ # # ]: 0 : } else if (rss_conf->rss_key_len != hw->vf_res->rss_key_size) {
1411 : 0 : PMD_DRV_LOG(ERR, "The size of hash key configured "
1412 : : "(%d) doesn't match the size of hardware can "
1413 : : "support (%d)", rss_conf->rss_key_len,
1414 : : hw->vf_res->rss_key_size);
1415 : 0 : return -EINVAL;
1416 : : }
1417 : :
1418 [ # # ]: 0 : rte_memcpy(hw->rss_key, rss_conf->rss_key, rss_conf->rss_key_len);
1419 : :
1420 : 0 : ret = ice_dcf_configure_rss_key(hw);
1421 [ # # ]: 0 : if (ret)
1422 : : return ret;
1423 : :
1424 : : /* Clear existing RSS. */
1425 : 0 : ret = ice_dcf_set_hena(hw, 0);
1426 : :
1427 : : /* It is a workaround, temporarily allow error to be returned
1428 : : * due to possible lack of PF handling for hena = 0.
1429 : : */
1430 [ # # ]: 0 : if (ret)
1431 : 0 : PMD_DRV_LOG(WARNING, "fail to clean existing RSS,"
1432 : : "lack PF support");
1433 : :
1434 : : /* Set new RSS configuration. */
1435 : 0 : ret = ice_dcf_rss_hash_set(hw, rss_conf->rss_hf, true);
1436 [ # # ]: 0 : if (ret) {
1437 : 0 : PMD_DRV_LOG(ERR, "fail to set new RSS");
1438 : 0 : return ret;
1439 : : }
1440 : :
1441 : : return 0;
1442 : : }
1443 : :
1444 : : static int
1445 : 0 : ice_dcf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
1446 : : struct rte_eth_rss_conf *rss_conf)
1447 : : {
1448 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1449 : : struct ice_dcf_hw *hw = &adapter->real_hw;
1450 : :
1451 [ # # ]: 0 : if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1452 : : return -ENOTSUP;
1453 : :
1454 : : /* Just set it to default value now. */
1455 : 0 : rss_conf->rss_hf = ICE_RSS_OFFLOAD_ALL;
1456 : :
1457 [ # # ]: 0 : if (!rss_conf->rss_key)
1458 : : return 0;
1459 : :
1460 : 0 : rss_conf->rss_key_len = hw->vf_res->rss_key_size;
1461 [ # # ]: 0 : rte_memcpy(rss_conf->rss_key, hw->rss_key, rss_conf->rss_key_len);
1462 : :
1463 : : return 0;
1464 : : }
1465 : :
1466 : : #define ICE_DCF_32_BIT_WIDTH (CHAR_BIT * 4)
1467 : : #define ICE_DCF_48_BIT_WIDTH (CHAR_BIT * 6)
1468 : : #define ICE_DCF_48_BIT_MASK RTE_LEN2MASK(ICE_DCF_48_BIT_WIDTH, uint64_t)
1469 : :
1470 : : static void
1471 : : ice_dcf_stat_update_48(uint64_t *offset, uint64_t *stat)
1472 : : {
1473 [ # # ]: 0 : if (*stat >= *offset)
1474 : 0 : *stat = *stat - *offset;
1475 : : else
1476 : 0 : *stat = (uint64_t)((*stat +
1477 : : ((uint64_t)1 << ICE_DCF_48_BIT_WIDTH)) - *offset);
1478 : :
1479 [ # # # # : 0 : *stat &= ICE_DCF_48_BIT_MASK;
# # # # #
# # # ]
1480 : : }
1481 : :
1482 : : static void
1483 : : ice_dcf_stat_update_32(uint64_t *offset, uint64_t *stat)
1484 : : {
1485 [ # # # # : 0 : if (*stat >= *offset)
# # ]
1486 : 0 : *stat = (uint64_t)(*stat - *offset);
1487 : : else
1488 : 0 : *stat = (uint64_t)((*stat +
1489 : : ((uint64_t)1 << ICE_DCF_32_BIT_WIDTH)) - *offset);
1490 : : }
1491 : :
1492 : : static void
1493 [ # # ]: 0 : ice_dcf_update_stats(struct virtchnl_eth_stats *oes,
1494 : : struct virtchnl_eth_stats *nes)
1495 : : {
1496 : : ice_dcf_stat_update_48(&oes->rx_bytes, &nes->rx_bytes);
1497 : : ice_dcf_stat_update_48(&oes->rx_unicast, &nes->rx_unicast);
1498 : : ice_dcf_stat_update_48(&oes->rx_multicast, &nes->rx_multicast);
1499 : : ice_dcf_stat_update_48(&oes->rx_broadcast, &nes->rx_broadcast);
1500 : : ice_dcf_stat_update_32(&oes->rx_discards, &nes->rx_discards);
1501 : : ice_dcf_stat_update_48(&oes->tx_bytes, &nes->tx_bytes);
1502 : : ice_dcf_stat_update_48(&oes->tx_unicast, &nes->tx_unicast);
1503 : : ice_dcf_stat_update_48(&oes->tx_multicast, &nes->tx_multicast);
1504 : : ice_dcf_stat_update_48(&oes->tx_broadcast, &nes->tx_broadcast);
1505 : : ice_dcf_stat_update_32(&oes->tx_errors, &nes->tx_errors);
1506 : : ice_dcf_stat_update_32(&oes->tx_discards, &nes->tx_discards);
1507 : 0 : }
1508 : :
1509 : :
1510 : : static int
1511 : 0 : ice_dcf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
1512 : : {
1513 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
1514 : 0 : struct ice_dcf_hw *hw = &ad->real_hw;
1515 : : struct virtchnl_eth_stats pstats;
1516 : : int ret;
1517 : :
1518 [ # # ]: 0 : if (hw->resetting) {
1519 : 0 : PMD_DRV_LOG(ERR,
1520 : : "The DCF has been reset by PF, please reinit first");
1521 : 0 : return -EIO;
1522 : : }
1523 : :
1524 : 0 : ret = ice_dcf_query_stats(hw, &pstats);
1525 [ # # ]: 0 : if (ret == 0) {
1526 : 0 : ice_dcf_update_stats(&hw->eth_stats_offset, &pstats);
1527 : 0 : stats->ipackets = pstats.rx_unicast + pstats.rx_multicast +
1528 : 0 : pstats.rx_broadcast - pstats.rx_discards;
1529 : 0 : stats->opackets = pstats.tx_broadcast + pstats.tx_multicast +
1530 : 0 : pstats.tx_unicast;
1531 : 0 : stats->imissed = pstats.rx_discards;
1532 : 0 : stats->oerrors = pstats.tx_errors + pstats.tx_discards;
1533 : 0 : stats->ibytes = pstats.rx_bytes;
1534 : 0 : stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN;
1535 : 0 : stats->obytes = pstats.tx_bytes;
1536 : : } else {
1537 : 0 : PMD_DRV_LOG(ERR, "Get statistics failed");
1538 : : }
1539 : : return ret;
1540 : : }
1541 : :
1542 : : static int
1543 : 0 : ice_dcf_stats_reset(struct rte_eth_dev *dev)
1544 : : {
1545 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
1546 : 0 : struct ice_dcf_hw *hw = &ad->real_hw;
1547 : : struct virtchnl_eth_stats pstats;
1548 : : int ret;
1549 : :
1550 [ # # ]: 0 : if (hw->resetting)
1551 : : return 0;
1552 : :
1553 : : /* read stat values to clear hardware registers */
1554 : 0 : ret = ice_dcf_query_stats(hw, &pstats);
1555 [ # # ]: 0 : if (ret != 0)
1556 : : return ret;
1557 : :
1558 : : /* set stats offset base on current values */
1559 : 0 : hw->eth_stats_offset = pstats;
1560 : :
1561 : 0 : return 0;
1562 : : }
1563 : :
1564 : 0 : static int ice_dcf_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
1565 : : struct rte_eth_xstat_name *xstats_names,
1566 : : __rte_unused unsigned int limit)
1567 : : {
1568 : : unsigned int i;
1569 : :
1570 [ # # ]: 0 : if (xstats_names != NULL)
1571 [ # # ]: 0 : for (i = 0; i < ICE_DCF_NB_XSTATS; i++) {
1572 : 0 : snprintf(xstats_names[i].name,
1573 : : sizeof(xstats_names[i].name),
1574 : 0 : "%s", rte_ice_dcf_stats_strings[i].name);
1575 : : }
1576 : 0 : return ICE_DCF_NB_XSTATS;
1577 : : }
1578 : :
1579 : 0 : static int ice_dcf_xstats_get(struct rte_eth_dev *dev,
1580 : : struct rte_eth_xstat *xstats, unsigned int n)
1581 : : {
1582 : : int ret;
1583 : : unsigned int i;
1584 : 0 : struct ice_dcf_adapter *adapter =
1585 : 0 : ICE_DCF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1586 : 0 : struct ice_dcf_hw *hw = &adapter->real_hw;
1587 : 0 : struct virtchnl_eth_stats *postats = &hw->eth_stats_offset;
1588 : : struct virtchnl_eth_stats pnstats;
1589 : :
1590 [ # # ]: 0 : if (n < ICE_DCF_NB_XSTATS)
1591 : : return ICE_DCF_NB_XSTATS;
1592 : :
1593 : 0 : ret = ice_dcf_query_stats(hw, &pnstats);
1594 [ # # ]: 0 : if (ret != 0)
1595 : : return 0;
1596 : :
1597 [ # # ]: 0 : if (!xstats)
1598 : : return 0;
1599 : :
1600 : 0 : ice_dcf_update_stats(postats, &pnstats);
1601 : :
1602 : : /* loop over xstats array and values from pstats */
1603 [ # # ]: 0 : for (i = 0; i < ICE_DCF_NB_XSTATS; i++) {
1604 : 0 : xstats[i].id = i;
1605 : 0 : xstats[i].value = *(uint64_t *)(((char *)&pnstats) +
1606 : 0 : rte_ice_dcf_stats_strings[i].offset);
1607 : : }
1608 : :
1609 : : return ICE_DCF_NB_XSTATS;
1610 : : }
1611 : :
1612 : : static void
1613 : : ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter)
1614 : : {
1615 [ # # ]: 0 : if (dcf_adapter->repr_infos) {
1616 : 0 : rte_free(dcf_adapter->repr_infos);
1617 : 0 : dcf_adapter->repr_infos = NULL;
1618 : : }
1619 : : }
1620 : :
1621 : : int
1622 : 0 : ice_dcf_handle_vf_repr_close(struct ice_dcf_adapter *dcf_adapter,
1623 : : uint16_t vf_id)
1624 : : {
1625 : : struct ice_dcf_repr_info *vf_rep_info;
1626 : :
1627 [ # # ]: 0 : if (dcf_adapter->num_reprs >= vf_id) {
1628 : 0 : PMD_DRV_LOG(ERR, "Invalid VF id: %d", vf_id);
1629 : 0 : return -1;
1630 : : }
1631 : :
1632 [ # # ]: 0 : if (!dcf_adapter->repr_infos)
1633 : : return 0;
1634 : :
1635 : 0 : vf_rep_info = &dcf_adapter->repr_infos[vf_id];
1636 : 0 : vf_rep_info->vf_rep_eth_dev = NULL;
1637 : :
1638 : 0 : return 0;
1639 : : }
1640 : :
1641 : : static int
1642 : 0 : ice_dcf_init_repr_info(struct ice_dcf_adapter *dcf_adapter)
1643 : : {
1644 : 0 : dcf_adapter->repr_infos =
1645 : 0 : rte_calloc("ice_dcf_rep_info",
1646 : 0 : dcf_adapter->real_hw.num_vfs,
1647 : : sizeof(dcf_adapter->repr_infos[0]), 0);
1648 [ # # ]: 0 : if (!dcf_adapter->repr_infos) {
1649 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc memory for VF representors");
1650 : 0 : return -ENOMEM;
1651 : : }
1652 : :
1653 : : return 0;
1654 : : }
1655 : :
1656 : : static int
1657 : 0 : ice_dcf_dev_close(struct rte_eth_dev *dev)
1658 : : {
1659 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1660 : :
1661 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1662 : : return 0;
1663 : :
1664 : 0 : ice_dcf_vf_repr_notify_all(adapter, false);
1665 : 0 : (void)ice_dcf_dev_stop(dev);
1666 : :
1667 : 0 : ice_free_queues(dev);
1668 : 0 : ice_dcf_uninit_parent_adapter(dev);
1669 : 0 : ice_dcf_uninit_hw(dev, &adapter->real_hw);
1670 : :
1671 : 0 : return 0;
1672 : : }
1673 : :
1674 : : int
1675 : 0 : ice_dcf_link_update(struct rte_eth_dev *dev,
1676 : : __rte_unused int wait_to_complete)
1677 : : {
1678 [ # # # # : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
# # # # #
# ]
1679 : : struct ice_dcf_hw *hw = &ad->real_hw;
1680 : : struct rte_eth_link new_link;
1681 : :
1682 : : memset(&new_link, 0, sizeof(new_link));
1683 : :
1684 : : /* Only read status info stored in VF, and the info is updated
1685 : : * when receive LINK_CHANGE event from PF by virtchnl.
1686 : : */
1687 [ # # # # : 0 : switch (hw->link_speed) {
# # # # #
# ]
1688 : 0 : case 10:
1689 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_10M;
1690 : 0 : break;
1691 : 0 : case 100:
1692 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_100M;
1693 : 0 : break;
1694 : 0 : case 1000:
1695 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_1G;
1696 : 0 : break;
1697 : 0 : case 10000:
1698 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_10G;
1699 : 0 : break;
1700 : 0 : case 20000:
1701 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_20G;
1702 : 0 : break;
1703 : 0 : case 25000:
1704 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_25G;
1705 : 0 : break;
1706 : 0 : case 40000:
1707 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_40G;
1708 : 0 : break;
1709 : 0 : case 50000:
1710 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_50G;
1711 : 0 : break;
1712 : 0 : case 100000:
1713 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_100G;
1714 : 0 : break;
1715 : : default:
1716 : : new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
1717 : : break;
1718 : : }
1719 : :
1720 : 0 : new_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
1721 : 0 : new_link.link_status = hw->link_up ? RTE_ETH_LINK_UP :
1722 : : RTE_ETH_LINK_DOWN;
1723 [ # # ]: 0 : new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
1724 : : RTE_ETH_LINK_SPEED_FIXED);
1725 : :
1726 : 0 : return rte_eth_linkstatus_set(dev, &new_link);
1727 : : }
1728 : :
1729 : : static int
1730 : 0 : ice_dcf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu __rte_unused)
1731 : : {
1732 : : /* mtu setting is forbidden if port is start */
1733 [ # # ]: 0 : if (dev->data->dev_started != 0) {
1734 : 0 : PMD_DRV_LOG(ERR, "port %d must be stopped before configuration",
1735 : : dev->data->port_id);
1736 : 0 : return -EBUSY;
1737 : : }
1738 : :
1739 : : return 0;
1740 : : }
1741 : :
1742 : : bool
1743 : 0 : ice_dcf_adminq_need_retry(struct ice_adapter *ad)
1744 : : {
1745 [ # # ]: 0 : return ad->hw.dcf_enabled &&
1746 [ # # ]: 0 : !rte_atomic_load_explicit(&ad->dcf_state_on, rte_memory_order_relaxed);
1747 : : }
1748 : :
1749 : : /* Add UDP tunneling port */
1750 : : static int
1751 : 0 : ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
1752 : : struct rte_eth_udp_tunnel *udp_tunnel)
1753 : : {
1754 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1755 : : struct ice_adapter *parent_adapter = &adapter->parent;
1756 : 0 : struct ice_hw *parent_hw = &parent_adapter->hw;
1757 : : int ret = 0;
1758 : :
1759 [ # # ]: 0 : if (!udp_tunnel)
1760 : : return -EINVAL;
1761 : :
1762 [ # # # ]: 0 : switch (udp_tunnel->prot_type) {
1763 : 0 : case RTE_ETH_TUNNEL_TYPE_VXLAN:
1764 : 0 : ret = ice_create_tunnel(parent_hw, TNL_VXLAN,
1765 : 0 : udp_tunnel->udp_port);
1766 : 0 : break;
1767 : 0 : case RTE_ETH_TUNNEL_TYPE_ECPRI:
1768 : 0 : ret = ice_create_tunnel(parent_hw, TNL_ECPRI,
1769 : 0 : udp_tunnel->udp_port);
1770 : 0 : break;
1771 : 0 : default:
1772 : 0 : PMD_DRV_LOG(ERR, "Invalid tunnel type");
1773 : : ret = -EINVAL;
1774 : 0 : break;
1775 : : }
1776 : :
1777 : : return ret;
1778 : : }
1779 : :
1780 : : /* Delete UDP tunneling port */
1781 : : static int
1782 : 0 : ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
1783 : : struct rte_eth_udp_tunnel *udp_tunnel)
1784 : : {
1785 : 0 : struct ice_dcf_adapter *adapter = dev->data->dev_private;
1786 : : struct ice_adapter *parent_adapter = &adapter->parent;
1787 : 0 : struct ice_hw *parent_hw = &parent_adapter->hw;
1788 : : int ret = 0;
1789 : :
1790 [ # # ]: 0 : if (!udp_tunnel)
1791 : : return -EINVAL;
1792 : :
1793 [ # # ]: 0 : switch (udp_tunnel->prot_type) {
1794 : 0 : case RTE_ETH_TUNNEL_TYPE_VXLAN:
1795 : : case RTE_ETH_TUNNEL_TYPE_ECPRI:
1796 : 0 : ret = ice_destroy_tunnel(parent_hw, udp_tunnel->udp_port, 0);
1797 : 0 : break;
1798 : 0 : default:
1799 : 0 : PMD_DRV_LOG(ERR, "Invalid tunnel type");
1800 : : ret = -EINVAL;
1801 : 0 : break;
1802 : : }
1803 : :
1804 : : return ret;
1805 : : }
1806 : :
1807 : : static int
1808 : 0 : ice_dcf_tm_ops_get(struct rte_eth_dev *dev __rte_unused,
1809 : : void *arg)
1810 : : {
1811 [ # # ]: 0 : if (!arg)
1812 : : return -EINVAL;
1813 : :
1814 : 0 : *(const void **)arg = &ice_dcf_tm_ops;
1815 : :
1816 : 0 : return 0;
1817 : : }
1818 : :
1819 : : static inline void
1820 : : ice_dcf_reset_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
1821 : : {
1822 : 0 : ice_dcf_uninit_hw(eth_dev, hw);
1823 : 0 : ice_dcf_init_hw(eth_dev, hw);
1824 : 0 : }
1825 : :
1826 : : /* Check if reset has been triggered by PF */
1827 : : static inline bool
1828 : : ice_dcf_is_reset(struct rte_eth_dev *dev)
1829 : : {
1830 : : struct ice_dcf_adapter *ad = dev->data->dev_private;
1831 : : struct iavf_hw *hw = &ad->real_hw.avf;
1832 : :
1833 : 0 : return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) &
1834 : : IAVF_VF_ARQLEN1_ARQENABLE_MASK);
1835 : : }
1836 : :
1837 : : static int
1838 : 0 : ice_dcf_dev_reset(struct rte_eth_dev *dev)
1839 : : {
1840 : 0 : struct ice_dcf_adapter *ad = dev->data->dev_private;
1841 : 0 : struct ice_dcf_hw *hw = &ad->real_hw;
1842 : : int ret;
1843 : :
1844 [ # # ]: 0 : if (ice_dcf_is_reset(dev)) {
1845 [ # # ]: 0 : if (!ad->real_hw.resetting)
1846 : 0 : ad->real_hw.resetting = true;
1847 : 0 : PMD_DRV_LOG(ERR, "The DCF has been reset by PF");
1848 : :
1849 : : /*
1850 : : * Simply reset hw to trigger an additional DCF enable/disable
1851 : : * cycle which help to workaround the issue that kernel driver
1852 : : * may not clean up resource during previous reset.
1853 : : */
1854 : : ice_dcf_reset_hw(dev, hw);
1855 : : }
1856 : :
1857 : 0 : ret = ice_dcf_dev_close(dev);
1858 [ # # ]: 0 : if (ret)
1859 : : return ret;
1860 : :
1861 : 0 : ret = ice_dcf_dev_init(dev);
1862 : :
1863 : 0 : return ret;
1864 : : }
1865 : :
1866 : : static const uint32_t *
1867 : 0 : ice_dcf_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused,
1868 : : size_t *no_of_elements)
1869 : : {
1870 : : static const uint32_t ptypes[] = {
1871 : : RTE_PTYPE_L2_ETHER,
1872 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1873 : : RTE_PTYPE_L4_FRAG,
1874 : : RTE_PTYPE_L4_ICMP,
1875 : : RTE_PTYPE_L4_NONFRAG,
1876 : : RTE_PTYPE_L4_SCTP,
1877 : : RTE_PTYPE_L4_TCP,
1878 : : RTE_PTYPE_L4_UDP,
1879 : : };
1880 : 0 : *no_of_elements = RTE_DIM(ptypes);
1881 : 0 : return ptypes;
1882 : : }
1883 : :
1884 : : static const struct eth_dev_ops ice_dcf_eth_dev_ops = {
1885 : : .dev_start = ice_dcf_dev_start,
1886 : : .dev_stop = ice_dcf_dev_stop,
1887 : : .dev_close = ice_dcf_dev_close,
1888 : : .dev_reset = ice_dcf_dev_reset,
1889 : : .dev_configure = ice_dcf_dev_configure,
1890 : : .dev_infos_get = ice_dcf_dev_info_get,
1891 : : .dev_supported_ptypes_get = ice_dcf_dev_supported_ptypes_get,
1892 : : .rx_queue_setup = ice_rx_queue_setup,
1893 : : .tx_queue_setup = ice_tx_queue_setup,
1894 : : .rx_queue_release = ice_dev_rx_queue_release,
1895 : : .tx_queue_release = ice_dev_tx_queue_release,
1896 : : .rx_queue_start = ice_dcf_rx_queue_start,
1897 : : .tx_queue_start = ice_dcf_tx_queue_start,
1898 : : .rx_queue_stop = ice_dcf_rx_queue_stop,
1899 : : .tx_queue_stop = ice_dcf_tx_queue_stop,
1900 : : .rxq_info_get = ice_rxq_info_get,
1901 : : .txq_info_get = ice_txq_info_get,
1902 : : .get_monitor_addr = ice_get_monitor_addr,
1903 : : .link_update = ice_dcf_link_update,
1904 : : .stats_get = ice_dcf_stats_get,
1905 : : .stats_reset = ice_dcf_stats_reset,
1906 : : .xstats_get = ice_dcf_xstats_get,
1907 : : .xstats_get_names = ice_dcf_xstats_get_names,
1908 : : .xstats_reset = ice_dcf_stats_reset,
1909 : : .promiscuous_enable = ice_dcf_dev_promiscuous_enable,
1910 : : .promiscuous_disable = ice_dcf_dev_promiscuous_disable,
1911 : : .allmulticast_enable = ice_dcf_dev_allmulticast_enable,
1912 : : .allmulticast_disable = ice_dcf_dev_allmulticast_disable,
1913 : : .mac_addr_add = dcf_dev_add_mac_addr,
1914 : : .mac_addr_remove = dcf_dev_del_mac_addr,
1915 : : .set_mc_addr_list = dcf_set_mc_addr_list,
1916 : : .mac_addr_set = dcf_dev_set_default_mac_addr,
1917 : : .vlan_filter_set = dcf_dev_vlan_filter_set,
1918 : : .vlan_offload_set = dcf_dev_vlan_offload_set,
1919 : : .flow_ops_get = ice_dcf_dev_flow_ops_get,
1920 : : .udp_tunnel_port_add = ice_dcf_dev_udp_tunnel_port_add,
1921 : : .udp_tunnel_port_del = ice_dcf_dev_udp_tunnel_port_del,
1922 : : .tm_ops_get = ice_dcf_tm_ops_get,
1923 : : .reta_update = ice_dcf_dev_rss_reta_update,
1924 : : .reta_query = ice_dcf_dev_rss_reta_query,
1925 : : .rss_hash_update = ice_dcf_dev_rss_hash_update,
1926 : : .rss_hash_conf_get = ice_dcf_dev_rss_hash_conf_get,
1927 : : .tx_done_cleanup = ice_tx_done_cleanup,
1928 : : .mtu_set = ice_dcf_dev_mtu_set,
1929 : : };
1930 : :
1931 : : static int
1932 : 0 : ice_dcf_dev_init(struct rte_eth_dev *eth_dev)
1933 : : {
1934 : 0 : struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
1935 : : struct ice_adapter *parent_adapter = &adapter->parent;
1936 : :
1937 : 0 : eth_dev->dev_ops = &ice_dcf_eth_dev_ops;
1938 : 0 : eth_dev->rx_pkt_burst = ice_dcf_recv_pkts;
1939 : 0 : eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts;
1940 : :
1941 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1942 : : return 0;
1943 : :
1944 : 0 : adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg;
1945 [ # # ]: 0 : if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) {
1946 : 0 : PMD_INIT_LOG(ERR, "Failed to init DCF hardware");
1947 : 0 : rte_atomic_store_explicit(&parent_adapter->dcf_state_on, false,
1948 : : rte_memory_order_relaxed);
1949 : 0 : return -1;
1950 : : }
1951 : :
1952 : 0 : rte_atomic_store_explicit(&parent_adapter->dcf_state_on, true, rte_memory_order_relaxed);
1953 : :
1954 [ # # ]: 0 : if (ice_dcf_init_parent_adapter(eth_dev) != 0) {
1955 : 0 : PMD_INIT_LOG(ERR, "Failed to init DCF parent adapter");
1956 : 0 : ice_dcf_uninit_hw(eth_dev, &adapter->real_hw);
1957 : 0 : return -1;
1958 : : }
1959 : :
1960 : 0 : ice_dcf_stats_reset(eth_dev);
1961 : :
1962 : 0 : dcf_config_promisc(adapter, false, false);
1963 : 0 : ice_dcf_vf_repr_notify_all(adapter, true);
1964 : :
1965 : 0 : return 0;
1966 : : }
1967 : :
1968 : : static int
1969 : 0 : ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev)
1970 : : {
1971 [ # # ]: 0 : struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
1972 : :
1973 : : ice_dcf_free_repr_info(adapter);
1974 : 0 : ice_dcf_dev_close(eth_dev);
1975 : :
1976 : 0 : return 0;
1977 : : }
1978 : :
1979 : : static int
1980 : 0 : ice_dcf_engine_disabled_handler(__rte_unused const char *key,
1981 : : const char *value, __rte_unused void *opaque)
1982 : : {
1983 [ # # ]: 0 : if (strcmp(value, "off"))
1984 : 0 : return -1;
1985 : :
1986 : : return 0;
1987 : : }
1988 : :
1989 : : static int
1990 : 0 : ice_dcf_cap_check_handler(__rte_unused const char *key,
1991 : : const char *value, __rte_unused void *opaque)
1992 : : {
1993 [ # # ]: 0 : if (strcmp(value, "dcf"))
1994 : 0 : return -1;
1995 : :
1996 : : return 0;
1997 : : }
1998 : :
1999 : : int
2000 : 0 : ice_devargs_check(struct rte_devargs *devargs, enum ice_dcf_devrarg devarg_type)
2001 : : {
2002 : : struct rte_kvargs *kvlist;
2003 : : unsigned int i = 0;
2004 : : int ret = 0;
2005 : :
2006 [ # # ]: 0 : if (devargs == NULL)
2007 : : return 0;
2008 : :
2009 : 0 : kvlist = rte_kvargs_parse(devargs->args, NULL);
2010 [ # # ]: 0 : if (kvlist == NULL)
2011 : : return 0;
2012 : :
2013 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ice_devargs_table); i++) {
2014 [ # # ]: 0 : if (devarg_type == ice_devargs_table[i].type) {
2015 [ # # ]: 0 : if (!rte_kvargs_count(kvlist, ice_devargs_table[i].key))
2016 : 0 : goto exit;
2017 : :
2018 [ # # ]: 0 : if (rte_kvargs_process(kvlist, ice_devargs_table[i].key,
2019 : 0 : ice_devargs_table[i].handler, NULL) < 0)
2020 : 0 : goto exit;
2021 : : ret = 1;
2022 : : break;
2023 : : }
2024 : : }
2025 : 0 : exit:
2026 : 0 : rte_kvargs_free(kvlist);
2027 : 0 : return ret;
2028 : : }
2029 : :
2030 : : static int
2031 : 0 : eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
2032 : : struct rte_pci_device *pci_dev)
2033 : : {
2034 : 0 : struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
2035 : : struct ice_dcf_vf_repr_param repr_param;
2036 : : char repr_name[RTE_ETH_NAME_MAX_LEN];
2037 : : struct ice_dcf_adapter *dcf_adapter;
2038 : : struct rte_eth_dev *dcf_ethdev;
2039 : : uint16_t dcf_vsi_id;
2040 : : int i, ret;
2041 : :
2042 [ # # ]: 0 : if (!ice_devargs_check(pci_dev->device.devargs, ICE_DCF_DEVARG_CAP))
2043 : : return 1;
2044 : :
2045 : 0 : ret = rte_eth_devargs_parse(pci_dev->device.devargs->args, ð_da, 1);
2046 [ # # ]: 0 : if (ret < 0)
2047 : : return ret;
2048 : :
2049 : 0 : ret = rte_eth_dev_pci_generic_probe(pci_dev,
2050 : : sizeof(struct ice_dcf_adapter),
2051 : : ice_dcf_dev_init);
2052 [ # # # # ]: 0 : if (ret || !eth_da.nb_representor_ports)
2053 : : return ret;
2054 [ # # ]: 0 : if (eth_da.type != RTE_ETH_REPRESENTOR_VF)
2055 : : return -ENOTSUP;
2056 : :
2057 : 0 : dcf_ethdev = rte_eth_dev_allocated(pci_dev->device.name);
2058 [ # # ]: 0 : if (dcf_ethdev == NULL)
2059 : : return -ENODEV;
2060 : :
2061 : 0 : dcf_adapter = dcf_ethdev->data->dev_private;
2062 : 0 : ret = ice_dcf_init_repr_info(dcf_adapter);
2063 [ # # ]: 0 : if (ret)
2064 : : return ret;
2065 : :
2066 [ # # # # ]: 0 : if (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs ||
2067 : : eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) {
2068 : 0 : PMD_DRV_LOG(ERR, "the number of port representors is too large: %u",
2069 : : eth_da.nb_representor_ports);
2070 : : ice_dcf_free_repr_info(dcf_adapter);
2071 : 0 : return -EINVAL;
2072 : : }
2073 : :
2074 : 0 : dcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID;
2075 : :
2076 : 0 : repr_param.dcf_eth_dev = dcf_ethdev;
2077 : 0 : repr_param.switch_domain_id = 0;
2078 : :
2079 [ # # ]: 0 : for (i = 0; i < eth_da.nb_representor_ports; i++) {
2080 : 0 : uint16_t vf_id = eth_da.representor_ports[i];
2081 : : struct rte_eth_dev *vf_rep_eth_dev;
2082 : :
2083 [ # # ]: 0 : if (vf_id >= dcf_adapter->real_hw.num_vfs) {
2084 : 0 : PMD_DRV_LOG(ERR, "VF ID %u is out of range (0 ~ %u)",
2085 : : vf_id, dcf_adapter->real_hw.num_vfs - 1);
2086 : : ret = -EINVAL;
2087 : 0 : break;
2088 : : }
2089 : :
2090 [ # # ]: 0 : if (dcf_adapter->real_hw.vf_vsi_map[vf_id] == dcf_vsi_id) {
2091 : 0 : PMD_DRV_LOG(ERR, "VF ID %u is DCF's ID.", vf_id);
2092 : : ret = -EINVAL;
2093 : 0 : break;
2094 : : }
2095 : :
2096 : 0 : repr_param.vf_id = vf_id;
2097 : 0 : snprintf(repr_name, sizeof(repr_name), "net_%s_representor_%u",
2098 : : pci_dev->device.name, vf_id);
2099 : 0 : ret = rte_eth_dev_create(&pci_dev->device, repr_name,
2100 : : sizeof(struct ice_dcf_vf_repr),
2101 : : NULL, NULL, ice_dcf_vf_repr_init,
2102 : : &repr_param);
2103 [ # # ]: 0 : if (ret) {
2104 : 0 : PMD_DRV_LOG(ERR, "failed to create DCF VF representor %s",
2105 : : repr_name);
2106 : 0 : break;
2107 : : }
2108 : :
2109 : 0 : vf_rep_eth_dev = rte_eth_dev_allocated(repr_name);
2110 [ # # ]: 0 : if (!vf_rep_eth_dev) {
2111 : 0 : PMD_DRV_LOG(ERR,
2112 : : "Failed to find the ethdev for DCF VF representor: %s",
2113 : : repr_name);
2114 : : ret = -ENODEV;
2115 : 0 : break;
2116 : : }
2117 : :
2118 : 0 : dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev = vf_rep_eth_dev;
2119 : 0 : dcf_adapter->num_reprs++;
2120 : : }
2121 : :
2122 : : return ret;
2123 : : }
2124 : :
2125 : : static int
2126 : 0 : eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev)
2127 : : {
2128 : : struct rte_eth_dev *eth_dev;
2129 : :
2130 : 0 : eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
2131 [ # # ]: 0 : if (!eth_dev)
2132 : : return 0;
2133 : :
2134 [ # # ]: 0 : if (rte_eth_dev_is_repr(eth_dev))
2135 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev,
2136 : : ice_dcf_vf_repr_uninit);
2137 : : else
2138 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev,
2139 : : ice_dcf_dev_uninit);
2140 : : }
2141 : :
2142 : : static const struct rte_pci_id pci_id_ice_dcf_map[] = {
2143 : : { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_ADAPTIVE_VF) },
2144 : : { .vendor_id = 0, /* sentinel */ },
2145 : : };
2146 : :
2147 : : static struct rte_pci_driver rte_ice_dcf_pmd = {
2148 : : .id_table = pci_id_ice_dcf_map,
2149 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
2150 : : .probe = eth_ice_dcf_pci_probe,
2151 : : .remove = eth_ice_dcf_pci_remove,
2152 : : };
2153 : :
2154 : 251 : RTE_PMD_REGISTER_PCI(net_ice_dcf, rte_ice_dcf_pmd);
2155 : : RTE_PMD_REGISTER_PCI_TABLE(net_ice_dcf, pci_id_ice_dcf_map);
2156 : : RTE_PMD_REGISTER_KMOD_DEP(net_ice_dcf, "* igb_uio | vfio-pci");
2157 : : RTE_PMD_REGISTER_PARAM_STRING(net_ice_dcf, "cap=dcf");
|