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 : : /* Initialize */
304 : : memset(&link, 0, sizeof(link));
305 : :
306 [ # # ]: 0 : if (adapter->idev.port_info->config.an_enable) {
307 : 0 : link.link_autoneg = RTE_ETH_LINK_AUTONEG;
308 : : }
309 : :
310 [ # # ]: 0 : if (!adapter->link_up ||
311 [ # # ]: 0 : !(lif->state & IONIC_LIF_F_UP)) {
312 : : /* Interface is down */
313 : : link.link_status = RTE_ETH_LINK_DOWN;
314 : : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
315 : : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
316 : : } else {
317 : : /* Interface is up */
318 : 0 : link.link_status = RTE_ETH_LINK_UP;
319 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
320 [ # # # # : 0 : switch (adapter->link_speed) {
# # # # ]
321 : 0 : case 1000:
322 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_1G;
323 : 0 : break;
324 : 0 : case 10000:
325 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_10G;
326 : 0 : break;
327 : 0 : case 25000:
328 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_25G;
329 : 0 : break;
330 : 0 : case 40000:
331 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_40G;
332 : 0 : break;
333 : 0 : case 50000:
334 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_50G;
335 : 0 : break;
336 : 0 : case 100000:
337 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100G;
338 : 0 : break;
339 : 0 : case 200000:
340 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_200G;
341 : 0 : break;
342 : : default:
343 : : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
344 : : break;
345 : : }
346 : : }
347 : :
348 : 0 : return rte_eth_linkstatus_set(eth_dev, &link);
349 : : }
350 : :
351 : : /**
352 : : * Interrupt handler triggered by NIC for handling
353 : : * specific interrupt.
354 : : *
355 : : * @param param
356 : : * The address of parameter registered before.
357 : : *
358 : : * @return
359 : : * void
360 : : */
361 : : void
362 : 0 : ionic_dev_interrupt_handler(void *param)
363 : : {
364 : : struct ionic_adapter *adapter = (struct ionic_adapter *)param;
365 : :
366 : 0 : IONIC_PRINT(DEBUG, "->");
367 : :
368 [ # # ]: 0 : if (adapter->lif)
369 : 0 : ionic_notifyq_handler(adapter->lif, -1);
370 : 0 : }
371 : :
372 : : static int
373 : 0 : ionic_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
374 : : {
375 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
376 : :
377 [ # # ]: 0 : if (lif->state & IONIC_LIF_F_UP) {
378 : 0 : IONIC_PRINT(ERR, "Stop %s before setting mtu", lif->name);
379 : 0 : return -EBUSY;
380 : : }
381 : :
382 : : /* Note: mtu check against min/max is done by the API */
383 : 0 : IONIC_PRINT(INFO, "Setting mtu %u", mtu);
384 : :
385 : : /* Update the frame size used by the Rx path */
386 : 0 : lif->frame_size = mtu + IONIC_ETH_OVERHEAD;
387 : :
388 : 0 : return 0;
389 : : }
390 : :
391 : : static int
392 : 0 : ionic_dev_info_get(struct rte_eth_dev *eth_dev,
393 : : struct rte_eth_dev_info *dev_info)
394 : : {
395 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
396 : 0 : struct ionic_adapter *adapter = lif->adapter;
397 : : struct ionic_identity *ident = &adapter->ident;
398 : : union ionic_lif_config *cfg = &ident->lif.eth.config;
399 : :
400 : 0 : IONIC_PRINT_CALL();
401 : :
402 : 0 : dev_info->max_rx_queues = (uint16_t)
403 : 0 : rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_RXQ]);
404 : 0 : dev_info->max_tx_queues = (uint16_t)
405 : 0 : rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_TXQ]);
406 : :
407 : : /* Also add ETHER_CRC_LEN if the adapter is able to keep CRC */
408 : 0 : dev_info->min_mtu = RTE_MAX((uint32_t)IONIC_MIN_MTU,
409 : : rte_le_to_cpu_32(ident->lif.eth.min_mtu));
410 : 0 : dev_info->max_mtu = RTE_MIN((uint32_t)IONIC_MAX_MTU,
411 : : rte_le_to_cpu_32(ident->lif.eth.max_mtu));
412 : 0 : dev_info->min_rx_bufsize = dev_info->min_mtu + IONIC_ETH_OVERHEAD;
413 : 0 : dev_info->max_rx_pktlen = dev_info->max_mtu + IONIC_ETH_OVERHEAD;
414 : 0 : dev_info->max_lro_pkt_size =
415 : 0 : eth_dev->data->dev_conf.rxmode.max_lro_pkt_size;
416 : :
417 : 0 : dev_info->max_mac_addrs = adapter->max_mac_addrs;
418 : 0 : dev_info->hash_key_size = IONIC_RSS_HASH_KEY_SIZE;
419 : 0 : dev_info->reta_size = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz);
420 : 0 : dev_info->flow_type_rss_offloads = IONIC_ETH_RSS_OFFLOAD_ALL;
421 : :
422 : 0 : dev_info->speed_capa =
423 : : RTE_ETH_LINK_SPEED_10G |
424 : : RTE_ETH_LINK_SPEED_25G |
425 : : RTE_ETH_LINK_SPEED_40G |
426 : : RTE_ETH_LINK_SPEED_50G |
427 : : RTE_ETH_LINK_SPEED_100G;
428 : :
429 : : /*
430 : : * Per-queue capabilities
431 : : * RTE does not support disabling a feature on a queue if it is
432 : : * enabled globally on the device. Thus the driver does not advertise
433 : : * capabilities like RTE_ETH_TX_OFFLOAD_IPV4_CKSUM as per-queue even
434 : : * though the driver would be otherwise capable of disabling it on
435 : : * a per-queue basis.
436 : : */
437 : :
438 : 0 : dev_info->rx_queue_offload_capa = 0;
439 : 0 : dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
440 : :
441 : : /*
442 : : * Per-port capabilities
443 : : * See ionic_set_features to request and check supported features
444 : : */
445 : :
446 : 0 : dev_info->rx_offload_capa = dev_info->rx_queue_offload_capa |
447 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
448 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
449 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
450 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
451 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
452 : : RTE_ETH_RX_OFFLOAD_SCATTER |
453 : : RTE_ETH_RX_OFFLOAD_RSS_HASH |
454 : : 0;
455 : :
456 : 0 : dev_info->tx_offload_capa = dev_info->tx_queue_offload_capa |
457 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
458 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
459 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
460 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
461 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM |
462 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
463 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
464 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
465 : : 0;
466 : :
467 : 0 : dev_info->rx_desc_lim = rx_desc_lim;
468 : 0 : dev_info->tx_desc_lim = tx_desc_lim_v1;
469 : :
470 : : /* Driver-preferred Rx/Tx parameters */
471 : 0 : dev_info->default_rxportconf.burst_size = IONIC_DEF_TXRX_BURST;
472 : 0 : dev_info->default_txportconf.burst_size = IONIC_DEF_TXRX_BURST;
473 : 0 : dev_info->default_rxportconf.nb_queues = 1;
474 : 0 : dev_info->default_txportconf.nb_queues = 1;
475 : 0 : dev_info->default_rxportconf.ring_size = IONIC_DEF_TXRX_DESC;
476 : 0 : dev_info->default_txportconf.ring_size = IONIC_DEF_TXRX_DESC;
477 : :
478 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
479 : : /* Packets are always dropped if no desc are available */
480 : : .rx_drop_en = 1,
481 : : };
482 : :
483 : 0 : return 0;
484 : : }
485 : :
486 : : static int
487 : 0 : ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev,
488 : : struct rte_eth_fc_conf *fc_conf)
489 : : {
490 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
491 : 0 : struct ionic_adapter *adapter = lif->adapter;
492 : : struct ionic_dev *idev = &adapter->idev;
493 : :
494 [ # # ]: 0 : if (idev->port_info) {
495 : : /* Flow control autoneg not supported */
496 : 0 : fc_conf->autoneg = 0;
497 : :
498 [ # # ]: 0 : if (idev->port_info->config.pause_type)
499 : 0 : fc_conf->mode = RTE_ETH_FC_FULL;
500 : : else
501 : 0 : fc_conf->mode = RTE_ETH_FC_NONE;
502 : : }
503 : :
504 : 0 : return 0;
505 : : }
506 : :
507 : : static int
508 : 0 : ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev,
509 : : struct rte_eth_fc_conf *fc_conf)
510 : : {
511 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
512 : 0 : struct ionic_adapter *adapter = lif->adapter;
513 : 0 : struct ionic_dev *idev = &adapter->idev;
514 : : uint8_t pause_type = IONIC_PORT_PAUSE_TYPE_NONE;
515 : : int err;
516 : :
517 [ # # ]: 0 : if (fc_conf->autoneg) {
518 : 0 : IONIC_PRINT(WARNING, "Flow control autoneg not supported");
519 : 0 : return -ENOTSUP;
520 : : }
521 : :
522 [ # # # ]: 0 : switch (fc_conf->mode) {
523 : : case RTE_ETH_FC_NONE:
524 : : pause_type = IONIC_PORT_PAUSE_TYPE_NONE;
525 : : break;
526 : 0 : case RTE_ETH_FC_FULL:
527 : : pause_type = IONIC_PORT_PAUSE_TYPE_LINK;
528 : 0 : break;
529 : : case RTE_ETH_FC_RX_PAUSE:
530 : : case RTE_ETH_FC_TX_PAUSE:
531 : : return -ENOTSUP;
532 : : }
533 : :
534 : 0 : ionic_dev_cmd_port_pause(idev, pause_type);
535 : 0 : err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
536 [ # # ]: 0 : if (err)
537 : 0 : IONIC_PRINT(WARNING, "Failed to configure flow control");
538 : :
539 : : return err;
540 : : }
541 : :
542 : : static int
543 : 0 : ionic_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
544 : : {
545 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
546 : :
547 : 0 : ionic_lif_configure_vlan_offload(lif, mask);
548 : :
549 : 0 : ionic_lif_set_features(lif);
550 : :
551 : 0 : return 0;
552 : : }
553 : :
554 : : static int
555 : 0 : ionic_dev_rss_reta_update(struct rte_eth_dev *eth_dev,
556 : : struct rte_eth_rss_reta_entry64 *reta_conf,
557 : : uint16_t reta_size)
558 : : {
559 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
560 : 0 : struct ionic_adapter *adapter = lif->adapter;
561 : : struct ionic_identity *ident = &adapter->ident;
562 : : uint32_t i, j, index, num;
563 : 0 : uint16_t tbl_sz = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz);
564 : :
565 : 0 : IONIC_PRINT_CALL();
566 : :
567 [ # # ]: 0 : if (!lif->rss_ind_tbl) {
568 : 0 : IONIC_PRINT(ERR, "RSS RETA not initialized, "
569 : : "can't update the table");
570 : 0 : return -EINVAL;
571 : : }
572 : :
573 [ # # ]: 0 : if (reta_size != tbl_sz) {
574 : 0 : IONIC_PRINT(ERR, "The size of hash lookup table configured "
575 : : "(%d) does not match the number hardware can support "
576 : : "(%d)",
577 : : reta_size, tbl_sz);
578 : 0 : return -EINVAL;
579 : : }
580 : :
581 : 0 : num = tbl_sz / RTE_ETH_RETA_GROUP_SIZE;
582 : :
583 [ # # ]: 0 : for (i = 0; i < num; i++) {
584 [ # # ]: 0 : for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) {
585 [ # # ]: 0 : if (reta_conf[i].mask & ((uint64_t)1 << j)) {
586 : 0 : index = (i * RTE_ETH_RETA_GROUP_SIZE) + j;
587 : 0 : lif->rss_ind_tbl[index] = reta_conf[i].reta[j];
588 : : }
589 : : }
590 : : }
591 : :
592 : 0 : return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL);
593 : : }
594 : :
595 : : static int
596 : 0 : ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev,
597 : : struct rte_eth_rss_reta_entry64 *reta_conf,
598 : : uint16_t reta_size)
599 : : {
600 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
601 : 0 : struct ionic_adapter *adapter = lif->adapter;
602 : : struct ionic_identity *ident = &adapter->ident;
603 : : int i, j, num;
604 : 0 : uint16_t tbl_sz = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz);
605 : :
606 : 0 : IONIC_PRINT_CALL();
607 : :
608 [ # # ]: 0 : if (reta_size != tbl_sz) {
609 : 0 : IONIC_PRINT(ERR, "The size of hash lookup table configured "
610 : : "(%d) does not match the number hardware can support "
611 : : "(%d)",
612 : : reta_size, tbl_sz);
613 : 0 : return -EINVAL;
614 : : }
615 : :
616 [ # # ]: 0 : if (!lif->rss_ind_tbl) {
617 : 0 : IONIC_PRINT(ERR, "RSS RETA has not been built yet");
618 : 0 : return -EINVAL;
619 : : }
620 : :
621 : 0 : num = reta_size / RTE_ETH_RETA_GROUP_SIZE;
622 : :
623 [ # # ]: 0 : for (i = 0; i < num; i++) {
624 [ # # ]: 0 : for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) {
625 : 0 : reta_conf->reta[j] =
626 : 0 : lif->rss_ind_tbl[(i * RTE_ETH_RETA_GROUP_SIZE) + j];
627 : : }
628 : 0 : reta_conf++;
629 : : }
630 : :
631 : : return 0;
632 : : }
633 : :
634 : : static int
635 : 0 : ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
636 : : struct rte_eth_rss_conf *rss_conf)
637 : : {
638 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
639 : : uint64_t rss_hf = 0;
640 : :
641 : 0 : IONIC_PRINT_CALL();
642 : :
643 [ # # ]: 0 : if (!lif->rss_ind_tbl) {
644 : 0 : IONIC_PRINT(NOTICE, "RSS not enabled");
645 : 0 : return 0;
646 : : }
647 : :
648 : : /* Get key value (if not null, rss_key is 40-byte) */
649 [ # # ]: 0 : if (rss_conf->rss_key != NULL &&
650 [ # # ]: 0 : rss_conf->rss_key_len >= IONIC_RSS_HASH_KEY_SIZE)
651 : 0 : memcpy(rss_conf->rss_key, lif->rss_hash_key,
652 : : IONIC_RSS_HASH_KEY_SIZE);
653 : :
654 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV4)
655 : : rss_hf |= RTE_ETH_RSS_IPV4;
656 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV4_TCP)
657 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
658 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV4_UDP)
659 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
660 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV6)
661 : 0 : rss_hf |= RTE_ETH_RSS_IPV6;
662 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV6_TCP)
663 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
664 [ # # ]: 0 : if (lif->rss_types & IONIC_RSS_TYPE_IPV6_UDP)
665 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
666 : :
667 : 0 : rss_conf->rss_hf = rss_hf;
668 : :
669 : 0 : return 0;
670 : : }
671 : :
672 : : static int
673 : 0 : ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev,
674 : : struct rte_eth_rss_conf *rss_conf)
675 : : {
676 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
677 : : uint32_t rss_types = 0;
678 : : uint8_t *key = NULL;
679 : :
680 : 0 : IONIC_PRINT_CALL();
681 : :
682 [ # # ]: 0 : if (rss_conf->rss_key)
683 : : key = rss_conf->rss_key;
684 : :
685 [ # # ]: 0 : if ((rss_conf->rss_hf & IONIC_ETH_RSS_OFFLOAD_ALL) == 0) {
686 : : /*
687 : : * Can't disable rss through hash flags,
688 : : * if it is enabled by default during init
689 : : */
690 [ # # ]: 0 : if (lif->rss_ind_tbl)
691 : 0 : return -EINVAL;
692 : : } else {
693 : : /* Can't enable rss if disabled by default during init */
694 [ # # ]: 0 : if (!lif->rss_ind_tbl)
695 : : return -EINVAL;
696 : :
697 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_IPV4)
698 : : rss_types |= IONIC_RSS_TYPE_IPV4;
699 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP)
700 : 0 : rss_types |= IONIC_RSS_TYPE_IPV4_TCP;
701 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP)
702 : 0 : rss_types |= IONIC_RSS_TYPE_IPV4_UDP;
703 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_IPV6)
704 : 0 : rss_types |= IONIC_RSS_TYPE_IPV6;
705 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP)
706 : 0 : rss_types |= IONIC_RSS_TYPE_IPV6_TCP;
707 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP)
708 : 0 : rss_types |= IONIC_RSS_TYPE_IPV6_UDP;
709 : :
710 : 0 : ionic_lif_rss_config(lif, rss_types, key, NULL);
711 : : }
712 : :
713 : : return 0;
714 : : }
715 : :
716 : : static int
717 : 0 : ionic_dev_stats_get(struct rte_eth_dev *eth_dev,
718 : : struct rte_eth_stats *stats)
719 : : {
720 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
721 : :
722 : 0 : ionic_lif_get_stats(lif, stats);
723 : :
724 : 0 : return 0;
725 : : }
726 : :
727 : : static int
728 : 0 : ionic_dev_stats_reset(struct rte_eth_dev *eth_dev)
729 : : {
730 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
731 : :
732 : 0 : IONIC_PRINT_CALL();
733 : :
734 : 0 : ionic_lif_reset_stats(lif);
735 : :
736 : 0 : return 0;
737 : : }
738 : :
739 : : static int
740 : 0 : ionic_dev_xstats_get_names(__rte_unused struct rte_eth_dev *eth_dev,
741 : : struct rte_eth_xstat_name *xstats_names,
742 : : __rte_unused unsigned int size)
743 : : {
744 : : unsigned int i;
745 : :
746 [ # # ]: 0 : if (xstats_names != NULL) {
747 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
748 : 0 : snprintf(xstats_names[i].name,
749 : : sizeof(xstats_names[i].name),
750 : 0 : "%s", rte_ionic_xstats_strings[i].name);
751 : : }
752 : : }
753 : :
754 : 0 : return IONIC_NB_HW_STATS;
755 : : }
756 : :
757 : : static int
758 : 0 : ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *eth_dev,
759 : : const uint64_t *ids, struct rte_eth_xstat_name *xstats_names,
760 : : unsigned int limit)
761 : : {
762 : : struct rte_eth_xstat_name xstats_names_copy[IONIC_NB_HW_STATS];
763 : : uint16_t i;
764 : :
765 [ # # ]: 0 : if (!ids) {
766 [ # # ]: 0 : if (xstats_names != NULL) {
767 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
768 : 0 : snprintf(xstats_names[i].name,
769 : : sizeof(xstats_names[i].name),
770 : 0 : "%s", rte_ionic_xstats_strings[i].name);
771 : : }
772 : : }
773 : :
774 : 0 : return IONIC_NB_HW_STATS;
775 : : }
776 : :
777 : 0 : ionic_dev_xstats_get_names_by_id(eth_dev, NULL, xstats_names_copy,
778 : : IONIC_NB_HW_STATS);
779 : :
780 [ # # ]: 0 : for (i = 0; i < limit; i++) {
781 [ # # ]: 0 : if (ids[i] >= IONIC_NB_HW_STATS) {
782 : 0 : IONIC_PRINT(ERR, "id value isn't valid");
783 : 0 : return -1;
784 : : }
785 : :
786 : 0 : strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
787 : : }
788 : :
789 : 0 : return limit;
790 : : }
791 : :
792 : : static int
793 : 0 : ionic_dev_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats,
794 : : unsigned int n)
795 : : {
796 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
797 : : struct ionic_lif_stats hw_stats;
798 : : uint16_t i;
799 : :
800 [ # # ]: 0 : if (n < IONIC_NB_HW_STATS)
801 : : return IONIC_NB_HW_STATS;
802 : :
803 : 0 : ionic_lif_get_hw_stats(lif, &hw_stats);
804 : :
805 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
806 : 0 : xstats[i].value = *(uint64_t *)(((char *)&hw_stats) +
807 : 0 : rte_ionic_xstats_strings[i].offset);
808 : 0 : xstats[i].id = i;
809 : : }
810 : :
811 : : return IONIC_NB_HW_STATS;
812 : : }
813 : :
814 : : static int
815 : 0 : ionic_dev_xstats_get_by_id(struct rte_eth_dev *eth_dev, const uint64_t *ids,
816 : : uint64_t *values, unsigned int n)
817 : : {
818 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
819 : : struct ionic_lif_stats hw_stats;
820 : : uint64_t values_copy[IONIC_NB_HW_STATS];
821 : : uint16_t i;
822 : :
823 [ # # ]: 0 : if (!ids) {
824 [ # # ]: 0 : if (!ids && n < IONIC_NB_HW_STATS)
825 : : return IONIC_NB_HW_STATS;
826 : :
827 : 0 : ionic_lif_get_hw_stats(lif, &hw_stats);
828 : :
829 [ # # ]: 0 : for (i = 0; i < IONIC_NB_HW_STATS; i++) {
830 : 0 : values[i] = *(uint64_t *)(((char *)&hw_stats) +
831 : 0 : rte_ionic_xstats_strings[i].offset);
832 : : }
833 : :
834 : : return IONIC_NB_HW_STATS;
835 : : }
836 : :
837 : 0 : ionic_dev_xstats_get_by_id(eth_dev, NULL, values_copy,
838 : : IONIC_NB_HW_STATS);
839 : :
840 [ # # ]: 0 : for (i = 0; i < n; i++) {
841 [ # # ]: 0 : if (ids[i] >= IONIC_NB_HW_STATS) {
842 : 0 : IONIC_PRINT(ERR, "id value isn't valid");
843 : 0 : return -1;
844 : : }
845 : :
846 : 0 : values[i] = values_copy[ids[i]];
847 : : }
848 : :
849 : 0 : return n;
850 : : }
851 : :
852 : : static int
853 : 0 : ionic_dev_xstats_reset(struct rte_eth_dev *eth_dev)
854 : : {
855 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
856 : :
857 : 0 : ionic_lif_reset_hw_stats(lif);
858 : :
859 : 0 : return 0;
860 : : }
861 : :
862 : : static int
863 : 0 : ionic_dev_configure(struct rte_eth_dev *eth_dev)
864 : : {
865 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
866 : :
867 : 0 : IONIC_PRINT_CALL();
868 : :
869 : 0 : ionic_lif_configure(lif);
870 : :
871 : 0 : return 0;
872 : : }
873 : :
874 : : static inline uint32_t
875 : : ionic_parse_link_speeds(uint16_t link_speeds)
876 : : {
877 : 0 : if (link_speeds & RTE_ETH_LINK_SPEED_100G)
878 : : return 100000;
879 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_50G)
880 : : return 50000;
881 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_40G)
882 : : return 40000;
883 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_25G)
884 : : return 25000;
885 [ # # ]: 0 : else if (link_speeds & RTE_ETH_LINK_SPEED_10G)
886 : : return 10000;
887 : : else
888 : : return 0;
889 : : }
890 : :
891 : : /*
892 : : * Configure device link speed and setup link.
893 : : * It returns 0 on success.
894 : : */
895 : : static int
896 : 0 : ionic_dev_start(struct rte_eth_dev *eth_dev)
897 : : {
898 : 0 : struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf;
899 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
900 : 0 : struct ionic_adapter *adapter = lif->adapter;
901 : 0 : struct ionic_dev *idev = &adapter->idev;
902 : : uint32_t speed = 0, allowed_speeds;
903 : : uint8_t an_enable;
904 : : int err;
905 : :
906 : 0 : IONIC_PRINT_CALL();
907 : :
908 : : allowed_speeds =
909 : : RTE_ETH_LINK_SPEED_FIXED |
910 : : RTE_ETH_LINK_SPEED_10G |
911 : : RTE_ETH_LINK_SPEED_25G |
912 : : RTE_ETH_LINK_SPEED_40G |
913 : : RTE_ETH_LINK_SPEED_50G |
914 : : RTE_ETH_LINK_SPEED_100G;
915 : :
916 [ # # ]: 0 : if (dev_conf->link_speeds & ~allowed_speeds) {
917 : 0 : IONIC_PRINT(ERR, "Invalid link setting");
918 : 0 : return -EINVAL;
919 : : }
920 : :
921 [ # # ]: 0 : if (dev_conf->lpbk_mode)
922 : 0 : IONIC_PRINT(WARNING, "Loopback mode not supported");
923 : :
924 : : /* Re-set features in case SG flag was added in rx_queue_setup() */
925 : 0 : err = ionic_lif_set_features(lif);
926 [ # # ]: 0 : if (err) {
927 : 0 : IONIC_PRINT(ERR, "Cannot set LIF features: %d", err);
928 : 0 : return err;
929 : : }
930 : :
931 : 0 : lif->frame_size = eth_dev->data->mtu + IONIC_ETH_OVERHEAD;
932 : :
933 : 0 : err = ionic_lif_change_mtu(lif, eth_dev->data->mtu);
934 [ # # ]: 0 : if (err) {
935 : 0 : IONIC_PRINT(ERR, "Cannot set LIF frame size %u: %d",
936 : : lif->frame_size, err);
937 : 0 : return err;
938 : : }
939 : :
940 : 0 : err = ionic_lif_start(lif);
941 [ # # ]: 0 : if (err) {
942 : 0 : IONIC_PRINT(ERR, "Cannot start LIF: %d", err);
943 : 0 : return err;
944 : : }
945 : :
946 : : /* Configure link */
947 : 0 : an_enable = (dev_conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) == 0;
948 : :
949 : 0 : ionic_dev_cmd_port_autoneg(idev, an_enable);
950 : 0 : err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
951 [ # # ]: 0 : if (err)
952 [ # # ]: 0 : IONIC_PRINT(WARNING, "Failed to %s autonegotiation",
953 : : an_enable ? "enable" : "disable");
954 : :
955 [ # # ]: 0 : if (!an_enable)
956 [ # # ]: 0 : speed = ionic_parse_link_speeds(dev_conf->link_speeds);
957 : : if (speed) {
958 : 0 : ionic_dev_cmd_port_speed(idev, speed);
959 : 0 : err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
960 [ # # ]: 0 : if (err)
961 : 0 : IONIC_PRINT(WARNING, "Failed to set link speed %u",
962 : : speed);
963 : : }
964 : :
965 [ # # ]: 0 : if (lif->hw_features & IONIC_ETH_HW_RX_SG)
966 : 0 : eth_dev->rx_pkt_burst = &ionic_recv_pkts_sg;
967 : : else
968 : 0 : eth_dev->rx_pkt_burst = &ionic_recv_pkts;
969 : :
970 [ # # ]: 0 : if (lif->hw_features & IONIC_ETH_HW_TX_SG)
971 : 0 : eth_dev->tx_pkt_burst = &ionic_xmit_pkts_sg;
972 : : else
973 : 0 : eth_dev->tx_pkt_burst = &ionic_xmit_pkts;
974 : :
975 : 0 : eth_dev->tx_pkt_prepare = &ionic_prep_pkts;
976 : :
977 : 0 : ionic_dev_link_update(eth_dev, 0);
978 : :
979 : 0 : return 0;
980 : : }
981 : :
982 : : /*
983 : : * Stop device: disable rx and tx functions to allow for reconfiguring.
984 : : */
985 : : static int
986 : 0 : ionic_dev_stop(struct rte_eth_dev *eth_dev)
987 : : {
988 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
989 : :
990 : 0 : IONIC_PRINT_CALL();
991 : :
992 : 0 : ionic_lif_stop(lif);
993 : :
994 : 0 : return 0;
995 : : }
996 : :
997 : : /*
998 : : * Reset and stop device.
999 : : */
1000 : : static int
1001 : 0 : ionic_dev_close(struct rte_eth_dev *eth_dev)
1002 : : {
1003 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
1004 : 0 : struct ionic_adapter *adapter = lif->adapter;
1005 : :
1006 : 0 : IONIC_PRINT_CALL();
1007 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1008 : : return 0;
1009 : :
1010 : 0 : IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name);
1011 [ # # ]: 0 : if (adapter->intf->unconfigure_intr)
1012 : 0 : (*adapter->intf->unconfigure_intr)(adapter);
1013 : :
1014 : 0 : ionic_reset(adapter);
1015 : :
1016 : 0 : ionic_lif_free_queues(lif);
1017 : 0 : ionic_lif_deinit(lif);
1018 : 0 : ionic_lif_free(lif); /* Does not free LIF object */
1019 : :
1020 [ # # ]: 0 : if (adapter->intf->unmap_bars)
1021 : 0 : (*adapter->intf->unmap_bars)(adapter);
1022 : :
1023 : 0 : lif->adapter = NULL;
1024 : 0 : rte_free(adapter);
1025 : :
1026 : 0 : return 0;
1027 : : }
1028 : :
1029 : : int
1030 : 0 : eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
1031 : : {
1032 : 0 : struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
1033 : : struct ionic_adapter *adapter = (struct ionic_adapter *)init_params;
1034 : : int err;
1035 : :
1036 : 0 : IONIC_PRINT_CALL();
1037 : :
1038 : 0 : eth_dev->dev_ops = &ionic_eth_dev_ops;
1039 : 0 : eth_dev->rx_descriptor_status = ionic_dev_rx_descriptor_status;
1040 : 0 : eth_dev->tx_descriptor_status = ionic_dev_tx_descriptor_status;
1041 : :
1042 : : /* Multi-process not supported, primary does initialization anyway */
1043 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1044 : : return 0;
1045 : :
1046 [ # # ]: 0 : if (adapter->intf->copy_bus_info)
1047 : 0 : (*adapter->intf->copy_bus_info)(adapter, eth_dev);
1048 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
1049 : :
1050 : 0 : lif->eth_dev = eth_dev;
1051 : 0 : lif->adapter = adapter;
1052 : 0 : adapter->lif = lif;
1053 : :
1054 : 0 : IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported",
1055 : : adapter->max_mac_addrs);
1056 : :
1057 : : /* Allocate memory for storing MAC addresses */
1058 : 0 : eth_dev->data->mac_addrs = rte_calloc("ionic",
1059 : 0 : adapter->max_mac_addrs,
1060 : : RTE_ETHER_ADDR_LEN,
1061 : : RTE_CACHE_LINE_SIZE);
1062 [ # # ]: 0 : if (eth_dev->data->mac_addrs == NULL) {
1063 : 0 : IONIC_PRINT(ERR, "Failed to allocate %u bytes needed to "
1064 : : "store MAC addresses",
1065 : : RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs);
1066 : : err = -ENOMEM;
1067 : 0 : goto err;
1068 : : }
1069 : :
1070 : 0 : err = ionic_lif_alloc(lif);
1071 [ # # ]: 0 : if (err) {
1072 : 0 : IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting",
1073 : : err);
1074 : 0 : goto err;
1075 : : }
1076 : :
1077 : 0 : err = ionic_lif_init(lif);
1078 [ # # ]: 0 : if (err) {
1079 : 0 : IONIC_PRINT(ERR, "Cannot init LIFs: %d, aborting", err);
1080 : 0 : goto err_free_lif;
1081 : : }
1082 : :
1083 : : /* Copy the MAC address */
1084 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr,
1085 : 0 : ð_dev->data->mac_addrs[0]);
1086 : :
1087 : 0 : IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id);
1088 : :
1089 : 0 : return 0;
1090 : :
1091 : : err_free_lif:
1092 : 0 : ionic_lif_free(lif);
1093 : : err:
1094 : : return err;
1095 : : }
1096 : :
1097 : : static int
1098 : 0 : eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev)
1099 : : {
1100 : 0 : IONIC_PRINT_CALL();
1101 : :
1102 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1103 : : return 0;
1104 : :
1105 [ # # ]: 0 : if (eth_dev->state != RTE_ETH_DEV_UNUSED)
1106 : 0 : ionic_dev_close(eth_dev);
1107 : :
1108 : 0 : eth_dev->dev_ops = NULL;
1109 : 0 : eth_dev->rx_pkt_burst = NULL;
1110 : 0 : eth_dev->tx_pkt_burst = NULL;
1111 : 0 : eth_dev->tx_pkt_prepare = NULL;
1112 : :
1113 : 0 : return 0;
1114 : : }
1115 : :
1116 : : int
1117 : 0 : eth_ionic_dev_probe(void *bus_dev, struct rte_device *rte_dev,
1118 : : struct ionic_bars *bars, const struct ionic_dev_intf *intf,
1119 : : uint16_t device_id, uint16_t vendor_id)
1120 : : {
1121 : : char name[RTE_ETH_NAME_MAX_LEN];
1122 : : struct ionic_adapter *adapter;
1123 : : struct ionic_hw *hw;
1124 : : unsigned long i;
1125 : : int err;
1126 : :
1127 : : /* Check structs (trigger error at compilation time) */
1128 : : ionic_struct_size_checks();
1129 : :
1130 : : /* Multi-process not supported */
1131 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1132 : : err = -EPERM;
1133 : 0 : goto err;
1134 : : }
1135 : :
1136 : 0 : adapter = rte_zmalloc("ionic", sizeof(*adapter), RTE_CACHE_LINE_SIZE);
1137 [ # # ]: 0 : if (!adapter) {
1138 : 0 : IONIC_PRINT(ERR, "OOM");
1139 : : err = -ENOMEM;
1140 : 0 : goto err;
1141 : : }
1142 : :
1143 : 0 : adapter->bus_dev = bus_dev;
1144 : 0 : hw = &adapter->hw;
1145 : :
1146 : : /* Vendor and Device ID need to be set before init of shared code */
1147 : 0 : hw->device_id = device_id;
1148 : 0 : hw->vendor_id = vendor_id;
1149 : :
1150 : 0 : err = ionic_init_mac(hw);
1151 [ # # ]: 0 : if (err != 0) {
1152 : 0 : IONIC_PRINT(ERR, "Mac init failed: %d", err);
1153 : : err = -EIO;
1154 : 0 : goto err_free_adapter;
1155 : : }
1156 : :
1157 : 0 : adapter->bars.num_bars = bars->num_bars;
1158 [ # # ]: 0 : for (i = 0; i < bars->num_bars; i++) {
1159 : 0 : adapter->bars.bar[i].vaddr = bars->bar[i].vaddr;
1160 : 0 : adapter->bars.bar[i].bus_addr = bars->bar[i].bus_addr;
1161 : 0 : adapter->bars.bar[i].len = bars->bar[i].len;
1162 : : }
1163 : :
1164 [ # # ]: 0 : if (intf->setup == NULL) {
1165 : 0 : IONIC_PRINT(ERR, "Device setup function is mandatory");
1166 : 0 : goto err_free_adapter;
1167 : : }
1168 : :
1169 : 0 : adapter->intf = intf;
1170 : :
1171 : : /* Parse device arguments */
1172 [ # # ]: 0 : if (adapter->intf->devargs) {
1173 : 0 : err = (*adapter->intf->devargs)(adapter, rte_dev->devargs);
1174 [ # # ]: 0 : if (err) {
1175 : 0 : IONIC_PRINT(ERR, "Cannot parse device arguments");
1176 : 0 : goto err_free_adapter;
1177 : : }
1178 : : }
1179 : :
1180 : : /* Discover ionic dev resources */
1181 : 0 : err = ionic_setup(adapter);
1182 [ # # ]: 0 : if (err) {
1183 : 0 : IONIC_PRINT(ERR, "Cannot setup device: %d, aborting", err);
1184 : 0 : goto err_free_adapter;
1185 : : }
1186 : :
1187 : 0 : err = ionic_identify(adapter);
1188 [ # # ]: 0 : if (err) {
1189 : 0 : IONIC_PRINT(ERR, "Cannot identify device: %d, aborting",
1190 : : err);
1191 : 0 : goto err_free_adapter;
1192 : : }
1193 : :
1194 : 0 : err = ionic_init(adapter);
1195 [ # # ]: 0 : if (err) {
1196 : 0 : IONIC_PRINT(ERR, "Cannot init device: %d, aborting", err);
1197 : 0 : goto err_free_adapter;
1198 : : }
1199 : :
1200 : : /* Configure the ports */
1201 : 0 : err = ionic_port_identify(adapter);
1202 [ # # ]: 0 : if (err) {
1203 : 0 : IONIC_PRINT(ERR, "Cannot identify port: %d, aborting",
1204 : : err);
1205 : 0 : goto err_free_adapter;
1206 : : }
1207 : :
1208 : 0 : err = ionic_port_init(adapter);
1209 [ # # ]: 0 : if (err) {
1210 : 0 : IONIC_PRINT(ERR, "Cannot init port: %d, aborting", err);
1211 : 0 : goto err_free_adapter;
1212 : : }
1213 : :
1214 : : /* Configure LIFs */
1215 : 0 : err = ionic_lif_identify(adapter);
1216 [ # # ]: 0 : if (err) {
1217 : 0 : IONIC_PRINT(ERR, "Cannot identify lif: %d, aborting", err);
1218 : 0 : goto err_free_adapter;
1219 : : }
1220 : :
1221 : : /* Allocate and init LIFs */
1222 : 0 : err = ionic_lifs_size(adapter);
1223 [ # # ]: 0 : if (err) {
1224 : 0 : IONIC_PRINT(ERR, "Cannot size LIFs: %d, aborting", err);
1225 : 0 : goto err_free_adapter;
1226 : : }
1227 : :
1228 : 0 : adapter->max_mac_addrs =
1229 : 0 : rte_le_to_cpu_32(adapter->ident.lif.eth.max_ucast_filters);
1230 : :
1231 [ # # ]: 0 : if (rte_le_to_cpu_32(adapter->ident.dev.nlifs) != 1) {
1232 : 0 : IONIC_PRINT(ERR, "Unexpected request for %d LIFs",
1233 : : rte_le_to_cpu_32(adapter->ident.dev.nlifs));
1234 : 0 : goto err_free_adapter;
1235 : : }
1236 : :
1237 : 0 : snprintf(name, sizeof(name), "%s_lif", rte_dev->name);
1238 : 0 : err = rte_eth_dev_create(rte_dev, name, sizeof(struct ionic_lif),
1239 : : NULL, NULL, eth_ionic_dev_init, adapter);
1240 [ # # ]: 0 : if (err) {
1241 : 0 : IONIC_PRINT(ERR, "Cannot create eth device for %s", name);
1242 : 0 : goto err_free_adapter;
1243 : : }
1244 : :
1245 [ # # ]: 0 : if (adapter->intf->configure_intr) {
1246 : 0 : err = (*adapter->intf->configure_intr)(adapter);
1247 [ # # ]: 0 : if (err) {
1248 : 0 : IONIC_PRINT(ERR, "Failed to configure interrupts");
1249 : 0 : goto err_free_adapter;
1250 : : }
1251 : : }
1252 : :
1253 : : return 0;
1254 : :
1255 : 0 : err_free_adapter:
1256 : 0 : rte_free(adapter);
1257 : : err:
1258 : : return err;
1259 : : }
1260 : :
1261 : : int
1262 : 0 : eth_ionic_dev_remove(struct rte_device *rte_dev)
1263 : : {
1264 : : char name[RTE_ETH_NAME_MAX_LEN];
1265 : : struct rte_eth_dev *eth_dev;
1266 : : int ret = 0;
1267 : :
1268 : : /* Adapter lookup is using the eth_dev name */
1269 : 0 : snprintf(name, sizeof(name), "%s_lif", rte_dev->name);
1270 : :
1271 : 0 : eth_dev = rte_eth_dev_allocated(name);
1272 [ # # ]: 0 : if (eth_dev)
1273 : 0 : ret = rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit);
1274 : : else
1275 : 0 : IONIC_PRINT(DEBUG, "Cannot find device %s", rte_dev->name);
1276 : :
1277 : 0 : return ret;
1278 : : }
1279 : :
1280 [ - + ]: 238 : RTE_LOG_REGISTER_DEFAULT(ionic_logtype, NOTICE);
|