Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <cnxk_ethdev.h>
6 : :
7 : : int
8 : 0 : cnxk_nix_info_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *devinfo)
9 : : {
10 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
11 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
12 : : int max_rx_pktlen;
13 : :
14 : 0 : max_rx_pktlen = (roc_nix_max_pkt_len(&dev->nix) + RTE_ETHER_CRC_LEN -
15 : : CNXK_NIX_MAX_VTAG_ACT_SIZE);
16 : :
17 : 0 : devinfo->min_rx_bufsize = NIX_MIN_HW_FRS + RTE_ETHER_CRC_LEN;
18 : 0 : devinfo->max_rx_pktlen = max_rx_pktlen;
19 : 0 : devinfo->max_rx_queues = RTE_MAX_QUEUES_PER_PORT;
20 : 0 : devinfo->max_tx_queues = RTE_MAX_QUEUES_PER_PORT;
21 : 0 : devinfo->max_mac_addrs = dev->max_mac_entries;
22 : 0 : devinfo->max_vfs = pci_dev->max_vfs;
23 : 0 : devinfo->max_mtu = devinfo->max_rx_pktlen - CNXK_NIX_L2_OVERHEAD;
24 : 0 : devinfo->min_mtu = devinfo->min_rx_bufsize - CNXK_NIX_L2_OVERHEAD;
25 : :
26 : 0 : devinfo->rx_offload_capa = dev->rx_offload_capa;
27 : 0 : devinfo->tx_offload_capa = dev->tx_offload_capa;
28 : 0 : devinfo->rx_queue_offload_capa = 0;
29 : 0 : devinfo->tx_queue_offload_capa = 0;
30 : :
31 : 0 : devinfo->reta_size = dev->nix.reta_sz;
32 : 0 : devinfo->hash_key_size = ROC_NIX_RSS_KEY_LEN;
33 : 0 : devinfo->flow_type_rss_offloads = CNXK_NIX_RSS_OFFLOAD;
34 : :
35 : 0 : devinfo->default_rxconf = (struct rte_eth_rxconf){
36 : : .rx_drop_en = 0,
37 : : .offloads = 0,
38 : : };
39 : :
40 : 0 : devinfo->default_txconf = (struct rte_eth_txconf){
41 : : .offloads = 0,
42 : : };
43 : :
44 : 0 : devinfo->default_rxportconf = (struct rte_eth_dev_portconf){
45 : : .ring_size = CNXK_NIX_RX_DEFAULT_RING_SZ,
46 : : };
47 : :
48 : 0 : devinfo->rx_desc_lim = (struct rte_eth_desc_lim){
49 : : .nb_max = UINT16_MAX,
50 : : .nb_min = CNXK_NIX_RX_MIN_DESC,
51 : : .nb_align = CNXK_NIX_RX_MIN_DESC_ALIGN,
52 : : .nb_seg_max = CNXK_NIX_RX_NB_SEG_MAX,
53 : : .nb_mtu_seg_max = CNXK_NIX_RX_NB_SEG_MAX,
54 : : };
55 : 0 : devinfo->rx_desc_lim.nb_max =
56 : : RTE_ALIGN_MUL_FLOOR(devinfo->rx_desc_lim.nb_max,
57 : : CNXK_NIX_RX_MIN_DESC_ALIGN);
58 : :
59 : 0 : devinfo->tx_desc_lim = (struct rte_eth_desc_lim){
60 : : .nb_max = UINT16_MAX,
61 : : .nb_min = 1,
62 : : .nb_align = 1,
63 : : .nb_seg_max = CNXK_NIX_TX_NB_SEG_MAX,
64 : : .nb_mtu_seg_max = CNXK_NIX_TX_NB_SEG_MAX,
65 : : };
66 : :
67 : 0 : devinfo->speed_capa = dev->speed_capa;
68 : 0 : devinfo->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
69 : : RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP |
70 : : RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
71 : :
72 : 0 : devinfo->max_rx_mempools = CNXK_NIX_NUM_POOLS_MAX;
73 [ # # ]: 0 : if (eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) {
74 : 0 : devinfo->switch_info.name = eth_dev->device->name;
75 : 0 : devinfo->switch_info.domain_id = dev->switch_domain_id;
76 : : }
77 : :
78 : 0 : return 0;
79 : : }
80 : :
81 : : int
82 : 0 : cnxk_nix_rx_burst_mode_get(struct rte_eth_dev *eth_dev, uint16_t queue_id,
83 : : struct rte_eth_burst_mode *mode)
84 : : {
85 : : ssize_t bytes = 0, str_size = RTE_ETH_BURST_MODE_INFO_SIZE, rc;
86 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
87 : : const struct burst_info {
88 : : uint64_t flags;
89 : : const char *output;
90 : 0 : } rx_offload_map[] = {
91 : : {RTE_ETH_RX_OFFLOAD_VLAN_STRIP, " VLAN Strip,"},
92 : : {RTE_ETH_RX_OFFLOAD_IPV4_CKSUM, " Inner IPv4 Checksum,"},
93 : : {RTE_ETH_RX_OFFLOAD_UDP_CKSUM, " UDP Checksum,"},
94 : : {RTE_ETH_RX_OFFLOAD_TCP_CKSUM, " TCP Checksum,"},
95 : : {RTE_ETH_RX_OFFLOAD_TCP_LRO, " TCP LRO,"},
96 : : {RTE_ETH_RX_OFFLOAD_QINQ_STRIP, " QinQ VLAN Strip,"},
97 : : {RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM, " Outer IPv4 Checksum,"},
98 : : {RTE_ETH_RX_OFFLOAD_MACSEC_STRIP, " MACsec Strip,"},
99 : : {RTE_ETH_RX_OFFLOAD_VLAN_FILTER, " VLAN Filter,"},
100 : : {RTE_ETH_RX_OFFLOAD_VLAN_EXTEND, " VLAN Extend,"},
101 : : {RTE_ETH_RX_OFFLOAD_SCATTER, " Scattered,"},
102 : : {RTE_ETH_RX_OFFLOAD_TIMESTAMP, " Timestamp,"},
103 : : {RTE_ETH_RX_OFFLOAD_SECURITY, " Security,"},
104 : : {RTE_ETH_RX_OFFLOAD_KEEP_CRC, " Keep CRC,"},
105 : : {RTE_ETH_RX_OFFLOAD_SCTP_CKSUM, " SCTP,"},
106 : : {RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM, " Outer UDP Checksum,"},
107 : : {RTE_ETH_RX_OFFLOAD_RSS_HASH, " RSS,"}
108 : : };
109 : : static const char *const burst_mode[] = {"Vector Neon, Rx Offloads:",
110 : : "Scalar, Rx Offloads:"
111 : : };
112 : : uint32_t i;
113 : :
114 : : PLT_SET_USED(queue_id);
115 : :
116 : : /* Update burst mode info */
117 : 0 : rc = rte_strscpy(mode->info + bytes, burst_mode[dev->scalar_ena],
118 : : str_size - bytes);
119 [ # # ]: 0 : if (rc < 0)
120 : 0 : goto done;
121 : :
122 : : bytes += rc;
123 : :
124 : : /* Update Rx offload info */
125 [ # # ]: 0 : for (i = 0; i < RTE_DIM(rx_offload_map); i++) {
126 [ # # ]: 0 : if (dev->rx_offloads & rx_offload_map[i].flags) {
127 : 0 : rc = rte_strscpy(mode->info + bytes,
128 : 0 : rx_offload_map[i].output,
129 : 0 : str_size - bytes);
130 [ # # ]: 0 : if (rc < 0)
131 : 0 : goto done;
132 : :
133 : 0 : bytes += rc;
134 : : }
135 : : }
136 : :
137 : 0 : done:
138 : 0 : return 0;
139 : : }
140 : :
141 : : int
142 : 0 : cnxk_nix_tx_burst_mode_get(struct rte_eth_dev *eth_dev, uint16_t queue_id,
143 : : struct rte_eth_burst_mode *mode)
144 : : {
145 : : ssize_t bytes = 0, str_size = RTE_ETH_BURST_MODE_INFO_SIZE, rc;
146 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
147 : : const struct burst_info {
148 : : uint64_t flags;
149 : : const char *output;
150 : 0 : } tx_offload_map[] = {
151 : : {RTE_ETH_TX_OFFLOAD_VLAN_INSERT, " VLAN Insert,"},
152 : : {RTE_ETH_TX_OFFLOAD_IPV4_CKSUM, " Inner IPv4 Checksum,"},
153 : : {RTE_ETH_TX_OFFLOAD_UDP_CKSUM, " UDP Checksum,"},
154 : : {RTE_ETH_TX_OFFLOAD_TCP_CKSUM, " TCP Checksum,"},
155 : : {RTE_ETH_TX_OFFLOAD_SCTP_CKSUM, " SCTP Checksum,"},
156 : : {RTE_ETH_TX_OFFLOAD_TCP_TSO, " TCP TSO,"},
157 : : {RTE_ETH_TX_OFFLOAD_UDP_TSO, " UDP TSO,"},
158 : : {RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM, " Outer IPv4 Checksum,"},
159 : : {RTE_ETH_TX_OFFLOAD_QINQ_INSERT, " QinQ VLAN Insert,"},
160 : : {RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO, " VXLAN Tunnel TSO,"},
161 : : {RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO, " GRE Tunnel TSO,"},
162 : : {RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO, " IP-in-IP Tunnel TSO,"},
163 : : {RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO, " Geneve Tunnel TSO,"},
164 : : {RTE_ETH_TX_OFFLOAD_MACSEC_INSERT, " MACsec Insert,"},
165 : : {RTE_ETH_TX_OFFLOAD_MT_LOCKFREE, " Multi Thread Lockless Tx,"},
166 : : {RTE_ETH_TX_OFFLOAD_MULTI_SEGS, " Scattered,"},
167 : : {RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE, " H/W MBUF Free,"},
168 : : {RTE_ETH_TX_OFFLOAD_SECURITY, " Security,"},
169 : : {RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO, " UDP Tunnel TSO,"},
170 : : {RTE_ETH_TX_OFFLOAD_IP_TNL_TSO, " IP Tunnel TSO,"},
171 : : {RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM, " Outer UDP Checksum,"},
172 : : {RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP, " Timestamp,"}
173 : : };
174 : : static const char *const burst_mode[] = {"Vector Neon, Tx Offloads:",
175 : : "Scalar, Tx Offloads:"
176 : : };
177 : : uint32_t i;
178 : :
179 : : PLT_SET_USED(queue_id);
180 : :
181 : : /* Update burst mode info */
182 : 0 : rc = rte_strscpy(mode->info + bytes, burst_mode[dev->scalar_ena],
183 : : str_size - bytes);
184 [ # # ]: 0 : if (rc < 0)
185 : 0 : goto done;
186 : :
187 : : bytes += rc;
188 : :
189 : : /* Update Tx offload info */
190 [ # # ]: 0 : for (i = 0; i < RTE_DIM(tx_offload_map); i++) {
191 [ # # ]: 0 : if (dev->tx_offloads & tx_offload_map[i].flags) {
192 : 0 : rc = rte_strscpy(mode->info + bytes,
193 : 0 : tx_offload_map[i].output,
194 : 0 : str_size - bytes);
195 [ # # ]: 0 : if (rc < 0)
196 : 0 : goto done;
197 : :
198 : 0 : bytes += rc;
199 : : }
200 : : }
201 : :
202 : 0 : done:
203 : 0 : return 0;
204 : : }
205 : :
206 : : int
207 : 0 : cnxk_nix_flow_ctrl_get(struct rte_eth_dev *eth_dev,
208 : : struct rte_eth_fc_conf *fc_conf)
209 : : {
210 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
211 : 0 : enum rte_eth_fc_mode mode_map[2][2] = {
212 : : [0][0] = RTE_ETH_FC_NONE,
213 : : [0][1] = RTE_ETH_FC_TX_PAUSE,
214 : : [1][0] = RTE_ETH_FC_RX_PAUSE,
215 : : [1][1] = RTE_ETH_FC_FULL,
216 : : };
217 : 0 : struct roc_nix *nix = &dev->nix;
218 : : uint8_t rx_pause, tx_pause;
219 : : int mode, i;
220 : :
221 [ # # ]: 0 : if (roc_nix_is_sdp(nix))
222 : : return 0;
223 : :
224 : 0 : mode = roc_nix_fc_mode_get(nix);
225 [ # # ]: 0 : if (mode < 0)
226 : : return mode;
227 : :
228 : 0 : rx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_RX);
229 : 0 : tx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_TX);
230 : :
231 : : /* Report flow control as disabled even if one RQ/SQ has it disabled */
232 [ # # ]: 0 : for (i = 0; i < dev->nb_rxq; i++) {
233 [ # # ]: 0 : if (dev->rqs[i].tc == ROC_NIX_PFC_CLASS_INVALID)
234 : : tx_pause = 0;
235 : : }
236 : :
237 [ # # ]: 0 : for (i = 0; i < dev->nb_txq; i++) {
238 [ # # ]: 0 : if (dev->sqs[i].tc == ROC_NIX_PFC_CLASS_INVALID)
239 : : rx_pause = 0;
240 : : }
241 : :
242 : : memset(fc_conf, 0, sizeof(struct rte_eth_fc_conf));
243 : 0 : fc_conf->mode = mode_map[rx_pause][tx_pause];
244 : 0 : return 0;
245 : : }
246 : :
247 : : int
248 : 0 : cnxk_nix_flow_ctrl_set(struct rte_eth_dev *eth_dev,
249 : : struct rte_eth_fc_conf *fc_conf)
250 : : {
251 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
252 : 0 : enum roc_nix_fc_mode mode_map[] = {
253 : : ROC_NIX_FC_NONE, ROC_NIX_FC_RX,
254 : : ROC_NIX_FC_TX, ROC_NIX_FC_FULL
255 : : };
256 : : struct rte_eth_dev_data *data = eth_dev->data;
257 : : struct cnxk_fc_cfg *fc = &dev->fc_cfg;
258 : 0 : struct roc_nix *nix = &dev->nix;
259 : : struct cnxk_eth_rxq_sp *rxq;
260 : : struct cnxk_eth_txq_sp *txq;
261 : : uint8_t rx_pause, tx_pause;
262 : : struct roc_nix_sq *sq;
263 : : struct roc_nix_cq *cq;
264 : : struct roc_nix_rq *rq;
265 : : uint8_t tc;
266 : : int rc, i;
267 : :
268 [ # # ]: 0 : if (roc_nix_is_sdp(nix))
269 : : return 0;
270 : :
271 [ # # ]: 0 : if (dev->pfc_cfg.rx_pause_en || dev->pfc_cfg.tx_pause_en) {
272 : 0 : plt_err("Disable PFC before configuring Flow Control");
273 : 0 : return -ENOTSUP;
274 : : }
275 : :
276 [ # # # # : 0 : if (fc_conf->high_water || fc_conf->low_water || fc_conf->pause_time ||
# # ]
277 [ # # ]: 0 : fc_conf->mac_ctrl_frame_fwd || fc_conf->autoneg) {
278 : 0 : plt_info("Only MODE configuration is supported");
279 : 0 : return -EINVAL;
280 : : }
281 : :
282 : : /* Disallow flow control changes when device is in started state */
283 [ # # ]: 0 : if (data->dev_started) {
284 : 0 : plt_info("Stop the port=%d for setting flow control", data->port_id);
285 : 0 : return -EBUSY;
286 : : }
287 : :
288 : 0 : rx_pause = (fc_conf->mode == RTE_ETH_FC_FULL) || (fc_conf->mode == RTE_ETH_FC_RX_PAUSE);
289 : 0 : tx_pause = (fc_conf->mode == RTE_ETH_FC_FULL) || (fc_conf->mode == RTE_ETH_FC_TX_PAUSE);
290 : :
291 : : /* Check if TX pause frame is already enabled or not */
292 [ # # ]: 0 : tc = tx_pause ? 0 : ROC_NIX_PFC_CLASS_INVALID;
293 [ # # ]: 0 : for (i = 0; i < data->nb_rx_queues; i++) {
294 : : struct roc_nix_fc_cfg fc_cfg;
295 : :
296 : : /* Skip if RQ does not exist */
297 [ # # ]: 0 : if (!data->rx_queues[i])
298 : 0 : continue;
299 : :
300 : : rxq = cnxk_eth_rxq_to_sp(data->rx_queues[i]);
301 : 0 : rq = &dev->rqs[rxq->qid];
302 : 0 : cq = &dev->cqs[rxq->qid];
303 : :
304 : : /* Skip if RQ is in expected state */
305 [ # # # # ]: 0 : if (fc->tx_pause == tx_pause && rq->tc == tc)
306 : 0 : continue;
307 : :
308 : : memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
309 : 0 : fc_cfg.type = ROC_NIX_FC_RQ_CFG;
310 : 0 : fc_cfg.rq_cfg.enable = !!tx_pause;
311 : : fc_cfg.rq_cfg.tc = 0;
312 : 0 : fc_cfg.rq_cfg.rq = rq->qid;
313 : 0 : fc_cfg.rq_cfg.pool = rq->aura_handle;
314 : 0 : fc_cfg.rq_cfg.spb_pool = rq->spb_aura_handle;
315 : 0 : fc_cfg.rq_cfg.cq_drop = cq->drop_thresh;
316 : 0 : fc_cfg.rq_cfg.cq_bp = cq->bp_thresh;
317 : 0 : fc_cfg.rq_cfg.pool_drop_pct = ROC_NIX_AURA_THRESH;
318 : :
319 : 0 : rc = roc_nix_fc_config_set(nix, &fc_cfg);
320 [ # # ]: 0 : if (rc)
321 : 0 : return rc;
322 : 0 : rxq->tx_pause = !!tx_pause;
323 : : }
324 : :
325 : : /* Check if RX pause frame is enabled or not */
326 [ # # ]: 0 : tc = rx_pause ? 0 : ROC_NIX_PFC_CLASS_INVALID;
327 [ # # ]: 0 : for (i = 0; i < data->nb_tx_queues; i++) {
328 : : struct roc_nix_fc_cfg fc_cfg;
329 : :
330 : : /* Skip if SQ does not exist */
331 [ # # ]: 0 : if (!data->tx_queues[i])
332 : 0 : continue;
333 : :
334 : : txq = cnxk_eth_txq_to_sp(data->tx_queues[i]);
335 : 0 : sq = &dev->sqs[txq->qid];
336 : :
337 : : /* Skip if SQ is in expected state */
338 [ # # # # ]: 0 : if (fc->rx_pause == rx_pause && sq->tc == tc)
339 : 0 : continue;
340 : :
341 : : memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
342 : 0 : fc_cfg.type = ROC_NIX_FC_TM_CFG;
343 : 0 : fc_cfg.tm_cfg.sq = txq->qid;
344 : : fc_cfg.tm_cfg.tc = 0;
345 : 0 : fc_cfg.tm_cfg.enable = !!rx_pause;
346 : 0 : rc = roc_nix_fc_config_set(nix, &fc_cfg);
347 [ # # ]: 0 : if (rc && rc != EEXIST)
348 : 0 : return rc;
349 : : }
350 : :
351 : : /* Skip mode set if it is we are in same state */
352 [ # # # # ]: 0 : if (fc->rx_pause == rx_pause && fc->tx_pause == tx_pause)
353 : : return 0;
354 : :
355 : 0 : rc = roc_nix_fc_mode_set(nix, mode_map[fc_conf->mode]);
356 [ # # ]: 0 : if (rc)
357 : : return rc;
358 : :
359 : 0 : fc->rx_pause = rx_pause;
360 : 0 : fc->tx_pause = tx_pause;
361 : 0 : fc->mode = fc_conf->mode;
362 : 0 : return rc;
363 : : }
364 : :
365 : : int
366 : 0 : cnxk_nix_priority_flow_ctrl_queue_info_get(struct rte_eth_dev *eth_dev,
367 : : struct rte_eth_pfc_queue_info *pfc_info)
368 : : {
369 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
370 : :
371 : 0 : pfc_info->tc_max = roc_nix_chan_count_get(&dev->nix);
372 : 0 : pfc_info->mode_capa = RTE_ETH_FC_FULL;
373 : 0 : return 0;
374 : : }
375 : :
376 : : int
377 [ # # ]: 0 : cnxk_nix_priority_flow_ctrl_queue_config(struct rte_eth_dev *eth_dev,
378 : : struct rte_eth_pfc_queue_conf *pfc_conf)
379 : : {
380 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
381 : : struct rte_eth_dev_data *data = eth_dev->data;
382 : 0 : struct roc_nix *nix = &dev->nix;
383 : : enum rte_eth_fc_mode mode;
384 : : uint8_t en, tc;
385 : : uint16_t qid;
386 : : int rc = 0;
387 : :
388 [ # # ]: 0 : if (dev->fc_cfg.mode != RTE_ETH_FC_NONE) {
389 : 0 : plt_err("Disable Flow Control before configuring PFC");
390 : 0 : return -ENOTSUP;
391 : : }
392 : :
393 [ # # # # ]: 0 : if (roc_nix_is_sdp(nix) || roc_nix_is_lbk(nix)) {
394 : 0 : plt_nix_dbg("Prio flow ctrl config is not allowed on SDP/LBK");
395 : 0 : return -ENOTSUP;
396 : : }
397 : :
398 : : /* Disallow flow control changes when device is in started state */
399 [ # # ]: 0 : if (data->dev_started) {
400 : 0 : plt_info("Stop the port=%d for setting PFC", data->port_id);
401 : 0 : return -EBUSY;
402 : : }
403 : :
404 : 0 : mode = pfc_conf->mode;
405 : :
406 : : /* Perform Tx pause configuration on RQ */
407 : 0 : qid = pfc_conf->tx_pause.rx_qid;
408 [ # # ]: 0 : if (qid < eth_dev->data->nb_rx_queues) {
409 : 0 : en = (mode == RTE_ETH_FC_FULL) || (mode == RTE_ETH_FC_TX_PAUSE);
410 : 0 : tc = pfc_conf->tx_pause.tc;
411 : 0 : rc = nix_priority_flow_ctrl_rq_conf(eth_dev, qid, en, tc);
412 : : }
413 : :
414 : : /* Perform Rx pause configuration on SQ */
415 : 0 : qid = pfc_conf->rx_pause.tx_qid;
416 [ # # ]: 0 : if (qid < eth_dev->data->nb_tx_queues) {
417 : 0 : en = (mode == RTE_ETH_FC_FULL) || (mode == RTE_ETH_FC_RX_PAUSE);
418 : 0 : tc = pfc_conf->rx_pause.tc;
419 : 0 : rc |= nix_priority_flow_ctrl_sq_conf(eth_dev, qid, en, tc);
420 : : }
421 : :
422 : : return rc;
423 : : }
424 : :
425 : : int
426 : 0 : cnxk_nix_flow_ops_get(struct rte_eth_dev *eth_dev,
427 : : const struct rte_flow_ops **ops)
428 : : {
429 : : RTE_SET_USED(eth_dev);
430 : :
431 : 0 : *ops = &cnxk_flow_ops;
432 : 0 : return 0;
433 : : }
434 : :
435 : : int
436 : 0 : cnxk_nix_mac_addr_set(struct rte_eth_dev *eth_dev, struct rte_ether_addr *addr)
437 : : {
438 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
439 : 0 : struct roc_nix *nix = &dev->nix;
440 : : int rc;
441 : :
442 : : /* Update mac address at NPC */
443 : 0 : rc = roc_nix_npc_mac_addr_set(nix, addr->addr_bytes);
444 [ # # ]: 0 : if (rc)
445 : 0 : goto exit;
446 : :
447 : : /* Update mac address at CGX for PFs only */
448 [ # # ]: 0 : if (!roc_nix_is_vf_or_sdp(nix)) {
449 : 0 : rc = roc_nix_mac_addr_set(nix, addr->addr_bytes);
450 [ # # ]: 0 : if (rc) {
451 : : /* Rollback to previous mac address */
452 : 0 : roc_nix_npc_mac_addr_set(nix, dev->mac_addr);
453 : 0 : goto exit;
454 : : }
455 : :
456 [ # # ]: 0 : if (eth_dev->data->promiscuous) {
457 : 0 : rc = roc_nix_mac_promisc_mode_enable(nix, true);
458 [ # # ]: 0 : if (rc)
459 : 0 : plt_err("Failed to setup promisc mode in mac, rc=%d(%s)", rc,
460 : : roc_error_msg_get(rc));
461 : : }
462 : : }
463 : :
464 : : /* Update mac address to cnxk ethernet device */
465 [ # # ]: 0 : rte_memcpy(dev->mac_addr, addr->addr_bytes, RTE_ETHER_ADDR_LEN);
466 : :
467 : 0 : exit:
468 : 0 : return rc;
469 : : }
470 : :
471 : : int
472 [ # # ]: 0 : cnxk_nix_mac_addr_add(struct rte_eth_dev *eth_dev, struct rte_ether_addr *addr,
473 : : uint32_t index, uint32_t pool)
474 : : {
475 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
476 : 0 : struct roc_nix *nix = &dev->nix;
477 : : struct rte_ether_addr *current;
478 : : int rc;
479 : :
480 : : PLT_SET_USED(pool);
481 : :
482 [ # # ]: 0 : if (dev->dmac_idx_map[index] != CNXK_NIX_DMAC_IDX_INVALID) {
483 : 0 : current = &dev->dmac_addrs[index];
484 : 0 : plt_nix_dbg("Mac address %02x:%02x:%02x:%02x:%02x:%02x already exists at index %u",
485 : : current->addr_bytes[0], current->addr_bytes[1], current->addr_bytes[2],
486 : : current->addr_bytes[3], current->addr_bytes[4], current->addr_bytes[5],
487 : : index);
488 : 0 : return 0;
489 : : }
490 : :
491 : 0 : rc = roc_nix_mac_addr_add(nix, addr->addr_bytes);
492 [ # # ]: 0 : if (rc < 0) {
493 : 0 : plt_err("Failed to add mac address, rc=%d", rc);
494 : 0 : return rc;
495 : : }
496 : :
497 : 0 : dev->dmac_idx_map[index] = rc;
498 : 0 : plt_nix_dbg("Added mac address %02x:%02x:%02x:%02x:%02x:%02x at index %u(%d)",
499 : : addr->addr_bytes[0], addr->addr_bytes[1], addr->addr_bytes[2],
500 : : addr->addr_bytes[3], addr->addr_bytes[4], addr->addr_bytes[5], index, rc);
501 : :
502 : 0 : memcpy(&dev->dmac_addrs[index], addr, RTE_ETHER_ADDR_LEN);
503 : :
504 : : /* Enable promiscuous mode at NIX level */
505 : 0 : roc_nix_npc_promisc_ena_dis(nix, true);
506 : 0 : dev->dmac_filter_enable = true;
507 : 0 : eth_dev->data->promiscuous = false;
508 : 0 : dev->dmac_filter_count++;
509 : :
510 : 0 : return 0;
511 : : }
512 : :
513 : : void
514 : 0 : cnxk_nix_mac_addr_del(struct rte_eth_dev *eth_dev, uint32_t index)
515 : : {
516 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
517 : 0 : struct roc_nix *nix = &dev->nix;
518 : : int rc;
519 : :
520 : 0 : rc = roc_nix_mac_addr_del(nix, dev->dmac_idx_map[index]);
521 [ # # ]: 0 : if (rc)
522 : 0 : plt_err("Failed to delete mac address, rc=%d", rc);
523 : :
524 : 0 : plt_nix_dbg("Deleted mac address at index %u(%d)", index, dev->dmac_idx_map[index]);
525 : 0 : dev->dmac_idx_map[index] = CNXK_NIX_DMAC_IDX_INVALID;
526 : 0 : dev->dmac_filter_count--;
527 : 0 : }
528 : :
529 : : int
530 : 0 : cnxk_nix_sq_flush(struct rte_eth_dev *eth_dev)
531 : : {
532 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
533 : : struct rte_eth_dev_data *data = eth_dev->data;
534 : : int i, rc = 0;
535 : :
536 : : /* Flush all tx queues */
537 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
538 : 0 : struct roc_nix_sq *sq = &dev->sqs[i];
539 : :
540 [ # # ]: 0 : if (eth_dev->data->tx_queues[i] == NULL)
541 : 0 : continue;
542 : :
543 : 0 : rc = roc_nix_tm_sq_aura_fc(sq, false);
544 [ # # ]: 0 : if (rc) {
545 : 0 : plt_err("Failed to disable sqb aura fc, rc=%d", rc);
546 : 0 : goto exit;
547 : : }
548 : :
549 : : /* Wait for sq entries to be flushed */
550 : 0 : rc = roc_nix_tm_sq_flush_spin(sq);
551 [ # # ]: 0 : if (rc) {
552 : 0 : plt_err("Failed to drain sq, rc=%d", rc);
553 : 0 : goto exit;
554 : : }
555 [ # # ]: 0 : if (data->tx_queue_state[i] == RTE_ETH_QUEUE_STATE_STARTED) {
556 : 0 : rc = roc_nix_tm_sq_aura_fc(sq, true);
557 [ # # ]: 0 : if (rc) {
558 : 0 : plt_err("Failed to enable sq aura fc, txq=%u, rc=%d", i, rc);
559 : 0 : goto exit;
560 : : }
561 : : }
562 : : }
563 : 0 : exit:
564 : 0 : return rc;
565 : : }
566 : :
567 : : int
568 : 0 : cnxk_nix_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
569 : : {
570 [ # # ]: 0 : uint32_t old_frame_size, frame_size = mtu + CNXK_NIX_L2_OVERHEAD;
571 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
572 : : struct rte_eth_dev_data *data = eth_dev->data;
573 : 0 : struct roc_nix *nix = &dev->nix;
574 : : struct cnxk_eth_rxq_sp *rxq_sp;
575 : : uint32_t buffsz = 0;
576 : : int rc = -EINVAL;
577 : :
578 : 0 : frame_size += CNXK_NIX_TIMESYNC_RX_OFFSET * dev->ptp_en;
579 : :
580 : : /* Check if MTU is within the allowed range */
581 [ # # ]: 0 : if ((frame_size - RTE_ETHER_CRC_LEN) < NIX_MIN_HW_FRS) {
582 : 0 : plt_err("MTU is lesser than minimum");
583 : 0 : goto exit;
584 : : }
585 : :
586 : 0 : if ((frame_size - RTE_ETHER_CRC_LEN) >
587 [ # # ]: 0 : ((uint32_t)roc_nix_max_pkt_len(nix))) {
588 : 0 : plt_err("MTU is greater than maximum");
589 : 0 : goto exit;
590 : : }
591 : :
592 [ # # ]: 0 : if (!eth_dev->data->nb_rx_queues)
593 : 0 : goto skip_buffsz_check;
594 : :
595 : : /* Perform buff size check */
596 [ # # ]: 0 : if (data->min_rx_buf_size) {
597 : : buffsz = data->min_rx_buf_size;
598 [ # # # # ]: 0 : } else if (eth_dev->data->rx_queues && eth_dev->data->rx_queues[0]) {
599 : 0 : rxq_sp = cnxk_eth_rxq_to_sp(data->rx_queues[0]);
600 : :
601 [ # # ]: 0 : if (rxq_sp->qconf.mp)
602 : 0 : buffsz = rte_pktmbuf_data_room_size(rxq_sp->qconf.mp);
603 : : }
604 : :
605 : : /* Skip validation if RQ's are not yet setup */
606 [ # # ]: 0 : if (!buffsz)
607 : 0 : goto skip_buffsz_check;
608 : :
609 : 0 : buffsz -= RTE_PKTMBUF_HEADROOM;
610 : :
611 : : /* Refuse MTU that requires the support of scattered packets
612 : : * when this feature has not been enabled before.
613 : : */
614 [ # # # # ]: 0 : if (data->dev_started && frame_size > buffsz &&
615 [ # # ]: 0 : !(dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER)) {
616 [ # # ]: 0 : if (!roc_nix_is_sdp(nix)) {
617 : 0 : plt_err("Scatter offload is not enabled for mtu");
618 : 0 : goto exit;
619 : : }
620 : 0 : plt_warn("Scatter offload is not enabled for mtu on SDP interface");
621 : : }
622 : :
623 : : /* Check <seg size> * <max_seg> >= max_frame */
624 [ # # ]: 0 : if ((dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER) &&
625 [ # # ]: 0 : frame_size > (buffsz * CNXK_NIX_RX_NB_SEG_MAX)) {
626 : 0 : plt_err("Greater than maximum supported packet length");
627 : 0 : goto exit;
628 : : }
629 : :
630 : 0 : skip_buffsz_check:
631 : 0 : old_frame_size = data->mtu + CNXK_NIX_L2_OVERHEAD;
632 : : /* if new MTU was smaller than old one, then flush all SQs before MTU change */
633 [ # # ]: 0 : if (old_frame_size > frame_size) {
634 [ # # ]: 0 : if (data->dev_started) {
635 : 0 : plt_err("Reducing MTU is not supported when device started");
636 : 0 : goto exit;
637 : : }
638 : 0 : cnxk_nix_sq_flush(eth_dev);
639 : : }
640 : :
641 : : frame_size -= RTE_ETHER_CRC_LEN;
642 : :
643 : : /* Set frame size on Rx */
644 : 0 : rc = roc_nix_mac_max_rx_len_set(nix, frame_size);
645 [ # # ]: 0 : if (rc) {
646 : 0 : plt_err("Failed to max Rx frame length, rc=%d", rc);
647 : 0 : goto exit;
648 : : }
649 : 0 : exit:
650 : 0 : return rc;
651 : : }
652 : :
653 : : int
654 : 0 : cnxk_nix_promisc_enable(struct rte_eth_dev *eth_dev)
655 : : {
656 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
657 : 0 : struct roc_nix *nix = &dev->nix;
658 : : int rc = 0;
659 : :
660 [ # # ]: 0 : if (roc_nix_is_vf_or_sdp(nix))
661 : : return rc;
662 : :
663 : 0 : rc = roc_nix_npc_promisc_ena_dis(nix, true);
664 [ # # ]: 0 : if (rc) {
665 : 0 : plt_err("Failed to setup promisc mode in npc, rc=%d(%s)", rc,
666 : : roc_error_msg_get(rc));
667 : 0 : return rc;
668 : : }
669 : :
670 : 0 : rc = roc_nix_mac_promisc_mode_enable(nix, true);
671 [ # # ]: 0 : if (rc) {
672 : 0 : plt_err("Failed to setup promisc mode in mac, rc=%d(%s)", rc,
673 : : roc_error_msg_get(rc));
674 : 0 : roc_nix_npc_promisc_ena_dis(nix, false);
675 : 0 : return rc;
676 : : }
677 : :
678 : : return 0;
679 : : }
680 : :
681 : : int
682 : 0 : cnxk_nix_promisc_disable(struct rte_eth_dev *eth_dev)
683 : : {
684 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
685 : 0 : struct roc_nix *nix = &dev->nix;
686 : : int rc = 0;
687 : :
688 [ # # ]: 0 : if (roc_nix_is_vf_or_sdp(nix))
689 : : return rc;
690 : :
691 : 0 : rc = roc_nix_npc_promisc_ena_dis(nix, dev->dmac_filter_enable);
692 [ # # ]: 0 : if (rc) {
693 : 0 : plt_err("Failed to setup promisc mode in npc, rc=%d(%s)", rc,
694 : : roc_error_msg_get(rc));
695 : 0 : return rc;
696 : : }
697 : :
698 : 0 : rc = roc_nix_mac_promisc_mode_enable(nix, false);
699 [ # # ]: 0 : if (rc) {
700 : 0 : plt_err("Failed to setup promisc mode in mac, rc=%d(%s)", rc,
701 : : roc_error_msg_get(rc));
702 : 0 : roc_nix_npc_promisc_ena_dis(nix, !dev->dmac_filter_enable);
703 : 0 : return rc;
704 : : }
705 : :
706 : 0 : dev->dmac_filter_enable = false;
707 : 0 : return 0;
708 : : }
709 : :
710 : : int
711 : 0 : cnxk_nix_allmulticast_enable(struct rte_eth_dev *eth_dev)
712 : : {
713 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
714 : :
715 : 0 : return roc_nix_npc_mcast_config(&dev->nix, true,
716 : 0 : eth_dev->data->promiscuous);
717 : : }
718 : :
719 : : int
720 : 0 : cnxk_nix_allmulticast_disable(struct rte_eth_dev *eth_dev)
721 : : {
722 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
723 : :
724 : 0 : return roc_nix_npc_mcast_config(&dev->nix, false,
725 : 0 : eth_dev->data->promiscuous);
726 : : }
727 : :
728 : : int
729 : 0 : cnxk_nix_set_link_up(struct rte_eth_dev *eth_dev)
730 : : {
731 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
732 : 0 : struct roc_nix *nix = &dev->nix;
733 : : int rc, i;
734 : :
735 [ # # ]: 0 : if (roc_nix_is_vf_or_sdp(nix))
736 : : return -ENOTSUP;
737 : :
738 : 0 : rc = roc_nix_mac_link_state_set(nix, true);
739 [ # # ]: 0 : if (rc)
740 : 0 : goto exit;
741 : :
742 : : /* Start tx queues */
743 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
744 : 0 : rc = cnxk_nix_tx_queue_start(eth_dev, i);
745 [ # # ]: 0 : if (rc)
746 : 0 : goto exit;
747 : : }
748 : :
749 : 0 : exit:
750 : : return rc;
751 : : }
752 : :
753 : : int
754 : 0 : cnxk_nix_set_link_down(struct rte_eth_dev *eth_dev)
755 : : {
756 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
757 : 0 : struct roc_nix *nix = &dev->nix;
758 : : int rc, i;
759 : :
760 [ # # ]: 0 : if (roc_nix_is_vf_or_sdp(nix))
761 : : return -ENOTSUP;
762 : :
763 : : /* Stop tx queues */
764 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
765 : 0 : rc = cnxk_nix_tx_queue_stop(eth_dev, i);
766 [ # # ]: 0 : if (rc)
767 : 0 : goto exit;
768 : : }
769 : :
770 : 0 : rc = roc_nix_mac_link_state_set(nix, false);
771 : : exit:
772 : : return rc;
773 : : }
774 : :
775 : : int
776 : 0 : cnxk_nix_get_module_info(struct rte_eth_dev *eth_dev,
777 : : struct rte_eth_dev_module_info *modinfo)
778 : : {
779 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
780 : 0 : struct roc_nix_eeprom_info eeprom_info = {0};
781 : 0 : struct roc_nix *nix = &dev->nix;
782 : : int rc;
783 : :
784 : 0 : rc = roc_nix_eeprom_info_get(nix, &eeprom_info);
785 [ # # ]: 0 : if (rc)
786 : : return rc;
787 : :
788 : 0 : modinfo->type = eeprom_info.sff_id;
789 : 0 : modinfo->eeprom_len = ROC_NIX_EEPROM_SIZE;
790 : 0 : return 0;
791 : : }
792 : :
793 : : int
794 [ # # ]: 0 : cnxk_nix_get_module_eeprom(struct rte_eth_dev *eth_dev,
795 : : struct rte_dev_eeprom_info *info)
796 : : {
797 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
798 : 0 : struct roc_nix_eeprom_info eeprom_info = {0};
799 : 0 : struct roc_nix *nix = &dev->nix;
800 : : int rc = -EINVAL;
801 : :
802 [ # # # # ]: 0 : if (!info->data || !info->length ||
803 [ # # ]: 0 : (info->offset + info->length > ROC_NIX_EEPROM_SIZE))
804 : : return rc;
805 : :
806 : 0 : rc = roc_nix_eeprom_info_get(nix, &eeprom_info);
807 [ # # ]: 0 : if (rc)
808 : : return rc;
809 : :
810 [ # # ]: 0 : rte_memcpy(info->data, eeprom_info.buf + info->offset, info->length);
811 : : return 0;
812 : : }
813 : :
814 : : int
815 : 0 : cnxk_nix_rx_queue_intr_enable(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
816 : : {
817 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
818 : :
819 : 0 : roc_nix_rx_queue_intr_enable(&dev->nix, rx_queue_id);
820 : 0 : return 0;
821 : : }
822 : :
823 : : int
824 : 0 : cnxk_nix_rx_queue_intr_disable(struct rte_eth_dev *eth_dev,
825 : : uint16_t rx_queue_id)
826 : : {
827 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
828 : :
829 : 0 : roc_nix_rx_queue_intr_disable(&dev->nix, rx_queue_id);
830 : 0 : return 0;
831 : : }
832 : :
833 : : int
834 : 0 : cnxk_nix_pool_ops_supported(struct rte_eth_dev *eth_dev, const char *pool)
835 : : {
836 : : RTE_SET_USED(eth_dev);
837 : :
838 [ # # ]: 0 : if (!strcmp(pool, rte_mbuf_platform_mempool_ops()))
839 : 0 : return 0;
840 : :
841 : : return -ENOTSUP;
842 : : }
843 : :
844 : : int
845 : 0 : cnxk_nix_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version,
846 : : size_t fw_size)
847 : : {
848 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
849 : 0 : const char *str = roc_npc_profile_name_get(&dev->npc);
850 : 0 : uint32_t size = strlen(str) + 1;
851 : :
852 [ # # ]: 0 : if (fw_size > size)
853 : : fw_size = size;
854 : :
855 : : rte_strlcpy(fw_version, str, fw_size);
856 : :
857 [ # # ]: 0 : if (fw_size < size)
858 : 0 : return size;
859 : :
860 : : return 0;
861 : : }
862 : :
863 : : void
864 : 0 : cnxk_nix_rxq_info_get(struct rte_eth_dev *eth_dev, uint16_t qid,
865 : : struct rte_eth_rxq_info *qinfo)
866 : : {
867 : 0 : void *rxq = eth_dev->data->rx_queues[qid];
868 : : struct cnxk_eth_rxq_sp *rxq_sp = cnxk_eth_rxq_to_sp(rxq);
869 : :
870 : : memset(qinfo, 0, sizeof(*qinfo));
871 : :
872 : 0 : qinfo->mp = rxq_sp->qconf.mp;
873 : 0 : qinfo->scattered_rx = eth_dev->data->scattered_rx;
874 : 0 : qinfo->nb_desc = rxq_sp->qconf.nb_desc;
875 : :
876 : 0 : memcpy(&qinfo->conf, &rxq_sp->qconf.conf.rx, sizeof(qinfo->conf));
877 : 0 : }
878 : :
879 : : void
880 : 0 : cnxk_nix_txq_info_get(struct rte_eth_dev *eth_dev, uint16_t qid,
881 : : struct rte_eth_txq_info *qinfo)
882 : : {
883 : 0 : void *txq = eth_dev->data->tx_queues[qid];
884 : : struct cnxk_eth_txq_sp *txq_sp = cnxk_eth_txq_to_sp(txq);
885 : :
886 : : memset(qinfo, 0, sizeof(*qinfo));
887 : :
888 : 0 : qinfo->nb_desc = txq_sp->qconf.nb_desc;
889 : :
890 : 0 : memcpy(&qinfo->conf, &txq_sp->qconf.conf.tx, sizeof(qinfo->conf));
891 : 0 : }
892 : :
893 : : int
894 : 0 : cnxk_nix_rx_queue_count(void *rxq)
895 : : {
896 : : struct cnxk_eth_rxq_sp *rxq_sp = cnxk_eth_rxq_to_sp(rxq);
897 : 0 : struct roc_nix *nix = &rxq_sp->dev->nix;
898 : : uint32_t head, tail;
899 : :
900 : 0 : roc_nix_cq_head_tail_get(nix, rxq_sp->qid, &head, &tail);
901 : 0 : return (tail - head) % (rxq_sp->qconf.nb_desc);
902 : : }
903 : :
904 : : static inline int
905 : : nix_offset_has_packet(uint32_t head, uint32_t tail, uint16_t offset, bool is_rx)
906 : : {
907 : : /* Check given offset(queue index) has packet filled/xmit by HW
908 : : * in case of Rx or Tx.
909 : : * Also, checks for wrap around case.
910 : : */
911 [ # # # # : 0 : return ((tail > head && offset <= tail && offset >= head) ||
# # # # #
# # # ]
912 [ # # # # : 0 : (head > tail && (offset >= head || offset <= tail))) ?
# # # # ]
913 : 0 : is_rx :
914 : : !is_rx;
915 : : }
916 : :
917 : : int
918 : 0 : cnxk_nix_rx_descriptor_status(void *rxq, uint16_t offset)
919 : : {
920 : : struct cnxk_eth_rxq_sp *rxq_sp = cnxk_eth_rxq_to_sp(rxq);
921 : 0 : struct roc_nix *nix = &rxq_sp->dev->nix;
922 : : uint32_t head, tail;
923 : :
924 [ # # ]: 0 : if (rxq_sp->qconf.nb_desc <= offset)
925 : : return -EINVAL;
926 : :
927 : 0 : roc_nix_cq_head_tail_get(nix, rxq_sp->qid, &head, &tail);
928 : :
929 [ # # ]: 0 : if (nix_offset_has_packet(head, tail, offset, 1))
930 : 0 : return RTE_ETH_RX_DESC_DONE;
931 : : else
932 : : return RTE_ETH_RX_DESC_AVAIL;
933 : : }
934 : :
935 : : int
936 : 0 : cnxk_nix_tx_descriptor_status(void *txq, uint16_t offset)
937 : : {
938 : : struct cnxk_eth_txq_sp *txq_sp = cnxk_eth_txq_to_sp(txq);
939 : 0 : struct roc_nix *nix = &txq_sp->dev->nix;
940 : 0 : uint32_t head = 0, tail = 0;
941 : :
942 [ # # ]: 0 : if (txq_sp->qconf.nb_desc <= offset)
943 : : return -EINVAL;
944 : :
945 : 0 : roc_nix_sq_head_tail_get(nix, txq_sp->qid, &head, &tail);
946 : :
947 [ # # ]: 0 : if (nix_offset_has_packet(head, tail, offset, 0))
948 : : return RTE_ETH_TX_DESC_DONE;
949 : : else
950 : 0 : return RTE_ETH_TX_DESC_FULL;
951 : : }
952 : :
953 : : /* It is a NOP for cnxk as HW frees the buffer on xmit */
954 : : int
955 : 0 : cnxk_nix_tx_done_cleanup(void *txq, uint32_t free_cnt)
956 : : {
957 : : RTE_SET_USED(txq);
958 : : RTE_SET_USED(free_cnt);
959 : :
960 : 0 : return 0;
961 : : }
962 : :
963 : : int
964 [ # # ]: 0 : cnxk_nix_dev_get_reg(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
965 : : {
966 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
967 : 0 : struct roc_nix *nix = &dev->nix;
968 : 0 : uint64_t *data = regs->data;
969 : : int rc = -ENOTSUP;
970 : :
971 [ # # ]: 0 : if (data == NULL) {
972 : 0 : rc = roc_nix_lf_get_reg_count(nix);
973 [ # # ]: 0 : if (rc > 0) {
974 : 0 : regs->length = rc;
975 : 0 : regs->width = 8;
976 : : rc = 0;
977 : : }
978 : 0 : return rc;
979 : : }
980 : :
981 [ # # ]: 0 : if (!regs->length ||
982 [ # # ]: 0 : regs->length == (uint32_t)roc_nix_lf_get_reg_count(nix))
983 : 0 : return roc_nix_lf_reg_dump(nix, data);
984 : :
985 : : return rc;
986 : : }
987 : :
988 : : int
989 [ # # ]: 0 : cnxk_nix_reta_update(struct rte_eth_dev *eth_dev,
990 : : struct rte_eth_rss_reta_entry64 *reta_conf,
991 : : uint16_t reta_size)
992 : : {
993 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
994 : : uint16_t reta[ROC_NIX_RSS_RETA_MAX];
995 : 0 : struct roc_nix *nix = &dev->nix;
996 : : int i, j, rc = -EINVAL, idx = 0;
997 : :
998 [ # # ]: 0 : if (reta_size != dev->nix.reta_sz) {
999 : 0 : plt_err("Size of hash lookup table configured (%d) does not "
1000 : : "match the number hardware can supported (%d)",
1001 : : reta_size, dev->nix.reta_sz);
1002 : 0 : goto fail;
1003 : : }
1004 : :
1005 : 0 : roc_nix_rss_reta_get(nix, 0, reta);
1006 : :
1007 : : /* Copy RETA table */
1008 [ # # ]: 0 : for (i = 0; i < (int)(dev->nix.reta_sz / RTE_ETH_RETA_GROUP_SIZE); i++) {
1009 [ # # ]: 0 : for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) {
1010 [ # # ]: 0 : if ((reta_conf[i].mask >> j) & 0x01)
1011 : 0 : reta[idx] = reta_conf[i].reta[j];
1012 : 0 : idx++;
1013 : : }
1014 : : }
1015 : :
1016 : 0 : return roc_nix_rss_reta_set(nix, 0, reta);
1017 : :
1018 : : fail:
1019 : 0 : return rc;
1020 : : }
1021 : :
1022 : : int
1023 [ # # ]: 0 : cnxk_nix_reta_query(struct rte_eth_dev *eth_dev,
1024 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1025 : : uint16_t reta_size)
1026 : : {
1027 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1028 : : uint16_t reta[ROC_NIX_RSS_RETA_MAX];
1029 : 0 : struct roc_nix *nix = &dev->nix;
1030 : : int rc = -EINVAL, i, j, idx = 0;
1031 : :
1032 [ # # ]: 0 : if (reta_size != dev->nix.reta_sz) {
1033 : 0 : plt_err("Size of hash lookup table configured (%d) does not "
1034 : : "match the number hardware can supported (%d)",
1035 : : reta_size, dev->nix.reta_sz);
1036 : 0 : goto fail;
1037 : : }
1038 : :
1039 : 0 : rc = roc_nix_rss_reta_get(nix, 0, reta);
1040 [ # # ]: 0 : if (rc)
1041 : 0 : goto fail;
1042 : :
1043 : : /* Copy RETA table */
1044 [ # # ]: 0 : for (i = 0; i < (int)(dev->nix.reta_sz / RTE_ETH_RETA_GROUP_SIZE); i++) {
1045 [ # # ]: 0 : for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) {
1046 [ # # ]: 0 : if ((reta_conf[i].mask >> j) & 0x01)
1047 : 0 : reta_conf[i].reta[j] = reta[idx];
1048 : 0 : idx++;
1049 : : }
1050 : : }
1051 : :
1052 : : return 0;
1053 : :
1054 : : fail:
1055 : : return rc;
1056 : : }
1057 : :
1058 : : int
1059 : 0 : cnxk_nix_eth_dev_priv_dump(struct rte_eth_dev *eth_dev, FILE *file)
1060 : : {
1061 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1062 : 0 : struct roc_nix *roc_nix = &dev->nix;
1063 : : int i;
1064 : :
1065 : 0 : roc_nix_dump(roc_nix, file);
1066 : :
1067 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
1068 : 0 : roc_nix_rq_dump(&dev->rqs[i], file);
1069 : :
1070 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
1071 : 0 : roc_nix_cq_dump(&dev->cqs[i], file);
1072 : :
1073 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
1074 : 0 : roc_nix_sq_dump(&dev->sqs[i], file);
1075 : :
1076 : 0 : roc_nix_queues_ctx_dump(roc_nix, file);
1077 : :
1078 : 0 : roc_nix_tm_dump(roc_nix, file);
1079 : :
1080 : 0 : roc_nix_inl_dev_dump(NULL, file);
1081 : :
1082 : 0 : roc_nix_inl_outb_cpt_lfs_dump(roc_nix, file);
1083 : :
1084 : 0 : return 0;
1085 : : }
1086 : :
1087 : : int
1088 [ # # ]: 0 : cnxk_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
1089 : : struct rte_eth_rss_conf *rss_conf)
1090 : : {
1091 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1092 : 0 : struct roc_nix *nix = &dev->nix;
1093 : : uint8_t rss_hash_level;
1094 : : uint32_t flowkey_cfg;
1095 : : int rc = -EINVAL;
1096 : : uint8_t alg_idx;
1097 : :
1098 [ # # # # ]: 0 : if (rss_conf->rss_key && rss_conf->rss_key_len != ROC_NIX_RSS_KEY_LEN) {
1099 : 0 : plt_err("Hash key size mismatch %d vs %d",
1100 : : rss_conf->rss_key_len, ROC_NIX_RSS_KEY_LEN);
1101 : 0 : goto fail;
1102 : : }
1103 : :
1104 [ # # ]: 0 : if (rss_conf->rss_key)
1105 : 0 : roc_nix_rss_key_set(nix, rss_conf->rss_key);
1106 : :
1107 : 0 : rss_hash_level = RTE_ETH_RSS_LEVEL(rss_conf->rss_hf);
1108 [ # # ]: 0 : if (rss_hash_level)
1109 : 0 : rss_hash_level -= 1;
1110 : : flowkey_cfg =
1111 : 0 : cnxk_rss_ethdev_to_nix(dev, rss_conf->rss_hf, rss_hash_level);
1112 : :
1113 : 0 : rc = roc_nix_rss_flowkey_set(nix, &alg_idx, flowkey_cfg,
1114 : : ROC_NIX_RSS_GROUP_DEFAULT,
1115 : : ROC_NIX_RSS_MCAM_IDX_DEFAULT);
1116 [ # # ]: 0 : if (rc) {
1117 : 0 : plt_err("Failed to set RSS hash function rc=%d", rc);
1118 : 0 : return rc;
1119 : : }
1120 : :
1121 : 0 : fail:
1122 : : return rc;
1123 : : }
1124 : :
1125 : : int
1126 [ # # ]: 0 : cnxk_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
1127 : : struct rte_eth_rss_conf *rss_conf)
1128 : : {
1129 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1130 : :
1131 [ # # ]: 0 : if (rss_conf->rss_key)
1132 : 0 : roc_nix_rss_key_get(&dev->nix, rss_conf->rss_key);
1133 : :
1134 : 0 : rss_conf->rss_key_len = ROC_NIX_RSS_KEY_LEN;
1135 : 0 : rss_conf->rss_hf = dev->ethdev_rss_hf;
1136 : :
1137 : 0 : return 0;
1138 : : }
1139 : :
1140 : : static int
1141 [ # # ]: 0 : nix_find_mac_addr(struct rte_eth_dev *eth_dev, struct rte_ether_addr *addr)
1142 : : {
1143 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1144 : : struct rte_ether_addr null_mac_addr;
1145 : : int i;
1146 : :
1147 : : memset(&null_mac_addr, 0, sizeof(null_mac_addr));
1148 [ # # ]: 0 : addr = addr ? addr : &null_mac_addr;
1149 [ # # ]: 0 : for (i = 0; i < dev->max_mac_entries; i++) {
1150 [ # # ]: 0 : if (!memcmp(ð_dev->data->mac_addrs[i], addr, sizeof(*addr)))
1151 : 0 : return i;
1152 : : }
1153 : :
1154 : : return -ENOENT;
1155 : : }
1156 : :
1157 : : static inline int
1158 : 0 : nix_mc_addr_list_flush(struct rte_eth_dev *eth_dev)
1159 : : {
1160 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1161 : : struct rte_eth_dev_data *data = eth_dev->data;
1162 : : struct rte_ether_addr null_mac_addr;
1163 : 0 : struct roc_nix *nix = &dev->nix;
1164 : : int i, rc = 0;
1165 : :
1166 : : memset(&null_mac_addr, 0, sizeof(null_mac_addr));
1167 : :
1168 : : /* All configured multicast filters should be flushed first */
1169 [ # # ]: 0 : for (i = 0; i < dev->max_mac_entries; i++) {
1170 [ # # ]: 0 : if (rte_is_multicast_ether_addr(&data->mac_addrs[i])) {
1171 : 0 : rc = roc_nix_mac_addr_del(nix, i);
1172 [ # # ]: 0 : if (rc) {
1173 : 0 : plt_err("Failed to flush mcast address, rc=%d",
1174 : : rc);
1175 : 0 : return rc;
1176 : : }
1177 : :
1178 : 0 : plt_nix_dbg("Deleted mac address at index %u(%d)", i, dev->dmac_idx_map[i]);
1179 : :
1180 : 0 : dev->dmac_idx_map[i] = CNXK_NIX_DMAC_IDX_INVALID;
1181 : 0 : dev->dmac_filter_count--;
1182 : : /* Update address in NIC data structure */
1183 : 0 : rte_ether_addr_copy(&null_mac_addr,
1184 : 0 : &data->mac_addrs[i]);
1185 : : }
1186 : : }
1187 : :
1188 : : return rc;
1189 : : }
1190 : :
1191 : : int
1192 [ # # ]: 0 : cnxk_nix_mc_addr_list_configure(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mc_addr_set,
1193 : : uint32_t nb_mc_addr)
1194 : : {
1195 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1196 : : struct rte_eth_dev_data *data = eth_dev->data;
1197 : 0 : struct roc_nix *nix = &dev->nix;
1198 : : int index, mc_addr_cnt = 0, j;
1199 : : uint32_t i;
1200 : :
1201 [ # # ]: 0 : if (!mc_addr_set || !nb_mc_addr)
1202 : 0 : return nix_mc_addr_list_flush(eth_dev);
1203 : :
1204 : : /* Count multicast MAC addresses in list */
1205 [ # # ]: 0 : for (i = 0; i < dev->max_mac_entries; i++)
1206 [ # # ]: 0 : if (rte_is_multicast_ether_addr(&data->mac_addrs[i]))
1207 : 0 : mc_addr_cnt++;
1208 : :
1209 : : /* Check for available space */
1210 : 0 : if (nb_mc_addr >
1211 [ # # ]: 0 : ((uint32_t)(dev->max_mac_entries - (dev->dmac_filter_count - mc_addr_cnt)))) {
1212 : 0 : plt_err("No space is available to add multicast filters");
1213 : 0 : return -ENOSPC;
1214 : : }
1215 : 0 : nix_mc_addr_list_flush(eth_dev);
1216 : :
1217 : : j = 0;
1218 : : /* Multicast addresses are to be installed */
1219 [ # # ]: 0 : for (i = 0; i < nb_mc_addr; i++) {
1220 : 0 : j = nix_find_mac_addr(eth_dev, NULL);
1221 [ # # ]: 0 : if (j < 0) {
1222 : 0 : plt_err("Failed to find free mac address");
1223 : 0 : return -ENOSPC;
1224 : : }
1225 : :
1226 : 0 : index = roc_nix_mac_addr_add(nix, mc_addr_set[i].addr_bytes);
1227 [ # # ]: 0 : if (index < 0) {
1228 : 0 : plt_err("Failed to add mcast mac address, rc=%d",
1229 : : index);
1230 : 0 : return index;
1231 : : }
1232 : :
1233 : 0 : dev->dmac_idx_map[j] = index;
1234 : 0 : plt_nix_dbg("Added mac address %02x:%02x:%02x:%02x:%02x:%02x at index %u(%d)",
1235 : : mc_addr_set[i].addr_bytes[0], mc_addr_set[i].addr_bytes[1],
1236 : : mc_addr_set[i].addr_bytes[2], mc_addr_set[i].addr_bytes[3],
1237 : : mc_addr_set[i].addr_bytes[4], mc_addr_set[i].addr_bytes[5], j, index);
1238 : :
1239 : 0 : dev->dmac_filter_count++;
1240 : : /* Update address in NIC data structure */
1241 : 0 : rte_ether_addr_copy(&mc_addr_set[i], &data->mac_addrs[j]);
1242 : 0 : rte_ether_addr_copy(&mc_addr_set[i], &dev->dmac_addrs[j]);
1243 : 0 : data->mac_pool_sel[j] = RTE_BIT64(0);
1244 : : }
1245 : :
1246 : 0 : roc_nix_npc_promisc_ena_dis(nix, true);
1247 : 0 : dev->dmac_filter_enable = true;
1248 : 0 : eth_dev->data->promiscuous = false;
1249 : :
1250 : 0 : return 0;
1251 : : }
1252 : :
1253 : : int
1254 [ # # ]: 0 : nix_priority_flow_ctrl_rq_conf(struct rte_eth_dev *eth_dev, uint16_t qid,
1255 : : uint8_t tx_pause, uint8_t tc)
1256 : : {
1257 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1258 : : struct rte_eth_dev_data *data = eth_dev->data;
1259 : : struct cnxk_pfc_cfg *pfc = &dev->pfc_cfg;
1260 : 0 : struct roc_nix *nix = &dev->nix;
1261 : : struct roc_nix_pfc_cfg pfc_cfg;
1262 : : struct roc_nix_fc_cfg fc_cfg;
1263 : : struct cnxk_eth_rxq_sp *rxq;
1264 : : enum roc_nix_fc_mode mode;
1265 : : struct roc_nix_rq *rq;
1266 : : struct roc_nix_cq *cq;
1267 : : int rc, i;
1268 : :
1269 [ # # ]: 0 : if (data->dev_started) {
1270 : : /* RQ should be in disabled state
1271 : : * while setting flow control configuration.
1272 : : */
1273 : 0 : plt_info("Stop the port=%d for setting flow control",
1274 : : data->port_id);
1275 : 0 : return 0;
1276 : : }
1277 : :
1278 [ # # ]: 0 : if (data->rx_queues == NULL)
1279 : : return -EINVAL;
1280 : :
1281 [ # # ]: 0 : if (qid >= eth_dev->data->nb_rx_queues)
1282 : : return -ENOTSUP;
1283 : :
1284 : : /* Configure RQ */
1285 : 0 : rxq = ((struct cnxk_eth_rxq_sp *)data->rx_queues[qid]) - 1;
1286 : 0 : rq = &dev->rqs[qid];
1287 : 0 : cq = &dev->cqs[qid];
1288 : :
1289 : : memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
1290 : 0 : fc_cfg.type = ROC_NIX_FC_RQ_CFG;
1291 : 0 : fc_cfg.rq_cfg.tc = tc;
1292 : 0 : fc_cfg.rq_cfg.enable = !!tx_pause;
1293 : 0 : fc_cfg.rq_cfg.rq = rq->qid;
1294 : 0 : fc_cfg.rq_cfg.pool = rxq->qconf.mp->pool_id;
1295 : 0 : fc_cfg.rq_cfg.spb_pool = rq->spb_aura_handle;
1296 : 0 : fc_cfg.rq_cfg.cq_drop = cq->drop_thresh;
1297 : 0 : fc_cfg.rq_cfg.cq_bp = cq->bp_thresh;
1298 : 0 : fc_cfg.rq_cfg.pool_drop_pct = ROC_NIX_AURA_THRESH;
1299 : 0 : rc = roc_nix_fc_config_set(nix, &fc_cfg);
1300 [ # # ]: 0 : if (rc)
1301 : : return rc;
1302 : :
1303 : 0 : rxq->tx_pause = !!tx_pause;
1304 : 0 : rxq->tc = tc;
1305 : : /* Recheck number of RQ's that have PFC enabled */
1306 : 0 : pfc->tx_pause_en = 0;
1307 [ # # ]: 0 : for (i = 0; i < dev->nb_rxq; i++)
1308 [ # # ]: 0 : if (dev->rqs[i].tc != ROC_NIX_PFC_CLASS_INVALID)
1309 : 0 : pfc->tx_pause_en++;
1310 : :
1311 : : /* Skip if PFC already enabled in mac */
1312 [ # # ]: 0 : if (pfc->tx_pause_en > 1)
1313 : : return 0;
1314 : :
1315 : : /* Configure MAC block */
1316 [ # # ]: 0 : pfc->class_en = pfc->tx_pause_en ? 0xFF : 0x0;
1317 : :
1318 [ # # ]: 0 : if (pfc->rx_pause_en)
1319 [ # # ]: 0 : mode = pfc->tx_pause_en ? ROC_NIX_FC_FULL : ROC_NIX_FC_RX;
1320 : : else
1321 [ # # ]: 0 : mode = pfc->tx_pause_en ? ROC_NIX_FC_TX : ROC_NIX_FC_NONE;
1322 : :
1323 : : memset(&pfc_cfg, 0, sizeof(struct roc_nix_pfc_cfg));
1324 : 0 : pfc_cfg.mode = mode;
1325 : 0 : pfc_cfg.tc = pfc->class_en;
1326 : 0 : return roc_nix_pfc_mode_set(nix, &pfc_cfg);
1327 : : }
1328 : :
1329 : : int
1330 [ # # ]: 0 : nix_priority_flow_ctrl_sq_conf(struct rte_eth_dev *eth_dev, uint16_t qid,
1331 : : uint8_t rx_pause, uint8_t tc)
1332 : : {
1333 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1334 : : struct rte_eth_dev_data *data = eth_dev->data;
1335 : : struct cnxk_pfc_cfg *pfc = &dev->pfc_cfg;
1336 : 0 : struct roc_nix *nix = &dev->nix;
1337 : : struct roc_nix_pfc_cfg pfc_cfg;
1338 : : struct roc_nix_fc_cfg fc_cfg;
1339 : : struct cnxk_eth_txq_sp *txq;
1340 : : enum roc_nix_fc_mode mode;
1341 : : struct roc_nix_sq *sq;
1342 : : int rc, i;
1343 : :
1344 [ # # ]: 0 : if (data->tx_queues == NULL)
1345 : : return -EINVAL;
1346 : :
1347 [ # # ]: 0 : if (qid >= eth_dev->data->nb_tx_queues)
1348 : : return -ENOTSUP;
1349 : :
1350 : : /* Check if RX pause frame is enabled or not and
1351 : : * confirm user requested for PFC.
1352 : : */
1353 [ # # # # ]: 0 : if (!pfc->rx_pause_en && rx_pause) {
1354 [ # # ]: 0 : if ((roc_nix_tm_tree_type_get(nix) == ROC_NIX_TM_DEFAULT) &&
1355 [ # # ]: 0 : eth_dev->data->nb_tx_queues > 1) {
1356 : : /*
1357 : : * Disabled xmit will be enabled when
1358 : : * new topology is available.
1359 : : */
1360 : 0 : rc = roc_nix_tm_hierarchy_disable(nix);
1361 [ # # ]: 0 : if (rc)
1362 : 0 : goto exit;
1363 : :
1364 : 0 : rc = roc_nix_tm_pfc_prepare_tree(nix);
1365 [ # # ]: 0 : if (rc)
1366 : 0 : goto exit;
1367 : :
1368 : 0 : rc = roc_nix_tm_hierarchy_enable(nix, ROC_NIX_TM_PFC,
1369 : : true);
1370 [ # # ]: 0 : if (rc)
1371 : 0 : goto exit;
1372 : : }
1373 : : }
1374 : :
1375 : 0 : txq = ((struct cnxk_eth_txq_sp *)data->tx_queues[qid]) - 1;
1376 : 0 : sq = &dev->sqs[txq->qid];
1377 : : memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
1378 : 0 : fc_cfg.type = ROC_NIX_FC_TM_CFG;
1379 : 0 : fc_cfg.tm_cfg.sq = sq->qid;
1380 : 0 : fc_cfg.tm_cfg.tc = tc;
1381 : 0 : fc_cfg.tm_cfg.enable = !!rx_pause;
1382 : 0 : rc = roc_nix_fc_config_set(nix, &fc_cfg);
1383 [ # # ]: 0 : if (rc)
1384 : : return rc;
1385 : :
1386 : : /* Recheck number of SQ's that have PFC enabled */
1387 : 0 : pfc->rx_pause_en = 0;
1388 [ # # ]: 0 : for (i = 0; i < dev->nb_txq; i++)
1389 [ # # ]: 0 : if (dev->sqs[i].tc != ROC_NIX_PFC_CLASS_INVALID)
1390 : 0 : pfc->rx_pause_en++;
1391 : :
1392 [ # # ]: 0 : if (pfc->rx_pause_en > 1)
1393 : 0 : goto exit;
1394 : :
1395 [ # # ]: 0 : if (pfc->tx_pause_en)
1396 [ # # ]: 0 : mode = pfc->rx_pause_en ? ROC_NIX_FC_FULL : ROC_NIX_FC_TX;
1397 : : else
1398 : 0 : mode = pfc->rx_pause_en ? ROC_NIX_FC_RX : ROC_NIX_FC_NONE;
1399 : :
1400 : : memset(&pfc_cfg, 0, sizeof(struct roc_nix_pfc_cfg));
1401 : 0 : pfc_cfg.mode = mode;
1402 : 0 : pfc_cfg.tc = pfc->class_en;
1403 : 0 : rc = roc_nix_pfc_mode_set(nix, &pfc_cfg);
1404 : : exit:
1405 : : return rc;
1406 : : }
1407 : :
1408 : : int
1409 : 0 : cnxk_nix_tx_descriptor_dump(const struct rte_eth_dev *eth_dev, uint16_t qid, uint16_t offset,
1410 : : uint16_t num, FILE *file)
1411 : : {
1412 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1413 : 0 : struct roc_nix *nix = &dev->nix;
1414 : :
1415 : 0 : return roc_nix_sq_desc_dump(nix, qid, offset, num, file);
1416 : : }
|