Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2014-2018 Netronome Systems, Inc.
3 : : * All rights reserved.
4 : : *
5 : : * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation.
6 : : */
7 : :
8 : : #include "nfp_net_common.h"
9 : :
10 : : #include <rte_alarm.h>
11 : :
12 : : #include "flower/nfp_flower_cmsg.h"
13 : : #include "flower/nfp_flower_representor.h"
14 : : #include "nfd3/nfp_nfd3.h"
15 : : #include "nfdk/nfp_nfdk.h"
16 : : #include "nfpcore/nfp_mip.h"
17 : : #include "nfpcore/nfp_nsp.h"
18 : : #include "nfpcore/nfp_rtsym.h"
19 : : #include "nfp_logs.h"
20 : : #include "nfp_net_meta.h"
21 : :
22 : : #define NFP_TX_MAX_SEG UINT8_MAX
23 : : #define NFP_TX_MAX_MTU_SEG 8
24 : :
25 : : #define NFP_NET_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */
26 : : #define NFP_NET_LINK_UP_CHECK_TIMEOUT 1000 /* ms */
27 : :
28 : : #define DEFAULT_FLBUF_SIZE 9216
29 : : #define NFP_ETH_OVERHEAD \
30 : : (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + RTE_VLAN_HLEN * 2)
31 : :
32 : : /* Only show FEC capability supported by the current speed. */
33 : : #define NFP_FEC_CAPA_ENTRY_NUM 1
34 : :
35 : : enum nfp_xstat_group {
36 : : NFP_XSTAT_GROUP_NET,
37 : : NFP_XSTAT_GROUP_MAC
38 : : };
39 : :
40 : : struct nfp_xstat {
41 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
42 : : int offset;
43 : : enum nfp_xstat_group group;
44 : : };
45 : :
46 : : #define NFP_XSTAT_NET(_name, _offset) { \
47 : : .name = _name, \
48 : : .offset = NFP_NET_CFG_STATS_##_offset, \
49 : : .group = NFP_XSTAT_GROUP_NET, \
50 : : }
51 : :
52 : : #define NFP_XSTAT_MAC(_name, _offset) { \
53 : : .name = _name, \
54 : : .offset = NFP_MAC_STATS_##_offset, \
55 : : .group = NFP_XSTAT_GROUP_MAC, \
56 : : }
57 : :
58 : : static const struct nfp_xstat nfp_net_xstats[] = {
59 : : /*
60 : : * Basic xstats available on both VF and PF.
61 : : * Note that in case new statistics of group NFP_XSTAT_GROUP_NET
62 : : * are added to this array, they must appear before any statistics
63 : : * of group NFP_XSTAT_GROUP_MAC.
64 : : */
65 : : NFP_XSTAT_NET("rx_good_packets_mc", RX_MC_FRAMES),
66 : : NFP_XSTAT_NET("tx_good_packets_mc", TX_MC_FRAMES),
67 : : NFP_XSTAT_NET("rx_good_packets_bc", RX_BC_FRAMES),
68 : : NFP_XSTAT_NET("tx_good_packets_bc", TX_BC_FRAMES),
69 : : NFP_XSTAT_NET("rx_good_bytes_uc", RX_UC_OCTETS),
70 : : NFP_XSTAT_NET("tx_good_bytes_uc", TX_UC_OCTETS),
71 : : NFP_XSTAT_NET("rx_good_bytes_mc", RX_MC_OCTETS),
72 : : NFP_XSTAT_NET("tx_good_bytes_mc", TX_MC_OCTETS),
73 : : NFP_XSTAT_NET("rx_good_bytes_bc", RX_BC_OCTETS),
74 : : NFP_XSTAT_NET("tx_good_bytes_bc", TX_BC_OCTETS),
75 : : NFP_XSTAT_NET("tx_missed_erros", TX_DISCARDS),
76 : : NFP_XSTAT_NET("bpf_pass_pkts", APP0_FRAMES),
77 : : NFP_XSTAT_NET("bpf_pass_bytes", APP0_BYTES),
78 : : NFP_XSTAT_NET("bpf_app1_pkts", APP1_FRAMES),
79 : : NFP_XSTAT_NET("bpf_app1_bytes", APP1_BYTES),
80 : : NFP_XSTAT_NET("bpf_app2_pkts", APP2_FRAMES),
81 : : NFP_XSTAT_NET("bpf_app2_bytes", APP2_BYTES),
82 : : NFP_XSTAT_NET("bpf_app3_pkts", APP3_FRAMES),
83 : : NFP_XSTAT_NET("bpf_app3_bytes", APP3_BYTES),
84 : : /*
85 : : * MAC xstats available only on PF. These statistics are not available for VFs as the
86 : : * PF is not initialized when the VF is initialized as it is still bound to the kernel
87 : : * driver. As such, the PMD cannot obtain a CPP handle and access the rtsym_table in order
88 : : * to get the pointer to the start of the MAC statistics counters.
89 : : */
90 : : NFP_XSTAT_MAC("mac.rx_octets", RX_IN_OCTS),
91 : : NFP_XSTAT_MAC("mac.rx_frame_too_long_errors", RX_FRAME_TOO_LONG_ERRORS),
92 : : NFP_XSTAT_MAC("mac.rx_range_length_errors", RX_RANGE_LENGTH_ERRORS),
93 : : NFP_XSTAT_MAC("mac.rx_vlan_received_ok", RX_VLAN_RECEIVED_OK),
94 : : NFP_XSTAT_MAC("mac.rx_errors", RX_IN_ERRORS),
95 : : NFP_XSTAT_MAC("mac.rx_broadcast_pkts", RX_IN_BROADCAST_PKTS),
96 : : NFP_XSTAT_MAC("mac.rx_drop_events", RX_DROP_EVENTS),
97 : : NFP_XSTAT_MAC("mac.rx_alignment_errors", RX_ALIGNMENT_ERRORS),
98 : : NFP_XSTAT_MAC("mac.rx_pause_mac_ctrl_frames", RX_PAUSE_MAC_CTRL_FRAMES),
99 : : NFP_XSTAT_MAC("mac.rx_frames_received_ok", RX_FRAMES_RECEIVED_OK),
100 : : NFP_XSTAT_MAC("mac.rx_frame_check_sequence_errors", RX_FRAME_CHECK_SEQ_ERRORS),
101 : : NFP_XSTAT_MAC("mac.rx_unicast_pkts", RX_UNICAST_PKTS),
102 : : NFP_XSTAT_MAC("mac.rx_multicast_pkts", RX_MULTICAST_PKTS),
103 : : NFP_XSTAT_MAC("mac.rx_pkts", RX_PKTS),
104 : : NFP_XSTAT_MAC("mac.rx_undersize_pkts", RX_UNDERSIZE_PKTS),
105 : : NFP_XSTAT_MAC("mac.rx_pkts_64_octets", RX_PKTS_64_OCTS),
106 : : NFP_XSTAT_MAC("mac.rx_pkts_65_to_127_octets", RX_PKTS_65_TO_127_OCTS),
107 : : NFP_XSTAT_MAC("mac.rx_pkts_128_to_255_octets", RX_PKTS_128_TO_255_OCTS),
108 : : NFP_XSTAT_MAC("mac.rx_pkts_256_to_511_octets", RX_PKTS_256_TO_511_OCTS),
109 : : NFP_XSTAT_MAC("mac.rx_pkts_512_to_1023_octets", RX_PKTS_512_TO_1023_OCTS),
110 : : NFP_XSTAT_MAC("mac.rx_pkts_1024_to_1518_octets", RX_PKTS_1024_TO_1518_OCTS),
111 : : NFP_XSTAT_MAC("mac.rx_pkts_1519_to_max_octets", RX_PKTS_1519_TO_MAX_OCTS),
112 : : NFP_XSTAT_MAC("mac.rx_jabbers", RX_JABBERS),
113 : : NFP_XSTAT_MAC("mac.rx_fragments", RX_FRAGMENTS),
114 : : NFP_XSTAT_MAC("mac.rx_oversize_pkts", RX_OVERSIZE_PKTS),
115 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class0", RX_PAUSE_FRAMES_CLASS0),
116 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class1", RX_PAUSE_FRAMES_CLASS1),
117 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class2", RX_PAUSE_FRAMES_CLASS2),
118 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class3", RX_PAUSE_FRAMES_CLASS3),
119 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class4", RX_PAUSE_FRAMES_CLASS4),
120 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class5", RX_PAUSE_FRAMES_CLASS5),
121 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class6", RX_PAUSE_FRAMES_CLASS6),
122 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class7", RX_PAUSE_FRAMES_CLASS7),
123 : : NFP_XSTAT_MAC("mac.rx_mac_ctrl_frames_received", RX_MAC_CTRL_FRAMES_REC),
124 : : NFP_XSTAT_MAC("mac.rx_mac_head_drop", RX_MAC_HEAD_DROP),
125 : : NFP_XSTAT_MAC("mac.tx_queue_drop", TX_QUEUE_DROP),
126 : : NFP_XSTAT_MAC("mac.tx_octets", TX_OUT_OCTS),
127 : : NFP_XSTAT_MAC("mac.tx_vlan_transmitted_ok", TX_VLAN_TRANSMITTED_OK),
128 : : NFP_XSTAT_MAC("mac.tx_errors", TX_OUT_ERRORS),
129 : : NFP_XSTAT_MAC("mac.tx_broadcast_pkts", TX_BROADCAST_PKTS),
130 : : NFP_XSTAT_MAC("mac.tx_pause_mac_ctrl_frames", TX_PAUSE_MAC_CTRL_FRAMES),
131 : : NFP_XSTAT_MAC("mac.tx_frames_transmitted_ok", TX_FRAMES_TRANSMITTED_OK),
132 : : NFP_XSTAT_MAC("mac.tx_unicast_pkts", TX_UNICAST_PKTS),
133 : : NFP_XSTAT_MAC("mac.tx_multicast_pkts", TX_MULTICAST_PKTS),
134 : : NFP_XSTAT_MAC("mac.tx_pkts_64_octets", TX_PKTS_64_OCTS),
135 : : NFP_XSTAT_MAC("mac.tx_pkts_65_to_127_octets", TX_PKTS_65_TO_127_OCTS),
136 : : NFP_XSTAT_MAC("mac.tx_pkts_128_to_255_octets", TX_PKTS_128_TO_255_OCTS),
137 : : NFP_XSTAT_MAC("mac.tx_pkts_256_to_511_octets", TX_PKTS_256_TO_511_OCTS),
138 : : NFP_XSTAT_MAC("mac.tx_pkts_512_to_1023_octets", TX_PKTS_512_TO_1023_OCTS),
139 : : NFP_XSTAT_MAC("mac.tx_pkts_1024_to_1518_octets", TX_PKTS_1024_TO_1518_OCTS),
140 : : NFP_XSTAT_MAC("mac.tx_pkts_1519_to_max_octets", TX_PKTS_1519_TO_MAX_OCTS),
141 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class0", TX_PAUSE_FRAMES_CLASS0),
142 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class1", TX_PAUSE_FRAMES_CLASS1),
143 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class2", TX_PAUSE_FRAMES_CLASS2),
144 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class3", TX_PAUSE_FRAMES_CLASS3),
145 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class4", TX_PAUSE_FRAMES_CLASS4),
146 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class5", TX_PAUSE_FRAMES_CLASS5),
147 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class6", TX_PAUSE_FRAMES_CLASS6),
148 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class7", TX_PAUSE_FRAMES_CLASS7),
149 : : };
150 : :
151 : : static const uint32_t nfp_net_link_speed_nfp2rte[] = {
152 : : [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = RTE_ETH_SPEED_NUM_NONE,
153 : : [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = RTE_ETH_SPEED_NUM_NONE,
154 : : [NFP_NET_CFG_STS_LINK_RATE_1G] = RTE_ETH_SPEED_NUM_1G,
155 : : [NFP_NET_CFG_STS_LINK_RATE_10G] = RTE_ETH_SPEED_NUM_10G,
156 : : [NFP_NET_CFG_STS_LINK_RATE_25G] = RTE_ETH_SPEED_NUM_25G,
157 : : [NFP_NET_CFG_STS_LINK_RATE_40G] = RTE_ETH_SPEED_NUM_40G,
158 : : [NFP_NET_CFG_STS_LINK_RATE_50G] = RTE_ETH_SPEED_NUM_50G,
159 : : [NFP_NET_CFG_STS_LINK_RATE_100G] = RTE_ETH_SPEED_NUM_100G,
160 : : };
161 : :
162 : : static bool
163 : : nfp_net_is_pf(struct rte_eth_dev *dev)
164 : : {
165 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev))
166 : 0 : return nfp_flower_repr_is_pf(dev);
167 : :
168 : 0 : return ((struct nfp_net_hw_priv *)dev->process_private)->is_pf;
169 : : }
170 : :
171 : : static size_t
172 : : nfp_net_link_speed_rte2nfp(uint32_t speed)
173 : : {
174 : : size_t i;
175 : :
176 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nfp_net_link_speed_nfp2rte); i++) {
177 [ # # ]: 0 : if (speed == nfp_net_link_speed_nfp2rte[i])
178 : : return i;
179 : : }
180 : :
181 : : return NFP_NET_CFG_STS_LINK_RATE_UNKNOWN;
182 : : }
183 : :
184 : : static uint32_t
185 : : nfp_net_link_speed_nfp2rte_check(uint32_t speed)
186 : : {
187 : : size_t i;
188 : :
189 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nfp_net_link_speed_nfp2rte); i++) {
190 [ # # ]: 0 : if (speed == nfp_net_link_speed_nfp2rte[i])
191 : : return nfp_net_link_speed_nfp2rte[i];
192 : : }
193 : :
194 : : return RTE_ETH_SPEED_NUM_NONE;
195 : : }
196 : :
197 : : void
198 : 0 : nfp_net_notify_port_speed(struct nfp_net_hw *hw,
199 : : struct rte_eth_link *link)
200 : : {
201 : : /*
202 : : * Read the link status from NFP_NET_CFG_STS. If the link is down
203 : : * then write the link speed NFP_NET_CFG_STS_LINK_RATE_UNKNOWN to
204 : : * NFP_NET_CFG_STS_NSP_LINK_RATE.
205 : : */
206 [ # # ]: 0 : if (link->link_status == RTE_ETH_LINK_DOWN) {
207 : : nn_cfg_writew(&hw->super, NFP_NET_CFG_STS_NSP_LINK_RATE,
208 : : NFP_NET_CFG_STS_LINK_RATE_UNKNOWN);
209 : 0 : return;
210 : : }
211 : :
212 : : /*
213 : : * Link is up so write the link speed from the eth_table to
214 : : * NFP_NET_CFG_STS_NSP_LINK_RATE.
215 : : */
216 : 0 : nn_cfg_writew(&hw->super, NFP_NET_CFG_STS_NSP_LINK_RATE,
217 : 0 : nfp_net_link_speed_rte2nfp(link->link_speed));
218 : : }
219 : :
220 : : /**
221 : : * Reconfigure the firmware of VF configure
222 : : *
223 : : * @param net_hw
224 : : * Device to reconfigure
225 : : * @param pf_dev
226 : : * Get the Device info
227 : : * @param update
228 : : * The value for the mailbox VF command
229 : : * @param value
230 : : * The value of update
231 : : * @param offset
232 : : * The offset in the VF configure table
233 : : *
234 : : * @return
235 : : * - (0) if OK to reconfigure vf configure.
236 : : * - (-EIO) if I/O err and fail to configure the vf configure
237 : : */
238 : : static int
239 : 0 : nfp_net_vf_reconfig(struct nfp_net_hw *net_hw,
240 : : struct nfp_pf_dev *pf_dev,
241 : : uint16_t update,
242 : : uint8_t value,
243 : : uint32_t offset)
244 : : {
245 : : int ret;
246 : : struct nfp_hw *hw;
247 : :
248 : 0 : hw = &net_hw->super;
249 : 0 : rte_spinlock_lock(&hw->reconfig_lock);
250 : :
251 : : /* Write update info to mailbox in VF config symbol */
252 : 0 : nn_writeb(value, pf_dev->vf_cfg_tbl_bar + offset);
253 : 0 : nn_writew(update, pf_dev->vf_cfg_tbl_bar + NFP_NET_VF_CFG_MB_UPD);
254 : : nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, NFP_NET_CFG_UPDATE_VF);
255 : :
256 : : rte_wmb();
257 : :
258 : 0 : ret = nfp_reconfig_real(hw, NFP_NET_CFG_UPDATE_VF);
259 : :
260 : : rte_spinlock_unlock(&hw->reconfig_lock);
261 : :
262 [ # # ]: 0 : if (ret != 0)
263 : : return -EIO;
264 : :
265 : 0 : return nn_readw(pf_dev->vf_cfg_tbl_bar + NFP_NET_VF_CFG_MB_RET);
266 : : }
267 : :
268 : : /**
269 : : * Reconfigure the firmware via the mailbox
270 : : *
271 : : * @param net_hw
272 : : * Device to reconfigure
273 : : * @param mbox_cmd
274 : : * The value for the mailbox command
275 : : *
276 : : * @return
277 : : * - (0) if OK to reconfigure by the mailbox.
278 : : * - (-EIO) if I/O err and fail to reconfigure by the mailbox
279 : : */
280 : : int
281 : 0 : nfp_net_mbox_reconfig(struct nfp_net_hw *net_hw,
282 : : uint32_t mbox_cmd)
283 : : {
284 : : int ret;
285 : : uint32_t mbox;
286 : :
287 : 0 : mbox = net_hw->tlv_caps.mbox_off;
288 : :
289 : 0 : rte_spinlock_lock(&net_hw->super.reconfig_lock);
290 : :
291 : : nn_cfg_writeq(&net_hw->super, mbox + NFP_NET_CFG_MBOX_SIMPLE_CMD, mbox_cmd);
292 : : nn_cfg_writel(&net_hw->super, NFP_NET_CFG_UPDATE, NFP_NET_CFG_UPDATE_MBOX);
293 : :
294 : : rte_wmb();
295 : :
296 : 0 : ret = nfp_reconfig_real(&net_hw->super, NFP_NET_CFG_UPDATE_MBOX);
297 : :
298 : : rte_spinlock_unlock(&net_hw->super.reconfig_lock);
299 : :
300 [ # # ]: 0 : if (ret != 0) {
301 : 0 : PMD_DRV_LOG(ERR, "Error nft net mailbox reconfig: mbox=%#08x update=%#08x.",
302 : : mbox_cmd, NFP_NET_CFG_UPDATE_MBOX);
303 : 0 : return -EIO;
304 : : }
305 : :
306 : 0 : return nn_cfg_readl(&net_hw->super, mbox + NFP_NET_CFG_MBOX_SIMPLE_RET);
307 : : }
308 : :
309 : : struct nfp_net_hw *
310 [ # # ]: 0 : nfp_net_get_hw(const struct rte_eth_dev *dev)
311 : : {
312 : : struct nfp_net_hw *hw;
313 : :
314 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev)) {
315 : : struct nfp_flower_representor *repr;
316 : 0 : repr = dev->data->dev_private;
317 : 0 : hw = repr->app_fw_flower->pf_hw;
318 : : } else {
319 : 0 : hw = dev->data->dev_private;
320 : : }
321 : :
322 : 0 : return hw;
323 : : }
324 : :
325 : : uint8_t
326 [ # # ]: 0 : nfp_net_get_idx(const struct rte_eth_dev *dev)
327 : : {
328 : : uint8_t idx;
329 : :
330 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev)) {
331 : : struct nfp_flower_representor *repr;
332 : 0 : repr = dev->data->dev_private;
333 : 0 : idx = repr->idx;
334 : : } else {
335 : : struct nfp_net_hw *hw;
336 : 0 : hw = dev->data->dev_private;
337 : 0 : idx = hw->idx;
338 : : }
339 : :
340 : 0 : return idx;
341 : : }
342 : :
343 : : /*
344 : : * Configure an Ethernet device.
345 : : *
346 : : * This function must be invoked first before any other function in the Ethernet API.
347 : : * This function can also be re-invoked when a device is in the stopped state.
348 : : *
349 : : * A DPDK app sends info about how many queues to use and how those queues
350 : : * need to be configured. This is used by the DPDK core and it makes sure no
351 : : * more queues than those advertised by the driver are requested.
352 : : * This function is called after that internal process.
353 : : */
354 : : int
355 : 0 : nfp_net_configure(struct rte_eth_dev *dev)
356 : : {
357 : : struct nfp_net_hw *hw;
358 : : struct rte_eth_conf *dev_conf;
359 : : struct rte_eth_rxmode *rxmode;
360 : : struct rte_eth_txmode *txmode;
361 : :
362 : 0 : hw = nfp_net_get_hw(dev);
363 : 0 : dev_conf = &dev->data->dev_conf;
364 : : rxmode = &dev_conf->rxmode;
365 : : txmode = &dev_conf->txmode;
366 : :
367 [ # # ]: 0 : if ((rxmode->mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) != 0)
368 : 0 : rxmode->offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
369 : :
370 : : /* Checking TX mode */
371 [ # # ]: 0 : if (txmode->mq_mode != RTE_ETH_MQ_TX_NONE) {
372 : 0 : PMD_DRV_LOG(ERR, "TX mq_mode DCB and VMDq not supported.");
373 : 0 : return -EINVAL;
374 : : }
375 : :
376 : : /* Checking RX mode */
377 [ # # ]: 0 : if ((rxmode->mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) != 0 &&
378 [ # # ]: 0 : (hw->super.cap & NFP_NET_CFG_CTRL_RSS_ANY) == 0) {
379 : 0 : PMD_DRV_LOG(ERR, "RSS not supported.");
380 : 0 : return -EINVAL;
381 : : }
382 : :
383 : : /* Checking MTU set */
384 [ # # ]: 0 : if (rxmode->mtu > hw->max_mtu + NFP_ETH_OVERHEAD) {
385 : 0 : PMD_DRV_LOG(ERR, "MTU (%u) larger than the maximum possible frame size (%u).",
386 : : rxmode->mtu, hw->max_mtu + NFP_ETH_OVERHEAD);
387 : 0 : return -ERANGE;
388 : : }
389 : :
390 : : return 0;
391 : : }
392 : :
393 : : void
394 : 0 : nfp_net_log_device_information(const struct nfp_net_hw *hw,
395 : : struct nfp_pf_dev *pf_dev)
396 : : {
397 : 0 : uint32_t cap = hw->super.cap;
398 : 0 : uint32_t cap_ext = hw->super.cap_ext;
399 : 0 : uint32_t cap_rss = hw->super.cap_rss;
400 : :
401 : 0 : PMD_INIT_LOG(INFO, "VER: %u.%u, Maximum supported MTU: %d.",
402 : : pf_dev->ver.major, pf_dev->ver.minor, hw->max_mtu);
403 : :
404 : 0 : PMD_INIT_LOG(INFO, "CAP: %#x.", cap);
405 [ # # # # : 0 : PMD_INIT_LOG(INFO, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
406 : : cap & NFP_NET_CFG_CTRL_ENABLE ? "ENABLE " : "",
407 : : cap & NFP_NET_CFG_CTRL_PROMISC ? "PROMISC " : "",
408 : : cap & NFP_NET_CFG_CTRL_L2BC ? "L2BCFILT " : "",
409 : : cap & NFP_NET_CFG_CTRL_L2MC ? "L2MCFILT " : "",
410 : : cap & NFP_NET_CFG_CTRL_RXCSUM ? "RXCSUM " : "",
411 : : cap & NFP_NET_CFG_CTRL_TXCSUM ? "TXCSUM " : "",
412 : : cap & NFP_NET_CFG_CTRL_RXVLAN ? "RXVLAN " : "",
413 : : cap & NFP_NET_CFG_CTRL_TXVLAN ? "TXVLAN " : "",
414 : : cap & NFP_NET_CFG_CTRL_SCATTER ? "SCATTER " : "",
415 : : cap & NFP_NET_CFG_CTRL_GATHER ? "GATHER " : "",
416 : : cap & NFP_NET_CFG_CTRL_LSO ? "TSO " : "",
417 : : cap & NFP_NET_CFG_CTRL_RXQINQ ? "RXQINQ " : "",
418 : : cap & NFP_NET_CFG_CTRL_RXVLAN_V2 ? "RXVLANv2 " : "",
419 : : cap & NFP_NET_CFG_CTRL_RINGCFG ? "RINGCFG " : "",
420 : : cap & NFP_NET_CFG_CTRL_RSS ? "RSS " : "",
421 : : cap & NFP_NET_CFG_CTRL_IRQMOD ? "IRQMOD " : "",
422 : : cap & NFP_NET_CFG_CTRL_RINGPRIO ? "RINGPRIO " : "",
423 : : cap & NFP_NET_CFG_CTRL_MSIXAUTO ? "MSIXAUTO " : "",
424 : : cap & NFP_NET_CFG_CTRL_TXRWB ? "TXRWB " : "",
425 : : cap & NFP_NET_CFG_CTRL_L2SWITCH ? "L2SWITCH " : "",
426 : : cap & NFP_NET_CFG_CTRL_TXVLAN_V2 ? "TXVLANv2 " : "",
427 : : cap & NFP_NET_CFG_CTRL_VXLAN ? "VXLAN " : "",
428 : : cap & NFP_NET_CFG_CTRL_NVGRE ? "NVGRE " : "",
429 : : cap & NFP_NET_CFG_CTRL_MSIX_TX_OFF ? "MSIX_TX_OFF " : "",
430 : : cap & NFP_NET_CFG_CTRL_LSO2 ? "TSOv2 " : "",
431 : : cap & NFP_NET_CFG_CTRL_RSS2 ? "RSSv2 " : "",
432 : : cap & NFP_NET_CFG_CTRL_CSUM_COMPLETE ? "CSUM " : "",
433 : : cap & NFP_NET_CFG_CTRL_LIVE_ADDR ? "LIVE_ADDR " : "",
434 : : cap & NFP_NET_CFG_CTRL_USO ? "USO" : "");
435 : :
436 : 0 : PMD_INIT_LOG(INFO, "CAP_WORD1: %#x.", cap_ext);
437 [ # # # # : 0 : PMD_INIT_LOG(INFO, "%s%s%s%s%s%s%s",
# # # # #
# # # #
# ]
438 : : cap_ext & NFP_NET_CFG_CTRL_PKT_TYPE ? "PKT_TYPE " : "",
439 : : cap_ext & NFP_NET_CFG_CTRL_IPSEC ? "IPSEC " : "",
440 : : cap_ext & NFP_NET_CFG_CTRL_IPSEC_SM_LOOKUP ? "IPSEC_SM " : "",
441 : : cap_ext & NFP_NET_CFG_CTRL_IPSEC_LM_LOOKUP ? "IPSEC_LM " : "",
442 : : cap_ext & NFP_NET_CFG_CTRL_MULTI_PF ? "MULTI_PF " : "",
443 : : cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER ? "FLOW_STEER " : "",
444 : : cap_ext & NFP_NET_CFG_CTRL_IN_ORDER ? "VIRTIO_IN_ORDER " : "");
445 : :
446 : 0 : PMD_INIT_LOG(INFO, "CAP_RSS: %#x.", cap_rss);
447 [ # # # # : 0 : PMD_INIT_LOG(INFO, "%s%s%s",
# # ]
448 : : cap_rss & NFP_NET_CFG_RSS_TOEPLITZ ? "RSS_TOEPLITZ " : "",
449 : : cap_rss & NFP_NET_CFG_RSS_XOR ? "RSS_XOR " : "",
450 : : cap_rss & NFP_NET_CFG_RSS_CRC32 ? "RSS_CRC32 " : "");
451 : :
452 : 0 : PMD_INIT_LOG(INFO, "The max_rx_queues: %u, max_tx_queues: %u.",
453 : : hw->max_rx_queues, hw->max_tx_queues);
454 : 0 : }
455 : :
456 : : static inline void
457 : : nfp_net_enable_rxvlan_cap(struct nfp_net_hw *hw,
458 : : uint32_t *ctrl)
459 : : {
460 [ # # # # ]: 0 : if ((hw->super.cap & NFP_NET_CFG_CTRL_RXVLAN_V2) != 0)
461 : 0 : *ctrl |= NFP_NET_CFG_CTRL_RXVLAN_V2;
462 [ # # # # ]: 0 : else if ((hw->super.cap & NFP_NET_CFG_CTRL_RXVLAN) != 0)
463 : 0 : *ctrl |= NFP_NET_CFG_CTRL_RXVLAN;
464 : : }
465 : :
466 : : void
467 : 0 : nfp_net_enable_queues(struct rte_eth_dev *dev)
468 : : {
469 : : struct nfp_net_hw *hw;
470 : :
471 : 0 : hw = nfp_net_get_hw(dev);
472 : :
473 : 0 : nfp_enable_queues(&hw->super, dev->data->nb_rx_queues,
474 : 0 : dev->data->nb_tx_queues);
475 : 0 : }
476 : :
477 : : void
478 : 0 : nfp_net_disable_queues(struct rte_eth_dev *dev)
479 : : {
480 : : struct nfp_net_hw *net_hw;
481 : :
482 : 0 : net_hw = nfp_net_get_hw(dev);
483 : :
484 : 0 : nfp_disable_queues(&net_hw->super);
485 : 0 : }
486 : :
487 : : void
488 : 0 : nfp_net_params_setup(struct nfp_net_hw *hw)
489 : : {
490 : 0 : nn_cfg_writel(&hw->super, NFP_NET_CFG_MTU, hw->mtu);
491 : 0 : nn_cfg_writel(&hw->super, NFP_NET_CFG_FLBUFSZ, hw->flbufsz);
492 : 0 : }
493 : :
494 : : void
495 : 0 : nfp_net_cfg_queue_setup(struct nfp_net_hw *hw)
496 : : {
497 : 0 : hw->super.qcp_cfg = hw->tx_bar + NFP_QCP_QUEUE_ADDR_SZ;
498 : 0 : }
499 : :
500 : : int
501 : 0 : nfp_net_set_mac_addr(struct rte_eth_dev *dev,
502 : : struct rte_ether_addr *mac_addr)
503 : : {
504 : : uint32_t update;
505 : : uint32_t new_ctrl;
506 : : struct nfp_hw *hw;
507 : : struct nfp_net_hw *net_hw;
508 : :
509 : 0 : net_hw = nfp_net_get_hw(dev);
510 : 0 : hw = &net_hw->super;
511 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) != 0 &&
512 [ # # ]: 0 : (hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR) == 0) {
513 : 0 : PMD_DRV_LOG(ERR, "MAC address unable to change when port enabled.");
514 : 0 : return -EBUSY;
515 : : }
516 : :
517 : : if (rte_is_valid_assigned_ether_addr(mac_addr) == 0) {
518 : 0 : PMD_DRV_LOG(ERR, "Invalid MAC address.");
519 : 0 : return -EINVAL;
520 : : }
521 : :
522 : : /* Writing new MAC to the specific port BAR address */
523 : 0 : nfp_write_mac(hw, (uint8_t *)mac_addr);
524 : :
525 : : update = NFP_NET_CFG_UPDATE_MACADDR;
526 : 0 : new_ctrl = hw->ctrl;
527 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) != 0 &&
528 [ # # ]: 0 : (hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR) != 0)
529 : 0 : new_ctrl |= NFP_NET_CFG_CTRL_LIVE_ADDR;
530 : :
531 : : /* Signal the NIC about the change */
532 [ # # ]: 0 : if (nfp_reconfig(hw, new_ctrl, update) != 0) {
533 : 0 : PMD_DRV_LOG(ERR, "MAC address update failed.");
534 : 0 : return -EIO;
535 : : }
536 : :
537 : 0 : hw->ctrl = new_ctrl;
538 : :
539 : 0 : return 0;
540 : : }
541 : :
542 : : int
543 : 0 : nfp_configure_rx_interrupt(struct rte_eth_dev *dev,
544 : : struct rte_intr_handle *intr_handle)
545 : : {
546 : : uint16_t i;
547 : : struct nfp_net_hw *hw;
548 : :
549 [ # # ]: 0 : if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
550 : 0 : dev->data->nb_rx_queues) != 0) {
551 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues intr_vec.",
552 : : dev->data->nb_rx_queues);
553 : 0 : return -ENOMEM;
554 : : }
555 : :
556 : 0 : hw = nfp_net_get_hw(dev);
557 : :
558 [ # # ]: 0 : if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_UIO) {
559 : 0 : PMD_DRV_LOG(INFO, "VF: enabling RX interrupt with UIO.");
560 : : /* UIO just supports one queue and no LSC */
561 : : nn_cfg_writeb(&hw->super, NFP_NET_CFG_RXR_VEC(0), 0);
562 [ # # ]: 0 : if (rte_intr_vec_list_index_set(intr_handle, 0, 0) != 0)
563 : : return -1;
564 : : } else {
565 : 0 : PMD_DRV_LOG(INFO, "VF: enabling RX interrupt with VFIO.");
566 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
567 : : /*
568 : : * The first msix vector is reserved for non
569 : : * efd interrupts.
570 : : */
571 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_RXR_VEC(i), i + 1);
572 [ # # ]: 0 : if (rte_intr_vec_list_index_set(intr_handle, i, i + 1) != 0)
573 : : return -1;
574 : : }
575 : : }
576 : :
577 : : /* Avoiding TX interrupts */
578 : 0 : hw->super.ctrl |= NFP_NET_CFG_CTRL_MSIX_TX_OFF;
579 : 0 : return 0;
580 : : }
581 : :
582 : : uint32_t
583 : 0 : nfp_check_offloads(struct rte_eth_dev *dev)
584 : : {
585 : : uint32_t cap;
586 : : uint32_t ctrl = 0;
587 : : uint64_t rx_offload;
588 : : uint64_t tx_offload;
589 : : struct nfp_net_hw *hw;
590 : : struct rte_eth_conf *dev_conf;
591 : :
592 : 0 : hw = nfp_net_get_hw(dev);
593 : 0 : cap = hw->super.cap;
594 : :
595 : 0 : dev_conf = &dev->data->dev_conf;
596 : 0 : rx_offload = dev_conf->rxmode.offloads;
597 : 0 : tx_offload = dev_conf->txmode.offloads;
598 : :
599 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) != 0) {
600 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXCSUM) != 0)
601 : : ctrl |= NFP_NET_CFG_CTRL_RXCSUM;
602 : : }
603 : :
604 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) != 0)
605 : : nfp_net_enable_rxvlan_cap(hw, &ctrl);
606 : :
607 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) != 0) {
608 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXQINQ) != 0)
609 : 0 : ctrl |= NFP_NET_CFG_CTRL_RXQINQ;
610 : : }
611 : :
612 : 0 : hw->mtu = dev->data->mtu;
613 : :
614 [ # # ]: 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) != 0) {
615 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_TXVLAN_V2) != 0)
616 : 0 : ctrl |= NFP_NET_CFG_CTRL_TXVLAN_V2;
617 [ # # ]: 0 : else if ((cap & NFP_NET_CFG_CTRL_TXVLAN) != 0)
618 : 0 : ctrl |= NFP_NET_CFG_CTRL_TXVLAN;
619 : : }
620 : :
621 : : /* L2 broadcast */
622 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_L2BC) != 0)
623 : 0 : ctrl |= NFP_NET_CFG_CTRL_L2BC;
624 : :
625 : : /* L2 multicast */
626 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_L2MC) != 0)
627 : 0 : ctrl |= NFP_NET_CFG_CTRL_L2MC;
628 : :
629 : : /* TX checksum offload */
630 : 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) != 0 ||
631 [ # # ]: 0 : (tx_offload & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) != 0 ||
632 : : (tx_offload & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) != 0)
633 : 0 : ctrl |= NFP_NET_CFG_CTRL_TXCSUM;
634 : :
635 : : /* LSO offload */
636 : 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_TCP_TSO) != 0 ||
637 [ # # ]: 0 : (tx_offload & RTE_ETH_TX_OFFLOAD_UDP_TSO) != 0 ||
638 : : (tx_offload & RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO) != 0) {
639 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_LSO) != 0)
640 : 0 : ctrl |= NFP_NET_CFG_CTRL_LSO;
641 [ # # ]: 0 : else if ((cap & NFP_NET_CFG_CTRL_LSO2) != 0)
642 : 0 : ctrl |= NFP_NET_CFG_CTRL_LSO2;
643 : : }
644 : :
645 : : /* RX gather */
646 [ # # ]: 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_MULTI_SEGS) != 0)
647 : 0 : ctrl |= NFP_NET_CFG_CTRL_GATHER;
648 : :
649 : 0 : return ctrl;
650 : : }
651 : :
652 : : int
653 : 0 : nfp_net_promisc_enable(struct rte_eth_dev *dev)
654 : : {
655 : : int ret;
656 : : uint32_t update;
657 : : uint32_t new_ctrl;
658 : : struct nfp_hw *hw;
659 : : struct nfp_net_hw *net_hw;
660 : :
661 : 0 : net_hw = nfp_net_get_hw(dev);
662 : :
663 : 0 : hw = &net_hw->super;
664 [ # # ]: 0 : if ((hw->cap & NFP_NET_CFG_CTRL_PROMISC) == 0) {
665 : 0 : PMD_DRV_LOG(ERR, "Promiscuous mode not supported.");
666 : 0 : return -ENOTSUP;
667 : : }
668 : :
669 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) != 0) {
670 : 0 : PMD_DRV_LOG(INFO, "Promiscuous mode already enabled.");
671 : 0 : return 0;
672 : : }
673 : :
674 : 0 : new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_PROMISC;
675 : : update = NFP_NET_CFG_UPDATE_GEN;
676 : :
677 : 0 : ret = nfp_reconfig(hw, new_ctrl, update);
678 [ # # ]: 0 : if (ret != 0)
679 : : return ret;
680 : :
681 : 0 : hw->ctrl = new_ctrl;
682 : :
683 : 0 : return 0;
684 : : }
685 : :
686 : : int
687 : 0 : nfp_net_promisc_disable(struct rte_eth_dev *dev)
688 : : {
689 : : int ret;
690 : : uint32_t update;
691 : : uint32_t new_ctrl;
692 : : struct nfp_hw *hw;
693 : : struct nfp_net_hw *net_hw;
694 : :
695 : 0 : net_hw = nfp_net_get_hw(dev);
696 : 0 : hw = &net_hw->super;
697 : :
698 [ # # ]: 0 : if ((hw->cap & NFP_NET_CFG_CTRL_PROMISC) == 0) {
699 : 0 : PMD_DRV_LOG(ERR, "Promiscuous mode not supported.");
700 : 0 : return -ENOTSUP;
701 : : }
702 : :
703 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) == 0) {
704 : 0 : PMD_DRV_LOG(INFO, "Promiscuous mode already disabled.");
705 : 0 : return 0;
706 : : }
707 : :
708 : 0 : new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC;
709 : : update = NFP_NET_CFG_UPDATE_GEN;
710 : :
711 : 0 : ret = nfp_reconfig(hw, new_ctrl, update);
712 [ # # ]: 0 : if (ret != 0)
713 : : return ret;
714 : :
715 : 0 : hw->ctrl = new_ctrl;
716 : :
717 : 0 : return 0;
718 : : }
719 : :
720 : : static int
721 : 0 : nfp_net_set_allmulticast_mode(struct rte_eth_dev *dev,
722 : : bool enable)
723 : : {
724 : : int ret;
725 : : uint32_t update;
726 : : struct nfp_hw *hw;
727 : : uint32_t cap_extend;
728 : : uint32_t ctrl_extend;
729 : : uint32_t new_ctrl_extend;
730 : : struct nfp_net_hw *net_hw;
731 : :
732 : 0 : net_hw = nfp_net_get_hw(dev);
733 : 0 : hw = &net_hw->super;
734 : :
735 : 0 : cap_extend = hw->cap_ext;
736 [ # # ]: 0 : if ((cap_extend & NFP_NET_CFG_CTRL_MCAST_FILTER) == 0) {
737 : 0 : PMD_DRV_LOG(DEBUG, "Allmulticast mode not supported.");
738 : 0 : return -ENOTSUP;
739 : : }
740 : :
741 : : /*
742 : : * Allmulticast mode enabled when NFP_NET_CFG_CTRL_MCAST_FILTER bit is 0.
743 : : * Allmulticast mode disabled when NFP_NET_CFG_CTRL_MCAST_FILTER bit is 1.
744 : : */
745 : 0 : ctrl_extend = hw->ctrl_ext;
746 [ # # ]: 0 : if (enable) {
747 [ # # ]: 0 : if ((ctrl_extend & NFP_NET_CFG_CTRL_MCAST_FILTER) == 0)
748 : : return 0;
749 : :
750 : 0 : new_ctrl_extend = ctrl_extend & ~NFP_NET_CFG_CTRL_MCAST_FILTER;
751 : : } else {
752 [ # # ]: 0 : if ((ctrl_extend & NFP_NET_CFG_CTRL_MCAST_FILTER) != 0)
753 : : return 0;
754 : :
755 : 0 : new_ctrl_extend = ctrl_extend | NFP_NET_CFG_CTRL_MCAST_FILTER;
756 : : }
757 : :
758 : : update = NFP_NET_CFG_UPDATE_GEN;
759 : :
760 : 0 : ret = nfp_ext_reconfig(hw, new_ctrl_extend, update);
761 [ # # ]: 0 : if (ret != 0)
762 : : return ret;
763 : :
764 : 0 : hw->ctrl_ext = new_ctrl_extend;
765 : 0 : return 0;
766 : : }
767 : :
768 : : int
769 : 0 : nfp_net_allmulticast_enable(struct rte_eth_dev *dev)
770 : : {
771 : 0 : return nfp_net_set_allmulticast_mode(dev, true);
772 : : }
773 : :
774 : : int
775 : 0 : nfp_net_allmulticast_disable(struct rte_eth_dev *dev)
776 : : {
777 : 0 : return nfp_net_set_allmulticast_mode(dev, false);
778 : : }
779 : :
780 : : static void
781 : 0 : nfp_net_pf_speed_update(struct rte_eth_dev *dev,
782 : : struct nfp_net_hw_priv *hw_priv,
783 : : struct rte_eth_link *link)
784 : : {
785 : : uint8_t idx;
786 : : enum nfp_eth_aneg aneg;
787 : : struct nfp_pf_dev *pf_dev;
788 : : struct nfp_eth_table *nfp_eth_table;
789 : : struct nfp_eth_table_port *eth_port;
790 : :
791 : 0 : pf_dev = hw_priv->pf_dev;
792 : 0 : idx = nfp_net_get_idx(dev);
793 : 0 : aneg = pf_dev->nfp_eth_table->ports[idx].aneg;
794 : :
795 : : /* Compare whether the current status has changed. */
796 [ # # # # ]: 0 : if (pf_dev->speed_updated || aneg == NFP_ANEG_AUTO) {
797 : 0 : nfp_eth_table = nfp_eth_read_ports(pf_dev->cpp);
798 [ # # ]: 0 : if (nfp_eth_table == NULL) {
799 : 0 : PMD_DRV_LOG(DEBUG, "Failed to get nfp_eth_table.");
800 : : } else {
801 : 0 : pf_dev->nfp_eth_table->ports[idx] = nfp_eth_table->ports[idx];
802 : 0 : free(nfp_eth_table);
803 : 0 : pf_dev->speed_updated = false;
804 : : }
805 : : }
806 : :
807 : 0 : nfp_eth_table = pf_dev->nfp_eth_table;
808 : : eth_port = &nfp_eth_table->ports[idx];
809 : :
810 : 0 : link->link_speed = nfp_net_link_speed_nfp2rte_check(eth_port->speed);
811 : :
812 [ # # ]: 0 : if (dev->data->dev_conf.link_speeds == RTE_ETH_LINK_SPEED_AUTONEG &&
813 [ # # ]: 0 : eth_port->supp_aneg)
814 : 0 : link->link_autoneg = RTE_ETH_LINK_AUTONEG;
815 : 0 : }
816 : :
817 : : static void
818 : : nfp_net_vf_speed_update(struct rte_eth_link *link,
819 : : uint32_t link_status)
820 : : {
821 : : size_t link_rate_index;
822 : :
823 : : /*
824 : : * Shift and mask link_status so that it is effectively the value
825 : : * at offset NFP_NET_CFG_STS_NSP_LINK_RATE.
826 : : */
827 : 0 : link_rate_index = (link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) &
828 : : NFP_NET_CFG_STS_LINK_RATE_MASK;
829 [ # # ]: 0 : if (link_rate_index < RTE_DIM(nfp_net_link_speed_nfp2rte))
830 : 0 : link->link_speed = nfp_net_link_speed_nfp2rte[link_rate_index];
831 : : else
832 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_NONE;
833 : : }
834 : :
835 : : int
836 : 0 : nfp_net_link_update_common(struct rte_eth_dev *dev,
837 : : struct rte_eth_link *link,
838 : : uint32_t link_status)
839 : : {
840 : : int ret;
841 : : struct nfp_net_hw_priv *hw_priv;
842 : :
843 : 0 : hw_priv = dev->process_private;
844 [ # # ]: 0 : if (link->link_status == RTE_ETH_LINK_UP) {
845 [ # # ]: 0 : if (nfp_net_is_pf(dev))
846 : 0 : nfp_net_pf_speed_update(dev, hw_priv, link);
847 : : else
848 : : nfp_net_vf_speed_update(link, link_status);
849 : : }
850 : :
851 : : ret = rte_eth_linkstatus_set(dev, link);
852 : : if (ret == 0) {
853 [ # # ]: 0 : if (link->link_status == RTE_ETH_LINK_UP)
854 : 0 : PMD_DRV_LOG(INFO, "NIC Link is Up.");
855 : : else
856 : 0 : PMD_DRV_LOG(INFO, "NIC Link is Down.");
857 : : }
858 : :
859 : 0 : return ret;
860 : : }
861 : :
862 : : /*
863 : : * Return 0 means link status changed, -1 means not changed
864 : : *
865 : : * Wait to complete is needed as it can take up to 9 seconds to get the Link
866 : : * status.
867 : : */
868 : : int
869 : 0 : nfp_net_link_update(struct rte_eth_dev *dev,
870 : : __rte_unused int wait_to_complete)
871 : : {
872 : : int ret;
873 : : struct nfp_net_hw *hw;
874 : : uint32_t nn_link_status;
875 : : struct rte_eth_link link;
876 : : struct nfp_net_hw_priv *hw_priv;
877 : :
878 : 0 : hw = nfp_net_get_hw(dev);
879 : 0 : hw_priv = dev->process_private;
880 : :
881 : : memset(&link, 0, sizeof(struct rte_eth_link));
882 : :
883 : : /* Read link status */
884 : 0 : nn_link_status = nn_cfg_readw(&hw->super, NFP_NET_CFG_STS);
885 [ # # ]: 0 : if ((nn_link_status & NFP_NET_CFG_STS_LINK) != 0)
886 : 0 : link.link_status = RTE_ETH_LINK_UP;
887 : :
888 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
889 : :
890 : 0 : ret = nfp_net_link_update_common(dev, &link, nn_link_status);
891 [ # # ]: 0 : if (ret == -EIO)
892 : : return ret;
893 : :
894 : : /*
895 : : * Notify the port to update the speed value in the CTRL BAR from NSP.
896 : : * Not applicable for VFs as the associated PF is still attached to the
897 : : * kernel driver.
898 : : */
899 [ # # # # ]: 0 : if (hw_priv != NULL && hw_priv->is_pf)
900 : 0 : nfp_net_notify_port_speed(hw, &link);
901 : :
902 : : return ret;
903 : : }
904 : :
905 : : int
906 : 0 : nfp_net_stats_get(struct rte_eth_dev *dev,
907 : : struct rte_eth_stats *stats, struct eth_queue_stats *qstats)
908 : : {
909 : : uint16_t i;
910 : : struct nfp_net_hw *hw;
911 : : struct rte_eth_stats nfp_dev_stats;
912 : :
913 [ # # ]: 0 : if (stats == NULL)
914 : : return -EINVAL;
915 : :
916 : 0 : hw = nfp_net_get_hw(dev);
917 : :
918 : : memset(&nfp_dev_stats, 0, sizeof(nfp_dev_stats));
919 : :
920 : : /* Reading per RX ring stats */
921 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
922 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
923 : : break;
924 : :
925 : 0 : uint64_t q_ipackets = nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i));
926 : 0 : q_ipackets -= hw->eth_qstats_base.q_ipackets[i];
927 : :
928 : 0 : uint64_t q_ibytes = nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i) + 0x8);
929 : 0 : q_ibytes -= hw->eth_qstats_base.q_ibytes[i];
930 : :
931 [ # # ]: 0 : if (qstats != NULL) {
932 : 0 : qstats->q_ipackets[i] = q_ipackets;
933 : 0 : qstats->q_ibytes[i] = q_ibytes;
934 : : }
935 : : }
936 : :
937 : : /* Reading per TX ring stats */
938 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
939 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
940 : : break;
941 : :
942 : 0 : uint64_t q_opackets = nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i));
943 : 0 : q_opackets -= hw->eth_qstats_base.q_opackets[i];
944 : :
945 : 0 : uint64_t q_obytes = nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i) + 0x8);
946 : 0 : q_obytes -= hw->eth_qstats_base.q_obytes[i];
947 : :
948 [ # # ]: 0 : if (qstats != NULL) {
949 : 0 : qstats->q_opackets[i] = q_opackets;
950 : 0 : qstats->q_obytes[i] = q_obytes;
951 : : }
952 : : }
953 : :
954 : : nfp_dev_stats.ipackets = nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_FRAMES);
955 : 0 : nfp_dev_stats.ipackets -= hw->eth_stats_base.ipackets;
956 : :
957 : : nfp_dev_stats.ibytes = nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_OCTETS);
958 : 0 : nfp_dev_stats.ibytes -= hw->eth_stats_base.ibytes;
959 : :
960 : : nfp_dev_stats.opackets =
961 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_FRAMES);
962 : 0 : nfp_dev_stats.opackets -= hw->eth_stats_base.opackets;
963 : :
964 : : nfp_dev_stats.obytes =
965 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_OCTETS);
966 : 0 : nfp_dev_stats.obytes -= hw->eth_stats_base.obytes;
967 : :
968 : : /* Reading general device stats */
969 : : nfp_dev_stats.ierrors =
970 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_ERRORS);
971 : 0 : nfp_dev_stats.ierrors -= hw->eth_stats_base.ierrors;
972 : :
973 : : nfp_dev_stats.oerrors =
974 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_ERRORS);
975 : 0 : nfp_dev_stats.oerrors -= hw->eth_stats_base.oerrors;
976 : :
977 : : /* RX ring mbuf allocation failures */
978 : 0 : nfp_dev_stats.rx_nombuf = dev->data->rx_mbuf_alloc_failed;
979 : :
980 : : nfp_dev_stats.imissed =
981 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_DISCARDS);
982 : 0 : nfp_dev_stats.imissed -= hw->eth_stats_base.imissed;
983 : :
984 : : memcpy(stats, &nfp_dev_stats, sizeof(*stats));
985 : 0 : return 0;
986 : : }
987 : :
988 : : /*
989 : : * hw->eth_stats_base and hw->eth_qstats_base record the per counter starting point.
990 : : * Let's update them now.
991 : : */
992 : : int
993 : 0 : nfp_net_stats_reset(struct rte_eth_dev *dev)
994 : : {
995 : : uint16_t i;
996 : : struct nfp_net_hw *hw;
997 : :
998 : 0 : hw = nfp_net_get_hw(dev);
999 : :
1000 : : /* Reading per RX ring stats */
1001 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1002 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
1003 : : break;
1004 : :
1005 : 0 : hw->eth_qstats_base.q_ipackets[i] =
1006 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i));
1007 : :
1008 : 0 : hw->eth_qstats_base.q_ibytes[i] =
1009 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i) + 0x8);
1010 : : }
1011 : :
1012 : : /* Reading per TX ring stats */
1013 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1014 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
1015 : : break;
1016 : :
1017 : 0 : hw->eth_qstats_base.q_opackets[i] =
1018 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i));
1019 : :
1020 : 0 : hw->eth_qstats_base.q_obytes[i] =
1021 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i) + 0x8);
1022 : : }
1023 : :
1024 : 0 : hw->eth_stats_base.ipackets =
1025 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_FRAMES);
1026 : :
1027 : 0 : hw->eth_stats_base.ibytes =
1028 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_OCTETS);
1029 : :
1030 : 0 : hw->eth_stats_base.opackets =
1031 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_FRAMES);
1032 : :
1033 : 0 : hw->eth_stats_base.obytes =
1034 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_OCTETS);
1035 : :
1036 : : /* Reading general device stats */
1037 : 0 : hw->eth_stats_base.ierrors =
1038 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_ERRORS);
1039 : :
1040 : 0 : hw->eth_stats_base.oerrors =
1041 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_ERRORS);
1042 : :
1043 : : /* RX ring mbuf allocation failures */
1044 : 0 : dev->data->rx_mbuf_alloc_failed = 0;
1045 : :
1046 : 0 : hw->eth_stats_base.imissed =
1047 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_DISCARDS);
1048 : :
1049 : 0 : return 0;
1050 : : }
1051 : :
1052 : : uint32_t
1053 [ # # ]: 0 : nfp_net_xstats_size(const struct rte_eth_dev *dev)
1054 : : {
1055 : : uint32_t count;
1056 : : bool vf_flag = false;
1057 : : struct nfp_net_hw *hw;
1058 : : struct nfp_flower_representor *repr;
1059 : : const uint32_t size = RTE_DIM(nfp_net_xstats);
1060 : :
1061 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev)) {
1062 : 0 : repr = dev->data->dev_private;
1063 [ # # ]: 0 : if (nfp_flower_repr_is_vf(repr))
1064 : : vf_flag = true;
1065 : : } else {
1066 : 0 : hw = dev->data->dev_private;
1067 [ # # ]: 0 : if (hw->mac_stats == NULL)
1068 : : vf_flag = true;
1069 : : }
1070 : :
1071 : : /* If the device is a VF or VF-repr, then there will be no MAC stats */
1072 : : if (vf_flag) {
1073 [ # # ]: 0 : for (count = 0; count < size; count++) {
1074 [ # # ]: 0 : if (nfp_net_xstats[count].group == NFP_XSTAT_GROUP_MAC)
1075 : : break;
1076 : : }
1077 : :
1078 : 0 : return count;
1079 : : }
1080 : :
1081 : : return size;
1082 : : }
1083 : :
1084 : : static const struct nfp_xstat *
1085 : 0 : nfp_net_xstats_info(const struct rte_eth_dev *dev,
1086 : : uint32_t index)
1087 : : {
1088 [ # # ]: 0 : if (index >= nfp_net_xstats_size(dev)) {
1089 : 0 : PMD_DRV_LOG(ERR, "The xstat index out of bounds.");
1090 : 0 : return NULL;
1091 : : }
1092 : :
1093 : 0 : return &nfp_net_xstats[index];
1094 : : }
1095 : :
1096 : : static uint64_t
1097 [ # # ]: 0 : nfp_net_xstats_value(const struct rte_eth_dev *dev,
1098 : : uint32_t index,
1099 : : bool raw)
1100 : : {
1101 : : uint64_t value;
1102 : : uint8_t *mac_stats;
1103 : : struct nfp_net_hw *hw;
1104 : : struct nfp_xstat xstat;
1105 : : struct rte_eth_xstat *xstats_base;
1106 : : struct nfp_flower_representor *repr;
1107 : :
1108 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev)) {
1109 : 0 : repr = dev->data->dev_private;
1110 : 0 : hw = repr->app_fw_flower->pf_hw;
1111 : :
1112 : 0 : mac_stats = repr->mac_stats;
1113 : 0 : xstats_base = repr->repr_xstats_base;
1114 : : } else {
1115 : 0 : hw = dev->data->dev_private;
1116 : :
1117 : 0 : mac_stats = hw->mac_stats;
1118 : 0 : xstats_base = hw->eth_xstats_base;
1119 : : }
1120 : :
1121 : 0 : xstat = nfp_net_xstats[index];
1122 : :
1123 [ # # ]: 0 : if (xstat.group == NFP_XSTAT_GROUP_MAC)
1124 : 0 : value = nn_readq(mac_stats + xstat.offset);
1125 : : else
1126 : 0 : value = nn_cfg_readq(&hw->super, xstat.offset);
1127 : :
1128 [ # # ]: 0 : if (raw)
1129 : : return value;
1130 : :
1131 : : /*
1132 : : * A baseline value of each statistic counter is recorded when stats are "reset".
1133 : : * Thus, the value returned by this function need to be decremented by this
1134 : : * baseline value. The result is the count of this statistic since the last time
1135 : : * it was "reset".
1136 : : */
1137 : 0 : return value - xstats_base[index].value;
1138 : : }
1139 : :
1140 : : /* NOTE: All callers ensure dev is always set. */
1141 : : int
1142 : 0 : nfp_net_xstats_get_names(struct rte_eth_dev *dev,
1143 : : struct rte_eth_xstat_name *xstats_names,
1144 : : unsigned int size)
1145 : : {
1146 : : uint32_t id;
1147 : : uint32_t nfp_size;
1148 : : uint32_t read_size;
1149 : :
1150 : 0 : nfp_size = nfp_net_xstats_size(dev);
1151 : :
1152 [ # # ]: 0 : if (xstats_names == NULL)
1153 : 0 : return nfp_size;
1154 : :
1155 : : /* Read at most NFP xstats number of names. */
1156 : 0 : read_size = RTE_MIN(size, nfp_size);
1157 : :
1158 [ # # ]: 0 : for (id = 0; id < read_size; id++)
1159 : 0 : rte_strlcpy(xstats_names[id].name, nfp_net_xstats[id].name,
1160 : : RTE_ETH_XSTATS_NAME_SIZE);
1161 : :
1162 : 0 : return read_size;
1163 : : }
1164 : :
1165 : : /* NOTE: All callers ensure dev is always set. */
1166 : : int
1167 : 0 : nfp_net_xstats_get(struct rte_eth_dev *dev,
1168 : : struct rte_eth_xstat *xstats,
1169 : : unsigned int n)
1170 : : {
1171 : : uint32_t id;
1172 : : uint32_t nfp_size;
1173 : : uint32_t read_size;
1174 : :
1175 : 0 : nfp_size = nfp_net_xstats_size(dev);
1176 : :
1177 [ # # ]: 0 : if (xstats == NULL)
1178 : 0 : return nfp_size;
1179 : :
1180 : : /* Read at most NFP xstats number of values. */
1181 : 0 : read_size = RTE_MIN(n, nfp_size);
1182 : :
1183 [ # # ]: 0 : for (id = 0; id < read_size; id++) {
1184 : 0 : xstats[id].id = id;
1185 : 0 : xstats[id].value = nfp_net_xstats_value(dev, id, false);
1186 : : }
1187 : :
1188 : 0 : return read_size;
1189 : : }
1190 : :
1191 : : /*
1192 : : * NOTE: The only caller rte_eth_xstats_get_names_by_id() ensures dev,
1193 : : * ids, xstats_names and size are valid, and non-NULL.
1194 : : */
1195 : : int
1196 : 0 : nfp_net_xstats_get_names_by_id(struct rte_eth_dev *dev,
1197 : : const uint64_t *ids,
1198 : : struct rte_eth_xstat_name *xstats_names,
1199 : : unsigned int size)
1200 : : {
1201 : : uint32_t i;
1202 : : uint32_t read_size;
1203 : :
1204 : : /* Read at most NFP xstats number of names. */
1205 : 0 : read_size = RTE_MIN(size, nfp_net_xstats_size(dev));
1206 : :
1207 [ # # ]: 0 : for (i = 0; i < read_size; i++) {
1208 : : const struct nfp_xstat *xstat;
1209 : :
1210 : : /* Make sure ID is valid for device. */
1211 : 0 : xstat = nfp_net_xstats_info(dev, ids[i]);
1212 [ # # ]: 0 : if (xstat == NULL)
1213 : : return -EINVAL;
1214 : :
1215 : 0 : rte_strlcpy(xstats_names[i].name, xstat->name,
1216 : : RTE_ETH_XSTATS_NAME_SIZE);
1217 : : }
1218 : :
1219 : 0 : return read_size;
1220 : : }
1221 : :
1222 : : /*
1223 : : * NOTE: The only caller rte_eth_xstats_get_by_id() ensures dev,
1224 : : * ids, values and n are valid, and non-NULL.
1225 : : */
1226 : : int
1227 : 0 : nfp_net_xstats_get_by_id(struct rte_eth_dev *dev,
1228 : : const uint64_t *ids,
1229 : : uint64_t *values,
1230 : : unsigned int n)
1231 : : {
1232 : : uint32_t i;
1233 : : uint32_t read_size;
1234 : :
1235 : : /* Read at most NFP xstats number of values. */
1236 : 0 : read_size = RTE_MIN(n, nfp_net_xstats_size(dev));
1237 : :
1238 [ # # ]: 0 : for (i = 0; i < read_size; i++) {
1239 : : const struct nfp_xstat *xstat;
1240 : :
1241 : : /* Make sure index is valid for device. */
1242 : 0 : xstat = nfp_net_xstats_info(dev, ids[i]);
1243 [ # # ]: 0 : if (xstat == NULL)
1244 : : return -EINVAL;
1245 : :
1246 : 0 : values[i] = nfp_net_xstats_value(dev, ids[i], false);
1247 : : }
1248 : :
1249 : 0 : return read_size;
1250 : : }
1251 : :
1252 : : int
1253 : 0 : nfp_net_xstats_reset(struct rte_eth_dev *dev)
1254 : : {
1255 : : uint32_t id;
1256 : : uint32_t read_size;
1257 : : struct nfp_net_hw *hw;
1258 : : struct rte_eth_xstat *xstats_base;
1259 : : struct nfp_flower_representor *repr;
1260 : :
1261 : 0 : read_size = nfp_net_xstats_size(dev);
1262 : :
1263 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev)) {
1264 : 0 : repr = dev->data->dev_private;
1265 : 0 : xstats_base = repr->repr_xstats_base;
1266 : : } else {
1267 : 0 : hw = dev->data->dev_private;
1268 : 0 : xstats_base = hw->eth_xstats_base;
1269 : : }
1270 : :
1271 [ # # ]: 0 : for (id = 0; id < read_size; id++) {
1272 : 0 : xstats_base[id].id = id;
1273 : 0 : xstats_base[id].value = nfp_net_xstats_value(dev, id, true);
1274 : : }
1275 : :
1276 : : /* Successfully reset xstats, now call function to reset basic stats. */
1277 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev))
1278 : 0 : return nfp_flower_repr_stats_reset(dev);
1279 : : else
1280 : 0 : return nfp_net_stats_reset(dev);
1281 : : }
1282 : :
1283 : : void
1284 : 0 : nfp_net_rx_desc_limits(struct nfp_net_hw_priv *hw_priv,
1285 : : uint16_t *min_rx_desc,
1286 : : uint16_t *max_rx_desc)
1287 : : {
1288 : 0 : *max_rx_desc = hw_priv->dev_info->max_qc_size;
1289 : 0 : *min_rx_desc = hw_priv->dev_info->min_qc_size;
1290 : 0 : }
1291 : :
1292 : : void
1293 : 0 : nfp_net_tx_desc_limits(struct nfp_net_hw_priv *hw_priv,
1294 : : uint16_t *min_tx_desc,
1295 : : uint16_t *max_tx_desc)
1296 : : {
1297 : : uint16_t tx_dpp;
1298 : :
1299 [ # # ]: 0 : if (hw_priv->pf_dev->ver.extend == NFP_NET_CFG_VERSION_DP_NFD3)
1300 : : tx_dpp = NFD3_TX_DESC_PER_PKT;
1301 : : else
1302 : : tx_dpp = NFDK_TX_DESC_PER_SIMPLE_PKT;
1303 : :
1304 : 0 : *max_tx_desc = hw_priv->dev_info->max_qc_size / tx_dpp;
1305 : 0 : *min_tx_desc = hw_priv->dev_info->min_qc_size / tx_dpp;
1306 : 0 : }
1307 : :
1308 : : int
1309 : 0 : nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
1310 : : {
1311 : : uint32_t cap;
1312 : : uint32_t cap_extend;
1313 : : uint16_t min_rx_desc;
1314 : : uint16_t max_rx_desc;
1315 : : uint16_t min_tx_desc;
1316 : : uint16_t max_tx_desc;
1317 : : struct nfp_net_hw *hw;
1318 : : struct nfp_net_hw_priv *hw_priv;
1319 : :
1320 : 0 : hw = nfp_net_get_hw(dev);
1321 : 0 : hw_priv = dev->process_private;
1322 [ # # ]: 0 : if (hw_priv == NULL)
1323 : : return -EINVAL;
1324 : :
1325 : 0 : nfp_net_rx_desc_limits(hw_priv, &min_rx_desc, &max_rx_desc);
1326 : 0 : nfp_net_tx_desc_limits(hw_priv, &min_tx_desc, &max_tx_desc);
1327 : :
1328 : 0 : dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
1329 : 0 : dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
1330 : 0 : dev_info->min_rx_bufsize = RTE_ETHER_MIN_MTU;
1331 : : /*
1332 : : * The maximum rx packet length is set to the maximum layer 3 MTU,
1333 : : * plus layer 2, CRC and VLAN headers.
1334 : : * The maximum layer 3 MTU (max_mtu) is read from hardware,
1335 : : * which was set by the firmware loaded onto the card.
1336 : : */
1337 : 0 : dev_info->max_rx_pktlen = hw->max_mtu + NFP_ETH_OVERHEAD;
1338 : 0 : dev_info->max_mtu = hw->max_mtu;
1339 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
1340 : : /* Next should change when PF support is implemented */
1341 : 0 : dev_info->max_mac_addrs = 1;
1342 : :
1343 : 0 : cap = hw->super.cap;
1344 : :
1345 [ # # ]: 0 : if ((cap & (NFP_NET_CFG_CTRL_RXVLAN | NFP_NET_CFG_CTRL_RXVLAN_V2)) != 0)
1346 : 0 : dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1347 : :
1348 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXQINQ) != 0)
1349 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
1350 : :
1351 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXCSUM) != 0)
1352 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
1353 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
1354 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM;
1355 : :
1356 [ # # ]: 0 : if ((cap & (NFP_NET_CFG_CTRL_TXVLAN | NFP_NET_CFG_CTRL_TXVLAN_V2)) != 0)
1357 : 0 : dev_info->tx_offload_capa = RTE_ETH_TX_OFFLOAD_VLAN_INSERT;
1358 : :
1359 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_TXCSUM) != 0)
1360 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
1361 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
1362 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
1363 : :
1364 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_LSO_ANY) != 0) {
1365 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
1366 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_USO) != 0)
1367 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_UDP_TSO;
1368 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_VXLAN) != 0)
1369 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO;
1370 : : }
1371 : :
1372 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_GATHER) != 0)
1373 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
1374 : :
1375 : 0 : cap_extend = hw->super.cap_ext;
1376 [ # # ]: 0 : if ((cap_extend & NFP_NET_CFG_CTRL_IPSEC) != 0) {
1377 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
1378 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
1379 : : }
1380 : :
1381 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
1382 : : .rx_thresh = {
1383 : : .pthresh = DEFAULT_RX_PTHRESH,
1384 : : .hthresh = DEFAULT_RX_HTHRESH,
1385 : : .wthresh = DEFAULT_RX_WTHRESH,
1386 : : },
1387 : : .rx_free_thresh = DEFAULT_RX_FREE_THRESH,
1388 : : .rx_drop_en = 0,
1389 : : };
1390 : :
1391 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
1392 : : .tx_thresh = {
1393 : : .pthresh = DEFAULT_TX_PTHRESH,
1394 : : .hthresh = DEFAULT_TX_HTHRESH,
1395 : : .wthresh = DEFAULT_TX_WTHRESH,
1396 : : },
1397 : : .tx_free_thresh = DEFAULT_TX_FREE_THRESH,
1398 : : .tx_rs_thresh = DEFAULT_TX_RSBIT_THRESH,
1399 : : };
1400 : :
1401 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
1402 : : .nb_max = max_rx_desc,
1403 : : .nb_min = min_rx_desc,
1404 : : .nb_align = NFP_ALIGN_RING_DESC,
1405 : : };
1406 : :
1407 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
1408 : : .nb_max = max_tx_desc,
1409 : : .nb_min = min_tx_desc,
1410 : : .nb_align = NFP_ALIGN_RING_DESC,
1411 : : .nb_seg_max = NFP_TX_MAX_SEG,
1412 : : .nb_mtu_seg_max = NFP_TX_MAX_MTU_SEG,
1413 : : };
1414 : :
1415 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RSS_ANY) != 0) {
1416 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
1417 : 0 : dev_info->flow_type_rss_offloads = NFP_NET_RSS_CAP;
1418 : 0 : dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
1419 : 0 : dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
1420 : 0 : nfp_net_rss_algo_capa_get(hw, dev_info);
1421 : : }
1422 : :
1423 : : /* Only PF supports getting speed capability. */
1424 [ # # ]: 0 : if (hw_priv->is_pf)
1425 : 0 : dev_info->speed_capa = hw_priv->pf_dev->speed_capa;
1426 : :
1427 : : return 0;
1428 : : }
1429 : :
1430 : : int
1431 : 0 : nfp_net_common_init(struct nfp_pf_dev *pf_dev,
1432 : : struct nfp_net_hw *hw)
1433 : : {
1434 : : const int stride = 4;
1435 : : struct rte_pci_device *pci_dev;
1436 : :
1437 : 0 : pci_dev = pf_dev->pci_dev;
1438 : 0 : hw->device_id = pci_dev->id.device_id;
1439 : 0 : hw->vendor_id = pci_dev->id.vendor_id;
1440 : 0 : hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
1441 : 0 : hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
1442 : :
1443 : 0 : hw->max_rx_queues = nn_cfg_readl(&hw->super, NFP_NET_CFG_MAX_RXRINGS);
1444 : 0 : hw->max_tx_queues = nn_cfg_readl(&hw->super, NFP_NET_CFG_MAX_TXRINGS);
1445 : 0 : hw->super.cap_rss = nn_cfg_readl(&hw->super, NFP_NET_CFG_RSS_CAP);
1446 [ # # # # ]: 0 : if (hw->max_rx_queues == 0 || hw->max_tx_queues == 0) {
1447 : 0 : PMD_INIT_LOG(ERR, "Device %s can not be used, there are no valid queue "
1448 : : "pairs for use.", pci_dev->name);
1449 : 0 : return -ENODEV;
1450 : : }
1451 : :
1452 [ # # ]: 0 : if (nfp_net_check_dma_mask(pf_dev, pci_dev->name) != 0)
1453 : : return -ENODEV;
1454 : :
1455 : : /* Get some of the read-only fields from the config BAR */
1456 : 0 : hw->super.cap = nn_cfg_readl(&hw->super, NFP_NET_CFG_CAP);
1457 : 0 : hw->super.cap_ext = nn_cfg_readl(&hw->super, NFP_NET_CFG_CAP_WORD1);
1458 : 0 : hw->max_mtu = nn_cfg_readl(&hw->super, NFP_NET_CFG_MAX_MTU);
1459 : 0 : hw->flbufsz = DEFAULT_FLBUF_SIZE;
1460 : :
1461 : 0 : nfp_net_meta_init_format(hw, pf_dev);
1462 : :
1463 : : /* Read the Rx offset configured from firmware */
1464 [ # # ]: 0 : if (pf_dev->ver.major < 2)
1465 : 0 : hw->rx_offset = NFP_NET_RX_OFFSET;
1466 : : else
1467 : 0 : hw->rx_offset = nn_cfg_readl(&hw->super, NFP_NET_CFG_RX_OFFSET);
1468 : :
1469 : 0 : hw->super.ctrl = 0;
1470 : 0 : hw->stride_rx = stride;
1471 : 0 : hw->stride_tx = stride;
1472 : :
1473 : 0 : return 0;
1474 : : }
1475 : :
1476 : : const uint32_t *
1477 : 0 : nfp_net_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
1478 : : {
1479 : : struct nfp_net_hw *net_hw;
1480 : : static const uint32_t ptypes[] = {
1481 : : RTE_PTYPE_L2_ETHER,
1482 : : RTE_PTYPE_L3_IPV4,
1483 : : RTE_PTYPE_L3_IPV4_EXT,
1484 : : RTE_PTYPE_L3_IPV6,
1485 : : RTE_PTYPE_L3_IPV6_EXT,
1486 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1487 : : RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
1488 : : RTE_PTYPE_L4_TCP,
1489 : : RTE_PTYPE_L4_UDP,
1490 : : RTE_PTYPE_L4_FRAG,
1491 : : RTE_PTYPE_L4_NONFRAG,
1492 : : RTE_PTYPE_L4_ICMP,
1493 : : RTE_PTYPE_L4_SCTP,
1494 : : RTE_PTYPE_TUNNEL_VXLAN,
1495 : : RTE_PTYPE_TUNNEL_NVGRE,
1496 : : RTE_PTYPE_TUNNEL_GENEVE,
1497 : : RTE_PTYPE_INNER_L2_ETHER,
1498 : : RTE_PTYPE_INNER_L3_IPV4,
1499 : : RTE_PTYPE_INNER_L3_IPV4_EXT,
1500 : : RTE_PTYPE_INNER_L3_IPV6,
1501 : : RTE_PTYPE_INNER_L3_IPV6_EXT,
1502 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
1503 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
1504 : : RTE_PTYPE_INNER_L4_TCP,
1505 : : RTE_PTYPE_INNER_L4_UDP,
1506 : : RTE_PTYPE_INNER_L4_FRAG,
1507 : : RTE_PTYPE_INNER_L4_NONFRAG,
1508 : : RTE_PTYPE_INNER_L4_ICMP,
1509 : : RTE_PTYPE_INNER_L4_SCTP,
1510 : : };
1511 : :
1512 [ # # ]: 0 : if (dev->rx_pkt_burst == NULL)
1513 : : return NULL;
1514 : :
1515 : 0 : net_hw = dev->data->dev_private;
1516 [ # # ]: 0 : if ((net_hw->super.cap_ext & NFP_NET_CFG_CTRL_PKT_TYPE) == 0)
1517 : : return NULL;
1518 : :
1519 : 0 : *no_of_elements = RTE_DIM(ptypes);
1520 : 0 : return ptypes;
1521 : : }
1522 : :
1523 : : int
1524 : 0 : nfp_net_ptypes_set(struct rte_eth_dev *dev,
1525 : : uint32_t ptype_mask)
1526 : : {
1527 : : int ret;
1528 : : uint32_t update;
1529 : : uint32_t ctrl_ext;
1530 : : struct nfp_hw *hw;
1531 : : struct nfp_net_hw *net_hw;
1532 : :
1533 : 0 : net_hw = dev->data->dev_private;
1534 : 0 : hw = &net_hw->super;
1535 : :
1536 [ # # ]: 0 : if ((hw->cap_ext & NFP_NET_CFG_CTRL_PKT_TYPE) == 0)
1537 : : return -ENOTSUP;
1538 : :
1539 : 0 : ctrl_ext = hw->ctrl_ext;
1540 [ # # ]: 0 : if (ptype_mask == 0) {
1541 [ # # ]: 0 : if ((ctrl_ext & NFP_NET_CFG_CTRL_PKT_TYPE) == 0)
1542 : : return 0;
1543 : :
1544 : 0 : ctrl_ext &= ~NFP_NET_CFG_CTRL_PKT_TYPE;
1545 : : } else {
1546 [ # # ]: 0 : if ((ctrl_ext & NFP_NET_CFG_CTRL_PKT_TYPE) != 0)
1547 : : return 0;
1548 : :
1549 : 0 : ctrl_ext |= NFP_NET_CFG_CTRL_PKT_TYPE;
1550 : : }
1551 : :
1552 : : update = NFP_NET_CFG_UPDATE_GEN;
1553 : :
1554 : 0 : ret = nfp_ext_reconfig(hw, ctrl_ext, update);
1555 [ # # ]: 0 : if (ret != 0)
1556 : : return ret;
1557 : :
1558 : 0 : hw->ctrl_ext = ctrl_ext;
1559 : :
1560 : 0 : return 0;
1561 : : }
1562 : :
1563 : : int
1564 : 0 : nfp_rx_queue_intr_enable(struct rte_eth_dev *dev,
1565 : : uint16_t queue_id)
1566 : : {
1567 : : uint16_t base = 0;
1568 : : struct nfp_net_hw *hw;
1569 : : struct rte_pci_device *pci_dev;
1570 : :
1571 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1572 [ # # ]: 0 : if (rte_intr_type_get(pci_dev->intr_handle) != RTE_INTR_HANDLE_UIO)
1573 : : base = 1;
1574 : :
1575 : : /* Make sure all updates are written before un-masking */
1576 : : rte_wmb();
1577 : :
1578 : 0 : hw = nfp_net_get_hw(dev);
1579 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_ICR(base + queue_id),
1580 : : NFP_NET_CFG_ICR_UNMASKED);
1581 : 0 : return 0;
1582 : : }
1583 : :
1584 : : int
1585 : 0 : nfp_rx_queue_intr_disable(struct rte_eth_dev *dev,
1586 : : uint16_t queue_id)
1587 : : {
1588 : : uint16_t base = 0;
1589 : : struct nfp_net_hw *hw;
1590 : : struct rte_pci_device *pci_dev;
1591 : :
1592 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1593 [ # # ]: 0 : if (rte_intr_type_get(pci_dev->intr_handle) != RTE_INTR_HANDLE_UIO)
1594 : : base = 1;
1595 : :
1596 : : /* Make sure all updates are written before un-masking */
1597 : : rte_wmb();
1598 : :
1599 : 0 : hw = nfp_net_get_hw(dev);
1600 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_ICR(base + queue_id), NFP_NET_CFG_ICR_RXTX);
1601 : :
1602 : 0 : return 0;
1603 : : }
1604 : :
1605 : : static void
1606 : 0 : nfp_net_dev_link_status_print(struct rte_eth_dev *dev)
1607 : : {
1608 : : struct rte_eth_link link;
1609 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1610 : :
1611 : 0 : rte_eth_linkstatus_get(dev, &link);
1612 [ # # ]: 0 : if (link.link_status != 0)
1613 [ # # ]: 0 : PMD_DRV_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s.",
1614 : : dev->data->port_id, link.link_speed,
1615 : : link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX ?
1616 : : "full-duplex" : "half-duplex");
1617 : : else
1618 : 0 : PMD_DRV_LOG(INFO, " Port %d: Link Down.", dev->data->port_id);
1619 : :
1620 : 0 : PMD_DRV_LOG(INFO, "PCI Address: " PCI_PRI_FMT,
1621 : : pci_dev->addr.domain, pci_dev->addr.bus,
1622 : : pci_dev->addr.devid, pci_dev->addr.function);
1623 : 0 : }
1624 : :
1625 : : /*
1626 : : * Unmask an interrupt
1627 : : *
1628 : : * If MSI-X auto-masking is enabled clear the mask bit, otherwise
1629 : : * clear the ICR for the entry.
1630 : : */
1631 : : void
1632 : 0 : nfp_net_irq_unmask(struct rte_eth_dev *dev)
1633 : : {
1634 : : struct nfp_net_hw *hw;
1635 : : struct rte_pci_device *pci_dev;
1636 : :
1637 : 0 : hw = nfp_net_get_hw(dev);
1638 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1639 : :
1640 : : /* Make sure all updates are written before un-masking */
1641 : : rte_wmb();
1642 : :
1643 [ # # ]: 0 : if ((hw->super.ctrl & NFP_NET_CFG_CTRL_MSIXAUTO) != 0) {
1644 : : /* If MSI-X auto-masking is used, clear the entry */
1645 : 0 : rte_intr_ack(pci_dev->intr_handle);
1646 : : } else {
1647 : : nn_cfg_writeb(&hw->super, NFP_NET_CFG_ICR(NFP_NET_IRQ_LSC_IDX),
1648 : : NFP_NET_CFG_ICR_UNMASKED);
1649 : : }
1650 : 0 : }
1651 : :
1652 : : /**
1653 : : * Interrupt handler which shall be registered for alarm callback for delayed
1654 : : * handling specific interrupt to wait for the stable nic state. As the NIC
1655 : : * interrupt state is not stable for nfp after link is just down, it needs
1656 : : * to wait 4 seconds to get the stable status.
1657 : : *
1658 : : * @param param
1659 : : * The address of parameter (struct rte_eth_dev *)
1660 : : */
1661 : : void
1662 : 0 : nfp_net_dev_interrupt_delayed_handler(void *param)
1663 : : {
1664 : : struct rte_eth_dev *dev = param;
1665 : :
1666 : 0 : nfp_net_link_update(dev, 0);
1667 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
1668 : :
1669 : 0 : nfp_net_dev_link_status_print(dev);
1670 : :
1671 : : /* Unmasking */
1672 : 0 : nfp_net_irq_unmask(dev);
1673 : 0 : }
1674 : :
1675 : : void
1676 : 0 : nfp_net_dev_interrupt_handler(void *param)
1677 : : {
1678 : : int64_t timeout;
1679 : : struct rte_eth_link link;
1680 : : struct rte_eth_dev *dev = param;
1681 : :
1682 : 0 : PMD_DRV_LOG(DEBUG, "We got a LSC interrupt!!!");
1683 : :
1684 : 0 : rte_eth_linkstatus_get(dev, &link);
1685 : :
1686 : 0 : nfp_net_link_update(dev, 0);
1687 : :
1688 : : /* Likely to up */
1689 [ # # ]: 0 : if (link.link_status == 0) {
1690 : : /* Handle it 1 sec later, wait it being stable */
1691 : : timeout = NFP_NET_LINK_UP_CHECK_TIMEOUT;
1692 : : } else { /* Likely to down */
1693 : : /* Handle it 4 sec later, wait it being stable */
1694 : : timeout = NFP_NET_LINK_DOWN_CHECK_TIMEOUT;
1695 : : }
1696 : :
1697 [ # # ]: 0 : if (rte_eal_alarm_set(timeout * 1000,
1698 : : nfp_net_dev_interrupt_delayed_handler,
1699 : : (void *)dev) != 0) {
1700 : 0 : PMD_INIT_LOG(ERR, "Error setting alarm.");
1701 : : /* Unmasking */
1702 : 0 : nfp_net_irq_unmask(dev);
1703 : : }
1704 : 0 : }
1705 : :
1706 : : int
1707 : 0 : nfp_net_dev_mtu_set(struct rte_eth_dev *dev,
1708 : : uint16_t mtu)
1709 : : {
1710 : : struct nfp_net_hw *hw;
1711 : :
1712 : 0 : hw = nfp_net_get_hw(dev);
1713 : :
1714 : : /* MTU setting is forbidden if port is started */
1715 [ # # ]: 0 : if (dev->data->dev_started) {
1716 : 0 : PMD_DRV_LOG(ERR, "Port %d must be stopped before configuration.",
1717 : : dev->data->port_id);
1718 : 0 : return -EBUSY;
1719 : : }
1720 : :
1721 : : /* MTU larger than current mbufsize not supported */
1722 [ # # ]: 0 : if (mtu > hw->flbufsz) {
1723 : 0 : PMD_DRV_LOG(ERR, "MTU (%u) larger than current mbufsize (%u) not supported.",
1724 : : mtu, hw->flbufsz);
1725 : 0 : return -ERANGE;
1726 : : }
1727 : :
1728 : : /* Writing to configuration space */
1729 : 0 : nn_cfg_writel(&hw->super, NFP_NET_CFG_MTU, mtu);
1730 : :
1731 : 0 : hw->mtu = mtu;
1732 : :
1733 : 0 : return 0;
1734 : : }
1735 : :
1736 : : int
1737 : 0 : nfp_net_vlan_offload_set(struct rte_eth_dev *dev,
1738 : : int mask)
1739 : : {
1740 : : int ret;
1741 : : uint32_t update;
1742 : : uint32_t new_ctrl;
1743 : : struct nfp_hw *hw;
1744 : : uint64_t rx_offload;
1745 : : struct nfp_net_hw *net_hw;
1746 : : uint32_t rxvlan_ctrl = 0;
1747 : :
1748 : 0 : net_hw = nfp_net_get_hw(dev);
1749 : 0 : hw = &net_hw->super;
1750 : 0 : rx_offload = dev->data->dev_conf.rxmode.offloads;
1751 : 0 : new_ctrl = hw->ctrl;
1752 : :
1753 : : /* VLAN stripping setting */
1754 [ # # ]: 0 : if ((mask & RTE_ETH_VLAN_STRIP_MASK) != 0) {
1755 : : nfp_net_enable_rxvlan_cap(net_hw, &rxvlan_ctrl);
1756 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) != 0)
1757 : 0 : new_ctrl |= rxvlan_ctrl;
1758 : : else
1759 : 0 : new_ctrl &= ~rxvlan_ctrl;
1760 : : }
1761 : :
1762 : : /* QinQ stripping setting */
1763 [ # # ]: 0 : if ((mask & RTE_ETH_QINQ_STRIP_MASK) != 0) {
1764 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) != 0)
1765 : 0 : new_ctrl |= NFP_NET_CFG_CTRL_RXQINQ;
1766 : : else
1767 : 0 : new_ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;
1768 : : }
1769 : :
1770 [ # # ]: 0 : if (new_ctrl == hw->ctrl)
1771 : : return 0;
1772 : :
1773 : : update = NFP_NET_CFG_UPDATE_GEN;
1774 : :
1775 : 0 : ret = nfp_reconfig(hw, new_ctrl, update);
1776 [ # # ]: 0 : if (ret != 0)
1777 : : return ret;
1778 : :
1779 : 0 : hw->ctrl = new_ctrl;
1780 : :
1781 : 0 : return 0;
1782 : : }
1783 : :
1784 : : static int
1785 : 0 : nfp_net_rss_reta_write(struct rte_eth_dev *dev,
1786 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1787 : : uint16_t reta_size)
1788 : : {
1789 : : uint16_t i;
1790 : : uint16_t j;
1791 : : uint16_t idx;
1792 : : uint8_t mask;
1793 : : uint32_t reta;
1794 : : uint16_t shift;
1795 : : struct nfp_hw *hw;
1796 : : struct nfp_net_hw *net_hw;
1797 : :
1798 : 0 : net_hw = nfp_net_get_hw(dev);
1799 : : hw = &net_hw->super;
1800 : :
1801 [ # # ]: 0 : if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) {
1802 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured (%hu)"
1803 : : " does not match hardware can supported (%d).",
1804 : : reta_size, NFP_NET_CFG_RSS_ITBL_SZ);
1805 : 0 : return -EINVAL;
1806 : : }
1807 : :
1808 : : /*
1809 : : * Update Redirection Table. There are 128 8bit-entries which can be
1810 : : * manage as 32 32bit-entries.
1811 : : */
1812 [ # # ]: 0 : for (i = 0; i < reta_size; i += 4) {
1813 : : /* Handling 4 RSS entries per loop */
1814 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1815 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1816 : 0 : mask = (uint8_t)((reta_conf[idx].mask >> shift) & 0xF);
1817 [ # # ]: 0 : if (mask == 0)
1818 : 0 : continue;
1819 : :
1820 : : reta = 0;
1821 : :
1822 : : /* If all 4 entries were set, don't need read RETA register */
1823 [ # # ]: 0 : if (mask != 0xF)
1824 : 0 : reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + i);
1825 : :
1826 [ # # ]: 0 : for (j = 0; j < 4; j++) {
1827 [ # # ]: 0 : if ((mask & (0x1 << j)) == 0)
1828 : 0 : continue;
1829 : :
1830 : : /* Clearing the entry bits */
1831 [ # # ]: 0 : if (mask != 0xF)
1832 : 0 : reta &= ~(0xFF << (8 * j));
1833 : :
1834 : 0 : reta |= reta_conf[idx].reta[shift + j] << (8 * j);
1835 : : }
1836 : :
1837 : 0 : nn_cfg_writel(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + shift, reta);
1838 : : }
1839 : :
1840 : : return 0;
1841 : : }
1842 : :
1843 : : /* Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device */
1844 : : int
1845 : 0 : nfp_net_reta_update(struct rte_eth_dev *dev,
1846 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1847 : : uint16_t reta_size)
1848 : : {
1849 : : int ret;
1850 : : uint32_t update;
1851 : : struct nfp_hw *hw;
1852 : : struct nfp_net_hw *net_hw;
1853 : :
1854 : 0 : net_hw = nfp_net_get_hw(dev);
1855 : 0 : hw = &net_hw->super;
1856 : :
1857 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
1858 : : return -EINVAL;
1859 : :
1860 : 0 : ret = nfp_net_rss_reta_write(dev, reta_conf, reta_size);
1861 [ # # ]: 0 : if (ret != 0)
1862 : : return ret;
1863 : :
1864 : : update = NFP_NET_CFG_UPDATE_RSS;
1865 : :
1866 [ # # ]: 0 : if (nfp_reconfig(hw, hw->ctrl, update) != 0)
1867 : 0 : return -EIO;
1868 : :
1869 : : return 0;
1870 : : }
1871 : :
1872 : : /* Query Redirection Table(RETA) of Receive Side Scaling of Ethernet device. */
1873 : : int
1874 : 0 : nfp_net_reta_query(struct rte_eth_dev *dev,
1875 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1876 : : uint16_t reta_size)
1877 : : {
1878 : : uint16_t i;
1879 : : uint16_t j;
1880 : : uint16_t idx;
1881 : : uint8_t mask;
1882 : : uint32_t reta;
1883 : : uint16_t shift;
1884 : : struct nfp_hw *hw;
1885 : : struct nfp_net_hw *net_hw;
1886 : :
1887 : 0 : net_hw = nfp_net_get_hw(dev);
1888 : : hw = &net_hw->super;
1889 : :
1890 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
1891 : : return -EINVAL;
1892 : :
1893 [ # # ]: 0 : if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) {
1894 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured (%d)"
1895 : : " does not match hardware can supported (%d).",
1896 : : reta_size, NFP_NET_CFG_RSS_ITBL_SZ);
1897 : 0 : return -EINVAL;
1898 : : }
1899 : :
1900 : : /*
1901 : : * Reading Redirection Table. There are 128 8bit-entries which can be
1902 : : * manage as 32 32bit-entries.
1903 : : */
1904 [ # # ]: 0 : for (i = 0; i < reta_size; i += 4) {
1905 : : /* Handling 4 RSS entries per loop */
1906 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1907 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1908 : 0 : mask = (reta_conf[idx].mask >> shift) & 0xF;
1909 : :
1910 [ # # ]: 0 : if (mask == 0)
1911 : 0 : continue;
1912 : :
1913 : 0 : reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + shift);
1914 [ # # ]: 0 : for (j = 0; j < 4; j++) {
1915 [ # # ]: 0 : if ((mask & (0x1 << j)) == 0)
1916 : 0 : continue;
1917 : :
1918 : 0 : reta_conf[idx].reta[shift + j] =
1919 : 0 : (uint8_t)((reta >> (8 * j)) & 0xF);
1920 : : }
1921 : : }
1922 : :
1923 : : return 0;
1924 : : }
1925 : :
1926 : : static void
1927 : 0 : nfp_net_rss_hf_get(uint32_t cfg_rss_ctrl,
1928 : : struct rte_eth_rss_conf *rss_conf)
1929 : : {
1930 : : uint64_t rss_hf = 0;
1931 : :
1932 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4) != 0)
1933 : : rss_hf |= RTE_ETH_RSS_IPV4;
1934 : :
1935 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_TCP) != 0)
1936 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
1937 : :
1938 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_TCP) != 0)
1939 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
1940 : :
1941 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_UDP) != 0)
1942 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
1943 : :
1944 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_UDP) != 0)
1945 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
1946 : :
1947 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6) != 0)
1948 : 0 : rss_hf |= RTE_ETH_RSS_IPV6;
1949 : :
1950 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_SCTP) != 0)
1951 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_SCTP;
1952 : :
1953 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_SCTP) != 0)
1954 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
1955 : :
1956 : 0 : rss_conf->rss_hf = rss_hf;
1957 : 0 : }
1958 : :
1959 : : static void
1960 : 0 : nfp_net_rss_hf_set(uint32_t *cfg_rss_ctrl,
1961 : : struct rte_eth_rss_conf *rss_conf)
1962 : : {
1963 : 0 : uint64_t rss_hf = rss_conf->rss_hf;
1964 : :
1965 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_IPV4) != 0)
1966 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4;
1967 : :
1968 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) != 0)
1969 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_TCP;
1970 : :
1971 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) != 0)
1972 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_UDP;
1973 : :
1974 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) != 0)
1975 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_SCTP;
1976 : :
1977 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_IPV6) != 0)
1978 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6;
1979 : :
1980 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) != 0)
1981 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_TCP;
1982 : :
1983 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) != 0)
1984 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_UDP;
1985 : :
1986 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) != 0)
1987 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_SCTP;
1988 : 0 : }
1989 : :
1990 : : static int
1991 : : nfp_net_rss_algo_conf_get(uint32_t cfg_rss_ctrl,
1992 : : struct rte_eth_rss_conf *rss_conf)
1993 : : {
1994 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_TOEPLITZ) != 0)
1995 : 0 : rss_conf->algorithm = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
1996 [ # # ]: 0 : else if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_XOR) != 0)
1997 : 0 : rss_conf->algorithm = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
1998 [ # # ]: 0 : else if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_CRC32) != 0)
1999 : 0 : rss_conf->algorithm = RTE_ETH_HASH_FUNCTION_DEFAULT;
2000 : : else
2001 : : return -EIO;
2002 : :
2003 : : return 0;
2004 : : }
2005 : :
2006 : : static int
2007 : : nfp_net_rss_algo_conf_set(uint32_t *cfg_rss_ctrl,
2008 : : struct rte_eth_rss_conf *rss_conf)
2009 : : {
2010 : 0 : enum rte_eth_hash_function algorithm = rss_conf->algorithm;
2011 : :
2012 : 0 : if (algorithm == RTE_ETH_HASH_FUNCTION_TOEPLITZ)
2013 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_TOEPLITZ;
2014 [ # # ]: 0 : else if (algorithm == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
2015 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_XOR;
2016 [ # # ]: 0 : else if (algorithm == RTE_ETH_HASH_FUNCTION_DEFAULT)
2017 : 0 : *cfg_rss_ctrl |= NFP_NET_CFG_RSS_CRC32;
2018 : : else
2019 : : return -ENOTSUP;
2020 : :
2021 : : return 0;
2022 : : }
2023 : :
2024 : : static int
2025 : 0 : nfp_net_rss_hash_write(struct rte_eth_dev *dev,
2026 : : struct rte_eth_rss_conf *rss_conf)
2027 : : {
2028 : : int ret;
2029 : : uint8_t i;
2030 : : uint8_t key;
2031 : : struct nfp_hw *hw;
2032 : : struct nfp_net_hw *net_hw;
2033 : 0 : uint32_t cfg_rss_ctrl = 0;
2034 : :
2035 : 0 : net_hw = nfp_net_get_hw(dev);
2036 : : hw = &net_hw->super;
2037 : :
2038 : : /* Writing the key byte by byte */
2039 [ # # ]: 0 : for (i = 0; i < rss_conf->rss_key_len; i++) {
2040 : 0 : memcpy(&key, &rss_conf->rss_key[i], 1);
2041 : 0 : nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY + i, key);
2042 : : }
2043 : :
2044 : 0 : nfp_net_rss_hf_set(&cfg_rss_ctrl, rss_conf);
2045 : :
2046 [ # # ]: 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_MASK;
2047 : :
2048 : : ret = nfp_net_rss_algo_conf_set(&cfg_rss_ctrl, rss_conf);
2049 : : if (ret != 0) {
2050 : 0 : PMD_DRV_LOG(ERR, "Fail to set rss algorithm configuration.");
2051 : 0 : return ret;
2052 : : }
2053 : :
2054 : : /* Configuring where to apply the RSS hash */
2055 : 0 : nn_cfg_writel(hw, NFP_NET_CFG_RSS_CTRL, cfg_rss_ctrl);
2056 : :
2057 : 0 : return 0;
2058 : : }
2059 : :
2060 : : int
2061 : 0 : nfp_net_rss_hash_update(struct rte_eth_dev *dev,
2062 : : struct rte_eth_rss_conf *rss_conf)
2063 : : {
2064 : : int ret;
2065 : : uint32_t update;
2066 : : struct nfp_hw *hw;
2067 : : struct nfp_net_hw *net_hw;
2068 : :
2069 : 0 : net_hw = nfp_net_get_hw(dev);
2070 : 0 : hw = &net_hw->super;
2071 : :
2072 : : /* Checking if RSS is enabled */
2073 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0) {
2074 : 0 : PMD_DRV_LOG(ERR, "RSS unsupported.");
2075 : 0 : return -EINVAL;
2076 : : }
2077 : :
2078 [ # # ]: 0 : if (rss_conf->rss_key_len > NFP_NET_CFG_RSS_KEY_SZ) {
2079 : 0 : PMD_DRV_LOG(ERR, "RSS hash key too long.");
2080 : 0 : return -EINVAL;
2081 : : }
2082 : :
2083 : 0 : ret = nfp_net_rss_hash_write(dev, rss_conf);
2084 [ # # ]: 0 : if (ret != 0) {
2085 : 0 : PMD_DRV_LOG(ERR, "RSS write failed.");
2086 : 0 : return ret;
2087 : : }
2088 : :
2089 : : update = NFP_NET_CFG_UPDATE_RSS;
2090 : :
2091 [ # # ]: 0 : if (nfp_reconfig(hw, hw->ctrl, update) != 0)
2092 : 0 : return -EIO;
2093 : :
2094 : : return 0;
2095 : : }
2096 : :
2097 : : int
2098 : 0 : nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev,
2099 : : struct rte_eth_rss_conf *rss_conf)
2100 : : {
2101 : : int ret;
2102 : : uint8_t i;
2103 : : uint8_t key;
2104 : : struct nfp_hw *hw;
2105 : : uint32_t cfg_rss_ctrl;
2106 : : struct nfp_net_hw *net_hw;
2107 : :
2108 : 0 : net_hw = nfp_net_get_hw(dev);
2109 : : hw = &net_hw->super;
2110 : :
2111 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
2112 : : return -EINVAL;
2113 : :
2114 : : cfg_rss_ctrl = nn_cfg_readl(hw, NFP_NET_CFG_RSS_CTRL);
2115 : :
2116 : : /* Propagate current RSS hash functions to caller */
2117 : 0 : nfp_net_rss_hf_get(cfg_rss_ctrl, rss_conf);
2118 : :
2119 : : /* Reading the key size */
2120 : 0 : rss_conf->rss_key_len = NFP_NET_CFG_RSS_KEY_SZ;
2121 : :
2122 : : /* Reading the key byte a byte */
2123 [ # # ]: 0 : if (rss_conf->rss_key != NULL) {
2124 [ # # ]: 0 : for (i = 0; i < rss_conf->rss_key_len; i++) {
2125 : 0 : key = nn_cfg_readb(hw, NFP_NET_CFG_RSS_KEY + i);
2126 : 0 : memcpy(&rss_conf->rss_key[i], &key, 1);
2127 : : }
2128 : : }
2129 : :
2130 : : ret = nfp_net_rss_algo_conf_get(cfg_rss_ctrl, rss_conf);
2131 : : if (ret != 0) {
2132 : 0 : PMD_DRV_LOG(ERR, "Fail to get rss algorithm configuration.");
2133 : 0 : return ret;
2134 : : }
2135 : :
2136 : : return 0;
2137 : : }
2138 : :
2139 : : int
2140 : 0 : nfp_net_rss_config_default(struct rte_eth_dev *dev)
2141 : : {
2142 : : int ret;
2143 : : uint8_t i;
2144 : : uint8_t j;
2145 : : uint16_t queue = 0;
2146 : 0 : uint8_t default_key[] = {
2147 : : 0x6d, 0x5a, 0x56, 0xda,
2148 : : 0x25, 0x5b, 0x0e, 0xc2,
2149 : : 0x41, 0x67, 0x25, 0x3d,
2150 : : 0x43, 0xa3, 0x8f, 0xb0,
2151 : : 0xd0, 0xca, 0x2b, 0xcb,
2152 : : 0xae, 0x7b, 0x30, 0xb4,
2153 : : 0x77, 0xcb, 0x2d, 0xa3,
2154 : : 0x80, 0x30, 0xf2, 0x0c,
2155 : : 0x6a, 0x42, 0xb7, 0x3b,
2156 : : 0xbe, 0xac, 0x01, 0xfa,
2157 : : };
2158 : : struct rte_eth_conf *dev_conf;
2159 : : struct rte_eth_rss_conf rss_conf;
2160 : 0 : uint16_t rx_queues = dev->data->nb_rx_queues;
2161 : : struct rte_eth_rss_reta_entry64 nfp_reta_conf[2];
2162 : :
2163 : 0 : nfp_reta_conf[0].mask = ~0x0;
2164 : 0 : nfp_reta_conf[1].mask = ~0x0;
2165 : :
2166 [ # # ]: 0 : for (i = 0; i < 0x40; i += 8) {
2167 [ # # ]: 0 : for (j = i; j < (i + 8); j++) {
2168 : 0 : nfp_reta_conf[0].reta[j] = queue;
2169 : 0 : nfp_reta_conf[1].reta[j] = queue++;
2170 : 0 : queue %= rx_queues;
2171 : : }
2172 : : }
2173 : :
2174 : 0 : ret = nfp_net_rss_reta_write(dev, nfp_reta_conf, 0x80);
2175 [ # # ]: 0 : if (ret != 0)
2176 : : return ret;
2177 : :
2178 : 0 : dev_conf = &dev->data->dev_conf;
2179 : : if (dev_conf == NULL) {
2180 : : PMD_DRV_LOG(ERR, "Wrong rss conf.");
2181 : : return -EINVAL;
2182 : : }
2183 : :
2184 : 0 : rss_conf = dev_conf->rx_adv_conf.rss_conf;
2185 [ # # ]: 0 : if (rss_conf.rss_key_len == 0) {
2186 : 0 : rss_conf.rss_key = default_key;
2187 : 0 : rss_conf.rss_key_len = NFP_NET_CFG_RSS_KEY_SZ;
2188 : : }
2189 : :
2190 : 0 : ret = nfp_net_rss_hash_write(dev, &rss_conf);
2191 : :
2192 : 0 : return ret;
2193 : : }
2194 : :
2195 : : void
2196 : 0 : nfp_net_stop_rx_queue(struct rte_eth_dev *dev)
2197 : : {
2198 : : uint16_t i;
2199 : : struct nfp_net_rxq *this_rx_q;
2200 : :
2201 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
2202 : 0 : this_rx_q = dev->data->rx_queues[i];
2203 : 0 : nfp_net_reset_rx_queue(this_rx_q);
2204 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
2205 : : }
2206 : 0 : }
2207 : :
2208 : : void
2209 : 0 : nfp_net_close_rx_queue(struct rte_eth_dev *dev)
2210 : : {
2211 : : uint16_t i;
2212 : : struct nfp_net_rxq *this_rx_q;
2213 : :
2214 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
2215 : 0 : this_rx_q = dev->data->rx_queues[i];
2216 : 0 : nfp_net_reset_rx_queue(this_rx_q);
2217 : 0 : nfp_net_rx_queue_release(dev, i);
2218 : : }
2219 : 0 : }
2220 : :
2221 : : void
2222 : 0 : nfp_net_stop_tx_queue(struct rte_eth_dev *dev)
2223 : : {
2224 : : uint16_t i;
2225 : : struct nfp_net_txq *this_tx_q;
2226 : :
2227 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
2228 : 0 : this_tx_q = dev->data->tx_queues[i];
2229 : 0 : nfp_net_reset_tx_queue(this_tx_q);
2230 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
2231 : : }
2232 : 0 : }
2233 : :
2234 : : void
2235 : 0 : nfp_net_close_tx_queue(struct rte_eth_dev *dev)
2236 : : {
2237 : : uint16_t i;
2238 : : struct nfp_net_txq *this_tx_q;
2239 : :
2240 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
2241 : 0 : this_tx_q = dev->data->tx_queues[i];
2242 : 0 : nfp_net_reset_tx_queue(this_tx_q);
2243 : 0 : nfp_net_tx_queue_release(dev, i);
2244 : : }
2245 : 0 : }
2246 : :
2247 : : int
2248 : 0 : nfp_net_set_vxlan_port(struct nfp_net_hw *net_hw,
2249 : : size_t idx,
2250 : : uint16_t port,
2251 : : uint32_t ctrl)
2252 : : {
2253 : : uint32_t i;
2254 : 0 : struct nfp_hw *hw = &net_hw->super;
2255 : :
2256 [ # # ]: 0 : if (idx >= NFP_NET_N_VXLAN_PORTS) {
2257 : 0 : PMD_DRV_LOG(ERR, "The idx value is out of range.");
2258 : 0 : return -ERANGE;
2259 : : }
2260 : :
2261 : 0 : net_hw->vxlan_ports[idx] = port;
2262 : :
2263 [ # # ]: 0 : for (i = 0; i < NFP_NET_N_VXLAN_PORTS; i += 2) {
2264 : 0 : nn_cfg_writel(hw, NFP_NET_CFG_VXLAN_PORT + i * sizeof(port),
2265 : 0 : (net_hw->vxlan_ports[i + 1] << 16) | net_hw->vxlan_ports[i]);
2266 : : }
2267 : :
2268 : 0 : return nfp_reconfig(hw, ctrl, NFP_NET_CFG_UPDATE_VXLAN);
2269 : : }
2270 : :
2271 : : /*
2272 : : * The firmware with NFD3 can not handle DMA address requiring more
2273 : : * than 40 bits.
2274 : : */
2275 : : int
2276 : 0 : nfp_net_check_dma_mask(struct nfp_pf_dev *pf_dev,
2277 : : char *name)
2278 : : {
2279 [ # # # # ]: 0 : if (pf_dev->ver.extend == NFP_NET_CFG_VERSION_DP_NFD3 &&
2280 : 0 : rte_mem_check_dma_mask(40) != 0) {
2281 : 0 : PMD_DRV_LOG(ERR, "Device %s can not be used: restricted dma mask to 40 bits!",
2282 : : name);
2283 : 0 : return -ENODEV;
2284 : : }
2285 : :
2286 : : return 0;
2287 : : }
2288 : :
2289 : : int
2290 : 0 : nfp_net_txrwb_alloc(struct rte_eth_dev *eth_dev)
2291 : : {
2292 : : struct nfp_net_hw *net_hw;
2293 : : char mz_name[RTE_MEMZONE_NAMESIZE];
2294 : :
2295 : 0 : net_hw = nfp_net_get_hw(eth_dev);
2296 : 0 : snprintf(mz_name, sizeof(mz_name), "%s_TXRWB", eth_dev->data->name);
2297 : 0 : net_hw->txrwb_mz = rte_memzone_reserve_aligned(mz_name,
2298 : 0 : net_hw->max_tx_queues * sizeof(uint64_t),
2299 : 0 : rte_socket_id(),
2300 : : RTE_MEMZONE_IOVA_CONTIG, RTE_CACHE_LINE_SIZE);
2301 [ # # ]: 0 : if (net_hw->txrwb_mz == NULL) {
2302 : 0 : PMD_INIT_LOG(ERR, "Failed to alloc %s for TX ring write back.",
2303 : : mz_name);
2304 : 0 : return -ENOMEM;
2305 : : }
2306 : :
2307 : : return 0;
2308 : : }
2309 : :
2310 : : void
2311 : 0 : nfp_net_txrwb_free(struct rte_eth_dev *eth_dev)
2312 : : {
2313 : : struct nfp_net_hw *net_hw;
2314 : :
2315 : 0 : net_hw = nfp_net_get_hw(eth_dev);
2316 [ # # ]: 0 : if (net_hw->txrwb_mz == NULL)
2317 : : return;
2318 : :
2319 : 0 : rte_memzone_free(net_hw->txrwb_mz);
2320 : 0 : net_hw->txrwb_mz = NULL;
2321 : : }
2322 : :
2323 : : static void
2324 : : nfp_net_cfg_read_version(struct nfp_hw *hw,
2325 : : struct nfp_pf_dev *pf_dev)
2326 : : {
2327 : : union {
2328 : : uint32_t whole;
2329 : : struct nfp_net_fw_ver split;
2330 : : } version;
2331 : :
2332 : : version.whole = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);
2333 : 0 : pf_dev->ver = version.split;
2334 : : }
2335 : :
2336 : : bool
2337 : 0 : nfp_net_version_check(struct nfp_hw *hw,
2338 : : struct nfp_pf_dev *pf_dev)
2339 : : {
2340 : : nfp_net_cfg_read_version(hw, pf_dev);
2341 [ # # ]: 0 : if (!nfp_net_is_valid_nfd_version(pf_dev->ver))
2342 : : return false;
2343 : :
2344 [ # # ]: 0 : if (!nfp_net_is_valid_version_class(pf_dev->ver))
2345 : 0 : return false;
2346 : :
2347 : : return true;
2348 : : }
2349 : :
2350 : : static void
2351 : 0 : nfp_net_get_nsp_info(struct nfp_net_hw_priv *hw_priv,
2352 : : char *nsp_version)
2353 : : {
2354 : : struct nfp_nsp *nsp;
2355 : :
2356 : 0 : nsp = nfp_nsp_open(hw_priv->pf_dev->cpp);
2357 [ # # ]: 0 : if (nsp == NULL)
2358 : : return;
2359 : :
2360 : 0 : snprintf(nsp_version, FW_VER_LEN, "%hu.%hu",
2361 : 0 : nfp_nsp_get_abi_ver_major(nsp),
2362 : 0 : nfp_nsp_get_abi_ver_minor(nsp));
2363 : :
2364 : 0 : nfp_nsp_close(nsp);
2365 : : }
2366 : :
2367 : : void
2368 : 0 : nfp_net_get_fw_version(struct nfp_cpp *cpp,
2369 : : uint32_t *mip_version)
2370 : : {
2371 : : struct nfp_mip *mip;
2372 : :
2373 : 0 : mip = nfp_mip_open(cpp);
2374 [ # # ]: 0 : if (mip == NULL) {
2375 : 0 : *mip_version = 0;
2376 : 0 : return;
2377 : : }
2378 : :
2379 : 0 : *mip_version = nfp_mip_fw_version(mip);
2380 : :
2381 : 0 : nfp_mip_close(mip);
2382 : : }
2383 : :
2384 : : static void
2385 : 0 : nfp_net_get_mip_name(struct nfp_net_hw_priv *hw_priv,
2386 : : char *mip_name)
2387 : : {
2388 : : struct nfp_mip *mip;
2389 : :
2390 : 0 : mip = nfp_mip_open(hw_priv->pf_dev->cpp);
2391 [ # # ]: 0 : if (mip == NULL)
2392 : : return;
2393 : :
2394 : 0 : strlcpy(mip_name, nfp_mip_name(mip), FW_VER_LEN);
2395 : :
2396 : 0 : nfp_mip_close(mip);
2397 : : }
2398 : :
2399 : : static void
2400 : 0 : nfp_net_get_app_name(struct nfp_net_hw_priv *hw_priv,
2401 : : char *app_name)
2402 : : {
2403 [ # # # ]: 0 : switch (hw_priv->pf_dev->app_fw_id) {
2404 : : case NFP_APP_FW_CORE_NIC:
2405 : : strlcpy(app_name, "nic", FW_VER_LEN);
2406 : : break;
2407 : : case NFP_APP_FW_FLOWER_NIC:
2408 : : strlcpy(app_name, "flower", FW_VER_LEN);
2409 : : break;
2410 : : default:
2411 : : strlcpy(app_name, "unknown", FW_VER_LEN);
2412 : : break;
2413 : : }
2414 : 0 : }
2415 : :
2416 : : int
2417 : 0 : nfp_net_firmware_version_get(struct rte_eth_dev *dev,
2418 : : char *fw_version,
2419 : : size_t fw_size)
2420 : : {
2421 : : struct nfp_net_hw *hw;
2422 : : struct nfp_pf_dev *pf_dev;
2423 : : struct nfp_net_hw_priv *hw_priv;
2424 : 0 : char app_name[FW_VER_LEN] = {0};
2425 : 0 : char mip_name[FW_VER_LEN] = {0};
2426 : 0 : char nsp_version[FW_VER_LEN] = {0};
2427 : 0 : char vnic_version[FW_VER_LEN] = {0};
2428 : :
2429 [ # # ]: 0 : if (fw_size < FW_VER_LEN)
2430 : : return FW_VER_LEN;
2431 : :
2432 : 0 : hw = nfp_net_get_hw(dev);
2433 : 0 : hw_priv = dev->process_private;
2434 : 0 : pf_dev = hw_priv->pf_dev;
2435 : :
2436 [ # # ]: 0 : if (hw->fw_version[0] != 0) {
2437 : 0 : snprintf(fw_version, FW_VER_LEN, "%s", hw->fw_version);
2438 : 0 : return 0;
2439 : : }
2440 : :
2441 [ # # ]: 0 : if (!rte_eth_dev_is_repr(dev)) {
2442 : 0 : snprintf(vnic_version, FW_VER_LEN, "%d.%d.%d.%d",
2443 : 0 : pf_dev->ver.extend, pf_dev->ver.class,
2444 : 0 : pf_dev->ver.major, pf_dev->ver.minor);
2445 : : } else {
2446 : : snprintf(vnic_version, FW_VER_LEN, "*");
2447 : : }
2448 : :
2449 : 0 : nfp_net_get_nsp_info(hw_priv, nsp_version);
2450 : 0 : nfp_net_get_mip_name(hw_priv, mip_name);
2451 : 0 : nfp_net_get_app_name(hw_priv, app_name);
2452 : :
2453 [ # # # # ]: 0 : if (nsp_version[0] == 0 || mip_name[0] == 0) {
2454 : : snprintf(fw_version, FW_VER_LEN, "%s %s %s %s",
2455 : : vnic_version, nsp_version, mip_name, app_name);
2456 : 0 : return 0;
2457 : : }
2458 : :
2459 : 0 : snprintf(hw->fw_version, FW_VER_LEN, "%s %s %s %s",
2460 : : vnic_version, nsp_version, mip_name, app_name);
2461 : :
2462 : : snprintf(fw_version, FW_VER_LEN, "%s", hw->fw_version);
2463 : :
2464 : 0 : return 0;
2465 : : }
2466 : :
2467 : : bool
2468 : 0 : nfp_net_is_valid_nfd_version(struct nfp_net_fw_ver version)
2469 : : {
2470 : 0 : uint8_t nfd_version = version.extend;
2471 : :
2472 [ # # ]: 0 : if (nfd_version == NFP_NET_CFG_VERSION_DP_NFD3)
2473 : : return true;
2474 : :
2475 [ # # ]: 0 : if (nfd_version == NFP_NET_CFG_VERSION_DP_NFDK) {
2476 [ # # ]: 0 : if (version.major < 5) {
2477 : 0 : PMD_INIT_LOG(ERR, "NFDK must use ABI 5 or newer, found: %d.",
2478 : : version.major);
2479 : 0 : return false;
2480 : : }
2481 : :
2482 : : return true;
2483 : : }
2484 : :
2485 : : return false;
2486 : : }
2487 : :
2488 : : bool
2489 : 0 : nfp_net_is_valid_version_class(struct nfp_net_fw_ver version)
2490 : : {
2491 [ # # ]: 0 : switch (version.class) {
2492 : : case NFP_NET_CFG_VERSION_CLASS_GENERIC:
2493 : : return true;
2494 : : case NFP_NET_CFG_VERSION_CLASS_NO_EMEM:
2495 : : return true;
2496 : 0 : default:
2497 : 0 : return false;
2498 : : }
2499 : : }
2500 : :
2501 : : void
2502 : 0 : nfp_net_ctrl_bar_size_set(struct nfp_pf_dev *pf_dev)
2503 : : {
2504 [ # # ]: 0 : if (pf_dev->ver.class == NFP_NET_CFG_VERSION_CLASS_GENERIC)
2505 : 0 : pf_dev->ctrl_bar_size = NFP_NET_CFG_BAR_SZ_32K;
2506 : : else
2507 : 0 : pf_dev->ctrl_bar_size = NFP_NET_CFG_BAR_SZ_8K;
2508 : 0 : }
2509 : :
2510 : : /* Disable rx and tx functions to allow for reconfiguring. */
2511 : : int
2512 : 0 : nfp_net_stop(struct rte_eth_dev *dev)
2513 : : {
2514 : : int ret;
2515 : : struct nfp_net_hw *hw;
2516 : : struct nfp_net_hw_priv *hw_priv;
2517 : :
2518 : 0 : hw = nfp_net_get_hw(dev);
2519 : 0 : hw_priv = dev->process_private;
2520 : :
2521 : 0 : nfp_net_disable_queues(dev);
2522 : :
2523 : : /* Clear queues */
2524 : 0 : nfp_net_stop_tx_queue(dev);
2525 : 0 : nfp_net_stop_rx_queue(dev);
2526 : :
2527 : 0 : ret = nfp_eth_set_configured(hw_priv->pf_dev->cpp, hw->nfp_idx, 0);
2528 : : if (ret < 0)
2529 : : return ret;
2530 : :
2531 : : return 0;
2532 : : }
2533 : :
2534 : : static enum rte_eth_fc_mode
2535 : : nfp_net_get_pause_mode(struct nfp_eth_table_port *eth_port)
2536 : : {
2537 : : enum rte_eth_fc_mode mode;
2538 : :
2539 : 0 : if (eth_port->rx_pause_enabled) {
2540 [ # # # # ]: 0 : if (eth_port->tx_pause_enabled)
2541 : : mode = RTE_ETH_FC_FULL;
2542 : : else
2543 : : mode = RTE_ETH_FC_RX_PAUSE;
2544 : : } else {
2545 [ # # # # ]: 0 : if (eth_port->tx_pause_enabled)
2546 : : mode = RTE_ETH_FC_TX_PAUSE;
2547 : : else
2548 : : mode = RTE_ETH_FC_NONE;
2549 : : }
2550 : :
2551 : : return mode;
2552 : : }
2553 : :
2554 : : int
2555 : 0 : nfp_net_flow_ctrl_get(struct rte_eth_dev *dev,
2556 : : struct rte_eth_fc_conf *fc_conf)
2557 : : {
2558 : : struct nfp_net_hw_priv *hw_priv;
2559 : : struct nfp_eth_table *nfp_eth_table;
2560 : : struct nfp_eth_table_port *eth_port;
2561 : :
2562 : 0 : hw_priv = dev->process_private;
2563 [ # # # # ]: 0 : if (hw_priv == NULL || hw_priv->pf_dev == NULL)
2564 : : return -EINVAL;
2565 : :
2566 : 0 : nfp_eth_table = hw_priv->pf_dev->nfp_eth_table;
2567 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[dev->data->port_id];
2568 : :
2569 : : /* Currently only RX/TX switch are supported */
2570 : 0 : fc_conf->mode = nfp_net_get_pause_mode(eth_port);
2571 : :
2572 : 0 : return 0;
2573 : : }
2574 : :
2575 : : static int
2576 : 0 : nfp_net_pause_frame_set(struct nfp_net_hw_priv *hw_priv,
2577 : : struct nfp_eth_table_port *eth_port,
2578 : : enum rte_eth_fc_mode mode)
2579 : : {
2580 : : int err;
2581 : : bool flag;
2582 : : struct nfp_nsp *nsp;
2583 : :
2584 : 0 : nsp = nfp_eth_config_start(hw_priv->pf_dev->cpp, eth_port->index);
2585 [ # # ]: 0 : if (nsp == NULL) {
2586 : 0 : PMD_DRV_LOG(ERR, "NFP error when obtaining NSP handle.");
2587 : 0 : return -EIO;
2588 : : }
2589 : :
2590 : 0 : flag = (mode & RTE_ETH_FC_TX_PAUSE) == 0 ? false : true;
2591 : 0 : err = nfp_eth_set_tx_pause(nsp, flag);
2592 [ # # ]: 0 : if (err != 0) {
2593 : 0 : PMD_DRV_LOG(ERR, "Failed to configure TX pause frame.");
2594 : 0 : nfp_eth_config_cleanup_end(nsp);
2595 : 0 : return err;
2596 : : }
2597 : :
2598 : 0 : flag = (mode & RTE_ETH_FC_RX_PAUSE) == 0 ? false : true;
2599 : 0 : err = nfp_eth_set_rx_pause(nsp, flag);
2600 [ # # ]: 0 : if (err != 0) {
2601 : 0 : PMD_DRV_LOG(ERR, "Failed to configure RX pause frame.");
2602 : 0 : nfp_eth_config_cleanup_end(nsp);
2603 : 0 : return err;
2604 : : }
2605 : :
2606 : 0 : err = nfp_eth_config_commit_end(nsp);
2607 [ # # ]: 0 : if (err < 0) {
2608 : 0 : PMD_DRV_LOG(ERR, "Failed to configure pause frame.");
2609 : 0 : return err;
2610 : : }
2611 : :
2612 : : return 0;
2613 : : }
2614 : :
2615 : : int
2616 : 0 : nfp_net_flow_ctrl_set(struct rte_eth_dev *dev,
2617 : : struct rte_eth_fc_conf *fc_conf)
2618 : : {
2619 : : int ret;
2620 : : uint8_t idx;
2621 : : enum rte_eth_fc_mode set_mode;
2622 : : struct nfp_net_hw_priv *hw_priv;
2623 : : enum rte_eth_fc_mode original_mode;
2624 : : struct nfp_eth_table *nfp_eth_table;
2625 : : struct nfp_eth_table_port *eth_port;
2626 : :
2627 : 0 : idx = nfp_net_get_idx(dev);
2628 : 0 : hw_priv = dev->process_private;
2629 [ # # # # ]: 0 : if (hw_priv == NULL || hw_priv->pf_dev == NULL)
2630 : : return -EINVAL;
2631 : :
2632 : 0 : nfp_eth_table = hw_priv->pf_dev->nfp_eth_table;
2633 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[idx];
2634 : :
2635 : : original_mode = nfp_net_get_pause_mode(eth_port);
2636 : 0 : set_mode = fc_conf->mode;
2637 : :
2638 [ # # ]: 0 : if (set_mode == original_mode)
2639 : : return 0;
2640 : :
2641 : 0 : ret = nfp_net_pause_frame_set(hw_priv, eth_port, set_mode);
2642 [ # # ]: 0 : if (ret != 0)
2643 : : return ret;
2644 : :
2645 : : /* Update eth_table after modifying RX/TX pause frame mode. */
2646 : 0 : eth_port->tx_pause_enabled = (set_mode & RTE_ETH_FC_TX_PAUSE) == 0 ? false : true;
2647 : 0 : eth_port->rx_pause_enabled = (set_mode & RTE_ETH_FC_RX_PAUSE) == 0 ? false : true;
2648 : :
2649 : 0 : return 0;
2650 : : }
2651 : :
2652 : : int
2653 : 0 : nfp_net_fec_get_capability(struct rte_eth_dev *dev,
2654 : : struct rte_eth_fec_capa *speed_fec_capa,
2655 : : __rte_unused unsigned int num)
2656 : : {
2657 : : uint8_t idx;
2658 : : uint16_t speed;
2659 : : uint32_t supported_fec;
2660 : : struct nfp_net_hw_priv *hw_priv;
2661 : : struct nfp_eth_table *nfp_eth_table;
2662 : : struct nfp_eth_table_port *eth_port;
2663 : :
2664 : 0 : idx = nfp_net_get_idx(dev);
2665 : 0 : hw_priv = dev->process_private;
2666 [ # # # # ]: 0 : if (hw_priv == NULL || hw_priv->pf_dev == NULL)
2667 : : return -EINVAL;
2668 : :
2669 : 0 : nfp_eth_table = hw_priv->pf_dev->nfp_eth_table;
2670 : 0 : eth_port = &nfp_eth_table->ports[idx];
2671 : :
2672 [ # # ]: 0 : speed = eth_port->speed;
2673 : : supported_fec = nfp_eth_supported_fec_modes(eth_port);
2674 [ # # ]: 0 : if (speed == 0 || supported_fec == 0) {
2675 : 0 : PMD_DRV_LOG(ERR, "FEC modes supported or Speed is invalid.");
2676 : 0 : return -EINVAL;
2677 : : }
2678 : :
2679 [ # # ]: 0 : if (speed_fec_capa == NULL)
2680 : : return NFP_FEC_CAPA_ENTRY_NUM;
2681 : :
2682 : 0 : speed_fec_capa->speed = speed;
2683 : :
2684 [ # # ]: 0 : if ((supported_fec & NFP_FEC_AUTO) != 0)
2685 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
2686 [ # # ]: 0 : if ((supported_fec & NFP_FEC_BASER) != 0)
2687 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
2688 [ # # ]: 0 : if ((supported_fec & NFP_FEC_REED_SOLOMON) != 0)
2689 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(RS);
2690 [ # # ]: 0 : if ((supported_fec & NFP_FEC_DISABLED) != 0)
2691 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
2692 : :
2693 : : return NFP_FEC_CAPA_ENTRY_NUM;
2694 : : }
2695 : :
2696 : : static uint32_t
2697 [ # # ]: 0 : nfp_net_fec_nfp_to_rte(enum nfp_eth_fec fec)
2698 : : {
2699 : : switch (fec) {
2700 : : case NFP_FEC_AUTO_BIT:
2701 : : return RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
2702 : : case NFP_FEC_BASER_BIT:
2703 : : return RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
2704 : : case NFP_FEC_REED_SOLOMON_BIT:
2705 : : return RTE_ETH_FEC_MODE_CAPA_MASK(RS);
2706 : : case NFP_FEC_DISABLED_BIT:
2707 : : return RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
2708 : 0 : default:
2709 : 0 : PMD_DRV_LOG(ERR, "FEC mode is invalid.");
2710 : 0 : return 0;
2711 : : }
2712 : : }
2713 : :
2714 : : int
2715 : 0 : nfp_net_fec_get(struct rte_eth_dev *dev,
2716 : : uint32_t *fec_capa)
2717 : : {
2718 : : uint8_t idx;
2719 : : struct nfp_net_hw_priv *hw_priv;
2720 : : struct nfp_eth_table *nfp_eth_table;
2721 : : struct nfp_eth_table_port *eth_port;
2722 : :
2723 : 0 : idx = nfp_net_get_idx(dev);
2724 : 0 : hw_priv = dev->process_private;
2725 [ # # # # ]: 0 : if (hw_priv == NULL || hw_priv->pf_dev == NULL)
2726 : : return -EINVAL;
2727 : :
2728 [ # # ]: 0 : if (dev->data->dev_link.link_status == RTE_ETH_LINK_DOWN) {
2729 : 0 : nfp_eth_table = nfp_eth_read_ports(hw_priv->pf_dev->cpp);
2730 : 0 : hw_priv->pf_dev->nfp_eth_table->ports[idx] = nfp_eth_table->ports[idx];
2731 : 0 : free(nfp_eth_table);
2732 : : }
2733 : :
2734 : 0 : nfp_eth_table = hw_priv->pf_dev->nfp_eth_table;
2735 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[idx];
2736 : :
2737 [ # # ]: 0 : if (!nfp_eth_can_support_fec(eth_port)) {
2738 : 0 : PMD_DRV_LOG(ERR, "NFP can not support FEC.");
2739 : 0 : return -ENOTSUP;
2740 : : }
2741 : :
2742 : : /*
2743 : : * If link is down and AUTO is enabled, AUTO is returned, otherwise,
2744 : : * configured FEC mode is returned.
2745 : : * If link is up, current FEC mode is returned.
2746 : : */
2747 [ # # ]: 0 : if (dev->data->dev_link.link_status == RTE_ETH_LINK_DOWN)
2748 : 0 : *fec_capa = nfp_net_fec_nfp_to_rte(eth_port->fec);
2749 : : else
2750 : 0 : *fec_capa = nfp_net_fec_nfp_to_rte(eth_port->act_fec);
2751 : :
2752 [ # # ]: 0 : if (*fec_capa == 0)
2753 : 0 : return -EINVAL;
2754 : :
2755 : : return 0;
2756 : : }
2757 : :
2758 : : static enum nfp_eth_fec
2759 : : nfp_net_fec_rte_to_nfp(uint32_t fec)
2760 : : {
2761 : : switch (fec) {
2762 : : case RTE_BIT32(RTE_ETH_FEC_AUTO):
2763 : : return NFP_FEC_AUTO_BIT;
2764 : : case RTE_BIT32(RTE_ETH_FEC_NOFEC):
2765 : : return NFP_FEC_DISABLED_BIT;
2766 : : case RTE_BIT32(RTE_ETH_FEC_RS):
2767 : : return NFP_FEC_REED_SOLOMON_BIT;
2768 : : case RTE_BIT32(RTE_ETH_FEC_BASER):
2769 : : return NFP_FEC_BASER_BIT;
2770 : : default:
2771 : : return NFP_FEC_INVALID_BIT;
2772 : : }
2773 : : }
2774 : :
2775 : : int
2776 : 0 : nfp_net_fec_set(struct rte_eth_dev *dev,
2777 : : uint32_t fec_capa)
2778 : : {
2779 : : int ret;
2780 : : uint8_t idx;
2781 : : enum nfp_eth_fec fec;
2782 : : uint32_t supported_fec;
2783 : : struct nfp_net_hw_priv *hw_priv;
2784 : : struct nfp_eth_table *nfp_eth_table;
2785 : : struct nfp_eth_table_port *eth_port;
2786 : :
2787 : 0 : idx = nfp_net_get_idx(dev);
2788 : 0 : hw_priv = dev->process_private;
2789 [ # # # # ]: 0 : if (hw_priv == NULL || hw_priv->pf_dev == NULL)
2790 : : return -EINVAL;
2791 : :
2792 : 0 : nfp_eth_table = hw_priv->pf_dev->nfp_eth_table;
2793 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[idx];
2794 : :
2795 : : supported_fec = nfp_eth_supported_fec_modes(eth_port);
2796 [ # # ]: 0 : if (supported_fec == 0) {
2797 : 0 : PMD_DRV_LOG(ERR, "NFP can not support FEC.");
2798 : 0 : return -ENOTSUP;
2799 : : }
2800 : :
2801 : : fec = nfp_net_fec_rte_to_nfp(fec_capa);
2802 [ # # ]: 0 : if (fec == NFP_FEC_INVALID_BIT) {
2803 : 0 : PMD_DRV_LOG(ERR, "FEC modes is invalid.");
2804 : 0 : return -EINVAL;
2805 : : }
2806 : :
2807 [ # # ]: 0 : if ((RTE_BIT32(fec) & supported_fec) == 0) {
2808 : 0 : PMD_DRV_LOG(ERR, "Unsupported FEC mode is set.");
2809 : 0 : return -EIO;
2810 : : }
2811 : :
2812 : 0 : ret = nfp_eth_set_fec(hw_priv->pf_dev->cpp, eth_port->index, fec);
2813 [ # # ]: 0 : if (ret < 0) {
2814 : 0 : PMD_DRV_LOG(ERR, "NFP set FEC mode failed.");
2815 : 0 : return ret;
2816 : : }
2817 : :
2818 : : return 0;
2819 : : }
2820 : :
2821 : : uint32_t
2822 : 0 : nfp_net_get_phyports_from_nsp(struct nfp_pf_dev *pf_dev)
2823 : : {
2824 [ # # ]: 0 : if (pf_dev->multi_pf.enabled)
2825 : : return 1;
2826 : : else
2827 : 0 : return pf_dev->nfp_eth_table->count;
2828 : : }
2829 : :
2830 : : uint32_t
2831 : 0 : nfp_net_get_phyports_from_fw(struct nfp_pf_dev *pf_dev)
2832 : : {
2833 : 0 : int ret = 0;
2834 : : uint8_t total_phyports;
2835 : : char pf_name[RTE_ETH_NAME_MAX_LEN];
2836 : :
2837 : : /* Read the number of vNIC's created for the PF */
2838 : 0 : snprintf(pf_name, sizeof(pf_name), "nfd_cfg_pf%u_num_ports",
2839 : 0 : pf_dev->multi_pf.function_id);
2840 : 0 : total_phyports = nfp_rtsym_read_le(pf_dev->sym_tbl, pf_name, &ret);
2841 [ # # # # ]: 0 : if (ret != 0 || total_phyports == 0 || total_phyports > 8) {
2842 : 0 : PMD_INIT_LOG(ERR, "%s symbol with wrong value", pf_name);
2843 : 0 : return 0;
2844 : : }
2845 : :
2846 : 0 : return total_phyports;
2847 : : }
2848 : :
2849 : : uint8_t
2850 : 0 : nfp_function_id_get(const struct nfp_pf_dev *pf_dev,
2851 : : uint8_t port_id)
2852 : : {
2853 [ # # ]: 0 : if (pf_dev->multi_pf.enabled)
2854 : 0 : return pf_dev->multi_pf.function_id;
2855 : :
2856 : : return port_id;
2857 : : }
2858 : :
2859 : : static int
2860 : : nfp_net_sriov_check(struct nfp_pf_dev *pf_dev,
2861 : : uint16_t cap)
2862 : : {
2863 : : uint16_t cap_vf;
2864 : :
2865 : 0 : cap_vf = nn_readw(pf_dev->vf_cfg_tbl_bar + NFP_NET_VF_CFG_MB_CAP);
2866 [ # # # # ]: 0 : if ((cap_vf & cap) != cap)
2867 : : return -ENOTSUP;
2868 : :
2869 : : return 0;
2870 : : }
2871 : :
2872 : : static int
2873 : 0 : nfp_net_sriov_update(struct nfp_net_hw *net_hw,
2874 : : struct nfp_pf_dev *pf_dev,
2875 : : uint16_t update)
2876 : : {
2877 : : int ret;
2878 : :
2879 : : /* Reuse NFP_NET_VF_CFG_MB_VF_NUM to pass vf_base_id to FW. */
2880 : 0 : ret = nfp_net_vf_reconfig(net_hw, pf_dev, update, pf_dev->vf_base_id,
2881 : : NFP_NET_VF_CFG_MB_VF_NUM);
2882 [ # # ]: 0 : if (ret != 0) {
2883 : 0 : PMD_INIT_LOG(ERR, "Error nfp VF reconfig.");
2884 : 0 : return ret;
2885 : : }
2886 : :
2887 : : return 0;
2888 : : }
2889 : :
2890 : : static int
2891 : 0 : nfp_net_vf_queues_config(struct nfp_net_hw *net_hw,
2892 : : struct nfp_pf_dev *pf_dev)
2893 : : {
2894 : : int ret;
2895 : : uint32_t i;
2896 : : uint32_t offset;
2897 : :
2898 : : ret = nfp_net_sriov_check(pf_dev, NFP_NET_VF_CFG_MB_CAP_QUEUE_CONFIG);
2899 : : if (ret != 0) {
2900 : : if (ret == -ENOTSUP) {
2901 : 0 : PMD_INIT_LOG(DEBUG, "Set VF max queue not supported.");
2902 : 0 : return 0;
2903 : : }
2904 : :
2905 : : PMD_INIT_LOG(ERR, "Set VF max queue failed.");
2906 : : return ret;
2907 : : }
2908 : :
2909 : 0 : offset = NFP_NET_VF_CFG_MB_SZ + pf_dev->max_vfs * NFP_NET_VF_CFG_SZ;
2910 [ # # ]: 0 : for (i = 0; i < pf_dev->sriov_vf; i++) {
2911 : 0 : ret = nfp_net_vf_reconfig(net_hw, pf_dev, NFP_NET_VF_CFG_MB_UPD_QUEUE_CONFIG,
2912 : 0 : pf_dev->queue_per_vf, pf_dev->vf_base_id + offset + i);
2913 [ # # ]: 0 : if (ret != 0) {
2914 : 0 : PMD_INIT_LOG(ERR, "Set VF max_queue failed.");
2915 : 0 : return ret;
2916 : : }
2917 : : }
2918 : :
2919 : : return 0;
2920 : : }
2921 : :
2922 : : static int
2923 : 0 : nfp_net_sriov_init(struct nfp_net_hw *net_hw,
2924 : : struct nfp_pf_dev *pf_dev)
2925 : : {
2926 : : int ret;
2927 : :
2928 : : ret = nfp_net_sriov_check(pf_dev, NFP_NET_VF_CFG_MB_CAP_SPLIT);
2929 : : if (ret != 0) {
2930 : : if (ret == -ENOTSUP) {
2931 : 0 : PMD_INIT_LOG(DEBUG, "Set VF split not supported.");
2932 : 0 : return 0;
2933 : : }
2934 : :
2935 : : PMD_INIT_LOG(ERR, "Set VF split failed.");
2936 : : return ret;
2937 : : }
2938 : :
2939 : 0 : nn_writeb(pf_dev->sriov_vf, pf_dev->vf_cfg_tbl_bar + NFP_NET_VF_CFG_MB_VF_CNT);
2940 : :
2941 : 0 : ret = nfp_net_sriov_update(net_hw, pf_dev, NFP_NET_VF_CFG_MB_UPD_SPLIT);
2942 [ # # ]: 0 : if (ret != 0) {
2943 : 0 : PMD_INIT_LOG(ERR, "The nfp sriov update spilt failed.");
2944 : 0 : return ret;
2945 : : }
2946 : :
2947 : : return 0;
2948 : : }
2949 : :
2950 : : int
2951 : 0 : nfp_net_vf_config_app_init(struct nfp_net_hw *net_hw,
2952 : : struct nfp_pf_dev *pf_dev)
2953 : : {
2954 : : int ret;
2955 : :
2956 [ # # ]: 0 : if (pf_dev->sriov_vf == 0)
2957 : : return 0;
2958 : :
2959 : 0 : ret = nfp_net_sriov_init(net_hw, pf_dev);
2960 [ # # ]: 0 : if (ret != 0) {
2961 : 0 : PMD_INIT_LOG(ERR, "Failed to init sriov module.");
2962 : 0 : return ret;
2963 : : }
2964 : :
2965 : 0 : ret = nfp_net_vf_queues_config(net_hw, pf_dev);
2966 [ # # ]: 0 : if (ret != 0) {
2967 : 0 : PMD_INIT_LOG(ERR, "Failed to config vf queue.");
2968 : 0 : return ret;
2969 : : }
2970 : :
2971 : : return 0;
2972 : : }
2973 : :
2974 : : static inline bool
2975 : 0 : nfp_net_meta_has_no_port_type(__rte_unused struct nfp_net_meta_parsed *meta)
2976 : : {
2977 : 0 : return true;
2978 : : }
2979 : :
2980 : : static inline bool
2981 : 0 : nfp_net_meta_is_not_pf_port(__rte_unused struct nfp_net_meta_parsed *meta)
2982 : : {
2983 : 0 : return false;
2984 : : }
2985 : :
2986 : : static inline bool
2987 : 0 : nfp_net_meta_is_pf_port(struct nfp_net_meta_parsed *meta)
2988 : : {
2989 : 0 : return nfp_flower_port_is_phy_port(meta->port_id);
2990 : : }
2991 : :
2992 : : bool
2993 : 0 : nfp_net_recv_pkt_meta_check_register(struct nfp_net_hw_priv *hw_priv)
2994 : : {
2995 : : struct nfp_pf_dev *pf_dev;
2996 : :
2997 : 0 : pf_dev = hw_priv->pf_dev;
2998 [ # # ]: 0 : if (!hw_priv->is_pf) {
2999 : 0 : pf_dev->recv_pkt_meta_check_t = nfp_net_meta_has_no_port_type;
3000 : 0 : return true;
3001 : : }
3002 : :
3003 [ # # # ]: 0 : switch (pf_dev->app_fw_id) {
3004 : 0 : case NFP_APP_FW_CORE_NIC:
3005 : 0 : pf_dev->recv_pkt_meta_check_t = nfp_net_meta_has_no_port_type;
3006 : 0 : break;
3007 : 0 : case NFP_APP_FW_FLOWER_NIC:
3008 [ # # ]: 0 : if (pf_dev->multi_pf.enabled)
3009 : 0 : pf_dev->recv_pkt_meta_check_t = nfp_net_meta_is_pf_port;
3010 : : else
3011 : 0 : pf_dev->recv_pkt_meta_check_t = nfp_net_meta_is_not_pf_port;
3012 : : break;
3013 : 0 : default:
3014 : 0 : PMD_INIT_LOG(ERR, "Unsupported Firmware loaded.");
3015 : 0 : return false;
3016 : : }
3017 : :
3018 : : return true;
3019 : : }
3020 : :
3021 : : static int
3022 : : nfp_net_get_nfp_index(struct rte_eth_dev *dev)
3023 : : {
3024 : : int nfp_idx;
3025 : :
3026 [ # # # # : 0 : if (rte_eth_dev_is_repr(dev)) {
# # ]
3027 : : struct nfp_flower_representor *repr;
3028 : 0 : repr = dev->data->dev_private;
3029 : 0 : nfp_idx = repr->nfp_idx;
3030 : : } else {
3031 : : struct nfp_net_hw *net_hw;
3032 : 0 : net_hw = dev->data->dev_private;
3033 : 0 : nfp_idx = net_hw->nfp_idx;
3034 : : }
3035 : :
3036 : : return nfp_idx;
3037 : : }
3038 : :
3039 : : int
3040 : 0 : nfp_net_get_eeprom_len(__rte_unused struct rte_eth_dev *dev)
3041 : : {
3042 : 0 : return RTE_ETHER_ADDR_LEN;
3043 : : }
3044 : :
3045 : : static int
3046 : 0 : nfp_net_get_port_mac_hwinfo(struct nfp_net_hw_priv *hw_priv,
3047 : : uint32_t index,
3048 : : struct rte_ether_addr *mac_addr)
3049 : : {
3050 : : int ret;
3051 : : char hwinfo[32];
3052 : : struct nfp_nsp *nsp;
3053 : :
3054 : : snprintf(hwinfo, sizeof(hwinfo), "eth%u.mac", index);
3055 : :
3056 : 0 : nsp = nfp_nsp_open(hw_priv->pf_dev->cpp);
3057 [ # # ]: 0 : if (nsp == NULL)
3058 : : return -EOPNOTSUPP;
3059 : :
3060 : 0 : ret = nfp_nsp_hwinfo_lookup(nsp, hwinfo, sizeof(hwinfo));
3061 : 0 : nfp_nsp_close(nsp);
3062 : :
3063 [ # # ]: 0 : if (ret != 0) {
3064 : 0 : PMD_DRV_LOG(ERR, "Read persistent MAC address failed for eth_index %u.", index);
3065 : 0 : return ret;
3066 : : }
3067 : :
3068 : 0 : ret = rte_ether_unformat_addr(hwinfo, mac_addr);
3069 [ # # ]: 0 : if (ret != 0) {
3070 : 0 : PMD_DRV_LOG(ERR, "Can not parse persistent MAC address.");
3071 : 0 : return -EOPNOTSUPP;
3072 : : }
3073 : :
3074 : : return 0;
3075 : : }
3076 : :
3077 : : static int
3078 : 0 : nfp_net_set_port_mac_hwinfo(struct nfp_net_hw_priv *hw_priv,
3079 : : uint32_t index,
3080 : : struct rte_ether_addr *mac_addr)
3081 : : {
3082 : : int ret;
3083 : : char hwinfo_mac[32];
3084 : : struct nfp_nsp *nsp;
3085 : : char buf[RTE_ETHER_ADDR_FMT_SIZE];
3086 : :
3087 : 0 : rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, mac_addr);
3088 : : snprintf(hwinfo_mac, sizeof(hwinfo_mac), "eth%u.mac=%s", index, buf);
3089 : :
3090 : 0 : nsp = nfp_nsp_open(hw_priv->pf_dev->cpp);
3091 [ # # ]: 0 : if (nsp == NULL)
3092 : : return -EOPNOTSUPP;
3093 : :
3094 : 0 : ret = nfp_nsp_hwinfo_set(nsp, hwinfo_mac, sizeof(hwinfo_mac));
3095 : 0 : nfp_nsp_close(nsp);
3096 : :
3097 [ # # ]: 0 : if (ret != 0) {
3098 : 0 : PMD_DRV_LOG(ERR, "HWinfo set failed: %d.", ret);
3099 : 0 : return ret;
3100 : : }
3101 : :
3102 : : return 0;
3103 : : }
3104 : :
3105 : : int
3106 : 0 : nfp_net_get_eeprom(struct rte_eth_dev *dev,
3107 : : struct rte_dev_eeprom_info *eeprom)
3108 : : {
3109 : : int ret;
3110 : : uint32_t nfp_idx;
3111 : : struct nfp_net_hw *net_hw;
3112 : : struct rte_ether_addr mac_addr;
3113 : : struct nfp_net_hw_priv *hw_priv;
3114 : :
3115 [ # # ]: 0 : if (eeprom->length == 0)
3116 : : return -EINVAL;
3117 : :
3118 [ # # ]: 0 : hw_priv = dev->process_private;
3119 : 0 : nfp_idx = nfp_net_get_nfp_index(dev);
3120 : :
3121 : 0 : ret = nfp_net_get_port_mac_hwinfo(hw_priv, nfp_idx, &mac_addr);
3122 [ # # ]: 0 : if (ret != 0)
3123 : : return -EOPNOTSUPP;
3124 : :
3125 : 0 : net_hw = nfp_net_get_hw(dev);
3126 : 0 : eeprom->magic = net_hw->vendor_id | (net_hw->device_id << 16);
3127 : 0 : memcpy(eeprom->data, mac_addr.addr_bytes + eeprom->offset, eeprom->length);
3128 : :
3129 : 0 : return 0;
3130 : : }
3131 : :
3132 : : int
3133 : 0 : nfp_net_set_eeprom(struct rte_eth_dev *dev,
3134 : : struct rte_dev_eeprom_info *eeprom)
3135 : : {
3136 : : int ret;
3137 : : uint32_t nfp_idx;
3138 : : struct nfp_net_hw *net_hw;
3139 : : struct rte_ether_addr mac_addr;
3140 : : struct nfp_net_hw_priv *hw_priv;
3141 : :
3142 [ # # ]: 0 : if (eeprom->length == 0)
3143 : : return -EINVAL;
3144 : :
3145 : 0 : net_hw = nfp_net_get_hw(dev);
3146 [ # # ]: 0 : if (eeprom->magic != (uint32_t)(net_hw->vendor_id | (net_hw->device_id << 16)))
3147 : : return -EINVAL;
3148 : :
3149 [ # # ]: 0 : hw_priv = dev->process_private;
3150 : 0 : nfp_idx = nfp_net_get_nfp_index(dev);
3151 : 0 : ret = nfp_net_get_port_mac_hwinfo(hw_priv, nfp_idx, &mac_addr);
3152 [ # # ]: 0 : if (ret != 0)
3153 : : return -EOPNOTSUPP;
3154 : :
3155 : 0 : memcpy(mac_addr.addr_bytes + eeprom->offset, eeprom->data, eeprom->length);
3156 : 0 : ret = nfp_net_set_port_mac_hwinfo(hw_priv, nfp_idx, &mac_addr);
3157 [ # # ]: 0 : if (ret != 0)
3158 : 0 : return -EOPNOTSUPP;
3159 : :
3160 : : return 0;
3161 : : }
3162 : :
3163 : : int
3164 : 0 : nfp_net_get_module_info(struct rte_eth_dev *dev,
3165 : : struct rte_eth_dev_module_info *info)
3166 : : {
3167 : : int ret = 0;
3168 : : uint8_t data;
3169 : : uint32_t idx;
3170 : : uint32_t read_len;
3171 : : struct nfp_nsp *nsp;
3172 : : struct nfp_net_hw_priv *hw_priv;
3173 : : struct nfp_eth_table_port *eth_port;
3174 : :
3175 : 0 : hw_priv = dev->process_private;
3176 : 0 : nsp = nfp_nsp_open(hw_priv->pf_dev->cpp);
3177 [ # # ]: 0 : if (nsp == NULL) {
3178 : 0 : PMD_DRV_LOG(ERR, "Unable to open NSP.");
3179 : 0 : return -EIO;
3180 : : }
3181 : :
3182 [ # # ]: 0 : if (!nfp_nsp_has_read_module_eeprom(nsp)) {
3183 : 0 : PMD_DRV_LOG(ERR, "Read module eeprom not supported. Please update flash.");
3184 : : ret = -EOPNOTSUPP;
3185 : 0 : goto exit_close_nsp;
3186 : : }
3187 : :
3188 : 0 : idx = nfp_net_get_idx(dev);
3189 : 0 : eth_port = &hw_priv->pf_dev->nfp_eth_table->ports[idx];
3190 [ # # # # ]: 0 : switch (eth_port->interface) {
3191 : 0 : case NFP_INTERFACE_SFP:
3192 : : /* FALLTHROUGH */
3193 : : case NFP_INTERFACE_SFP28:
3194 : : /* Read which revision the transceiver compiles with */
3195 : 0 : ret = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
3196 : : SFP_SFF8472_COMPLIANCE, &data, 1, &read_len);
3197 [ # # ]: 0 : if (ret != 0)
3198 : 0 : goto exit_close_nsp;
3199 : :
3200 [ # # ]: 0 : if (data == 0) {
3201 : 0 : info->type = RTE_ETH_MODULE_SFF_8079;
3202 : 0 : info->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
3203 : : } else {
3204 : 0 : info->type = RTE_ETH_MODULE_SFF_8472;
3205 : 0 : info->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
3206 : : }
3207 : : break;
3208 : 0 : case NFP_INTERFACE_QSFP:
3209 : : /* Read which revision the transceiver compiles with */
3210 : 0 : ret = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
3211 : : SFP_SFF_REV_COMPLIANCE, &data, 1, &read_len);
3212 [ # # ]: 0 : if (ret != 0)
3213 : 0 : goto exit_close_nsp;
3214 : :
3215 [ # # ]: 0 : if (data == 0) {
3216 : 0 : info->type = RTE_ETH_MODULE_SFF_8436;
3217 : 0 : info->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
3218 : : } else {
3219 : 0 : info->type = RTE_ETH_MODULE_SFF_8636;
3220 : 0 : info->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
3221 : : }
3222 : : break;
3223 : 0 : case NFP_INTERFACE_QSFP28:
3224 : 0 : info->type = RTE_ETH_MODULE_SFF_8636;
3225 : 0 : info->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
3226 : 0 : break;
3227 : 0 : default:
3228 : 0 : PMD_DRV_LOG(ERR, "Unsupported module %#x detected.",
3229 : : eth_port->interface);
3230 : : ret = -EINVAL;
3231 : : }
3232 : :
3233 : 0 : exit_close_nsp:
3234 : 0 : nfp_nsp_close(nsp);
3235 : 0 : return ret;
3236 : : }
3237 : :
3238 : : int
3239 : 0 : nfp_net_get_module_eeprom(struct rte_eth_dev *dev,
3240 : : struct rte_dev_eeprom_info *info)
3241 : : {
3242 : : int ret = 0;
3243 : : uint32_t idx;
3244 : : struct nfp_nsp *nsp;
3245 : : struct nfp_net_hw_priv *hw_priv;
3246 : : struct nfp_eth_table_port *eth_port;
3247 : :
3248 : 0 : hw_priv = dev->process_private;
3249 : 0 : nsp = nfp_nsp_open(hw_priv->pf_dev->cpp);
3250 [ # # ]: 0 : if (nsp == NULL) {
3251 : 0 : PMD_DRV_LOG(ERR, "Unable to open NSP.");
3252 : 0 : return -EIO;
3253 : : }
3254 : :
3255 [ # # ]: 0 : if (!nfp_nsp_has_read_module_eeprom(nsp)) {
3256 : 0 : PMD_DRV_LOG(ERR, "Read module eeprom not supported. Please update flash.");
3257 : : ret = -EOPNOTSUPP;
3258 : 0 : goto exit_close_nsp;
3259 : : }
3260 : :
3261 : 0 : idx = nfp_net_get_idx(dev);
3262 : 0 : eth_port = &hw_priv->pf_dev->nfp_eth_table->ports[idx];
3263 : 0 : ret = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index, info->offset,
3264 : : info->data, info->length, &info->length);
3265 [ # # ]: 0 : if (ret != 0) {
3266 [ # # ]: 0 : if (info->length)
3267 : 0 : PMD_DRV_LOG(ERR, "Incomplete read from module EEPROM: %d.", ret);
3268 : : else
3269 : 0 : PMD_DRV_LOG(ERR, "Read from module EEPROM failed: %d.", ret);
3270 : : }
3271 : :
3272 : 0 : exit_close_nsp:
3273 : 0 : nfp_nsp_close(nsp);
3274 : 0 : return ret;
3275 : : }
3276 : :
3277 : : static int
3278 : 0 : nfp_net_led_control(struct rte_eth_dev *dev,
3279 : : bool is_on)
3280 : : {
3281 : : int ret;
3282 : : uint32_t nfp_idx;
3283 : : struct nfp_net_hw_priv *hw_priv;
3284 : :
3285 [ # # ]: 0 : hw_priv = dev->process_private;
3286 : 0 : nfp_idx = nfp_net_get_nfp_index(dev);
3287 : :
3288 : 0 : ret = nfp_eth_set_idmode(hw_priv->pf_dev->cpp, nfp_idx, is_on);
3289 [ # # ]: 0 : if (ret < 0) {
3290 : 0 : PMD_DRV_LOG(ERR, "Set nfp idmode failed.");
3291 : 0 : return ret;
3292 : : }
3293 : :
3294 : : return 0;
3295 : : }
3296 : :
3297 : : int
3298 : 0 : nfp_net_led_on(struct rte_eth_dev *dev)
3299 : : {
3300 : 0 : return nfp_net_led_control(dev, true);
3301 : : }
3302 : :
3303 : : int
3304 : 0 : nfp_net_led_off(struct rte_eth_dev *dev)
3305 : : {
3306 : 0 : return nfp_net_led_control(dev, false);
3307 : : }
3308 : :
3309 : : void
3310 : 0 : nfp_net_rss_algo_capa_get(struct nfp_net_hw *hw,
3311 : : struct rte_eth_dev_info *dev_info)
3312 : : {
3313 : : uint32_t cap_rss;
3314 : :
3315 : 0 : cap_rss = hw->super.cap_rss;
3316 [ # # ]: 0 : if ((cap_rss & NFP_NET_CFG_RSS_TOEPLITZ) != 0)
3317 : 0 : dev_info->rss_algo_capa |= RTE_ETH_HASH_ALGO_CAPA_MASK(TOEPLITZ);
3318 : :
3319 [ # # ]: 0 : if ((cap_rss & NFP_NET_CFG_RSS_XOR) != 0)
3320 : 0 : dev_info->rss_algo_capa |= RTE_ETH_HASH_ALGO_CAPA_MASK(SIMPLE_XOR);
3321 : :
3322 [ # # ]: 0 : if ((cap_rss & NFP_NET_CFG_RSS_CRC32) != 0)
3323 : 0 : dev_info->rss_algo_capa |= RTE_ETH_HASH_ALGO_CAPA_MASK(DEFAULT);
3324 : 0 : }
|