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