Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2024-2026 NXP
3 : : */
4 : :
5 : : #include <stdbool.h>
6 : : #include <rte_kvargs.h>
7 : : #include <rte_random.h>
8 : : #include <dpaax_iova_table.h>
9 : : #include "enetc_logs.h"
10 : : #include "enetc.h"
11 : :
12 : : #define ENETC4_VSI_DISABLE "enetc4_vsi_disable"
13 : : #define ENETC4_VSI_TIMEOUT "enetc4_vsi_timeout"
14 : : #define ENETC4_VSI_DELAY "enetc4_vsi_delay"
15 : : #define ENETC4_NC_MEMORY "nc"
16 : :
17 : : static void
18 : 0 : enetc4_vf_get_devarg_nc(struct rte_eth_dev *dev)
19 : : {
20 : : struct enetc_eth_hw *hw =
21 : 0 : ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
22 : 0 : struct rte_devargs *devargs = dev->device->devargs;
23 : : struct rte_kvargs *kvlist;
24 : : const char *val;
25 : :
26 [ # # ]: 0 : if (!devargs)
27 : : return;
28 : :
29 : 0 : kvlist = rte_kvargs_parse(devargs->args, NULL);
30 [ # # ]: 0 : if (!kvlist)
31 : : return;
32 : :
33 : 0 : val = rte_kvargs_get(kvlist, ENETC4_NC_MEMORY);
34 [ # # # # ]: 0 : if (val && atoi(val) == 1)
35 : 0 : hw->nc_mode = 1;
36 : :
37 : 0 : rte_kvargs_free(kvlist);
38 : : }
39 : :
40 : : #define ENETC_CRC_TABLE_SIZE 256
41 : : #define ENETC_POLY 0x1021
42 : : #define ENETC_CRC_INIT 0xffff
43 : : #define ENETC_BYTE_SIZE 8
44 : : #define ENETC_MSB_BIT 0x8000
45 : :
46 : : uint16_t enetc_crc_table[ENETC_CRC_TABLE_SIZE];
47 : : bool enetc_crc_gen;
48 : :
49 : : /* Supported Rx offloads */
50 : : static uint64_t dev_rx_offloads_sup =
51 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
52 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
53 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
54 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
55 : : RTE_ETH_RX_OFFLOAD_SCATTER;
56 : :
57 : : /* Supported Tx offloads */
58 : : static uint64_t dev_tx_offloads_sup =
59 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
60 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
61 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
62 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
63 : :
64 : : static void
65 : 0 : enetc_gen_crc_table(void)
66 : : {
67 : : uint16_t crc = 0;
68 : : uint16_t c;
69 : :
70 [ # # ]: 0 : for (int i = 0; i < ENETC_CRC_TABLE_SIZE; i++) {
71 : : crc = 0;
72 : 0 : c = i << ENETC_BYTE_SIZE;
73 [ # # ]: 0 : for (int j = 0; j < ENETC_BYTE_SIZE; j++) {
74 [ # # ]: 0 : if ((crc ^ c) & ENETC_MSB_BIT)
75 : 0 : crc = (crc << 1) ^ ENETC_POLY;
76 : : else
77 : 0 : crc = crc << 1;
78 : 0 : c = c << 1;
79 : : }
80 : :
81 : 0 : enetc_crc_table[i] = crc;
82 : : }
83 : :
84 : 0 : enetc_crc_gen = true;
85 : 0 : }
86 : :
87 : : static uint16_t
88 : : enetc_crc_calc(uint16_t crc, const uint8_t *buffer, size_t len)
89 : : {
90 : : uint8_t data;
91 : :
92 [ # # # # : 0 : while (len--) {
# # # # #
# # # # #
# # # # #
# ]
93 : 0 : data = *buffer;
94 : 0 : crc = (crc << 8) ^ enetc_crc_table[((crc >> 8) ^ data) & 0xff];
95 : 0 : buffer++;
96 : : }
97 : : return crc;
98 : : }
99 : :
100 : : static int
101 : 0 : enetc4_vf_dev_infos_get(struct rte_eth_dev *dev,
102 : : struct rte_eth_dev_info *dev_info)
103 : : {
104 : : struct enetc_eth_hw *hw =
105 : 0 : ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
106 : :
107 : 0 : PMD_INIT_FUNC_TRACE();
108 : :
109 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
110 : : .nb_max = MAX_BD_COUNT,
111 : : .nb_min = MIN_BD_COUNT,
112 : : .nb_align = BD_ALIGN,
113 : : .nb_seg_max = ENETC4_MAX_SEGS,
114 : : .nb_mtu_seg_max = ENETC4_MAX_SEGS,
115 : : };
116 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
117 : : .nb_max = MAX_BD_COUNT,
118 : : .nb_min = MIN_BD_COUNT,
119 : : .nb_align = BD_ALIGN,
120 : : .nb_seg_max = ENETC4_MAX_SEGS,
121 : : .nb_mtu_seg_max = ENETC4_MAX_SEGS,
122 : : };
123 : 0 : dev_info->max_rx_queues = hw->max_rx_queues;
124 : 0 : dev_info->max_tx_queues = hw->max_tx_queues;
125 : 0 : dev_info->max_rx_pktlen = ENETC4_MAC_MAXFRM_SIZE;
126 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN);
127 : 0 : dev_info->max_mac_addrs = ENETC4_MAC_ENTRIES;
128 : 0 : dev_info->rx_offload_capa = dev_rx_offloads_sup;
129 : 0 : dev_info->tx_offload_capa = dev_tx_offloads_sup;
130 : 0 : dev_info->flow_type_rss_offloads = ENETC_RSS_OFFLOAD_ALL;
131 : :
132 : 0 : return 0;
133 : : }
134 : :
135 : :
136 : : int
137 : 0 : enetc4_vf_dev_stop(struct rte_eth_dev *dev __rte_unused)
138 : : {
139 : 0 : PMD_INIT_FUNC_TRACE();
140 : :
141 : 0 : return 0;
142 : : }
143 : :
144 : : static int
145 : 0 : enetc4_vf_dev_start(struct rte_eth_dev *dev __rte_unused)
146 : : {
147 : 0 : PMD_INIT_FUNC_TRACE();
148 : :
149 : 0 : return 0;
150 : : }
151 : :
152 : : static int
153 : 0 : enetc4_vf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
154 : : struct eth_queue_stats *qstats __rte_unused)
155 : : {
156 : : struct enetc_eth_hw *hw =
157 : 0 : ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
158 : : struct enetc_hw *enetc_hw = &hw->hw;
159 : : struct enetc_bdr *rx_ring;
160 : : uint8_t i;
161 : :
162 : 0 : PMD_INIT_FUNC_TRACE();
163 : 0 : stats->ipackets = enetc4_rd(enetc_hw, ENETC4_SIRFRM0);
164 : 0 : stats->opackets = enetc4_rd(enetc_hw, ENETC4_SITFRM0);
165 : 0 : stats->ibytes = enetc4_rd(enetc_hw, ENETC4_SIROCT0);
166 : 0 : stats->obytes = enetc4_rd(enetc_hw, ENETC4_SITOCT0);
167 : 0 : stats->oerrors = enetc4_rd(enetc_hw, ENETC4_SITDFCR);
168 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
169 : 0 : rx_ring = dev->data->rx_queues[i];
170 : 0 : stats->ierrors += rx_ring->ierrors;
171 : : }
172 : 0 : return 0;
173 : : }
174 : :
175 : :
176 : : static void
177 : : enetc_msg_vf_fill_common_hdr(struct enetc_msg_swbd *msg,
178 : : uint8_t class_id, uint8_t cmd_id, uint8_t proto_ver,
179 : : uint8_t len, uint8_t cookie)
180 : : {
181 : 0 : struct enetc_msg_cmd_header *hdr = msg->vaddr;
182 : :
183 : 0 : hdr->class_id = class_id;
184 : 0 : hdr->cmd_id = cmd_id;
185 : 0 : hdr->proto_ver = proto_ver;
186 : 0 : hdr->len = len;
187 : 0 : hdr->cookie = cookie;
188 : : /* Incrementing msg 2 bytes ahead as the first two bytes are for CRC */
189 : 0 : hdr->csum = rte_cpu_to_be_16(enetc_crc_calc(ENETC_CRC_INIT,
190 : : (uint8_t *)msg->vaddr + sizeof(uint16_t),
191 : : msg->size - sizeof(uint16_t)));
192 : :
193 : : dcbf(hdr);
194 : 0 : }
195 : :
196 : : /* Messaging */
197 : : static void
198 : : enetc4_msg_vsi_write_msg(struct enetc_hw *hw,
199 : : struct enetc_msg_swbd *msg)
200 : : {
201 : : uint32_t val;
202 : :
203 [ # # ]: 0 : val = enetc_vsi_set_msize(msg->size) | lower_32_bits(msg->dma);
204 : 0 : enetc_wr(hw, ENETC4_VSIMSGSNDAR1, upper_32_bits(msg->dma));
205 : 0 : enetc_wr(hw, ENETC4_VSIMSGSNDAR0, val);
206 : 0 : }
207 : :
208 : : static void
209 : : enetc4_msg_vsi_reply_msg(struct enetc_hw *enetc_hw, struct enetc_psi_reply_msg *reply_msg)
210 : : {
211 : : int vsimsgsr;
212 : : int8_t class_id = 0;
213 : : uint8_t status = 0;
214 : :
215 : 0 : vsimsgsr = enetc_rd(enetc_hw, ENETC4_VSIMSGSR);
216 : :
217 : : /* Extracting 8 bits of message result in class_id */
218 : 0 : class_id |= ((ENETC_SIMSGSR_GET_MC(vsimsgsr) >> 8) & 0xff);
219 : :
220 : : /* Extracting 4 bits of message result in status */
221 : 0 : status |= ((ENETC_SIMSGSR_GET_MC(vsimsgsr) >> 4) & 0xf);
222 : :
223 : 0 : reply_msg->class_id = class_id;
224 : 0 : reply_msg->status = status;
225 : 0 : }
226 : :
227 : : static void
228 : : enetc4_msg_get_psi_msg(struct enetc_hw *enetc_hw, struct enetc_psi_reply_msg *reply_msg)
229 : : {
230 : : int vsimsgrr;
231 : : int8_t class_id = 0;
232 : : uint8_t status = 0;
233 : :
234 : 0 : vsimsgrr = enetc_rd(enetc_hw, ENETC4_VSIMSGRR);
235 : :
236 : : /* Extracting 8 bits of message result in class_id */
237 : 0 : class_id |= ((ENETC_SIMSGSR_GET_MC(vsimsgrr) >> 8) & 0xff);
238 : :
239 : : /* Extracting 4 bits of message result in status */
240 : 0 : status |= ((ENETC_SIMSGSR_GET_MC(vsimsgrr) >> 4) & 0xf);
241 : :
242 : 0 : reply_msg->class_id = class_id;
243 : 0 : reply_msg->status = status;
244 : : }
245 : :
246 : : static void
247 : 0 : enetc4_process_psi_msg(struct rte_eth_dev *eth_dev, struct enetc_hw *enetc_hw)
248 : : {
249 : : struct enetc_psi_reply_msg *msg;
250 : : struct rte_eth_link link;
251 : : int ret = 0;
252 : :
253 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
254 [ # # ]: 0 : if (!msg) {
255 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
256 : 0 : return;
257 : : }
258 : :
259 : 0 : rte_eth_linkstatus_get(eth_dev, &link);
260 : : enetc4_msg_get_psi_msg(enetc_hw, msg);
261 : :
262 [ # # ]: 0 : if (msg->class_id == ENETC_CLASS_ID_LINK_STATUS) {
263 [ # # # ]: 0 : switch (msg->status) {
264 : 0 : case ENETC_LINK_UP:
265 : 0 : ENETC_PMD_DEBUG("Link is up");
266 : 0 : link.link_status = RTE_ETH_LINK_UP;
267 : 0 : break;
268 : 0 : case ENETC_LINK_DOWN:
269 : 0 : ENETC_PMD_DEBUG("Link is down");
270 : 0 : link.link_status = RTE_ETH_LINK_DOWN;
271 : 0 : break;
272 : 0 : default:
273 : 0 : ENETC_PMD_ERR("Unknown link status 0x%x", msg->status);
274 : 0 : break;
275 : : }
276 : : ret = rte_eth_linkstatus_set(eth_dev, &link);
277 : : if (!ret)
278 : 0 : ENETC_PMD_DEBUG("Link status has been changed");
279 : :
280 : : /* Process user registered callback */
281 : 0 : rte_eth_dev_callback_process(eth_dev,
282 : : RTE_ETH_EVENT_INTR_LSC, NULL);
283 : : } else {
284 : 0 : ENETC_PMD_ERR("Wrong message 0x%x", msg->class_id);
285 : : }
286 : :
287 : 0 : rte_free(msg);
288 : : }
289 : :
290 : : static int
291 : 0 : enetc4_msg_vsi_send(struct enetc_eth_hw *hw, struct enetc_msg_swbd *msg)
292 : : {
293 : : struct enetc_hw *enetc_hw = &hw->hw;
294 [ # # ]: 0 : int timeout = hw->vsi_timeout ? (int)hw->vsi_timeout :
295 : : ENETC4_DEF_VSI_WAIT_TIMEOUT_UPDATE;
296 [ # # ]: 0 : int delay_us = hw->vsi_delay ? (int)hw->vsi_delay :
297 : : ENETC4_DEF_VSI_WAIT_DELAY_UPDATE;
298 : : uint8_t class_id = 0;
299 : : int err = 0;
300 : : int vsimsgsr;
301 : :
302 : : enetc4_msg_vsi_write_msg(enetc_hw, msg);
303 : :
304 : : do {
305 : 0 : vsimsgsr = enetc_rd(enetc_hw, ENETC4_VSIMSGSR);
306 [ # # ]: 0 : if (!(vsimsgsr & ENETC4_VSIMSGSR_MB))
307 : : break;
308 : 0 : rte_delay_us(delay_us);
309 [ # # ]: 0 : } while (--timeout);
310 : :
311 [ # # ]: 0 : if (!timeout) {
312 : 0 : ENETC_PMD_ERR("Message not processed by PSI");
313 : 0 : return -ETIMEDOUT;
314 : : }
315 : : /* check for message delivery error */
316 [ # # ]: 0 : if (vsimsgsr & ENETC4_VSIMSGSR_MS) {
317 : 0 : ENETC_PMD_ERR("Transfer error when copying the data");
318 : 0 : return -EIO;
319 : : }
320 : :
321 : 0 : class_id |= ((ENETC_SIMSGSR_GET_MC(vsimsgsr) >> 8) & 0xff);
322 : :
323 : : /* Check the user-defined completion status. */
324 [ # # ]: 0 : if (class_id != ENETC_MSG_CLASS_ID_CMD_SUCCESS) {
325 [ # # # # : 0 : switch (class_id) {
# # # #
# ]
326 : 0 : case ENETC_MSG_CLASS_ID_PERMISSION_DENY:
327 : 0 : ENETC_PMD_ERR("Permission denied");
328 : : err = -EACCES;
329 : 0 : break;
330 : 0 : case ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT:
331 : 0 : ENETC_PMD_ERR("Command not supported");
332 : : err = -EOPNOTSUPP;
333 : 0 : break;
334 : 0 : case ENETC_MSG_CLASS_ID_PSI_BUSY:
335 : 0 : ENETC_PMD_ERR("PSI Busy");
336 : : err = -EBUSY;
337 : 0 : break;
338 : 0 : case ENETC_MSG_CLASS_ID_CMD_TIMEOUT:
339 : 0 : ENETC_PMD_ERR("Command timeout");
340 : : err = -ETIME;
341 : 0 : break;
342 : 0 : case ENETC_MSG_CLASS_ID_CRC_ERROR:
343 : 0 : ENETC_PMD_ERR("CRC error");
344 : : err = -EIO;
345 : 0 : break;
346 : 0 : case ENETC_MSG_CLASS_ID_PROTO_NOT_SUPPORT:
347 : 0 : ENETC_PMD_ERR("Protocol Version not supported");
348 : : err = -EOPNOTSUPP;
349 : 0 : break;
350 : 0 : case ENETC_MSG_CLASS_ID_INVALID_MSG_LEN:
351 : 0 : ENETC_PMD_ERR("Invalid message length");
352 : : err = -EINVAL;
353 : 0 : break;
354 : : case ENETC_CLASS_ID_MAC_FILTER:
355 : : case ENETC_CLASS_ID_LINK_STATUS:
356 : : case ENETC_CLASS_ID_LINK_SPEED:
357 : : break;
358 : 0 : default:
359 : : err = -EIO;
360 : : }
361 : : }
362 : :
363 : : return err;
364 : : }
365 : :
366 : : static int
367 : 0 : enetc4_vf_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
368 : : {
369 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
370 : : struct enetc_hw *enetc_hw = &hw->hw;
371 : : struct enetc_msg_cmd_set_primary_mac *cmd;
372 : : struct enetc_msg_swbd *msg;
373 : : struct enetc_psi_reply_msg *reply_msg;
374 : : uint32_t msg_size;
375 : : int err = 0;
376 : :
377 : 0 : PMD_INIT_FUNC_TRACE();
378 : 0 : reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
379 [ # # ]: 0 : if (!reply_msg) {
380 : 0 : ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
381 : 0 : return -ENOMEM;
382 : : }
383 : :
384 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
385 [ # # ]: 0 : if (!msg) {
386 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
387 : : err = -ENOMEM;
388 : 0 : rte_free(reply_msg);
389 : 0 : return err;
390 : : }
391 : :
392 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_primary_mac),
393 : : ENETC_VSI_PSI_MSG_SIZE);
394 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
395 [ # # ]: 0 : if (!msg->vaddr) {
396 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
397 : 0 : rte_free(msg);
398 : 0 : rte_free(reply_msg);
399 : 0 : return -ENOMEM;
400 : : }
401 : :
402 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
403 : 0 : msg->size = msg_size;
404 : :
405 : 0 : cmd = (struct enetc_msg_cmd_set_primary_mac *)msg->vaddr;
406 : :
407 : 0 : cmd->count = 0;
408 : 0 : memcpy(&cmd->addr.addr_bytes, addr, sizeof(struct rte_ether_addr));
409 : :
410 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
411 : : ENETC_CMD_ID_SET_PRIMARY_MAC, 0, 0, 0);
412 : :
413 : : /* send the command and wait */
414 : 0 : err = enetc4_msg_vsi_send(hw, msg);
415 [ # # ]: 0 : if (err) {
416 : 0 : ENETC_PMD_ERR("VSI message send error");
417 : 0 : goto end;
418 : : }
419 : :
420 : : enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
421 : :
422 [ # # ]: 0 : if (reply_msg->class_id == ENETC_CLASS_ID_MAC_FILTER) {
423 [ # # # ]: 0 : switch (reply_msg->status) {
424 : 0 : case ENETC_INVALID_MAC_ADDR:
425 : 0 : ENETC_PMD_ERR("Invalid MAC address");
426 : : err = -EINVAL;
427 : : break;
428 : 0 : case ENETC_DUPLICATE_MAC_ADDR:
429 : 0 : ENETC_PMD_ERR("Duplicate MAC address");
430 : : err = -EINVAL;
431 : : break;
432 : : default:
433 : : err = -EINVAL;
434 : : break;
435 : : }
436 : : }
437 : :
438 : : if (err) {
439 : 0 : ENETC_PMD_ERR("VSI command execute error!");
440 : 0 : goto end;
441 : : }
442 : :
443 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)&cmd->addr,
444 : 0 : &dev->data->mac_addrs[0]);
445 : :
446 : 0 : end:
447 : : /* free memory no longer required */
448 : 0 : rte_free(msg->vaddr);
449 : 0 : rte_free(reply_msg);
450 : 0 : rte_free(msg);
451 : 0 : return err;
452 : : }
453 : :
454 : : static int
455 : 0 : enetc4_vf_promisc_send_message(struct rte_eth_dev *dev, bool promisc_en)
456 : : {
457 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
458 : : struct enetc_msg_cmd_set_promisc *cmd;
459 : : struct enetc_msg_swbd *msg;
460 : : uint32_t msg_size;
461 : : int err = 0;
462 : :
463 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
464 [ # # ]: 0 : if (!msg) {
465 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
466 : : err = -ENOMEM;
467 : 0 : return err;
468 : : }
469 : :
470 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_promisc), ENETC_VSI_PSI_MSG_SIZE);
471 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
472 [ # # ]: 0 : if (!msg->vaddr) {
473 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
474 : 0 : rte_free(msg);
475 : 0 : return -ENOMEM;
476 : : }
477 : :
478 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
479 : 0 : msg->size = msg_size;
480 : :
481 : 0 : cmd = (struct enetc_msg_cmd_set_promisc *)msg->vaddr;
482 : :
483 : : /* op_type is based on the result of message format
484 : : * 7 6 1 0
485 : : type promisc flush
486 : : */
487 : :
488 [ # # ]: 0 : if (promisc_en)
489 : 0 : cmd->op_type = ENETC_PROMISC_ENABLE;
490 : : else
491 : 0 : cmd->op_type = ENETC_PROMISC_DISABLE;
492 : :
493 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
494 : : ENETC_CMD_ID_SET_MAC_PROMISCUOUS, 0, 0, 0);
495 : :
496 : : /* send the command and wait */
497 : 0 : err = enetc4_msg_vsi_send(hw, msg);
498 [ # # ]: 0 : if (err) {
499 : 0 : ENETC_PMD_ERR("VSI message send error");
500 : 0 : goto end;
501 : : }
502 : :
503 : 0 : end:
504 : : /* free memory no longer required */
505 : 0 : rte_free(msg->vaddr);
506 : 0 : rte_free(msg);
507 : 0 : return err;
508 : : }
509 : :
510 : : static int
511 : 0 : enetc4_vf_allmulti_send_message(struct rte_eth_dev *dev, bool mc_promisc)
512 : : {
513 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
514 : : struct enetc_msg_cmd_set_promisc *cmd;
515 : : struct enetc_msg_swbd *msg;
516 : : uint32_t msg_size;
517 : : int err = 0;
518 : :
519 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
520 [ # # ]: 0 : if (!msg) {
521 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
522 : : err = -ENOMEM;
523 : 0 : return err;
524 : : }
525 : :
526 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_promisc),
527 : : ENETC_VSI_PSI_MSG_SIZE);
528 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
529 [ # # ]: 0 : if (!msg->vaddr) {
530 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
531 : 0 : rte_free(msg);
532 : 0 : return -ENOMEM;
533 : : }
534 : :
535 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
536 : 0 : msg->size = msg_size;
537 : :
538 : 0 : cmd = (struct enetc_msg_cmd_set_promisc *)msg->vaddr;
539 : :
540 : : /* op_type is based on the result of message format
541 : : * 7 6 1 0
542 : : type promisc flush
543 : : */
544 : :
545 [ # # ]: 0 : if (mc_promisc)
546 : 0 : cmd->op_type = ENETC_ALLMULTI_PROMISC_EN;
547 : : else
548 : 0 : cmd->op_type = ENETC_ALLMULTI_PROMISC_DIS;
549 : :
550 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
551 : : ENETC_CMD_ID_SET_MAC_PROMISCUOUS, 0, 0, 0);
552 : :
553 : : /* send the command and wait */
554 : 0 : err = enetc4_msg_vsi_send(hw, msg);
555 [ # # ]: 0 : if (err) {
556 : 0 : ENETC_PMD_ERR("VSI message send error");
557 : 0 : goto end;
558 : : }
559 : :
560 : 0 : end:
561 : : /* free memory no longer required */
562 : 0 : rte_free(msg->vaddr);
563 : 0 : rte_free(msg);
564 : 0 : return err;
565 : : }
566 : :
567 : :
568 : : static int
569 : 0 : enetc4_vf_multicast_enable(struct rte_eth_dev *dev)
570 : : {
571 : : int err;
572 : :
573 : 0 : PMD_INIT_FUNC_TRACE();
574 : 0 : err = enetc4_vf_allmulti_send_message(dev, true);
575 [ # # ]: 0 : if (err) {
576 : 0 : ENETC_PMD_ERR("Failed to enable multicast promiscuous mode");
577 : 0 : return err;
578 : : }
579 : :
580 : : return 0;
581 : : }
582 : :
583 : : static int
584 : 0 : enetc4_vf_multicast_disable(struct rte_eth_dev *dev)
585 : : {
586 : : int err;
587 : :
588 : 0 : PMD_INIT_FUNC_TRACE();
589 : 0 : err = enetc4_vf_allmulti_send_message(dev, false);
590 [ # # ]: 0 : if (err) {
591 : 0 : ENETC_PMD_ERR("Failed to disable multicast promiscuous mode");
592 : 0 : return err;
593 : : }
594 : :
595 : : return 0;
596 : : }
597 : :
598 : : static int
599 : 0 : enetc4_vf_promisc_enable(struct rte_eth_dev *dev)
600 : : {
601 : : int err;
602 : :
603 : 0 : PMD_INIT_FUNC_TRACE();
604 : 0 : err = enetc4_vf_promisc_send_message(dev, true);
605 [ # # ]: 0 : if (err) {
606 : 0 : ENETC_PMD_ERR("Failed to enable promiscuous mode");
607 : 0 : return err;
608 : : }
609 : :
610 : : return 0;
611 : : }
612 : :
613 : : static int
614 : 0 : enetc4_vf_promisc_disable(struct rte_eth_dev *dev)
615 : : {
616 : : int err;
617 : :
618 : 0 : PMD_INIT_FUNC_TRACE();
619 : 0 : err = enetc4_vf_promisc_send_message(dev, false);
620 [ # # ]: 0 : if (err) {
621 : 0 : ENETC_PMD_ERR("Failed to disable promiscuous mode");
622 : 0 : return err;
623 : : }
624 : :
625 : : return 0;
626 : : }
627 : :
628 : : static int
629 : 0 : enetc4_vf_get_link_status(struct rte_eth_dev *dev, struct enetc_psi_reply_msg *reply_msg)
630 : : {
631 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
632 : : struct enetc_hw *enetc_hw = &hw->hw;
633 : : struct enetc_msg_swbd *msg;
634 : : uint32_t msg_size;
635 : : int err = 0;
636 : :
637 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
638 [ # # ]: 0 : if (!msg) {
639 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
640 : : err = -ENOMEM;
641 : 0 : return err;
642 : : }
643 : :
644 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_get_link_status),
645 : : ENETC_VSI_PSI_MSG_SIZE);
646 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
647 [ # # ]: 0 : if (!msg->vaddr) {
648 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
649 : 0 : rte_free(msg);
650 : 0 : return -ENOMEM;
651 : : }
652 : :
653 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
654 : 0 : msg->size = msg_size;
655 : :
656 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_LINK_STATUS,
657 : : ENETC_CMD_ID_GET_LINK_STATUS, 0, 0, 0);
658 : :
659 : : /* send the command and wait */
660 : 0 : err = enetc4_msg_vsi_send(hw, msg);
661 [ # # ]: 0 : if (err) {
662 : 0 : ENETC_PMD_ERR("VSI message send error");
663 : 0 : goto end;
664 : : }
665 : :
666 : : enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
667 : 0 : end:
668 : : /* free memory no longer required */
669 : 0 : rte_free(msg->vaddr);
670 : 0 : rte_free(msg);
671 : 0 : return err;
672 : : }
673 : :
674 : : static int
675 : 0 : enetc4_vf_get_link_speed(struct rte_eth_dev *dev, struct enetc_psi_reply_msg *reply_msg)
676 : : {
677 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
678 : : struct enetc_hw *enetc_hw = &hw->hw;
679 : : struct enetc_msg_swbd *msg;
680 : : uint32_t msg_size;
681 : : int err = 0;
682 : :
683 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
684 [ # # ]: 0 : if (!msg) {
685 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
686 : : err = -ENOMEM;
687 : 0 : return err;
688 : : }
689 : :
690 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_get_link_speed),
691 : : ENETC_VSI_PSI_MSG_SIZE);
692 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
693 [ # # ]: 0 : if (!msg->vaddr) {
694 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
695 : 0 : rte_free(msg);
696 : 0 : return -ENOMEM;
697 : : }
698 : :
699 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
700 : 0 : msg->size = msg_size;
701 : :
702 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_LINK_SPEED,
703 : : ENETC_CMD_ID_GET_LINK_SPEED, 0, 0, 0);
704 : :
705 : : /* send the command and wait */
706 : 0 : err = enetc4_msg_vsi_send(hw, msg);
707 [ # # ]: 0 : if (err) {
708 : 0 : ENETC_PMD_ERR("VSI message send error");
709 : 0 : goto end;
710 : : }
711 : :
712 : : enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
713 : 0 : end:
714 : : /* free memory no longer required */
715 : 0 : rte_free(msg->vaddr);
716 : 0 : rte_free(msg);
717 : 0 : return err;
718 : : }
719 : :
720 : : static int
721 : 0 : enetc4_vf_link_update_dummy(struct rte_eth_dev *dev __rte_unused,
722 : : int wait_to_complete __rte_unused)
723 : : {
724 : 0 : return 0;
725 : : }
726 : :
727 : : static int
728 : 0 : enetc4_vf_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
729 : : {
730 : : struct enetc_psi_reply_msg *reply_msg;
731 : : struct rte_eth_link link;
732 : : int err;
733 : :
734 : 0 : PMD_INIT_FUNC_TRACE();
735 : 0 : reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
736 [ # # ]: 0 : if (!reply_msg) {
737 : 0 : ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
738 : 0 : return -ENOMEM;
739 : : }
740 : :
741 : : memset(&link, 0, sizeof(struct rte_eth_link));
742 : :
743 : 0 : err = enetc4_vf_get_link_status(dev, reply_msg);
744 [ # # ]: 0 : if (err) {
745 : 0 : ENETC_PMD_ERR("Failed to get link status");
746 : 0 : rte_free(reply_msg);
747 : 0 : return err;
748 : : }
749 : :
750 [ # # ]: 0 : if (reply_msg->class_id == ENETC_CLASS_ID_LINK_STATUS) {
751 [ # # # ]: 0 : switch (reply_msg->status) {
752 : 0 : case ENETC_LINK_UP:
753 : 0 : link.link_status = RTE_ETH_LINK_UP;
754 : 0 : break;
755 : : case ENETC_LINK_DOWN:
756 : : link.link_status = RTE_ETH_LINK_DOWN;
757 : : break;
758 : 0 : default:
759 : 0 : ENETC_PMD_ERR("Unknown link status");
760 : 0 : break;
761 : : }
762 : : } else {
763 : 0 : ENETC_PMD_ERR("Wrong reply message");
764 : 0 : return -1;
765 : : }
766 : :
767 : 0 : err = enetc4_vf_get_link_speed(dev, reply_msg);
768 [ # # ]: 0 : if (err) {
769 : 0 : ENETC_PMD_ERR("Failed to get link speed");
770 : 0 : rte_free(reply_msg);
771 : 0 : return err;
772 : : }
773 : :
774 [ # # ]: 0 : if (reply_msg->class_id == ENETC_CLASS_ID_LINK_SPEED) {
775 [ # # # # : 0 : switch (reply_msg->status) {
# # # # #
# # # #
# ]
776 : 0 : case ENETC_SPEED_UNKNOWN:
777 : 0 : ENETC_PMD_DEBUG("Speed unknown");
778 : : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
779 : 0 : break;
780 : 0 : case ENETC_SPEED_10_HALF_DUPLEX:
781 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_10M;
782 : : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
783 : 0 : break;
784 : 0 : case ENETC_SPEED_10_FULL_DUPLEX:
785 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_10M;
786 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
787 : 0 : break;
788 : 0 : case ENETC_SPEED_100_HALF_DUPLEX:
789 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100M;
790 : : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
791 : 0 : break;
792 : 0 : case ENETC_SPEED_100_FULL_DUPLEX:
793 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100M;
794 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
795 : 0 : break;
796 : 0 : case ENETC_SPEED_1000:
797 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_1G;
798 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
799 : 0 : break;
800 : 0 : case ENETC_SPEED_2500:
801 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_2_5G;
802 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
803 : 0 : break;
804 : 0 : case ENETC_SPEED_5000:
805 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_5G;
806 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
807 : 0 : break;
808 : 0 : case ENETC_SPEED_10G:
809 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_10G;
810 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
811 : 0 : break;
812 : 0 : case ENETC_SPEED_25G:
813 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_25G;
814 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
815 : 0 : break;
816 : 0 : case ENETC_SPEED_50G:
817 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_50G;
818 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
819 : 0 : break;
820 : 0 : case ENETC_SPEED_100G:
821 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100G;
822 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
823 : 0 : break;
824 : 0 : case ENETC_SPEED_NOT_SUPPORTED:
825 : 0 : ENETC_PMD_DEBUG("Speed not supported");
826 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
827 : 0 : break;
828 : 0 : default:
829 : 0 : ENETC_PMD_ERR("Unknown speed status");
830 : 0 : break;
831 : : }
832 : : } else {
833 : 0 : ENETC_PMD_ERR("Wrong reply message");
834 : 0 : return -1;
835 : : }
836 : :
837 : 0 : link.link_autoneg = 1;
838 : :
839 : 0 : rte_eth_linkstatus_set(dev, &link);
840 : :
841 : 0 : rte_free(reply_msg);
842 : 0 : return 0;
843 : : }
844 : :
845 : : static int
846 : 0 : enetc4_vf_vlan_promisc(struct rte_eth_dev *dev, bool promisc_en)
847 : : {
848 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
849 : : struct enetc_msg_cmd_set_vlan_promisc *cmd;
850 : : struct enetc_msg_swbd *msg;
851 : : uint32_t msg_size;
852 : : int err = 0;
853 : :
854 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
855 [ # # ]: 0 : if (!msg) {
856 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
857 : : err = -ENOMEM;
858 : 0 : return err;
859 : : }
860 : :
861 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_vlan_promisc),
862 : : ENETC_VSI_PSI_MSG_SIZE);
863 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
864 [ # # ]: 0 : if (!msg->vaddr) {
865 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
866 : 0 : rte_free(msg);
867 : 0 : return -ENOMEM;
868 : : }
869 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
870 : 0 : msg->size = msg_size;
871 : :
872 : 0 : cmd = (struct enetc_msg_cmd_set_vlan_promisc *)msg->vaddr;
873 : : /* op is based on the result of message format
874 : : * 1 0
875 : : * promisc flush
876 : : */
877 : :
878 [ # # ]: 0 : if (promisc_en)
879 : 0 : cmd->op = ENETC_PROMISC_VLAN_ENABLE;
880 : : else
881 : 0 : cmd->op = ENETC_PROMISC_VLAN_DISABLE;
882 : :
883 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_VLAN_FILTER,
884 : : ENETC_CMD_ID_SET_VLAN_PROMISCUOUS, 0, 0, 0);
885 : :
886 : : /* send the command and wait */
887 : 0 : err = enetc4_msg_vsi_send(hw, msg);
888 [ # # ]: 0 : if (err) {
889 : 0 : ENETC_PMD_ERR("VSI message send error");
890 : 0 : goto end;
891 : : }
892 : :
893 : 0 : end:
894 : : /* free memory no longer required */
895 : 0 : rte_free(msg->vaddr);
896 : 0 : rte_free(msg);
897 : 0 : return err;
898 : : }
899 : :
900 : : static int
901 : 0 : enetc4_vf_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *addr,
902 : : uint32_t index __rte_unused, uint32_t pool __rte_unused)
903 : : {
904 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
905 : : struct enetc_hw *enetc_hw = &hw->hw;
906 : : struct enetc_msg_cmd_set_primary_mac *cmd;
907 : : struct enetc_msg_swbd *msg;
908 : : struct enetc_psi_reply_msg *reply_msg;
909 : : uint32_t msg_size;
910 : : int err = 0;
911 : :
912 : 0 : PMD_INIT_FUNC_TRACE();
913 : :
914 : : if (!rte_is_valid_assigned_ether_addr(addr))
915 : : return -EINVAL;
916 : :
917 : 0 : reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
918 [ # # ]: 0 : if (!reply_msg) {
919 : 0 : ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
920 : 0 : return -ENOMEM;
921 : : }
922 : :
923 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
924 [ # # ]: 0 : if (!msg) {
925 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
926 : : err = -ENOMEM;
927 : 0 : rte_free(reply_msg);
928 : 0 : return err;
929 : : }
930 : :
931 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_primary_mac),
932 : : ENETC_VSI_PSI_MSG_SIZE);
933 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
934 [ # # ]: 0 : if (!msg->vaddr) {
935 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
936 : 0 : rte_free(msg);
937 : 0 : rte_free(reply_msg);
938 : 0 : return -ENOMEM;
939 : : }
940 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
941 : 0 : msg->size = msg_size;
942 : 0 : cmd = (struct enetc_msg_cmd_set_primary_mac *)msg->vaddr;
943 : 0 : memcpy(&cmd->addr.addr_bytes, addr, sizeof(struct rte_ether_addr));
944 : 0 : cmd->count = 1;
945 : :
946 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
947 : : ENETC_MSG_ADD_EXACT_MAC_ENTRIES, 0, 0, 0);
948 : :
949 : : /* send the command and wait */
950 : 0 : err = enetc4_msg_vsi_send(hw, msg);
951 [ # # ]: 0 : if (err) {
952 : 0 : ENETC_PMD_ERR("VSI message send error");
953 : 0 : goto end;
954 : : }
955 : :
956 : : enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
957 : :
958 [ # # ]: 0 : if (reply_msg->class_id == ENETC_CLASS_ID_MAC_FILTER) {
959 [ # # # # ]: 0 : switch (reply_msg->status) {
960 : 0 : case ENETC_INVALID_MAC_ADDR:
961 : 0 : ENETC_PMD_ERR("Invalid MAC address");
962 : : err = -EINVAL;
963 : : break;
964 : 0 : case ENETC_DUPLICATE_MAC_ADDR:
965 : 0 : ENETC_PMD_ERR("Duplicate MAC address");
966 : : err = -EINVAL;
967 : : break;
968 : 0 : case ENETC_MAC_FILTER_NO_RESOURCE:
969 : 0 : ENETC_PMD_ERR("Not enough exact-match entries available");
970 : : err = -EINVAL;
971 : : break;
972 : : default:
973 : : err = -EINVAL;
974 : : break;
975 : : }
976 : : }
977 : :
978 : : if (err) {
979 : 0 : ENETC_PMD_ERR("VSI command execute error!");
980 : 0 : goto end;
981 : : }
982 : :
983 : 0 : end:
984 : : /* free memory no longer required */
985 : 0 : rte_free(msg->vaddr);
986 : 0 : rte_free(reply_msg);
987 : 0 : rte_free(msg);
988 : 0 : return err;
989 : : }
990 : :
991 : 0 : static int enetc4_vf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
992 : : {
993 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
994 : : struct enetc_hw *enetc_hw = &hw->hw;
995 : : struct enetc_msg_vlan_exact_filter *cmd;
996 : : struct enetc_msg_swbd *msg;
997 : : struct enetc_psi_reply_msg *reply_msg;
998 : : uint32_t msg_size;
999 : : int err = 0;
1000 : :
1001 : 0 : PMD_INIT_FUNC_TRACE();
1002 : :
1003 : 0 : reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
1004 [ # # ]: 0 : if (!reply_msg) {
1005 : 0 : ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
1006 : 0 : return -ENOMEM;
1007 : : }
1008 : :
1009 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
1010 [ # # ]: 0 : if (!msg) {
1011 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
1012 : : err = -ENOMEM;
1013 : 0 : rte_free(reply_msg);
1014 : 0 : return err;
1015 : : }
1016 : :
1017 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_vlan_exact_filter),
1018 : : ENETC_VSI_PSI_MSG_SIZE);
1019 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
1020 [ # # ]: 0 : if (!msg->vaddr) {
1021 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
1022 : 0 : rte_free(msg);
1023 : 0 : rte_free(reply_msg);
1024 : 0 : return -ENOMEM;
1025 : : }
1026 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
1027 : 0 : msg->size = msg_size;
1028 : 0 : cmd = (struct enetc_msg_vlan_exact_filter *)msg->vaddr;
1029 : 0 : cmd->vlan_count = 1;
1030 : 0 : cmd->vlan_id = vlan_id;
1031 : :
1032 : : /* TPID 2-bit encoding value is taken from the H/W block guide:
1033 : : * 00b Standard C-VLAN 0x8100
1034 : : * 01b Standard S-VLAN 0x88A8
1035 : : * 10b Custom VLAN as defined by CVLANR1[ETYPE]
1036 : : * 11b Custom VLAN as defined by CVLANR2[ETYPE]
1037 : : * Currently Standard C-VLAN is supported. To support others in future.
1038 : : */
1039 : 0 : cmd->tpid = 0;
1040 : :
1041 [ # # ]: 0 : if (on) {
1042 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_VLAN_FILTER,
1043 : : ENETC_MSG_ADD_EXACT_VLAN_ENTRIES, 0, 0, 0);
1044 : : } else {
1045 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_VLAN_FILTER,
1046 : : ENETC_MSG_REMOVE_EXACT_VLAN_ENTRIES, 0, 0, 0);
1047 : : }
1048 : :
1049 : : /* send the command and wait */
1050 : 0 : err = enetc4_msg_vsi_send(hw, msg);
1051 [ # # ]: 0 : if (err) {
1052 : 0 : ENETC_PMD_ERR("VSI message send error");
1053 : 0 : goto end;
1054 : : }
1055 : :
1056 : : enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
1057 : :
1058 [ # # ]: 0 : if (reply_msg->class_id == ENETC_CLASS_ID_VLAN_FILTER) {
1059 [ # # # # : 0 : switch (reply_msg->status) {
# ]
1060 : 0 : case ENETC_INVALID_VLAN_ENTRY:
1061 : 0 : ENETC_PMD_ERR("VLAN entry not valid");
1062 : : err = -EINVAL;
1063 : : break;
1064 : 0 : case ENETC_DUPLICATE_VLAN_ENTRY:
1065 : 0 : ENETC_PMD_ERR("Duplicated VLAN entry");
1066 : : err = -EINVAL;
1067 : : break;
1068 : 0 : case ENETC_VLAN_ENTRY_NOT_FOUND:
1069 : 0 : ENETC_PMD_ERR("VLAN entry not found");
1070 : : err = -EINVAL;
1071 : : break;
1072 : 0 : case ENETC_VLAN_NO_RESOURCE:
1073 : 0 : ENETC_PMD_ERR("Not enough exact-match entries available");
1074 : : err = -EINVAL;
1075 : : break;
1076 : : default:
1077 : : err = -EINVAL;
1078 : : break;
1079 : : }
1080 : : }
1081 : :
1082 : : if (err) {
1083 : 0 : ENETC_PMD_ERR("VSI command execute error!");
1084 : 0 : goto end;
1085 : : }
1086 : :
1087 : 0 : end:
1088 : : /* free memory no longer required */
1089 : 0 : rte_free(msg->vaddr);
1090 : 0 : rte_free(reply_msg);
1091 : 0 : rte_free(msg);
1092 : 0 : return err;
1093 : : }
1094 : :
1095 : 0 : static int enetc4_vf_vlan_offload_set(struct rte_eth_dev *dev, int mask __rte_unused)
1096 : : {
1097 : : int err = 0;
1098 : :
1099 : 0 : PMD_INIT_FUNC_TRACE();
1100 : :
1101 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.offloads) {
1102 : 0 : ENETC_PMD_DEBUG("VLAN filter table entry inserted:"
1103 : : "Disabling VLAN promisc mode");
1104 : 0 : err = enetc4_vf_vlan_promisc(dev, false);
1105 [ # # ]: 0 : if (err) {
1106 : 0 : ENETC_PMD_ERR("Added VLAN filter table entry:"
1107 : : "Failed to disable promiscuous mode");
1108 : 0 : return err;
1109 : : }
1110 : : } else {
1111 : 0 : ENETC_PMD_DEBUG("Enabling VLAN promisc mode");
1112 : 0 : err = enetc4_vf_vlan_promisc(dev, true);
1113 [ # # ]: 0 : if (err) {
1114 : 0 : ENETC_PMD_ERR("Vlan filter table empty:"
1115 : : "Failed to enable promiscuous mode");
1116 : 0 : return err;
1117 : : }
1118 : : }
1119 : :
1120 : : return 0;
1121 : : }
1122 : :
1123 : : static int
1124 : 0 : enetc4_vf_mtu_set(struct rte_eth_dev *dev __rte_unused, uint16_t mtu __rte_unused)
1125 : : {
1126 : 0 : return 0;
1127 : : }
1128 : :
1129 : : static int
1130 : 0 : enetc4_vf_link_register_notif(struct rte_eth_dev *dev, bool enable)
1131 : : {
1132 : 0 : struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1133 : : struct enetc_msg_swbd *msg;
1134 : : struct rte_eth_link link;
1135 : : uint32_t msg_size;
1136 : : int err = 0;
1137 : : uint8_t cmd;
1138 : :
1139 : 0 : PMD_INIT_FUNC_TRACE();
1140 : : memset(&link, 0, sizeof(struct rte_eth_link));
1141 : 0 : msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
1142 [ # # ]: 0 : if (!msg) {
1143 : 0 : ENETC_PMD_ERR("Failed to alloc msg");
1144 : : err = -ENOMEM;
1145 : 0 : return err;
1146 : : }
1147 : :
1148 : : msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_get_link_status), ENETC_VSI_PSI_MSG_SIZE);
1149 : 0 : msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
1150 [ # # ]: 0 : if (!msg->vaddr) {
1151 : 0 : ENETC_PMD_ERR("Failed to alloc memory for msg");
1152 : 0 : rte_free(msg);
1153 : 0 : return -ENOMEM;
1154 : : }
1155 : :
1156 : 0 : msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
1157 : 0 : msg->size = msg_size;
1158 [ # # ]: 0 : if (enable)
1159 : : cmd = ENETC_CMD_ID_REGISTER_LINK_NOTIF;
1160 : : else
1161 : : cmd = ENETC_CMD_ID_UNREGISTER_LINK_NOTIF;
1162 : : enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_LINK_STATUS,
1163 : : cmd, 0, 0, 0);
1164 : :
1165 : : /* send the command and wait */
1166 : 0 : err = enetc4_msg_vsi_send(hw, msg);
1167 [ # # ]: 0 : if (err)
1168 : 0 : ENETC_PMD_ERR("VSI msg error for link status notification");
1169 : :
1170 : : /* free memory no longer required */
1171 : 0 : rte_free(msg->vaddr);
1172 : 0 : rte_free(msg);
1173 : :
1174 : 0 : return err;
1175 : : }
1176 : :
1177 : : /*
1178 : : * The set of PCI devices this driver supports
1179 : : */
1180 : : static const struct rte_pci_id pci_vf_id_enetc4_map[] = {
1181 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_NXP, ENETC4_DEV_ID_VF) },
1182 : : { .vendor_id = 0, /* sentinel */ },
1183 : : };
1184 : :
1185 : : /* Features supported by this driver */
1186 : : /* ops table used when VSI messaging is disabled */
1187 : : static const struct eth_dev_ops enetc4_vf_ops_no_vsi_m = {
1188 : : .dev_configure = enetc4_dev_configure,
1189 : : .dev_start = enetc4_vf_dev_start,
1190 : : .dev_stop = enetc4_vf_dev_stop,
1191 : : .dev_close = enetc4_dev_close,
1192 : : .stats_get = enetc4_vf_stats_get,
1193 : : .dev_infos_get = enetc4_vf_dev_infos_get,
1194 : : .mtu_set = enetc4_vf_mtu_set,
1195 : : .link_update = enetc4_vf_link_update_dummy,
1196 : : .rx_queue_setup = enetc4_rx_queue_setup,
1197 : : .rx_queue_start = enetc4_rx_queue_start,
1198 : : .rx_queue_stop = enetc4_rx_queue_stop,
1199 : : .rx_queue_release = enetc4_rx_queue_release,
1200 : : .tx_queue_setup = enetc4_tx_queue_setup,
1201 : : .tx_queue_start = enetc4_tx_queue_start,
1202 : : .tx_queue_stop = enetc4_tx_queue_stop,
1203 : : .tx_queue_release = enetc4_tx_queue_release,
1204 : : .dev_supported_ptypes_get = enetc4_supported_ptypes_get,
1205 : : };
1206 : :
1207 : : static const struct eth_dev_ops enetc4_vf_ops = {
1208 : : .dev_configure = enetc4_dev_configure,
1209 : : .dev_start = enetc4_vf_dev_start,
1210 : : .dev_stop = enetc4_vf_dev_stop,
1211 : : .dev_close = enetc4_dev_close,
1212 : : .stats_get = enetc4_vf_stats_get,
1213 : : .dev_infos_get = enetc4_vf_dev_infos_get,
1214 : : .mtu_set = enetc4_vf_mtu_set,
1215 : : .mac_addr_set = enetc4_vf_set_mac_addr,
1216 : : .mac_addr_add = enetc4_vf_mac_addr_add,
1217 : : .promiscuous_enable = enetc4_vf_promisc_enable,
1218 : : .promiscuous_disable = enetc4_vf_promisc_disable,
1219 : : .allmulticast_enable = enetc4_vf_multicast_enable,
1220 : : .allmulticast_disable = enetc4_vf_multicast_disable,
1221 : : .link_update = enetc4_vf_link_update,
1222 : : .vlan_filter_set = enetc4_vf_vlan_filter_set,
1223 : : .vlan_offload_set = enetc4_vf_vlan_offload_set,
1224 : : .rx_queue_setup = enetc4_rx_queue_setup,
1225 : : .rx_queue_start = enetc4_rx_queue_start,
1226 : : .rx_queue_stop = enetc4_rx_queue_stop,
1227 : : .rx_queue_release = enetc4_rx_queue_release,
1228 : : .tx_queue_setup = enetc4_tx_queue_setup,
1229 : : .tx_queue_start = enetc4_tx_queue_start,
1230 : : .tx_queue_stop = enetc4_tx_queue_stop,
1231 : : .tx_queue_release = enetc4_tx_queue_release,
1232 : : .dev_supported_ptypes_get = enetc4_supported_ptypes_get,
1233 : : };
1234 : :
1235 : : static int
1236 : 0 : enetc4_vf_mac_init(struct enetc_eth_hw *hw, struct rte_eth_dev *eth_dev)
1237 : : {
1238 : 0 : uint32_t *mac = (uint32_t *)hw->mac.addr;
1239 : : struct enetc_hw *enetc_hw = &hw->hw;
1240 : : uint32_t high_mac = 0;
1241 : : uint16_t low_mac = 0;
1242 : : char vf_eth_name[ENETC_ETH_NAMESIZE];
1243 : :
1244 : 0 : PMD_INIT_FUNC_TRACE();
1245 : :
1246 : : /* Enabling Station Interface */
1247 : 0 : enetc4_wr(enetc_hw, ENETC_SIMR, ENETC_SIMR_EN);
1248 : 0 : *mac = (uint32_t)enetc_rd(enetc_hw, ENETC_SIPMAR0);
1249 : : high_mac = (uint32_t)*mac;
1250 : : mac++;
1251 : 0 : *mac = (uint16_t)enetc_rd(enetc_hw, ENETC_SIPMAR1);
1252 : : low_mac = (uint16_t)*mac;
1253 : :
1254 [ # # ]: 0 : if ((high_mac | low_mac) == 0) {
1255 : : char *first_byte;
1256 : 0 : ENETC_PMD_NOTICE("MAC is not available for this SI, "
1257 : : "set random MAC");
1258 : : mac = (uint32_t *)hw->mac.addr;
1259 : 0 : *mac = (uint32_t)rte_rand();
1260 : : first_byte = (char *)mac;
1261 : 0 : *first_byte &= 0xfe; /* clear multicast bit */
1262 : 0 : *first_byte |= 0x02; /* set local assignment bit (IEEE802) */
1263 : 0 : enetc4_port_wr(enetc_hw, ENETC4_PMAR0, *mac);
1264 : : mac++;
1265 : 0 : *mac = (uint16_t)rte_rand();
1266 : 0 : enetc4_port_wr(enetc_hw, ENETC4_PMAR1, *mac);
1267 : 0 : enetc_print_ethaddr("New address: ",
1268 : : (const struct rte_ether_addr *)hw->mac.addr);
1269 : : }
1270 : :
1271 : : /* Allocate memory for storing MAC addresses */
1272 : 0 : snprintf(vf_eth_name, sizeof(vf_eth_name), "enetc4_vf_eth_%d", eth_dev->data->port_id);
1273 : 0 : eth_dev->data->mac_addrs = rte_zmalloc(vf_eth_name,
1274 : : RTE_ETHER_ADDR_LEN, 0);
1275 [ # # ]: 0 : if (!eth_dev->data->mac_addrs) {
1276 : 0 : ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
1277 : : "store MAC addresses",
1278 : : RTE_ETHER_ADDR_LEN * 1);
1279 : 0 : return -ENOMEM;
1280 : : }
1281 : :
1282 [ # # ]: 0 : if (!enetc_crc_gen)
1283 : 0 : enetc_gen_crc_table();
1284 : :
1285 : : /* Copy the permanent MAC address */
1286 : : rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
1287 : : ð_dev->data->mac_addrs[0]);
1288 : :
1289 : 0 : return 0;
1290 : : }
1291 : :
1292 : : static void
1293 : 0 : enetc_vf_enable_mr_int(struct enetc_hw *hw, bool en)
1294 : : {
1295 : : uint32_t val;
1296 : :
1297 : 0 : val = enetc_rd(hw, ENETC4_VSIIER);
1298 : 0 : val &= ~ENETC4_VSIIER_MRIE;
1299 [ # # ]: 0 : val |= (en) ? ENETC4_VSIIER_MRIE : 0;
1300 : 0 : enetc_wr(hw, ENETC4_VSIIER, val);
1301 : 0 : ENETC_PMD_DEBUG("Interrupt enable status (VSIIER) = 0x%x", val);
1302 : 0 : }
1303 : :
1304 : : static void
1305 : 0 : enetc4_dev_interrupt_handler(void *param)
1306 : : {
1307 : : struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
1308 : : struct enetc_eth_hw *hw =
1309 : 0 : ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
1310 : 0 : struct enetc_hw *enetc_hw = &hw->hw;
1311 : : uint32_t status;
1312 : :
1313 : : /* Disable interrupts before process */
1314 : 0 : enetc_vf_enable_mr_int(enetc_hw, false);
1315 : :
1316 : 0 : status = enetc_rd(enetc_hw, ENETC4_VSIIDR);
1317 : 0 : ENETC_PMD_DEBUG("Got INTR VSIIDR status = 0x%0x", status);
1318 : : /* Check for PSI to VSI message interrupt */
1319 [ # # ]: 0 : if (!(status & ENETC4_VSIIER_MRIE)) {
1320 : 0 : ENETC_PMD_ERR("Interrupt is not PSI to VSI");
1321 : 0 : goto intr_clear;
1322 : : }
1323 : :
1324 : 0 : enetc4_process_psi_msg(eth_dev, enetc_hw);
1325 : 0 : intr_clear:
1326 : : /* Clear Interrupts */
1327 : 0 : enetc_wr(enetc_hw, ENETC4_VSIIDR, 0xffffffff);
1328 : 0 : enetc_vf_enable_mr_int(enetc_hw, true);
1329 : 0 : }
1330 : :
1331 : : static int
1332 : 0 : enetc4_vf_dev_init(struct rte_eth_dev *eth_dev)
1333 : : {
1334 : 0 : struct enetc_eth_hw *hw =
1335 : 0 : ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
1336 : 0 : struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
1337 : : int error = 0;
1338 : : uint32_t si_cap;
1339 : : struct enetc_hw *enetc_hw = &hw->hw;
1340 : :
1341 : 0 : PMD_INIT_FUNC_TRACE();
1342 : :
1343 : : /* check if VSI messaging should be disabled via devarg */
1344 [ # # ]: 0 : if (eth_dev->device->devargs) {
1345 : : struct rte_kvargs *kvlist;
1346 : :
1347 : 0 : kvlist = rte_kvargs_parse(eth_dev->device->devargs->args,
1348 : : NULL);
1349 [ # # ]: 0 : if (kvlist) {
1350 : : const char *val;
1351 : :
1352 [ # # ]: 0 : if (rte_kvargs_count(kvlist, ENETC4_VSI_DISABLE) != 0) {
1353 : 0 : ENETC_PMD_NOTICE("VSI messaging disabled by devarg");
1354 : 0 : eth_dev->dev_ops = &enetc4_vf_ops_no_vsi_m;
1355 : : } else {
1356 : 0 : eth_dev->dev_ops = &enetc4_vf_ops;
1357 : : }
1358 : :
1359 : : /* parse optional VSI-PSI timeout devarg */
1360 : 0 : val = rte_kvargs_get(kvlist, ENETC4_VSI_TIMEOUT);
1361 [ # # ]: 0 : if (val) {
1362 : 0 : errno = 0;
1363 : 0 : hw->vsi_timeout = (uint32_t)strtoul(val, NULL, 0);
1364 [ # # # # ]: 0 : if (errno != 0 || hw->vsi_timeout == 0) {
1365 : 0 : ENETC_PMD_ERR("Invalid VSI Timeout value = %u",
1366 : : hw->vsi_timeout);
1367 : 0 : rte_kvargs_free(kvlist);
1368 : 0 : return -1;
1369 : : }
1370 : 0 : ENETC_PMD_NOTICE("VSI timeout set to %u", hw->vsi_timeout);
1371 : : }
1372 : :
1373 : : /* parse optional VSI-PSI delay devarg */
1374 : 0 : val = rte_kvargs_get(kvlist, ENETC4_VSI_DELAY);
1375 [ # # ]: 0 : if (val) {
1376 : 0 : errno = 0;
1377 : 0 : hw->vsi_delay = (uint32_t)strtoul(val, NULL, 0);
1378 [ # # # # ]: 0 : if (errno != 0 || hw->vsi_delay == 0) {
1379 : 0 : ENETC_PMD_ERR("Invalid VSI Delay value = %u",
1380 : : hw->vsi_delay);
1381 : 0 : rte_kvargs_free(kvlist);
1382 : 0 : return -1;
1383 : : }
1384 : 0 : ENETC_PMD_NOTICE("VSI delay set to %u us", hw->vsi_delay);
1385 : : }
1386 : :
1387 : 0 : rte_kvargs_free(kvlist);
1388 : : } else {
1389 : 0 : eth_dev->dev_ops = &enetc4_vf_ops;
1390 : : }
1391 : : } else {
1392 : 0 : eth_dev->dev_ops = &enetc4_vf_ops;
1393 : : }
1394 : :
1395 : 0 : enetc4_dev_hw_init(eth_dev);
1396 : :
1397 : 0 : hw->nc_mode = 0;
1398 : 0 : enetc4_vf_get_devarg_nc(eth_dev);
1399 [ # # ]: 0 : if (hw->nc_mode) {
1400 : 0 : eth_dev->rx_pkt_burst = &enetc_recv_pkts_nc;
1401 : 0 : eth_dev->tx_pkt_burst = &enetc_xmit_pkts_nc;
1402 : 0 : ENETC_PMD_LOG(INFO, "nc=1: using non-cacheable BD ops (_nc)");
1403 : : }
1404 : :
1405 : 0 : si_cap = enetc_rd(enetc_hw, ENETC_SICAPR0);
1406 : 0 : hw->max_tx_queues = si_cap & ENETC_SICAPR0_BDR_MASK;
1407 : 0 : hw->max_rx_queues = (si_cap >> 16) & ENETC_SICAPR0_BDR_MASK;
1408 : :
1409 : 0 : ENETC_PMD_DEBUG("Max RX queues = %d Max TX queues = %d",
1410 : : hw->max_rx_queues, hw->max_tx_queues);
1411 : 0 : error = enetc4_vf_mac_init(hw, eth_dev);
1412 [ # # ]: 0 : if (error != 0) {
1413 : 0 : ENETC_PMD_ERR("MAC initialization failed!!");
1414 : 0 : return -1;
1415 : : }
1416 : :
1417 [ # # ]: 0 : if (rte_eal_iova_mode() == RTE_IOVA_PA)
1418 : 0 : dpaax_iova_table_populate();
1419 : :
1420 : 0 : ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
1421 : : eth_dev->data->port_id, pci_dev->id.vendor_id,
1422 : : pci_dev->id.device_id);
1423 : : /* update link if VSI messaging is enabled */
1424 [ # # ]: 0 : if (eth_dev->dev_ops == &enetc4_vf_ops)
1425 : 0 : enetc4_vf_link_update(eth_dev, 0);
1426 : :
1427 : : return 0;
1428 : : }
1429 : :
1430 : : static int
1431 : 0 : enetc4_vf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
1432 : : struct rte_pci_device *pci_dev)
1433 : : {
1434 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
1435 : : sizeof(struct enetc_eth_adapter),
1436 : : enetc4_vf_dev_init);
1437 : : }
1438 : :
1439 : : int
1440 : 0 : enetc4_vf_dev_intr(struct rte_eth_dev *eth_dev, bool enable)
1441 : : {
1442 : : struct enetc_eth_hw *hw =
1443 : 0 : ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
1444 : 0 : struct enetc_hw *enetc_hw = &hw->hw;
1445 : 0 : struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
1446 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
1447 : : int ret = 0;
1448 : :
1449 : 0 : PMD_INIT_FUNC_TRACE();
1450 [ # # # # ]: 0 : if (!(intr_handle && rte_intr_fd_get(intr_handle))) {
1451 : 0 : ENETC_PMD_ERR("No INTR handle");
1452 : 0 : return -1;
1453 : : }
1454 [ # # ]: 0 : if (enable) {
1455 : : /* if the interrupts were configured on this devices*/
1456 : 0 : ret = rte_intr_callback_register(intr_handle,
1457 : : enetc4_dev_interrupt_handler, eth_dev);
1458 [ # # ]: 0 : if (ret) {
1459 : 0 : ENETC_PMD_ERR("Failed to register INTR callback %d", ret);
1460 : 0 : return ret;
1461 : : }
1462 : : /* set one IRQ entry for PSI-to-VSI messaging */
1463 : : /* Vector index 0 */
1464 : 0 : enetc_wr(enetc_hw, ENETC4_SIMSIVR, ENETC4_SI_INT_IDX);
1465 : :
1466 : : /* enable uio/vfio intr/eventfd mapping */
1467 : 0 : ret = rte_intr_enable(intr_handle);
1468 [ # # ]: 0 : if (ret) {
1469 : 0 : ENETC_PMD_ERR("Failed to enable INTR %d", ret);
1470 : 0 : goto intr_enable_fail;
1471 : : }
1472 : :
1473 : : /* Enable message received interrupt */
1474 : 0 : enetc_vf_enable_mr_int(enetc_hw, true);
1475 : 0 : ret = enetc4_vf_link_register_notif(eth_dev, true);
1476 [ # # ]: 0 : if (ret) {
1477 : 0 : ENETC_PMD_ERR("Failed to register link notifications %d", ret);
1478 : 0 : goto disable;
1479 : : }
1480 : :
1481 : : return ret;
1482 : : }
1483 : :
1484 : 0 : ret = enetc4_vf_link_register_notif(eth_dev, false);
1485 [ # # ]: 0 : if (ret)
1486 : 0 : ENETC_PMD_WARN("Failed to un-register link notification %d", ret);
1487 : 0 : disable:
1488 : 0 : enetc_vf_enable_mr_int(enetc_hw, false);
1489 : 0 : ret = rte_intr_disable(intr_handle);
1490 [ # # ]: 0 : if (ret)
1491 : 0 : ENETC_PMD_WARN("Failed to disable INTR %d", ret);
1492 : 0 : intr_enable_fail:
1493 : 0 : rte_intr_callback_unregister(intr_handle,
1494 : : enetc4_dev_interrupt_handler, eth_dev);
1495 : :
1496 : 0 : return ret;
1497 : : }
1498 : :
1499 : : static struct rte_pci_driver rte_enetc4_vf_pmd = {
1500 : : .id_table = pci_vf_id_enetc4_map,
1501 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
1502 : : .probe = enetc4_vf_pci_probe,
1503 : : .remove = enetc4_pci_remove,
1504 : : };
1505 : :
1506 : 303 : RTE_PMD_REGISTER_PCI(net_enetc4_vf, rte_enetc4_vf_pmd);
1507 : : RTE_PMD_REGISTER_PCI_TABLE(net_enetc4_vf, pci_vf_id_enetc4_map);
1508 : : RTE_PMD_REGISTER_KMOD_DEP(net_enetc4_vf, "* igb_uio | uio_pci_generic");
1509 : : RTE_PMD_REGISTER_PARAM_STRING(net_enetc4_vf,
1510 : : ENETC4_VSI_DISABLE "=<any> "
1511 : : ENETC4_VSI_TIMEOUT "=<uint> "
1512 : : ENETC4_VSI_DELAY "=<uint> "
1513 : : ENETC4_NC_MEMORY "=<int>");
1514 [ - + ]: 303 : RTE_LOG_REGISTER_DEFAULT(enetc4_vf_logtype_pmd, NOTICE);
|