Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2018-2022 Advanced Micro Devices, Inc.
3 : : */
4 : :
5 : : #include <rte_ethdev.h>
6 : : #include <ethdev_driver.h>
7 : : #include <rte_malloc.h>
8 : :
9 : : #include "ionic_logs.h"
10 : : #include "ionic.h"
11 : : #include "ionic_dev.h"
12 : : #include "ionic_mac_api.h"
13 : : #include "ionic_lif.h"
14 : : #include "ionic_ethdev.h"
15 : : #include "ionic_rxtx.h"
16 : :
17 : : static int eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
18 : : static int eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev);
19 : : static int ionic_dev_info_get(struct rte_eth_dev *eth_dev,
20 : : struct rte_eth_dev_info *dev_info);
21 : : static int ionic_dev_configure(struct rte_eth_dev *dev);
22 : : static int ionic_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
23 : : static int ionic_dev_start(struct rte_eth_dev *dev);
24 : : static int ionic_dev_stop(struct rte_eth_dev *dev);
25 : : static int ionic_dev_close(struct rte_eth_dev *dev);
26 : : static int ionic_dev_set_link_up(struct rte_eth_dev *dev);
27 : : static int ionic_dev_set_link_down(struct rte_eth_dev *dev);
28 : : static int ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev,
29 : : struct rte_eth_fc_conf *fc_conf);
30 : : static int ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev,
31 : : struct rte_eth_fc_conf *fc_conf);
32 : : static int ionic_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask);
33 : : static int ionic_dev_rss_reta_update(struct rte_eth_dev *eth_dev,
34 : : struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size);
35 : : static int ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev,
36 : : struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size);
37 : : static int ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
38 : : struct rte_eth_rss_conf *rss_conf);
39 : : static int ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev,
40 : : struct rte_eth_rss_conf *rss_conf);
41 : : static int ionic_dev_stats_get(struct rte_eth_dev *eth_dev,
42 : : struct rte_eth_stats *stats);
43 : : static int ionic_dev_stats_reset(struct rte_eth_dev *eth_dev);
44 : : static int ionic_dev_xstats_get(struct rte_eth_dev *dev,
45 : : struct rte_eth_xstat *xstats, unsigned int n);
46 : : static int ionic_dev_xstats_get_by_id(struct rte_eth_dev *dev,
47 : : const uint64_t *ids, uint64_t *values, unsigned int n);
48 : : static int ionic_dev_xstats_reset(struct rte_eth_dev *dev);
49 : : static int ionic_dev_xstats_get_names(struct rte_eth_dev *dev,
50 : : struct rte_eth_xstat_name *xstats_names, unsigned int size);
51 : : static int ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
52 : : const uint64_t *ids, struct rte_eth_xstat_name *xstats_names,
53 : : unsigned int limit);
54 : : static int ionic_dev_fw_version_get(struct rte_eth_dev *eth_dev,
55 : : char *fw_version, size_t fw_size);
56 : :
57 : : static const struct rte_eth_desc_lim rx_desc_lim = {
58 : : .nb_max = IONIC_MAX_RING_DESC,
59 : : .nb_min = IONIC_MIN_RING_DESC,
60 : : .nb_align = 1,
61 : : };
62 : :
63 : : static const struct rte_eth_desc_lim tx_desc_lim_v1 = {
64 : : .nb_max = IONIC_MAX_RING_DESC,
65 : : .nb_min = IONIC_MIN_RING_DESC,
66 : : .nb_align = 1,
67 : : .nb_seg_max = IONIC_TX_MAX_SG_ELEMS_V1 + 1,
68 : : .nb_mtu_seg_max = IONIC_TX_MAX_SG_ELEMS_V1 + 1,
69 : : };
70 : :
71 : : static const struct eth_dev_ops ionic_eth_dev_ops = {
72 : : .dev_infos_get = ionic_dev_info_get,
73 : : .dev_supported_ptypes_get = ionic_dev_supported_ptypes_get,
74 : : .dev_configure = ionic_dev_configure,
75 : : .mtu_set = ionic_dev_mtu_set,
76 : : .dev_start = ionic_dev_start,
77 : : .dev_stop = ionic_dev_stop,
78 : : .dev_close = ionic_dev_close,
79 : : .link_update = ionic_dev_link_update,
80 : : .dev_set_link_up = ionic_dev_set_link_up,
81 : : .dev_set_link_down = ionic_dev_set_link_down,
82 : : .mac_addr_add = ionic_dev_add_mac,
83 : : .mac_addr_remove = ionic_dev_remove_mac,
84 : : .mac_addr_set = ionic_dev_set_mac,
85 : : .vlan_filter_set = ionic_dev_vlan_filter_set,
86 : : .promiscuous_enable = ionic_dev_promiscuous_enable,
87 : : .promiscuous_disable = ionic_dev_promiscuous_disable,
88 : : .allmulticast_enable = ionic_dev_allmulticast_enable,
89 : : .allmulticast_disable = ionic_dev_allmulticast_disable,
90 : : .flow_ctrl_get = ionic_flow_ctrl_get,
91 : : .flow_ctrl_set = ionic_flow_ctrl_set,
92 : : .rxq_info_get = ionic_rxq_info_get,
93 : : .txq_info_get = ionic_txq_info_get,
94 : : .rx_queue_setup = ionic_dev_rx_queue_setup,
95 : : .rx_queue_release = ionic_dev_rx_queue_release,
96 : : .rx_queue_start = ionic_dev_rx_queue_start,
97 : : .rx_queue_stop = ionic_dev_rx_queue_stop,
98 : : .tx_queue_setup = ionic_dev_tx_queue_setup,
99 : : .tx_queue_release = ionic_dev_tx_queue_release,
100 : : .tx_queue_start = ionic_dev_tx_queue_start,
101 : : .tx_queue_stop = ionic_dev_tx_queue_stop,
102 : : .vlan_offload_set = ionic_vlan_offload_set,
103 : : .reta_update = ionic_dev_rss_reta_update,
104 : : .reta_query = ionic_dev_rss_reta_query,
105 : : .rss_hash_conf_get = ionic_dev_rss_hash_conf_get,
106 : : .rss_hash_update = ionic_dev_rss_hash_update,
107 : : .stats_get = ionic_dev_stats_get,
108 : : .stats_reset = ionic_dev_stats_reset,
109 : : .xstats_get = ionic_dev_xstats_get,
110 : : .xstats_get_by_id = ionic_dev_xstats_get_by_id,
111 : : .xstats_reset = ionic_dev_xstats_reset,
112 : : .xstats_get_names = ionic_dev_xstats_get_names,
113 : : .xstats_get_names_by_id = ionic_dev_xstats_get_names_by_id,
114 : : .fw_version_get = ionic_dev_fw_version_get,
115 : : };
116 : :
117 : : struct rte_ionic_xstats_name_off {
118 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
119 : : unsigned int offset;
120 : : };
121 : :
122 : : static const struct rte_ionic_xstats_name_off rte_ionic_xstats_strings[] = {
123 : : /* RX */
124 : : {"rx_ucast_bytes", offsetof(struct ionic_lif_stats,
125 : : rx_ucast_bytes)},
126 : : {"rx_ucast_packets", offsetof(struct ionic_lif_stats,
127 : : rx_ucast_packets)},
128 : : {"rx_mcast_bytes", offsetof(struct ionic_lif_stats,
129 : : rx_mcast_bytes)},
130 : : {"rx_mcast_packets", offsetof(struct ionic_lif_stats,
131 : : rx_mcast_packets)},
132 : : {"rx_bcast_bytes", offsetof(struct ionic_lif_stats,
133 : : rx_bcast_bytes)},
134 : : {"rx_bcast_packets", offsetof(struct ionic_lif_stats,
135 : : rx_bcast_packets)},
136 : : /* RX drops */
137 : : {"rx_ucast_drop_bytes", offsetof(struct ionic_lif_stats,
138 : : rx_ucast_drop_bytes)},
139 : : {"rx_ucast_drop_packets", offsetof(struct ionic_lif_stats,
140 : : rx_ucast_drop_packets)},
141 : : {"rx_mcast_drop_bytes", offsetof(struct ionic_lif_stats,
142 : : rx_mcast_drop_bytes)},
143 : : {"rx_mcast_drop_packets", offsetof(struct ionic_lif_stats,
144 : : rx_mcast_drop_packets)},
145 : : {"rx_bcast_drop_bytes", offsetof(struct ionic_lif_stats,
146 : : rx_bcast_drop_bytes)},
147 : : {"rx_bcast_drop_packets", offsetof(struct ionic_lif_stats,
148 : : rx_bcast_drop_packets)},
149 : : {"rx_dma_error", offsetof(struct ionic_lif_stats,
150 : : rx_dma_error)},
151 : : /* TX */
152 : : {"tx_ucast_bytes", offsetof(struct ionic_lif_stats,
153 : : tx_ucast_bytes)},
154 : : {"tx_ucast_packets", offsetof(struct ionic_lif_stats,
155 : : tx_ucast_packets)},
156 : : {"tx_mcast_bytes", offsetof(struct ionic_lif_stats,
157 : : tx_mcast_bytes)},
158 : : {"tx_mcast_packets", offsetof(struct ionic_lif_stats,
159 : : tx_mcast_packets)},
160 : : {"tx_bcast_bytes", offsetof(struct ionic_lif_stats,
161 : : tx_bcast_bytes)},
162 : : {"tx_bcast_packets", offsetof(struct ionic_lif_stats,
163 : : tx_bcast_packets)},
164 : : /* TX drops */
165 : : {"tx_ucast_drop_bytes", offsetof(struct ionic_lif_stats,
166 : : tx_ucast_drop_bytes)},
167 : : {"tx_ucast_drop_packets", offsetof(struct ionic_lif_stats,
168 : : tx_ucast_drop_packets)},
169 : : {"tx_mcast_drop_bytes", offsetof(struct ionic_lif_stats,
170 : : tx_mcast_drop_bytes)},
171 : : {"tx_mcast_drop_packets", offsetof(struct ionic_lif_stats,
172 : : tx_mcast_drop_packets)},
173 : : {"tx_bcast_drop_bytes", offsetof(struct ionic_lif_stats,
174 : : tx_bcast_drop_bytes)},
175 : : {"tx_bcast_drop_packets", offsetof(struct ionic_lif_stats,
176 : : tx_bcast_drop_packets)},
177 : : {"tx_dma_error", offsetof(struct ionic_lif_stats,
178 : : tx_dma_error)},
179 : : /* Rx Queue/Ring drops */
180 : : {"rx_queue_disabled", offsetof(struct ionic_lif_stats,
181 : : rx_queue_disabled)},
182 : : {"rx_queue_empty", offsetof(struct ionic_lif_stats,
183 : : rx_queue_empty)},
184 : : {"rx_queue_error", offsetof(struct ionic_lif_stats,
185 : : rx_queue_error)},
186 : : {"rx_desc_fetch_error", offsetof(struct ionic_lif_stats,
187 : : rx_desc_fetch_error)},
188 : : {"rx_desc_data_error", offsetof(struct ionic_lif_stats,
189 : : rx_desc_data_error)},
190 : : /* Tx Queue/Ring drops */
191 : : {"tx_queue_disabled", offsetof(struct ionic_lif_stats,
192 : : tx_queue_disabled)},
193 : : {"tx_queue_error", offsetof(struct ionic_lif_stats,
194 : : tx_queue_error)},
195 : : {"tx_desc_fetch_error", offsetof(struct ionic_lif_stats,
196 : : tx_desc_fetch_error)},
197 : : {"tx_desc_data_error", offsetof(struct ionic_lif_stats,
198 : : tx_desc_data_error)},
199 : : /* Flexible firmware events */
200 : : {"fw_flex_event1", offsetof(struct ionic_lif_stats, flex1)},
201 : : {"fw_flex_event2", offsetof(struct ionic_lif_stats, flex2)},
202 : : {"fw_flex_event3", offsetof(struct ionic_lif_stats, flex3)},
203 : : {"fw_flex_event4", offsetof(struct ionic_lif_stats, flex4)},
204 : : {"fw_flex_event5", offsetof(struct ionic_lif_stats, flex5)},
205 : : {"fw_flex_event6", offsetof(struct ionic_lif_stats, flex6)},
206 : : {"fw_flex_event7", offsetof(struct ionic_lif_stats, flex7)},
207 : : {"fw_flex_event8", offsetof(struct ionic_lif_stats, flex8)},
208 : : {"fw_flex_event9", offsetof(struct ionic_lif_stats, flex9)},
209 : : {"fw_flex_event10", offsetof(struct ionic_lif_stats, flex10)},
210 : : {"fw_flex_event11", offsetof(struct ionic_lif_stats, flex11)},
211 : : {"fw_flex_event12", offsetof(struct ionic_lif_stats, flex12)},
212 : : {"fw_flex_event13", offsetof(struct ionic_lif_stats, flex13)},
213 : : {"fw_flex_event14", offsetof(struct ionic_lif_stats, flex14)},
214 : : {"fw_flex_event15", offsetof(struct ionic_lif_stats, flex15)},
215 : : {"fw_flex_event16", offsetof(struct ionic_lif_stats, flex16)},
216 : : {"fw_flex_event17", offsetof(struct ionic_lif_stats, flex17)},
217 : : {"fw_flex_event18", offsetof(struct ionic_lif_stats, flex18)},
218 : : {"fw_flex_event19", offsetof(struct ionic_lif_stats, flex19)},
219 : : {"fw_flex_event20", offsetof(struct ionic_lif_stats, flex20)},
220 : : {"fw_flex_event21", offsetof(struct ionic_lif_stats, flex21)},
221 : : {"fw_flex_event22", offsetof(struct ionic_lif_stats, flex22)},
222 : : {"fw_flex_event23", offsetof(struct ionic_lif_stats, flex23)},
223 : : {"fw_flex_event24", offsetof(struct ionic_lif_stats, flex24)},
224 : : {"fw_flex_event25", offsetof(struct ionic_lif_stats, flex25)},
225 : : {"fw_flex_event26", offsetof(struct ionic_lif_stats, flex26)},
226 : : {"fw_flex_event27", offsetof(struct ionic_lif_stats, flex27)},
227 : : {"fw_flex_event28", offsetof(struct ionic_lif_stats, flex28)},
228 : : {"fw_flex_event29", offsetof(struct ionic_lif_stats, flex29)},
229 : : {"fw_flex_event30", offsetof(struct ionic_lif_stats, flex30)},
230 : : {"fw_flex_event31", offsetof(struct ionic_lif_stats, flex31)},
231 : : {"fw_flex_event32", offsetof(struct ionic_lif_stats, flex32)},
232 : : };
233 : :
234 : : #define IONIC_NB_HW_STATS RTE_DIM(rte_ionic_xstats_strings)
235 : :
236 : : static int
237 : 0 : ionic_dev_fw_version_get(struct rte_eth_dev *eth_dev,
238 : : char *fw_version, size_t fw_size)
239 : : {
240 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
241 : 0 : struct ionic_adapter *adapter = lif->adapter;
242 : : int ret;
243 : :
244 : : ret = snprintf(fw_version, fw_size, "%s",
245 [ # # ]: 0 : adapter->fw_version);
246 [ # # ]: 0 : if (ret < 0)
247 : : return -EINVAL;
248 : :
249 : 0 : ret += 1; /* add the size of '\0' */
250 [ # # ]: 0 : if (fw_size < (size_t)ret)
251 : : return ret;
252 : : else
253 : 0 : return 0;
254 : : }
255 : :
256 : : /*
257 : : * Set device link up, enable tx.
258 : : */
259 : : static int
260 : 0 : ionic_dev_set_link_up(struct rte_eth_dev *eth_dev)
261 : : {
262 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
263 : : int err;
264 : :
265 : 0 : IONIC_PRINT_CALL();
266 : :
267 : 0 : err = ionic_lif_start(lif);
268 [ # # ]: 0 : if (err)
269 : 0 : IONIC_PRINT(ERR, "Could not start lif to set link up");
270 : :
271 : 0 : ionic_dev_link_update(lif->eth_dev, 0);
272 : :
273 : 0 : return err;
274 : : }
275 : :
276 : : /*
277 : : * Set device link down, disable tx.
278 : : */
279 : : static int
280 : 0 : ionic_dev_set_link_down(struct rte_eth_dev *eth_dev)
281 : : {
282 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
283 : :
284 : 0 : IONIC_PRINT_CALL();
285 : :
286 : 0 : ionic_lif_stop(lif);
287 : :
288 : 0 : ionic_dev_link_update(lif->eth_dev, 0);
289 : :
290 : 0 : return 0;
291 : : }
292 : :
293 : : int
294 : 0 : ionic_dev_link_update(struct rte_eth_dev *eth_dev,
295 : : int wait_to_complete __rte_unused)
296 : : {
297 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
298 : 0 : struct ionic_adapter *adapter = lif->adapter;
299 : : struct rte_eth_link link;
300 : :
301 : 0 : IONIC_PRINT_CALL();
302 : :
303 : : /*
304 : : * There is no way to hook up the device interrupts in the vdev
305 : : * framework. Instead, poll for updates on the adapter.
306 : : */
307 [ # # # # ]: 0 : if (adapter->intf && adapter->intf->poll)
308 : 0 : (*adapter->intf->poll)(adapter);
309 : :
310 : : /* Initialize */
311 : : memset(&link, 0, sizeof(link));
312 : :
313 [ # # ]: 0 : if (adapter->idev.port_info->config.an_enable) {
314 : 0 : link.link_autoneg = RTE_ETH_LINK_AUTONEG;
315 : : }
316 : :
317 [ # # ]: 0 : if (!adapter->link_up ||
318 [ # # ]: 0 : !(lif->state & IONIC_LIF_F_UP)) {
319 : : /* Interface is down */
320 : : link.link_status = RTE_ETH_LINK_DOWN;
321 : : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
322 : : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
323 : : } else {
324 : : /* Interface is up */
325 : 0 : link.link_status = RTE_ETH_LINK_UP;
326 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
327 [ # # # # : 0 : switch (adapter->link_speed) {
# # # # ]
328 : 0 : case 1000:
329 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_1G;
330 : 0 : break;
331 : 0 : case 10000:
332 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_10G;
333 : 0 : break;
334 : 0 : case 25000:
335 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_25G;
336 : 0 : break;
337 : 0 : case 40000:
338 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_40G;
339 : 0 : break;
340 : 0 : case 50000:
341 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_50G;
342 : 0 : break;
343 : 0 : case 100000:
344 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100G;
345 : 0 : break;
346 : 0 : case 200000:
347 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_200G;
348 : 0 : break;
349 : : default:
350 : : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
351 : : break;
352 : : }
353 : : }
354 : :
355 : 0 : return rte_eth_linkstatus_set(eth_dev, &link);
356 : : }
357 : :
358 : : /**
359 : : * Interrupt handler triggered by NIC for handling
360 : : * specific interrupt.
361 : : *
362 : : * @param param
363 : : * The address of parameter registered before.
364 : : *
365 : : * @return
366 : : * void
367 : : */
368 : : void
369 : 0 : ionic_dev_interrupt_handler(void *param)
370 : : {
371 : : struct ionic_adapter *adapter = (struct ionic_adapter *)param;
372 : :
373 : 0 : IONIC_PRINT(DEBUG, "->");
374 : :
375 [ # # ]: 0 : if (adapter->lif)
376 : 0 : ionic_notifyq_handler(adapter->lif, -1);
377 : 0 : }
378 : :
379 : : static int
380 : 0 : ionic_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
381 : : {
382 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
383 : :
384 [ # # ]: 0 : if (lif->state & IONIC_LIF_F_UP) {
385 : 0 : IONIC_PRINT(ERR, "Stop %s before setting mtu", lif->name);
386 : 0 : return -EBUSY;
387 : : }
388 : :
389 : : /* Note: mtu check against min/max is done by the API */
390 : 0 : IONIC_PRINT(INFO, "Setting mtu %u", mtu);
391 : :
392 : : /* Update the frame size used by the Rx path */
393 : 0 : lif->frame_size = mtu + IONIC_ETH_OVERHEAD;
394 : :
395 : 0 : return 0;
396 : : }
397 : :
398 : : static int
399 : 0 : ionic_dev_info_get(struct rte_eth_dev *eth_dev,
400 : : struct rte_eth_dev_info *dev_info)
401 : : {
402 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
403 : 0 : struct ionic_adapter *adapter = lif->adapter;
404 : : struct ionic_identity *ident = &adapter->ident;
405 : : union ionic_lif_config *cfg = &ident->lif.eth.config;
406 : :
407 : 0 : IONIC_PRINT_CALL();
408 : :
409 : 0 : dev_info->max_rx_queues = (uint16_t)
410 : 0 : rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_RXQ]);
411 : 0 : dev_info->max_tx_queues = (uint16_t)
412 : 0 : rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_TXQ]);
413 : :
414 : : /* Also add ETHER_CRC_LEN if the adapter is able to keep CRC */
415 : 0 : dev_info->min_mtu = RTE_MAX((uint32_t)IONIC_MIN_MTU,
416 : : rte_le_to_cpu_32(ident->lif.eth.min_mtu));
417 : 0 : dev_info->max_mtu = RTE_MIN((uint32_t)IONIC_MAX_MTU,
418 : : rte_le_to_cpu_32(ident->lif.eth.max_mtu));
419 : 0 : dev_info->min_rx_bufsize = dev_info->min_mtu + IONIC_ETH_OVERHEAD;
420 : 0 : dev_info->max_rx_pktlen = dev_info->max_mtu + IONIC_ETH_OVERHEAD;
421 : 0 : dev_info->max_lro_pkt_size =
422 : 0 : eth_dev->data->dev_conf.rxmode.max_lro_pkt_size;
423 : :
424 : 0 : dev_info->max_mac_addrs = adapter->max_mac_addrs;
425 : 0 : dev_info->hash_key_size = IONIC_RSS_HASH_KEY_SIZE;
426 : 0 : dev_info->reta_size = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz);
427 : 0 : dev_info->flow_type_rss_offloads = IONIC_ETH_RSS_OFFLOAD_ALL;
428 : :
429 : 0 : dev_info->speed_capa =
430 : : RTE_ETH_LINK_SPEED_10G |
431 : : RTE_ETH_LINK_SPEED_25G |
432 : : RTE_ETH_LINK_SPEED_40G |
433 : : RTE_ETH_LINK_SPEED_50G |
434 : : RTE_ETH_LINK_SPEED_100G;
435 : :
436 : : /*
437 : : * Per-queue capabilities
438 : : * RTE does not support disabling a feature on a queue if it is
439 : : * enabled globally on the device. Thus the driver does not advertise
440 : : * capabilities like RTE_ETH_TX_OFFLOAD_IPV4_CKSUM as per-queue even
441 : : * though the driver would be otherwise capable of disabling it on
442 : : * a per-queue basis.
443 : : */
444 : :
445 : 0 : dev_info->rx_queue_offload_capa = 0;
446 : 0 : dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
447 : :
448 : : /*
449 : : * Per-port capabilities
450 : : * See ionic_set_features to request and check supported features
451 : : */
452 : :
453 : 0 : dev_info->rx_offload_capa = dev_info->rx_queue_offload_capa |
454 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
455 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
456 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
457 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
458 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
459 : : RTE_ETH_RX_OFFLOAD_SCATTER |
460 : : RTE_ETH_RX_OFFLOAD_RSS_HASH |
461 : : 0;
462 : :
463 : 0 : dev_info->tx_offload_capa = dev_info->tx_queue_offload_capa |
464 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
465 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
466 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
467 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
468 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM |
469 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
470 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
471 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
472 : : 0;
473 : :
474 : 0 : dev_info->rx_desc_lim = rx_desc_lim;
475 : 0 : dev_info->tx_desc_lim = tx_desc_lim_v1;
476 : :
477 : : /* Driver-preferred Rx/Tx parameters */
478 : 0 : dev_info->default_rxportconf.burst_size = IONIC_DEF_TXRX_BURST;
479 : 0 : dev_info->default_txportconf.burst_size = IONIC_DEF_TXRX_BURST;
480 : 0 : dev_info->default_rxportconf.nb_queues = 1;
481 : 0 : dev_info->default_txportconf.nb_queues = 1;
482 : 0 : dev_info->default_rxportconf.ring_size = IONIC_DEF_TXRX_DESC;
483 : 0 : dev_info->default_txportconf.ring_size = IONIC_DEF_TXRX_DESC;
484 : :
485 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
486 : : /* Packets are always dropped if no desc are available */
487 : : .rx_drop_en = 1,
488 : : };
489 : :
490 : 0 : return 0;
491 : : }
492 : :
493 : : static int
494 : 0 : ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev,
495 : : struct rte_eth_fc_conf *fc_conf)
496 : : {
497 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
498 : 0 : struct ionic_adapter *adapter = lif->adapter;
499 : : struct ionic_dev *idev = &adapter->idev;
500 : :
501 [ # # ]: 0 : if (idev->port_info) {
502 : : /* Flow control autoneg not supported */
503 : 0 : fc_conf->autoneg = 0;
504 : :
505 [ # # ]: 0 : if (idev->port_info->config.pause_type)
506 : 0 : fc_conf->mode = RTE_ETH_FC_FULL;
507 : : else
508 : 0 : fc_conf->mode = RTE_ETH_FC_NONE;
509 : : }
510 : :
511 : 0 : return 0;
512 : : }
513 : :
514 : : static int
515 : 0 : ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev,
516 : : struct rte_eth_fc_conf *fc_conf)
517 : : {
518 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
519 : 0 : struct ionic_adapter *adapter = lif->adapter;
520 : 0 : struct ionic_dev *idev = &adapter->idev;
521 : : uint8_t pause_type = IONIC_PORT_PAUSE_TYPE_NONE;
522 : : int err;
523 : :
524 [ # # ]: 0 : if (fc_conf->autoneg) {
525 : 0 : IONIC_PRINT(WARNING, "Flow control autoneg not supported");
526 : 0 : return -ENOTSUP;
527 : : }
528 : :
529 [ # # # ]: 0 : switch (fc_conf->mode) {
530 : : case RTE_ETH_FC_NONE:
531 : : pause_type = IONIC_PORT_PAUSE_TYPE_NONE;
532 : : break;
533 : 0 : case RTE_ETH_FC_FULL:
534 : : pause_type = IONIC_PORT_PAUSE_TYPE_LINK;
535 : 0 : break;
536 : : case RTE_ETH_FC_RX_PAUSE:
537 : : case RTE_ETH_FC_TX_PAUSE:
538 : : return -ENOTSUP;
539 : : }
540 : :
541 : 0 : ionic_dev_cmd_port_pause(idev, pause_type);
542 : 0 : err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
543 [ # # ]: 0 : if (err)
544 : 0 : IONIC_PRINT(WARNING, "Failed to configure flow control");
545 : :
546 : : return err;
547 : : }
548 : :
549 : : static int
550 : 0 : ionic_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
551 : : {
552 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
553 : :
554 : 0 : ionic_lif_configure_vlan_offload(lif, mask);
555 : :
556 : 0 : ionic_lif_set_features(lif);
557 : :
558 : 0 : return 0;
559 : : }
560 : :
561 : : static int
562 : 0 : ionic_dev_rss_reta_update(struct rte_eth_dev *eth_dev,
563 : : struct rte_eth_rss_reta_entry64 *reta_conf,
564 : : uint16_t reta_size)
565 : : {
566 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
567 : 0 : struct ionic_adapter *adapter = lif->adapter;
568 : : struct ionic_identity *ident = &adapter->ident;
569 : : uint32_t i, j, index, num;
570 : 0 : uint16_t tbl_sz = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz);
571 : :
572 : 0 : IONIC_PRINT_CALL();
573 : :
574 [ # # ]: 0 : if (!lif->rss_ind_tbl) {
575 : 0 : IONIC_PRINT(ERR, "RSS RETA not initialized, "
576 : : "can't update the table");
577 : 0 : return -EINVAL;
578 : : }
579 : :
580 [ # # ]: 0 : if (reta_size != tbl_sz) {
581 : 0 : IONIC_PRINT(ERR, "The size of hash lookup table configured "
582 : : "(%d) does not match the number hardware can support "
583 : : "(%d)",
584 : : reta_size, tbl_sz);
585 : 0 : return -EINVAL;
586 : : }
587 : :
588 : 0 : num = tbl_sz / RTE_ETH_RETA_GROUP_SIZE;
589 : :
590 [ # # ]: 0 : for (i = 0; i < num; i++) {
591 [ # # ]: 0 : for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) {
592 [ # # ]: 0 : if (reta_conf[i].mask & ((uint64_t)1 << j)) {
593 : 0 : index = (i * RTE_ETH_RETA_GROUP_SIZE) + j;
594 : 0 : lif->rss_ind_tbl[index] = reta_conf[i].reta[j];
595 : : }
596 : : }
597 : : }
598 : :
599 : 0 : return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL);
600 : : }
601 : :
602 : : static int
603 : 0 : ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev,
604 : : struct rte_eth_rss_reta_entry64 *reta_conf,
605 : : uint16_t reta_size)
606 : : {
607 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
608 : 0 : struct ionic_adapter *adapter = lif->adapter;
609 : : struct ionic_identity *ident = &adapter->ident;
610 : : int i, j, num;
611 : 0 : uint16_t tbl_sz = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz);
612 : :
613 : 0 : IONIC_PRINT_CALL();
614 : :
615 [ # # ]: 0 : if (reta_size != tbl_sz) {
616 : 0 : IONIC_PRINT(ERR, "The size of hash lookup table configured "
617 : : "(%d) does not match the number hardware can support "
618 : : "(%d)",
619 : : reta_size, tbl_sz);
620 : 0 : return -EINVAL;
621 : : }
622 : :
623 [ # # ]: 0 : if (!lif->rss_ind_tbl) {
624 : 0 : IONIC_PRINT(ERR, "RSS RETA has not been built yet");
625 : 0 : return -EINVAL;
626 : : }
627 : :
628 : 0 : num = reta_size / RTE_ETH_RETA_GROUP_SIZE;
629 : :
630 [ # # ]: 0 : for (i = 0; i < num; i++) {
631 [ # # ]: 0 : for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) {
632 : 0 : reta_conf->reta[j] =
633 : 0 : lif->rss_ind_tbl[(i * RTE_ETH_RETA_GROUP_SIZE) + j];
634 : : }
635 : 0 : reta_conf++;
636 : : }
637 : :
638 : : return 0;
639 : : }
640 : :
641 : : static int
642 : 0 : ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
643 : : struct rte_eth_rss_conf *rss_conf)
644 : : {
645 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
646 : : uint64_t rss_hf = 0;
647 : :
648 : 0 : IONIC_PRINT_CALL();
649 : :
650 [ # # ]: 0 : if (!lif->rss_ind_tbl) {
651 : 0 : IONIC_PRINT(NOTICE, "RSS not enabled");
652 : 0 : return 0;
653 : : }
654 : :
655 : : /* Get key value (if not null, rss_key is 40-byte) */
656 [ # # ]: 0 : if (rss_conf->rss_key != NULL &&
657 [ # # ]: 0 : rss_conf->rss_key_len >= IONIC_RSS_HASH_KEY_SIZE)
658 : 0 : memcpy(rss_conf->rss_key, lif->rss_hash_key,
659 : : IONIC_RSS_HASH_KEY_SIZE);
660 : :
661 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV4)
662 : : rss_hf |= RTE_ETH_RSS_IPV4;
663 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV4_TCP)
664 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
665 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV4_UDP)
666 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
667 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV6)
668 : 0 : rss_hf |= RTE_ETH_RSS_IPV6;
669 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV6_TCP)
670 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
671 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV6_UDP)
672 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
673 : :
674 : 0 : rss_conf->rss_hf = rss_hf;
675 : :
676 : 0 : return 0;
677 : : }
678 : :
679 : : static int
680 : 0 : ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev,
681 : : struct rte_eth_rss_conf *rss_conf)
682 : : {
683 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
684 : : uint32_t rss_types = 0;
685 : : uint8_t *key = NULL;
686 : :
687 : 0 : IONIC_PRINT_CALL();
688 : :
689 [ # # ]: 0 : if (rss_conf->rss_key)
690 : : key = rss_conf->rss_key;
691 : :
692 [ # # ]: 0 : if ((rss_conf->rss_hf & IONIC_ETH_RSS_OFFLOAD_ALL) == 0) {
693 : : /*
694 : : * Can't disable rss through hash flags,
695 : : * if it is enabled by default during init
696 : : */
697 [ # # ]: 0 : if (lif->rss_ind_tbl)
698 : 0 : return -EINVAL;
699 : : } else {
700 : : /* Can't enable rss if disabled by default during init */
701 [ # # ]: 0 : if (!lif->rss_ind_tbl)
702 : : return -EINVAL;
703 : :
704 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_IPV4)
705 : : rss_types |= IONIC_RSS_TYPE_IPV4;
706 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP)
707 : 0 : rss_types |= IONIC_RSS_TYPE_IPV4_TCP;
708 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP)
709 : 0 : rss_types |= IONIC_RSS_TYPE_IPV4_UDP;
710 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_IPV6)
711 : 0 : rss_types |= IONIC_RSS_TYPE_IPV6;
712 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP)
713 : 0 : rss_types |= IONIC_RSS_TYPE_IPV6_TCP;
714 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP)
715 : 0 : rss_types |= IONIC_RSS_TYPE_IPV6_UDP;
716 : :
717 : 0 : ionic_lif_rss_config(lif, rss_types, key, NULL);
718 : : }
719 : :
720 : : return 0;
721 : : }
722 : :
723 : : static int
724 : 0 : ionic_dev_stats_get(struct rte_eth_dev *eth_dev,
725 : : struct rte_eth_stats *stats)
726 : : {
727 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
728 : :
729 : 0 : ionic_lif_get_stats(lif, stats);
730 : :
731 : 0 : return 0;
732 : : }
733 : :
734 : : static int
735 : 0 : ionic_dev_stats_reset(struct rte_eth_dev *eth_dev)
736 : : {
737 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
738 : :
739 : 0 : IONIC_PRINT_CALL();
740 : :
741 : 0 : ionic_lif_reset_stats(lif);
742 : :
743 : 0 : return 0;
744 : : }
745 : :
746 : : static int
747 : 0 : ionic_dev_xstats_get_names(__rte_unused struct rte_eth_dev *eth_dev,
748 : : struct rte_eth_xstat_name *xstats_names,
749 : : __rte_unused unsigned int size)
750 : : {
751 : : unsigned int i;
752 : :
753 [ # # ]: 0 : if (xstats_names != NULL) {
754 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
755 : 0 : snprintf(xstats_names[i].name,
756 : : sizeof(xstats_names[i].name),
757 : 0 : "%s", rte_ionic_xstats_strings[i].name);
758 : : }
759 : : }
760 : :
761 : 0 : return IONIC_NB_HW_STATS;
762 : : }
763 : :
764 : : static int
765 : 0 : ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *eth_dev,
766 : : const uint64_t *ids, struct rte_eth_xstat_name *xstats_names,
767 : : unsigned int limit)
768 : : {
769 : : struct rte_eth_xstat_name xstats_names_copy[IONIC_NB_HW_STATS];
770 : : uint16_t i;
771 : :
772 [ # # ]: 0 : if (!ids) {
773 [ # # ]: 0 : if (xstats_names != NULL) {
774 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
775 : 0 : snprintf(xstats_names[i].name,
776 : : sizeof(xstats_names[i].name),
777 : 0 : "%s", rte_ionic_xstats_strings[i].name);
778 : : }
779 : : }
780 : :
781 : 0 : return IONIC_NB_HW_STATS;
782 : : }
783 : :
784 : 0 : ionic_dev_xstats_get_names_by_id(eth_dev, NULL, xstats_names_copy,
785 : : IONIC_NB_HW_STATS);
786 : :
787 [ # # ]: 0 : for (i = 0; i < limit; i++) {
788 [ # # ]: 0 : if (ids[i] >= IONIC_NB_HW_STATS) {
789 : 0 : IONIC_PRINT(ERR, "id value isn't valid");
790 : 0 : return -1;
791 : : }
792 : :
793 : 0 : strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
794 : : }
795 : :
796 : 0 : return limit;
797 : : }
798 : :
799 : : static int
800 : 0 : ionic_dev_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats,
801 : : unsigned int n)
802 : : {
803 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
804 : : struct ionic_lif_stats hw_stats;
805 : : uint16_t i;
806 : :
807 [ # # ]: 0 : if (n < IONIC_NB_HW_STATS)
808 : : return IONIC_NB_HW_STATS;
809 : :
810 : 0 : ionic_lif_get_hw_stats(lif, &hw_stats);
811 : :
812 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
813 : 0 : xstats[i].value = *(uint64_t *)(((char *)&hw_stats) +
814 : 0 : rte_ionic_xstats_strings[i].offset);
815 : 0 : xstats[i].id = i;
816 : : }
817 : :
818 : : return IONIC_NB_HW_STATS;
819 : : }
820 : :
821 : : static int
822 : 0 : ionic_dev_xstats_get_by_id(struct rte_eth_dev *eth_dev, const uint64_t *ids,
823 : : uint64_t *values, unsigned int n)
824 : : {
825 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
826 : : struct ionic_lif_stats hw_stats;
827 : : uint64_t values_copy[IONIC_NB_HW_STATS];
828 : : uint16_t i;
829 : :
830 [ # # ]: 0 : if (!ids) {
831 [ # # ]: 0 : if (!ids && n < IONIC_NB_HW_STATS)
832 : : return IONIC_NB_HW_STATS;
833 : :
834 : 0 : ionic_lif_get_hw_stats(lif, &hw_stats);
835 : :
836 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
837 : 0 : values[i] = *(uint64_t *)(((char *)&hw_stats) +
838 : 0 : rte_ionic_xstats_strings[i].offset);
839 : : }
840 : :
841 : : return IONIC_NB_HW_STATS;
842 : : }
843 : :
844 : 0 : ionic_dev_xstats_get_by_id(eth_dev, NULL, values_copy,
845 : : IONIC_NB_HW_STATS);
846 : :
847 [ # # ]: 0 : for (i = 0; i < n; i++) {
848 [ # # ]: 0 : if (ids[i] >= IONIC_NB_HW_STATS) {
849 : 0 : IONIC_PRINT(ERR, "id value isn't valid");
850 : 0 : return -1;
851 : : }
852 : :
853 : 0 : values[i] = values_copy[ids[i]];
854 : : }
855 : :
856 : 0 : return n;
857 : : }
858 : :
859 : : static int
860 : 0 : ionic_dev_xstats_reset(struct rte_eth_dev *eth_dev)
861 : : {
862 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
863 : :
864 : 0 : ionic_lif_reset_hw_stats(lif);
865 : :
866 : 0 : return 0;
867 : : }
868 : :
869 : : static int
870 : 0 : ionic_dev_configure(struct rte_eth_dev *eth_dev)
871 : : {
872 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
873 : :
874 : 0 : IONIC_PRINT_CALL();
875 : :
876 : 0 : ionic_lif_configure(lif);
877 : :
878 : 0 : return 0;
879 : : }
880 : :
881 : : static inline uint32_t
882 : : ionic_parse_link_speeds(uint16_t link_speeds)
883 : : {
884 : 0 : if (link_speeds & RTE_ETH_LINK_SPEED_100G)
885 : : return 100000;
886 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_50G)
887 : : return 50000;
888 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_40G)
889 : : return 40000;
890 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_25G)
891 : : return 25000;
892 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_10G)
893 : : return 10000;
894 : : else
895 : : return 0;
896 : : }
897 : :
898 : : /*
899 : : * Configure device link speed and setup link.
900 : : * It returns 0 on success.
901 : : */
902 : : static int
903 : 0 : ionic_dev_start(struct rte_eth_dev *eth_dev)
904 : : {
905 : 0 : struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf;
906 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
907 : 0 : struct ionic_adapter *adapter = lif->adapter;
908 : 0 : struct ionic_dev *idev = &adapter->idev;
909 : : uint32_t speed = 0, allowed_speeds;
910 : : uint8_t an_enable;
911 : : int err;
912 : :
913 : 0 : IONIC_PRINT_CALL();
914 : :
915 : : allowed_speeds =
916 : : RTE_ETH_LINK_SPEED_FIXED |
917 : : RTE_ETH_LINK_SPEED_10G |
918 : : RTE_ETH_LINK_SPEED_25G |
919 : : RTE_ETH_LINK_SPEED_40G |
920 : : RTE_ETH_LINK_SPEED_50G |
921 : : RTE_ETH_LINK_SPEED_100G;
922 : :
923 [ # # ]: 0 : if (dev_conf->link_speeds & ~allowed_speeds) {
924 : 0 : IONIC_PRINT(ERR, "Invalid link setting");
925 : 0 : return -EINVAL;
926 : : }
927 : :
928 [ # # ]: 0 : if (dev_conf->lpbk_mode)
929 : 0 : IONIC_PRINT(WARNING, "Loopback mode not supported");
930 : :
931 : : /* Re-set features in case SG flag was added in rx_queue_setup() */
932 : 0 : err = ionic_lif_set_features(lif);
933 [ # # ]: 0 : if (err) {
934 : 0 : IONIC_PRINT(ERR, "Cannot set LIF features: %d", err);
935 : 0 : return err;
936 : : }
937 : :
938 : 0 : lif->frame_size = eth_dev->data->mtu + IONIC_ETH_OVERHEAD;
939 : :
940 : 0 : err = ionic_lif_change_mtu(lif, eth_dev->data->mtu);
941 [ # # ]: 0 : if (err) {
942 : 0 : IONIC_PRINT(ERR, "Cannot set LIF frame size %u: %d",
943 : : lif->frame_size, err);
944 : 0 : return err;
945 : : }
946 : :
947 : 0 : err = ionic_lif_start(lif);
948 [ # # ]: 0 : if (err) {
949 : 0 : IONIC_PRINT(ERR, "Cannot start LIF: %d", err);
950 : 0 : return err;
951 : : }
952 : :
953 : : /* Configure link */
954 : 0 : an_enable = (dev_conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) == 0;
955 : :
956 : 0 : ionic_dev_cmd_port_autoneg(idev, an_enable);
957 : 0 : err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
958 [ # # ]: 0 : if (err)
959 [ # # ]: 0 : IONIC_PRINT(WARNING, "Failed to %s autonegotiation",
960 : : an_enable ? "enable" : "disable");
961 : :
962 [ # # ]: 0 : if (!an_enable)
963 [ # # ]: 0 : speed = ionic_parse_link_speeds(dev_conf->link_speeds);
964 : : if (speed) {
965 : 0 : ionic_dev_cmd_port_speed(idev, speed);
966 : 0 : err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
967 [ # # ]: 0 : if (err)
968 : 0 : IONIC_PRINT(WARNING, "Failed to set link speed %u",
969 : : speed);
970 : : }
971 : :
972 [ # # ]: 0 : if (lif->hw_features & IONIC_ETH_HW_RX_SG)
973 : 0 : eth_dev->rx_pkt_burst = &ionic_recv_pkts_sg;
974 : : else
975 : 0 : eth_dev->rx_pkt_burst = &ionic_recv_pkts;
976 : :
977 [ # # ]: 0 : if (lif->hw_features & IONIC_ETH_HW_TX_SG)
978 : 0 : eth_dev->tx_pkt_burst = &ionic_xmit_pkts_sg;
979 : : else
980 : 0 : eth_dev->tx_pkt_burst = &ionic_xmit_pkts;
981 : :
982 : 0 : eth_dev->tx_pkt_prepare = &ionic_prep_pkts;
983 : :
984 : 0 : ionic_dev_link_update(eth_dev, 0);
985 : :
986 : 0 : return 0;
987 : : }
988 : :
989 : : /*
990 : : * Stop device: disable rx and tx functions to allow for reconfiguring.
991 : : */
992 : : static int
993 : 0 : ionic_dev_stop(struct rte_eth_dev *eth_dev)
994 : : {
995 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
996 : :
997 : 0 : IONIC_PRINT_CALL();
998 : :
999 : 0 : ionic_lif_stop(lif);
1000 : :
1001 : 0 : return 0;
1002 : : }
1003 : :
1004 : : /*
1005 : : * Reset and stop device.
1006 : : */
1007 : : static int
1008 : 0 : ionic_dev_close(struct rte_eth_dev *eth_dev)
1009 : : {
1010 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
1011 : 0 : struct ionic_adapter *adapter = lif->adapter;
1012 : :
1013 : 0 : IONIC_PRINT_CALL();
1014 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1015 : : return 0;
1016 : :
1017 : 0 : IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name);
1018 [ # # ]: 0 : if (adapter->intf->unconfigure_intr)
1019 : 0 : (*adapter->intf->unconfigure_intr)(adapter);
1020 : :
1021 : 0 : ionic_reset(adapter);
1022 : :
1023 : 0 : ionic_lif_free_queues(lif);
1024 : 0 : ionic_lif_deinit(lif);
1025 : 0 : ionic_lif_free(lif); /* Does not free LIF object */
1026 : :
1027 [ # # ]: 0 : if (adapter->intf->unmap_bars)
1028 : 0 : (*adapter->intf->unmap_bars)(adapter);
1029 : :
1030 : 0 : lif->adapter = NULL;
1031 : 0 : rte_free(adapter);
1032 : :
1033 : 0 : return 0;
1034 : : }
1035 : :
1036 : : int
1037 : 0 : eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
1038 : : {
1039 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
1040 : : struct ionic_adapter *adapter = (struct ionic_adapter *)init_params;
1041 : : int err;
1042 : :
1043 : 0 : IONIC_PRINT_CALL();
1044 : :
1045 : 0 : eth_dev->dev_ops = &ionic_eth_dev_ops;
1046 : 0 : eth_dev->rx_descriptor_status = ionic_dev_rx_descriptor_status;
1047 : 0 : eth_dev->tx_descriptor_status = ionic_dev_tx_descriptor_status;
1048 : :
1049 : : /* Multi-process not supported, primary does initialization anyway */
1050 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1051 : : return 0;
1052 : :
1053 [ # # ]: 0 : if (adapter->intf->copy_bus_info)
1054 : 0 : (*adapter->intf->copy_bus_info)(adapter, eth_dev);
1055 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
1056 : :
1057 : 0 : lif->eth_dev = eth_dev;
1058 : 0 : lif->adapter = adapter;
1059 : 0 : adapter->lif = lif;
1060 : :
1061 : 0 : IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported",
1062 : : adapter->max_mac_addrs);
1063 : :
1064 : : /* Allocate memory for storing MAC addresses */
1065 : 0 : eth_dev->data->mac_addrs = rte_calloc("ionic",
1066 : 0 : adapter->max_mac_addrs,
1067 : : RTE_ETHER_ADDR_LEN,
1068 : : RTE_CACHE_LINE_SIZE);
1069 [ # # ]: 0 : if (eth_dev->data->mac_addrs == NULL) {
1070 : 0 : IONIC_PRINT(ERR, "Failed to allocate %u bytes needed to "
1071 : : "store MAC addresses",
1072 : : RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs);
1073 : : err = -ENOMEM;
1074 : 0 : goto err;
1075 : : }
1076 : :
1077 : 0 : err = ionic_lif_alloc(lif);
1078 [ # # ]: 0 : if (err) {
1079 : 0 : IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting",
1080 : : err);
1081 : 0 : goto err;
1082 : : }
1083 : :
1084 : 0 : err = ionic_lif_init(lif);
1085 [ # # ]: 0 : if (err) {
1086 : 0 : IONIC_PRINT(ERR, "Cannot init LIFs: %d, aborting", err);
1087 : 0 : goto err_free_lif;
1088 : : }
1089 : :
1090 : : /* Copy the MAC address */
1091 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr,
1092 : 0 : ð_dev->data->mac_addrs[0]);
1093 : :
1094 : 0 : IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id);
1095 : :
1096 : 0 : return 0;
1097 : :
1098 : : err_free_lif:
1099 : 0 : ionic_lif_free(lif);
1100 : : err:
1101 : : return err;
1102 : : }
1103 : :
1104 : : static int
1105 : 0 : eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev)
1106 : : {
1107 : 0 : IONIC_PRINT_CALL();
1108 : :
1109 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1110 : : return 0;
1111 : :
1112 [ # # ]: 0 : if (eth_dev->state != RTE_ETH_DEV_UNUSED)
1113 : 0 : ionic_dev_close(eth_dev);
1114 : :
1115 : 0 : eth_dev->dev_ops = NULL;
1116 : 0 : eth_dev->rx_pkt_burst = NULL;
1117 : 0 : eth_dev->tx_pkt_burst = NULL;
1118 : 0 : eth_dev->tx_pkt_prepare = NULL;
1119 : :
1120 : 0 : return 0;
1121 : : }
1122 : :
1123 : : int
1124 : 0 : eth_ionic_dev_probe(void *bus_dev, struct rte_device *rte_dev,
1125 : : struct ionic_bars *bars, const struct ionic_dev_intf *intf,
1126 : : uint16_t device_id, uint16_t vendor_id)
1127 : : {
1128 : : char name[RTE_ETH_NAME_MAX_LEN];
1129 : : struct ionic_adapter *adapter;
1130 : : struct ionic_hw *hw;
1131 : : unsigned long i;
1132 : : int err;
1133 : :
1134 : : /* Check structs (trigger error at compilation time) */
1135 : : ionic_struct_size_checks();
1136 : :
1137 : : /* Multi-process not supported */
1138 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1139 : : err = -EPERM;
1140 : 0 : goto err;
1141 : : }
1142 : :
1143 : 0 : adapter = rte_zmalloc("ionic", sizeof(*adapter), RTE_CACHE_LINE_SIZE);
1144 [ # # ]: 0 : if (!adapter) {
1145 : 0 : IONIC_PRINT(ERR, "OOM");
1146 : : err = -ENOMEM;
1147 : 0 : goto err;
1148 : : }
1149 : :
1150 : 0 : adapter->bus_dev = bus_dev;
1151 : 0 : hw = &adapter->hw;
1152 : :
1153 : : /* Vendor and Device ID need to be set before init of shared code */
1154 : 0 : hw->device_id = device_id;
1155 : 0 : hw->vendor_id = vendor_id;
1156 : :
1157 : 0 : err = ionic_init_mac(hw);
1158 [ # # ]: 0 : if (err != 0) {
1159 : 0 : IONIC_PRINT(ERR, "Mac init failed: %d", err);
1160 : : err = -EIO;
1161 : 0 : goto err_free_adapter;
1162 : : }
1163 : :
1164 : 0 : adapter->bars.num_bars = bars->num_bars;
1165 [ # # ]: 0 : for (i = 0; i < bars->num_bars; i++) {
1166 : 0 : adapter->bars.bar[i].vaddr = bars->bar[i].vaddr;
1167 : 0 : adapter->bars.bar[i].bus_addr = bars->bar[i].bus_addr;
1168 : 0 : adapter->bars.bar[i].len = bars->bar[i].len;
1169 : : }
1170 : :
1171 [ # # ]: 0 : if (intf->setup == NULL) {
1172 : 0 : IONIC_PRINT(ERR, "Device setup function is mandatory");
1173 : 0 : goto err_free_adapter;
1174 : : }
1175 : :
1176 : 0 : adapter->intf = intf;
1177 : :
1178 : : /* Parse device arguments */
1179 [ # # ]: 0 : if (adapter->intf->devargs) {
1180 : 0 : err = (*adapter->intf->devargs)(adapter, rte_dev->devargs);
1181 [ # # ]: 0 : if (err) {
1182 : 0 : IONIC_PRINT(ERR, "Cannot parse device arguments");
1183 : 0 : goto err_free_adapter;
1184 : : }
1185 : : }
1186 : :
1187 : : /* Discover ionic dev resources */
1188 : 0 : err = ionic_setup(adapter);
1189 [ # # ]: 0 : if (err) {
1190 : 0 : IONIC_PRINT(ERR, "Cannot setup device: %d, aborting", err);
1191 : 0 : goto err_free_adapter;
1192 : : }
1193 : :
1194 : 0 : err = ionic_identify(adapter);
1195 [ # # ]: 0 : if (err) {
1196 : 0 : IONIC_PRINT(ERR, "Cannot identify device: %d, aborting",
1197 : : err);
1198 : 0 : goto err_free_adapter;
1199 : : }
1200 : :
1201 : 0 : err = ionic_init(adapter);
1202 [ # # ]: 0 : if (err) {
1203 : 0 : IONIC_PRINT(ERR, "Cannot init device: %d, aborting", err);
1204 : 0 : goto err_free_adapter;
1205 : : }
1206 : :
1207 : : /* Configure the ports */
1208 : 0 : err = ionic_port_identify(adapter);
1209 [ # # ]: 0 : if (err) {
1210 : 0 : IONIC_PRINT(ERR, "Cannot identify port: %d, aborting",
1211 : : err);
1212 : 0 : goto err_free_adapter;
1213 : : }
1214 : :
1215 : 0 : err = ionic_port_init(adapter);
1216 [ # # ]: 0 : if (err) {
1217 : 0 : IONIC_PRINT(ERR, "Cannot init port: %d, aborting", err);
1218 : 0 : goto err_free_adapter;
1219 : : }
1220 : :
1221 : : /* Configure LIFs */
1222 : 0 : err = ionic_lif_identify(adapter);
1223 [ # # ]: 0 : if (err) {
1224 : 0 : IONIC_PRINT(ERR, "Cannot identify lif: %d, aborting", err);
1225 : 0 : goto err_free_adapter;
1226 : : }
1227 : :
1228 : : /* Allocate and init LIFs */
1229 : 0 : err = ionic_lifs_size(adapter);
1230 [ # # ]: 0 : if (err) {
1231 : 0 : IONIC_PRINT(ERR, "Cannot size LIFs: %d, aborting", err);
1232 : 0 : goto err_free_adapter;
1233 : : }
1234 : :
1235 : 0 : adapter->max_mac_addrs =
1236 : 0 : rte_le_to_cpu_32(adapter->ident.lif.eth.max_ucast_filters);
1237 : :
1238 [ # # ]: 0 : if (rte_le_to_cpu_32(adapter->ident.dev.nlifs) != 1) {
1239 : 0 : IONIC_PRINT(ERR, "Unexpected request for %d LIFs",
1240 : : rte_le_to_cpu_32(adapter->ident.dev.nlifs));
1241 : 0 : goto err_free_adapter;
1242 : : }
1243 : :
1244 : 0 : snprintf(name, sizeof(name), "%s_lif", rte_dev->name);
1245 : 0 : err = rte_eth_dev_create(rte_dev, name, sizeof(struct ionic_lif),
1246 : : NULL, NULL, eth_ionic_dev_init, adapter);
1247 [ # # ]: 0 : if (err) {
1248 : 0 : IONIC_PRINT(ERR, "Cannot create eth device for %s", name);
1249 : 0 : goto err_free_adapter;
1250 : : }
1251 : :
1252 [ # # ]: 0 : if (adapter->intf->configure_intr) {
1253 : 0 : err = (*adapter->intf->configure_intr)(adapter);
1254 [ # # ]: 0 : if (err) {
1255 : 0 : IONIC_PRINT(ERR, "Failed to configure interrupts");
1256 : 0 : goto err_free_adapter;
1257 : : }
1258 : : }
1259 : :
1260 : : return 0;
1261 : :
1262 : 0 : err_free_adapter:
1263 : 0 : rte_free(adapter);
1264 : : err:
1265 : : return err;
1266 : : }
1267 : :
1268 : : int
1269 : 0 : eth_ionic_dev_remove(struct rte_device *rte_dev)
1270 : : {
1271 : : char name[RTE_ETH_NAME_MAX_LEN];
1272 : : struct rte_eth_dev *eth_dev;
1273 : : int ret = 0;
1274 : :
1275 : : /* Adapter lookup is using the eth_dev name */
1276 : 0 : snprintf(name, sizeof(name), "%s_lif", rte_dev->name);
1277 : :
1278 : 0 : eth_dev = rte_eth_dev_allocated(name);
1279 [ # # ]: 0 : if (eth_dev)
1280 : 0 : ret = rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit);
1281 : : else
1282 : 0 : IONIC_PRINT(DEBUG, "Cannot find device %s", rte_dev->name);
1283 : :
1284 : 0 : return ret;
1285 : : }
1286 : :
1287 [ - + ]: 252 : RTE_LOG_REGISTER_DEFAULT(ionic_logtype, NOTICE);
|