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