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_representor.h"
13 : : #include "nfd3/nfp_nfd3.h"
14 : : #include "nfdk/nfp_nfdk.h"
15 : : #include "nfpcore/nfp_mip.h"
16 : : #include "nfpcore/nfp_nsp.h"
17 : : #include "nfp_logs.h"
18 : :
19 : : #define NFP_TX_MAX_SEG UINT8_MAX
20 : : #define NFP_TX_MAX_MTU_SEG 8
21 : :
22 : : #define NFP_NET_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */
23 : : #define NFP_NET_LINK_UP_CHECK_TIMEOUT 1000 /* ms */
24 : :
25 : : #define DEFAULT_FLBUF_SIZE 9216
26 : : #define NFP_ETH_OVERHEAD \
27 : : (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + RTE_VLAN_HLEN * 2)
28 : :
29 : : /* Only show FEC capability supported by the current speed. */
30 : : #define NFP_FEC_CAPA_ENTRY_NUM 1
31 : :
32 : : enum nfp_xstat_group {
33 : : NFP_XSTAT_GROUP_NET,
34 : : NFP_XSTAT_GROUP_MAC
35 : : };
36 : :
37 : : struct nfp_xstat {
38 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
39 : : int offset;
40 : : enum nfp_xstat_group group;
41 : : };
42 : :
43 : : #define NFP_XSTAT_NET(_name, _offset) { \
44 : : .name = _name, \
45 : : .offset = NFP_NET_CFG_STATS_##_offset, \
46 : : .group = NFP_XSTAT_GROUP_NET, \
47 : : }
48 : :
49 : : #define NFP_XSTAT_MAC(_name, _offset) { \
50 : : .name = _name, \
51 : : .offset = NFP_MAC_STATS_##_offset, \
52 : : .group = NFP_XSTAT_GROUP_MAC, \
53 : : }
54 : :
55 : : static const struct nfp_xstat nfp_net_xstats[] = {
56 : : /*
57 : : * Basic xstats available on both VF and PF.
58 : : * Note that in case new statistics of group NFP_XSTAT_GROUP_NET
59 : : * are added to this array, they must appear before any statistics
60 : : * of group NFP_XSTAT_GROUP_MAC.
61 : : */
62 : : NFP_XSTAT_NET("rx_good_packets_mc", RX_MC_FRAMES),
63 : : NFP_XSTAT_NET("tx_good_packets_mc", TX_MC_FRAMES),
64 : : NFP_XSTAT_NET("rx_good_packets_bc", RX_BC_FRAMES),
65 : : NFP_XSTAT_NET("tx_good_packets_bc", TX_BC_FRAMES),
66 : : NFP_XSTAT_NET("rx_good_bytes_uc", RX_UC_OCTETS),
67 : : NFP_XSTAT_NET("tx_good_bytes_uc", TX_UC_OCTETS),
68 : : NFP_XSTAT_NET("rx_good_bytes_mc", RX_MC_OCTETS),
69 : : NFP_XSTAT_NET("tx_good_bytes_mc", TX_MC_OCTETS),
70 : : NFP_XSTAT_NET("rx_good_bytes_bc", RX_BC_OCTETS),
71 : : NFP_XSTAT_NET("tx_good_bytes_bc", TX_BC_OCTETS),
72 : : NFP_XSTAT_NET("tx_missed_erros", TX_DISCARDS),
73 : : NFP_XSTAT_NET("bpf_pass_pkts", APP0_FRAMES),
74 : : NFP_XSTAT_NET("bpf_pass_bytes", APP0_BYTES),
75 : : NFP_XSTAT_NET("bpf_app1_pkts", APP1_FRAMES),
76 : : NFP_XSTAT_NET("bpf_app1_bytes", APP1_BYTES),
77 : : NFP_XSTAT_NET("bpf_app2_pkts", APP2_FRAMES),
78 : : NFP_XSTAT_NET("bpf_app2_bytes", APP2_BYTES),
79 : : NFP_XSTAT_NET("bpf_app3_pkts", APP3_FRAMES),
80 : : NFP_XSTAT_NET("bpf_app3_bytes", APP3_BYTES),
81 : : /*
82 : : * MAC xstats available only on PF. These statistics are not available for VFs as the
83 : : * PF is not initialized when the VF is initialized as it is still bound to the kernel
84 : : * driver. As such, the PMD cannot obtain a CPP handle and access the rtsym_table in order
85 : : * to get the pointer to the start of the MAC statistics counters.
86 : : */
87 : : NFP_XSTAT_MAC("mac.rx_octets", RX_IN_OCTS),
88 : : NFP_XSTAT_MAC("mac.rx_frame_too_long_errors", RX_FRAME_TOO_LONG_ERRORS),
89 : : NFP_XSTAT_MAC("mac.rx_range_length_errors", RX_RANGE_LENGTH_ERRORS),
90 : : NFP_XSTAT_MAC("mac.rx_vlan_received_ok", RX_VLAN_RECEIVED_OK),
91 : : NFP_XSTAT_MAC("mac.rx_errors", RX_IN_ERRORS),
92 : : NFP_XSTAT_MAC("mac.rx_broadcast_pkts", RX_IN_BROADCAST_PKTS),
93 : : NFP_XSTAT_MAC("mac.rx_drop_events", RX_DROP_EVENTS),
94 : : NFP_XSTAT_MAC("mac.rx_alignment_errors", RX_ALIGNMENT_ERRORS),
95 : : NFP_XSTAT_MAC("mac.rx_pause_mac_ctrl_frames", RX_PAUSE_MAC_CTRL_FRAMES),
96 : : NFP_XSTAT_MAC("mac.rx_frames_received_ok", RX_FRAMES_RECEIVED_OK),
97 : : NFP_XSTAT_MAC("mac.rx_frame_check_sequence_errors", RX_FRAME_CHECK_SEQ_ERRORS),
98 : : NFP_XSTAT_MAC("mac.rx_unicast_pkts", RX_UNICAST_PKTS),
99 : : NFP_XSTAT_MAC("mac.rx_multicast_pkts", RX_MULTICAST_PKTS),
100 : : NFP_XSTAT_MAC("mac.rx_pkts", RX_PKTS),
101 : : NFP_XSTAT_MAC("mac.rx_undersize_pkts", RX_UNDERSIZE_PKTS),
102 : : NFP_XSTAT_MAC("mac.rx_pkts_64_octets", RX_PKTS_64_OCTS),
103 : : NFP_XSTAT_MAC("mac.rx_pkts_65_to_127_octets", RX_PKTS_65_TO_127_OCTS),
104 : : NFP_XSTAT_MAC("mac.rx_pkts_128_to_255_octets", RX_PKTS_128_TO_255_OCTS),
105 : : NFP_XSTAT_MAC("mac.rx_pkts_256_to_511_octets", RX_PKTS_256_TO_511_OCTS),
106 : : NFP_XSTAT_MAC("mac.rx_pkts_512_to_1023_octets", RX_PKTS_512_TO_1023_OCTS),
107 : : NFP_XSTAT_MAC("mac.rx_pkts_1024_to_1518_octets", RX_PKTS_1024_TO_1518_OCTS),
108 : : NFP_XSTAT_MAC("mac.rx_pkts_1519_to_max_octets", RX_PKTS_1519_TO_MAX_OCTS),
109 : : NFP_XSTAT_MAC("mac.rx_jabbers", RX_JABBERS),
110 : : NFP_XSTAT_MAC("mac.rx_fragments", RX_FRAGMENTS),
111 : : NFP_XSTAT_MAC("mac.rx_oversize_pkts", RX_OVERSIZE_PKTS),
112 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class0", RX_PAUSE_FRAMES_CLASS0),
113 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class1", RX_PAUSE_FRAMES_CLASS1),
114 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class2", RX_PAUSE_FRAMES_CLASS2),
115 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class3", RX_PAUSE_FRAMES_CLASS3),
116 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class4", RX_PAUSE_FRAMES_CLASS4),
117 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class5", RX_PAUSE_FRAMES_CLASS5),
118 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class6", RX_PAUSE_FRAMES_CLASS6),
119 : : NFP_XSTAT_MAC("mac.rx_pause_frames_class7", RX_PAUSE_FRAMES_CLASS7),
120 : : NFP_XSTAT_MAC("mac.rx_mac_ctrl_frames_received", RX_MAC_CTRL_FRAMES_REC),
121 : : NFP_XSTAT_MAC("mac.rx_mac_head_drop", RX_MAC_HEAD_DROP),
122 : : NFP_XSTAT_MAC("mac.tx_queue_drop", TX_QUEUE_DROP),
123 : : NFP_XSTAT_MAC("mac.tx_octets", TX_OUT_OCTS),
124 : : NFP_XSTAT_MAC("mac.tx_vlan_transmitted_ok", TX_VLAN_TRANSMITTED_OK),
125 : : NFP_XSTAT_MAC("mac.tx_errors", TX_OUT_ERRORS),
126 : : NFP_XSTAT_MAC("mac.tx_broadcast_pkts", TX_BROADCAST_PKTS),
127 : : NFP_XSTAT_MAC("mac.tx_pause_mac_ctrl_frames", TX_PAUSE_MAC_CTRL_FRAMES),
128 : : NFP_XSTAT_MAC("mac.tx_frames_transmitted_ok", TX_FRAMES_TRANSMITTED_OK),
129 : : NFP_XSTAT_MAC("mac.tx_unicast_pkts", TX_UNICAST_PKTS),
130 : : NFP_XSTAT_MAC("mac.tx_multicast_pkts", TX_MULTICAST_PKTS),
131 : : NFP_XSTAT_MAC("mac.tx_pkts_64_octets", TX_PKTS_64_OCTS),
132 : : NFP_XSTAT_MAC("mac.tx_pkts_65_to_127_octets", TX_PKTS_65_TO_127_OCTS),
133 : : NFP_XSTAT_MAC("mac.tx_pkts_128_to_255_octets", TX_PKTS_128_TO_255_OCTS),
134 : : NFP_XSTAT_MAC("mac.tx_pkts_256_to_511_octets", TX_PKTS_256_TO_511_OCTS),
135 : : NFP_XSTAT_MAC("mac.tx_pkts_512_to_1023_octets", TX_PKTS_512_TO_1023_OCTS),
136 : : NFP_XSTAT_MAC("mac.tx_pkts_1024_to_1518_octets", TX_PKTS_1024_TO_1518_OCTS),
137 : : NFP_XSTAT_MAC("mac.tx_pkts_1519_to_max_octets", TX_PKTS_1519_TO_MAX_OCTS),
138 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class0", TX_PAUSE_FRAMES_CLASS0),
139 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class1", TX_PAUSE_FRAMES_CLASS1),
140 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class2", TX_PAUSE_FRAMES_CLASS2),
141 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class3", TX_PAUSE_FRAMES_CLASS3),
142 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class4", TX_PAUSE_FRAMES_CLASS4),
143 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class5", TX_PAUSE_FRAMES_CLASS5),
144 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class6", TX_PAUSE_FRAMES_CLASS6),
145 : : NFP_XSTAT_MAC("mac.tx_pause_frames_class7", TX_PAUSE_FRAMES_CLASS7),
146 : : };
147 : :
148 : : static const uint32_t nfp_net_link_speed_nfp2rte[] = {
149 : : [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = RTE_ETH_SPEED_NUM_NONE,
150 : : [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = RTE_ETH_SPEED_NUM_NONE,
151 : : [NFP_NET_CFG_STS_LINK_RATE_1G] = RTE_ETH_SPEED_NUM_1G,
152 : : [NFP_NET_CFG_STS_LINK_RATE_10G] = RTE_ETH_SPEED_NUM_10G,
153 : : [NFP_NET_CFG_STS_LINK_RATE_25G] = RTE_ETH_SPEED_NUM_25G,
154 : : [NFP_NET_CFG_STS_LINK_RATE_40G] = RTE_ETH_SPEED_NUM_40G,
155 : : [NFP_NET_CFG_STS_LINK_RATE_50G] = RTE_ETH_SPEED_NUM_50G,
156 : : [NFP_NET_CFG_STS_LINK_RATE_100G] = RTE_ETH_SPEED_NUM_100G,
157 : : };
158 : :
159 : : static uint16_t
160 : : nfp_net_link_speed_rte2nfp(uint16_t speed)
161 : : {
162 : : uint16_t i;
163 : :
164 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nfp_net_link_speed_nfp2rte); i++) {
165 [ # # ]: 0 : if (speed == nfp_net_link_speed_nfp2rte[i])
166 : : return i;
167 : : }
168 : :
169 : : return NFP_NET_CFG_STS_LINK_RATE_UNKNOWN;
170 : : }
171 : :
172 : : static void
173 : : nfp_net_notify_port_speed(struct nfp_net_hw *hw,
174 : : struct rte_eth_link *link)
175 : : {
176 : : /*
177 : : * Read the link status from NFP_NET_CFG_STS. If the link is down
178 : : * then write the link speed NFP_NET_CFG_STS_LINK_RATE_UNKNOWN to
179 : : * NFP_NET_CFG_STS_NSP_LINK_RATE.
180 : : */
181 [ # # ]: 0 : if (link->link_status == RTE_ETH_LINK_DOWN) {
182 : : nn_cfg_writew(&hw->super, NFP_NET_CFG_STS_NSP_LINK_RATE,
183 : : NFP_NET_CFG_STS_LINK_RATE_UNKNOWN);
184 : 0 : return;
185 : : }
186 : :
187 : : /*
188 : : * Link is up so write the link speed from the eth_table to
189 : : * NFP_NET_CFG_STS_NSP_LINK_RATE.
190 : : */
191 : : nn_cfg_writew(&hw->super, NFP_NET_CFG_STS_NSP_LINK_RATE,
192 : 0 : nfp_net_link_speed_rte2nfp(link->link_speed));
193 : : }
194 : :
195 : : /* The length of firmware version string */
196 : : #define FW_VER_LEN 32
197 : :
198 : : /**
199 : : * Reconfigure the firmware via the mailbox
200 : : *
201 : : * @param net_hw
202 : : * Device to reconfigure
203 : : * @param mbox_cmd
204 : : * The value for the mailbox command
205 : : *
206 : : * @return
207 : : * - (0) if OK to reconfigure by the mailbox.
208 : : * - (-EIO) if I/O err and fail to reconfigure by the mailbox
209 : : */
210 : : int
211 : 0 : nfp_net_mbox_reconfig(struct nfp_net_hw *net_hw,
212 : : uint32_t mbox_cmd)
213 : : {
214 : : int ret;
215 : : uint32_t mbox;
216 : :
217 : 0 : mbox = net_hw->tlv_caps.mbox_off;
218 : :
219 : 0 : rte_spinlock_lock(&net_hw->super.reconfig_lock);
220 : :
221 : : nn_cfg_writeq(&net_hw->super, mbox + NFP_NET_CFG_MBOX_SIMPLE_CMD, mbox_cmd);
222 : : nn_cfg_writel(&net_hw->super, NFP_NET_CFG_UPDATE, NFP_NET_CFG_UPDATE_MBOX);
223 : :
224 : : rte_wmb();
225 : :
226 : 0 : ret = nfp_reconfig_real(&net_hw->super, NFP_NET_CFG_UPDATE_MBOX);
227 : :
228 : : rte_spinlock_unlock(&net_hw->super.reconfig_lock);
229 : :
230 [ # # ]: 0 : if (ret != 0) {
231 : 0 : PMD_DRV_LOG(ERR, "Error nft net mailbox reconfig: mbox=%#08x update=%#08x",
232 : : mbox_cmd, NFP_NET_CFG_UPDATE_MBOX);
233 : 0 : return -EIO;
234 : : }
235 : :
236 : 0 : return nn_cfg_readl(&net_hw->super, mbox + NFP_NET_CFG_MBOX_SIMPLE_RET);
237 : : }
238 : :
239 : : struct nfp_net_hw *
240 : 0 : nfp_net_get_hw(const struct rte_eth_dev *dev)
241 : : {
242 : : struct nfp_net_hw *hw;
243 : :
244 [ # # ]: 0 : if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
245 : : struct nfp_flower_representor *repr;
246 : 0 : repr = dev->data->dev_private;
247 : 0 : hw = repr->app_fw_flower->pf_hw;
248 : : } else {
249 : 0 : hw = dev->data->dev_private;
250 : : }
251 : :
252 : 0 : return hw;
253 : : }
254 : :
255 : : /*
256 : : * Configure an Ethernet device.
257 : : *
258 : : * This function must be invoked first before any other function in the Ethernet API.
259 : : * This function can also be re-invoked when a device is in the stopped state.
260 : : *
261 : : * A DPDK app sends info about how many queues to use and how those queues
262 : : * need to be configured. This is used by the DPDK core and it makes sure no
263 : : * more queues than those advertised by the driver are requested.
264 : : * This function is called after that internal process.
265 : : */
266 : : int
267 : 0 : nfp_net_configure(struct rte_eth_dev *dev)
268 : : {
269 : : struct nfp_net_hw *hw;
270 : : struct rte_eth_conf *dev_conf;
271 : : struct rte_eth_rxmode *rxmode;
272 : : struct rte_eth_txmode *txmode;
273 : :
274 : 0 : hw = nfp_net_get_hw(dev);
275 : 0 : dev_conf = &dev->data->dev_conf;
276 : : rxmode = &dev_conf->rxmode;
277 : : txmode = &dev_conf->txmode;
278 : :
279 [ # # ]: 0 : if ((rxmode->mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) != 0)
280 : 0 : rxmode->offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
281 : :
282 : : /* Checking TX mode */
283 [ # # ]: 0 : if (txmode->mq_mode != RTE_ETH_MQ_TX_NONE) {
284 : 0 : PMD_DRV_LOG(ERR, "TX mq_mode DCB and VMDq not supported");
285 : 0 : return -EINVAL;
286 : : }
287 : :
288 : : /* Checking RX mode */
289 [ # # ]: 0 : if ((rxmode->mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) != 0 &&
290 [ # # ]: 0 : (hw->super.cap & NFP_NET_CFG_CTRL_RSS_ANY) == 0) {
291 : 0 : PMD_DRV_LOG(ERR, "RSS not supported");
292 : 0 : return -EINVAL;
293 : : }
294 : :
295 : : /* Checking MTU set */
296 [ # # ]: 0 : if (rxmode->mtu > hw->max_mtu + NFP_ETH_OVERHEAD) {
297 : 0 : PMD_DRV_LOG(ERR, "MTU (%u) larger than the maximum possible frame size (%u)",
298 : : rxmode->mtu, hw->max_mtu + NFP_ETH_OVERHEAD);
299 : 0 : return -ERANGE;
300 : : }
301 : :
302 : : return 0;
303 : : }
304 : :
305 : : void
306 : 0 : nfp_net_log_device_information(const struct nfp_net_hw *hw)
307 : : {
308 : 0 : uint32_t cap = hw->super.cap;
309 : 0 : uint32_t cap_ext = hw->super.cap_ext;
310 : :
311 : 0 : PMD_INIT_LOG(INFO, "VER: %u.%u, Maximum supported MTU: %d",
312 : : hw->ver.major, hw->ver.minor, hw->max_mtu);
313 : :
314 : 0 : PMD_INIT_LOG(INFO, "CAP: %#x", cap);
315 [ # # # # : 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",
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
316 : : cap & NFP_NET_CFG_CTRL_ENABLE ? "ENABLE " : "",
317 : : cap & NFP_NET_CFG_CTRL_PROMISC ? "PROMISC " : "",
318 : : cap & NFP_NET_CFG_CTRL_L2BC ? "L2BCFILT " : "",
319 : : cap & NFP_NET_CFG_CTRL_L2MC ? "L2MCFILT " : "",
320 : : cap & NFP_NET_CFG_CTRL_RXCSUM ? "RXCSUM " : "",
321 : : cap & NFP_NET_CFG_CTRL_TXCSUM ? "TXCSUM " : "",
322 : : cap & NFP_NET_CFG_CTRL_RXVLAN ? "RXVLAN " : "",
323 : : cap & NFP_NET_CFG_CTRL_TXVLAN ? "TXVLAN " : "",
324 : : cap & NFP_NET_CFG_CTRL_SCATTER ? "SCATTER " : "",
325 : : cap & NFP_NET_CFG_CTRL_GATHER ? "GATHER " : "",
326 : : cap & NFP_NET_CFG_CTRL_LSO ? "TSO " : "",
327 : : cap & NFP_NET_CFG_CTRL_RXQINQ ? "RXQINQ " : "",
328 : : cap & NFP_NET_CFG_CTRL_RXVLAN_V2 ? "RXVLANv2 " : "",
329 : : cap & NFP_NET_CFG_CTRL_RINGCFG ? "RINGCFG " : "",
330 : : cap & NFP_NET_CFG_CTRL_RSS ? "RSS " : "",
331 : : cap & NFP_NET_CFG_CTRL_IRQMOD ? "IRQMOD " : "",
332 : : cap & NFP_NET_CFG_CTRL_RINGPRIO ? "RINGPRIO " : "",
333 : : cap & NFP_NET_CFG_CTRL_MSIXAUTO ? "MSIXAUTO " : "",
334 : : cap & NFP_NET_CFG_CTRL_TXRWB ? "TXRWB " : "",
335 : : cap & NFP_NET_CFG_CTRL_L2SWITCH ? "L2SWITCH " : "",
336 : : cap & NFP_NET_CFG_CTRL_TXVLAN_V2 ? "TXVLANv2 " : "",
337 : : cap & NFP_NET_CFG_CTRL_VXLAN ? "VXLAN " : "",
338 : : cap & NFP_NET_CFG_CTRL_NVGRE ? "NVGRE " : "",
339 : : cap & NFP_NET_CFG_CTRL_MSIX_TX_OFF ? "MSIX_TX_OFF " : "",
340 : : cap & NFP_NET_CFG_CTRL_LSO2 ? "TSOv2 " : "",
341 : : cap & NFP_NET_CFG_CTRL_RSS2 ? "RSSv2 " : "",
342 : : cap & NFP_NET_CFG_CTRL_CSUM_COMPLETE ? "CSUM " : "",
343 : : cap & NFP_NET_CFG_CTRL_LIVE_ADDR ? "LIVE_ADDR " : "",
344 : : cap & NFP_NET_CFG_CTRL_USO ? "USO" : "");
345 : :
346 : 0 : PMD_INIT_LOG(INFO, "CAP_WORD1: %#x", cap_ext);
347 [ # # # # : 0 : PMD_INIT_LOG(INFO, "%s%s%s%s%s%s%s",
# # # # #
# # # #
# ]
348 : : cap_ext & NFP_NET_CFG_CTRL_PKT_TYPE ? "PKT_TYPE " : "",
349 : : cap_ext & NFP_NET_CFG_CTRL_IPSEC ? "IPSEC " : "",
350 : : cap_ext & NFP_NET_CFG_CTRL_IPSEC_SM_LOOKUP ? "IPSEC_SM " : "",
351 : : cap_ext & NFP_NET_CFG_CTRL_IPSEC_LM_LOOKUP ? "IPSEC_LM " : "",
352 : : cap_ext & NFP_NET_CFG_CTRL_MULTI_PF ? "MULTI_PF " : "",
353 : : cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER ? "FLOW_STEER " : "",
354 : : cap_ext & NFP_NET_CFG_CTRL_IN_ORDER ? "VIRTIO_IN_ORDER " : "");
355 : :
356 : 0 : PMD_INIT_LOG(INFO, "max_rx_queues: %u, max_tx_queues: %u",
357 : : hw->max_rx_queues, hw->max_tx_queues);
358 : 0 : }
359 : :
360 : : static inline void
361 : : nfp_net_enable_rxvlan_cap(struct nfp_net_hw *hw,
362 : : uint32_t *ctrl)
363 : : {
364 [ # # # # ]: 0 : if ((hw->super.cap & NFP_NET_CFG_CTRL_RXVLAN_V2) != 0)
365 : 0 : *ctrl |= NFP_NET_CFG_CTRL_RXVLAN_V2;
366 [ # # # # ]: 0 : else if ((hw->super.cap & NFP_NET_CFG_CTRL_RXVLAN) != 0)
367 : 0 : *ctrl |= NFP_NET_CFG_CTRL_RXVLAN;
368 : : }
369 : :
370 : : void
371 : 0 : nfp_net_enable_queues(struct rte_eth_dev *dev)
372 : : {
373 : : struct nfp_net_hw *hw;
374 : :
375 : 0 : hw = nfp_net_get_hw(dev);
376 : :
377 : 0 : nfp_enable_queues(&hw->super, dev->data->nb_rx_queues,
378 : 0 : dev->data->nb_tx_queues);
379 : 0 : }
380 : :
381 : : void
382 : 0 : nfp_net_disable_queues(struct rte_eth_dev *dev)
383 : : {
384 : : struct nfp_net_hw *net_hw;
385 : :
386 : 0 : net_hw = nfp_net_get_hw(dev);
387 : :
388 : 0 : nfp_disable_queues(&net_hw->super);
389 : 0 : }
390 : :
391 : : void
392 : 0 : nfp_net_params_setup(struct nfp_net_hw *hw)
393 : : {
394 : 0 : nn_cfg_writel(&hw->super, NFP_NET_CFG_MTU, hw->mtu);
395 : 0 : nn_cfg_writel(&hw->super, NFP_NET_CFG_FLBUFSZ, hw->flbufsz);
396 : 0 : }
397 : :
398 : : void
399 : 0 : nfp_net_cfg_queue_setup(struct nfp_net_hw *hw)
400 : : {
401 : 0 : hw->super.qcp_cfg = hw->tx_bar + NFP_QCP_QUEUE_ADDR_SZ;
402 : 0 : }
403 : :
404 : : int
405 : 0 : nfp_net_set_mac_addr(struct rte_eth_dev *dev,
406 : : struct rte_ether_addr *mac_addr)
407 : : {
408 : : uint32_t update;
409 : : uint32_t new_ctrl;
410 : : struct nfp_hw *hw;
411 : : struct nfp_net_hw *net_hw;
412 : :
413 : 0 : net_hw = nfp_net_get_hw(dev);
414 : 0 : hw = &net_hw->super;
415 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) != 0 &&
416 [ # # ]: 0 : (hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR) == 0) {
417 : 0 : PMD_DRV_LOG(ERR, "MAC address unable to change when port enabled");
418 : 0 : return -EBUSY;
419 : : }
420 : :
421 : : if (rte_is_valid_assigned_ether_addr(mac_addr) == 0) {
422 : 0 : PMD_DRV_LOG(ERR, "Invalid MAC address");
423 : 0 : return -EINVAL;
424 : : }
425 : :
426 : : /* Writing new MAC to the specific port BAR address */
427 : 0 : nfp_write_mac(hw, (uint8_t *)mac_addr);
428 : :
429 : : update = NFP_NET_CFG_UPDATE_MACADDR;
430 : 0 : new_ctrl = hw->ctrl;
431 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) != 0 &&
432 [ # # ]: 0 : (hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR) != 0)
433 : 0 : new_ctrl |= NFP_NET_CFG_CTRL_LIVE_ADDR;
434 : :
435 : : /* Signal the NIC about the change */
436 [ # # ]: 0 : if (nfp_reconfig(hw, new_ctrl, update) != 0) {
437 : 0 : PMD_DRV_LOG(ERR, "MAC address update failed");
438 : 0 : return -EIO;
439 : : }
440 : :
441 : 0 : hw->ctrl = new_ctrl;
442 : :
443 : 0 : return 0;
444 : : }
445 : :
446 : : int
447 : 0 : nfp_configure_rx_interrupt(struct rte_eth_dev *dev,
448 : : struct rte_intr_handle *intr_handle)
449 : : {
450 : : uint16_t i;
451 : : struct nfp_net_hw *hw;
452 : :
453 [ # # ]: 0 : if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
454 : 0 : dev->data->nb_rx_queues) != 0) {
455 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues intr_vec",
456 : : dev->data->nb_rx_queues);
457 : 0 : return -ENOMEM;
458 : : }
459 : :
460 : 0 : hw = nfp_net_get_hw(dev);
461 : :
462 [ # # ]: 0 : if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_UIO) {
463 : 0 : PMD_DRV_LOG(INFO, "VF: enabling RX interrupt with UIO");
464 : : /* UIO just supports one queue and no LSC */
465 : : nn_cfg_writeb(&hw->super, NFP_NET_CFG_RXR_VEC(0), 0);
466 [ # # ]: 0 : if (rte_intr_vec_list_index_set(intr_handle, 0, 0) != 0)
467 : : return -1;
468 : : } else {
469 : 0 : PMD_DRV_LOG(INFO, "VF: enabling RX interrupt with VFIO");
470 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
471 : : /*
472 : : * The first msix vector is reserved for non
473 : : * efd interrupts.
474 : : */
475 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_RXR_VEC(i), i + 1);
476 [ # # ]: 0 : if (rte_intr_vec_list_index_set(intr_handle, i, i + 1) != 0)
477 : : return -1;
478 : : }
479 : : }
480 : :
481 : : /* Avoiding TX interrupts */
482 : 0 : hw->super.ctrl |= NFP_NET_CFG_CTRL_MSIX_TX_OFF;
483 : 0 : return 0;
484 : : }
485 : :
486 : : uint32_t
487 : 0 : nfp_check_offloads(struct rte_eth_dev *dev)
488 : : {
489 : : uint32_t cap;
490 : : uint32_t ctrl = 0;
491 : : uint64_t rx_offload;
492 : : uint64_t tx_offload;
493 : : struct nfp_net_hw *hw;
494 : : struct rte_eth_conf *dev_conf;
495 : :
496 : 0 : hw = nfp_net_get_hw(dev);
497 : 0 : cap = hw->super.cap;
498 : :
499 : 0 : dev_conf = &dev->data->dev_conf;
500 : 0 : rx_offload = dev_conf->rxmode.offloads;
501 : 0 : tx_offload = dev_conf->txmode.offloads;
502 : :
503 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) != 0) {
504 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXCSUM) != 0)
505 : : ctrl |= NFP_NET_CFG_CTRL_RXCSUM;
506 : : }
507 : :
508 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) != 0)
509 : : nfp_net_enable_rxvlan_cap(hw, &ctrl);
510 : :
511 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) != 0) {
512 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXQINQ) != 0)
513 : 0 : ctrl |= NFP_NET_CFG_CTRL_RXQINQ;
514 : : }
515 : :
516 : 0 : hw->mtu = dev->data->mtu;
517 : :
518 [ # # ]: 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) != 0) {
519 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_TXVLAN_V2) != 0)
520 : 0 : ctrl |= NFP_NET_CFG_CTRL_TXVLAN_V2;
521 [ # # ]: 0 : else if ((cap & NFP_NET_CFG_CTRL_TXVLAN) != 0)
522 : 0 : ctrl |= NFP_NET_CFG_CTRL_TXVLAN;
523 : : }
524 : :
525 : : /* L2 broadcast */
526 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_L2BC) != 0)
527 : 0 : ctrl |= NFP_NET_CFG_CTRL_L2BC;
528 : :
529 : : /* L2 multicast */
530 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_L2MC) != 0)
531 : 0 : ctrl |= NFP_NET_CFG_CTRL_L2MC;
532 : :
533 : : /* TX checksum offload */
534 : 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) != 0 ||
535 [ # # ]: 0 : (tx_offload & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) != 0 ||
536 : : (tx_offload & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) != 0)
537 : 0 : ctrl |= NFP_NET_CFG_CTRL_TXCSUM;
538 : :
539 : : /* LSO offload */
540 : 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_TCP_TSO) != 0 ||
541 [ # # ]: 0 : (tx_offload & RTE_ETH_TX_OFFLOAD_UDP_TSO) != 0 ||
542 : : (tx_offload & RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO) != 0) {
543 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_LSO) != 0)
544 : 0 : ctrl |= NFP_NET_CFG_CTRL_LSO;
545 [ # # ]: 0 : else if ((cap & NFP_NET_CFG_CTRL_LSO2) != 0)
546 : 0 : ctrl |= NFP_NET_CFG_CTRL_LSO2;
547 : : }
548 : :
549 : : /* RX gather */
550 [ # # ]: 0 : if ((tx_offload & RTE_ETH_TX_OFFLOAD_MULTI_SEGS) != 0)
551 : 0 : ctrl |= NFP_NET_CFG_CTRL_GATHER;
552 : :
553 : 0 : return ctrl;
554 : : }
555 : :
556 : : int
557 : 0 : nfp_net_promisc_enable(struct rte_eth_dev *dev)
558 : : {
559 : : int ret;
560 : : uint32_t update;
561 : : uint32_t new_ctrl;
562 : : struct nfp_hw *hw;
563 : : struct nfp_net_hw *net_hw;
564 : :
565 : 0 : net_hw = nfp_net_get_hw(dev);
566 : :
567 : 0 : hw = &net_hw->super;
568 [ # # ]: 0 : if ((hw->cap & NFP_NET_CFG_CTRL_PROMISC) == 0) {
569 : 0 : PMD_DRV_LOG(ERR, "Promiscuous mode not supported");
570 : 0 : return -ENOTSUP;
571 : : }
572 : :
573 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) != 0) {
574 : 0 : PMD_DRV_LOG(INFO, "Promiscuous mode already enabled");
575 : 0 : return 0;
576 : : }
577 : :
578 : 0 : new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_PROMISC;
579 : : update = NFP_NET_CFG_UPDATE_GEN;
580 : :
581 : 0 : ret = nfp_reconfig(hw, new_ctrl, update);
582 [ # # ]: 0 : if (ret != 0)
583 : : return ret;
584 : :
585 : 0 : hw->ctrl = new_ctrl;
586 : :
587 : 0 : return 0;
588 : : }
589 : :
590 : : int
591 : 0 : nfp_net_promisc_disable(struct rte_eth_dev *dev)
592 : : {
593 : : int ret;
594 : : uint32_t update;
595 : : uint32_t new_ctrl;
596 : : struct nfp_hw *hw;
597 : : struct nfp_net_hw *net_hw;
598 : :
599 : 0 : net_hw = nfp_net_get_hw(dev);
600 : 0 : hw = &net_hw->super;
601 : :
602 [ # # ]: 0 : if ((hw->cap & NFP_NET_CFG_CTRL_PROMISC) == 0) {
603 : 0 : PMD_DRV_LOG(ERR, "Promiscuous mode not supported");
604 : 0 : return -ENOTSUP;
605 : : }
606 : :
607 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) == 0) {
608 : 0 : PMD_DRV_LOG(INFO, "Promiscuous mode already disabled");
609 : 0 : return 0;
610 : : }
611 : :
612 : 0 : new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC;
613 : : update = NFP_NET_CFG_UPDATE_GEN;
614 : :
615 : 0 : ret = nfp_reconfig(hw, new_ctrl, update);
616 [ # # ]: 0 : if (ret != 0)
617 : : return ret;
618 : :
619 : 0 : hw->ctrl = new_ctrl;
620 : :
621 : 0 : return 0;
622 : : }
623 : :
624 : : static int
625 : 0 : nfp_net_set_allmulticast_mode(struct rte_eth_dev *dev,
626 : : bool enable)
627 : : {
628 : : int ret;
629 : : uint32_t update;
630 : : struct nfp_hw *hw;
631 : : uint32_t cap_extend;
632 : : uint32_t ctrl_extend;
633 : : uint32_t new_ctrl_extend;
634 : : struct nfp_net_hw *net_hw;
635 : :
636 : 0 : net_hw = nfp_net_get_hw(dev);
637 : 0 : hw = &net_hw->super;
638 : :
639 : 0 : cap_extend = hw->cap_ext;
640 [ # # ]: 0 : if ((cap_extend & NFP_NET_CFG_CTRL_MCAST_FILTER) == 0) {
641 : 0 : PMD_DRV_LOG(ERR, "Allmulticast mode not supported");
642 : 0 : return -ENOTSUP;
643 : : }
644 : :
645 : : /*
646 : : * Allmulticast mode enabled when NFP_NET_CFG_CTRL_MCAST_FILTER bit is 0.
647 : : * Allmulticast mode disabled when NFP_NET_CFG_CTRL_MCAST_FILTER bit is 1.
648 : : */
649 : 0 : ctrl_extend = hw->ctrl_ext;
650 [ # # ]: 0 : if (enable) {
651 [ # # ]: 0 : if ((ctrl_extend & NFP_NET_CFG_CTRL_MCAST_FILTER) == 0)
652 : : return 0;
653 : :
654 : 0 : new_ctrl_extend = ctrl_extend & ~NFP_NET_CFG_CTRL_MCAST_FILTER;
655 : : } else {
656 [ # # ]: 0 : if ((ctrl_extend & NFP_NET_CFG_CTRL_MCAST_FILTER) != 0)
657 : : return 0;
658 : :
659 : 0 : new_ctrl_extend = ctrl_extend | NFP_NET_CFG_CTRL_MCAST_FILTER;
660 : : }
661 : :
662 : : update = NFP_NET_CFG_UPDATE_GEN;
663 : :
664 : 0 : ret = nfp_ext_reconfig(hw, new_ctrl_extend, update);
665 [ # # ]: 0 : if (ret != 0)
666 : : return ret;
667 : :
668 : 0 : hw->ctrl_ext = new_ctrl_extend;
669 : 0 : return 0;
670 : : }
671 : :
672 : : int
673 : 0 : nfp_net_allmulticast_enable(struct rte_eth_dev *dev)
674 : : {
675 : 0 : return nfp_net_set_allmulticast_mode(dev, true);
676 : : }
677 : :
678 : : int
679 : 0 : nfp_net_allmulticast_disable(struct rte_eth_dev *dev)
680 : : {
681 : 0 : return nfp_net_set_allmulticast_mode(dev, false);
682 : : }
683 : :
684 : : static int
685 : 0 : nfp_net_speed_aneg_update(struct rte_eth_dev *dev,
686 : : struct nfp_net_hw *hw,
687 : : struct rte_eth_link *link)
688 : : {
689 : : uint32_t i;
690 : : uint32_t speed;
691 : : struct nfp_eth_table *nfp_eth_table;
692 : : struct nfp_eth_table_port *eth_port;
693 : :
694 : : /* Compare whether the current status has changed. */
695 [ # # ]: 0 : if (dev->data->dev_link.link_status != link->link_status) {
696 : 0 : nfp_eth_table = nfp_eth_read_ports(hw->cpp);
697 [ # # ]: 0 : if (nfp_eth_table == NULL) {
698 : 0 : PMD_DRV_LOG(DEBUG, "Error reading NFP ethernet table.");
699 : 0 : return -EIO;
700 : : }
701 : :
702 : 0 : hw->pf_dev->nfp_eth_table->ports[hw->idx] = nfp_eth_table->ports[hw->idx];
703 : 0 : free(nfp_eth_table);
704 : : }
705 : :
706 : 0 : nfp_eth_table = hw->pf_dev->nfp_eth_table;
707 : 0 : eth_port = &nfp_eth_table->ports[hw->idx];
708 : 0 : speed = eth_port->speed;
709 : :
710 [ # # ]: 0 : for (i = 0; i < RTE_DIM(nfp_net_link_speed_nfp2rte); i++) {
711 [ # # ]: 0 : if (nfp_net_link_speed_nfp2rte[i] == speed) {
712 : 0 : link->link_speed = speed;
713 : 0 : break;
714 : : }
715 : : }
716 : :
717 [ # # ]: 0 : if (dev->data->dev_conf.link_speeds == RTE_ETH_LINK_SPEED_AUTONEG &&
718 [ # # ]: 0 : eth_port->supp_aneg)
719 : 0 : link->link_autoneg = RTE_ETH_LINK_AUTONEG;
720 : :
721 : : return 0;
722 : : }
723 : :
724 : : int
725 : 0 : nfp_net_link_update_common(struct rte_eth_dev *dev,
726 : : struct nfp_net_hw *hw,
727 : : struct rte_eth_link *link,
728 : : uint32_t link_status)
729 : : {
730 : : int ret;
731 : : uint32_t nn_link_status;
732 : :
733 [ # # ]: 0 : if (link->link_status == RTE_ETH_LINK_UP) {
734 [ # # ]: 0 : if (hw->pf_dev != NULL) {
735 : 0 : ret = nfp_net_speed_aneg_update(dev, hw, link);
736 [ # # ]: 0 : if (ret != 0) {
737 : 0 : PMD_DRV_LOG(DEBUG, "Failed to update speed and aneg.");
738 : 0 : return ret;
739 : : }
740 : : } else {
741 : : /*
742 : : * Shift and mask nn_link_status so that it is effectively the value
743 : : * at offset NFP_NET_CFG_STS_NSP_LINK_RATE.
744 : : */
745 : 0 : nn_link_status = (link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) &
746 : : NFP_NET_CFG_STS_LINK_RATE_MASK;
747 [ # # ]: 0 : if (nn_link_status < RTE_DIM(nfp_net_link_speed_nfp2rte))
748 : 0 : link->link_speed = nfp_net_link_speed_nfp2rte[nn_link_status];
749 : : }
750 : : }
751 : :
752 : : ret = rte_eth_linkstatus_set(dev, link);
753 : : if (ret == 0) {
754 [ # # ]: 0 : if (link->link_status != 0)
755 : 0 : PMD_DRV_LOG(INFO, "NIC Link is Up");
756 : : else
757 : 0 : PMD_DRV_LOG(INFO, "NIC Link is Down");
758 : : }
759 : :
760 : : return ret;
761 : : }
762 : :
763 : : /*
764 : : * Return 0 means link status changed, -1 means not changed
765 : : *
766 : : * Wait to complete is needed as it can take up to 9 seconds to get the Link
767 : : * status.
768 : : */
769 : : int
770 : 0 : nfp_net_link_update(struct rte_eth_dev *dev,
771 : : __rte_unused int wait_to_complete)
772 : : {
773 : : int ret;
774 : : struct nfp_net_hw *hw;
775 : : uint32_t nn_link_status;
776 : : struct rte_eth_link link;
777 : :
778 : 0 : hw = nfp_net_get_hw(dev);
779 : :
780 : : memset(&link, 0, sizeof(struct rte_eth_link));
781 : :
782 : : /* Read link status */
783 : 0 : nn_link_status = nn_cfg_readw(&hw->super, NFP_NET_CFG_STS);
784 [ # # ]: 0 : if ((nn_link_status & NFP_NET_CFG_STS_LINK) != 0)
785 : 0 : link.link_status = RTE_ETH_LINK_UP;
786 : :
787 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
788 : :
789 : 0 : ret = nfp_net_link_update_common(dev, hw, &link, nn_link_status);
790 [ # # ]: 0 : if (ret == -EIO)
791 : : return ret;
792 : :
793 : : /*
794 : : * Notify the port to update the speed value in the CTRL BAR from NSP.
795 : : * Not applicable for VFs as the associated PF is still attached to the
796 : : * kernel driver.
797 : : */
798 [ # # ]: 0 : if (hw->pf_dev != NULL)
799 : : nfp_net_notify_port_speed(hw, &link);
800 : :
801 : : return ret;
802 : : }
803 : :
804 : : int
805 : 0 : nfp_net_stats_get(struct rte_eth_dev *dev,
806 : : struct rte_eth_stats *stats)
807 : : {
808 : : uint16_t i;
809 : : struct nfp_net_hw *hw;
810 : : struct rte_eth_stats nfp_dev_stats;
811 : :
812 [ # # ]: 0 : if (stats == NULL)
813 : : return -EINVAL;
814 : :
815 : 0 : hw = nfp_net_get_hw(dev);
816 : :
817 : : memset(&nfp_dev_stats, 0, sizeof(nfp_dev_stats));
818 : :
819 : : /* Reading per RX ring stats */
820 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
821 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
822 : : break;
823 : :
824 : : nfp_dev_stats.q_ipackets[i] =
825 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i));
826 : 0 : nfp_dev_stats.q_ipackets[i] -=
827 : 0 : hw->eth_stats_base.q_ipackets[i];
828 : :
829 : : nfp_dev_stats.q_ibytes[i] =
830 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i) + 0x8);
831 : 0 : nfp_dev_stats.q_ibytes[i] -=
832 : 0 : hw->eth_stats_base.q_ibytes[i];
833 : : }
834 : :
835 : : /* Reading per TX ring stats */
836 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
837 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
838 : : break;
839 : :
840 : : nfp_dev_stats.q_opackets[i] =
841 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i));
842 : 0 : nfp_dev_stats.q_opackets[i] -= hw->eth_stats_base.q_opackets[i];
843 : :
844 : : nfp_dev_stats.q_obytes[i] =
845 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i) + 0x8);
846 : 0 : nfp_dev_stats.q_obytes[i] -= hw->eth_stats_base.q_obytes[i];
847 : : }
848 : :
849 : : nfp_dev_stats.ipackets = nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_FRAMES);
850 : 0 : nfp_dev_stats.ipackets -= hw->eth_stats_base.ipackets;
851 : :
852 : : nfp_dev_stats.ibytes = nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_OCTETS);
853 : 0 : nfp_dev_stats.ibytes -= hw->eth_stats_base.ibytes;
854 : :
855 : : nfp_dev_stats.opackets =
856 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_FRAMES);
857 : 0 : nfp_dev_stats.opackets -= hw->eth_stats_base.opackets;
858 : :
859 : : nfp_dev_stats.obytes =
860 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_OCTETS);
861 : 0 : nfp_dev_stats.obytes -= hw->eth_stats_base.obytes;
862 : :
863 : : /* Reading general device stats */
864 : : nfp_dev_stats.ierrors =
865 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_ERRORS);
866 : 0 : nfp_dev_stats.ierrors -= hw->eth_stats_base.ierrors;
867 : :
868 : : nfp_dev_stats.oerrors =
869 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_ERRORS);
870 : 0 : nfp_dev_stats.oerrors -= hw->eth_stats_base.oerrors;
871 : :
872 : : /* RX ring mbuf allocation failures */
873 : 0 : nfp_dev_stats.rx_nombuf = dev->data->rx_mbuf_alloc_failed;
874 : :
875 : : nfp_dev_stats.imissed =
876 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_DISCARDS);
877 : 0 : nfp_dev_stats.imissed -= hw->eth_stats_base.imissed;
878 : :
879 : : memcpy(stats, &nfp_dev_stats, sizeof(*stats));
880 : 0 : return 0;
881 : : }
882 : :
883 : : /*
884 : : * hw->eth_stats_base records the per counter starting point.
885 : : * Lets update it now.
886 : : */
887 : : int
888 : 0 : nfp_net_stats_reset(struct rte_eth_dev *dev)
889 : : {
890 : : uint16_t i;
891 : : struct nfp_net_hw *hw;
892 : :
893 : 0 : hw = nfp_net_get_hw(dev);
894 : :
895 : : /* Reading per RX ring stats */
896 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
897 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
898 : : break;
899 : :
900 : 0 : hw->eth_stats_base.q_ipackets[i] =
901 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i));
902 : :
903 : 0 : hw->eth_stats_base.q_ibytes[i] =
904 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i) + 0x8);
905 : : }
906 : :
907 : : /* Reading per TX ring stats */
908 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
909 [ # # ]: 0 : if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
910 : : break;
911 : :
912 : 0 : hw->eth_stats_base.q_opackets[i] =
913 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i));
914 : :
915 : 0 : hw->eth_stats_base.q_obytes[i] =
916 : 0 : nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i) + 0x8);
917 : : }
918 : :
919 : 0 : hw->eth_stats_base.ipackets =
920 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_FRAMES);
921 : :
922 : 0 : hw->eth_stats_base.ibytes =
923 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_OCTETS);
924 : :
925 : 0 : hw->eth_stats_base.opackets =
926 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_FRAMES);
927 : :
928 : 0 : hw->eth_stats_base.obytes =
929 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_OCTETS);
930 : :
931 : : /* Reading general device stats */
932 : 0 : hw->eth_stats_base.ierrors =
933 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_ERRORS);
934 : :
935 : 0 : hw->eth_stats_base.oerrors =
936 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_TX_ERRORS);
937 : :
938 : : /* RX ring mbuf allocation failures */
939 : 0 : dev->data->rx_mbuf_alloc_failed = 0;
940 : :
941 : 0 : hw->eth_stats_base.imissed =
942 : : nn_cfg_readq(&hw->super, NFP_NET_CFG_STATS_RX_DISCARDS);
943 : :
944 : 0 : return 0;
945 : : }
946 : :
947 : : uint32_t
948 : 0 : nfp_net_xstats_size(const struct rte_eth_dev *dev)
949 : : {
950 : : uint32_t count;
951 : : struct nfp_net_hw *hw;
952 : : const uint32_t size = RTE_DIM(nfp_net_xstats);
953 : :
954 : : /* If the device is a VF, then there will be no MAC stats */
955 : 0 : hw = nfp_net_get_hw(dev);
956 [ # # ]: 0 : if (hw->mac_stats == NULL) {
957 [ # # ]: 0 : for (count = 0; count < size; count++) {
958 [ # # ]: 0 : if (nfp_net_xstats[count].group == NFP_XSTAT_GROUP_MAC)
959 : : break;
960 : : }
961 : :
962 : 0 : return count;
963 : : }
964 : :
965 : : return size;
966 : : }
967 : :
968 : : static const struct nfp_xstat *
969 : 0 : nfp_net_xstats_info(const struct rte_eth_dev *dev,
970 : : uint32_t index)
971 : : {
972 [ # # ]: 0 : if (index >= nfp_net_xstats_size(dev)) {
973 : 0 : PMD_DRV_LOG(ERR, "xstat index out of bounds");
974 : 0 : return NULL;
975 : : }
976 : :
977 : 0 : return &nfp_net_xstats[index];
978 : : }
979 : :
980 : : static uint64_t
981 : 0 : nfp_net_xstats_value(const struct rte_eth_dev *dev,
982 : : uint32_t index,
983 : : bool raw)
984 : : {
985 : : uint64_t value;
986 : : struct nfp_net_hw *hw;
987 : : struct nfp_xstat xstat;
988 : :
989 : 0 : hw = nfp_net_get_hw(dev);
990 : 0 : xstat = nfp_net_xstats[index];
991 : :
992 [ # # ]: 0 : if (xstat.group == NFP_XSTAT_GROUP_MAC)
993 : 0 : value = nn_readq(hw->mac_stats + xstat.offset);
994 : : else
995 : 0 : value = nn_cfg_readq(&hw->super, xstat.offset);
996 : :
997 [ # # ]: 0 : if (raw)
998 : : return value;
999 : :
1000 : : /*
1001 : : * A baseline value of each statistic counter is recorded when stats are "reset".
1002 : : * Thus, the value returned by this function need to be decremented by this
1003 : : * baseline value. The result is the count of this statistic since the last time
1004 : : * it was "reset".
1005 : : */
1006 : 0 : return value - hw->eth_xstats_base[index].value;
1007 : : }
1008 : :
1009 : : /* NOTE: All callers ensure dev is always set. */
1010 : : int
1011 : 0 : nfp_net_xstats_get_names(struct rte_eth_dev *dev,
1012 : : struct rte_eth_xstat_name *xstats_names,
1013 : : unsigned int size)
1014 : : {
1015 : : uint32_t id;
1016 : : uint32_t nfp_size;
1017 : : uint32_t read_size;
1018 : :
1019 : 0 : nfp_size = nfp_net_xstats_size(dev);
1020 : :
1021 [ # # ]: 0 : if (xstats_names == NULL)
1022 : 0 : return nfp_size;
1023 : :
1024 : : /* Read at most NFP xstats number of names. */
1025 : 0 : read_size = RTE_MIN(size, nfp_size);
1026 : :
1027 [ # # ]: 0 : for (id = 0; id < read_size; id++)
1028 : 0 : rte_strlcpy(xstats_names[id].name, nfp_net_xstats[id].name,
1029 : : RTE_ETH_XSTATS_NAME_SIZE);
1030 : :
1031 : 0 : return read_size;
1032 : : }
1033 : :
1034 : : /* NOTE: All callers ensure dev is always set. */
1035 : : int
1036 : 0 : nfp_net_xstats_get(struct rte_eth_dev *dev,
1037 : : struct rte_eth_xstat *xstats,
1038 : : unsigned int n)
1039 : : {
1040 : : uint32_t id;
1041 : : uint32_t nfp_size;
1042 : : uint32_t read_size;
1043 : :
1044 : 0 : nfp_size = nfp_net_xstats_size(dev);
1045 : :
1046 [ # # ]: 0 : if (xstats == NULL)
1047 : 0 : return nfp_size;
1048 : :
1049 : : /* Read at most NFP xstats number of values. */
1050 : 0 : read_size = RTE_MIN(n, nfp_size);
1051 : :
1052 [ # # ]: 0 : for (id = 0; id < read_size; id++) {
1053 : 0 : xstats[id].id = id;
1054 : 0 : xstats[id].value = nfp_net_xstats_value(dev, id, false);
1055 : : }
1056 : :
1057 : 0 : return read_size;
1058 : : }
1059 : :
1060 : : /*
1061 : : * NOTE: The only caller rte_eth_xstats_get_names_by_id() ensures dev,
1062 : : * ids, xstats_names and size are valid, and non-NULL.
1063 : : */
1064 : : int
1065 : 0 : nfp_net_xstats_get_names_by_id(struct rte_eth_dev *dev,
1066 : : const uint64_t *ids,
1067 : : struct rte_eth_xstat_name *xstats_names,
1068 : : unsigned int size)
1069 : : {
1070 : : uint32_t i;
1071 : : uint32_t read_size;
1072 : :
1073 : : /* Read at most NFP xstats number of names. */
1074 : 0 : read_size = RTE_MIN(size, nfp_net_xstats_size(dev));
1075 : :
1076 [ # # ]: 0 : for (i = 0; i < read_size; i++) {
1077 : : const struct nfp_xstat *xstat;
1078 : :
1079 : : /* Make sure ID is valid for device. */
1080 : 0 : xstat = nfp_net_xstats_info(dev, ids[i]);
1081 [ # # ]: 0 : if (xstat == NULL)
1082 : : return -EINVAL;
1083 : :
1084 : 0 : rte_strlcpy(xstats_names[i].name, xstat->name,
1085 : : RTE_ETH_XSTATS_NAME_SIZE);
1086 : : }
1087 : :
1088 : 0 : return read_size;
1089 : : }
1090 : :
1091 : : /*
1092 : : * NOTE: The only caller rte_eth_xstats_get_by_id() ensures dev,
1093 : : * ids, values and n are valid, and non-NULL.
1094 : : */
1095 : : int
1096 : 0 : nfp_net_xstats_get_by_id(struct rte_eth_dev *dev,
1097 : : const uint64_t *ids,
1098 : : uint64_t *values,
1099 : : unsigned int n)
1100 : : {
1101 : : uint32_t i;
1102 : : uint32_t read_size;
1103 : :
1104 : : /* Read at most NFP xstats number of values. */
1105 : 0 : read_size = RTE_MIN(n, nfp_net_xstats_size(dev));
1106 : :
1107 [ # # ]: 0 : for (i = 0; i < read_size; i++) {
1108 : : const struct nfp_xstat *xstat;
1109 : :
1110 : : /* Make sure index is valid for device. */
1111 : 0 : xstat = nfp_net_xstats_info(dev, ids[i]);
1112 [ # # ]: 0 : if (xstat == NULL)
1113 : : return -EINVAL;
1114 : :
1115 : 0 : values[i] = nfp_net_xstats_value(dev, ids[i], false);
1116 : : }
1117 : :
1118 : 0 : return read_size;
1119 : : }
1120 : :
1121 : : int
1122 : 0 : nfp_net_xstats_reset(struct rte_eth_dev *dev)
1123 : : {
1124 : : uint32_t id;
1125 : : uint32_t read_size;
1126 : : struct nfp_net_hw *hw;
1127 : :
1128 : 0 : hw = nfp_net_get_hw(dev);
1129 : 0 : read_size = nfp_net_xstats_size(dev);
1130 : :
1131 [ # # ]: 0 : for (id = 0; id < read_size; id++) {
1132 : 0 : hw->eth_xstats_base[id].id = id;
1133 : 0 : hw->eth_xstats_base[id].value = nfp_net_xstats_value(dev, id, true);
1134 : : }
1135 : :
1136 : : /* Successfully reset xstats, now call function to reset basic stats. */
1137 : 0 : return nfp_net_stats_reset(dev);
1138 : : }
1139 : :
1140 : : void
1141 : 0 : nfp_net_rx_desc_limits(struct nfp_net_hw *hw,
1142 : : uint16_t *min_rx_desc,
1143 : : uint16_t *max_rx_desc)
1144 : : {
1145 : 0 : *max_rx_desc = hw->dev_info->max_qc_size;
1146 : 0 : *min_rx_desc = hw->dev_info->min_qc_size;
1147 : 0 : }
1148 : :
1149 : : void
1150 : 0 : nfp_net_tx_desc_limits(struct nfp_net_hw *hw,
1151 : : uint16_t *min_tx_desc,
1152 : : uint16_t *max_tx_desc)
1153 : : {
1154 : : uint16_t tx_dpp;
1155 : :
1156 [ # # ]: 0 : if (hw->ver.extend == NFP_NET_CFG_VERSION_DP_NFD3)
1157 : : tx_dpp = NFD3_TX_DESC_PER_PKT;
1158 : : else
1159 : : tx_dpp = NFDK_TX_DESC_PER_SIMPLE_PKT;
1160 : :
1161 : 0 : *max_tx_desc = hw->dev_info->max_qc_size / tx_dpp;
1162 : 0 : *min_tx_desc = hw->dev_info->min_qc_size / tx_dpp;
1163 : 0 : }
1164 : :
1165 : : int
1166 : 0 : nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
1167 : : {
1168 : : uint32_t cap;
1169 : : uint32_t cap_extend;
1170 : : uint16_t min_rx_desc;
1171 : : uint16_t max_rx_desc;
1172 : : uint16_t min_tx_desc;
1173 : : uint16_t max_tx_desc;
1174 : : struct nfp_net_hw *hw;
1175 : :
1176 : 0 : hw = nfp_net_get_hw(dev);
1177 : :
1178 : 0 : nfp_net_rx_desc_limits(hw, &min_rx_desc, &max_rx_desc);
1179 : 0 : nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
1180 : :
1181 : 0 : dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
1182 : 0 : dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
1183 : 0 : dev_info->min_rx_bufsize = RTE_ETHER_MIN_MTU;
1184 : : /*
1185 : : * The maximum rx packet length is set to the maximum layer 3 MTU,
1186 : : * plus layer 2, CRC and VLAN headers.
1187 : : * The maximum layer 3 MTU (max_mtu) is read from hardware,
1188 : : * which was set by the firmware loaded onto the card.
1189 : : */
1190 : 0 : dev_info->max_rx_pktlen = hw->max_mtu + NFP_ETH_OVERHEAD;
1191 : 0 : dev_info->max_mtu = hw->max_mtu;
1192 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
1193 : : /* Next should change when PF support is implemented */
1194 : 0 : dev_info->max_mac_addrs = 1;
1195 : :
1196 : 0 : cap = hw->super.cap;
1197 : :
1198 [ # # ]: 0 : if ((cap & (NFP_NET_CFG_CTRL_RXVLAN | NFP_NET_CFG_CTRL_RXVLAN_V2)) != 0)
1199 : 0 : dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1200 : :
1201 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXQINQ) != 0)
1202 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
1203 : :
1204 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RXCSUM) != 0)
1205 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
1206 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
1207 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM;
1208 : :
1209 [ # # ]: 0 : if ((cap & (NFP_NET_CFG_CTRL_TXVLAN | NFP_NET_CFG_CTRL_TXVLAN_V2)) != 0)
1210 : 0 : dev_info->tx_offload_capa = RTE_ETH_TX_OFFLOAD_VLAN_INSERT;
1211 : :
1212 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_TXCSUM) != 0)
1213 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
1214 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
1215 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
1216 : :
1217 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_LSO_ANY) != 0) {
1218 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
1219 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_USO) != 0)
1220 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_UDP_TSO;
1221 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_VXLAN) != 0)
1222 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO;
1223 : : }
1224 : :
1225 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_GATHER) != 0)
1226 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
1227 : :
1228 : 0 : cap_extend = hw->super.cap_ext;
1229 [ # # ]: 0 : if ((cap_extend & NFP_NET_CFG_CTRL_IPSEC) != 0) {
1230 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
1231 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
1232 : : }
1233 : :
1234 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
1235 : : .rx_thresh = {
1236 : : .pthresh = DEFAULT_RX_PTHRESH,
1237 : : .hthresh = DEFAULT_RX_HTHRESH,
1238 : : .wthresh = DEFAULT_RX_WTHRESH,
1239 : : },
1240 : : .rx_free_thresh = DEFAULT_RX_FREE_THRESH,
1241 : : .rx_drop_en = 0,
1242 : : };
1243 : :
1244 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
1245 : : .tx_thresh = {
1246 : : .pthresh = DEFAULT_TX_PTHRESH,
1247 : : .hthresh = DEFAULT_TX_HTHRESH,
1248 : : .wthresh = DEFAULT_TX_WTHRESH,
1249 : : },
1250 : : .tx_free_thresh = DEFAULT_TX_FREE_THRESH,
1251 : : .tx_rs_thresh = DEFAULT_TX_RSBIT_THRESH,
1252 : : };
1253 : :
1254 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
1255 : : .nb_max = max_rx_desc,
1256 : : .nb_min = min_rx_desc,
1257 : : .nb_align = NFP_ALIGN_RING_DESC,
1258 : : };
1259 : :
1260 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
1261 : : .nb_max = max_tx_desc,
1262 : : .nb_min = min_tx_desc,
1263 : : .nb_align = NFP_ALIGN_RING_DESC,
1264 : : .nb_seg_max = NFP_TX_MAX_SEG,
1265 : : .nb_mtu_seg_max = NFP_TX_MAX_MTU_SEG,
1266 : : };
1267 : :
1268 [ # # ]: 0 : if ((cap & NFP_NET_CFG_CTRL_RSS_ANY) != 0) {
1269 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
1270 : :
1271 : 0 : dev_info->flow_type_rss_offloads = RTE_ETH_RSS_IPV4 |
1272 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1273 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1274 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
1275 : : RTE_ETH_RSS_IPV6 |
1276 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1277 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1278 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
1279 : :
1280 : 0 : dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
1281 : 0 : dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
1282 : : }
1283 : :
1284 : : /* Only PF supports getting speed capability. */
1285 [ # # ]: 0 : if (hw->pf_dev != NULL)
1286 : 0 : dev_info->speed_capa = hw->pf_dev->speed_capa;
1287 : :
1288 : 0 : return 0;
1289 : : }
1290 : :
1291 : : int
1292 : 0 : nfp_net_common_init(struct rte_pci_device *pci_dev,
1293 : : struct nfp_net_hw *hw)
1294 : : {
1295 : : const int stride = 4;
1296 : :
1297 : 0 : hw->device_id = pci_dev->id.device_id;
1298 : 0 : hw->vendor_id = pci_dev->id.vendor_id;
1299 : 0 : hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
1300 : 0 : hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
1301 : :
1302 : 0 : hw->max_rx_queues = nn_cfg_readl(&hw->super, NFP_NET_CFG_MAX_RXRINGS);
1303 : 0 : hw->max_tx_queues = nn_cfg_readl(&hw->super, NFP_NET_CFG_MAX_TXRINGS);
1304 [ # # # # ]: 0 : if (hw->max_rx_queues == 0 || hw->max_tx_queues == 0) {
1305 : 0 : PMD_INIT_LOG(ERR, "Device %s can not be used, there are no valid queue "
1306 : : "pairs for use", pci_dev->name);
1307 : 0 : return -ENODEV;
1308 : : }
1309 : :
1310 : 0 : nfp_net_cfg_read_version(hw);
1311 [ # # ]: 0 : if (!nfp_net_is_valid_nfd_version(hw->ver))
1312 : : return -EINVAL;
1313 : :
1314 [ # # ]: 0 : if (nfp_net_check_dma_mask(hw, pci_dev->name) != 0)
1315 : : return -ENODEV;
1316 : :
1317 : : /* Get some of the read-only fields from the config BAR */
1318 : 0 : hw->super.cap = nn_cfg_readl(&hw->super, NFP_NET_CFG_CAP);
1319 : 0 : hw->super.cap_ext = nn_cfg_readl(&hw->super, NFP_NET_CFG_CAP_WORD1);
1320 : 0 : hw->max_mtu = nn_cfg_readl(&hw->super, NFP_NET_CFG_MAX_MTU);
1321 : 0 : hw->flbufsz = DEFAULT_FLBUF_SIZE;
1322 : :
1323 : 0 : nfp_net_init_metadata_format(hw);
1324 : :
1325 : : /* Read the Rx offset configured from firmware */
1326 [ # # ]: 0 : if (hw->ver.major < 2)
1327 : 0 : hw->rx_offset = NFP_NET_RX_OFFSET;
1328 : : else
1329 : 0 : hw->rx_offset = nn_cfg_readl(&hw->super, NFP_NET_CFG_RX_OFFSET);
1330 : :
1331 : 0 : hw->super.ctrl = 0;
1332 : 0 : hw->stride_rx = stride;
1333 : 0 : hw->stride_tx = stride;
1334 : :
1335 : 0 : return 0;
1336 : : }
1337 : :
1338 : : const uint32_t *
1339 : 0 : nfp_net_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
1340 : : {
1341 : : struct nfp_net_hw *net_hw;
1342 : : static const uint32_t ptypes[] = {
1343 : : RTE_PTYPE_L2_ETHER,
1344 : : RTE_PTYPE_L3_IPV4,
1345 : : RTE_PTYPE_L3_IPV4_EXT,
1346 : : RTE_PTYPE_L3_IPV6,
1347 : : RTE_PTYPE_L3_IPV6_EXT,
1348 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1349 : : RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
1350 : : RTE_PTYPE_L4_TCP,
1351 : : RTE_PTYPE_L4_UDP,
1352 : : RTE_PTYPE_L4_FRAG,
1353 : : RTE_PTYPE_L4_NONFRAG,
1354 : : RTE_PTYPE_L4_ICMP,
1355 : : RTE_PTYPE_L4_SCTP,
1356 : : RTE_PTYPE_TUNNEL_VXLAN,
1357 : : RTE_PTYPE_TUNNEL_NVGRE,
1358 : : RTE_PTYPE_TUNNEL_GENEVE,
1359 : : RTE_PTYPE_INNER_L2_ETHER,
1360 : : RTE_PTYPE_INNER_L3_IPV4,
1361 : : RTE_PTYPE_INNER_L3_IPV4_EXT,
1362 : : RTE_PTYPE_INNER_L3_IPV6,
1363 : : RTE_PTYPE_INNER_L3_IPV6_EXT,
1364 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
1365 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
1366 : : RTE_PTYPE_INNER_L4_TCP,
1367 : : RTE_PTYPE_INNER_L4_UDP,
1368 : : RTE_PTYPE_INNER_L4_FRAG,
1369 : : RTE_PTYPE_INNER_L4_NONFRAG,
1370 : : RTE_PTYPE_INNER_L4_ICMP,
1371 : : RTE_PTYPE_INNER_L4_SCTP,
1372 : : };
1373 : :
1374 [ # # ]: 0 : if (dev->rx_pkt_burst != nfp_net_recv_pkts)
1375 : : return NULL;
1376 : :
1377 : 0 : net_hw = dev->data->dev_private;
1378 [ # # ]: 0 : if ((net_hw->super.ctrl_ext & NFP_NET_CFG_CTRL_PKT_TYPE) == 0)
1379 : : return NULL;
1380 : :
1381 : 0 : *no_of_elements = RTE_DIM(ptypes);
1382 : 0 : return ptypes;
1383 : : }
1384 : :
1385 : : int
1386 : 0 : nfp_rx_queue_intr_enable(struct rte_eth_dev *dev,
1387 : : uint16_t queue_id)
1388 : : {
1389 : : uint16_t base = 0;
1390 : : struct nfp_net_hw *hw;
1391 : : struct rte_pci_device *pci_dev;
1392 : :
1393 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1394 [ # # ]: 0 : if (rte_intr_type_get(pci_dev->intr_handle) != RTE_INTR_HANDLE_UIO)
1395 : : base = 1;
1396 : :
1397 : : /* Make sure all updates are written before un-masking */
1398 : : rte_wmb();
1399 : :
1400 : 0 : hw = nfp_net_get_hw(dev);
1401 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_ICR(base + queue_id),
1402 : : NFP_NET_CFG_ICR_UNMASKED);
1403 : 0 : return 0;
1404 : : }
1405 : :
1406 : : int
1407 : 0 : nfp_rx_queue_intr_disable(struct rte_eth_dev *dev,
1408 : : uint16_t queue_id)
1409 : : {
1410 : : uint16_t base = 0;
1411 : : struct nfp_net_hw *hw;
1412 : : struct rte_pci_device *pci_dev;
1413 : :
1414 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1415 [ # # ]: 0 : if (rte_intr_type_get(pci_dev->intr_handle) != RTE_INTR_HANDLE_UIO)
1416 : : base = 1;
1417 : :
1418 : : /* Make sure all updates are written before un-masking */
1419 : : rte_wmb();
1420 : :
1421 : 0 : hw = nfp_net_get_hw(dev);
1422 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_ICR(base + queue_id), NFP_NET_CFG_ICR_RXTX);
1423 : :
1424 : 0 : return 0;
1425 : : }
1426 : :
1427 : : static void
1428 : 0 : nfp_net_dev_link_status_print(struct rte_eth_dev *dev)
1429 : : {
1430 : : struct rte_eth_link link;
1431 [ # # ]: 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1432 : :
1433 : : rte_eth_linkstatus_get(dev, &link);
1434 [ # # ]: 0 : if (link.link_status != 0)
1435 [ # # ]: 0 : PMD_DRV_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s",
1436 : : dev->data->port_id, link.link_speed,
1437 : : link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX ?
1438 : : "full-duplex" : "half-duplex");
1439 : : else
1440 : 0 : PMD_DRV_LOG(INFO, " Port %d: Link Down", dev->data->port_id);
1441 : :
1442 : 0 : PMD_DRV_LOG(INFO, "PCI Address: " PCI_PRI_FMT,
1443 : : pci_dev->addr.domain, pci_dev->addr.bus,
1444 : : pci_dev->addr.devid, pci_dev->addr.function);
1445 : 0 : }
1446 : :
1447 : : /*
1448 : : * Unmask an interrupt
1449 : : *
1450 : : * If MSI-X auto-masking is enabled clear the mask bit, otherwise
1451 : : * clear the ICR for the entry.
1452 : : */
1453 : : void
1454 : 0 : nfp_net_irq_unmask(struct rte_eth_dev *dev)
1455 : : {
1456 : : struct nfp_net_hw *hw;
1457 : : struct rte_pci_device *pci_dev;
1458 : :
1459 : 0 : hw = nfp_net_get_hw(dev);
1460 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1461 : :
1462 : : /* Make sure all updates are written before un-masking */
1463 : : rte_wmb();
1464 : :
1465 [ # # ]: 0 : if ((hw->super.ctrl & NFP_NET_CFG_CTRL_MSIXAUTO) != 0) {
1466 : : /* If MSI-X auto-masking is used, clear the entry */
1467 : 0 : rte_intr_ack(pci_dev->intr_handle);
1468 : : } else {
1469 : : nn_cfg_writeb(&hw->super, NFP_NET_CFG_ICR(NFP_NET_IRQ_LSC_IDX),
1470 : : NFP_NET_CFG_ICR_UNMASKED);
1471 : : }
1472 : 0 : }
1473 : :
1474 : : /**
1475 : : * Interrupt handler which shall be registered for alarm callback for delayed
1476 : : * handling specific interrupt to wait for the stable nic state. As the NIC
1477 : : * interrupt state is not stable for nfp after link is just down, it needs
1478 : : * to wait 4 seconds to get the stable status.
1479 : : *
1480 : : * @param param
1481 : : * The address of parameter (struct rte_eth_dev *)
1482 : : */
1483 : : void
1484 : 0 : nfp_net_dev_interrupt_delayed_handler(void *param)
1485 : : {
1486 : : struct rte_eth_dev *dev = param;
1487 : :
1488 : 0 : nfp_net_link_update(dev, 0);
1489 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
1490 : :
1491 : 0 : nfp_net_dev_link_status_print(dev);
1492 : :
1493 : : /* Unmasking */
1494 : 0 : nfp_net_irq_unmask(dev);
1495 : 0 : }
1496 : :
1497 : : void
1498 : 0 : nfp_net_dev_interrupt_handler(void *param)
1499 : : {
1500 : : int64_t timeout;
1501 : : struct rte_eth_link link;
1502 : : struct rte_eth_dev *dev = param;
1503 : :
1504 : 0 : PMD_DRV_LOG(DEBUG, "We got a LSC interrupt!!!");
1505 : :
1506 : : rte_eth_linkstatus_get(dev, &link);
1507 : :
1508 : 0 : nfp_net_link_update(dev, 0);
1509 : :
1510 : : /* Likely to up */
1511 [ # # ]: 0 : if (link.link_status == 0) {
1512 : : /* Handle it 1 sec later, wait it being stable */
1513 : : timeout = NFP_NET_LINK_UP_CHECK_TIMEOUT;
1514 : : } else { /* Likely to down */
1515 : : /* Handle it 4 sec later, wait it being stable */
1516 : : timeout = NFP_NET_LINK_DOWN_CHECK_TIMEOUT;
1517 : : }
1518 : :
1519 [ # # ]: 0 : if (rte_eal_alarm_set(timeout * 1000,
1520 : : nfp_net_dev_interrupt_delayed_handler,
1521 : : (void *)dev) != 0) {
1522 : 0 : PMD_INIT_LOG(ERR, "Error setting alarm");
1523 : : /* Unmasking */
1524 : 0 : nfp_net_irq_unmask(dev);
1525 : : }
1526 : 0 : }
1527 : :
1528 : : int
1529 : 0 : nfp_net_dev_mtu_set(struct rte_eth_dev *dev,
1530 : : uint16_t mtu)
1531 : : {
1532 : : struct nfp_net_hw *hw;
1533 : :
1534 : 0 : hw = nfp_net_get_hw(dev);
1535 : :
1536 : : /* MTU setting is forbidden if port is started */
1537 [ # # ]: 0 : if (dev->data->dev_started) {
1538 : 0 : PMD_DRV_LOG(ERR, "port %d must be stopped before configuration",
1539 : : dev->data->port_id);
1540 : 0 : return -EBUSY;
1541 : : }
1542 : :
1543 : : /* MTU larger than current mbufsize not supported */
1544 [ # # ]: 0 : if (mtu > hw->flbufsz) {
1545 : 0 : PMD_DRV_LOG(ERR, "MTU (%u) larger than current mbufsize (%u) not supported",
1546 : : mtu, hw->flbufsz);
1547 : 0 : return -ERANGE;
1548 : : }
1549 : :
1550 : : /* Writing to configuration space */
1551 : 0 : nn_cfg_writel(&hw->super, NFP_NET_CFG_MTU, mtu);
1552 : :
1553 : 0 : hw->mtu = mtu;
1554 : :
1555 : 0 : return 0;
1556 : : }
1557 : :
1558 : : int
1559 : 0 : nfp_net_vlan_offload_set(struct rte_eth_dev *dev,
1560 : : int mask)
1561 : : {
1562 : : int ret;
1563 : : uint32_t update;
1564 : : uint32_t new_ctrl;
1565 : : struct nfp_hw *hw;
1566 : : uint64_t rx_offload;
1567 : : struct nfp_net_hw *net_hw;
1568 : : uint32_t rxvlan_ctrl = 0;
1569 : :
1570 : 0 : net_hw = nfp_net_get_hw(dev);
1571 : 0 : hw = &net_hw->super;
1572 : 0 : rx_offload = dev->data->dev_conf.rxmode.offloads;
1573 : 0 : new_ctrl = hw->ctrl;
1574 : :
1575 : : /* VLAN stripping setting */
1576 [ # # ]: 0 : if ((mask & RTE_ETH_VLAN_STRIP_MASK) != 0) {
1577 : : nfp_net_enable_rxvlan_cap(net_hw, &rxvlan_ctrl);
1578 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) != 0)
1579 : 0 : new_ctrl |= rxvlan_ctrl;
1580 : : else
1581 : 0 : new_ctrl &= ~rxvlan_ctrl;
1582 : : }
1583 : :
1584 : : /* QinQ stripping setting */
1585 [ # # ]: 0 : if ((mask & RTE_ETH_QINQ_STRIP_MASK) != 0) {
1586 [ # # ]: 0 : if ((rx_offload & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) != 0)
1587 : 0 : new_ctrl |= NFP_NET_CFG_CTRL_RXQINQ;
1588 : : else
1589 : 0 : new_ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;
1590 : : }
1591 : :
1592 [ # # ]: 0 : if (new_ctrl == hw->ctrl)
1593 : : return 0;
1594 : :
1595 : : update = NFP_NET_CFG_UPDATE_GEN;
1596 : :
1597 : 0 : ret = nfp_reconfig(hw, new_ctrl, update);
1598 [ # # ]: 0 : if (ret != 0)
1599 : : return ret;
1600 : :
1601 : 0 : hw->ctrl = new_ctrl;
1602 : :
1603 : 0 : return 0;
1604 : : }
1605 : :
1606 : : static int
1607 : 0 : nfp_net_rss_reta_write(struct rte_eth_dev *dev,
1608 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1609 : : uint16_t reta_size)
1610 : : {
1611 : : uint16_t i;
1612 : : uint16_t j;
1613 : : uint16_t idx;
1614 : : uint8_t mask;
1615 : : uint32_t reta;
1616 : : uint16_t shift;
1617 : : struct nfp_hw *hw;
1618 : : struct nfp_net_hw *net_hw;
1619 : :
1620 : 0 : net_hw = nfp_net_get_hw(dev);
1621 : : hw = &net_hw->super;
1622 : :
1623 [ # # ]: 0 : if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) {
1624 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured (%hu)"
1625 : : " doesn't match hardware can supported (%d)",
1626 : : reta_size, NFP_NET_CFG_RSS_ITBL_SZ);
1627 : 0 : return -EINVAL;
1628 : : }
1629 : :
1630 : : /*
1631 : : * Update Redirection Table. There are 128 8bit-entries which can be
1632 : : * manage as 32 32bit-entries.
1633 : : */
1634 [ # # ]: 0 : for (i = 0; i < reta_size; i += 4) {
1635 : : /* Handling 4 RSS entries per loop */
1636 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1637 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1638 : 0 : mask = (uint8_t)((reta_conf[idx].mask >> shift) & 0xF);
1639 [ # # ]: 0 : if (mask == 0)
1640 : 0 : continue;
1641 : :
1642 : : reta = 0;
1643 : :
1644 : : /* If all 4 entries were set, don't need read RETA register */
1645 [ # # ]: 0 : if (mask != 0xF)
1646 : 0 : reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + i);
1647 : :
1648 [ # # ]: 0 : for (j = 0; j < 4; j++) {
1649 [ # # ]: 0 : if ((mask & (0x1 << j)) == 0)
1650 : 0 : continue;
1651 : :
1652 : : /* Clearing the entry bits */
1653 [ # # ]: 0 : if (mask != 0xF)
1654 : 0 : reta &= ~(0xFF << (8 * j));
1655 : :
1656 : 0 : reta |= reta_conf[idx].reta[shift + j] << (8 * j);
1657 : : }
1658 : :
1659 : 0 : nn_cfg_writel(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + shift, reta);
1660 : : }
1661 : :
1662 : : return 0;
1663 : : }
1664 : :
1665 : : /* Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device */
1666 : : int
1667 : 0 : nfp_net_reta_update(struct rte_eth_dev *dev,
1668 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1669 : : uint16_t reta_size)
1670 : : {
1671 : : int ret;
1672 : : uint32_t update;
1673 : : struct nfp_hw *hw;
1674 : : struct nfp_net_hw *net_hw;
1675 : :
1676 : 0 : net_hw = nfp_net_get_hw(dev);
1677 : 0 : hw = &net_hw->super;
1678 : :
1679 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
1680 : : return -EINVAL;
1681 : :
1682 : 0 : ret = nfp_net_rss_reta_write(dev, reta_conf, reta_size);
1683 [ # # ]: 0 : if (ret != 0)
1684 : : return ret;
1685 : :
1686 : : update = NFP_NET_CFG_UPDATE_RSS;
1687 : :
1688 [ # # ]: 0 : if (nfp_reconfig(hw, hw->ctrl, update) != 0)
1689 : 0 : return -EIO;
1690 : :
1691 : : return 0;
1692 : : }
1693 : :
1694 : : /* Query Redirection Table(RETA) of Receive Side Scaling of Ethernet device. */
1695 : : int
1696 : 0 : nfp_net_reta_query(struct rte_eth_dev *dev,
1697 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1698 : : uint16_t reta_size)
1699 : : {
1700 : : uint16_t i;
1701 : : uint16_t j;
1702 : : uint16_t idx;
1703 : : uint8_t mask;
1704 : : uint32_t reta;
1705 : : uint16_t shift;
1706 : : struct nfp_hw *hw;
1707 : : struct nfp_net_hw *net_hw;
1708 : :
1709 : 0 : net_hw = nfp_net_get_hw(dev);
1710 : : hw = &net_hw->super;
1711 : :
1712 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
1713 : : return -EINVAL;
1714 : :
1715 [ # # ]: 0 : if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) {
1716 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured (%d)"
1717 : : " doesn't match hardware can supported (%d)",
1718 : : reta_size, NFP_NET_CFG_RSS_ITBL_SZ);
1719 : 0 : return -EINVAL;
1720 : : }
1721 : :
1722 : : /*
1723 : : * Reading Redirection Table. There are 128 8bit-entries which can be
1724 : : * manage as 32 32bit-entries.
1725 : : */
1726 [ # # ]: 0 : for (i = 0; i < reta_size; i += 4) {
1727 : : /* Handling 4 RSS entries per loop */
1728 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1729 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1730 : 0 : mask = (reta_conf[idx].mask >> shift) & 0xF;
1731 : :
1732 [ # # ]: 0 : if (mask == 0)
1733 : 0 : continue;
1734 : :
1735 : 0 : reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + shift);
1736 [ # # ]: 0 : for (j = 0; j < 4; j++) {
1737 [ # # ]: 0 : if ((mask & (0x1 << j)) == 0)
1738 : 0 : continue;
1739 : :
1740 : 0 : reta_conf[idx].reta[shift + j] =
1741 : 0 : (uint8_t)((reta >> (8 * j)) & 0xF);
1742 : : }
1743 : : }
1744 : :
1745 : : return 0;
1746 : : }
1747 : :
1748 : : static int
1749 : 0 : nfp_net_rss_hash_write(struct rte_eth_dev *dev,
1750 : : struct rte_eth_rss_conf *rss_conf)
1751 : : {
1752 : : uint8_t i;
1753 : : uint8_t key;
1754 : : uint64_t rss_hf;
1755 : : struct nfp_hw *hw;
1756 : : struct nfp_net_hw *net_hw;
1757 : : uint32_t cfg_rss_ctrl = 0;
1758 : :
1759 : 0 : net_hw = nfp_net_get_hw(dev);
1760 : : hw = &net_hw->super;
1761 : :
1762 : : /* Writing the key byte by byte */
1763 [ # # ]: 0 : for (i = 0; i < rss_conf->rss_key_len; i++) {
1764 : 0 : memcpy(&key, &rss_conf->rss_key[i], 1);
1765 : 0 : nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY + i, key);
1766 : : }
1767 : :
1768 : 0 : rss_hf = rss_conf->rss_hf;
1769 : :
1770 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_IPV4) != 0)
1771 : : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4;
1772 : :
1773 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) != 0)
1774 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_TCP;
1775 : :
1776 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) != 0)
1777 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_UDP;
1778 : :
1779 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) != 0)
1780 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_SCTP;
1781 : :
1782 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_IPV6) != 0)
1783 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6;
1784 : :
1785 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) != 0)
1786 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_TCP;
1787 : :
1788 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) != 0)
1789 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_UDP;
1790 : :
1791 [ # # ]: 0 : if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) != 0)
1792 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_SCTP;
1793 : :
1794 : : cfg_rss_ctrl |= NFP_NET_CFG_RSS_MASK;
1795 : 0 : cfg_rss_ctrl |= NFP_NET_CFG_RSS_TOEPLITZ;
1796 : :
1797 : : /* Configuring where to apply the RSS hash */
1798 : : nn_cfg_writel(hw, NFP_NET_CFG_RSS_CTRL, cfg_rss_ctrl);
1799 : :
1800 : : /* Writing the key size */
1801 : 0 : nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY_SZ, rss_conf->rss_key_len);
1802 : :
1803 : 0 : return 0;
1804 : : }
1805 : :
1806 : : int
1807 : 0 : nfp_net_rss_hash_update(struct rte_eth_dev *dev,
1808 : : struct rte_eth_rss_conf *rss_conf)
1809 : : {
1810 : : uint32_t update;
1811 : : uint64_t rss_hf;
1812 : : struct nfp_hw *hw;
1813 : : struct nfp_net_hw *net_hw;
1814 : :
1815 : 0 : net_hw = nfp_net_get_hw(dev);
1816 : 0 : hw = &net_hw->super;
1817 : :
1818 : 0 : rss_hf = rss_conf->rss_hf;
1819 : :
1820 : : /* Checking if RSS is enabled */
1821 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0) {
1822 [ # # ]: 0 : if (rss_hf != 0) {
1823 : 0 : PMD_DRV_LOG(ERR, "RSS unsupported");
1824 : 0 : return -EINVAL;
1825 : : }
1826 : :
1827 : : return 0; /* Nothing to do */
1828 : : }
1829 : :
1830 [ # # ]: 0 : if (rss_conf->rss_key_len > NFP_NET_CFG_RSS_KEY_SZ) {
1831 : 0 : PMD_DRV_LOG(ERR, "RSS hash key too long");
1832 : 0 : return -EINVAL;
1833 : : }
1834 : :
1835 : 0 : nfp_net_rss_hash_write(dev, rss_conf);
1836 : :
1837 : : update = NFP_NET_CFG_UPDATE_RSS;
1838 : :
1839 [ # # ]: 0 : if (nfp_reconfig(hw, hw->ctrl, update) != 0)
1840 : 0 : return -EIO;
1841 : :
1842 : : return 0;
1843 : : }
1844 : :
1845 : : int
1846 : 0 : nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev,
1847 : : struct rte_eth_rss_conf *rss_conf)
1848 : : {
1849 : : uint8_t i;
1850 : : uint8_t key;
1851 : : uint64_t rss_hf;
1852 : : struct nfp_hw *hw;
1853 : : uint32_t cfg_rss_ctrl;
1854 : : struct nfp_net_hw *net_hw;
1855 : :
1856 : 0 : net_hw = nfp_net_get_hw(dev);
1857 : : hw = &net_hw->super;
1858 : :
1859 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
1860 : : return -EINVAL;
1861 : :
1862 : 0 : rss_hf = rss_conf->rss_hf;
1863 : : cfg_rss_ctrl = nn_cfg_readl(hw, NFP_NET_CFG_RSS_CTRL);
1864 : :
1865 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4) != 0)
1866 : 0 : rss_hf |= RTE_ETH_RSS_IPV4;
1867 : :
1868 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_TCP) != 0)
1869 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
1870 : :
1871 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_TCP) != 0)
1872 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
1873 : :
1874 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_UDP) != 0)
1875 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
1876 : :
1877 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_UDP) != 0)
1878 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
1879 : :
1880 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6) != 0)
1881 : 0 : rss_hf |= RTE_ETH_RSS_IPV6;
1882 : :
1883 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_SCTP) != 0)
1884 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_SCTP;
1885 : :
1886 [ # # ]: 0 : if ((cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_SCTP) != 0)
1887 : 0 : rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_SCTP;
1888 : :
1889 : : /* Propagate current RSS hash functions to caller */
1890 : 0 : rss_conf->rss_hf = rss_hf;
1891 : :
1892 : : /* Reading the key size */
1893 : 0 : rss_conf->rss_key_len = nn_cfg_readl(hw, NFP_NET_CFG_RSS_KEY_SZ);
1894 : :
1895 : : /* Reading the key byte a byte */
1896 [ # # ]: 0 : for (i = 0; i < rss_conf->rss_key_len; i++) {
1897 : 0 : key = nn_cfg_readb(hw, NFP_NET_CFG_RSS_KEY + i);
1898 : 0 : memcpy(&rss_conf->rss_key[i], &key, 1);
1899 : : }
1900 : :
1901 : : return 0;
1902 : : }
1903 : :
1904 : : int
1905 : 0 : nfp_net_rss_config_default(struct rte_eth_dev *dev)
1906 : : {
1907 : : int ret;
1908 : : uint8_t i;
1909 : : uint8_t j;
1910 : : uint16_t queue = 0;
1911 : : struct rte_eth_conf *dev_conf;
1912 : : struct rte_eth_rss_conf rss_conf;
1913 : 0 : uint16_t rx_queues = dev->data->nb_rx_queues;
1914 : : struct rte_eth_rss_reta_entry64 nfp_reta_conf[2];
1915 : :
1916 : 0 : nfp_reta_conf[0].mask = ~0x0;
1917 : 0 : nfp_reta_conf[1].mask = ~0x0;
1918 : :
1919 [ # # ]: 0 : for (i = 0; i < 0x40; i += 8) {
1920 [ # # ]: 0 : for (j = i; j < (i + 8); j++) {
1921 : 0 : nfp_reta_conf[0].reta[j] = queue;
1922 : 0 : nfp_reta_conf[1].reta[j] = queue++;
1923 : 0 : queue %= rx_queues;
1924 : : }
1925 : : }
1926 : :
1927 : 0 : ret = nfp_net_rss_reta_write(dev, nfp_reta_conf, 0x80);
1928 [ # # ]: 0 : if (ret != 0)
1929 : : return ret;
1930 : :
1931 : 0 : dev_conf = &dev->data->dev_conf;
1932 : : if (dev_conf == NULL) {
1933 : : PMD_DRV_LOG(ERR, "Wrong rss conf");
1934 : : return -EINVAL;
1935 : : }
1936 : :
1937 : 0 : rss_conf = dev_conf->rx_adv_conf.rss_conf;
1938 : 0 : ret = nfp_net_rss_hash_write(dev, &rss_conf);
1939 : :
1940 : 0 : return ret;
1941 : : }
1942 : :
1943 : : void
1944 : 0 : nfp_net_stop_rx_queue(struct rte_eth_dev *dev)
1945 : : {
1946 : : uint16_t i;
1947 : : struct nfp_net_rxq *this_rx_q;
1948 : :
1949 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1950 : 0 : this_rx_q = dev->data->rx_queues[i];
1951 : 0 : nfp_net_reset_rx_queue(this_rx_q);
1952 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1953 : : }
1954 : 0 : }
1955 : :
1956 : : void
1957 : 0 : nfp_net_close_rx_queue(struct rte_eth_dev *dev)
1958 : : {
1959 : : uint16_t i;
1960 : : struct nfp_net_rxq *this_rx_q;
1961 : :
1962 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1963 : 0 : this_rx_q = dev->data->rx_queues[i];
1964 : 0 : nfp_net_reset_rx_queue(this_rx_q);
1965 : 0 : nfp_net_rx_queue_release(dev, i);
1966 : : }
1967 : 0 : }
1968 : :
1969 : : void
1970 : 0 : nfp_net_stop_tx_queue(struct rte_eth_dev *dev)
1971 : : {
1972 : : uint16_t i;
1973 : : struct nfp_net_txq *this_tx_q;
1974 : :
1975 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1976 : 0 : this_tx_q = dev->data->tx_queues[i];
1977 : 0 : nfp_net_reset_tx_queue(this_tx_q);
1978 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1979 : : }
1980 : 0 : }
1981 : :
1982 : : void
1983 : 0 : nfp_net_close_tx_queue(struct rte_eth_dev *dev)
1984 : : {
1985 : : uint16_t i;
1986 : : struct nfp_net_txq *this_tx_q;
1987 : :
1988 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1989 : 0 : this_tx_q = dev->data->tx_queues[i];
1990 : 0 : nfp_net_reset_tx_queue(this_tx_q);
1991 : 0 : nfp_net_tx_queue_release(dev, i);
1992 : : }
1993 : 0 : }
1994 : :
1995 : : int
1996 : 0 : nfp_net_set_vxlan_port(struct nfp_net_hw *net_hw,
1997 : : size_t idx,
1998 : : uint16_t port)
1999 : : {
2000 : : int ret;
2001 : : uint32_t i;
2002 : 0 : struct nfp_hw *hw = &net_hw->super;
2003 : :
2004 [ # # ]: 0 : if (idx >= NFP_NET_N_VXLAN_PORTS) {
2005 : 0 : PMD_DRV_LOG(ERR, "The idx value is out of range.");
2006 : 0 : return -ERANGE;
2007 : : }
2008 : :
2009 : 0 : net_hw->vxlan_ports[idx] = port;
2010 : :
2011 [ # # ]: 0 : for (i = 0; i < NFP_NET_N_VXLAN_PORTS; i += 2) {
2012 : 0 : nn_cfg_writel(hw, NFP_NET_CFG_VXLAN_PORT + i * sizeof(port),
2013 : 0 : (net_hw->vxlan_ports[i + 1] << 16) | net_hw->vxlan_ports[i]);
2014 : : }
2015 : :
2016 : 0 : rte_spinlock_lock(&hw->reconfig_lock);
2017 : :
2018 : : nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, NFP_NET_CFG_UPDATE_VXLAN);
2019 : : rte_wmb();
2020 : :
2021 : 0 : ret = nfp_reconfig_real(hw, NFP_NET_CFG_UPDATE_VXLAN);
2022 : :
2023 : : rte_spinlock_unlock(&hw->reconfig_lock);
2024 : :
2025 : 0 : return ret;
2026 : : }
2027 : :
2028 : : /*
2029 : : * The firmware with NFD3 can not handle DMA address requiring more
2030 : : * than 40 bits.
2031 : : */
2032 : : int
2033 : 0 : nfp_net_check_dma_mask(struct nfp_net_hw *hw,
2034 : : char *name)
2035 : : {
2036 [ # # # # ]: 0 : if (hw->ver.extend == NFP_NET_CFG_VERSION_DP_NFD3 &&
2037 : 0 : rte_mem_check_dma_mask(40) != 0) {
2038 : 0 : PMD_DRV_LOG(ERR, "Device %s can't be used: restricted dma mask to 40 bits!",
2039 : : name);
2040 : 0 : return -ENODEV;
2041 : : }
2042 : :
2043 : : return 0;
2044 : : }
2045 : :
2046 : : void
2047 : 0 : nfp_net_init_metadata_format(struct nfp_net_hw *hw)
2048 : : {
2049 : : /*
2050 : : * ABI 4.x and ctrl vNIC always use chained metadata, in other cases we allow use of
2051 : : * single metadata if only RSS(v1) is supported by hw capability, and RSS(v2)
2052 : : * also indicate that we are using chained metadata.
2053 : : */
2054 [ # # ]: 0 : if (hw->ver.major == 4) {
2055 : 0 : hw->meta_format = NFP_NET_METAFORMAT_CHAINED;
2056 [ # # ]: 0 : } else if ((hw->super.cap & NFP_NET_CFG_CTRL_CHAIN_META) != 0) {
2057 : 0 : hw->meta_format = NFP_NET_METAFORMAT_CHAINED;
2058 : : /*
2059 : : * RSS is incompatible with chained metadata. hw->super.cap just represents
2060 : : * firmware's ability rather than the firmware's configuration. We decide
2061 : : * to reduce the confusion to allow us can use hw->super.cap to identify RSS later.
2062 : : */
2063 : 0 : hw->super.cap &= ~NFP_NET_CFG_CTRL_RSS;
2064 : : } else {
2065 : 0 : hw->meta_format = NFP_NET_METAFORMAT_SINGLE;
2066 : : }
2067 : 0 : }
2068 : :
2069 : : void
2070 : 0 : nfp_net_cfg_read_version(struct nfp_net_hw *hw)
2071 : : {
2072 : : union {
2073 : : uint32_t whole;
2074 : : struct nfp_net_fw_ver split;
2075 : : } version;
2076 : :
2077 : : version.whole = nn_cfg_readl(&hw->super, NFP_NET_CFG_VERSION);
2078 : 0 : hw->ver = version.split;
2079 : 0 : }
2080 : :
2081 : : static void
2082 : 0 : nfp_net_get_nsp_info(struct nfp_net_hw *hw,
2083 : : char *nsp_version)
2084 : : {
2085 : : struct nfp_nsp *nsp;
2086 : :
2087 : 0 : nsp = nfp_nsp_open(hw->cpp);
2088 [ # # ]: 0 : if (nsp == NULL)
2089 : : return;
2090 : :
2091 : 0 : snprintf(nsp_version, FW_VER_LEN, "%hu.%hu",
2092 : 0 : nfp_nsp_get_abi_ver_major(nsp),
2093 : 0 : nfp_nsp_get_abi_ver_minor(nsp));
2094 : :
2095 : 0 : nfp_nsp_close(nsp);
2096 : : }
2097 : :
2098 : : static void
2099 : 0 : nfp_net_get_mip_name(struct nfp_net_hw *hw,
2100 : : char *mip_name)
2101 : : {
2102 : : struct nfp_mip *mip;
2103 : :
2104 : 0 : mip = nfp_mip_open(hw->cpp);
2105 [ # # ]: 0 : if (mip == NULL)
2106 : : return;
2107 : :
2108 : 0 : snprintf(mip_name, FW_VER_LEN, "%s", nfp_mip_name(mip));
2109 : :
2110 : 0 : nfp_mip_close(mip);
2111 : : }
2112 : :
2113 : : static void
2114 : 0 : nfp_net_get_app_name(struct nfp_net_hw *hw,
2115 : : char *app_name)
2116 : : {
2117 [ # # # ]: 0 : switch (hw->pf_dev->app_fw_id) {
2118 : : case NFP_APP_FW_CORE_NIC:
2119 : : snprintf(app_name, FW_VER_LEN, "%s", "nic");
2120 : : break;
2121 : : case NFP_APP_FW_FLOWER_NIC:
2122 : : snprintf(app_name, FW_VER_LEN, "%s", "flower");
2123 : : break;
2124 : : default:
2125 : : snprintf(app_name, FW_VER_LEN, "%s", "unknown");
2126 : : break;
2127 : : }
2128 : 0 : }
2129 : :
2130 : : int
2131 : 0 : nfp_net_firmware_version_get(struct rte_eth_dev *dev,
2132 : : char *fw_version,
2133 : : size_t fw_size)
2134 : : {
2135 : : struct nfp_net_hw *hw;
2136 : : char mip_name[FW_VER_LEN];
2137 : : char app_name[FW_VER_LEN];
2138 : : char nsp_version[FW_VER_LEN];
2139 : : char vnic_version[FW_VER_LEN];
2140 : :
2141 [ # # ]: 0 : if (fw_size < FW_VER_LEN)
2142 : : return FW_VER_LEN;
2143 : :
2144 : 0 : hw = nfp_net_get_hw(dev);
2145 : :
2146 [ # # ]: 0 : if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
2147 : 0 : snprintf(vnic_version, FW_VER_LEN, "%d.%d.%d.%d",
2148 : 0 : hw->ver.extend, hw->ver.class,
2149 : 0 : hw->ver.major, hw->ver.minor);
2150 : : } else {
2151 : : snprintf(vnic_version, FW_VER_LEN, "*");
2152 : : }
2153 : :
2154 : 0 : nfp_net_get_nsp_info(hw, nsp_version);
2155 : 0 : nfp_net_get_mip_name(hw, mip_name);
2156 : 0 : nfp_net_get_app_name(hw, app_name);
2157 : :
2158 : : snprintf(fw_version, FW_VER_LEN, "%s %s %s %s",
2159 : : vnic_version, nsp_version, mip_name, app_name);
2160 : :
2161 : 0 : return 0;
2162 : : }
2163 : :
2164 : : bool
2165 : 0 : nfp_net_is_valid_nfd_version(struct nfp_net_fw_ver version)
2166 : : {
2167 : 0 : uint8_t nfd_version = version.extend;
2168 : :
2169 [ # # ]: 0 : if (nfd_version == NFP_NET_CFG_VERSION_DP_NFD3)
2170 : : return true;
2171 : :
2172 [ # # ]: 0 : if (nfd_version == NFP_NET_CFG_VERSION_DP_NFDK) {
2173 [ # # ]: 0 : if (version.major < 5) {
2174 : 0 : PMD_INIT_LOG(ERR, "NFDK must use ABI 5 or newer, found: %d",
2175 : : version.major);
2176 : 0 : return false;
2177 : : }
2178 : :
2179 : : return true;
2180 : : }
2181 : :
2182 : : return false;
2183 : : }
2184 : :
2185 : : /* Disable rx and tx functions to allow for reconfiguring. */
2186 : : int
2187 : 0 : nfp_net_stop(struct rte_eth_dev *dev)
2188 : : {
2189 : : struct nfp_cpp *cpp;
2190 : : struct nfp_net_hw *hw;
2191 : :
2192 : 0 : hw = nfp_net_get_hw(dev);
2193 : :
2194 : 0 : nfp_net_disable_queues(dev);
2195 : :
2196 : : /* Clear queues */
2197 : 0 : nfp_net_stop_tx_queue(dev);
2198 : 0 : nfp_net_stop_rx_queue(dev);
2199 : :
2200 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY)
2201 : 0 : cpp = hw->cpp;
2202 : : else
2203 : 0 : cpp = ((struct nfp_pf_dev *)(dev->process_private))->cpp;
2204 : :
2205 : 0 : nfp_eth_set_configured(cpp, hw->nfp_idx, 0);
2206 : :
2207 : 0 : return 0;
2208 : : }
2209 : :
2210 : : static enum rte_eth_fc_mode
2211 : : nfp_net_get_pause_mode(struct nfp_eth_table_port *eth_port)
2212 : : {
2213 : : enum rte_eth_fc_mode mode;
2214 : :
2215 : 0 : if (eth_port->rx_pause_enabled) {
2216 [ # # # # ]: 0 : if (eth_port->tx_pause_enabled)
2217 : : mode = RTE_ETH_FC_FULL;
2218 : : else
2219 : : mode = RTE_ETH_FC_RX_PAUSE;
2220 : : } else {
2221 [ # # # # ]: 0 : if (eth_port->tx_pause_enabled)
2222 : : mode = RTE_ETH_FC_TX_PAUSE;
2223 : : else
2224 : : mode = RTE_ETH_FC_NONE;
2225 : : }
2226 : :
2227 : : return mode;
2228 : : }
2229 : :
2230 : : int
2231 : 0 : nfp_net_flow_ctrl_get(struct rte_eth_dev *dev,
2232 : : struct rte_eth_fc_conf *fc_conf)
2233 : : {
2234 : : struct nfp_net_hw *net_hw;
2235 : : struct nfp_eth_table *nfp_eth_table;
2236 : : struct nfp_eth_table_port *eth_port;
2237 : :
2238 : 0 : net_hw = nfp_net_get_hw(dev);
2239 [ # # ]: 0 : if (net_hw->pf_dev == NULL)
2240 : : return -EINVAL;
2241 : :
2242 : 0 : nfp_eth_table = net_hw->pf_dev->nfp_eth_table;
2243 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[dev->data->port_id];
2244 : :
2245 : : /* Currently only RX/TX switch are supported */
2246 : 0 : fc_conf->mode = nfp_net_get_pause_mode(eth_port);
2247 : :
2248 : 0 : return 0;
2249 : : }
2250 : :
2251 : : static int
2252 : 0 : nfp_net_pause_frame_set(struct nfp_net_hw *net_hw,
2253 : : struct nfp_eth_table_port *eth_port,
2254 : : enum rte_eth_fc_mode mode)
2255 : : {
2256 : : int err;
2257 : : bool flag;
2258 : : struct nfp_nsp *nsp;
2259 : :
2260 : 0 : nsp = nfp_eth_config_start(net_hw->cpp, eth_port->index);
2261 [ # # ]: 0 : if (nsp == NULL) {
2262 : 0 : PMD_DRV_LOG(ERR, "NFP error when obtaining NSP handle.");
2263 : 0 : return -EIO;
2264 : : }
2265 : :
2266 : 0 : flag = (mode & RTE_ETH_FC_TX_PAUSE) == 0 ? false : true;
2267 : 0 : err = nfp_eth_set_tx_pause(nsp, flag);
2268 [ # # ]: 0 : if (err != 0) {
2269 : 0 : PMD_DRV_LOG(ERR, "Failed to configure TX pause frame.");
2270 : 0 : nfp_eth_config_cleanup_end(nsp);
2271 : 0 : return err;
2272 : : }
2273 : :
2274 : 0 : flag = (mode & RTE_ETH_FC_RX_PAUSE) == 0 ? false : true;
2275 : 0 : err = nfp_eth_set_rx_pause(nsp, flag);
2276 [ # # ]: 0 : if (err != 0) {
2277 : 0 : PMD_DRV_LOG(ERR, "Failed to configure RX pause frame.");
2278 : 0 : nfp_eth_config_cleanup_end(nsp);
2279 : 0 : return err;
2280 : : }
2281 : :
2282 : 0 : err = nfp_eth_config_commit_end(nsp);
2283 [ # # ]: 0 : if (err != 0) {
2284 : 0 : PMD_DRV_LOG(ERR, "Failed to configure pause frame.");
2285 : 0 : return err;
2286 : : }
2287 : :
2288 : : return 0;
2289 : : }
2290 : :
2291 : : int
2292 : 0 : nfp_net_flow_ctrl_set(struct rte_eth_dev *dev,
2293 : : struct rte_eth_fc_conf *fc_conf)
2294 : : {
2295 : : int ret;
2296 : : struct nfp_net_hw *net_hw;
2297 : : enum rte_eth_fc_mode set_mode;
2298 : : enum rte_eth_fc_mode original_mode;
2299 : : struct nfp_eth_table *nfp_eth_table;
2300 : : struct nfp_eth_table_port *eth_port;
2301 : :
2302 : 0 : net_hw = nfp_net_get_hw(dev);
2303 [ # # ]: 0 : if (net_hw->pf_dev == NULL)
2304 : : return -EINVAL;
2305 : :
2306 : 0 : nfp_eth_table = net_hw->pf_dev->nfp_eth_table;
2307 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[net_hw->idx];
2308 : :
2309 : : original_mode = nfp_net_get_pause_mode(eth_port);
2310 : 0 : set_mode = fc_conf->mode;
2311 : :
2312 [ # # ]: 0 : if (set_mode == original_mode)
2313 : : return 0;
2314 : :
2315 : 0 : ret = nfp_net_pause_frame_set(net_hw, eth_port, set_mode);
2316 [ # # ]: 0 : if (ret != 0)
2317 : : return ret;
2318 : :
2319 : : /* Update eth_table after modifying RX/TX pause frame mode. */
2320 : 0 : eth_port->tx_pause_enabled = (set_mode & RTE_ETH_FC_TX_PAUSE) == 0 ? false : true;
2321 : 0 : eth_port->rx_pause_enabled = (set_mode & RTE_ETH_FC_RX_PAUSE) == 0 ? false : true;
2322 : :
2323 : 0 : return 0;
2324 : : }
2325 : :
2326 : : int
2327 : 0 : nfp_net_fec_get_capability(struct rte_eth_dev *dev,
2328 : : struct rte_eth_fec_capa *speed_fec_capa,
2329 : : __rte_unused unsigned int num)
2330 : : {
2331 : : uint16_t speed;
2332 : : struct nfp_net_hw *hw;
2333 : : uint32_t supported_fec;
2334 : : struct nfp_eth_table *nfp_eth_table;
2335 : : struct nfp_eth_table_port *eth_port;
2336 : :
2337 : 0 : hw = nfp_net_get_hw(dev);
2338 [ # # ]: 0 : if (hw->pf_dev == NULL)
2339 : : return -EINVAL;
2340 : :
2341 : 0 : nfp_eth_table = hw->pf_dev->nfp_eth_table;
2342 : 0 : eth_port = &nfp_eth_table->ports[hw->idx];
2343 : :
2344 [ # # ]: 0 : speed = eth_port->speed;
2345 : : supported_fec = nfp_eth_supported_fec_modes(eth_port);
2346 [ # # ]: 0 : if (speed == 0 || supported_fec == 0) {
2347 : 0 : PMD_DRV_LOG(ERR, "FEC modes supported or Speed is invalid.");
2348 : 0 : return -EINVAL;
2349 : : }
2350 : :
2351 [ # # ]: 0 : if (speed_fec_capa == NULL)
2352 : : return NFP_FEC_CAPA_ENTRY_NUM;
2353 : :
2354 : 0 : speed_fec_capa->speed = speed;
2355 : :
2356 [ # # ]: 0 : if ((supported_fec & NFP_FEC_AUTO) != 0)
2357 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
2358 [ # # ]: 0 : if ((supported_fec & NFP_FEC_BASER) != 0)
2359 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
2360 [ # # ]: 0 : if ((supported_fec & NFP_FEC_REED_SOLOMON) != 0)
2361 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(RS);
2362 [ # # ]: 0 : if ((supported_fec & NFP_FEC_DISABLED) != 0)
2363 : 0 : speed_fec_capa->capa |= RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
2364 : :
2365 : : return NFP_FEC_CAPA_ENTRY_NUM;
2366 : : }
2367 : :
2368 : : static uint32_t
2369 : : nfp_net_fec_nfp_to_rte(enum nfp_eth_fec fec)
2370 : : {
2371 : : switch (fec) {
2372 : : case NFP_FEC_AUTO_BIT:
2373 : : return RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
2374 : : case NFP_FEC_BASER_BIT:
2375 : : return RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
2376 : : case NFP_FEC_REED_SOLOMON_BIT:
2377 : : return RTE_ETH_FEC_MODE_CAPA_MASK(RS);
2378 : : case NFP_FEC_DISABLED_BIT:
2379 : : return RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
2380 : 0 : default:
2381 : 0 : PMD_DRV_LOG(ERR, "FEC mode is invalid.");
2382 : 0 : return 0;
2383 : : }
2384 : : }
2385 : :
2386 : : int
2387 : 0 : nfp_net_fec_get(struct rte_eth_dev *dev,
2388 : : uint32_t *fec_capa)
2389 : : {
2390 : : struct nfp_net_hw *hw;
2391 : : struct nfp_eth_table *nfp_eth_table;
2392 : : struct nfp_eth_table_port *eth_port;
2393 : :
2394 : 0 : hw = nfp_net_get_hw(dev);
2395 [ # # ]: 0 : if (hw->pf_dev == NULL)
2396 : : return -EINVAL;
2397 : :
2398 [ # # ]: 0 : if (dev->data->dev_link.link_status == RTE_ETH_LINK_DOWN) {
2399 : 0 : nfp_eth_table = nfp_eth_read_ports(hw->cpp);
2400 : 0 : hw->pf_dev->nfp_eth_table->ports[hw->idx] = nfp_eth_table->ports[hw->idx];
2401 : 0 : free(nfp_eth_table);
2402 : : }
2403 : :
2404 : 0 : nfp_eth_table = hw->pf_dev->nfp_eth_table;
2405 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[hw->idx];
2406 : :
2407 [ # # ]: 0 : if (!nfp_eth_can_support_fec(eth_port)) {
2408 : 0 : PMD_DRV_LOG(ERR, "NFP can not support FEC.");
2409 : 0 : return -ENOTSUP;
2410 : : }
2411 : :
2412 : : /*
2413 : : * If link is down and AUTO is enabled, AUTO is returned, otherwise,
2414 : : * configured FEC mode is returned.
2415 : : * If link is up, current FEC mode is returned.
2416 : : */
2417 [ # # ]: 0 : if (dev->data->dev_link.link_status == RTE_ETH_LINK_DOWN)
2418 [ # # ]: 0 : *fec_capa = nfp_net_fec_nfp_to_rte(eth_port->fec);
2419 : : else
2420 [ # # ]: 0 : *fec_capa = nfp_net_fec_nfp_to_rte(eth_port->act_fec);
2421 : :
2422 [ # # ]: 0 : if (*fec_capa == 0)
2423 : 0 : return -EINVAL;
2424 : :
2425 : : return 0;
2426 : : }
2427 : :
2428 : : static enum nfp_eth_fec
2429 : : nfp_net_fec_rte_to_nfp(uint32_t fec)
2430 : : {
2431 : : switch (fec) {
2432 : : case RTE_BIT32(RTE_ETH_FEC_AUTO):
2433 : : return NFP_FEC_AUTO_BIT;
2434 : : case RTE_BIT32(RTE_ETH_FEC_NOFEC):
2435 : : return NFP_FEC_DISABLED_BIT;
2436 : : case RTE_BIT32(RTE_ETH_FEC_RS):
2437 : : return NFP_FEC_REED_SOLOMON_BIT;
2438 : : case RTE_BIT32(RTE_ETH_FEC_BASER):
2439 : : return NFP_FEC_BASER_BIT;
2440 : : default:
2441 : : return NFP_FEC_INVALID_BIT;
2442 : : }
2443 : : }
2444 : :
2445 : : int
2446 : 0 : nfp_net_fec_set(struct rte_eth_dev *dev,
2447 : : uint32_t fec_capa)
2448 : : {
2449 : : enum nfp_eth_fec fec;
2450 : : struct nfp_net_hw *hw;
2451 : : uint32_t supported_fec;
2452 : : struct nfp_eth_table *nfp_eth_table;
2453 : : struct nfp_eth_table_port *eth_port;
2454 : :
2455 : 0 : hw = nfp_net_get_hw(dev);
2456 [ # # ]: 0 : if (hw->pf_dev == NULL)
2457 : : return -EINVAL;
2458 : :
2459 : 0 : nfp_eth_table = hw->pf_dev->nfp_eth_table;
2460 [ # # ]: 0 : eth_port = &nfp_eth_table->ports[hw->idx];
2461 : :
2462 : : supported_fec = nfp_eth_supported_fec_modes(eth_port);
2463 [ # # ]: 0 : if (supported_fec == 0) {
2464 : 0 : PMD_DRV_LOG(ERR, "NFP can not support FEC.");
2465 : 0 : return -ENOTSUP;
2466 : : }
2467 : :
2468 : : fec = nfp_net_fec_rte_to_nfp(fec_capa);
2469 [ # # ]: 0 : if (fec == NFP_FEC_INVALID_BIT) {
2470 : 0 : PMD_DRV_LOG(ERR, "FEC modes is invalid.");
2471 : 0 : return -EINVAL;
2472 : : }
2473 : :
2474 [ # # ]: 0 : if ((RTE_BIT32(fec) & supported_fec) == 0) {
2475 : 0 : PMD_DRV_LOG(ERR, "Unsupported FEC mode is set.");
2476 : 0 : return -EIO;
2477 : : }
2478 : :
2479 : 0 : return nfp_eth_set_fec(hw->cpp, eth_port->index, fec);
2480 : : }
|