1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RVU Admin Function driver
3 *
4 * Copyright (C) 2018 Marvell.
5 *
6 */
7
8 #include <linux/module.h>
9 #include <linux/pci.h>
10
11 #include "rvu_struct.h"
12 #include "rvu_reg.h"
13 #include "rvu.h"
14 #include "npc.h"
15 #include "mcs.h"
16 #include "cgx.h"
17 #include "lmac_common.h"
18 #include "rvu_npc_hash.h"
19 #include "cn20k/npc.h"
20
21 static void nix_free_tx_vtag_entries(struct rvu *rvu, u16 pcifunc);
22 static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req,
23 int type, int chan_id);
24 static int nix_update_mce_rule(struct rvu *rvu, u16 pcifunc,
25 int type, bool add);
26 static int nix_setup_ipolicers(struct rvu *rvu,
27 struct nix_hw *nix_hw, int blkaddr);
28 static void nix_ipolicer_freemem(struct rvu *rvu, struct nix_hw *nix_hw);
29 static int nix_verify_bandprof(struct nix_cn10k_aq_enq_req *req,
30 struct nix_hw *nix_hw, u16 pcifunc);
31 static int nix_free_all_bandprof(struct rvu *rvu, u16 pcifunc);
32 static void nix_clear_ratelimit_aggr(struct rvu *rvu, struct nix_hw *nix_hw,
33 u32 leaf_prof);
34 static const char *nix_get_ctx_name(int ctype);
35 static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc);
36
37 enum mc_tbl_sz {
38 MC_TBL_SZ_256,
39 MC_TBL_SZ_512,
40 MC_TBL_SZ_1K,
41 MC_TBL_SZ_2K,
42 MC_TBL_SZ_4K,
43 MC_TBL_SZ_8K,
44 MC_TBL_SZ_16K,
45 MC_TBL_SZ_32K,
46 MC_TBL_SZ_64K,
47 };
48
49 enum mc_buf_cnt {
50 MC_BUF_CNT_8,
51 MC_BUF_CNT_16,
52 MC_BUF_CNT_32,
53 MC_BUF_CNT_64,
54 MC_BUF_CNT_128,
55 MC_BUF_CNT_256,
56 MC_BUF_CNT_512,
57 MC_BUF_CNT_1024,
58 MC_BUF_CNT_2048,
59 };
60
61 enum nix_makr_fmt_indexes {
62 NIX_MARK_CFG_IP_DSCP_RED,
63 NIX_MARK_CFG_IP_DSCP_YELLOW,
64 NIX_MARK_CFG_IP_DSCP_YELLOW_RED,
65 NIX_MARK_CFG_IP_ECN_RED,
66 NIX_MARK_CFG_IP_ECN_YELLOW,
67 NIX_MARK_CFG_IP_ECN_YELLOW_RED,
68 NIX_MARK_CFG_VLAN_DEI_RED,
69 NIX_MARK_CFG_VLAN_DEI_YELLOW,
70 NIX_MARK_CFG_VLAN_DEI_YELLOW_RED,
71 NIX_MARK_CFG_MAX,
72 };
73
74 /* For now considering MC resources needed for broadcast
75 * pkt replication only. i.e 256 HWVFs + 12 PFs.
76 */
77 #define MC_TBL_SIZE MC_TBL_SZ_2K
78 #define MC_BUF_CNT MC_BUF_CNT_1024
79
80 #define MC_TX_MAX 2048
81
82 struct mce {
83 struct hlist_node node;
84 u32 rq_rss_index;
85 u16 pcifunc;
86 u16 channel;
87 u8 dest_type;
88 u8 is_active;
89 u8 reserved[2];
90 };
91
rvu_get_next_nix_blkaddr(struct rvu * rvu,int blkaddr)92 int rvu_get_next_nix_blkaddr(struct rvu *rvu, int blkaddr)
93 {
94 int i = 0;
95
96 /*If blkaddr is 0, return the first nix block address*/
97 if (blkaddr == 0)
98 return rvu->nix_blkaddr[blkaddr];
99
100 while (i + 1 < MAX_NIX_BLKS) {
101 if (rvu->nix_blkaddr[i] == blkaddr)
102 return rvu->nix_blkaddr[i + 1];
103 i++;
104 }
105
106 return 0;
107 }
108
is_nixlf_attached(struct rvu * rvu,u16 pcifunc)109 bool is_nixlf_attached(struct rvu *rvu, u16 pcifunc)
110 {
111 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
112 int blkaddr;
113
114 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
115 if (!pfvf->nixlf || blkaddr < 0)
116 return false;
117 return true;
118 }
119
rvu_get_nixlf_count(struct rvu * rvu)120 int rvu_get_nixlf_count(struct rvu *rvu)
121 {
122 int blkaddr = 0, max = 0;
123 struct rvu_block *block;
124
125 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
126 while (blkaddr) {
127 block = &rvu->hw->block[blkaddr];
128 max += block->lf.max;
129 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
130 }
131 return max;
132 }
133
nix_get_nixlf(struct rvu * rvu,u16 pcifunc,int * nixlf,int * nix_blkaddr)134 int nix_get_nixlf(struct rvu *rvu, u16 pcifunc, int *nixlf, int *nix_blkaddr)
135 {
136 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
137 struct rvu_hwinfo *hw = rvu->hw;
138 int blkaddr;
139
140 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
141 if (!pfvf->nixlf || blkaddr < 0)
142 return NIX_AF_ERR_AF_LF_INVALID;
143
144 *nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
145 if (*nixlf < 0)
146 return NIX_AF_ERR_AF_LF_INVALID;
147
148 if (nix_blkaddr)
149 *nix_blkaddr = blkaddr;
150
151 return 0;
152 }
153
nix_get_struct_ptrs(struct rvu * rvu,u16 pcifunc,struct nix_hw ** nix_hw,int * blkaddr)154 int nix_get_struct_ptrs(struct rvu *rvu, u16 pcifunc,
155 struct nix_hw **nix_hw, int *blkaddr)
156 {
157 struct rvu_pfvf *pfvf;
158
159 pfvf = rvu_get_pfvf(rvu, pcifunc);
160 *blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
161 if (!pfvf->nixlf || *blkaddr < 0)
162 return NIX_AF_ERR_AF_LF_INVALID;
163
164 *nix_hw = get_nix_hw(rvu->hw, *blkaddr);
165 if (!*nix_hw)
166 return NIX_AF_ERR_INVALID_NIXBLK;
167 return 0;
168 }
169
nix_mce_list_init(struct nix_mce_list * list,int max)170 static void nix_mce_list_init(struct nix_mce_list *list, int max)
171 {
172 INIT_HLIST_HEAD(&list->head);
173 list->count = 0;
174 list->max = max;
175 }
176
nix_alloc_mce_list(struct nix_mcast * mcast,int count,u8 dir)177 static int nix_alloc_mce_list(struct nix_mcast *mcast, int count, u8 dir)
178 {
179 struct rsrc_bmap *mce_counter;
180 int idx;
181
182 if (!mcast)
183 return -EINVAL;
184
185 mce_counter = &mcast->mce_counter[dir];
186 if (!rvu_rsrc_check_contig(mce_counter, count))
187 return -ENOSPC;
188
189 idx = rvu_alloc_rsrc_contig(mce_counter, count);
190 return idx;
191 }
192
nix_free_mce_list(struct nix_mcast * mcast,int count,int start,u8 dir)193 static void nix_free_mce_list(struct nix_mcast *mcast, int count, int start, u8 dir)
194 {
195 struct rsrc_bmap *mce_counter;
196
197 if (!mcast)
198 return;
199
200 mce_counter = &mcast->mce_counter[dir];
201 rvu_free_rsrc_contig(mce_counter, count, start);
202 }
203
get_nix_hw(struct rvu_hwinfo * hw,int blkaddr)204 struct nix_hw *get_nix_hw(struct rvu_hwinfo *hw, int blkaddr)
205 {
206 int nix_blkaddr = 0, i = 0;
207 struct rvu *rvu = hw->rvu;
208
209 nix_blkaddr = rvu_get_next_nix_blkaddr(rvu, nix_blkaddr);
210 while (nix_blkaddr) {
211 if (blkaddr == nix_blkaddr && hw->nix)
212 return &hw->nix[i];
213 nix_blkaddr = rvu_get_next_nix_blkaddr(rvu, nix_blkaddr);
214 i++;
215 }
216 return NULL;
217 }
218
nix_get_dwrr_mtu_reg(struct rvu_hwinfo * hw,int smq_link_type)219 int nix_get_dwrr_mtu_reg(struct rvu_hwinfo *hw, int smq_link_type)
220 {
221 if (hw->cap.nix_multiple_dwrr_mtu)
222 return NIX_AF_DWRR_MTUX(smq_link_type);
223
224 if (smq_link_type == SMQ_LINK_TYPE_SDP)
225 return NIX_AF_DWRR_SDP_MTU;
226
227 /* Here it's same reg for RPM and LBK */
228 return NIX_AF_DWRR_RPM_MTU;
229 }
230
convert_dwrr_mtu_to_bytes(u8 dwrr_mtu)231 u32 convert_dwrr_mtu_to_bytes(u8 dwrr_mtu)
232 {
233 dwrr_mtu &= 0x1FULL;
234
235 /* MTU used for DWRR calculation is in power of 2 up until 64K bytes.
236 * Value of 4 is reserved for MTU value of 9728 bytes.
237 * Value of 5 is reserved for MTU value of 10240 bytes.
238 */
239 switch (dwrr_mtu) {
240 case 4:
241 return 9728;
242 case 5:
243 return 10240;
244 default:
245 return BIT_ULL(dwrr_mtu);
246 }
247
248 return 0;
249 }
250
convert_bytes_to_dwrr_mtu(u32 bytes)251 u32 convert_bytes_to_dwrr_mtu(u32 bytes)
252 {
253 /* MTU used for DWRR calculation is in power of 2 up until 64K bytes.
254 * Value of 4 is reserved for MTU value of 9728 bytes.
255 * Value of 5 is reserved for MTU value of 10240 bytes.
256 */
257 if (bytes > BIT_ULL(16))
258 return 0;
259
260 switch (bytes) {
261 case 9728:
262 return 4;
263 case 10240:
264 return 5;
265 default:
266 return ilog2(bytes);
267 }
268
269 return 0;
270 }
271
nix_rx_sync(struct rvu * rvu,int blkaddr)272 static int nix_rx_sync(struct rvu *rvu, int blkaddr)
273 {
274 int err;
275
276 mutex_lock(&rvu->rsrc_lock);
277
278 /* Sync all in flight RX packets to LLC/DRAM */
279 rvu_write64(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0));
280 err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true);
281 if (err) {
282 dev_err(rvu->dev, "SYNC1: NIX RX software sync failed\n");
283 goto unlock;
284 }
285
286 /* SW_SYNC ensures all existing transactions are finished and pkts
287 * are written to LLC/DRAM, queues should be teared down after
288 * successful SW_SYNC. Due to a HW errata, in some rare scenarios
289 * an existing transaction might end after SW_SYNC operation. To
290 * ensure operation is fully done, do the SW_SYNC twice.
291 */
292 rvu_write64(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0));
293 err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true);
294 if (err)
295 dev_err(rvu->dev, "SYNC2: NIX RX software sync failed\n");
296
297 unlock:
298 mutex_unlock(&rvu->rsrc_lock);
299 return err;
300 }
301
is_valid_txschq(struct rvu * rvu,int blkaddr,int lvl,u16 pcifunc,u16 schq)302 static bool is_valid_txschq(struct rvu *rvu, int blkaddr,
303 int lvl, u16 pcifunc, u16 schq)
304 {
305 struct rvu_hwinfo *hw = rvu->hw;
306 struct nix_txsch *txsch;
307 struct nix_hw *nix_hw;
308 u16 map_func;
309
310 nix_hw = get_nix_hw(rvu->hw, blkaddr);
311 if (!nix_hw)
312 return false;
313
314 txsch = &nix_hw->txsch[lvl];
315 /* Check out of bounds */
316 if (schq >= txsch->schq.max)
317 return false;
318
319 mutex_lock(&rvu->rsrc_lock);
320 map_func = TXSCH_MAP_FUNC(txsch->pfvf_map[schq]);
321 mutex_unlock(&rvu->rsrc_lock);
322
323 /* TLs aggegating traffic are shared across PF and VFs */
324 if (lvl >= hw->cap.nix_tx_aggr_lvl) {
325 if ((nix_get_tx_link(rvu, map_func) !=
326 nix_get_tx_link(rvu, pcifunc)) &&
327 (rvu_get_pf(rvu->pdev, map_func) !=
328 rvu_get_pf(rvu->pdev, pcifunc)))
329 return false;
330 else
331 return true;
332 }
333
334 if (map_func != pcifunc)
335 return false;
336
337 return true;
338 }
339
nix_interface_init(struct rvu * rvu,u16 pcifunc,int type,int nixlf,struct nix_lf_alloc_rsp * rsp,bool loop)340 static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
341 struct nix_lf_alloc_rsp *rsp, bool loop)
342 {
343 struct rvu_pfvf *parent_pf, *pfvf = rvu_get_pfvf(rvu, pcifunc);
344 u16 req_chan_base, req_chan_end, req_chan_cnt;
345 struct rvu_hwinfo *hw = rvu->hw;
346 struct sdp_node_info *sdp_info;
347 int pkind, pf, vf, lbkid, vfid;
348 u8 cgx_id, lmac_id;
349 bool from_vf;
350 int err;
351
352 pf = rvu_get_pf(rvu->pdev, pcifunc);
353 if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK &&
354 type != NIX_INTF_TYPE_SDP)
355 return 0;
356
357 switch (type) {
358 case NIX_INTF_TYPE_CGX:
359 pfvf->cgx_lmac = rvu->pf2cgxlmac_map[pf];
360 rvu_get_cgx_lmac_id(pfvf->cgx_lmac, &cgx_id, &lmac_id);
361
362 pkind = rvu_npc_get_pkind(rvu, pf);
363 if (pkind < 0) {
364 dev_err(rvu->dev,
365 "PF_Func 0x%x: Invalid pkind\n", pcifunc);
366 return -EINVAL;
367 }
368 pfvf->rx_chan_base = rvu_nix_chan_cgx(rvu, cgx_id, lmac_id, 0);
369 pfvf->tx_chan_base = pfvf->rx_chan_base;
370 pfvf->rx_chan_cnt = 1;
371 pfvf->tx_chan_cnt = 1;
372 rsp->tx_link = cgx_id * hw->lmac_per_cgx + lmac_id;
373
374 if (rvu_cgx_check_permission_and_set_pkind(rvu, pcifunc, pkind))
375 rvu_npc_set_pkind(rvu, pkind, pfvf);
376 break;
377 case NIX_INTF_TYPE_LBK:
378 vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1;
379
380 /* If NIX1 block is present on the silicon then NIXes are
381 * assigned alternatively for lbk interfaces. NIX0 should
382 * send packets on lbk link 1 channels and NIX1 should send
383 * on lbk link 0 channels for the communication between
384 * NIX0 and NIX1.
385 */
386 lbkid = 0;
387 if (rvu->hw->lbk_links > 1)
388 lbkid = vf & 0x1 ? 0 : 1;
389
390 /* By default NIX0 is configured to send packet on lbk link 1
391 * (which corresponds to LBK1), same packet will receive on
392 * NIX1 over lbk link 0. If NIX1 sends packet on lbk link 0
393 * (which corresponds to LBK2) packet will receive on NIX0 lbk
394 * link 1.
395 * But if lbk links for NIX0 and NIX1 are negated, i.e NIX0
396 * transmits and receives on lbk link 0, whick corresponds
397 * to LBK1 block, back to back connectivity between NIX and
398 * LBK can be achieved (which is similar to 96xx)
399 *
400 * RX TX
401 * NIX0 lbk link 1 (LBK2) 1 (LBK1)
402 * NIX0 lbk link 0 (LBK0) 0 (LBK0)
403 * NIX1 lbk link 0 (LBK1) 0 (LBK2)
404 * NIX1 lbk link 1 (LBK3) 1 (LBK3)
405 */
406 if (loop)
407 lbkid = !lbkid;
408
409 /* Note that AF's VFs work in pairs and talk over consecutive
410 * loopback channels.Therefore if odd number of AF VFs are
411 * enabled then the last VF remains with no pair.
412 */
413 pfvf->rx_chan_base = rvu_nix_chan_lbk(rvu, lbkid, vf);
414 pfvf->tx_chan_base = vf & 0x1 ?
415 rvu_nix_chan_lbk(rvu, lbkid, vf - 1) :
416 rvu_nix_chan_lbk(rvu, lbkid, vf + 1);
417 pfvf->rx_chan_cnt = 1;
418 pfvf->tx_chan_cnt = 1;
419 rsp->tx_link = hw->cgx_links + lbkid;
420 pfvf->lbkid = lbkid;
421 rvu_npc_set_pkind(rvu, NPC_RX_LBK_PKIND, pfvf);
422 rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
423 pfvf->rx_chan_base,
424 pfvf->rx_chan_cnt);
425
426 break;
427 case NIX_INTF_TYPE_SDP:
428 from_vf = !!(pcifunc & RVU_PFVF_FUNC_MASK);
429 parent_pf = &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
430 sdp_info = parent_pf->sdp_info;
431 if (!sdp_info) {
432 dev_err(rvu->dev, "Invalid sdp_info pointer\n");
433 return -EINVAL;
434 }
435 if (from_vf) {
436 req_chan_base = rvu_nix_chan_sdp(rvu, 0) + sdp_info->pf_srn +
437 sdp_info->num_pf_rings;
438 vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1;
439 for (vfid = 0; vfid < vf; vfid++)
440 req_chan_base += sdp_info->vf_rings[vfid];
441 req_chan_cnt = sdp_info->vf_rings[vf];
442 req_chan_end = req_chan_base + req_chan_cnt - 1;
443 if (req_chan_base < rvu_nix_chan_sdp(rvu, 0) ||
444 req_chan_end > rvu_nix_chan_sdp(rvu, 255)) {
445 dev_err(rvu->dev,
446 "PF_Func 0x%x: Invalid channel base and count\n",
447 pcifunc);
448 return -EINVAL;
449 }
450 } else {
451 req_chan_base = rvu_nix_chan_sdp(rvu, 0) + sdp_info->pf_srn;
452 req_chan_cnt = sdp_info->num_pf_rings;
453 }
454
455 pfvf->rx_chan_base = req_chan_base;
456 pfvf->rx_chan_cnt = req_chan_cnt;
457 pfvf->tx_chan_base = pfvf->rx_chan_base;
458 pfvf->tx_chan_cnt = pfvf->rx_chan_cnt;
459
460 rsp->tx_link = hw->cgx_links + hw->lbk_links;
461 rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
462 pfvf->rx_chan_base,
463 pfvf->rx_chan_cnt);
464 break;
465 }
466
467 /* Add a UCAST forwarding rule in MCAM with this NIXLF attached
468 * RVU PF/VF's MAC address.
469 */
470 rvu_npc_install_ucast_entry(rvu, pcifunc, nixlf,
471 pfvf->rx_chan_base, pfvf->mac_addr);
472
473 /* Add this PF_FUNC to bcast pkt replication list */
474 err = nix_update_mce_rule(rvu, pcifunc, NIXLF_BCAST_ENTRY, true);
475 if (err) {
476 dev_err(rvu->dev,
477 "Bcast list, failed to enable PF_FUNC 0x%x\n",
478 pcifunc);
479 return err;
480 }
481 /* Install MCAM rule matching Ethernet broadcast mac address */
482 rvu_npc_install_bcast_match_entry(rvu, pcifunc,
483 nixlf, pfvf->rx_chan_base);
484
485 pfvf->maxlen = NIC_HW_MIN_FRS;
486 pfvf->minlen = NIC_HW_MIN_FRS;
487
488 return 0;
489 }
490
nix_interface_deinit(struct rvu * rvu,u16 pcifunc,u8 nixlf)491 static void nix_interface_deinit(struct rvu *rvu, u16 pcifunc, u8 nixlf)
492 {
493 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
494 int err;
495
496 pfvf->maxlen = 0;
497 pfvf->minlen = 0;
498
499 /* Remove this PF_FUNC from bcast pkt replication list */
500 err = nix_update_mce_rule(rvu, pcifunc, NIXLF_BCAST_ENTRY, false);
501 if (err) {
502 dev_err(rvu->dev,
503 "Bcast list, failed to disable PF_FUNC 0x%x\n",
504 pcifunc);
505 }
506
507 /* Free and disable any MCAM entries used by this NIX LF */
508 rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);
509
510 /* Disable DMAC filters used */
511 rvu_cgx_disable_dmac_entries(rvu, pcifunc);
512 }
513
514 #define NIX_BPIDS_PER_LMAC 8
515 #define NIX_BPIDS_PER_CPT 1
nix_setup_bpids(struct rvu * rvu,struct nix_hw * hw,int blkaddr)516 static int nix_setup_bpids(struct rvu *rvu, struct nix_hw *hw, int blkaddr)
517 {
518 struct nix_bp *bp = &hw->bp;
519 int err, max_bpids;
520 u64 cfg;
521
522 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
523 max_bpids = FIELD_GET(NIX_CONST_MAX_BPIDS, cfg);
524
525 /* Reserve the BPIds for CGX and SDP */
526 bp->cgx_bpid_cnt = rvu->hw->cgx_links * NIX_BPIDS_PER_LMAC;
527 bp->sdp_bpid_cnt = rvu->hw->sdp_links * FIELD_GET(NIX_CONST_SDP_CHANS, cfg);
528 bp->free_pool_base = bp->cgx_bpid_cnt + bp->sdp_bpid_cnt +
529 NIX_BPIDS_PER_CPT;
530 bp->bpids.max = max_bpids - bp->free_pool_base;
531
532 err = rvu_alloc_bitmap(&bp->bpids);
533 if (err)
534 return err;
535
536 bp->fn_map = devm_kcalloc(rvu->dev, bp->bpids.max,
537 sizeof(u16), GFP_KERNEL);
538 if (!bp->fn_map)
539 goto free_bpids;
540
541 bp->intf_map = devm_kcalloc(rvu->dev, bp->bpids.max,
542 sizeof(u8), GFP_KERNEL);
543 if (!bp->intf_map)
544 goto free_bpids;
545
546 bp->ref_cnt = devm_kcalloc(rvu->dev, bp->bpids.max,
547 sizeof(u8), GFP_KERNEL);
548 if (!bp->ref_cnt)
549 goto free_bpids;
550
551 return 0;
552
553 free_bpids:
554 rvu_free_bitmap(&bp->bpids);
555 bp->bpids.bmap = NULL;
556 return -ENOMEM;
557 }
558
rvu_nix_flr_free_bpids(struct rvu * rvu,u16 pcifunc)559 void rvu_nix_flr_free_bpids(struct rvu *rvu, u16 pcifunc)
560 {
561 int blkaddr, bpid, err;
562 struct nix_hw *nix_hw;
563 struct nix_bp *bp;
564
565 if (!is_lbk_vf(rvu, pcifunc))
566 return;
567
568 err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
569 if (err)
570 return;
571
572 bp = &nix_hw->bp;
573
574 mutex_lock(&rvu->rsrc_lock);
575 for (bpid = 0; bpid < bp->bpids.max; bpid++) {
576 if (bp->fn_map[bpid] == pcifunc) {
577 bp->ref_cnt[bpid]--;
578 if (bp->ref_cnt[bpid])
579 continue;
580 rvu_free_rsrc(&bp->bpids, bpid);
581 bp->fn_map[bpid] = 0;
582 }
583 }
584 mutex_unlock(&rvu->rsrc_lock);
585 }
586
nix_get_channel(u16 chan,bool cpt_link)587 static u16 nix_get_channel(u16 chan, bool cpt_link)
588 {
589 /* CPT channel for a given link channel is always
590 * assumed to be BIT(11) set in link channel.
591 */
592 return cpt_link ? chan | BIT(11) : chan;
593 }
594
nix_bp_disable(struct rvu * rvu,struct nix_bp_cfg_req * req,struct msg_rsp * rsp,bool cpt_link)595 static int nix_bp_disable(struct rvu *rvu,
596 struct nix_bp_cfg_req *req,
597 struct msg_rsp *rsp, bool cpt_link)
598 {
599 u16 pcifunc = req->hdr.pcifunc;
600 int blkaddr, pf, type, err;
601 u16 chan_base, chan, bpid;
602 struct rvu_pfvf *pfvf;
603 struct nix_hw *nix_hw;
604 struct nix_bp *bp;
605 u16 chan_v;
606 u64 cfg;
607
608 pf = rvu_get_pf(rvu->pdev, pcifunc);
609 type = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
610 if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK)
611 return 0;
612
613 if (is_sdp_pfvf(rvu, pcifunc))
614 type = NIX_INTF_TYPE_SDP;
615
616 if (cpt_link && !rvu->hw->cpt_links)
617 return 0;
618
619 pfvf = rvu_get_pfvf(rvu, pcifunc);
620 err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
621 if (err)
622 return err;
623
624 bp = &nix_hw->bp;
625 chan_base = pfvf->rx_chan_base + req->chan_base;
626 for (chan = chan_base; chan < (chan_base + req->chan_cnt); chan++) {
627 chan_v = nix_get_channel(chan, cpt_link);
628 cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(chan_v));
629 rvu_write64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(chan_v),
630 cfg & ~BIT_ULL(16));
631
632 if (type == NIX_INTF_TYPE_LBK) {
633 bpid = cfg & GENMASK(8, 0);
634 mutex_lock(&rvu->rsrc_lock);
635 rvu_free_rsrc(&bp->bpids, bpid - bp->free_pool_base);
636 for (bpid = 0; bpid < bp->bpids.max; bpid++) {
637 if (bp->fn_map[bpid] == pcifunc) {
638 bp->fn_map[bpid] = 0;
639 bp->ref_cnt[bpid] = 0;
640 }
641 }
642 mutex_unlock(&rvu->rsrc_lock);
643 }
644 }
645 return 0;
646 }
647
rvu_mbox_handler_nix_bp_disable(struct rvu * rvu,struct nix_bp_cfg_req * req,struct msg_rsp * rsp)648 int rvu_mbox_handler_nix_bp_disable(struct rvu *rvu,
649 struct nix_bp_cfg_req *req,
650 struct msg_rsp *rsp)
651 {
652 return nix_bp_disable(rvu, req, rsp, false);
653 }
654
rvu_mbox_handler_nix_cpt_bp_disable(struct rvu * rvu,struct nix_bp_cfg_req * req,struct msg_rsp * rsp)655 int rvu_mbox_handler_nix_cpt_bp_disable(struct rvu *rvu,
656 struct nix_bp_cfg_req *req,
657 struct msg_rsp *rsp)
658 {
659 return nix_bp_disable(rvu, req, rsp, true);
660 }
661
rvu_nix_get_bpid(struct rvu * rvu,struct nix_bp_cfg_req * req,int type,int chan_id)662 static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req,
663 int type, int chan_id)
664 {
665 int bpid, blkaddr, sdp_chan_base, err;
666 struct rvu_hwinfo *hw = rvu->hw;
667 struct rvu_pfvf *pfvf;
668 struct nix_hw *nix_hw;
669 u8 cgx_id, lmac_id;
670 struct nix_bp *bp;
671
672 pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
673
674 err = nix_get_struct_ptrs(rvu, req->hdr.pcifunc, &nix_hw, &blkaddr);
675 if (err)
676 return err;
677
678 bp = &nix_hw->bp;
679
680 /* Backpressure IDs range division
681 * CGX channles are mapped to (0 - 191) BPIDs
682 * LBK channles are mapped to (192 - 255) BPIDs
683 * SDP channles are mapped to (256 - 511) BPIDs
684 *
685 * Lmac channles and bpids mapped as follows
686 * cgx(0)_lmac(0)_chan(0 - 15) = bpid(0 - 15)
687 * cgx(0)_lmac(1)_chan(0 - 15) = bpid(16 - 31) ....
688 * cgx(1)_lmac(0)_chan(0 - 15) = bpid(64 - 79) ....
689 */
690 switch (type) {
691 case NIX_INTF_TYPE_CGX:
692 if ((req->chan_base + req->chan_cnt) > NIX_BPIDS_PER_LMAC)
693 return NIX_AF_ERR_INVALID_BPID_REQ;
694 rvu_get_cgx_lmac_id(pfvf->cgx_lmac, &cgx_id, &lmac_id);
695 /* Assign bpid based on cgx, lmac and chan id */
696 bpid = (cgx_id * hw->lmac_per_cgx * NIX_BPIDS_PER_LMAC) +
697 (lmac_id * NIX_BPIDS_PER_LMAC) + req->chan_base;
698
699 if (req->bpid_per_chan)
700 bpid += chan_id;
701 if (bpid > bp->cgx_bpid_cnt)
702 return NIX_AF_ERR_INVALID_BPID;
703 break;
704
705 case NIX_INTF_TYPE_LBK:
706 /* Alloc bpid from the free pool */
707 mutex_lock(&rvu->rsrc_lock);
708 bpid = rvu_alloc_rsrc(&bp->bpids);
709 if (bpid < 0) {
710 mutex_unlock(&rvu->rsrc_lock);
711 return NIX_AF_ERR_INVALID_BPID;
712 }
713 bp->fn_map[bpid] = req->hdr.pcifunc;
714 bp->ref_cnt[bpid]++;
715 bpid += bp->free_pool_base;
716 mutex_unlock(&rvu->rsrc_lock);
717 break;
718 case NIX_INTF_TYPE_SDP:
719 if ((req->chan_base + req->chan_cnt) > bp->sdp_bpid_cnt)
720 return NIX_AF_ERR_INVALID_BPID_REQ;
721
722 /* Handle usecase of 2 SDP blocks */
723 if (!hw->cap.programmable_chans)
724 sdp_chan_base = pfvf->rx_chan_base - NIX_CHAN_SDP_CH_START;
725 else
726 sdp_chan_base = pfvf->rx_chan_base - hw->sdp_chan_base;
727
728 bpid = bp->cgx_bpid_cnt + req->chan_base + sdp_chan_base;
729 if (req->bpid_per_chan)
730 bpid += chan_id;
731
732 if (bpid > (bp->cgx_bpid_cnt + bp->sdp_bpid_cnt))
733 return NIX_AF_ERR_INVALID_BPID;
734 break;
735 default:
736 return -EINVAL;
737 }
738 return bpid;
739 }
740
nix_bp_enable(struct rvu * rvu,struct nix_bp_cfg_req * req,struct nix_bp_cfg_rsp * rsp,bool cpt_link)741 static int nix_bp_enable(struct rvu *rvu,
742 struct nix_bp_cfg_req *req,
743 struct nix_bp_cfg_rsp *rsp,
744 bool cpt_link)
745 {
746 int blkaddr, pf, type, chan_id = 0;
747 u16 pcifunc = req->hdr.pcifunc;
748 struct rvu_pfvf *pfvf;
749 u16 chan_base, chan;
750 s16 bpid, bpid_base;
751 u16 chan_v;
752 u64 cfg;
753
754 pf = rvu_get_pf(rvu->pdev, pcifunc);
755 type = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
756 if (is_sdp_pfvf(rvu, pcifunc))
757 type = NIX_INTF_TYPE_SDP;
758
759 /* Enable backpressure only for CGX mapped PFs and LBK/SDP interface */
760 if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK &&
761 type != NIX_INTF_TYPE_SDP)
762 return 0;
763
764 if (cpt_link && !rvu->hw->cpt_links)
765 return 0;
766
767 pfvf = rvu_get_pfvf(rvu, pcifunc);
768 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
769
770 bpid_base = rvu_nix_get_bpid(rvu, req, type, chan_id);
771 chan_base = pfvf->rx_chan_base + req->chan_base;
772 bpid = bpid_base;
773
774 for (chan = chan_base; chan < (chan_base + req->chan_cnt); chan++) {
775 if (bpid < 0) {
776 dev_warn(rvu->dev, "Fail to enable backpressure\n");
777 return -EINVAL;
778 }
779
780 chan_v = nix_get_channel(chan, cpt_link);
781
782 cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(chan_v));
783 cfg &= ~GENMASK_ULL(8, 0);
784 rvu_write64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(chan_v),
785 cfg | (bpid & GENMASK_ULL(8, 0)) | BIT_ULL(16));
786 chan_id++;
787 bpid = rvu_nix_get_bpid(rvu, req, type, chan_id);
788 }
789
790 for (chan = 0; chan < req->chan_cnt; chan++) {
791 /* Map channel and bpid assign to it */
792 rsp->chan_bpid[chan] = ((req->chan_base + chan) & 0x7F) << 10 |
793 (bpid_base & 0x3FF);
794 if (req->bpid_per_chan)
795 bpid_base++;
796 }
797 rsp->chan_cnt = req->chan_cnt;
798
799 return 0;
800 }
801
rvu_mbox_handler_nix_bp_enable(struct rvu * rvu,struct nix_bp_cfg_req * req,struct nix_bp_cfg_rsp * rsp)802 int rvu_mbox_handler_nix_bp_enable(struct rvu *rvu,
803 struct nix_bp_cfg_req *req,
804 struct nix_bp_cfg_rsp *rsp)
805 {
806 return nix_bp_enable(rvu, req, rsp, false);
807 }
808
rvu_mbox_handler_nix_cpt_bp_enable(struct rvu * rvu,struct nix_bp_cfg_req * req,struct nix_bp_cfg_rsp * rsp)809 int rvu_mbox_handler_nix_cpt_bp_enable(struct rvu *rvu,
810 struct nix_bp_cfg_req *req,
811 struct nix_bp_cfg_rsp *rsp)
812 {
813 return nix_bp_enable(rvu, req, rsp, true);
814 }
815
nix_setup_lso_tso_l3(struct rvu * rvu,int blkaddr,u64 format,bool v4,u64 * fidx)816 static void nix_setup_lso_tso_l3(struct rvu *rvu, int blkaddr,
817 u64 format, bool v4, u64 *fidx)
818 {
819 struct nix_lso_format field = {0};
820
821 /* IP's Length field */
822 field.layer = NIX_TXLAYER_OL3;
823 /* In ipv4, length field is at offset 2 bytes, for ipv6 it's 4 */
824 field.offset = v4 ? 2 : 4;
825 field.sizem1 = 1; /* i.e 2 bytes */
826 field.alg = NIX_LSOALG_ADD_PAYLEN;
827 rvu_write64(rvu, blkaddr,
828 NIX_AF_LSO_FORMATX_FIELDX(format, (*fidx)++),
829 *(u64 *)&field);
830
831 /* No ID field in IPv6 header */
832 if (!v4)
833 return;
834
835 /* IP's ID field */
836 field.layer = NIX_TXLAYER_OL3;
837 field.offset = 4;
838 field.sizem1 = 1; /* i.e 2 bytes */
839 field.alg = NIX_LSOALG_ADD_SEGNUM;
840 rvu_write64(rvu, blkaddr,
841 NIX_AF_LSO_FORMATX_FIELDX(format, (*fidx)++),
842 *(u64 *)&field);
843 }
844
nix_setup_lso_tso_l4(struct rvu * rvu,int blkaddr,u64 format,u64 * fidx)845 static void nix_setup_lso_tso_l4(struct rvu *rvu, int blkaddr,
846 u64 format, u64 *fidx)
847 {
848 struct nix_lso_format field = {0};
849
850 /* TCP's sequence number field */
851 field.layer = NIX_TXLAYER_OL4;
852 field.offset = 4;
853 field.sizem1 = 3; /* i.e 4 bytes */
854 field.alg = NIX_LSOALG_ADD_OFFSET;
855 rvu_write64(rvu, blkaddr,
856 NIX_AF_LSO_FORMATX_FIELDX(format, (*fidx)++),
857 *(u64 *)&field);
858
859 /* TCP's flags field */
860 field.layer = NIX_TXLAYER_OL4;
861 field.offset = 12;
862 field.sizem1 = 1; /* 2 bytes */
863 field.alg = NIX_LSOALG_TCP_FLAGS;
864 rvu_write64(rvu, blkaddr,
865 NIX_AF_LSO_FORMATX_FIELDX(format, (*fidx)++),
866 *(u64 *)&field);
867 }
868
nix_setup_lso(struct rvu * rvu,struct nix_hw * nix_hw,int blkaddr)869 static void nix_setup_lso(struct rvu *rvu, struct nix_hw *nix_hw, int blkaddr)
870 {
871 u64 cfg, idx, fidx = 0;
872
873 /* Get max HW supported format indices */
874 cfg = (rvu_read64(rvu, blkaddr, NIX_AF_CONST1) >> 48) & 0xFF;
875 nix_hw->lso.total = cfg;
876
877 /* Enable LSO */
878 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LSO_CFG);
879 /* For TSO, set first and middle segment flags to
880 * mask out PSH, RST & FIN flags in TCP packet
881 */
882 cfg &= ~((0xFFFFULL << 32) | (0xFFFFULL << 16));
883 cfg |= (0xFFF2ULL << 32) | (0xFFF2ULL << 16);
884 rvu_write64(rvu, blkaddr, NIX_AF_LSO_CFG, cfg | BIT_ULL(63));
885
886 /* Setup default static LSO formats
887 *
888 * Configure format fields for TCPv4 segmentation offload
889 */
890 idx = NIX_LSO_FORMAT_IDX_TSOV4;
891 nix_setup_lso_tso_l3(rvu, blkaddr, idx, true, &fidx);
892 nix_setup_lso_tso_l4(rvu, blkaddr, idx, &fidx);
893
894 /* Set rest of the fields to NOP */
895 for (; fidx < 8; fidx++) {
896 rvu_write64(rvu, blkaddr,
897 NIX_AF_LSO_FORMATX_FIELDX(idx, fidx), 0x0ULL);
898 }
899 nix_hw->lso.in_use++;
900
901 /* Configure format fields for TCPv6 segmentation offload */
902 idx = NIX_LSO_FORMAT_IDX_TSOV6;
903 fidx = 0;
904 nix_setup_lso_tso_l3(rvu, blkaddr, idx, false, &fidx);
905 nix_setup_lso_tso_l4(rvu, blkaddr, idx, &fidx);
906
907 /* Set rest of the fields to NOP */
908 for (; fidx < 8; fidx++) {
909 rvu_write64(rvu, blkaddr,
910 NIX_AF_LSO_FORMATX_FIELDX(idx, fidx), 0x0ULL);
911 }
912 nix_hw->lso.in_use++;
913 }
914
nix_ctx_free(struct rvu * rvu,struct rvu_pfvf * pfvf)915 static void nix_ctx_free(struct rvu *rvu, struct rvu_pfvf *pfvf)
916 {
917 kfree(pfvf->rq_bmap);
918 kfree(pfvf->sq_bmap);
919 kfree(pfvf->cq_bmap);
920 if (pfvf->rq_ctx)
921 qmem_free(rvu->dev, pfvf->rq_ctx);
922 if (pfvf->sq_ctx)
923 qmem_free(rvu->dev, pfvf->sq_ctx);
924 if (pfvf->cq_ctx)
925 qmem_free(rvu->dev, pfvf->cq_ctx);
926 if (pfvf->rss_ctx)
927 qmem_free(rvu->dev, pfvf->rss_ctx);
928 if (pfvf->nix_qints_ctx)
929 qmem_free(rvu->dev, pfvf->nix_qints_ctx);
930 if (pfvf->cq_ints_ctx)
931 qmem_free(rvu->dev, pfvf->cq_ints_ctx);
932
933 pfvf->rq_bmap = NULL;
934 pfvf->cq_bmap = NULL;
935 pfvf->sq_bmap = NULL;
936 pfvf->rq_ctx = NULL;
937 pfvf->sq_ctx = NULL;
938 pfvf->cq_ctx = NULL;
939 pfvf->rss_ctx = NULL;
940 pfvf->nix_qints_ctx = NULL;
941 pfvf->cq_ints_ctx = NULL;
942 }
943
nixlf_rss_ctx_init(struct rvu * rvu,int blkaddr,struct rvu_pfvf * pfvf,int nixlf,int rss_sz,int rss_grps,int hwctx_size,u64 way_mask,bool tag_lsb_as_adder)944 static int nixlf_rss_ctx_init(struct rvu *rvu, int blkaddr,
945 struct rvu_pfvf *pfvf, int nixlf,
946 int rss_sz, int rss_grps, int hwctx_size,
947 u64 way_mask, bool tag_lsb_as_adder)
948 {
949 int err, grp, num_indices;
950 u64 val;
951
952 /* RSS is not requested for this NIXLF */
953 if (!rss_sz)
954 return 0;
955 num_indices = rss_sz * rss_grps;
956
957 /* Alloc NIX RSS HW context memory and config the base */
958 err = qmem_alloc(rvu->dev, &pfvf->rss_ctx, num_indices, hwctx_size);
959 if (err)
960 return err;
961
962 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RSS_BASE(nixlf),
963 (u64)pfvf->rss_ctx->iova);
964
965 /* Config full RSS table size, enable RSS and caching */
966 val = BIT_ULL(36) | BIT_ULL(4) | way_mask << 20 |
967 ilog2(num_indices / MAX_RSS_INDIR_TBL_SIZE);
968
969 if (tag_lsb_as_adder)
970 val |= BIT_ULL(5);
971
972 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RSS_CFG(nixlf), val);
973 /* Config RSS group offset and sizes */
974 for (grp = 0; grp < rss_grps; grp++)
975 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RSS_GRPX(nixlf, grp),
976 ((ilog2(rss_sz) - 1) << 16) | (rss_sz * grp));
977 return 0;
978 }
979
nix_aq_enqueue_wait(struct rvu * rvu,struct rvu_block * block,struct nix_aq_inst_s * inst)980 static int nix_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
981 struct nix_aq_inst_s *inst)
982 {
983 struct admin_queue *aq = block->aq;
984 struct nix_aq_res_s *result;
985 int timeout = 1000;
986 u64 reg, head;
987 int ret;
988
989 result = (struct nix_aq_res_s *)aq->res->base;
990
991 /* Get current head pointer where to append this instruction */
992 reg = rvu_read64(rvu, block->addr, NIX_AF_AQ_STATUS);
993 head = (reg >> 4) & AQ_PTR_MASK;
994
995 memcpy((void *)(aq->inst->base + (head * aq->inst->entry_sz)),
996 (void *)inst, aq->inst->entry_sz);
997 memset(result, 0, sizeof(*result));
998 /* sync into memory */
999 wmb();
1000
1001 /* Ring the doorbell and wait for result */
1002 rvu_write64(rvu, block->addr, NIX_AF_AQ_DOOR, 1);
1003 while (result->compcode == NIX_AQ_COMP_NOTDONE) {
1004 cpu_relax();
1005 udelay(1);
1006 timeout--;
1007 if (!timeout)
1008 return -EBUSY;
1009 }
1010
1011 if (result->compcode != NIX_AQ_COMP_GOOD) {
1012 /* TODO: Replace this with some error code */
1013 if (result->compcode == NIX_AQ_COMP_CTX_FAULT ||
1014 result->compcode == NIX_AQ_COMP_LOCKERR ||
1015 result->compcode == NIX_AQ_COMP_CTX_POISON) {
1016 ret = rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX0_RX);
1017 ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX0_TX);
1018 ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX1_RX);
1019 ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX1_TX);
1020 if (ret)
1021 dev_err(rvu->dev,
1022 "%s: Not able to unlock cachelines\n", __func__);
1023 }
1024
1025 return -EBUSY;
1026 }
1027
1028 return 0;
1029 }
1030
nix_get_aq_req_smq(struct rvu * rvu,struct nix_aq_enq_req * req,u16 * smq,u16 * smq_mask)1031 static void nix_get_aq_req_smq(struct rvu *rvu, struct nix_aq_enq_req *req,
1032 u16 *smq, u16 *smq_mask)
1033 {
1034 struct nix_cn10k_aq_enq_req *aq_req;
1035
1036 if (is_cn20k(rvu->pdev)) {
1037 *smq = ((struct nix_cn20k_aq_enq_req *)req)->sq.smq;
1038 *smq_mask = ((struct nix_cn20k_aq_enq_req *)req)->sq_mask.smq;
1039 return;
1040 }
1041
1042 if (!is_rvu_otx2(rvu)) {
1043 aq_req = (struct nix_cn10k_aq_enq_req *)req;
1044 *smq = aq_req->sq.smq;
1045 *smq_mask = aq_req->sq_mask.smq;
1046 } else {
1047 *smq = req->sq.smq;
1048 *smq_mask = req->sq_mask.smq;
1049 }
1050 }
1051
rvu_nix_blk_aq_enq_inst(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_aq_enq_req * req,struct nix_aq_enq_rsp * rsp)1052 static int rvu_nix_blk_aq_enq_inst(struct rvu *rvu, struct nix_hw *nix_hw,
1053 struct nix_aq_enq_req *req,
1054 struct nix_aq_enq_rsp *rsp)
1055 {
1056 struct rvu_hwinfo *hw = rvu->hw;
1057 u16 pcifunc = req->hdr.pcifunc;
1058 int nixlf, blkaddr, rc = 0;
1059 struct nix_aq_inst_s inst;
1060 struct rvu_block *block;
1061 struct admin_queue *aq;
1062 struct rvu_pfvf *pfvf;
1063 u16 smq, smq_mask;
1064 void *ctx, *mask;
1065 bool ena;
1066 u64 cfg;
1067
1068 blkaddr = nix_hw->blkaddr;
1069 block = &hw->block[blkaddr];
1070 aq = block->aq;
1071 if (!aq) {
1072 dev_warn(rvu->dev, "%s: NIX AQ not initialized\n", __func__);
1073 return NIX_AF_ERR_AQ_ENQUEUE;
1074 }
1075
1076 pfvf = rvu_get_pfvf(rvu, pcifunc);
1077 nixlf = rvu_get_lf(rvu, block, pcifunc, 0);
1078
1079 /* Skip NIXLF check for broadcast MCE entry and bandwidth profile
1080 * operations done by AF itself.
1081 */
1082 if (!((!rsp && req->ctype == NIX_AQ_CTYPE_MCE) ||
1083 (req->ctype == NIX_AQ_CTYPE_BANDPROF && !pcifunc))) {
1084 if (!pfvf->nixlf || nixlf < 0)
1085 return NIX_AF_ERR_AF_LF_INVALID;
1086 }
1087
1088 switch (req->ctype) {
1089 case NIX_AQ_CTYPE_RQ:
1090 /* Check if index exceeds max no of queues */
1091 if (!pfvf->rq_ctx || req->qidx >= pfvf->rq_ctx->qsize)
1092 rc = NIX_AF_ERR_AQ_ENQUEUE;
1093 break;
1094 case NIX_AQ_CTYPE_SQ:
1095 if (!pfvf->sq_ctx || req->qidx >= pfvf->sq_ctx->qsize)
1096 rc = NIX_AF_ERR_AQ_ENQUEUE;
1097 break;
1098 case NIX_AQ_CTYPE_CQ:
1099 if (!pfvf->cq_ctx || req->qidx >= pfvf->cq_ctx->qsize)
1100 rc = NIX_AF_ERR_AQ_ENQUEUE;
1101 break;
1102 case NIX_AQ_CTYPE_RSS:
1103 /* Check if RSS is enabled and qidx is within range */
1104 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LFX_RSS_CFG(nixlf));
1105 if (!(cfg & BIT_ULL(4)) || !pfvf->rss_ctx ||
1106 (req->qidx >= (256UL << (cfg & 0xF))))
1107 rc = NIX_AF_ERR_AQ_ENQUEUE;
1108 break;
1109 case NIX_AQ_CTYPE_MCE:
1110 cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_MCAST_CFG);
1111
1112 /* Check if index exceeds MCE list length */
1113 if (!nix_hw->mcast.mce_ctx ||
1114 (req->qidx >= (256UL << (cfg & 0xF))))
1115 rc = NIX_AF_ERR_AQ_ENQUEUE;
1116
1117 /* Adding multicast lists for requests from PF/VFs is not
1118 * yet supported, so ignore this.
1119 */
1120 if (rsp)
1121 rc = NIX_AF_ERR_AQ_ENQUEUE;
1122 break;
1123 case NIX_AQ_CTYPE_BANDPROF:
1124 if (nix_verify_bandprof((struct nix_cn10k_aq_enq_req *)req,
1125 nix_hw, pcifunc))
1126 rc = NIX_AF_ERR_INVALID_BANDPROF;
1127 break;
1128 default:
1129 rc = NIX_AF_ERR_AQ_ENQUEUE;
1130 }
1131
1132 if (rc)
1133 return rc;
1134
1135 nix_get_aq_req_smq(rvu, req, &smq, &smq_mask);
1136 /* Check if SQ pointed SMQ belongs to this PF/VF or not */
1137 if (req->ctype == NIX_AQ_CTYPE_SQ &&
1138 ((req->op == NIX_AQ_INSTOP_INIT && req->sq.ena) ||
1139 (req->op == NIX_AQ_INSTOP_WRITE &&
1140 req->sq_mask.ena && req->sq.ena && smq_mask))) {
1141 if (!is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_SMQ,
1142 pcifunc, smq))
1143 return NIX_AF_ERR_AQ_ENQUEUE;
1144 }
1145
1146 memset(&inst, 0, sizeof(struct nix_aq_inst_s));
1147 inst.lf = nixlf;
1148 inst.cindex = req->qidx;
1149 inst.ctype = req->ctype;
1150 inst.op = req->op;
1151 /* Currently we are not supporting enqueuing multiple instructions,
1152 * so always choose first entry in result memory.
1153 */
1154 inst.res_addr = (u64)aq->res->iova;
1155
1156 /* Hardware uses same aq->res->base for updating result of
1157 * previous instruction hence wait here till it is done.
1158 */
1159 spin_lock(&aq->lock);
1160
1161 /* Clean result + context memory */
1162 memset(aq->res->base, 0, aq->res->entry_sz);
1163 /* Context needs to be written at RES_ADDR + 128 */
1164 ctx = aq->res->base + 128;
1165 /* Mask needs to be written at RES_ADDR + 256 */
1166 mask = aq->res->base + 256;
1167
1168 switch (req->op) {
1169 case NIX_AQ_INSTOP_WRITE:
1170 if (req->ctype == NIX_AQ_CTYPE_RQ)
1171 memcpy(mask, &req->rq_mask,
1172 NIX_MAX_CTX_SIZE);
1173 else if (req->ctype == NIX_AQ_CTYPE_SQ)
1174 memcpy(mask, &req->sq_mask,
1175 NIX_MAX_CTX_SIZE);
1176 else if (req->ctype == NIX_AQ_CTYPE_CQ)
1177 memcpy(mask, &req->cq_mask,
1178 NIX_MAX_CTX_SIZE);
1179 else if (req->ctype == NIX_AQ_CTYPE_RSS)
1180 memcpy(mask, &req->rss_mask,
1181 NIX_MAX_CTX_SIZE);
1182 else if (req->ctype == NIX_AQ_CTYPE_MCE)
1183 memcpy(mask, &req->mce_mask,
1184 NIX_MAX_CTX_SIZE);
1185 else if (req->ctype == NIX_AQ_CTYPE_BANDPROF)
1186 memcpy(mask, &req->prof_mask,
1187 NIX_MAX_CTX_SIZE);
1188 fallthrough;
1189 case NIX_AQ_INSTOP_INIT:
1190 if (req->ctype == NIX_AQ_CTYPE_RQ)
1191 memcpy(ctx, &req->rq, NIX_MAX_CTX_SIZE);
1192 else if (req->ctype == NIX_AQ_CTYPE_SQ)
1193 memcpy(ctx, &req->sq, NIX_MAX_CTX_SIZE);
1194 else if (req->ctype == NIX_AQ_CTYPE_CQ)
1195 memcpy(ctx, &req->cq, NIX_MAX_CTX_SIZE);
1196 else if (req->ctype == NIX_AQ_CTYPE_RSS)
1197 memcpy(ctx, &req->rss, NIX_MAX_CTX_SIZE);
1198 else if (req->ctype == NIX_AQ_CTYPE_MCE)
1199 memcpy(ctx, &req->mce, NIX_MAX_CTX_SIZE);
1200 else if (req->ctype == NIX_AQ_CTYPE_BANDPROF)
1201 memcpy(ctx, &req->prof, NIX_MAX_CTX_SIZE);
1202 break;
1203 case NIX_AQ_INSTOP_NOP:
1204 case NIX_AQ_INSTOP_READ:
1205 case NIX_AQ_INSTOP_LOCK:
1206 case NIX_AQ_INSTOP_UNLOCK:
1207 break;
1208 default:
1209 rc = NIX_AF_ERR_AQ_ENQUEUE;
1210 spin_unlock(&aq->lock);
1211 return rc;
1212 }
1213
1214 /* Submit the instruction to AQ */
1215 rc = nix_aq_enqueue_wait(rvu, block, &inst);
1216 if (rc) {
1217 spin_unlock(&aq->lock);
1218 return rc;
1219 }
1220
1221 /* Set RQ/SQ/CQ bitmap if respective queue hw context is enabled */
1222 if (req->op == NIX_AQ_INSTOP_INIT) {
1223 if (req->ctype == NIX_AQ_CTYPE_RQ && req->rq.ena)
1224 __set_bit(req->qidx, pfvf->rq_bmap);
1225 if (req->ctype == NIX_AQ_CTYPE_SQ && req->sq.ena)
1226 __set_bit(req->qidx, pfvf->sq_bmap);
1227 if (req->ctype == NIX_AQ_CTYPE_CQ && req->cq.ena)
1228 __set_bit(req->qidx, pfvf->cq_bmap);
1229 }
1230
1231 if (req->op == NIX_AQ_INSTOP_WRITE) {
1232 if (req->ctype == NIX_AQ_CTYPE_RQ) {
1233 ena = (req->rq.ena & req->rq_mask.ena) |
1234 (test_bit(req->qidx, pfvf->rq_bmap) &
1235 ~req->rq_mask.ena);
1236 if (ena)
1237 __set_bit(req->qidx, pfvf->rq_bmap);
1238 else
1239 __clear_bit(req->qidx, pfvf->rq_bmap);
1240 }
1241 if (req->ctype == NIX_AQ_CTYPE_SQ) {
1242 ena = (req->rq.ena & req->sq_mask.ena) |
1243 (test_bit(req->qidx, pfvf->sq_bmap) &
1244 ~req->sq_mask.ena);
1245 if (ena)
1246 __set_bit(req->qidx, pfvf->sq_bmap);
1247 else
1248 __clear_bit(req->qidx, pfvf->sq_bmap);
1249 }
1250 if (req->ctype == NIX_AQ_CTYPE_CQ) {
1251 ena = (req->rq.ena & req->cq_mask.ena) |
1252 (test_bit(req->qidx, pfvf->cq_bmap) &
1253 ~req->cq_mask.ena);
1254 if (ena)
1255 __set_bit(req->qidx, pfvf->cq_bmap);
1256 else
1257 __clear_bit(req->qidx, pfvf->cq_bmap);
1258 }
1259 }
1260
1261 if (rsp) {
1262 /* Copy read context into mailbox */
1263 if (req->op == NIX_AQ_INSTOP_READ) {
1264 if (req->ctype == NIX_AQ_CTYPE_RQ)
1265 memcpy(&rsp->rq, ctx,
1266 NIX_MAX_CTX_SIZE);
1267 else if (req->ctype == NIX_AQ_CTYPE_SQ)
1268 memcpy(&rsp->sq, ctx,
1269 NIX_MAX_CTX_SIZE);
1270 else if (req->ctype == NIX_AQ_CTYPE_CQ)
1271 memcpy(&rsp->cq, ctx,
1272 NIX_MAX_CTX_SIZE);
1273 else if (req->ctype == NIX_AQ_CTYPE_RSS)
1274 memcpy(&rsp->rss, ctx,
1275 NIX_MAX_CTX_SIZE);
1276 else if (req->ctype == NIX_AQ_CTYPE_MCE)
1277 memcpy(&rsp->mce, ctx,
1278 NIX_MAX_CTX_SIZE);
1279 else if (req->ctype == NIX_AQ_CTYPE_BANDPROF)
1280 memcpy(&rsp->prof, ctx,
1281 NIX_MAX_CTX_SIZE);
1282 }
1283 }
1284
1285 spin_unlock(&aq->lock);
1286 return 0;
1287 }
1288
rvu_nix_verify_aq_ctx(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_aq_enq_req * req,u8 ctype)1289 static int rvu_nix_verify_aq_ctx(struct rvu *rvu, struct nix_hw *nix_hw,
1290 struct nix_aq_enq_req *req, u8 ctype)
1291 {
1292 struct nix_cn10k_aq_enq_req aq_req;
1293 struct nix_cn10k_aq_enq_rsp aq_rsp;
1294 int rc, word;
1295
1296 if (req->ctype != NIX_AQ_CTYPE_CQ)
1297 return 0;
1298
1299 rc = nix_aq_context_read(rvu, nix_hw, &aq_req, &aq_rsp,
1300 req->hdr.pcifunc, ctype, req->qidx);
1301 if (rc) {
1302 dev_err(rvu->dev,
1303 "%s: Failed to fetch %s%d context of PFFUNC 0x%x\n",
1304 __func__, nix_get_ctx_name(ctype), req->qidx,
1305 req->hdr.pcifunc);
1306 return rc;
1307 }
1308
1309 /* Make copy of original context & mask which are required
1310 * for resubmission
1311 */
1312 memcpy(&aq_req.cq_mask, &req->cq_mask, NIX_MAX_CTX_SIZE);
1313 memcpy(&aq_req.cq, &req->cq, NIX_MAX_CTX_SIZE);
1314
1315 /* exclude fields which HW can update */
1316 aq_req.cq_mask.cq_err = 0;
1317 aq_req.cq_mask.wrptr = 0;
1318 aq_req.cq_mask.tail = 0;
1319 aq_req.cq_mask.head = 0;
1320 aq_req.cq_mask.avg_level = 0;
1321 aq_req.cq_mask.update_time = 0;
1322 aq_req.cq_mask.substream = 0;
1323
1324 /* Context mask (cq_mask) holds mask value of fields which
1325 * are changed in AQ WRITE operation.
1326 * for example cq.drop = 0xa;
1327 * cq_mask.drop = 0xff;
1328 * Below logic performs '&' between cq and cq_mask so that non
1329 * updated fields are masked out for request and response
1330 * comparison
1331 */
1332 for (word = 0; word < NIX_MAX_CTX_SIZE / sizeof(u64);
1333 word++) {
1334 *(u64 *)((u8 *)&aq_rsp.cq + word * 8) &=
1335 (*(u64 *)((u8 *)&aq_req.cq_mask + word * 8));
1336 *(u64 *)((u8 *)&aq_req.cq + word * 8) &=
1337 (*(u64 *)((u8 *)&aq_req.cq_mask + word * 8));
1338 }
1339
1340 if (memcmp(&aq_req.cq, &aq_rsp.cq, NIX_MAX_CTX_SIZE))
1341 return NIX_AF_ERR_AQ_CTX_RETRY_WRITE;
1342
1343 return 0;
1344 }
1345
rvu_nix_aq_enq_inst(struct rvu * rvu,struct nix_aq_enq_req * req,struct nix_aq_enq_rsp * rsp)1346 int rvu_nix_aq_enq_inst(struct rvu *rvu, struct nix_aq_enq_req *req,
1347 struct nix_aq_enq_rsp *rsp)
1348 {
1349 struct nix_hw *nix_hw;
1350 int err, retries = 5;
1351 int blkaddr;
1352
1353 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, req->hdr.pcifunc);
1354 if (blkaddr < 0)
1355 return NIX_AF_ERR_AF_LF_INVALID;
1356
1357 nix_hw = get_nix_hw(rvu->hw, blkaddr);
1358 if (!nix_hw)
1359 return NIX_AF_ERR_INVALID_NIXBLK;
1360
1361 retry:
1362 err = rvu_nix_blk_aq_enq_inst(rvu, nix_hw, req, rsp);
1363
1364 /* HW errata 'AQ Modification to CQ could be discarded on heavy traffic'
1365 * As a work around perfrom CQ context read after each AQ write. If AQ
1366 * read shows AQ write is not updated perform AQ write again.
1367 */
1368 if (!err && req->op == NIX_AQ_INSTOP_WRITE) {
1369 err = rvu_nix_verify_aq_ctx(rvu, nix_hw, req, NIX_AQ_CTYPE_CQ);
1370 if (err == NIX_AF_ERR_AQ_CTX_RETRY_WRITE) {
1371 if (retries--)
1372 goto retry;
1373 else
1374 return NIX_AF_ERR_CQ_CTX_WRITE_ERR;
1375 }
1376 }
1377
1378 return err;
1379 }
1380
nix_get_ctx_name(int ctype)1381 static const char *nix_get_ctx_name(int ctype)
1382 {
1383 switch (ctype) {
1384 case NIX_AQ_CTYPE_CQ:
1385 return "CQ";
1386 case NIX_AQ_CTYPE_SQ:
1387 return "SQ";
1388 case NIX_AQ_CTYPE_RQ:
1389 return "RQ";
1390 case NIX_AQ_CTYPE_RSS:
1391 return "RSS";
1392 }
1393 return "";
1394 }
1395
nix_lf_hwctx_disable(struct rvu * rvu,struct hwctx_disable_req * req)1396 static int nix_lf_hwctx_disable(struct rvu *rvu, struct hwctx_disable_req *req)
1397 {
1398 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
1399 struct nix_aq_enq_req aq_req;
1400 unsigned long *bmap;
1401 int qidx, q_cnt = 0;
1402 int err = 0, rc;
1403
1404 if (!pfvf->cq_ctx || !pfvf->sq_ctx || !pfvf->rq_ctx)
1405 return NIX_AF_ERR_AQ_ENQUEUE;
1406
1407 memset(&aq_req, 0, sizeof(struct nix_aq_enq_req));
1408 aq_req.hdr.pcifunc = req->hdr.pcifunc;
1409
1410 if (req->ctype == NIX_AQ_CTYPE_CQ) {
1411 aq_req.cq.ena = 0;
1412 aq_req.cq_mask.ena = 1;
1413 aq_req.cq.bp_ena = 0;
1414 aq_req.cq_mask.bp_ena = 1;
1415 q_cnt = pfvf->cq_ctx->qsize;
1416 bmap = pfvf->cq_bmap;
1417 }
1418 if (req->ctype == NIX_AQ_CTYPE_SQ) {
1419 aq_req.sq.ena = 0;
1420 aq_req.sq_mask.ena = 1;
1421 q_cnt = pfvf->sq_ctx->qsize;
1422 bmap = pfvf->sq_bmap;
1423 }
1424 if (req->ctype == NIX_AQ_CTYPE_RQ) {
1425 aq_req.rq.ena = 0;
1426 aq_req.rq_mask.ena = 1;
1427 q_cnt = pfvf->rq_ctx->qsize;
1428 bmap = pfvf->rq_bmap;
1429 }
1430
1431 aq_req.ctype = req->ctype;
1432 aq_req.op = NIX_AQ_INSTOP_WRITE;
1433
1434 for (qidx = 0; qidx < q_cnt; qidx++) {
1435 if (!test_bit(qidx, bmap))
1436 continue;
1437 aq_req.qidx = qidx;
1438 rc = rvu_nix_aq_enq_inst(rvu, &aq_req, NULL);
1439 if (rc) {
1440 err = rc;
1441 dev_err(rvu->dev, "Failed to disable %s:%d context\n",
1442 nix_get_ctx_name(req->ctype), qidx);
1443 }
1444 }
1445
1446 return err;
1447 }
1448
1449 #ifdef CONFIG_NDC_DIS_DYNAMIC_CACHING
nix_lf_hwctx_lockdown(struct rvu * rvu,struct nix_aq_enq_req * req)1450 static int nix_lf_hwctx_lockdown(struct rvu *rvu, struct nix_aq_enq_req *req)
1451 {
1452 struct nix_aq_enq_req lock_ctx_req;
1453 int err;
1454
1455 if (req->op != NIX_AQ_INSTOP_INIT)
1456 return 0;
1457
1458 if (req->ctype == NIX_AQ_CTYPE_MCE ||
1459 req->ctype == NIX_AQ_CTYPE_DYNO)
1460 return 0;
1461
1462 memset(&lock_ctx_req, 0, sizeof(struct nix_aq_enq_req));
1463 lock_ctx_req.hdr.pcifunc = req->hdr.pcifunc;
1464 lock_ctx_req.ctype = req->ctype;
1465 lock_ctx_req.op = NIX_AQ_INSTOP_LOCK;
1466 lock_ctx_req.qidx = req->qidx;
1467 err = rvu_nix_aq_enq_inst(rvu, &lock_ctx_req, NULL);
1468 if (err)
1469 dev_err(rvu->dev,
1470 "PFUNC 0x%x: Failed to lock NIX %s:%d context\n",
1471 req->hdr.pcifunc,
1472 nix_get_ctx_name(req->ctype), req->qidx);
1473 return err;
1474 }
1475
rvu_mbox_handler_nix_aq_enq(struct rvu * rvu,struct nix_aq_enq_req * req,struct nix_aq_enq_rsp * rsp)1476 int rvu_mbox_handler_nix_aq_enq(struct rvu *rvu,
1477 struct nix_aq_enq_req *req,
1478 struct nix_aq_enq_rsp *rsp)
1479 {
1480 int err;
1481
1482 err = rvu_nix_aq_enq_inst(rvu, req, rsp);
1483 if (!err)
1484 err = nix_lf_hwctx_lockdown(rvu, req);
1485 return err;
1486 }
1487 #else
1488
rvu_mbox_handler_nix_aq_enq(struct rvu * rvu,struct nix_aq_enq_req * req,struct nix_aq_enq_rsp * rsp)1489 int rvu_mbox_handler_nix_aq_enq(struct rvu *rvu,
1490 struct nix_aq_enq_req *req,
1491 struct nix_aq_enq_rsp *rsp)
1492 {
1493 return rvu_nix_aq_enq_inst(rvu, req, rsp);
1494 }
1495 #endif
1496 /* CN10K mbox handler */
rvu_mbox_handler_nix_cn10k_aq_enq(struct rvu * rvu,struct nix_cn10k_aq_enq_req * req,struct nix_cn10k_aq_enq_rsp * rsp)1497 int rvu_mbox_handler_nix_cn10k_aq_enq(struct rvu *rvu,
1498 struct nix_cn10k_aq_enq_req *req,
1499 struct nix_cn10k_aq_enq_rsp *rsp)
1500 {
1501 return rvu_nix_aq_enq_inst(rvu, (struct nix_aq_enq_req *)req,
1502 (struct nix_aq_enq_rsp *)rsp);
1503 }
1504
rvu_mbox_handler_nix_hwctx_disable(struct rvu * rvu,struct hwctx_disable_req * req,struct msg_rsp * rsp)1505 int rvu_mbox_handler_nix_hwctx_disable(struct rvu *rvu,
1506 struct hwctx_disable_req *req,
1507 struct msg_rsp *rsp)
1508 {
1509 return nix_lf_hwctx_disable(rvu, req);
1510 }
1511
rvu_mbox_handler_nix_lf_alloc(struct rvu * rvu,struct nix_lf_alloc_req * req,struct nix_lf_alloc_rsp * rsp)1512 int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
1513 struct nix_lf_alloc_req *req,
1514 struct nix_lf_alloc_rsp *rsp)
1515 {
1516 int nixlf, qints, hwctx_size, intf, rc = 0, pf;
1517 u16 bcast, mcast, promisc, ucast;
1518 struct rvu_hwinfo *hw = rvu->hw;
1519 u16 pcifunc = req->hdr.pcifunc;
1520 u8 cgx_id = 0, lmac_id = 0;
1521 bool rules_created = false;
1522 struct rvu_block *block;
1523 struct rvu_pfvf *pfvf;
1524 struct cgx *cgxd;
1525 u64 cfg, ctx_cfg;
1526 int blkaddr;
1527
1528 if (!req->rq_cnt || !req->sq_cnt || !req->cq_cnt)
1529 return NIX_AF_ERR_PARAM;
1530
1531 if (req->way_mask)
1532 req->way_mask &= 0xFFFF;
1533
1534 pfvf = rvu_get_pfvf(rvu, pcifunc);
1535 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
1536 if (!pfvf->nixlf || blkaddr < 0)
1537 return NIX_AF_ERR_AF_LF_INVALID;
1538
1539 block = &hw->block[blkaddr];
1540 nixlf = rvu_get_lf(rvu, block, pcifunc, 0);
1541 if (nixlf < 0)
1542 return NIX_AF_ERR_AF_LF_INVALID;
1543
1544 /* Check if requested 'NIXLF <=> NPALF' mapping is valid */
1545 if (req->npa_func) {
1546 /* If default, use 'this' NIXLF's PFFUNC */
1547 if (req->npa_func == RVU_DEFAULT_PF_FUNC)
1548 req->npa_func = pcifunc;
1549 if (!is_pffunc_map_valid(rvu, req->npa_func, BLKTYPE_NPA))
1550 return NIX_AF_INVAL_NPA_PF_FUNC;
1551 }
1552
1553 /* Check if requested 'NIXLF <=> SSOLF' mapping is valid */
1554 if (req->sso_func) {
1555 /* If default, use 'this' NIXLF's PFFUNC */
1556 if (req->sso_func == RVU_DEFAULT_PF_FUNC)
1557 req->sso_func = pcifunc;
1558 if (!is_pffunc_map_valid(rvu, req->sso_func, BLKTYPE_SSO))
1559 return NIX_AF_INVAL_SSO_PF_FUNC;
1560 }
1561
1562 /* If RSS is being enabled, check if requested config is valid.
1563 * RSS table size should be power of two, otherwise
1564 * RSS_GRP::OFFSET + adder might go beyond that group or
1565 * won't be able to use entire table.
1566 */
1567 if (req->rss_sz && (req->rss_sz > MAX_RSS_INDIR_TBL_SIZE ||
1568 !is_power_of_2(req->rss_sz)))
1569 return NIX_AF_ERR_RSS_SIZE_INVALID;
1570
1571 if (req->rss_sz &&
1572 (!req->rss_grps || req->rss_grps > MAX_RSS_GROUPS))
1573 return NIX_AF_ERR_RSS_GRPS_INVALID;
1574
1575 /* Reset this NIX LF */
1576 rc = rvu_lf_reset(rvu, block, nixlf);
1577 if (rc) {
1578 dev_err(rvu->dev, "Failed to reset NIX%d LF%d\n",
1579 block->addr - BLKADDR_NIX0, nixlf);
1580 return NIX_AF_ERR_LF_RESET;
1581 }
1582
1583 ctx_cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST3);
1584
1585 /* Alloc NIX RQ HW context memory and config the base */
1586 hwctx_size = 1UL << ((ctx_cfg >> 4) & 0xF);
1587 rc = qmem_alloc(rvu->dev, &pfvf->rq_ctx, req->rq_cnt, hwctx_size);
1588 if (rc)
1589 goto free_mem;
1590
1591 pfvf->rq_bmap = kcalloc(req->rq_cnt, sizeof(long), GFP_KERNEL);
1592 if (!pfvf->rq_bmap) {
1593 rc = -ENOMEM;
1594 goto free_mem;
1595 }
1596
1597 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RQS_BASE(nixlf),
1598 (u64)pfvf->rq_ctx->iova);
1599
1600 /* Set caching and queue count in HW */
1601 cfg = BIT_ULL(36) | (req->rq_cnt - 1) | req->way_mask << 20;
1602 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RQS_CFG(nixlf), cfg);
1603
1604 /* Alloc NIX SQ HW context memory and config the base */
1605 hwctx_size = 1UL << (ctx_cfg & 0xF);
1606 rc = qmem_alloc(rvu->dev, &pfvf->sq_ctx, req->sq_cnt, hwctx_size);
1607 if (rc)
1608 goto free_mem;
1609
1610 pfvf->sq_bmap = kcalloc(req->sq_cnt, sizeof(long), GFP_KERNEL);
1611 if (!pfvf->sq_bmap) {
1612 rc = -ENOMEM;
1613 goto free_mem;
1614 }
1615
1616 rvu_write64(rvu, blkaddr, NIX_AF_LFX_SQS_BASE(nixlf),
1617 (u64)pfvf->sq_ctx->iova);
1618
1619 cfg = BIT_ULL(36) | (req->sq_cnt - 1) | req->way_mask << 20;
1620 rvu_write64(rvu, blkaddr, NIX_AF_LFX_SQS_CFG(nixlf), cfg);
1621
1622 /* Alloc NIX CQ HW context memory and config the base */
1623 hwctx_size = 1UL << ((ctx_cfg >> 8) & 0xF);
1624 rc = qmem_alloc(rvu->dev, &pfvf->cq_ctx, req->cq_cnt, hwctx_size);
1625 if (rc)
1626 goto free_mem;
1627
1628 pfvf->cq_bmap = kcalloc(req->cq_cnt, sizeof(long), GFP_KERNEL);
1629 if (!pfvf->cq_bmap) {
1630 rc = -ENOMEM;
1631 goto free_mem;
1632 }
1633
1634 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CQS_BASE(nixlf),
1635 (u64)pfvf->cq_ctx->iova);
1636
1637 cfg = BIT_ULL(36) | (req->cq_cnt - 1) | req->way_mask << 20;
1638 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CQS_CFG(nixlf), cfg);
1639
1640 /* Initialize receive side scaling (RSS) */
1641 hwctx_size = 1UL << ((ctx_cfg >> 12) & 0xF);
1642 rc = nixlf_rss_ctx_init(rvu, blkaddr, pfvf, nixlf, req->rss_sz,
1643 req->rss_grps, hwctx_size, req->way_mask,
1644 !!(req->flags & NIX_LF_RSS_TAG_LSB_AS_ADDER));
1645 if (rc)
1646 goto free_mem;
1647
1648 /* Alloc memory for CQINT's HW contexts */
1649 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
1650 qints = (cfg >> 24) & 0xFFF;
1651 hwctx_size = 1UL << ((ctx_cfg >> 24) & 0xF);
1652 rc = qmem_alloc(rvu->dev, &pfvf->cq_ints_ctx, qints, hwctx_size);
1653 if (rc)
1654 goto free_mem;
1655
1656 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CINTS_BASE(nixlf),
1657 (u64)pfvf->cq_ints_ctx->iova);
1658
1659 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CINTS_CFG(nixlf),
1660 BIT_ULL(36) | req->way_mask << 20);
1661
1662 /* Alloc memory for QINT's HW contexts */
1663 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
1664 qints = (cfg >> 12) & 0xFFF;
1665 hwctx_size = 1UL << ((ctx_cfg >> 20) & 0xF);
1666 rc = qmem_alloc(rvu->dev, &pfvf->nix_qints_ctx, qints, hwctx_size);
1667 if (rc)
1668 goto free_mem;
1669
1670 rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_BASE(nixlf),
1671 (u64)pfvf->nix_qints_ctx->iova);
1672 rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_CFG(nixlf),
1673 BIT_ULL(36) | req->way_mask << 20);
1674
1675 /* Setup VLANX TPID's.
1676 * Use VLAN1 for 802.1Q
1677 * and VLAN0 for 802.1AD.
1678 */
1679 cfg = (0x8100ULL << 16) | 0x88A8ULL;
1680 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf), cfg);
1681
1682 /* Enable LMTST for this NIX LF */
1683 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_CFG2(nixlf), BIT_ULL(0));
1684
1685 /* Set CQE/WQE size, NPA_PF_FUNC for SQBs and also SSO_PF_FUNC */
1686 if (req->npa_func)
1687 cfg = req->npa_func;
1688 if (req->sso_func)
1689 cfg |= (u64)req->sso_func << 16;
1690
1691 cfg |= (u64)req->xqe_sz << 33;
1692 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CFG(nixlf), cfg);
1693
1694 /* Config Rx pkt length, csum checks and apad enable / disable */
1695 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_CFG(nixlf), req->rx_cfg);
1696
1697 /* Configure pkind for TX parse config */
1698
1699 pf = rvu_get_pf(rvu->pdev, pcifunc);
1700 cfg = NPC_TX_DEF_PKIND;
1701
1702 if (is_pf_cgxmapped(rvu, pf) && is_vf(pcifunc)) {
1703 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1704 cgxd = rvu_cgx_pdata(cgx_id, rvu);
1705 mutex_lock(&cgxd->lock);
1706 if (rvu_cgx_is_pkind_config_permitted(rvu, pcifunc))
1707 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg);
1708 mutex_unlock(&cgxd->lock);
1709 } else {
1710 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg);
1711 }
1712
1713 if (is_rep_dev(rvu, pcifunc)) {
1714 pfvf->tx_chan_base = RVU_SWITCH_LBK_CHAN;
1715 pfvf->tx_chan_cnt = 1;
1716 goto exit;
1717 }
1718
1719 intf = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
1720 if (is_sdp_pfvf(rvu, pcifunc))
1721 intf = NIX_INTF_TYPE_SDP;
1722
1723 if (is_cn20k(rvu->pdev)) {
1724 rc = npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &bcast, &mcast,
1725 &promisc, &ucast);
1726 if (rc) {
1727 rc = npc_cn20k_dft_rules_alloc(rvu, pcifunc);
1728 if (rc)
1729 goto free_mem;
1730
1731 rules_created = true;
1732 }
1733 }
1734
1735 rc = nix_interface_init(rvu, pcifunc, intf, nixlf, rsp,
1736 !!(req->flags & NIX_LF_LBK_BLK_SEL));
1737 if (rc)
1738 goto free_dft;
1739
1740 /* Disable NPC entries as NIXLF's contexts are not initialized yet */
1741 rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);
1742
1743 /* Configure RX VTAG Type 7 (strip) for vf vlan */
1744 rvu_write64(rvu, blkaddr,
1745 NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, NIX_AF_LFX_RX_VTAG_TYPE7),
1746 VTAGSIZE_T4 | VTAG_STRIP);
1747
1748 goto exit;
1749
1750 free_dft:
1751 if (is_cn20k(rvu->pdev) && rules_created)
1752 npc_cn20k_dft_rules_free(rvu, pcifunc);
1753
1754 free_mem:
1755 nix_ctx_free(rvu, pfvf);
1756
1757 exit:
1758 /* Set macaddr of this PF/VF */
1759 ether_addr_copy(rsp->mac_addr, pfvf->mac_addr);
1760
1761 /* set SQB size info */
1762 cfg = rvu_read64(rvu, blkaddr, NIX_AF_SQ_CONST);
1763 rsp->sqb_size = (cfg >> 34) & 0xFFFF;
1764 rsp->rx_chan_base = pfvf->rx_chan_base;
1765 rsp->tx_chan_base = pfvf->tx_chan_base;
1766 rsp->rx_chan_cnt = pfvf->rx_chan_cnt;
1767 rsp->tx_chan_cnt = pfvf->tx_chan_cnt;
1768 rsp->lso_tsov4_idx = NIX_LSO_FORMAT_IDX_TSOV4;
1769 rsp->lso_tsov6_idx = NIX_LSO_FORMAT_IDX_TSOV6;
1770 /* Get HW supported stat count */
1771 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
1772 rsp->lf_rx_stats = ((cfg >> 32) & 0xFF);
1773 rsp->lf_tx_stats = ((cfg >> 24) & 0xFF);
1774 /* Get count of CQ IRQs and error IRQs supported per LF */
1775 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
1776 rsp->qints = ((cfg >> 12) & 0xFFF);
1777 rsp->cints = ((cfg >> 24) & 0xFFF);
1778 rsp->cgx_links = hw->cgx_links;
1779 rsp->lbk_links = hw->lbk_links;
1780 rsp->sdp_links = hw->sdp_links;
1781
1782 return rc;
1783 }
1784
rvu_mbox_handler_nix_lf_free(struct rvu * rvu,struct nix_lf_free_req * req,struct msg_rsp * rsp)1785 int rvu_mbox_handler_nix_lf_free(struct rvu *rvu, struct nix_lf_free_req *req,
1786 struct msg_rsp *rsp)
1787 {
1788 struct rvu_hwinfo *hw = rvu->hw;
1789 u16 pcifunc = req->hdr.pcifunc;
1790 struct rvu_block *block;
1791 int blkaddr, nixlf, err;
1792 struct rvu_pfvf *pfvf;
1793
1794 pfvf = rvu_get_pfvf(rvu, pcifunc);
1795 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
1796 if (!pfvf->nixlf || blkaddr < 0)
1797 return NIX_AF_ERR_AF_LF_INVALID;
1798
1799 block = &hw->block[blkaddr];
1800 nixlf = rvu_get_lf(rvu, block, pcifunc, 0);
1801 if (nixlf < 0)
1802 return NIX_AF_ERR_AF_LF_INVALID;
1803
1804 if (is_rep_dev(rvu, pcifunc))
1805 goto free_lf;
1806
1807 if (req->flags & NIX_LF_DISABLE_FLOWS)
1808 rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);
1809 else
1810 rvu_npc_free_mcam_entries(rvu, pcifunc, nixlf);
1811
1812 /* Free any tx vtag def entries used by this NIX LF */
1813 if (!(req->flags & NIX_LF_DONT_FREE_TX_VTAG))
1814 nix_free_tx_vtag_entries(rvu, pcifunc);
1815
1816 nix_interface_deinit(rvu, pcifunc, nixlf);
1817
1818 free_lf:
1819 /* Reset this NIX LF */
1820 err = rvu_lf_reset(rvu, block, nixlf);
1821 if (err) {
1822 dev_err(rvu->dev, "Failed to reset NIX%d LF%d\n",
1823 block->addr - BLKADDR_NIX0, nixlf);
1824 return NIX_AF_ERR_LF_RESET;
1825 }
1826
1827 nix_ctx_free(rvu, pfvf);
1828
1829 if (is_cn20k(rvu->pdev) && !(req->flags & NIX_LF_DONT_FREE_DFT_IDXS))
1830 npc_cn20k_dft_rules_free(rvu, pcifunc);
1831
1832 return 0;
1833 }
1834
rvu_mbox_handler_nix_mark_format_cfg(struct rvu * rvu,struct nix_mark_format_cfg * req,struct nix_mark_format_cfg_rsp * rsp)1835 int rvu_mbox_handler_nix_mark_format_cfg(struct rvu *rvu,
1836 struct nix_mark_format_cfg *req,
1837 struct nix_mark_format_cfg_rsp *rsp)
1838 {
1839 u16 pcifunc = req->hdr.pcifunc;
1840 struct nix_hw *nix_hw;
1841 struct rvu_pfvf *pfvf;
1842 int blkaddr, rc;
1843 u32 cfg;
1844
1845 pfvf = rvu_get_pfvf(rvu, pcifunc);
1846 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
1847 if (!pfvf->nixlf || blkaddr < 0)
1848 return NIX_AF_ERR_AF_LF_INVALID;
1849
1850 nix_hw = get_nix_hw(rvu->hw, blkaddr);
1851 if (!nix_hw)
1852 return NIX_AF_ERR_INVALID_NIXBLK;
1853
1854 cfg = (((u32)req->offset & 0x7) << 16) |
1855 (((u32)req->y_mask & 0xF) << 12) |
1856 (((u32)req->y_val & 0xF) << 8) |
1857 (((u32)req->r_mask & 0xF) << 4) | ((u32)req->r_val & 0xF);
1858
1859 rc = rvu_nix_reserve_mark_format(rvu, nix_hw, blkaddr, cfg);
1860 if (rc < 0) {
1861 dev_err(rvu->dev, "No mark_format_ctl for (pf:%d, vf:%d)",
1862 rvu_get_pf(rvu->pdev, pcifunc),
1863 pcifunc & RVU_PFVF_FUNC_MASK);
1864 return NIX_AF_ERR_MARK_CFG_FAIL;
1865 }
1866
1867 rsp->mark_format_idx = rc;
1868 return 0;
1869 }
1870
1871 /* Handle shaper update specially for few revisions */
1872 static bool
handle_txschq_shaper_update(struct rvu * rvu,int blkaddr,int nixlf,int lvl,u64 reg,u64 regval)1873 handle_txschq_shaper_update(struct rvu *rvu, int blkaddr, int nixlf,
1874 int lvl, u64 reg, u64 regval)
1875 {
1876 u64 regbase, oldval, sw_xoff = 0;
1877 u64 dbgval, md_debug0 = 0;
1878 unsigned long poll_tmo;
1879 bool rate_reg = 0;
1880 u32 schq;
1881
1882 regbase = reg & 0xFFFF;
1883 schq = TXSCHQ_IDX(reg, TXSCHQ_IDX_SHIFT);
1884
1885 /* Check for rate register */
1886 switch (lvl) {
1887 case NIX_TXSCH_LVL_TL1:
1888 md_debug0 = NIX_AF_TL1X_MD_DEBUG0(schq);
1889 sw_xoff = NIX_AF_TL1X_SW_XOFF(schq);
1890
1891 rate_reg = !!(regbase == NIX_AF_TL1X_CIR(0));
1892 break;
1893 case NIX_TXSCH_LVL_TL2:
1894 md_debug0 = NIX_AF_TL2X_MD_DEBUG0(schq);
1895 sw_xoff = NIX_AF_TL2X_SW_XOFF(schq);
1896
1897 rate_reg = (regbase == NIX_AF_TL2X_CIR(0) ||
1898 regbase == NIX_AF_TL2X_PIR(0));
1899 break;
1900 case NIX_TXSCH_LVL_TL3:
1901 md_debug0 = NIX_AF_TL3X_MD_DEBUG0(schq);
1902 sw_xoff = NIX_AF_TL3X_SW_XOFF(schq);
1903
1904 rate_reg = (regbase == NIX_AF_TL3X_CIR(0) ||
1905 regbase == NIX_AF_TL3X_PIR(0));
1906 break;
1907 case NIX_TXSCH_LVL_TL4:
1908 md_debug0 = NIX_AF_TL4X_MD_DEBUG0(schq);
1909 sw_xoff = NIX_AF_TL4X_SW_XOFF(schq);
1910
1911 rate_reg = (regbase == NIX_AF_TL4X_CIR(0) ||
1912 regbase == NIX_AF_TL4X_PIR(0));
1913 break;
1914 case NIX_TXSCH_LVL_MDQ:
1915 sw_xoff = NIX_AF_MDQX_SW_XOFF(schq);
1916 rate_reg = (regbase == NIX_AF_MDQX_CIR(0) ||
1917 regbase == NIX_AF_MDQX_PIR(0));
1918 break;
1919 }
1920
1921 if (!rate_reg)
1922 return false;
1923
1924 /* Nothing special to do when state is not toggled */
1925 oldval = rvu_read64(rvu, blkaddr, reg);
1926 if ((oldval & 0x1) == (regval & 0x1)) {
1927 rvu_write64(rvu, blkaddr, reg, regval);
1928 return true;
1929 }
1930
1931 /* PIR/CIR disable */
1932 if (!(regval & 0x1)) {
1933 rvu_write64(rvu, blkaddr, sw_xoff, 1);
1934 rvu_write64(rvu, blkaddr, reg, 0);
1935 udelay(4);
1936 rvu_write64(rvu, blkaddr, sw_xoff, 0);
1937 return true;
1938 }
1939
1940 /* PIR/CIR enable */
1941 rvu_write64(rvu, blkaddr, sw_xoff, 1);
1942 if (md_debug0) {
1943 poll_tmo = jiffies + usecs_to_jiffies(10000);
1944 /* Wait until VLD(bit32) == 1 or C_CON(bit48) == 0 */
1945 do {
1946 if (time_after(jiffies, poll_tmo)) {
1947 dev_err(rvu->dev,
1948 "NIXLF%d: TLX%u(lvl %u) CIR/PIR enable failed\n",
1949 nixlf, schq, lvl);
1950 goto exit;
1951 }
1952 usleep_range(1, 5);
1953 dbgval = rvu_read64(rvu, blkaddr, md_debug0);
1954 } while (!(dbgval & BIT_ULL(32)) && (dbgval & BIT_ULL(48)));
1955 }
1956 rvu_write64(rvu, blkaddr, reg, regval);
1957 exit:
1958 rvu_write64(rvu, blkaddr, sw_xoff, 0);
1959 return true;
1960 }
1961
nix_reset_tx_schedule(struct rvu * rvu,int blkaddr,int lvl,int schq)1962 static void nix_reset_tx_schedule(struct rvu *rvu, int blkaddr,
1963 int lvl, int schq)
1964 {
1965 u64 tlx_parent = 0, tlx_schedule = 0;
1966
1967 switch (lvl) {
1968 case NIX_TXSCH_LVL_TL2:
1969 tlx_parent = NIX_AF_TL2X_PARENT(schq);
1970 tlx_schedule = NIX_AF_TL2X_SCHEDULE(schq);
1971 break;
1972 case NIX_TXSCH_LVL_TL3:
1973 tlx_parent = NIX_AF_TL3X_PARENT(schq);
1974 tlx_schedule = NIX_AF_TL3X_SCHEDULE(schq);
1975 break;
1976 case NIX_TXSCH_LVL_TL4:
1977 tlx_parent = NIX_AF_TL4X_PARENT(schq);
1978 tlx_schedule = NIX_AF_TL4X_SCHEDULE(schq);
1979 break;
1980 case NIX_TXSCH_LVL_MDQ:
1981 /* no need to reset SMQ_CFG as HW clears this CSR
1982 * on SMQ flush
1983 */
1984 tlx_parent = NIX_AF_MDQX_PARENT(schq);
1985 tlx_schedule = NIX_AF_MDQX_SCHEDULE(schq);
1986 break;
1987 default:
1988 return;
1989 }
1990
1991 if (tlx_parent)
1992 rvu_write64(rvu, blkaddr, tlx_parent, 0x0);
1993
1994 if (tlx_schedule)
1995 rvu_write64(rvu, blkaddr, tlx_schedule, 0x0);
1996 }
1997
1998 /* Disable shaping of pkts by a scheduler queue
1999 * at a given scheduler level.
2000 */
nix_reset_tx_shaping(struct rvu * rvu,int blkaddr,int nixlf,int lvl,int schq)2001 static void nix_reset_tx_shaping(struct rvu *rvu, int blkaddr,
2002 int nixlf, int lvl, int schq)
2003 {
2004 struct rvu_hwinfo *hw = rvu->hw;
2005 u64 cir_reg = 0, pir_reg = 0;
2006 u64 cfg;
2007
2008 switch (lvl) {
2009 case NIX_TXSCH_LVL_TL1:
2010 cir_reg = NIX_AF_TL1X_CIR(schq);
2011 pir_reg = 0; /* PIR not available at TL1 */
2012 break;
2013 case NIX_TXSCH_LVL_TL2:
2014 cir_reg = NIX_AF_TL2X_CIR(schq);
2015 pir_reg = NIX_AF_TL2X_PIR(schq);
2016 break;
2017 case NIX_TXSCH_LVL_TL3:
2018 cir_reg = NIX_AF_TL3X_CIR(schq);
2019 pir_reg = NIX_AF_TL3X_PIR(schq);
2020 break;
2021 case NIX_TXSCH_LVL_TL4:
2022 cir_reg = NIX_AF_TL4X_CIR(schq);
2023 pir_reg = NIX_AF_TL4X_PIR(schq);
2024 break;
2025 case NIX_TXSCH_LVL_MDQ:
2026 cir_reg = NIX_AF_MDQX_CIR(schq);
2027 pir_reg = NIX_AF_MDQX_PIR(schq);
2028 break;
2029 }
2030
2031 /* Shaper state toggle needs wait/poll */
2032 if (hw->cap.nix_shaper_toggle_wait) {
2033 if (cir_reg)
2034 handle_txschq_shaper_update(rvu, blkaddr, nixlf,
2035 lvl, cir_reg, 0);
2036 if (pir_reg)
2037 handle_txschq_shaper_update(rvu, blkaddr, nixlf,
2038 lvl, pir_reg, 0);
2039 return;
2040 }
2041
2042 if (!cir_reg)
2043 return;
2044 cfg = rvu_read64(rvu, blkaddr, cir_reg);
2045 rvu_write64(rvu, blkaddr, cir_reg, cfg & ~BIT_ULL(0));
2046
2047 if (!pir_reg)
2048 return;
2049 cfg = rvu_read64(rvu, blkaddr, pir_reg);
2050 rvu_write64(rvu, blkaddr, pir_reg, cfg & ~BIT_ULL(0));
2051 }
2052
nix_reset_tx_linkcfg(struct rvu * rvu,int blkaddr,int lvl,int schq)2053 static void nix_reset_tx_linkcfg(struct rvu *rvu, int blkaddr,
2054 int lvl, int schq)
2055 {
2056 struct rvu_hwinfo *hw = rvu->hw;
2057 int link_level;
2058 int link;
2059
2060 if (lvl >= hw->cap.nix_tx_aggr_lvl)
2061 return;
2062
2063 /* Reset TL4's SDP link config */
2064 if (lvl == NIX_TXSCH_LVL_TL4)
2065 rvu_write64(rvu, blkaddr, NIX_AF_TL4X_SDP_LINK_CFG(schq), 0x00);
2066
2067 link_level = rvu_read64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL) & 0x01 ?
2068 NIX_TXSCH_LVL_TL3 : NIX_TXSCH_LVL_TL2;
2069 if (lvl != link_level)
2070 return;
2071
2072 /* Reset TL2's CGX or LBK link config */
2073 for (link = 0; link < (hw->cgx_links + hw->lbk_links); link++)
2074 rvu_write64(rvu, blkaddr,
2075 NIX_AF_TL3_TL2X_LINKX_CFG(schq, link), 0x00);
2076 }
2077
nix_clear_tx_xoff(struct rvu * rvu,int blkaddr,int lvl,int schq)2078 static void nix_clear_tx_xoff(struct rvu *rvu, int blkaddr,
2079 int lvl, int schq)
2080 {
2081 struct rvu_hwinfo *hw = rvu->hw;
2082 u64 reg;
2083
2084 /* Skip this if shaping is not supported */
2085 if (!hw->cap.nix_shaping)
2086 return;
2087
2088 /* Clear level specific SW_XOFF */
2089 switch (lvl) {
2090 case NIX_TXSCH_LVL_TL1:
2091 reg = NIX_AF_TL1X_SW_XOFF(schq);
2092 break;
2093 case NIX_TXSCH_LVL_TL2:
2094 reg = NIX_AF_TL2X_SW_XOFF(schq);
2095 break;
2096 case NIX_TXSCH_LVL_TL3:
2097 reg = NIX_AF_TL3X_SW_XOFF(schq);
2098 break;
2099 case NIX_TXSCH_LVL_TL4:
2100 reg = NIX_AF_TL4X_SW_XOFF(schq);
2101 break;
2102 case NIX_TXSCH_LVL_MDQ:
2103 reg = NIX_AF_MDQX_SW_XOFF(schq);
2104 break;
2105 default:
2106 return;
2107 }
2108
2109 rvu_write64(rvu, blkaddr, reg, 0x0);
2110 }
2111
nix_get_tx_link(struct rvu * rvu,u16 pcifunc)2112 static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc)
2113 {
2114 struct rvu_hwinfo *hw = rvu->hw;
2115 int pf = rvu_get_pf(rvu->pdev, pcifunc);
2116 u8 cgx_id = 0, lmac_id = 0;
2117
2118 if (is_lbk_vf(rvu, pcifunc)) {/* LBK links */
2119 return hw->cgx_links;
2120 } else if (is_pf_cgxmapped(rvu, pf)) {
2121 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
2122 return (cgx_id * hw->lmac_per_cgx) + lmac_id;
2123 }
2124
2125 /* SDP link */
2126 return hw->cgx_links + hw->lbk_links;
2127 }
2128
nix_get_txschq_range(struct rvu * rvu,u16 pcifunc,int link,int * start,int * end)2129 static void nix_get_txschq_range(struct rvu *rvu, u16 pcifunc,
2130 int link, int *start, int *end)
2131 {
2132 struct rvu_hwinfo *hw = rvu->hw;
2133 int pf = rvu_get_pf(rvu->pdev, pcifunc);
2134
2135 /* LBK links */
2136 if (is_lbk_vf(rvu, pcifunc) || is_rep_dev(rvu, pcifunc)) {
2137 *start = hw->cap.nix_txsch_per_cgx_lmac * link;
2138 *end = *start + hw->cap.nix_txsch_per_lbk_lmac;
2139 } else if (is_pf_cgxmapped(rvu, pf)) { /* CGX links */
2140 *start = hw->cap.nix_txsch_per_cgx_lmac * link;
2141 *end = *start + hw->cap.nix_txsch_per_cgx_lmac;
2142 } else { /* SDP link */
2143 *start = (hw->cap.nix_txsch_per_cgx_lmac * hw->cgx_links) +
2144 (hw->cap.nix_txsch_per_lbk_lmac * hw->lbk_links);
2145 *end = *start + hw->cap.nix_txsch_per_sdp_lmac;
2146 }
2147 }
2148
nix_check_txschq_alloc_req(struct rvu * rvu,int lvl,u16 pcifunc,struct nix_hw * nix_hw,struct nix_txsch_alloc_req * req)2149 static int nix_check_txschq_alloc_req(struct rvu *rvu, int lvl, u16 pcifunc,
2150 struct nix_hw *nix_hw,
2151 struct nix_txsch_alloc_req *req)
2152 {
2153 struct rvu_hwinfo *hw = rvu->hw;
2154 int schq, req_schq, free_cnt;
2155 struct nix_txsch *txsch;
2156 int link, start, end;
2157
2158 txsch = &nix_hw->txsch[lvl];
2159 req_schq = req->schq_contig[lvl] + req->schq[lvl];
2160
2161 if (!req_schq)
2162 return 0;
2163
2164 link = nix_get_tx_link(rvu, pcifunc);
2165
2166 /* For traffic aggregating scheduler level, one queue is enough */
2167 if (lvl >= hw->cap.nix_tx_aggr_lvl) {
2168 if (req_schq != 1)
2169 return NIX_AF_ERR_TLX_ALLOC_FAIL;
2170 return 0;
2171 }
2172
2173 /* Get free SCHQ count and check if request can be accomodated */
2174 if (hw->cap.nix_fixed_txschq_mapping) {
2175 nix_get_txschq_range(rvu, pcifunc, link, &start, &end);
2176 schq = start + (pcifunc & RVU_PFVF_FUNC_MASK);
2177 if (end <= txsch->schq.max && schq < end &&
2178 !test_bit(schq, txsch->schq.bmap))
2179 free_cnt = 1;
2180 else
2181 free_cnt = 0;
2182 } else {
2183 free_cnt = rvu_rsrc_free_count(&txsch->schq);
2184 }
2185
2186 if (free_cnt < req_schq || req->schq[lvl] > MAX_TXSCHQ_PER_FUNC ||
2187 req->schq_contig[lvl] > MAX_TXSCHQ_PER_FUNC)
2188 return NIX_AF_ERR_TLX_ALLOC_FAIL;
2189
2190 /* If contiguous queues are needed, check for availability */
2191 if (!hw->cap.nix_fixed_txschq_mapping && req->schq_contig[lvl] &&
2192 !rvu_rsrc_check_contig(&txsch->schq, req->schq_contig[lvl]))
2193 return NIX_AF_ERR_TLX_ALLOC_FAIL;
2194
2195 return 0;
2196 }
2197
nix_txsch_alloc(struct rvu * rvu,struct nix_txsch * txsch,struct nix_txsch_alloc_rsp * rsp,int lvl,int start,int end)2198 static void nix_txsch_alloc(struct rvu *rvu, struct nix_txsch *txsch,
2199 struct nix_txsch_alloc_rsp *rsp,
2200 int lvl, int start, int end)
2201 {
2202 struct rvu_hwinfo *hw = rvu->hw;
2203 u16 pcifunc = rsp->hdr.pcifunc;
2204 int idx, schq;
2205
2206 /* For traffic aggregating levels, queue alloc is based
2207 * on transmit link to which PF_FUNC is mapped to.
2208 */
2209 if (lvl >= hw->cap.nix_tx_aggr_lvl) {
2210 /* A single TL queue is allocated */
2211 if (rsp->schq_contig[lvl]) {
2212 rsp->schq_contig[lvl] = 1;
2213 rsp->schq_contig_list[lvl][0] = start;
2214 }
2215
2216 /* Both contig and non-contig reqs doesn't make sense here */
2217 if (rsp->schq_contig[lvl])
2218 rsp->schq[lvl] = 0;
2219
2220 if (rsp->schq[lvl]) {
2221 rsp->schq[lvl] = 1;
2222 rsp->schq_list[lvl][0] = start;
2223 }
2224 return;
2225 }
2226
2227 /* Adjust the queue request count if HW supports
2228 * only one queue per level configuration.
2229 */
2230 if (hw->cap.nix_fixed_txschq_mapping) {
2231 idx = pcifunc & RVU_PFVF_FUNC_MASK;
2232 schq = start + idx;
2233 if (idx >= (end - start) || test_bit(schq, txsch->schq.bmap)) {
2234 rsp->schq_contig[lvl] = 0;
2235 rsp->schq[lvl] = 0;
2236 return;
2237 }
2238
2239 if (rsp->schq_contig[lvl]) {
2240 rsp->schq_contig[lvl] = 1;
2241 set_bit(schq, txsch->schq.bmap);
2242 rsp->schq_contig_list[lvl][0] = schq;
2243 rsp->schq[lvl] = 0;
2244 } else if (rsp->schq[lvl]) {
2245 rsp->schq[lvl] = 1;
2246 set_bit(schq, txsch->schq.bmap);
2247 rsp->schq_list[lvl][0] = schq;
2248 }
2249 return;
2250 }
2251
2252 /* Allocate contiguous queue indices requesty first */
2253 if (rsp->schq_contig[lvl]) {
2254 schq = bitmap_find_next_zero_area(txsch->schq.bmap,
2255 txsch->schq.max, start,
2256 rsp->schq_contig[lvl], 0);
2257 if (schq >= end)
2258 rsp->schq_contig[lvl] = 0;
2259 for (idx = 0; idx < rsp->schq_contig[lvl]; idx++) {
2260 set_bit(schq, txsch->schq.bmap);
2261 rsp->schq_contig_list[lvl][idx] = schq;
2262 schq++;
2263 }
2264 }
2265
2266 /* Allocate non-contiguous queue indices */
2267 if (rsp->schq[lvl]) {
2268 idx = 0;
2269 for (schq = start; schq < end; schq++) {
2270 if (!test_bit(schq, txsch->schq.bmap)) {
2271 set_bit(schq, txsch->schq.bmap);
2272 rsp->schq_list[lvl][idx++] = schq;
2273 }
2274 if (idx == rsp->schq[lvl])
2275 break;
2276 }
2277 /* Update how many were allocated */
2278 rsp->schq[lvl] = idx;
2279 }
2280 }
2281
rvu_mbox_handler_nix_txsch_alloc(struct rvu * rvu,struct nix_txsch_alloc_req * req,struct nix_txsch_alloc_rsp * rsp)2282 int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rvu,
2283 struct nix_txsch_alloc_req *req,
2284 struct nix_txsch_alloc_rsp *rsp)
2285 {
2286 struct rvu_hwinfo *hw = rvu->hw;
2287 u16 pcifunc = req->hdr.pcifunc;
2288 int link, blkaddr, rc = 0;
2289 int lvl, idx, start, end;
2290 struct nix_txsch *txsch;
2291 struct nix_hw *nix_hw;
2292 u32 *pfvf_map;
2293 int nixlf;
2294 u16 schq;
2295
2296 rc = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
2297 if (rc)
2298 return rc;
2299
2300 nix_hw = get_nix_hw(rvu->hw, blkaddr);
2301 if (!nix_hw)
2302 return NIX_AF_ERR_INVALID_NIXBLK;
2303
2304 mutex_lock(&rvu->rsrc_lock);
2305
2306 /* Check if request is valid as per HW capabilities
2307 * and can be accomodated.
2308 */
2309 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
2310 rc = nix_check_txschq_alloc_req(rvu, lvl, pcifunc, nix_hw, req);
2311 if (rc)
2312 goto err;
2313 }
2314
2315 /* Allocate requested Tx scheduler queues */
2316 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
2317 txsch = &nix_hw->txsch[lvl];
2318 pfvf_map = txsch->pfvf_map;
2319
2320 if (!req->schq[lvl] && !req->schq_contig[lvl])
2321 continue;
2322
2323 rsp->schq[lvl] = req->schq[lvl];
2324 rsp->schq_contig[lvl] = req->schq_contig[lvl];
2325
2326 link = nix_get_tx_link(rvu, pcifunc);
2327
2328 if (lvl >= hw->cap.nix_tx_aggr_lvl) {
2329 start = link;
2330 end = link;
2331 } else if (hw->cap.nix_fixed_txschq_mapping) {
2332 nix_get_txschq_range(rvu, pcifunc, link, &start, &end);
2333 } else {
2334 start = 0;
2335 end = txsch->schq.max;
2336 }
2337
2338 nix_txsch_alloc(rvu, txsch, rsp, lvl, start, end);
2339
2340 /* Reset queue config */
2341 for (idx = 0; idx < req->schq_contig[lvl]; idx++) {
2342 schq = rsp->schq_contig_list[lvl][idx];
2343 if (!(TXSCH_MAP_FLAGS(pfvf_map[schq]) &
2344 NIX_TXSCHQ_CFG_DONE))
2345 pfvf_map[schq] = TXSCH_MAP(pcifunc, 0);
2346 nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
2347 nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
2348 nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
2349 }
2350
2351 for (idx = 0; idx < req->schq[lvl]; idx++) {
2352 schq = rsp->schq_list[lvl][idx];
2353 if (!(TXSCH_MAP_FLAGS(pfvf_map[schq]) &
2354 NIX_TXSCHQ_CFG_DONE))
2355 pfvf_map[schq] = TXSCH_MAP(pcifunc, 0);
2356 nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
2357 nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
2358 nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
2359 }
2360 }
2361
2362 rsp->aggr_level = hw->cap.nix_tx_aggr_lvl;
2363 rsp->aggr_lvl_rr_prio = TXSCH_TL1_DFLT_RR_PRIO;
2364 rsp->link_cfg_lvl = rvu_read64(rvu, blkaddr,
2365 NIX_AF_PSE_CHANNEL_LEVEL) & 0x01 ?
2366 NIX_TXSCH_LVL_TL3 : NIX_TXSCH_LVL_TL2;
2367 goto exit;
2368 err:
2369 rc = NIX_AF_ERR_TLX_ALLOC_FAIL;
2370 exit:
2371 mutex_unlock(&rvu->rsrc_lock);
2372 return rc;
2373 }
2374
nix_smq_flush_fill_ctx(struct rvu * rvu,int blkaddr,int smq,struct nix_smq_flush_ctx * smq_flush_ctx)2375 static void nix_smq_flush_fill_ctx(struct rvu *rvu, int blkaddr, int smq,
2376 struct nix_smq_flush_ctx *smq_flush_ctx)
2377 {
2378 struct nix_smq_tree_ctx *smq_tree_ctx;
2379 u64 parent_off, regval;
2380 u16 schq;
2381 int lvl;
2382
2383 smq_flush_ctx->smq = smq;
2384
2385 schq = smq;
2386 for (lvl = NIX_TXSCH_LVL_SMQ; lvl <= NIX_TXSCH_LVL_TL1; lvl++) {
2387 smq_tree_ctx = &smq_flush_ctx->smq_tree_ctx[lvl];
2388 smq_tree_ctx->schq = schq;
2389 if (lvl == NIX_TXSCH_LVL_TL1) {
2390 smq_tree_ctx->cir_off = NIX_AF_TL1X_CIR(schq);
2391 smq_tree_ctx->pir_off = 0;
2392 smq_tree_ctx->pir_val = 0;
2393 parent_off = 0;
2394 } else if (lvl == NIX_TXSCH_LVL_TL2) {
2395 smq_tree_ctx->cir_off = NIX_AF_TL2X_CIR(schq);
2396 smq_tree_ctx->pir_off = NIX_AF_TL2X_PIR(schq);
2397 parent_off = NIX_AF_TL2X_PARENT(schq);
2398 } else if (lvl == NIX_TXSCH_LVL_TL3) {
2399 smq_tree_ctx->cir_off = NIX_AF_TL3X_CIR(schq);
2400 smq_tree_ctx->pir_off = NIX_AF_TL3X_PIR(schq);
2401 parent_off = NIX_AF_TL3X_PARENT(schq);
2402 } else if (lvl == NIX_TXSCH_LVL_TL4) {
2403 smq_tree_ctx->cir_off = NIX_AF_TL4X_CIR(schq);
2404 smq_tree_ctx->pir_off = NIX_AF_TL4X_PIR(schq);
2405 parent_off = NIX_AF_TL4X_PARENT(schq);
2406 } else if (lvl == NIX_TXSCH_LVL_MDQ) {
2407 smq_tree_ctx->cir_off = NIX_AF_MDQX_CIR(schq);
2408 smq_tree_ctx->pir_off = NIX_AF_MDQX_PIR(schq);
2409 parent_off = NIX_AF_MDQX_PARENT(schq);
2410 }
2411 /* save cir/pir register values */
2412 smq_tree_ctx->cir_val = rvu_read64(rvu, blkaddr, smq_tree_ctx->cir_off);
2413 if (smq_tree_ctx->pir_off)
2414 smq_tree_ctx->pir_val = rvu_read64(rvu, blkaddr, smq_tree_ctx->pir_off);
2415
2416 /* get parent txsch node */
2417 if (parent_off) {
2418 regval = rvu_read64(rvu, blkaddr, parent_off);
2419 schq = (regval >> 16) & 0x1FF;
2420 }
2421 }
2422 }
2423
nix_smq_flush_enadis_xoff(struct rvu * rvu,int blkaddr,struct nix_smq_flush_ctx * smq_flush_ctx,bool enable)2424 static void nix_smq_flush_enadis_xoff(struct rvu *rvu, int blkaddr,
2425 struct nix_smq_flush_ctx *smq_flush_ctx, bool enable)
2426 {
2427 struct nix_txsch *txsch;
2428 struct nix_hw *nix_hw;
2429 int tl2, tl2_schq;
2430 u64 regoff;
2431
2432 nix_hw = get_nix_hw(rvu->hw, blkaddr);
2433 if (!nix_hw)
2434 return;
2435
2436 /* loop through all TL2s with matching PF_FUNC */
2437 txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL2];
2438 tl2_schq = smq_flush_ctx->smq_tree_ctx[NIX_TXSCH_LVL_TL2].schq;
2439 for (tl2 = 0; tl2 < txsch->schq.max; tl2++) {
2440 /* skip the smq(flush) TL2 */
2441 if (tl2 == tl2_schq)
2442 continue;
2443 /* skip unused TL2s */
2444 if (TXSCH_MAP_FLAGS(txsch->pfvf_map[tl2]) & NIX_TXSCHQ_FREE)
2445 continue;
2446 /* skip if PF_FUNC doesn't match */
2447 if ((TXSCH_MAP_FUNC(txsch->pfvf_map[tl2]) & ~RVU_PFVF_FUNC_MASK) !=
2448 (TXSCH_MAP_FUNC(txsch->pfvf_map[tl2_schq]) &
2449 ~RVU_PFVF_FUNC_MASK))
2450 continue;
2451 /* enable/disable XOFF */
2452 regoff = NIX_AF_TL2X_SW_XOFF(tl2);
2453 if (enable)
2454 rvu_write64(rvu, blkaddr, regoff, 0x1);
2455 else
2456 rvu_write64(rvu, blkaddr, regoff, 0x0);
2457 }
2458 }
2459
nix_smq_flush_enadis_rate(struct rvu * rvu,int blkaddr,struct nix_smq_flush_ctx * smq_flush_ctx,bool enable)2460 static void nix_smq_flush_enadis_rate(struct rvu *rvu, int blkaddr,
2461 struct nix_smq_flush_ctx *smq_flush_ctx, bool enable)
2462 {
2463 u64 cir_off, pir_off, cir_val, pir_val;
2464 struct nix_smq_tree_ctx *smq_tree_ctx;
2465 int lvl;
2466
2467 for (lvl = NIX_TXSCH_LVL_SMQ; lvl <= NIX_TXSCH_LVL_TL1; lvl++) {
2468 smq_tree_ctx = &smq_flush_ctx->smq_tree_ctx[lvl];
2469 cir_off = smq_tree_ctx->cir_off;
2470 cir_val = smq_tree_ctx->cir_val;
2471 pir_off = smq_tree_ctx->pir_off;
2472 pir_val = smq_tree_ctx->pir_val;
2473
2474 if (enable) {
2475 rvu_write64(rvu, blkaddr, cir_off, cir_val);
2476 if (lvl != NIX_TXSCH_LVL_TL1)
2477 rvu_write64(rvu, blkaddr, pir_off, pir_val);
2478 } else {
2479 rvu_write64(rvu, blkaddr, cir_off, 0x0);
2480 if (lvl != NIX_TXSCH_LVL_TL1)
2481 rvu_write64(rvu, blkaddr, pir_off, 0x0);
2482 }
2483 }
2484 }
2485
nix_smq_flush(struct rvu * rvu,int blkaddr,int smq,u16 pcifunc,int nixlf)2486 static int nix_smq_flush(struct rvu *rvu, int blkaddr,
2487 int smq, u16 pcifunc, int nixlf)
2488 {
2489 struct nix_smq_flush_ctx *smq_flush_ctx;
2490 int err, restore_tx_en = 0, i;
2491 int pf = rvu_get_pf(rvu->pdev, pcifunc);
2492 u8 cgx_id = 0, lmac_id = 0;
2493 u16 tl2_tl3_link_schq;
2494 u64 cfg, bmap = 0;
2495 u8 link_level;
2496
2497 if (!is_rvu_otx2(rvu)) {
2498 /* Skip SMQ flush if pkt count is zero */
2499 cfg = rvu_read64(rvu, blkaddr, NIX_AF_MDQX_IN_MD_COUNT(smq));
2500 if (!cfg)
2501 return 0;
2502 }
2503
2504 /* enable cgx tx if disabled */
2505 if (is_pf_cgxmapped(rvu, pf)) {
2506 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
2507 restore_tx_en = !rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu),
2508 lmac_id, true);
2509 }
2510
2511 /* XOFF all TL2s whose parent TL1 matches SMQ tree TL1 */
2512 smq_flush_ctx = kzalloc_obj(*smq_flush_ctx);
2513 if (!smq_flush_ctx)
2514 return -ENOMEM;
2515 nix_smq_flush_fill_ctx(rvu, blkaddr, smq, smq_flush_ctx);
2516 nix_smq_flush_enadis_xoff(rvu, blkaddr, smq_flush_ctx, true);
2517 nix_smq_flush_enadis_rate(rvu, blkaddr, smq_flush_ctx, false);
2518
2519 /* Disable backpressure from physical link,
2520 * otherwise SMQ flush may stall.
2521 */
2522 rvu_cgx_enadis_rx_bp(rvu, pf, false);
2523
2524 link_level = rvu_read64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL) & 0x01 ?
2525 NIX_TXSCH_LVL_TL3 : NIX_TXSCH_LVL_TL2;
2526 tl2_tl3_link_schq = smq_flush_ctx->smq_tree_ctx[link_level].schq;
2527
2528 /* SMQ set enqueue xoff */
2529 cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq));
2530 cfg |= BIT_ULL(50);
2531 rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq), cfg);
2532
2533 /* Clear all NIX_AF_TL3_TL2_LINK_CFG[ENA] for the TL3/TL2 queue */
2534 for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) {
2535 cfg = rvu_read64(rvu, blkaddr,
2536 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, i));
2537 if (!(cfg & BIT_ULL(12)))
2538 continue;
2539 bmap |= BIT_ULL(i);
2540 cfg &= ~BIT_ULL(12);
2541 rvu_write64(rvu, blkaddr,
2542 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, i), cfg);
2543 }
2544
2545 /* Do SMQ flush and set enqueue xoff */
2546 cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq));
2547 cfg |= BIT_ULL(50) | BIT_ULL(49);
2548 rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq), cfg);
2549
2550 /* Wait for flush to complete */
2551 err = rvu_poll_reg(rvu, blkaddr,
2552 NIX_AF_SMQX_CFG(smq), BIT_ULL(49), true);
2553 if (err)
2554 dev_info(rvu->dev,
2555 "NIXLF%d: SMQ%d flush failed, txlink might be busy\n",
2556 nixlf, smq);
2557
2558 /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */
2559 for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) {
2560 if (!(bmap & BIT_ULL(i)))
2561 continue;
2562 cfg = rvu_read64(rvu, blkaddr,
2563 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, i));
2564 cfg |= BIT_ULL(12);
2565 rvu_write64(rvu, blkaddr,
2566 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, i), cfg);
2567 }
2568
2569 /* clear XOFF on TL2s */
2570 nix_smq_flush_enadis_rate(rvu, blkaddr, smq_flush_ctx, true);
2571 nix_smq_flush_enadis_xoff(rvu, blkaddr, smq_flush_ctx, false);
2572 kfree(smq_flush_ctx);
2573
2574 rvu_cgx_enadis_rx_bp(rvu, pf, true);
2575 /* restore cgx tx state */
2576 if (restore_tx_en)
2577 rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), lmac_id, false);
2578 return err;
2579 }
2580
nix_txschq_free(struct rvu * rvu,u16 pcifunc)2581 static int nix_txschq_free(struct rvu *rvu, u16 pcifunc)
2582 {
2583 int blkaddr, nixlf, lvl, schq, err;
2584 struct rvu_hwinfo *hw = rvu->hw;
2585 struct nix_txsch *txsch;
2586 struct nix_hw *nix_hw;
2587 u16 map_func;
2588
2589 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
2590 if (blkaddr < 0)
2591 return NIX_AF_ERR_AF_LF_INVALID;
2592
2593 nix_hw = get_nix_hw(rvu->hw, blkaddr);
2594 if (!nix_hw)
2595 return NIX_AF_ERR_INVALID_NIXBLK;
2596
2597 nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
2598 if (nixlf < 0)
2599 return NIX_AF_ERR_AF_LF_INVALID;
2600
2601 /* Disable TL2/3 queue links and all XOFF's before SMQ flush*/
2602 mutex_lock(&rvu->rsrc_lock);
2603 for (lvl = NIX_TXSCH_LVL_MDQ; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
2604 txsch = &nix_hw->txsch[lvl];
2605
2606 if (lvl >= hw->cap.nix_tx_aggr_lvl)
2607 continue;
2608
2609 for (schq = 0; schq < txsch->schq.max; schq++) {
2610 if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc)
2611 continue;
2612 nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
2613 nix_clear_tx_xoff(rvu, blkaddr, lvl, schq);
2614 nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
2615 }
2616 }
2617 nix_clear_tx_xoff(rvu, blkaddr, NIX_TXSCH_LVL_TL1,
2618 nix_get_tx_link(rvu, pcifunc));
2619
2620 /* On PF cleanup, clear cfg done flag as
2621 * PF would have changed default config.
2622 */
2623 if (!(pcifunc & RVU_PFVF_FUNC_MASK)) {
2624 txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL1];
2625 schq = nix_get_tx_link(rvu, pcifunc);
2626 /* Do not clear pcifunc in txsch->pfvf_map[schq] because
2627 * VF might be using this TL1 queue
2628 */
2629 map_func = TXSCH_MAP_FUNC(txsch->pfvf_map[schq]);
2630 txsch->pfvf_map[schq] = TXSCH_SET_FLAG(map_func, 0x0);
2631 }
2632
2633 /* Flush SMQs */
2634 txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ];
2635 for (schq = 0; schq < txsch->schq.max; schq++) {
2636 if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc)
2637 continue;
2638 nix_smq_flush(rvu, blkaddr, schq, pcifunc, nixlf);
2639 }
2640
2641 /* Now free scheduler queues to free pool */
2642 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
2643 /* TLs above aggregation level are shared across all PF
2644 * and it's VFs, hence skip freeing them.
2645 */
2646 if (lvl >= hw->cap.nix_tx_aggr_lvl)
2647 continue;
2648
2649 txsch = &nix_hw->txsch[lvl];
2650 for (schq = 0; schq < txsch->schq.max; schq++) {
2651 if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc)
2652 continue;
2653 nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
2654 rvu_free_rsrc(&txsch->schq, schq);
2655 txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE);
2656 }
2657 }
2658 mutex_unlock(&rvu->rsrc_lock);
2659
2660 err = rvu_ndc_sync(rvu, blkaddr, nixlf, NIX_AF_NDC_TX_SYNC);
2661 if (err)
2662 dev_err(rvu->dev, "NDC-TX sync failed for NIXLF %d\n", nixlf);
2663
2664 return 0;
2665 }
2666
nix_txschq_free_one(struct rvu * rvu,struct nix_txsch_free_req * req)2667 static int nix_txschq_free_one(struct rvu *rvu,
2668 struct nix_txsch_free_req *req)
2669 {
2670 struct rvu_hwinfo *hw = rvu->hw;
2671 u16 pcifunc = req->hdr.pcifunc;
2672 int lvl, schq, nixlf, blkaddr;
2673 struct nix_txsch *txsch;
2674 struct nix_hw *nix_hw;
2675 u32 *pfvf_map;
2676 int rc;
2677
2678 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
2679 if (blkaddr < 0)
2680 return NIX_AF_ERR_AF_LF_INVALID;
2681
2682 nix_hw = get_nix_hw(rvu->hw, blkaddr);
2683 if (!nix_hw)
2684 return NIX_AF_ERR_INVALID_NIXBLK;
2685
2686 nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
2687 if (nixlf < 0)
2688 return NIX_AF_ERR_AF_LF_INVALID;
2689
2690 lvl = req->schq_lvl;
2691 schq = req->schq;
2692 txsch = &nix_hw->txsch[lvl];
2693
2694 if (lvl >= hw->cap.nix_tx_aggr_lvl || schq >= txsch->schq.max)
2695 return 0;
2696
2697 pfvf_map = txsch->pfvf_map;
2698 mutex_lock(&rvu->rsrc_lock);
2699
2700 if (TXSCH_MAP_FUNC(pfvf_map[schq]) != pcifunc) {
2701 rc = NIX_AF_ERR_TLX_INVALID;
2702 goto err;
2703 }
2704
2705 /* Clear SW_XOFF of this resource only.
2706 * For SMQ level, all path XOFF's
2707 * need to be made clear by user
2708 */
2709 nix_clear_tx_xoff(rvu, blkaddr, lvl, schq);
2710
2711 nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
2712 nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
2713
2714 /* Flush if it is a SMQ. Onus of disabling
2715 * TL2/3 queue links before SMQ flush is on user
2716 */
2717 if (lvl == NIX_TXSCH_LVL_SMQ &&
2718 nix_smq_flush(rvu, blkaddr, schq, pcifunc, nixlf)) {
2719 rc = NIX_AF_SMQ_FLUSH_FAILED;
2720 goto err;
2721 }
2722
2723 nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
2724
2725 /* Free the resource */
2726 rvu_free_rsrc(&txsch->schq, schq);
2727 txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE);
2728 mutex_unlock(&rvu->rsrc_lock);
2729 return 0;
2730 err:
2731 mutex_unlock(&rvu->rsrc_lock);
2732 return rc;
2733 }
2734
rvu_mbox_handler_nix_txsch_free(struct rvu * rvu,struct nix_txsch_free_req * req,struct msg_rsp * rsp)2735 int rvu_mbox_handler_nix_txsch_free(struct rvu *rvu,
2736 struct nix_txsch_free_req *req,
2737 struct msg_rsp *rsp)
2738 {
2739 if (req->flags & TXSCHQ_FREE_ALL)
2740 return nix_txschq_free(rvu, req->hdr.pcifunc);
2741 else
2742 return nix_txschq_free_one(rvu, req);
2743 }
2744
is_txschq_hierarchy_valid(struct rvu * rvu,u16 pcifunc,int blkaddr,int lvl,u64 reg,u64 regval)2745 static bool is_txschq_hierarchy_valid(struct rvu *rvu, u16 pcifunc, int blkaddr,
2746 int lvl, u64 reg, u64 regval)
2747 {
2748 u64 regbase = reg & 0xFFFF;
2749 u16 schq, parent;
2750
2751 if (!rvu_check_valid_reg(TXSCHQ_HWREGMAP, lvl, reg))
2752 return false;
2753
2754 schq = TXSCHQ_IDX(reg, TXSCHQ_IDX_SHIFT);
2755 /* Check if this schq belongs to this PF/VF or not */
2756 if (!is_valid_txschq(rvu, blkaddr, lvl, pcifunc, schq))
2757 return false;
2758
2759 parent = (regval >> 16) & 0x1FF;
2760 /* Validate MDQ's TL4 parent */
2761 if (regbase == NIX_AF_MDQX_PARENT(0) &&
2762 !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL4, pcifunc, parent))
2763 return false;
2764
2765 /* Validate TL4's TL3 parent */
2766 if (regbase == NIX_AF_TL4X_PARENT(0) &&
2767 !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL3, pcifunc, parent))
2768 return false;
2769
2770 /* Validate TL3's TL2 parent */
2771 if (regbase == NIX_AF_TL3X_PARENT(0) &&
2772 !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL2, pcifunc, parent))
2773 return false;
2774
2775 /* Validate TL2's TL1 parent */
2776 if (regbase == NIX_AF_TL2X_PARENT(0) &&
2777 !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL1, pcifunc, parent))
2778 return false;
2779
2780 return true;
2781 }
2782
is_txschq_shaping_valid(struct rvu_hwinfo * hw,int lvl,u64 reg)2783 static bool is_txschq_shaping_valid(struct rvu_hwinfo *hw, int lvl, u64 reg)
2784 {
2785 u64 regbase;
2786
2787 if (hw->cap.nix_shaping)
2788 return true;
2789
2790 /* If shaping and coloring is not supported, then
2791 * *_CIR and *_PIR registers should not be configured.
2792 */
2793 regbase = reg & 0xFFFF;
2794
2795 switch (lvl) {
2796 case NIX_TXSCH_LVL_TL1:
2797 if (regbase == NIX_AF_TL1X_CIR(0))
2798 return false;
2799 break;
2800 case NIX_TXSCH_LVL_TL2:
2801 if (regbase == NIX_AF_TL2X_CIR(0) ||
2802 regbase == NIX_AF_TL2X_PIR(0))
2803 return false;
2804 break;
2805 case NIX_TXSCH_LVL_TL3:
2806 if (regbase == NIX_AF_TL3X_CIR(0) ||
2807 regbase == NIX_AF_TL3X_PIR(0))
2808 return false;
2809 break;
2810 case NIX_TXSCH_LVL_TL4:
2811 if (regbase == NIX_AF_TL4X_CIR(0) ||
2812 regbase == NIX_AF_TL4X_PIR(0))
2813 return false;
2814 break;
2815 case NIX_TXSCH_LVL_MDQ:
2816 if (regbase == NIX_AF_MDQX_CIR(0) ||
2817 regbase == NIX_AF_MDQX_PIR(0))
2818 return false;
2819 break;
2820 }
2821 return true;
2822 }
2823
nix_tl1_default_cfg(struct rvu * rvu,struct nix_hw * nix_hw,u16 pcifunc,int blkaddr)2824 static void nix_tl1_default_cfg(struct rvu *rvu, struct nix_hw *nix_hw,
2825 u16 pcifunc, int blkaddr)
2826 {
2827 u32 *pfvf_map;
2828 int schq;
2829
2830 schq = nix_get_tx_link(rvu, pcifunc);
2831 pfvf_map = nix_hw->txsch[NIX_TXSCH_LVL_TL1].pfvf_map;
2832 /* Skip if PF has already done the config */
2833 if (TXSCH_MAP_FLAGS(pfvf_map[schq]) & NIX_TXSCHQ_CFG_DONE)
2834 return;
2835 rvu_write64(rvu, blkaddr, NIX_AF_TL1X_TOPOLOGY(schq),
2836 (TXSCH_TL1_DFLT_RR_PRIO << 1));
2837
2838 /* On OcteonTx2 the config was in bytes and newer silcons
2839 * it's changed to weight.
2840 */
2841 if (!rvu->hw->cap.nix_common_dwrr_mtu)
2842 rvu_write64(rvu, blkaddr, NIX_AF_TL1X_SCHEDULE(schq),
2843 TXSCH_TL1_DFLT_RR_QTM);
2844 else
2845 rvu_write64(rvu, blkaddr, NIX_AF_TL1X_SCHEDULE(schq),
2846 CN10K_MAX_DWRR_WEIGHT);
2847
2848 rvu_write64(rvu, blkaddr, NIX_AF_TL1X_CIR(schq), 0x00);
2849 pfvf_map[schq] = TXSCH_SET_FLAG(pfvf_map[schq], NIX_TXSCHQ_CFG_DONE);
2850 }
2851
2852 /* Register offset - [15:0]
2853 * Scheduler Queue number - [25:16]
2854 */
2855 #define NIX_TX_SCHQ_MASK GENMASK_ULL(25, 0)
2856
nix_txschq_cfg_read(struct rvu * rvu,struct nix_hw * nix_hw,int blkaddr,struct nix_txschq_config * req,struct nix_txschq_config * rsp)2857 static int nix_txschq_cfg_read(struct rvu *rvu, struct nix_hw *nix_hw,
2858 int blkaddr, struct nix_txschq_config *req,
2859 struct nix_txschq_config *rsp)
2860 {
2861 u16 pcifunc = req->hdr.pcifunc;
2862 int idx, schq;
2863 u64 reg;
2864
2865 for (idx = 0; idx < req->num_regs; idx++) {
2866 reg = req->reg[idx];
2867 reg &= NIX_TX_SCHQ_MASK;
2868 schq = TXSCHQ_IDX(reg, TXSCHQ_IDX_SHIFT);
2869 if (!rvu_check_valid_reg(TXSCHQ_HWREGMAP, req->lvl, reg) ||
2870 !is_valid_txschq(rvu, blkaddr, req->lvl, pcifunc, schq))
2871 return NIX_AF_INVAL_TXSCHQ_CFG;
2872 rsp->regval[idx] = rvu_read64(rvu, blkaddr, reg);
2873 }
2874 rsp->lvl = req->lvl;
2875 rsp->num_regs = req->num_regs;
2876 return 0;
2877 }
2878
rvu_nix_tx_tl2_cfg(struct rvu * rvu,int blkaddr,u16 pcifunc,struct nix_txsch * txsch,bool enable)2879 void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int blkaddr, u16 pcifunc,
2880 struct nix_txsch *txsch, bool enable)
2881 {
2882 struct rvu_hwinfo *hw = rvu->hw;
2883 int lbk_link_start, lbk_links;
2884 u8 pf = rvu_get_pf(rvu->pdev, pcifunc);
2885 int schq;
2886 u64 cfg;
2887
2888 if (!is_pf_cgxmapped(rvu, pf) && !is_rep_dev(rvu, pcifunc))
2889 return;
2890
2891 cfg = enable ? (BIT_ULL(12) | RVU_SWITCH_LBK_CHAN) : 0;
2892 lbk_link_start = hw->cgx_links;
2893
2894 for (schq = 0; schq < txsch->schq.max; schq++) {
2895 if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc)
2896 continue;
2897 /* Enable all LBK links with channel 63 by default so that
2898 * packets can be sent to LBK with a NPC TX MCAM rule
2899 */
2900 lbk_links = hw->lbk_links;
2901 while (lbk_links--)
2902 rvu_write64(rvu, blkaddr,
2903 NIX_AF_TL3_TL2X_LINKX_CFG(schq,
2904 lbk_link_start +
2905 lbk_links), cfg);
2906 }
2907 }
2908
rvu_mbox_handler_nix_txschq_cfg(struct rvu * rvu,struct nix_txschq_config * req,struct nix_txschq_config * rsp)2909 int rvu_mbox_handler_nix_txschq_cfg(struct rvu *rvu,
2910 struct nix_txschq_config *req,
2911 struct nix_txschq_config *rsp)
2912 {
2913 u64 reg, val, regval, schq_regbase, val_mask;
2914 struct rvu_hwinfo *hw = rvu->hw;
2915 u16 pcifunc = req->hdr.pcifunc;
2916 struct nix_txsch *txsch;
2917 struct nix_hw *nix_hw;
2918 int blkaddr, idx, err;
2919 int nixlf, schq;
2920 u32 *pfvf_map;
2921
2922 if (req->lvl >= NIX_TXSCH_LVL_CNT ||
2923 req->num_regs > MAX_REGS_PER_MBOX_MSG)
2924 return NIX_AF_INVAL_TXSCHQ_CFG;
2925
2926 err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
2927 if (err)
2928 return err;
2929
2930 nix_hw = get_nix_hw(rvu->hw, blkaddr);
2931 if (!nix_hw)
2932 return NIX_AF_ERR_INVALID_NIXBLK;
2933
2934 if (req->read)
2935 return nix_txschq_cfg_read(rvu, nix_hw, blkaddr, req, rsp);
2936
2937 txsch = &nix_hw->txsch[req->lvl];
2938 pfvf_map = txsch->pfvf_map;
2939
2940 if (req->lvl >= hw->cap.nix_tx_aggr_lvl &&
2941 pcifunc & RVU_PFVF_FUNC_MASK) {
2942 mutex_lock(&rvu->rsrc_lock);
2943 if (req->lvl == NIX_TXSCH_LVL_TL1)
2944 nix_tl1_default_cfg(rvu, nix_hw, pcifunc, blkaddr);
2945 mutex_unlock(&rvu->rsrc_lock);
2946 return 0;
2947 }
2948
2949 for (idx = 0; idx < req->num_regs; idx++) {
2950 reg = req->reg[idx];
2951 reg &= NIX_TX_SCHQ_MASK;
2952 regval = req->regval[idx];
2953 schq_regbase = reg & 0xFFFF;
2954 val_mask = req->regval_mask[idx];
2955
2956 if (!is_txschq_hierarchy_valid(rvu, pcifunc, blkaddr,
2957 txsch->lvl, reg, regval))
2958 return NIX_AF_INVAL_TXSCHQ_CFG;
2959
2960 /* Check if shaping and coloring is supported */
2961 if (!is_txschq_shaping_valid(hw, req->lvl, reg))
2962 continue;
2963
2964 val = rvu_read64(rvu, blkaddr, reg);
2965 regval = (val & val_mask) | (regval & ~val_mask);
2966
2967 /* Handle shaping state toggle specially */
2968 if (hw->cap.nix_shaper_toggle_wait &&
2969 handle_txschq_shaper_update(rvu, blkaddr, nixlf,
2970 req->lvl, reg, regval))
2971 continue;
2972
2973 /* Replace PF/VF visible NIXLF slot with HW NIXLF id */
2974 if (schq_regbase == NIX_AF_SMQX_CFG(0)) {
2975 nixlf = rvu_get_lf(rvu, &hw->block[blkaddr],
2976 pcifunc, 0);
2977 regval &= ~(0x7FULL << 24);
2978 regval |= ((u64)nixlf << 24);
2979 }
2980
2981 /* Clear 'BP_ENA' config, if it's not allowed */
2982 if (!hw->cap.nix_tx_link_bp) {
2983 if (schq_regbase == NIX_AF_TL4X_SDP_LINK_CFG(0) ||
2984 (schq_regbase & 0xFF00) ==
2985 NIX_AF_TL3_TL2X_LINKX_CFG(0, 0))
2986 regval &= ~BIT_ULL(13);
2987 }
2988
2989 /* Mark config as done for TL1 by PF */
2990 if (schq_regbase >= NIX_AF_TL1X_SCHEDULE(0) &&
2991 schq_regbase <= NIX_AF_TL1X_GREEN_BYTES(0)) {
2992 schq = TXSCHQ_IDX(reg, TXSCHQ_IDX_SHIFT);
2993 mutex_lock(&rvu->rsrc_lock);
2994 pfvf_map[schq] = TXSCH_SET_FLAG(pfvf_map[schq],
2995 NIX_TXSCHQ_CFG_DONE);
2996 mutex_unlock(&rvu->rsrc_lock);
2997 }
2998
2999 /* SMQ flush is special hence split register writes such
3000 * that flush first and write rest of the bits later.
3001 */
3002 if (schq_regbase == NIX_AF_SMQX_CFG(0) &&
3003 (regval & BIT_ULL(49))) {
3004 schq = TXSCHQ_IDX(reg, TXSCHQ_IDX_SHIFT);
3005 nix_smq_flush(rvu, blkaddr, schq, pcifunc, nixlf);
3006 regval &= ~BIT_ULL(49);
3007 }
3008 rvu_write64(rvu, blkaddr, reg, regval);
3009 }
3010
3011 return 0;
3012 }
3013
nix_rx_vtag_cfg(struct rvu * rvu,int nixlf,int blkaddr,struct nix_vtag_config * req)3014 static int nix_rx_vtag_cfg(struct rvu *rvu, int nixlf, int blkaddr,
3015 struct nix_vtag_config *req)
3016 {
3017 u64 regval = req->vtag_size;
3018
3019 if (req->rx.vtag_type > NIX_AF_LFX_RX_VTAG_TYPE7 ||
3020 req->vtag_size > VTAGSIZE_T8)
3021 return -EINVAL;
3022
3023 /* RX VTAG Type 7 reserved for vf vlan */
3024 if (req->rx.vtag_type == NIX_AF_LFX_RX_VTAG_TYPE7)
3025 return NIX_AF_ERR_RX_VTAG_INUSE;
3026
3027 if (req->rx.capture_vtag)
3028 regval |= BIT_ULL(5);
3029 if (req->rx.strip_vtag)
3030 regval |= BIT_ULL(4);
3031
3032 rvu_write64(rvu, blkaddr,
3033 NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, req->rx.vtag_type), regval);
3034 return 0;
3035 }
3036
nix_tx_vtag_free(struct rvu * rvu,int blkaddr,u16 pcifunc,int index)3037 static int nix_tx_vtag_free(struct rvu *rvu, int blkaddr,
3038 u16 pcifunc, int index)
3039 {
3040 struct nix_hw *nix_hw = get_nix_hw(rvu->hw, blkaddr);
3041 struct nix_txvlan *vlan;
3042
3043 if (!nix_hw)
3044 return NIX_AF_ERR_INVALID_NIXBLK;
3045
3046 vlan = &nix_hw->txvlan;
3047 if (vlan->entry2pfvf_map[index] != pcifunc)
3048 return NIX_AF_ERR_PARAM;
3049
3050 rvu_write64(rvu, blkaddr,
3051 NIX_AF_TX_VTAG_DEFX_DATA(index), 0x0ull);
3052 rvu_write64(rvu, blkaddr,
3053 NIX_AF_TX_VTAG_DEFX_CTL(index), 0x0ull);
3054
3055 vlan->entry2pfvf_map[index] = 0;
3056 rvu_free_rsrc(&vlan->rsrc, index);
3057
3058 return 0;
3059 }
3060
nix_free_tx_vtag_entries(struct rvu * rvu,u16 pcifunc)3061 static void nix_free_tx_vtag_entries(struct rvu *rvu, u16 pcifunc)
3062 {
3063 struct nix_txvlan *vlan;
3064 struct nix_hw *nix_hw;
3065 int index, blkaddr;
3066
3067 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
3068 if (blkaddr < 0)
3069 return;
3070
3071 nix_hw = get_nix_hw(rvu->hw, blkaddr);
3072 if (!nix_hw)
3073 return;
3074
3075 vlan = &nix_hw->txvlan;
3076
3077 mutex_lock(&vlan->rsrc_lock);
3078 /* Scan all the entries and free the ones mapped to 'pcifunc' */
3079 for (index = 0; index < vlan->rsrc.max; index++) {
3080 if (vlan->entry2pfvf_map[index] == pcifunc)
3081 nix_tx_vtag_free(rvu, blkaddr, pcifunc, index);
3082 }
3083 mutex_unlock(&vlan->rsrc_lock);
3084 }
3085
nix_tx_vtag_alloc(struct rvu * rvu,int blkaddr,u64 vtag,u8 size)3086 static int nix_tx_vtag_alloc(struct rvu *rvu, int blkaddr,
3087 u64 vtag, u8 size)
3088 {
3089 struct nix_hw *nix_hw = get_nix_hw(rvu->hw, blkaddr);
3090 struct nix_txvlan *vlan;
3091 u64 regval;
3092 int index;
3093
3094 if (!nix_hw)
3095 return NIX_AF_ERR_INVALID_NIXBLK;
3096
3097 vlan = &nix_hw->txvlan;
3098
3099 mutex_lock(&vlan->rsrc_lock);
3100
3101 index = rvu_alloc_rsrc(&vlan->rsrc);
3102 if (index < 0) {
3103 mutex_unlock(&vlan->rsrc_lock);
3104 return index;
3105 }
3106
3107 mutex_unlock(&vlan->rsrc_lock);
3108
3109 regval = size ? vtag : vtag << 32;
3110
3111 rvu_write64(rvu, blkaddr,
3112 NIX_AF_TX_VTAG_DEFX_DATA(index), regval);
3113 rvu_write64(rvu, blkaddr,
3114 NIX_AF_TX_VTAG_DEFX_CTL(index), size);
3115
3116 return index;
3117 }
3118
nix_tx_vtag_decfg(struct rvu * rvu,int blkaddr,struct nix_vtag_config * req)3119 static int nix_tx_vtag_decfg(struct rvu *rvu, int blkaddr,
3120 struct nix_vtag_config *req)
3121 {
3122 struct nix_hw *nix_hw = get_nix_hw(rvu->hw, blkaddr);
3123 u16 pcifunc = req->hdr.pcifunc;
3124 int idx0 = req->tx.vtag0_idx;
3125 int idx1 = req->tx.vtag1_idx;
3126 struct nix_txvlan *vlan;
3127 int err = 0;
3128
3129 if (!nix_hw)
3130 return NIX_AF_ERR_INVALID_NIXBLK;
3131
3132 vlan = &nix_hw->txvlan;
3133 if (req->tx.free_vtag0 && req->tx.free_vtag1)
3134 if (vlan->entry2pfvf_map[idx0] != pcifunc ||
3135 vlan->entry2pfvf_map[idx1] != pcifunc)
3136 return NIX_AF_ERR_PARAM;
3137
3138 mutex_lock(&vlan->rsrc_lock);
3139
3140 if (req->tx.free_vtag0) {
3141 err = nix_tx_vtag_free(rvu, blkaddr, pcifunc, idx0);
3142 if (err)
3143 goto exit;
3144 }
3145
3146 if (req->tx.free_vtag1)
3147 err = nix_tx_vtag_free(rvu, blkaddr, pcifunc, idx1);
3148
3149 exit:
3150 mutex_unlock(&vlan->rsrc_lock);
3151 return err;
3152 }
3153
nix_tx_vtag_cfg(struct rvu * rvu,int blkaddr,struct nix_vtag_config * req,struct nix_vtag_config_rsp * rsp)3154 static int nix_tx_vtag_cfg(struct rvu *rvu, int blkaddr,
3155 struct nix_vtag_config *req,
3156 struct nix_vtag_config_rsp *rsp)
3157 {
3158 struct nix_hw *nix_hw = get_nix_hw(rvu->hw, blkaddr);
3159 struct nix_txvlan *vlan;
3160 u16 pcifunc = req->hdr.pcifunc;
3161
3162 if (!nix_hw)
3163 return NIX_AF_ERR_INVALID_NIXBLK;
3164
3165 vlan = &nix_hw->txvlan;
3166 if (req->tx.cfg_vtag0) {
3167 rsp->vtag0_idx =
3168 nix_tx_vtag_alloc(rvu, blkaddr,
3169 req->tx.vtag0, req->vtag_size);
3170
3171 if (rsp->vtag0_idx < 0)
3172 return NIX_AF_ERR_TX_VTAG_NOSPC;
3173
3174 vlan->entry2pfvf_map[rsp->vtag0_idx] = pcifunc;
3175 }
3176
3177 if (req->tx.cfg_vtag1) {
3178 rsp->vtag1_idx =
3179 nix_tx_vtag_alloc(rvu, blkaddr,
3180 req->tx.vtag1, req->vtag_size);
3181
3182 if (rsp->vtag1_idx < 0)
3183 goto err_free;
3184
3185 vlan->entry2pfvf_map[rsp->vtag1_idx] = pcifunc;
3186 }
3187
3188 return 0;
3189
3190 err_free:
3191 if (req->tx.cfg_vtag0)
3192 nix_tx_vtag_free(rvu, blkaddr, pcifunc, rsp->vtag0_idx);
3193
3194 return NIX_AF_ERR_TX_VTAG_NOSPC;
3195 }
3196
rvu_mbox_handler_nix_vtag_cfg(struct rvu * rvu,struct nix_vtag_config * req,struct nix_vtag_config_rsp * rsp)3197 int rvu_mbox_handler_nix_vtag_cfg(struct rvu *rvu,
3198 struct nix_vtag_config *req,
3199 struct nix_vtag_config_rsp *rsp)
3200 {
3201 u16 pcifunc = req->hdr.pcifunc;
3202 int blkaddr, nixlf, err;
3203
3204 err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
3205 if (err)
3206 return err;
3207
3208 if (req->cfg_type) {
3209 /* rx vtag configuration */
3210 err = nix_rx_vtag_cfg(rvu, nixlf, blkaddr, req);
3211 if (err)
3212 return NIX_AF_ERR_PARAM;
3213 } else {
3214 /* tx vtag configuration */
3215 if ((req->tx.cfg_vtag0 || req->tx.cfg_vtag1) &&
3216 (req->tx.free_vtag0 || req->tx.free_vtag1))
3217 return NIX_AF_ERR_PARAM;
3218
3219 if (req->tx.cfg_vtag0 || req->tx.cfg_vtag1)
3220 return nix_tx_vtag_cfg(rvu, blkaddr, req, rsp);
3221
3222 if (req->tx.free_vtag0 || req->tx.free_vtag1)
3223 return nix_tx_vtag_decfg(rvu, blkaddr, req);
3224 }
3225
3226 return 0;
3227 }
3228
nix_blk_setup_mce(struct rvu * rvu,struct nix_hw * nix_hw,int mce,u8 op,u16 pcifunc,int next,int index,u8 mce_op,bool eol)3229 static int nix_blk_setup_mce(struct rvu *rvu, struct nix_hw *nix_hw,
3230 int mce, u8 op, u16 pcifunc, int next,
3231 int index, u8 mce_op, bool eol)
3232 {
3233 struct nix_aq_enq_req aq_req;
3234 int err;
3235
3236 aq_req.hdr.pcifunc = 0;
3237 aq_req.ctype = NIX_AQ_CTYPE_MCE;
3238 aq_req.op = op;
3239 aq_req.qidx = mce;
3240
3241 /* Use RSS with RSS index 0 */
3242 aq_req.mce.op = mce_op;
3243 aq_req.mce.index = index;
3244 aq_req.mce.eol = eol;
3245 aq_req.mce.pf_func = pcifunc;
3246 aq_req.mce.next = next;
3247
3248 /* All fields valid */
3249 *(u64 *)(&aq_req.mce_mask) = ~0ULL;
3250
3251 err = rvu_nix_blk_aq_enq_inst(rvu, nix_hw, &aq_req, NULL);
3252 if (err) {
3253 dev_err(rvu->dev, "Failed to setup Bcast MCE for PF%d:VF%d\n",
3254 rvu_get_pf(rvu->pdev, pcifunc),
3255 pcifunc & RVU_PFVF_FUNC_MASK);
3256 return err;
3257 }
3258 return 0;
3259 }
3260
nix_delete_mcast_mce_list(struct nix_mce_list * mce_list)3261 static void nix_delete_mcast_mce_list(struct nix_mce_list *mce_list)
3262 {
3263 struct hlist_node *tmp;
3264 struct mce *mce;
3265
3266 /* Scan through the current list */
3267 hlist_for_each_entry_safe(mce, tmp, &mce_list->head, node) {
3268 hlist_del(&mce->node);
3269 kfree(mce);
3270 }
3271
3272 mce_list->count = 0;
3273 mce_list->max = 0;
3274 }
3275
nix_get_last_mce_list_index(struct nix_mcast_grp_elem * elem)3276 static int nix_get_last_mce_list_index(struct nix_mcast_grp_elem *elem)
3277 {
3278 return elem->mce_start_index + elem->mcast_mce_list.count - 1;
3279 }
3280
nix_update_ingress_mce_list_hw(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_mcast_grp_elem * elem)3281 static int nix_update_ingress_mce_list_hw(struct rvu *rvu,
3282 struct nix_hw *nix_hw,
3283 struct nix_mcast_grp_elem *elem)
3284 {
3285 int idx, last_idx, next_idx, err;
3286 struct nix_mce_list *mce_list;
3287 struct mce *mce, *prev_mce;
3288
3289 mce_list = &elem->mcast_mce_list;
3290 idx = elem->mce_start_index;
3291 last_idx = nix_get_last_mce_list_index(elem);
3292 hlist_for_each_entry(mce, &mce_list->head, node) {
3293 if (idx > last_idx)
3294 break;
3295
3296 if (!mce->is_active) {
3297 if (idx == elem->mce_start_index) {
3298 idx++;
3299 prev_mce = mce;
3300 elem->mce_start_index = idx;
3301 continue;
3302 } else if (idx == last_idx) {
3303 err = nix_blk_setup_mce(rvu, nix_hw, idx - 1, NIX_AQ_INSTOP_WRITE,
3304 prev_mce->pcifunc, next_idx,
3305 prev_mce->rq_rss_index,
3306 prev_mce->dest_type,
3307 false);
3308 if (err)
3309 return err;
3310
3311 break;
3312 }
3313 }
3314
3315 next_idx = idx + 1;
3316 /* EOL should be set in last MCE */
3317 err = nix_blk_setup_mce(rvu, nix_hw, idx, NIX_AQ_INSTOP_WRITE,
3318 mce->pcifunc, next_idx,
3319 mce->rq_rss_index, mce->dest_type,
3320 (next_idx > last_idx) ? true : false);
3321 if (err)
3322 return err;
3323
3324 idx++;
3325 prev_mce = mce;
3326 }
3327
3328 return 0;
3329 }
3330
nix_update_egress_mce_list_hw(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_mcast_grp_elem * elem)3331 static void nix_update_egress_mce_list_hw(struct rvu *rvu,
3332 struct nix_hw *nix_hw,
3333 struct nix_mcast_grp_elem *elem)
3334 {
3335 struct nix_mce_list *mce_list;
3336 int idx, last_idx, next_idx;
3337 struct mce *mce, *prev_mce;
3338 u64 regval;
3339 u8 eol;
3340
3341 mce_list = &elem->mcast_mce_list;
3342 idx = elem->mce_start_index;
3343 last_idx = nix_get_last_mce_list_index(elem);
3344 hlist_for_each_entry(mce, &mce_list->head, node) {
3345 if (idx > last_idx)
3346 break;
3347
3348 if (!mce->is_active) {
3349 if (idx == elem->mce_start_index) {
3350 idx++;
3351 prev_mce = mce;
3352 elem->mce_start_index = idx;
3353 continue;
3354 } else if (idx == last_idx) {
3355 regval = (next_idx << 16) | (1 << 12) | prev_mce->channel;
3356 rvu_write64(rvu, nix_hw->blkaddr,
3357 NIX_AF_TX_MCASTX(idx - 1),
3358 regval);
3359 break;
3360 }
3361 }
3362
3363 eol = 0;
3364 next_idx = idx + 1;
3365 /* EOL should be set in last MCE */
3366 if (next_idx > last_idx)
3367 eol = 1;
3368
3369 regval = (next_idx << 16) | (eol << 12) | mce->channel;
3370 rvu_write64(rvu, nix_hw->blkaddr,
3371 NIX_AF_TX_MCASTX(idx),
3372 regval);
3373 idx++;
3374 prev_mce = mce;
3375 }
3376 }
3377
nix_del_mce_list_entry(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_mcast_grp_elem * elem,struct nix_mcast_grp_update_req * req)3378 static int nix_del_mce_list_entry(struct rvu *rvu,
3379 struct nix_hw *nix_hw,
3380 struct nix_mcast_grp_elem *elem,
3381 struct nix_mcast_grp_update_req *req)
3382 {
3383 u32 num_entry = req->num_mce_entry;
3384 struct nix_mce_list *mce_list;
3385 struct mce *mce;
3386 bool is_found;
3387 int i;
3388
3389 mce_list = &elem->mcast_mce_list;
3390 for (i = 0; i < num_entry; i++) {
3391 is_found = false;
3392 hlist_for_each_entry(mce, &mce_list->head, node) {
3393 /* If already exists, then delete */
3394 if (mce->pcifunc == req->pcifunc[i]) {
3395 hlist_del(&mce->node);
3396 kfree(mce);
3397 mce_list->count--;
3398 is_found = true;
3399 break;
3400 }
3401 }
3402
3403 if (!is_found)
3404 return NIX_AF_ERR_INVALID_MCAST_DEL_REQ;
3405 }
3406
3407 mce_list->max = mce_list->count;
3408 /* Dump the updated list to HW */
3409 if (elem->dir == NIX_MCAST_INGRESS)
3410 return nix_update_ingress_mce_list_hw(rvu, nix_hw, elem);
3411
3412 nix_update_egress_mce_list_hw(rvu, nix_hw, elem);
3413 return 0;
3414 }
3415
nix_add_mce_list_entry(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_mcast_grp_elem * elem,struct nix_mcast_grp_update_req * req)3416 static int nix_add_mce_list_entry(struct rvu *rvu,
3417 struct nix_hw *nix_hw,
3418 struct nix_mcast_grp_elem *elem,
3419 struct nix_mcast_grp_update_req *req)
3420 {
3421 u32 num_entry = req->num_mce_entry;
3422 struct nix_mce_list *mce_list;
3423 struct hlist_node *tmp;
3424 struct mce *mce;
3425 int i;
3426
3427 mce_list = &elem->mcast_mce_list;
3428 for (i = 0; i < num_entry; i++) {
3429 mce = kzalloc_obj(*mce);
3430 if (!mce)
3431 goto free_mce;
3432
3433 mce->pcifunc = req->pcifunc[i];
3434 mce->channel = req->channel[i];
3435 mce->rq_rss_index = req->rq_rss_index[i];
3436 mce->dest_type = req->dest_type[i];
3437 mce->is_active = 1;
3438 hlist_add_head(&mce->node, &mce_list->head);
3439 mce_list->count++;
3440 }
3441
3442 mce_list->max += num_entry;
3443
3444 /* Dump the updated list to HW */
3445 if (elem->dir == NIX_MCAST_INGRESS)
3446 return nix_update_ingress_mce_list_hw(rvu, nix_hw, elem);
3447
3448 nix_update_egress_mce_list_hw(rvu, nix_hw, elem);
3449 return 0;
3450
3451 free_mce:
3452 hlist_for_each_entry_safe(mce, tmp, &mce_list->head, node) {
3453 hlist_del(&mce->node);
3454 kfree(mce);
3455 mce_list->count--;
3456 }
3457
3458 return -ENOMEM;
3459 }
3460
nix_update_mce_list_entry(struct nix_mce_list * mce_list,u16 pcifunc,bool add)3461 static int nix_update_mce_list_entry(struct nix_mce_list *mce_list,
3462 u16 pcifunc, bool add)
3463 {
3464 struct mce *mce, *tail = NULL;
3465 bool delete = false;
3466
3467 /* Scan through the current list */
3468 hlist_for_each_entry(mce, &mce_list->head, node) {
3469 /* If already exists, then delete */
3470 if (mce->pcifunc == pcifunc && !add) {
3471 delete = true;
3472 break;
3473 } else if (mce->pcifunc == pcifunc && add) {
3474 /* entry already exists */
3475 return 0;
3476 }
3477 tail = mce;
3478 }
3479
3480 if (delete) {
3481 hlist_del(&mce->node);
3482 kfree(mce);
3483 mce_list->count--;
3484 return 0;
3485 }
3486
3487 if (!add)
3488 return 0;
3489
3490 /* Add a new one to the list, at the tail */
3491 mce = kzalloc_obj(*mce);
3492 if (!mce)
3493 return -ENOMEM;
3494 mce->pcifunc = pcifunc;
3495 if (!tail)
3496 hlist_add_head(&mce->node, &mce_list->head);
3497 else
3498 hlist_add_behind(&mce->node, &tail->node);
3499 mce_list->count++;
3500 return 0;
3501 }
3502
nix_update_mce_list(struct rvu * rvu,u16 pcifunc,struct nix_mce_list * mce_list,int mce_idx,int mcam_index,bool add)3503 int nix_update_mce_list(struct rvu *rvu, u16 pcifunc,
3504 struct nix_mce_list *mce_list,
3505 int mce_idx, int mcam_index, bool add)
3506 {
3507 int err = 0, idx, next_idx, last_idx, blkaddr, npc_blkaddr;
3508 struct npc_mcam *mcam = &rvu->hw->mcam;
3509 struct nix_mcast *mcast;
3510 struct nix_hw *nix_hw;
3511 struct mce *mce;
3512
3513 if (!mce_list)
3514 return -EINVAL;
3515
3516 /* Get this PF/VF func's MCE index */
3517 idx = mce_idx + (pcifunc & RVU_PFVF_FUNC_MASK);
3518
3519 if (idx > (mce_idx + mce_list->max)) {
3520 dev_err(rvu->dev,
3521 "%s: Idx %d > max MCE idx %d, for PF%d bcast list\n",
3522 __func__, idx, mce_list->max,
3523 rvu_get_pf(rvu->pdev, pcifunc));
3524 return -EINVAL;
3525 }
3526
3527 err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
3528 if (err)
3529 return err;
3530
3531 mcast = &nix_hw->mcast;
3532 mutex_lock(&mcast->mce_lock);
3533
3534 err = nix_update_mce_list_entry(mce_list, pcifunc, add);
3535 if (err)
3536 goto end;
3537
3538 /* Disable MCAM entry in NPC */
3539 if (!mce_list->count) {
3540 npc_blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
3541 npc_enable_mcam_entry(rvu, mcam, npc_blkaddr, mcam_index, false);
3542 goto end;
3543 }
3544
3545 /* Dump the updated list to HW */
3546 idx = mce_idx;
3547 last_idx = idx + mce_list->count - 1;
3548 hlist_for_each_entry(mce, &mce_list->head, node) {
3549 if (idx > last_idx)
3550 break;
3551
3552 next_idx = idx + 1;
3553 /* EOL should be set in last MCE */
3554 err = nix_blk_setup_mce(rvu, nix_hw, idx, NIX_AQ_INSTOP_WRITE,
3555 mce->pcifunc, next_idx,
3556 0, 1,
3557 (next_idx > last_idx) ? true : false);
3558 if (err)
3559 goto end;
3560 idx++;
3561 }
3562
3563 end:
3564 mutex_unlock(&mcast->mce_lock);
3565 return err;
3566 }
3567
nix_get_mce_list(struct rvu * rvu,u16 pcifunc,int type,struct nix_mce_list ** mce_list,int * mce_idx)3568 void nix_get_mce_list(struct rvu *rvu, u16 pcifunc, int type,
3569 struct nix_mce_list **mce_list, int *mce_idx)
3570 {
3571 struct rvu_hwinfo *hw = rvu->hw;
3572 struct rvu_pfvf *pfvf;
3573
3574 if (!hw->cap.nix_rx_multicast ||
3575 !is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev,
3576 pcifunc & ~RVU_PFVF_FUNC_MASK))) {
3577 *mce_list = NULL;
3578 *mce_idx = 0;
3579 return;
3580 }
3581
3582 /* Get this PF/VF func's MCE index */
3583 pfvf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
3584
3585 if (type == NIXLF_BCAST_ENTRY) {
3586 *mce_list = &pfvf->bcast_mce_list;
3587 *mce_idx = pfvf->bcast_mce_idx;
3588 } else if (type == NIXLF_ALLMULTI_ENTRY) {
3589 *mce_list = &pfvf->mcast_mce_list;
3590 *mce_idx = pfvf->mcast_mce_idx;
3591 } else if (type == NIXLF_PROMISC_ENTRY) {
3592 *mce_list = &pfvf->promisc_mce_list;
3593 *mce_idx = pfvf->promisc_mce_idx;
3594 } else {
3595 *mce_list = NULL;
3596 *mce_idx = 0;
3597 }
3598 }
3599
nix_update_mce_rule(struct rvu * rvu,u16 pcifunc,int type,bool add)3600 static int nix_update_mce_rule(struct rvu *rvu, u16 pcifunc,
3601 int type, bool add)
3602 {
3603 int err = 0, nixlf, blkaddr, mcam_index, mce_idx;
3604 struct npc_mcam *mcam = &rvu->hw->mcam;
3605 struct rvu_hwinfo *hw = rvu->hw;
3606 struct nix_mce_list *mce_list;
3607 int pf;
3608
3609 /* skip multicast pkt replication for AF's VFs & SDP links */
3610 if (is_lbk_vf(rvu, pcifunc) || is_sdp_pfvf(rvu, pcifunc))
3611 return 0;
3612
3613 if (!hw->cap.nix_rx_multicast)
3614 return 0;
3615
3616 pf = rvu_get_pf(rvu->pdev, pcifunc);
3617 if (!is_pf_cgxmapped(rvu, pf))
3618 return 0;
3619
3620 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
3621 if (blkaddr < 0)
3622 return -EINVAL;
3623
3624 nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
3625 if (nixlf < 0)
3626 return -EINVAL;
3627
3628 nix_get_mce_list(rvu, pcifunc, type, &mce_list, &mce_idx);
3629
3630 mcam_index = npc_get_nixlf_mcam_index(mcam,
3631 pcifunc & ~RVU_PFVF_FUNC_MASK,
3632 nixlf, type);
3633 if (mcam_index < 0)
3634 return -EINVAL;
3635
3636 err = nix_update_mce_list(rvu, pcifunc, mce_list,
3637 mce_idx, mcam_index, add);
3638 return err;
3639 }
3640
nix_setup_mcast_grp(struct nix_hw * nix_hw)3641 static void nix_setup_mcast_grp(struct nix_hw *nix_hw)
3642 {
3643 struct nix_mcast_grp *mcast_grp = &nix_hw->mcast_grp;
3644
3645 INIT_LIST_HEAD(&mcast_grp->mcast_grp_head);
3646 mutex_init(&mcast_grp->mcast_grp_lock);
3647 mcast_grp->next_grp_index = 1;
3648 mcast_grp->count = 0;
3649 }
3650
nix_setup_mce_tables(struct rvu * rvu,struct nix_hw * nix_hw)3651 static int nix_setup_mce_tables(struct rvu *rvu, struct nix_hw *nix_hw)
3652 {
3653 struct nix_mcast *mcast = &nix_hw->mcast;
3654 int err, pf, numvfs, idx;
3655 struct rvu_pfvf *pfvf;
3656 u16 pcifunc;
3657 u64 cfg;
3658
3659 /* Skip PF0 (i.e AF) */
3660 for (pf = 1; pf < (rvu->cgx_mapped_pfs + 1); pf++) {
3661 cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
3662 /* If PF is not enabled, nothing to do */
3663 if (!((cfg >> 20) & 0x01))
3664 continue;
3665 /* Get numVFs attached to this PF */
3666 numvfs = (cfg >> 12) & 0xFF;
3667
3668 pfvf = &rvu->pf[pf];
3669
3670 /* This NIX0/1 block mapped to PF ? */
3671 if (pfvf->nix_blkaddr != nix_hw->blkaddr)
3672 continue;
3673
3674 /* save start idx of broadcast mce list */
3675 pfvf->bcast_mce_idx = nix_alloc_mce_list(mcast, numvfs + 1, NIX_MCAST_INGRESS);
3676 nix_mce_list_init(&pfvf->bcast_mce_list, numvfs + 1);
3677
3678 /* save start idx of multicast mce list */
3679 pfvf->mcast_mce_idx = nix_alloc_mce_list(mcast, numvfs + 1, NIX_MCAST_INGRESS);
3680 nix_mce_list_init(&pfvf->mcast_mce_list, numvfs + 1);
3681
3682 /* save the start idx of promisc mce list */
3683 pfvf->promisc_mce_idx = nix_alloc_mce_list(mcast, numvfs + 1, NIX_MCAST_INGRESS);
3684 nix_mce_list_init(&pfvf->promisc_mce_list, numvfs + 1);
3685
3686 for (idx = 0; idx < (numvfs + 1); idx++) {
3687 /* idx-0 is for PF, followed by VFs */
3688 pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
3689 pcifunc |= idx;
3690 /* Add dummy entries now, so that we don't have to check
3691 * for whether AQ_OP should be INIT/WRITE later on.
3692 * Will be updated when a NIXLF is attached/detached to
3693 * these PF/VFs.
3694 */
3695 err = nix_blk_setup_mce(rvu, nix_hw,
3696 pfvf->bcast_mce_idx + idx,
3697 NIX_AQ_INSTOP_INIT,
3698 pcifunc, 0, 0, 1, true);
3699 if (err)
3700 return err;
3701
3702 /* add dummy entries to multicast mce list */
3703 err = nix_blk_setup_mce(rvu, nix_hw,
3704 pfvf->mcast_mce_idx + idx,
3705 NIX_AQ_INSTOP_INIT,
3706 pcifunc, 0, 0, 1, true);
3707 if (err)
3708 return err;
3709
3710 /* add dummy entries to promisc mce list */
3711 err = nix_blk_setup_mce(rvu, nix_hw,
3712 pfvf->promisc_mce_idx + idx,
3713 NIX_AQ_INSTOP_INIT,
3714 pcifunc, 0, 0, 1, true);
3715 if (err)
3716 return err;
3717 }
3718 }
3719 return 0;
3720 }
3721
nix_setup_mcast(struct rvu * rvu,struct nix_hw * nix_hw,int blkaddr)3722 static int nix_setup_mcast(struct rvu *rvu, struct nix_hw *nix_hw, int blkaddr)
3723 {
3724 struct nix_mcast *mcast = &nix_hw->mcast;
3725 struct rvu_hwinfo *hw = rvu->hw;
3726 int err, size;
3727
3728 size = (rvu_read64(rvu, blkaddr, NIX_AF_CONST3) >> 16) & 0x0F;
3729 size = BIT_ULL(size);
3730
3731 /* Allocate bitmap for rx mce entries */
3732 mcast->mce_counter[NIX_MCAST_INGRESS].max = 256UL << MC_TBL_SIZE;
3733 err = rvu_alloc_bitmap(&mcast->mce_counter[NIX_MCAST_INGRESS]);
3734 if (err)
3735 return -ENOMEM;
3736
3737 /* Allocate bitmap for tx mce entries */
3738 mcast->mce_counter[NIX_MCAST_EGRESS].max = MC_TX_MAX;
3739 err = rvu_alloc_bitmap(&mcast->mce_counter[NIX_MCAST_EGRESS]);
3740 if (err) {
3741 rvu_free_bitmap(&mcast->mce_counter[NIX_MCAST_INGRESS]);
3742 return -ENOMEM;
3743 }
3744
3745 /* Alloc memory for multicast/mirror replication entries */
3746 err = qmem_alloc(rvu->dev, &mcast->mce_ctx,
3747 mcast->mce_counter[NIX_MCAST_INGRESS].max, size);
3748 if (err) {
3749 rvu_free_bitmap(&mcast->mce_counter[NIX_MCAST_INGRESS]);
3750 rvu_free_bitmap(&mcast->mce_counter[NIX_MCAST_EGRESS]);
3751 return -ENOMEM;
3752 }
3753
3754 rvu_write64(rvu, blkaddr, NIX_AF_RX_MCAST_BASE,
3755 (u64)mcast->mce_ctx->iova);
3756
3757 /* Set max list length equal to max no of VFs per PF + PF itself */
3758 rvu_write64(rvu, blkaddr, NIX_AF_RX_MCAST_CFG,
3759 BIT_ULL(36) | (hw->max_vfs_per_pf << 4) | MC_TBL_SIZE);
3760
3761 /* Alloc memory for multicast replication buffers */
3762 size = rvu_read64(rvu, blkaddr, NIX_AF_MC_MIRROR_CONST) & 0xFFFF;
3763 err = qmem_alloc(rvu->dev, &mcast->mcast_buf,
3764 (8UL << MC_BUF_CNT), size);
3765 if (err) {
3766 rvu_free_bitmap(&mcast->mce_counter[NIX_MCAST_INGRESS]);
3767 rvu_free_bitmap(&mcast->mce_counter[NIX_MCAST_EGRESS]);
3768 return -ENOMEM;
3769 }
3770
3771 rvu_write64(rvu, blkaddr, NIX_AF_RX_MCAST_BUF_BASE,
3772 (u64)mcast->mcast_buf->iova);
3773
3774 /* Alloc pkind for NIX internal RX multicast/mirror replay */
3775 mcast->replay_pkind = rvu_alloc_rsrc(&hw->pkind.rsrc);
3776
3777 rvu_write64(rvu, blkaddr, NIX_AF_RX_MCAST_BUF_CFG,
3778 BIT_ULL(63) | (mcast->replay_pkind << 24) |
3779 BIT_ULL(20) | MC_BUF_CNT);
3780
3781 mutex_init(&mcast->mce_lock);
3782
3783 nix_setup_mcast_grp(nix_hw);
3784
3785 return nix_setup_mce_tables(rvu, nix_hw);
3786 }
3787
nix_setup_txvlan(struct rvu * rvu,struct nix_hw * nix_hw)3788 static int nix_setup_txvlan(struct rvu *rvu, struct nix_hw *nix_hw)
3789 {
3790 struct nix_txvlan *vlan = &nix_hw->txvlan;
3791 int err;
3792
3793 /* Allocate resource bimap for tx vtag def registers*/
3794 vlan->rsrc.max = NIX_TX_VTAG_DEF_MAX;
3795 err = rvu_alloc_bitmap(&vlan->rsrc);
3796 if (err)
3797 return -ENOMEM;
3798
3799 /* Alloc memory for saving entry to RVU PFFUNC allocation mapping */
3800 vlan->entry2pfvf_map = devm_kcalloc(rvu->dev, vlan->rsrc.max,
3801 sizeof(u16), GFP_KERNEL);
3802 if (!vlan->entry2pfvf_map)
3803 goto free_mem;
3804
3805 mutex_init(&vlan->rsrc_lock);
3806 return 0;
3807
3808 free_mem:
3809 kfree(vlan->rsrc.bmap);
3810 return -ENOMEM;
3811 }
3812
nix_setup_txschq(struct rvu * rvu,struct nix_hw * nix_hw,int blkaddr)3813 static int nix_setup_txschq(struct rvu *rvu, struct nix_hw *nix_hw, int blkaddr)
3814 {
3815 struct nix_txsch *txsch;
3816 int err, lvl, schq;
3817 u64 cfg, reg;
3818
3819 /* Get scheduler queue count of each type and alloc
3820 * bitmap for each for alloc/free/attach operations.
3821 */
3822 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
3823 txsch = &nix_hw->txsch[lvl];
3824 txsch->lvl = lvl;
3825 switch (lvl) {
3826 case NIX_TXSCH_LVL_SMQ:
3827 reg = NIX_AF_MDQ_CONST;
3828 break;
3829 case NIX_TXSCH_LVL_TL4:
3830 reg = NIX_AF_TL4_CONST;
3831 break;
3832 case NIX_TXSCH_LVL_TL3:
3833 reg = NIX_AF_TL3_CONST;
3834 break;
3835 case NIX_TXSCH_LVL_TL2:
3836 reg = NIX_AF_TL2_CONST;
3837 break;
3838 case NIX_TXSCH_LVL_TL1:
3839 reg = NIX_AF_TL1_CONST;
3840 break;
3841 }
3842 cfg = rvu_read64(rvu, blkaddr, reg);
3843 txsch->schq.max = cfg & 0xFFFF;
3844 err = rvu_alloc_bitmap(&txsch->schq);
3845 if (err)
3846 return err;
3847
3848 /* Allocate memory for scheduler queues to
3849 * PF/VF pcifunc mapping info.
3850 */
3851 txsch->pfvf_map = devm_kcalloc(rvu->dev, txsch->schq.max,
3852 sizeof(u32), GFP_KERNEL);
3853 if (!txsch->pfvf_map)
3854 return -ENOMEM;
3855 for (schq = 0; schq < txsch->schq.max; schq++)
3856 txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE);
3857 }
3858
3859 /* Setup a default value of 8192 as DWRR MTU */
3860 if (rvu->hw->cap.nix_common_dwrr_mtu ||
3861 rvu->hw->cap.nix_multiple_dwrr_mtu) {
3862 rvu_write64(rvu, blkaddr,
3863 nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM),
3864 convert_bytes_to_dwrr_mtu(8192));
3865 rvu_write64(rvu, blkaddr,
3866 nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_LBK),
3867 convert_bytes_to_dwrr_mtu(8192));
3868 rvu_write64(rvu, blkaddr,
3869 nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_SDP),
3870 convert_bytes_to_dwrr_mtu(8192));
3871 }
3872
3873 return 0;
3874 }
3875
rvu_nix_reserve_mark_format(struct rvu * rvu,struct nix_hw * nix_hw,int blkaddr,u32 cfg)3876 int rvu_nix_reserve_mark_format(struct rvu *rvu, struct nix_hw *nix_hw,
3877 int blkaddr, u32 cfg)
3878 {
3879 int fmt_idx;
3880
3881 for (fmt_idx = 0; fmt_idx < nix_hw->mark_format.in_use; fmt_idx++) {
3882 if (nix_hw->mark_format.cfg[fmt_idx] == cfg)
3883 return fmt_idx;
3884 }
3885 if (fmt_idx >= nix_hw->mark_format.total)
3886 return -ERANGE;
3887
3888 rvu_write64(rvu, blkaddr, NIX_AF_MARK_FORMATX_CTL(fmt_idx), cfg);
3889 nix_hw->mark_format.cfg[fmt_idx] = cfg;
3890 nix_hw->mark_format.in_use++;
3891 return fmt_idx;
3892 }
3893
nix_af_mark_format_setup(struct rvu * rvu,struct nix_hw * nix_hw,int blkaddr)3894 static int nix_af_mark_format_setup(struct rvu *rvu, struct nix_hw *nix_hw,
3895 int blkaddr)
3896 {
3897 u64 cfgs[] = {
3898 [NIX_MARK_CFG_IP_DSCP_RED] = 0x10003,
3899 [NIX_MARK_CFG_IP_DSCP_YELLOW] = 0x11200,
3900 [NIX_MARK_CFG_IP_DSCP_YELLOW_RED] = 0x11203,
3901 [NIX_MARK_CFG_IP_ECN_RED] = 0x6000c,
3902 [NIX_MARK_CFG_IP_ECN_YELLOW] = 0x60c00,
3903 [NIX_MARK_CFG_IP_ECN_YELLOW_RED] = 0x60c0c,
3904 [NIX_MARK_CFG_VLAN_DEI_RED] = 0x30008,
3905 [NIX_MARK_CFG_VLAN_DEI_YELLOW] = 0x30800,
3906 [NIX_MARK_CFG_VLAN_DEI_YELLOW_RED] = 0x30808,
3907 };
3908 int i, rc;
3909 u64 total;
3910
3911 total = (rvu_read64(rvu, blkaddr, NIX_AF_PSE_CONST) & 0xFF00) >> 8;
3912 nix_hw->mark_format.total = (u8)total;
3913 nix_hw->mark_format.cfg = devm_kcalloc(rvu->dev, total, sizeof(u32),
3914 GFP_KERNEL);
3915 if (!nix_hw->mark_format.cfg)
3916 return -ENOMEM;
3917 for (i = 0; i < NIX_MARK_CFG_MAX; i++) {
3918 rc = rvu_nix_reserve_mark_format(rvu, nix_hw, blkaddr, cfgs[i]);
3919 if (rc < 0)
3920 dev_err(rvu->dev, "Err %d in setup mark format %d\n",
3921 i, rc);
3922 }
3923
3924 return 0;
3925 }
3926
rvu_get_lbk_link_max_frs(struct rvu * rvu,u16 * max_mtu)3927 static void rvu_get_lbk_link_max_frs(struct rvu *rvu, u16 *max_mtu)
3928 {
3929 /* CN10K supports LBK FIFO size 72 KB */
3930 if (rvu->hw->lbk_bufsize == 0x12000)
3931 *max_mtu = CN10K_LBK_LINK_MAX_FRS;
3932 else
3933 *max_mtu = NIC_HW_MAX_FRS;
3934 }
3935
rvu_get_lmac_link_max_frs(struct rvu * rvu,u16 * max_mtu)3936 static void rvu_get_lmac_link_max_frs(struct rvu *rvu, u16 *max_mtu)
3937 {
3938 int fifo_size = rvu_cgx_get_fifolen(rvu);
3939
3940 /* RPM supports FIFO len 128 KB and RPM2 supports double the
3941 * FIFO len to accommodate 8 LMACS
3942 */
3943 if (fifo_size == 0x20000 || fifo_size == 0x40000)
3944 *max_mtu = CN10K_LMAC_LINK_MAX_FRS;
3945 else
3946 *max_mtu = NIC_HW_MAX_FRS;
3947 }
3948
rvu_mbox_handler_nix_get_hw_info(struct rvu * rvu,struct msg_req * req,struct nix_hw_info * rsp)3949 int rvu_mbox_handler_nix_get_hw_info(struct rvu *rvu, struct msg_req *req,
3950 struct nix_hw_info *rsp)
3951 {
3952 u16 pcifunc = req->hdr.pcifunc;
3953 u64 dwrr_mtu;
3954 int blkaddr;
3955
3956 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
3957 if (blkaddr < 0)
3958 return NIX_AF_ERR_AF_LF_INVALID;
3959
3960 rsp->vwqe_delay = 0;
3961 if (!is_rvu_otx2(rvu))
3962 rsp->vwqe_delay = rvu_read64(rvu, blkaddr, NIX_AF_VWQE_TIMER) &
3963 GENMASK_ULL(9, 0);
3964
3965 if (is_lbk_vf(rvu, pcifunc))
3966 rvu_get_lbk_link_max_frs(rvu, &rsp->max_mtu);
3967 else
3968 rvu_get_lmac_link_max_frs(rvu, &rsp->max_mtu);
3969
3970 rsp->min_mtu = NIC_HW_MIN_FRS;
3971
3972 if (!rvu->hw->cap.nix_common_dwrr_mtu &&
3973 !rvu->hw->cap.nix_multiple_dwrr_mtu) {
3974 /* Return '1' on OTx2 */
3975 rsp->rpm_dwrr_mtu = 1;
3976 rsp->sdp_dwrr_mtu = 1;
3977 rsp->lbk_dwrr_mtu = 1;
3978 return 0;
3979 }
3980
3981 /* Return DWRR_MTU for TLx_SCHEDULE[RR_WEIGHT] config */
3982 dwrr_mtu = rvu_read64(rvu, blkaddr,
3983 nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM));
3984 rsp->rpm_dwrr_mtu = convert_dwrr_mtu_to_bytes(dwrr_mtu);
3985
3986 dwrr_mtu = rvu_read64(rvu, blkaddr,
3987 nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_SDP));
3988 rsp->sdp_dwrr_mtu = convert_dwrr_mtu_to_bytes(dwrr_mtu);
3989
3990 dwrr_mtu = rvu_read64(rvu, blkaddr,
3991 nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_LBK));
3992 rsp->lbk_dwrr_mtu = convert_dwrr_mtu_to_bytes(dwrr_mtu);
3993
3994 return 0;
3995 }
3996
rvu_mbox_handler_nix_stats_rst(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)3997 int rvu_mbox_handler_nix_stats_rst(struct rvu *rvu, struct msg_req *req,
3998 struct msg_rsp *rsp)
3999 {
4000 u16 pcifunc = req->hdr.pcifunc;
4001 int i, nixlf, blkaddr, err;
4002 u64 stats;
4003
4004 err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
4005 if (err)
4006 return err;
4007
4008 /* Get stats count supported by HW */
4009 stats = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
4010
4011 /* Reset tx stats */
4012 for (i = 0; i < ((stats >> 24) & 0xFF); i++)
4013 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_STATX(nixlf, i), 0);
4014
4015 /* Reset rx stats */
4016 for (i = 0; i < ((stats >> 32) & 0xFF); i++)
4017 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_STATX(nixlf, i), 0);
4018
4019 return 0;
4020 }
4021
4022 /* Returns the ALG index to be set into NPC_RX_ACTION */
get_flowkey_alg_idx(struct nix_hw * nix_hw,u32 flow_cfg)4023 static int get_flowkey_alg_idx(struct nix_hw *nix_hw, u32 flow_cfg)
4024 {
4025 int i;
4026
4027 /* Scan over exiting algo entries to find a match */
4028 for (i = 0; i < nix_hw->flowkey.in_use; i++)
4029 if (nix_hw->flowkey.flowkey[i] == flow_cfg)
4030 return i;
4031
4032 return -ERANGE;
4033 }
4034
4035 /* Mask to match ipv6(NPC_LT_LC_IP6) and ipv6 ext(NPC_LT_LC_IP6_EXT) */
4036 #define NPC_LT_LC_IP6_MATCH_MSK ((~(NPC_LT_LC_IP6 ^ NPC_LT_LC_IP6_EXT)) & 0xf)
4037 /* Mask to match both ipv4(NPC_LT_LC_IP) and ipv4 ext(NPC_LT_LC_IP_OPT) */
4038 #define NPC_LT_LC_IP_MATCH_MSK ((~(NPC_LT_LC_IP ^ NPC_LT_LC_IP_OPT)) & 0xf)
4039
set_flowkey_fields(struct nix_rx_flowkey_alg * alg,u32 flow_cfg)4040 static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
4041 {
4042 int idx, nr_field, key_off, field_marker, keyoff_marker;
4043 int max_key_off, max_bit_pos, group_member;
4044 struct nix_rx_flowkey_alg *field;
4045 struct nix_rx_flowkey_alg tmp;
4046 u32 key_type, valid_key;
4047 u32 l3_l4_src_dst;
4048 int l4_key_offset = 0;
4049
4050 if (!alg)
4051 return -EINVAL;
4052
4053 #define FIELDS_PER_ALG 5
4054 #define MAX_KEY_OFF 40
4055 /* Clear all fields */
4056 memset(alg, 0, sizeof(uint64_t) * FIELDS_PER_ALG);
4057
4058 /* Each of the 32 possible flow key algorithm definitions should
4059 * fall into above incremental config (except ALG0). Otherwise a
4060 * single NPC MCAM entry is not sufficient for supporting RSS.
4061 *
4062 * If a different definition or combination needed then NPC MCAM
4063 * has to be programmed to filter such pkts and it's action should
4064 * point to this definition to calculate flowtag or hash.
4065 *
4066 * The `for loop` goes over _all_ protocol field and the following
4067 * variables depicts the state machine forward progress logic.
4068 *
4069 * keyoff_marker - Enabled when hash byte length needs to be accounted
4070 * in field->key_offset update.
4071 * field_marker - Enabled when a new field needs to be selected.
4072 * group_member - Enabled when protocol is part of a group.
4073 */
4074
4075 /* Last 4 bits (31:28) are reserved to specify SRC, DST
4076 * selection for L3, L4 i.e IPV[4,6]_SRC, IPV[4,6]_DST,
4077 * [TCP,UDP,SCTP]_SRC, [TCP,UDP,SCTP]_DST
4078 * 31 => L3_SRC, 30 => L3_DST, 29 => L4_SRC, 28 => L4_DST
4079 */
4080 l3_l4_src_dst = flow_cfg;
4081 /* Reset these 4 bits, so that these won't be part of key */
4082 flow_cfg &= NIX_FLOW_KEY_TYPE_L3_L4_MASK;
4083
4084 keyoff_marker = 0; max_key_off = 0; group_member = 0;
4085 nr_field = 0; key_off = 0; field_marker = 1;
4086 field = &tmp; max_bit_pos = fls(flow_cfg);
4087 for (idx = 0;
4088 idx < max_bit_pos && nr_field < FIELDS_PER_ALG &&
4089 key_off < MAX_KEY_OFF; idx++) {
4090 key_type = BIT(idx);
4091 valid_key = flow_cfg & key_type;
4092 /* Found a field marker, reset the field values */
4093 if (field_marker)
4094 memset(&tmp, 0, sizeof(tmp));
4095
4096 field_marker = true;
4097 keyoff_marker = true;
4098 switch (key_type) {
4099 case NIX_FLOW_KEY_TYPE_PORT:
4100 field->sel_chan = true;
4101 /* This should be set to 1, when SEL_CHAN is set */
4102 field->bytesm1 = 1;
4103 break;
4104 case NIX_FLOW_KEY_TYPE_IPV4_PROTO:
4105 field->lid = NPC_LID_LC;
4106 field->hdr_offset = 9; /* offset */
4107 field->bytesm1 = 0; /* 1 byte */
4108 field->ltype_match = NPC_LT_LC_IP;
4109 field->ltype_mask = NPC_LT_LC_IP_MATCH_MSK;
4110 break;
4111 case NIX_FLOW_KEY_TYPE_IPV4:
4112 case NIX_FLOW_KEY_TYPE_INNR_IPV4:
4113 field->lid = NPC_LID_LC;
4114 field->ltype_match = NPC_LT_LC_IP;
4115 if (key_type == NIX_FLOW_KEY_TYPE_INNR_IPV4) {
4116 field->lid = NPC_LID_LG;
4117 field->ltype_match = NPC_LT_LG_TU_IP;
4118 }
4119 field->hdr_offset = 12; /* SIP offset */
4120 field->bytesm1 = 7; /* SIP + DIP, 8 bytes */
4121
4122 /* Only SIP */
4123 if (l3_l4_src_dst & NIX_FLOW_KEY_TYPE_L3_SRC_ONLY)
4124 field->bytesm1 = 3; /* SIP, 4 bytes */
4125
4126 if (l3_l4_src_dst & NIX_FLOW_KEY_TYPE_L3_DST_ONLY) {
4127 /* Both SIP + DIP */
4128 if (field->bytesm1 == 3) {
4129 field->bytesm1 = 7; /* SIP + DIP, 8B */
4130 } else {
4131 /* Only DIP */
4132 field->hdr_offset = 16; /* DIP off */
4133 field->bytesm1 = 3; /* DIP, 4 bytes */
4134 }
4135 }
4136 field->ltype_mask = NPC_LT_LC_IP_MATCH_MSK;
4137 keyoff_marker = false;
4138 break;
4139 case NIX_FLOW_KEY_TYPE_IPV6:
4140 case NIX_FLOW_KEY_TYPE_INNR_IPV6:
4141 field->lid = NPC_LID_LC;
4142 field->ltype_match = NPC_LT_LC_IP6;
4143 if (key_type == NIX_FLOW_KEY_TYPE_INNR_IPV6) {
4144 field->lid = NPC_LID_LG;
4145 field->ltype_match = NPC_LT_LG_TU_IP6;
4146 }
4147 field->hdr_offset = 8; /* SIP offset */
4148 field->bytesm1 = 31; /* SIP + DIP, 32 bytes */
4149
4150 /* Only SIP */
4151 if (l3_l4_src_dst & NIX_FLOW_KEY_TYPE_L3_SRC_ONLY)
4152 field->bytesm1 = 15; /* SIP, 16 bytes */
4153
4154 if (l3_l4_src_dst & NIX_FLOW_KEY_TYPE_L3_DST_ONLY) {
4155 /* Both SIP + DIP */
4156 if (field->bytesm1 == 15) {
4157 /* SIP + DIP, 32 bytes */
4158 field->bytesm1 = 31;
4159 } else {
4160 /* Only DIP */
4161 field->hdr_offset = 24; /* DIP off */
4162 field->bytesm1 = 15; /* DIP,16 bytes */
4163 }
4164 }
4165 field->ltype_mask = NPC_LT_LC_IP6_MATCH_MSK;
4166 break;
4167 case NIX_FLOW_KEY_TYPE_TCP:
4168 case NIX_FLOW_KEY_TYPE_UDP:
4169 case NIX_FLOW_KEY_TYPE_SCTP:
4170 case NIX_FLOW_KEY_TYPE_INNR_TCP:
4171 case NIX_FLOW_KEY_TYPE_INNR_UDP:
4172 case NIX_FLOW_KEY_TYPE_INNR_SCTP:
4173 field->lid = NPC_LID_LD;
4174 if (key_type == NIX_FLOW_KEY_TYPE_INNR_TCP ||
4175 key_type == NIX_FLOW_KEY_TYPE_INNR_UDP ||
4176 key_type == NIX_FLOW_KEY_TYPE_INNR_SCTP)
4177 field->lid = NPC_LID_LH;
4178 field->bytesm1 = 3; /* Sport + Dport, 4 bytes */
4179
4180 if (l3_l4_src_dst & NIX_FLOW_KEY_TYPE_L4_SRC_ONLY)
4181 field->bytesm1 = 1; /* SRC, 2 bytes */
4182
4183 if (l3_l4_src_dst & NIX_FLOW_KEY_TYPE_L4_DST_ONLY) {
4184 /* Both SRC + DST */
4185 if (field->bytesm1 == 1) {
4186 /* SRC + DST, 4 bytes */
4187 field->bytesm1 = 3;
4188 } else {
4189 /* Only DIP */
4190 field->hdr_offset = 2; /* DST off */
4191 field->bytesm1 = 1; /* DST, 2 bytes */
4192 }
4193 }
4194
4195 /* Enum values for NPC_LID_LD and NPC_LID_LG are same,
4196 * so no need to change the ltype_match, just change
4197 * the lid for inner protocols
4198 */
4199 BUILD_BUG_ON((int)NPC_LT_LD_TCP !=
4200 (int)NPC_LT_LH_TU_TCP);
4201 BUILD_BUG_ON((int)NPC_LT_LD_UDP !=
4202 (int)NPC_LT_LH_TU_UDP);
4203 BUILD_BUG_ON((int)NPC_LT_LD_SCTP !=
4204 (int)NPC_LT_LH_TU_SCTP);
4205
4206 if ((key_type == NIX_FLOW_KEY_TYPE_TCP ||
4207 key_type == NIX_FLOW_KEY_TYPE_INNR_TCP) &&
4208 valid_key) {
4209 field->ltype_match |= NPC_LT_LD_TCP;
4210 group_member = true;
4211 } else if ((key_type == NIX_FLOW_KEY_TYPE_UDP ||
4212 key_type == NIX_FLOW_KEY_TYPE_INNR_UDP) &&
4213 valid_key) {
4214 field->ltype_match |= NPC_LT_LD_UDP;
4215 group_member = true;
4216 } else if ((key_type == NIX_FLOW_KEY_TYPE_SCTP ||
4217 key_type == NIX_FLOW_KEY_TYPE_INNR_SCTP) &&
4218 valid_key) {
4219 field->ltype_match |= NPC_LT_LD_SCTP;
4220 group_member = true;
4221 }
4222 field->ltype_mask = ~field->ltype_match;
4223 if (key_type == NIX_FLOW_KEY_TYPE_SCTP ||
4224 key_type == NIX_FLOW_KEY_TYPE_INNR_SCTP) {
4225 /* Handle the case where any of the group item
4226 * is enabled in the group but not the final one
4227 */
4228 if (group_member) {
4229 valid_key = true;
4230 group_member = false;
4231 }
4232 } else {
4233 field_marker = false;
4234 keyoff_marker = false;
4235 }
4236
4237 /* TCP/UDP/SCTP and ESP/AH falls at same offset so
4238 * remember the TCP key offset of 40 byte hash key.
4239 */
4240 if (key_type == NIX_FLOW_KEY_TYPE_TCP)
4241 l4_key_offset = key_off;
4242 break;
4243 case NIX_FLOW_KEY_TYPE_NVGRE:
4244 field->lid = NPC_LID_LD;
4245 field->hdr_offset = 4; /* VSID offset */
4246 field->bytesm1 = 2;
4247 field->ltype_match = NPC_LT_LD_NVGRE;
4248 field->ltype_mask = 0xF;
4249 break;
4250 case NIX_FLOW_KEY_TYPE_VXLAN:
4251 case NIX_FLOW_KEY_TYPE_GENEVE:
4252 field->lid = NPC_LID_LE;
4253 field->bytesm1 = 2;
4254 field->hdr_offset = 4;
4255 field->ltype_mask = 0xF;
4256 field_marker = false;
4257 keyoff_marker = false;
4258
4259 if (key_type == NIX_FLOW_KEY_TYPE_VXLAN && valid_key) {
4260 field->ltype_match |= NPC_LT_LE_VXLAN;
4261 group_member = true;
4262 }
4263
4264 if (key_type == NIX_FLOW_KEY_TYPE_GENEVE && valid_key) {
4265 field->ltype_match |= NPC_LT_LE_GENEVE;
4266 group_member = true;
4267 }
4268
4269 if (key_type == NIX_FLOW_KEY_TYPE_GENEVE) {
4270 if (group_member) {
4271 field->ltype_mask = ~field->ltype_match;
4272 field_marker = true;
4273 keyoff_marker = true;
4274 valid_key = true;
4275 group_member = false;
4276 }
4277 }
4278 break;
4279 case NIX_FLOW_KEY_TYPE_ETH_DMAC:
4280 case NIX_FLOW_KEY_TYPE_INNR_ETH_DMAC:
4281 field->lid = NPC_LID_LA;
4282 field->ltype_match = NPC_LT_LA_ETHER;
4283 if (key_type == NIX_FLOW_KEY_TYPE_INNR_ETH_DMAC) {
4284 field->lid = NPC_LID_LF;
4285 field->ltype_match = NPC_LT_LF_TU_ETHER;
4286 }
4287 field->hdr_offset = 0;
4288 field->bytesm1 = 5; /* DMAC 6 Byte */
4289 field->ltype_mask = 0xF;
4290 break;
4291 case NIX_FLOW_KEY_TYPE_IPV6_EXT:
4292 field->lid = NPC_LID_LC;
4293 field->hdr_offset = 40; /* IPV6 hdr */
4294 field->bytesm1 = 0; /* 1 Byte ext hdr*/
4295 field->ltype_match = NPC_LT_LC_IP6_EXT;
4296 field->ltype_mask = 0xF;
4297 break;
4298 case NIX_FLOW_KEY_TYPE_GTPU:
4299 field->lid = NPC_LID_LE;
4300 field->hdr_offset = 4;
4301 field->bytesm1 = 3; /* 4 bytes TID*/
4302 field->ltype_match = NPC_LT_LE_GTPU;
4303 field->ltype_mask = 0xF;
4304 break;
4305 case NIX_FLOW_KEY_TYPE_CUSTOM0:
4306 field->lid = NPC_LID_LC;
4307 field->hdr_offset = 6;
4308 field->bytesm1 = 1; /* 2 Bytes*/
4309 field->ltype_match = NPC_LT_LC_CUSTOM0;
4310 field->ltype_mask = 0xF;
4311 break;
4312 case NIX_FLOW_KEY_TYPE_CH_LEN_90B:
4313 field->lid = NPC_LID_LA;
4314 field->hdr_offset = 24;
4315 field->bytesm1 = 1; /* 2 Bytes*/
4316 field->ltype_match = NPC_LT_LA_CUSTOM_L2_90B_ETHER;
4317 field->ltype_mask = 0xF;
4318 break;
4319 case NIX_FLOW_KEY_TYPE_VLAN:
4320 field->lid = NPC_LID_LB;
4321 field->hdr_offset = 2; /* Skip TPID (2-bytes) */
4322 field->bytesm1 = 1; /* 2 Bytes (Actually 12 bits) */
4323 field->ltype_match = NPC_LT_LB_CTAG;
4324 field->ltype_mask = 0xF;
4325 field->fn_mask = 1; /* Mask out the first nibble */
4326 break;
4327 case NIX_FLOW_KEY_TYPE_AH:
4328 case NIX_FLOW_KEY_TYPE_ESP:
4329 field->hdr_offset = 0;
4330 field->bytesm1 = 7; /* SPI + sequence number */
4331 field->ltype_mask = 0xF;
4332 field->lid = NPC_LID_LE;
4333 field->ltype_match = NPC_LT_LE_ESP;
4334 if (key_type == NIX_FLOW_KEY_TYPE_AH) {
4335 field->lid = NPC_LID_LD;
4336 field->ltype_match = NPC_LT_LD_AH;
4337 field->hdr_offset = 4;
4338 keyoff_marker = false;
4339 }
4340 break;
4341 case NIX_FLOW_KEY_TYPE_ROCEV2:
4342 field->hdr_offset = 5;
4343 field->bytesm1 = 2; /* Destination QP */
4344 field->ltype_mask = 0xF;
4345 field->lid = NPC_LID_LE;
4346 field->ltype_match = NPC_LT_LE_ROCEV2;
4347 break;
4348 }
4349 field->ena = 1;
4350
4351 /* Found a valid flow key type */
4352 if (valid_key) {
4353 /* Use the key offset of TCP/UDP/SCTP fields
4354 * for ESP/AH fields.
4355 */
4356 if (key_type == NIX_FLOW_KEY_TYPE_ESP ||
4357 key_type == NIX_FLOW_KEY_TYPE_AH)
4358 key_off = l4_key_offset;
4359 field->key_offset = key_off;
4360 memcpy(&alg[nr_field], field, sizeof(*field));
4361 max_key_off = max(max_key_off, field->bytesm1 + 1);
4362
4363 /* Found a field marker, get the next field */
4364 if (field_marker)
4365 nr_field++;
4366 }
4367
4368 /* Found a keyoff marker, update the new key_off */
4369 if (keyoff_marker) {
4370 key_off += max_key_off;
4371 max_key_off = 0;
4372 }
4373 }
4374 /* Processed all the flow key types */
4375 if (idx == max_bit_pos && key_off <= MAX_KEY_OFF)
4376 return 0;
4377 else
4378 return NIX_AF_ERR_RSS_NOSPC_FIELD;
4379 }
4380
reserve_flowkey_alg_idx(struct rvu * rvu,int blkaddr,u32 flow_cfg)4381 static int reserve_flowkey_alg_idx(struct rvu *rvu, int blkaddr, u32 flow_cfg)
4382 {
4383 u64 field[FIELDS_PER_ALG];
4384 struct nix_hw *hw;
4385 int fid, rc;
4386
4387 hw = get_nix_hw(rvu->hw, blkaddr);
4388 if (!hw)
4389 return NIX_AF_ERR_INVALID_NIXBLK;
4390
4391 /* No room to add new flow hash algoritham */
4392 if (hw->flowkey.in_use >= NIX_FLOW_KEY_ALG_MAX)
4393 return NIX_AF_ERR_RSS_NOSPC_ALGO;
4394
4395 /* Generate algo fields for the given flow_cfg */
4396 rc = set_flowkey_fields((struct nix_rx_flowkey_alg *)field, flow_cfg);
4397 if (rc)
4398 return rc;
4399
4400 /* Update ALGX_FIELDX register with generated fields */
4401 for (fid = 0; fid < FIELDS_PER_ALG; fid++)
4402 rvu_write64(rvu, blkaddr,
4403 NIX_AF_RX_FLOW_KEY_ALGX_FIELDX(hw->flowkey.in_use,
4404 fid), field[fid]);
4405
4406 /* Store the flow_cfg for futher lookup */
4407 rc = hw->flowkey.in_use;
4408 hw->flowkey.flowkey[rc] = flow_cfg;
4409 hw->flowkey.in_use++;
4410
4411 return rc;
4412 }
4413
rvu_mbox_handler_nix_rss_flowkey_cfg(struct rvu * rvu,struct nix_rss_flowkey_cfg * req,struct nix_rss_flowkey_cfg_rsp * rsp)4414 int rvu_mbox_handler_nix_rss_flowkey_cfg(struct rvu *rvu,
4415 struct nix_rss_flowkey_cfg *req,
4416 struct nix_rss_flowkey_cfg_rsp *rsp)
4417 {
4418 u16 pcifunc = req->hdr.pcifunc;
4419 int alg_idx, nixlf, blkaddr;
4420 struct nix_hw *nix_hw;
4421 int err;
4422
4423 err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
4424 if (err)
4425 return err;
4426
4427 nix_hw = get_nix_hw(rvu->hw, blkaddr);
4428 if (!nix_hw)
4429 return NIX_AF_ERR_INVALID_NIXBLK;
4430
4431 alg_idx = get_flowkey_alg_idx(nix_hw, req->flowkey_cfg);
4432 /* Failed to get algo index from the exiting list, reserve new */
4433 if (alg_idx < 0) {
4434 alg_idx = reserve_flowkey_alg_idx(rvu, blkaddr,
4435 req->flowkey_cfg);
4436 if (alg_idx < 0)
4437 return alg_idx;
4438 }
4439 rsp->alg_idx = alg_idx;
4440 rvu_npc_update_flowkey_alg_idx(rvu, pcifunc, nixlf, req->group,
4441 alg_idx, req->mcam_index);
4442 return 0;
4443 }
4444
nix_rx_flowkey_alg_cfg(struct rvu * rvu,int blkaddr)4445 static int nix_rx_flowkey_alg_cfg(struct rvu *rvu, int blkaddr)
4446 {
4447 u32 flowkey_cfg, minkey_cfg;
4448 int alg, fid, rc;
4449
4450 /* Disable all flow key algx fieldx */
4451 for (alg = 0; alg < NIX_FLOW_KEY_ALG_MAX; alg++) {
4452 for (fid = 0; fid < FIELDS_PER_ALG; fid++)
4453 rvu_write64(rvu, blkaddr,
4454 NIX_AF_RX_FLOW_KEY_ALGX_FIELDX(alg, fid),
4455 0);
4456 }
4457
4458 /* IPv4/IPv6 SIP/DIPs */
4459 flowkey_cfg = NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6;
4460 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4461 if (rc < 0)
4462 return rc;
4463
4464 /* TCPv4/v6 4-tuple, SIP, DIP, Sport, Dport */
4465 minkey_cfg = flowkey_cfg;
4466 flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP;
4467 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4468 if (rc < 0)
4469 return rc;
4470
4471 /* UDPv4/v6 4-tuple, SIP, DIP, Sport, Dport */
4472 flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_UDP;
4473 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4474 if (rc < 0)
4475 return rc;
4476
4477 /* SCTPv4/v6 4-tuple, SIP, DIP, Sport, Dport */
4478 flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_SCTP;
4479 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4480 if (rc < 0)
4481 return rc;
4482
4483 /* TCP/UDP v4/v6 4-tuple, rest IP pkts 2-tuple */
4484 flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP |
4485 NIX_FLOW_KEY_TYPE_UDP;
4486 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4487 if (rc < 0)
4488 return rc;
4489
4490 /* TCP/SCTP v4/v6 4-tuple, rest IP pkts 2-tuple */
4491 flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP |
4492 NIX_FLOW_KEY_TYPE_SCTP;
4493 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4494 if (rc < 0)
4495 return rc;
4496
4497 /* UDP/SCTP v4/v6 4-tuple, rest IP pkts 2-tuple */
4498 flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_UDP |
4499 NIX_FLOW_KEY_TYPE_SCTP;
4500 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4501 if (rc < 0)
4502 return rc;
4503
4504 /* TCP/UDP/SCTP v4/v6 4-tuple, rest IP pkts 2-tuple */
4505 flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP |
4506 NIX_FLOW_KEY_TYPE_UDP | NIX_FLOW_KEY_TYPE_SCTP;
4507 rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
4508 if (rc < 0)
4509 return rc;
4510
4511 return 0;
4512 }
4513
rvu_mbox_handler_nix_set_mac_addr(struct rvu * rvu,struct nix_set_mac_addr * req,struct msg_rsp * rsp)4514 int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
4515 struct nix_set_mac_addr *req,
4516 struct msg_rsp *rsp)
4517 {
4518 bool from_vf = req->hdr.pcifunc & RVU_PFVF_FUNC_MASK;
4519 u16 pcifunc = req->hdr.pcifunc;
4520 int blkaddr, nixlf, err;
4521 struct rvu_pfvf *pfvf;
4522
4523 err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
4524 if (err)
4525 return err;
4526
4527 pfvf = rvu_get_pfvf(rvu, pcifunc);
4528
4529 /* untrusted VF can't overwrite admin(PF) changes */
4530 if (!test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) &&
4531 (from_vf && test_bit(PF_SET_VF_MAC, &pfvf->flags))) {
4532 dev_warn(rvu->dev,
4533 "MAC address set by admin(PF) cannot be overwritten by untrusted VF");
4534 return -EPERM;
4535 }
4536
4537 ether_addr_copy(pfvf->mac_addr, req->mac_addr);
4538
4539 rvu_npc_install_ucast_entry(rvu, pcifunc, nixlf,
4540 pfvf->rx_chan_base, req->mac_addr);
4541
4542 if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf)
4543 ether_addr_copy(pfvf->default_mac, req->mac_addr);
4544
4545 return 0;
4546 }
4547
rvu_mbox_handler_nix_get_mac_addr(struct rvu * rvu,struct msg_req * req,struct nix_get_mac_addr_rsp * rsp)4548 int rvu_mbox_handler_nix_get_mac_addr(struct rvu *rvu,
4549 struct msg_req *req,
4550 struct nix_get_mac_addr_rsp *rsp)
4551 {
4552 u16 pcifunc = req->hdr.pcifunc;
4553 struct rvu_pfvf *pfvf;
4554
4555 if (!is_nixlf_attached(rvu, pcifunc))
4556 return NIX_AF_ERR_AF_LF_INVALID;
4557
4558 pfvf = rvu_get_pfvf(rvu, pcifunc);
4559
4560 ether_addr_copy(rsp->mac_addr, pfvf->mac_addr);
4561
4562 return 0;
4563 }
4564
rvu_mbox_handler_nix_set_rx_mode(struct rvu * rvu,struct nix_rx_mode * req,struct msg_rsp * rsp)4565 int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
4566 struct msg_rsp *rsp)
4567 {
4568 bool allmulti, promisc, nix_rx_multicast;
4569 u16 pcifunc = req->hdr.pcifunc;
4570 struct rvu_pfvf *pfvf;
4571 int nixlf, err;
4572
4573 pfvf = rvu_get_pfvf(rvu, pcifunc);
4574 promisc = req->mode & NIX_RX_MODE_PROMISC ? true : false;
4575 allmulti = req->mode & NIX_RX_MODE_ALLMULTI ? true : false;
4576 pfvf->use_mce_list = req->mode & NIX_RX_MODE_USE_MCE ? true : false;
4577
4578 nix_rx_multicast = rvu->hw->cap.nix_rx_multicast & pfvf->use_mce_list;
4579
4580 if (is_vf(pcifunc) && !nix_rx_multicast &&
4581 (promisc || allmulti)) {
4582 dev_warn_ratelimited(rvu->dev,
4583 "VF promisc/multicast not supported\n");
4584 return 0;
4585 }
4586
4587 /* untrusted VF can't configure promisc/allmulti */
4588 if (is_vf(pcifunc) && !test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) &&
4589 (promisc || allmulti))
4590 return 0;
4591
4592 err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
4593 if (err)
4594 return err;
4595
4596 if (nix_rx_multicast) {
4597 /* add/del this PF_FUNC to/from mcast pkt replication list */
4598 err = nix_update_mce_rule(rvu, pcifunc, NIXLF_ALLMULTI_ENTRY,
4599 allmulti);
4600 if (err) {
4601 dev_err(rvu->dev,
4602 "Failed to update pcifunc 0x%x to multicast list\n",
4603 pcifunc);
4604 return err;
4605 }
4606
4607 /* add/del this PF_FUNC to/from promisc pkt replication list */
4608 err = nix_update_mce_rule(rvu, pcifunc, NIXLF_PROMISC_ENTRY,
4609 promisc);
4610 if (err) {
4611 dev_err(rvu->dev,
4612 "Failed to update pcifunc 0x%x to promisc list\n",
4613 pcifunc);
4614 return err;
4615 }
4616 }
4617
4618 /* install/uninstall allmulti entry */
4619 if (allmulti) {
4620 rvu_npc_install_allmulti_entry(rvu, pcifunc, nixlf,
4621 pfvf->rx_chan_base);
4622 } else {
4623 if (!nix_rx_multicast && !is_vf(pcifunc))
4624 rvu_npc_enable_allmulti_entry(rvu, pcifunc, nixlf, false);
4625 }
4626
4627 /* install/uninstall promisc entry */
4628 if (promisc)
4629 rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
4630 pfvf->rx_chan_base,
4631 pfvf->rx_chan_cnt);
4632 else
4633 if (!nix_rx_multicast && !is_vf(pcifunc))
4634 rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf, false);
4635
4636 return 0;
4637 }
4638
nix_find_link_frs(struct rvu * rvu,struct nix_frs_cfg * req,u16 pcifunc)4639 static void nix_find_link_frs(struct rvu *rvu,
4640 struct nix_frs_cfg *req, u16 pcifunc)
4641 {
4642 int pf = rvu_get_pf(rvu->pdev, pcifunc);
4643 struct rvu_pfvf *pfvf;
4644 int maxlen, minlen;
4645 int numvfs, hwvf;
4646 int vf;
4647
4648 /* Update with requester's min/max lengths */
4649 pfvf = rvu_get_pfvf(rvu, pcifunc);
4650 pfvf->maxlen = req->maxlen;
4651 if (req->update_minlen)
4652 pfvf->minlen = req->minlen;
4653
4654 maxlen = req->maxlen;
4655 minlen = req->update_minlen ? req->minlen : 0;
4656
4657 /* Get this PF's numVFs and starting hwvf */
4658 rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvf);
4659
4660 /* For each VF, compare requested max/minlen */
4661 for (vf = 0; vf < numvfs; vf++) {
4662 pfvf = &rvu->hwvf[hwvf + vf];
4663 if (pfvf->maxlen > maxlen)
4664 maxlen = pfvf->maxlen;
4665 if (req->update_minlen &&
4666 pfvf->minlen && pfvf->minlen < minlen)
4667 minlen = pfvf->minlen;
4668 }
4669
4670 /* Compare requested max/minlen with PF's max/minlen */
4671 pfvf = &rvu->pf[pf];
4672 if (pfvf->maxlen > maxlen)
4673 maxlen = pfvf->maxlen;
4674 if (req->update_minlen &&
4675 pfvf->minlen && pfvf->minlen < minlen)
4676 minlen = pfvf->minlen;
4677
4678 /* Update the request with max/min PF's and it's VF's max/min */
4679 req->maxlen = maxlen;
4680 if (req->update_minlen)
4681 req->minlen = minlen;
4682 }
4683
rvu_mbox_handler_nix_set_hw_frs(struct rvu * rvu,struct nix_frs_cfg * req,struct msg_rsp * rsp)4684 int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req,
4685 struct msg_rsp *rsp)
4686 {
4687 struct rvu_hwinfo *hw = rvu->hw;
4688 u16 pcifunc = req->hdr.pcifunc;
4689 int pf = rvu_get_pf(rvu->pdev, pcifunc);
4690 int blkaddr, link = -1;
4691 struct nix_hw *nix_hw;
4692 struct rvu_pfvf *pfvf;
4693 u8 cgx = 0, lmac = 0;
4694 u16 max_mtu;
4695 u64 cfg;
4696
4697 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
4698 if (blkaddr < 0)
4699 return NIX_AF_ERR_AF_LF_INVALID;
4700
4701 nix_hw = get_nix_hw(rvu->hw, blkaddr);
4702 if (!nix_hw)
4703 return NIX_AF_ERR_INVALID_NIXBLK;
4704
4705 if (is_lbk_vf(rvu, pcifunc) || is_rep_dev(rvu, pcifunc))
4706 rvu_get_lbk_link_max_frs(rvu, &max_mtu);
4707 else
4708 rvu_get_lmac_link_max_frs(rvu, &max_mtu);
4709
4710 if (!req->sdp_link && req->maxlen > max_mtu)
4711 return NIX_AF_ERR_FRS_INVALID;
4712
4713 if (req->update_minlen && req->minlen < NIC_HW_MIN_FRS)
4714 return NIX_AF_ERR_FRS_INVALID;
4715
4716 /* Check if config is for SDP link */
4717 if (req->sdp_link) {
4718 if (!hw->sdp_links)
4719 return NIX_AF_ERR_RX_LINK_INVALID;
4720 link = hw->cgx_links + hw->lbk_links;
4721 goto linkcfg;
4722 }
4723
4724 /* Check if the request is from CGX mapped RVU PF */
4725 if (is_pf_cgxmapped(rvu, pf)) {
4726 /* Get CGX and LMAC to which this PF is mapped and find link */
4727 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx, &lmac);
4728 link = (cgx * hw->lmac_per_cgx) + lmac;
4729 } else if (pf == 0) {
4730 /* For VFs of PF0 ingress is LBK port, so config LBK link */
4731 pfvf = rvu_get_pfvf(rvu, pcifunc);
4732 link = hw->cgx_links + pfvf->lbkid;
4733 } else if (is_rep_dev(rvu, pcifunc)) {
4734 link = hw->cgx_links + 0;
4735 }
4736
4737 if (link < 0)
4738 return NIX_AF_ERR_RX_LINK_INVALID;
4739
4740 linkcfg:
4741 nix_find_link_frs(rvu, req, pcifunc);
4742
4743 cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link));
4744 cfg = (cfg & ~(0xFFFFULL << 16)) | ((u64)req->maxlen << 16);
4745 if (req->update_minlen)
4746 cfg = (cfg & ~0xFFFFULL) | req->minlen;
4747 rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link), cfg);
4748
4749 return 0;
4750 }
4751
rvu_mbox_handler_nix_set_rx_cfg(struct rvu * rvu,struct nix_rx_cfg * req,struct msg_rsp * rsp)4752 int rvu_mbox_handler_nix_set_rx_cfg(struct rvu *rvu, struct nix_rx_cfg *req,
4753 struct msg_rsp *rsp)
4754 {
4755 int nixlf, blkaddr, err;
4756 u64 cfg;
4757
4758 err = nix_get_nixlf(rvu, req->hdr.pcifunc, &nixlf, &blkaddr);
4759 if (err)
4760 return err;
4761
4762 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LFX_RX_CFG(nixlf));
4763 /* Set the interface configuration */
4764 if (req->len_verify & BIT(0))
4765 cfg |= BIT_ULL(41);
4766 else
4767 cfg &= ~BIT_ULL(41);
4768
4769 if (req->len_verify & BIT(1))
4770 cfg |= BIT_ULL(40);
4771 else
4772 cfg &= ~BIT_ULL(40);
4773
4774 if (req->len_verify & NIX_RX_DROP_RE)
4775 cfg |= BIT_ULL(32);
4776 else
4777 cfg &= ~BIT_ULL(32);
4778
4779 if (req->csum_verify & BIT(0))
4780 cfg |= BIT_ULL(37);
4781 else
4782 cfg &= ~BIT_ULL(37);
4783
4784 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_CFG(nixlf), cfg);
4785
4786 return 0;
4787 }
4788
rvu_get_lbk_link_credits(struct rvu * rvu,u16 lbk_max_frs)4789 static u64 rvu_get_lbk_link_credits(struct rvu *rvu, u16 lbk_max_frs)
4790 {
4791 return 1600; /* 16 * max LBK datarate = 16 * 100Gbps */
4792 }
4793
nix_link_config(struct rvu * rvu,int blkaddr,struct nix_hw * nix_hw)4794 static void nix_link_config(struct rvu *rvu, int blkaddr,
4795 struct nix_hw *nix_hw)
4796 {
4797 struct rvu_hwinfo *hw = rvu->hw;
4798 int cgx, lmac_cnt, slink, link;
4799 u16 lbk_max_frs, lmac_max_frs;
4800 unsigned long lmac_bmap;
4801 u64 tx_credits, cfg;
4802 u64 lmac_fifo_len;
4803 int iter;
4804
4805 rvu_get_lbk_link_max_frs(rvu, &lbk_max_frs);
4806 rvu_get_lmac_link_max_frs(rvu, &lmac_max_frs);
4807
4808 /* Set SDP link credit */
4809 rvu_write64(rvu, blkaddr, NIX_AF_SDP_LINK_CREDIT, SDP_LINK_CREDIT);
4810
4811 /* Set default min/max packet lengths allowed on NIX Rx links.
4812 *
4813 * With HW reset minlen value of 60byte, HW will treat ARP pkts
4814 * as undersize and report them to SW as error pkts, hence
4815 * setting it to 40 bytes.
4816 */
4817 for (link = 0; link < hw->cgx_links; link++) {
4818 rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link),
4819 ((u64)lmac_max_frs << 16) | NIC_HW_MIN_FRS);
4820 }
4821
4822 for (link = hw->cgx_links; link < hw->lbk_links; link++) {
4823 rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link),
4824 ((u64)lbk_max_frs << 16) | NIC_HW_MIN_FRS);
4825 }
4826 if (hw->sdp_links) {
4827 link = hw->cgx_links + hw->lbk_links;
4828 rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link),
4829 SDP_HW_MAX_FRS << 16 | SDP_HW_MIN_FRS);
4830 }
4831
4832 /* Get MCS external bypass status for CN10K-B */
4833 if (mcs_get_blkcnt() == 1) {
4834 /* Adjust for 2 credits when external bypass is disabled */
4835 nix_hw->cc_mcs_cnt = is_mcs_bypass(0) ? 0 : 2;
4836 }
4837
4838 /* Set credits for Tx links assuming max packet length allowed.
4839 * This will be reconfigured based on MTU set for PF/VF.
4840 */
4841 for (cgx = 0; cgx < hw->cgx; cgx++) {
4842 lmac_cnt = cgx_get_lmac_cnt(rvu_cgx_pdata(cgx, rvu));
4843 /* Skip when cgx is not available or lmac cnt is zero */
4844 if (lmac_cnt <= 0)
4845 continue;
4846 slink = cgx * hw->lmac_per_cgx;
4847
4848 /* Get LMAC id's from bitmap */
4849 lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu));
4850 for_each_set_bit(iter, &lmac_bmap, rvu->hw->lmac_per_cgx) {
4851 lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, iter);
4852 if (!lmac_fifo_len) {
4853 dev_err(rvu->dev,
4854 "%s: Failed to get CGX/RPM%d:LMAC%d FIFO size\n",
4855 __func__, cgx, iter);
4856 continue;
4857 }
4858 tx_credits = (lmac_fifo_len - lmac_max_frs) / 16;
4859 /* Enable credits and set credit pkt count to max allowed */
4860 cfg = (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1);
4861 cfg |= FIELD_PREP(NIX_AF_LINKX_MCS_CNT_MASK, nix_hw->cc_mcs_cnt);
4862
4863 link = iter + slink;
4864 nix_hw->tx_credits[link] = tx_credits;
4865 rvu_write64(rvu, blkaddr,
4866 NIX_AF_TX_LINKX_NORM_CREDIT(link), cfg);
4867 }
4868 }
4869
4870 /* Set Tx credits for LBK link */
4871 slink = hw->cgx_links;
4872 for (link = slink; link < (slink + hw->lbk_links); link++) {
4873 tx_credits = rvu_get_lbk_link_credits(rvu, lbk_max_frs);
4874 nix_hw->tx_credits[link] = tx_credits;
4875 /* Enable credits and set credit pkt count to max allowed */
4876 tx_credits = (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1);
4877 rvu_write64(rvu, blkaddr,
4878 NIX_AF_TX_LINKX_NORM_CREDIT(link), tx_credits);
4879 }
4880 }
4881
nix_calibrate_x2p(struct rvu * rvu,int blkaddr)4882 static int nix_calibrate_x2p(struct rvu *rvu, int blkaddr)
4883 {
4884 int idx, err;
4885 u64 status;
4886
4887 /* Start X2P bus calibration */
4888 rvu_write64(rvu, blkaddr, NIX_AF_CFG,
4889 rvu_read64(rvu, blkaddr, NIX_AF_CFG) | BIT_ULL(9));
4890 /* Wait for calibration to complete */
4891 err = rvu_poll_reg(rvu, blkaddr,
4892 NIX_AF_STATUS, BIT_ULL(10), false);
4893 if (err) {
4894 dev_err(rvu->dev, "NIX X2P bus calibration failed\n");
4895 return err;
4896 }
4897
4898 status = rvu_read64(rvu, blkaddr, NIX_AF_STATUS);
4899 /* Check if CGX devices are ready */
4900 for (idx = 0; idx < rvu->cgx_cnt_max; idx++) {
4901 /* Skip when cgx port is not available */
4902 if (!rvu_cgx_pdata(idx, rvu) ||
4903 (status & (BIT_ULL(16 + idx))))
4904 continue;
4905 dev_err(rvu->dev,
4906 "CGX%d didn't respond to NIX X2P calibration\n", idx);
4907 err = -EBUSY;
4908 }
4909
4910 /* Check if LBK is ready */
4911 if (!(status & BIT_ULL(19))) {
4912 dev_err(rvu->dev,
4913 "LBK didn't respond to NIX X2P calibration\n");
4914 err = -EBUSY;
4915 }
4916
4917 /* Clear 'calibrate_x2p' bit */
4918 rvu_write64(rvu, blkaddr, NIX_AF_CFG,
4919 rvu_read64(rvu, blkaddr, NIX_AF_CFG) & ~BIT_ULL(9));
4920 if (err || (status & 0x3FFULL))
4921 dev_err(rvu->dev,
4922 "NIX X2P calibration failed, status 0x%llx\n", status);
4923 if (err)
4924 return err;
4925 return 0;
4926 }
4927
nix_aq_init(struct rvu * rvu,struct rvu_block * block)4928 static int nix_aq_init(struct rvu *rvu, struct rvu_block *block)
4929 {
4930 u64 cfg;
4931 int err;
4932
4933 /* Set admin queue endianness */
4934 cfg = rvu_read64(rvu, block->addr, NIX_AF_CFG);
4935 #ifdef __BIG_ENDIAN
4936 cfg |= BIT_ULL(8);
4937 rvu_write64(rvu, block->addr, NIX_AF_CFG, cfg);
4938 #else
4939 cfg &= ~BIT_ULL(8);
4940 rvu_write64(rvu, block->addr, NIX_AF_CFG, cfg);
4941 #endif
4942
4943 /* Do not bypass NDC cache */
4944 cfg = rvu_read64(rvu, block->addr, NIX_AF_NDC_CFG);
4945 cfg &= ~0x3FFEULL;
4946 #ifdef CONFIG_NDC_DIS_DYNAMIC_CACHING
4947 /* Disable caching of SQB aka SQEs */
4948 cfg |= 0x04ULL;
4949 #endif
4950 rvu_write64(rvu, block->addr, NIX_AF_NDC_CFG, cfg);
4951
4952 /* Result structure can be followed by RQ/SQ/CQ context at
4953 * RES + 128bytes and a write mask at RES + 256 bytes, depending on
4954 * operation type. Alloc sufficient result memory for all operations.
4955 */
4956 err = rvu_aq_alloc(rvu, &block->aq,
4957 Q_COUNT(AQ_SIZE), sizeof(struct nix_aq_inst_s),
4958 ALIGN(sizeof(struct nix_aq_res_s), 128) + 256);
4959 if (err)
4960 return err;
4961
4962 rvu_write64(rvu, block->addr, NIX_AF_AQ_CFG, AQ_SIZE);
4963 rvu_write64(rvu, block->addr,
4964 NIX_AF_AQ_BASE, (u64)block->aq->inst->iova);
4965 return 0;
4966 }
4967
rvu_nix_setup_capabilities(struct rvu * rvu,int blkaddr)4968 static void rvu_nix_setup_capabilities(struct rvu *rvu, int blkaddr)
4969 {
4970 struct rvu_hwinfo *hw = rvu->hw;
4971 u64 hw_const;
4972
4973 hw_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
4974
4975 /* On OcteonTx2 DWRR quantum is directly configured into each of
4976 * the transmit scheduler queues. And PF/VF drivers were free to
4977 * config any value upto 2^24.
4978 * On CN10K, HW is modified, the quantum configuration at scheduler
4979 * queues is in terms of weight. And SW needs to setup a base DWRR MTU
4980 * at NIX_AF_DWRR_RPM_MTU / NIX_AF_DWRR_SDP_MTU. HW will do
4981 * 'DWRR MTU * weight' to get the quantum.
4982 *
4983 * Check if HW uses a common MTU for all DWRR quantum configs.
4984 * On OcteonTx2 this register field is '0'.
4985 */
4986 if ((((hw_const >> 56) & 0x10) == 0x10) && !(hw_const & BIT_ULL(61)))
4987 hw->cap.nix_common_dwrr_mtu = true;
4988
4989 if (hw_const & BIT_ULL(61))
4990 hw->cap.nix_multiple_dwrr_mtu = true;
4991 }
4992
rvu_nix_block_init(struct rvu * rvu,struct nix_hw * nix_hw)4993 static int rvu_nix_block_init(struct rvu *rvu, struct nix_hw *nix_hw)
4994 {
4995 const struct npc_lt_def_cfg *ltdefs;
4996 struct rvu_hwinfo *hw = rvu->hw;
4997 int blkaddr = nix_hw->blkaddr;
4998 struct rvu_block *block;
4999 int err;
5000 u64 cfg;
5001
5002 block = &hw->block[blkaddr];
5003
5004 if (is_rvu_96xx_B0(rvu)) {
5005 /* As per a HW errata in 96xx A0/B0 silicon, NIX may corrupt
5006 * internal state when conditional clocks are turned off.
5007 * Hence enable them.
5008 */
5009 rvu_write64(rvu, blkaddr, NIX_AF_CFG,
5010 rvu_read64(rvu, blkaddr, NIX_AF_CFG) | 0x40ULL);
5011 }
5012
5013 /* Set chan/link to backpressure TL3 instead of TL2 */
5014 rvu_write64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL, 0x01);
5015
5016 /* Disable SQ manager's sticky mode operation (set TM6 = 0, TM11 = 0)
5017 * This sticky mode is known to cause SQ stalls when multiple
5018 * SQs are mapped to same SMQ and transmitting pkts simultaneously.
5019 * NIX PSE may deadlock when there are any sticky to non-sticky
5020 * transmission. Hence disable it (TM5 = 0).
5021 */
5022 cfg = rvu_read64(rvu, blkaddr, NIX_AF_SQM_DBG_CTL_STATUS);
5023 cfg &= ~(BIT_ULL(15) | BIT_ULL(14) | BIT_ULL(23));
5024 /* NIX may drop credits when condition clocks are turned off.
5025 * Hence enable control flow clk (set TM9 = 1).
5026 */
5027 cfg |= BIT_ULL(21);
5028 rvu_write64(rvu, blkaddr, NIX_AF_SQM_DBG_CTL_STATUS, cfg);
5029
5030 ltdefs = rvu->kpu.lt_def;
5031 /* Calibrate X2P bus to check if CGX/LBK links are fine */
5032 err = nix_calibrate_x2p(rvu, blkaddr);
5033 if (err)
5034 return err;
5035
5036 /* Setup capabilities of the NIX block */
5037 rvu_nix_setup_capabilities(rvu, blkaddr);
5038
5039 /* Initialize admin queue */
5040 err = nix_aq_init(rvu, block);
5041 if (err)
5042 return err;
5043
5044 /* Restore CINT timer delay to HW reset values */
5045 rvu_write64(rvu, blkaddr, NIX_AF_CINT_DELAY, 0x0ULL);
5046
5047 cfg = rvu_read64(rvu, blkaddr, NIX_AF_SEB_CFG);
5048
5049 /* For better performance use NDC TX instead of NDC RX for SQ's SQEs" */
5050 cfg |= 1ULL;
5051 if (!is_rvu_otx2(rvu))
5052 cfg |= NIX_PTP_1STEP_EN;
5053
5054 rvu_write64(rvu, blkaddr, NIX_AF_SEB_CFG, cfg);
5055
5056 if (!is_rvu_otx2(rvu))
5057 rvu_nix_block_cn10k_init(rvu, nix_hw);
5058
5059 if (is_block_implemented(hw, blkaddr)) {
5060 err = nix_setup_txschq(rvu, nix_hw, blkaddr);
5061 if (err)
5062 return err;
5063
5064 err = nix_setup_ipolicers(rvu, nix_hw, blkaddr);
5065 if (err)
5066 return err;
5067
5068 err = nix_af_mark_format_setup(rvu, nix_hw, blkaddr);
5069 if (err)
5070 return err;
5071
5072 err = nix_setup_mcast(rvu, nix_hw, blkaddr);
5073 if (err)
5074 return err;
5075
5076 err = nix_setup_txvlan(rvu, nix_hw);
5077 if (err)
5078 return err;
5079
5080 err = nix_setup_bpids(rvu, nix_hw, blkaddr);
5081 if (err)
5082 return err;
5083
5084 /* Configure segmentation offload formats */
5085 nix_setup_lso(rvu, nix_hw, blkaddr);
5086
5087 /* Config Outer/Inner L2, IP, TCP, UDP and SCTP NPC layer info.
5088 * This helps HW protocol checker to identify headers
5089 * and validate length and checksums.
5090 */
5091 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OL2,
5092 (ltdefs->rx_ol2.lid << 8) | (ltdefs->rx_ol2.ltype_match << 4) |
5093 ltdefs->rx_ol2.ltype_mask);
5094 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OIP4,
5095 (ltdefs->rx_oip4.lid << 8) | (ltdefs->rx_oip4.ltype_match << 4) |
5096 ltdefs->rx_oip4.ltype_mask);
5097 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_IIP4,
5098 (ltdefs->rx_iip4.lid << 8) | (ltdefs->rx_iip4.ltype_match << 4) |
5099 ltdefs->rx_iip4.ltype_mask);
5100 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OIP6,
5101 (ltdefs->rx_oip6.lid << 8) | (ltdefs->rx_oip6.ltype_match << 4) |
5102 ltdefs->rx_oip6.ltype_mask);
5103 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_IIP6,
5104 (ltdefs->rx_iip6.lid << 8) | (ltdefs->rx_iip6.ltype_match << 4) |
5105 ltdefs->rx_iip6.ltype_mask);
5106 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OTCP,
5107 (ltdefs->rx_otcp.lid << 8) | (ltdefs->rx_otcp.ltype_match << 4) |
5108 ltdefs->rx_otcp.ltype_mask);
5109 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_ITCP,
5110 (ltdefs->rx_itcp.lid << 8) | (ltdefs->rx_itcp.ltype_match << 4) |
5111 ltdefs->rx_itcp.ltype_mask);
5112 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OUDP,
5113 (ltdefs->rx_oudp.lid << 8) | (ltdefs->rx_oudp.ltype_match << 4) |
5114 ltdefs->rx_oudp.ltype_mask);
5115 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_IUDP,
5116 (ltdefs->rx_iudp.lid << 8) | (ltdefs->rx_iudp.ltype_match << 4) |
5117 ltdefs->rx_iudp.ltype_mask);
5118 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OSCTP,
5119 (ltdefs->rx_osctp.lid << 8) | (ltdefs->rx_osctp.ltype_match << 4) |
5120 ltdefs->rx_osctp.ltype_mask);
5121 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_ISCTP,
5122 (ltdefs->rx_isctp.lid << 8) | (ltdefs->rx_isctp.ltype_match << 4) |
5123 ltdefs->rx_isctp.ltype_mask);
5124
5125 if (!is_rvu_otx2(rvu)) {
5126 /* Enable APAD calculation for other protocols
5127 * matching APAD0 and APAD1 lt def registers.
5128 */
5129 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_CST_APAD0,
5130 (ltdefs->rx_apad0.valid << 11) |
5131 (ltdefs->rx_apad0.lid << 8) |
5132 (ltdefs->rx_apad0.ltype_match << 4) |
5133 ltdefs->rx_apad0.ltype_mask);
5134 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_CST_APAD1,
5135 (ltdefs->rx_apad1.valid << 11) |
5136 (ltdefs->rx_apad1.lid << 8) |
5137 (ltdefs->rx_apad1.ltype_match << 4) |
5138 ltdefs->rx_apad1.ltype_mask);
5139
5140 /* Receive ethertype definition register defines layer
5141 * information in NPC_RESULT_S to identify the Ethertype
5142 * location in L2 header. Used for Ethertype overwriting
5143 * in inline IPsec flow.
5144 */
5145 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_ET(0),
5146 (ltdefs->rx_et[0].offset << 12) |
5147 (ltdefs->rx_et[0].valid << 11) |
5148 (ltdefs->rx_et[0].lid << 8) |
5149 (ltdefs->rx_et[0].ltype_match << 4) |
5150 ltdefs->rx_et[0].ltype_mask);
5151 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_ET(1),
5152 (ltdefs->rx_et[1].offset << 12) |
5153 (ltdefs->rx_et[1].valid << 11) |
5154 (ltdefs->rx_et[1].lid << 8) |
5155 (ltdefs->rx_et[1].ltype_match << 4) |
5156 ltdefs->rx_et[1].ltype_mask);
5157 }
5158
5159 err = nix_rx_flowkey_alg_cfg(rvu, blkaddr);
5160 if (err)
5161 return err;
5162
5163 nix_hw->tx_credits = kcalloc(hw->cgx_links + hw->lbk_links,
5164 sizeof(u64), GFP_KERNEL);
5165 if (!nix_hw->tx_credits)
5166 return -ENOMEM;
5167
5168 /* Initialize CGX/LBK/SDP link credits, min/max pkt lengths */
5169 nix_link_config(rvu, blkaddr, nix_hw);
5170
5171 /* Enable Channel backpressure */
5172 rvu_write64(rvu, blkaddr, NIX_AF_RX_CFG, BIT_ULL(0));
5173 }
5174 return 0;
5175 }
5176
rvu_nix_init(struct rvu * rvu)5177 int rvu_nix_init(struct rvu *rvu)
5178 {
5179 struct rvu_hwinfo *hw = rvu->hw;
5180 struct nix_hw *nix_hw;
5181 int blkaddr = 0, err;
5182 int i = 0;
5183
5184 hw->nix = devm_kcalloc(rvu->dev, MAX_NIX_BLKS, sizeof(struct nix_hw),
5185 GFP_KERNEL);
5186 if (!hw->nix)
5187 return -ENOMEM;
5188
5189 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
5190 while (blkaddr) {
5191 nix_hw = &hw->nix[i];
5192 nix_hw->rvu = rvu;
5193 nix_hw->blkaddr = blkaddr;
5194 err = rvu_nix_block_init(rvu, nix_hw);
5195 if (err)
5196 return err;
5197 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
5198 i++;
5199 }
5200
5201 return 0;
5202 }
5203
rvu_nix_block_freemem(struct rvu * rvu,int blkaddr,struct rvu_block * block)5204 static void rvu_nix_block_freemem(struct rvu *rvu, int blkaddr,
5205 struct rvu_block *block)
5206 {
5207 struct nix_txsch *txsch;
5208 struct nix_mcast *mcast;
5209 struct nix_txvlan *vlan;
5210 struct nix_hw *nix_hw;
5211 int lvl;
5212
5213 rvu_aq_free(rvu, block->aq);
5214
5215 if (is_block_implemented(rvu->hw, blkaddr)) {
5216 nix_hw = get_nix_hw(rvu->hw, blkaddr);
5217 if (!nix_hw)
5218 return;
5219
5220 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
5221 txsch = &nix_hw->txsch[lvl];
5222 kfree(txsch->schq.bmap);
5223 }
5224
5225 kfree(nix_hw->tx_credits);
5226
5227 nix_ipolicer_freemem(rvu, nix_hw);
5228
5229 vlan = &nix_hw->txvlan;
5230 kfree(vlan->rsrc.bmap);
5231 mutex_destroy(&vlan->rsrc_lock);
5232
5233 mcast = &nix_hw->mcast;
5234 qmem_free(rvu->dev, mcast->mce_ctx);
5235 qmem_free(rvu->dev, mcast->mcast_buf);
5236 mutex_destroy(&mcast->mce_lock);
5237 }
5238 }
5239
rvu_nix_freemem(struct rvu * rvu)5240 void rvu_nix_freemem(struct rvu *rvu)
5241 {
5242 struct rvu_hwinfo *hw = rvu->hw;
5243 struct rvu_block *block;
5244 int blkaddr = 0;
5245
5246 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
5247 while (blkaddr) {
5248 block = &hw->block[blkaddr];
5249 rvu_nix_block_freemem(rvu, blkaddr, block);
5250 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
5251 }
5252 }
5253
nix_mcast_update_action(struct rvu * rvu,struct nix_mcast_grp_elem * elem)5254 static void nix_mcast_update_action(struct rvu *rvu,
5255 struct nix_mcast_grp_elem *elem)
5256 {
5257 struct npc_mcam *mcam = &rvu->hw->mcam;
5258 struct nix_rx_action rx_action = { 0 };
5259 struct nix_tx_action tx_action = { 0 };
5260 int npc_blkaddr;
5261
5262 npc_blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
5263 if (elem->dir == NIX_MCAST_INGRESS) {
5264 *(u64 *)&rx_action = npc_get_mcam_action(rvu, mcam,
5265 npc_blkaddr,
5266 elem->mcam_index);
5267 rx_action.index = elem->mce_start_index;
5268 npc_set_mcam_action(rvu, mcam, npc_blkaddr, elem->mcam_index,
5269 *(u64 *)&rx_action);
5270 } else {
5271 *(u64 *)&tx_action = npc_get_mcam_action(rvu, mcam,
5272 npc_blkaddr,
5273 elem->mcam_index);
5274 tx_action.index = elem->mce_start_index;
5275 npc_set_mcam_action(rvu, mcam, npc_blkaddr, elem->mcam_index,
5276 *(u64 *)&tx_action);
5277 }
5278 }
5279
nix_mcast_update_mce_entry(struct rvu * rvu,u16 pcifunc,u8 is_active)5280 static void nix_mcast_update_mce_entry(struct rvu *rvu, u16 pcifunc, u8 is_active)
5281 {
5282 struct nix_mcast_grp_elem *elem;
5283 struct nix_mcast_grp *mcast_grp;
5284 struct nix_hw *nix_hw;
5285 int blkaddr;
5286
5287 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
5288 nix_hw = get_nix_hw(rvu->hw, blkaddr);
5289 if (!nix_hw)
5290 return;
5291
5292 mcast_grp = &nix_hw->mcast_grp;
5293
5294 mutex_lock(&mcast_grp->mcast_grp_lock);
5295 list_for_each_entry(elem, &mcast_grp->mcast_grp_head, list) {
5296 struct nix_mce_list *mce_list;
5297 struct mce *mce;
5298
5299 /* Iterate the group elements and disable the element which
5300 * received the disable request.
5301 */
5302 mce_list = &elem->mcast_mce_list;
5303 hlist_for_each_entry(mce, &mce_list->head, node) {
5304 if (mce->pcifunc == pcifunc) {
5305 mce->is_active = is_active;
5306 break;
5307 }
5308 }
5309
5310 /* Dump the updated list to HW */
5311 if (elem->dir == NIX_MCAST_INGRESS)
5312 nix_update_ingress_mce_list_hw(rvu, nix_hw, elem);
5313 else
5314 nix_update_egress_mce_list_hw(rvu, nix_hw, elem);
5315
5316 /* Update the multicast index in NPC rule */
5317 nix_mcast_update_action(rvu, elem);
5318 }
5319 mutex_unlock(&mcast_grp->mcast_grp_lock);
5320 }
5321
rvu_mbox_handler_nix_lf_start_rx(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)5322 int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
5323 struct msg_rsp *rsp)
5324 {
5325 u16 pcifunc = req->hdr.pcifunc;
5326 struct rvu_pfvf *pfvf;
5327 int nixlf, err, pf;
5328
5329 err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
5330 if (err)
5331 return err;
5332
5333 /* Enable the interface if it is in any multicast list */
5334 nix_mcast_update_mce_entry(rvu, pcifunc, 1);
5335
5336 rvu_npc_enable_default_entries(rvu, pcifunc, nixlf);
5337
5338 npc_mcam_enable_flows(rvu, pcifunc);
5339
5340 pfvf = rvu_get_pfvf(rvu, pcifunc);
5341 set_bit(NIXLF_INITIALIZED, &pfvf->flags);
5342
5343 rvu_switch_update_rules(rvu, pcifunc, true);
5344
5345 pf = rvu_get_pf(rvu->pdev, pcifunc);
5346 if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
5347 rvu_rep_notify_pfvf_state(rvu, pcifunc, true);
5348
5349 return rvu_cgx_start_stop_io(rvu, pcifunc, true);
5350 }
5351
rvu_mbox_handler_nix_lf_stop_rx(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)5352 int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
5353 struct msg_rsp *rsp)
5354 {
5355 u16 pcifunc = req->hdr.pcifunc;
5356 struct rvu_pfvf *pfvf;
5357 int nixlf, err, pf;
5358
5359 err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
5360 if (err)
5361 return err;
5362
5363 rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);
5364 /* Disable the interface if it is in any multicast list */
5365 nix_mcast_update_mce_entry(rvu, pcifunc, 0);
5366
5367 pfvf = rvu_get_pfvf(rvu, pcifunc);
5368 clear_bit(NIXLF_INITIALIZED, &pfvf->flags);
5369
5370 err = rvu_cgx_start_stop_io(rvu, pcifunc, false);
5371 if (err)
5372 return err;
5373
5374 rvu_switch_update_rules(rvu, pcifunc, false);
5375 rvu_cgx_tx_enable(rvu, pcifunc, true);
5376
5377 pf = rvu_get_pf(rvu->pdev, pcifunc);
5378 if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
5379 rvu_rep_notify_pfvf_state(rvu, pcifunc, false);
5380 return 0;
5381 }
5382
5383 #define RX_SA_BASE GENMASK_ULL(52, 7)
5384
rvu_nix_lf_teardown(struct rvu * rvu,u16 pcifunc,int blkaddr,int nixlf)5385 void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
5386 {
5387 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
5388 struct hwctx_disable_req ctx_req;
5389 int pf = rvu_get_pf(rvu->pdev, pcifunc);
5390 struct mac_ops *mac_ops;
5391 u8 cgx_id, lmac_id;
5392 u64 sa_base;
5393 void *cgxd;
5394 int err;
5395
5396 ctx_req.hdr.pcifunc = pcifunc;
5397
5398 /* Cleanup NPC MCAM entries, free Tx scheduler queues being used */
5399 rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);
5400 rvu_npc_free_mcam_entries(rvu, pcifunc, nixlf);
5401 nix_interface_deinit(rvu, pcifunc, nixlf);
5402 nix_rx_sync(rvu, blkaddr);
5403 nix_txschq_free(rvu, pcifunc);
5404
5405 clear_bit(NIXLF_INITIALIZED, &pfvf->flags);
5406
5407 if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
5408 rvu_rep_notify_pfvf_state(rvu, pcifunc, false);
5409
5410 rvu_cgx_start_stop_io(rvu, pcifunc, false);
5411
5412 if (pfvf->sq_ctx) {
5413 ctx_req.ctype = NIX_AQ_CTYPE_SQ;
5414 err = nix_lf_hwctx_disable(rvu, &ctx_req);
5415 if (err)
5416 dev_err(rvu->dev, "SQ ctx disable failed\n");
5417 }
5418
5419 if (pfvf->rq_ctx) {
5420 ctx_req.ctype = NIX_AQ_CTYPE_RQ;
5421 err = nix_lf_hwctx_disable(rvu, &ctx_req);
5422 if (err)
5423 dev_err(rvu->dev, "RQ ctx disable failed\n");
5424 }
5425
5426 if (pfvf->cq_ctx) {
5427 ctx_req.ctype = NIX_AQ_CTYPE_CQ;
5428 err = nix_lf_hwctx_disable(rvu, &ctx_req);
5429 if (err)
5430 dev_err(rvu->dev, "CQ ctx disable failed\n");
5431 }
5432
5433 /* reset HW config done for Switch headers */
5434 rvu_npc_set_parse_mode(rvu, pcifunc, OTX2_PRIV_FLAGS_DEFAULT,
5435 (PKIND_TX | PKIND_RX), 0, 0, 0, 0, 0);
5436
5437 /* Disabling CGX and NPC config done for PTP */
5438 if (pfvf->hw_rx_tstamp_en) {
5439 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
5440 cgxd = rvu_cgx_pdata(cgx_id, rvu);
5441 mac_ops = get_mac_ops(cgxd);
5442 mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, false);
5443 /* Undo NPC config done for PTP */
5444 if (npc_config_ts_kpuaction(rvu, pf, pcifunc, false))
5445 dev_err(rvu->dev, "NPC config for PTP failed\n");
5446 pfvf->hw_rx_tstamp_en = false;
5447 }
5448
5449 /* reset priority flow control config */
5450 rvu_cgx_prio_flow_ctrl_cfg(rvu, pcifunc, 0, 0, 0);
5451
5452 /* reset 802.3x flow control config */
5453 rvu_cgx_cfg_pause_frm(rvu, pcifunc, 0, 0);
5454
5455 nix_ctx_free(rvu, pfvf);
5456
5457 nix_free_all_bandprof(rvu, pcifunc);
5458
5459 sa_base = rvu_read64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_SA_BASE(nixlf));
5460 if (FIELD_GET(RX_SA_BASE, sa_base)) {
5461 err = rvu_cpt_ctx_flush(rvu, pcifunc);
5462 if (err)
5463 dev_err(rvu->dev,
5464 "CPT ctx flush failed with error: %d\n", err);
5465 }
5466 }
5467
5468 #define NIX_AF_LFX_TX_CFG_PTP_EN BIT_ULL(32)
5469
rvu_nix_lf_ptp_tx_cfg(struct rvu * rvu,u16 pcifunc,bool enable)5470 static int rvu_nix_lf_ptp_tx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
5471 {
5472 struct rvu_hwinfo *hw = rvu->hw;
5473 struct rvu_block *block;
5474 int blkaddr, pf;
5475 int nixlf;
5476 u64 cfg;
5477
5478 pf = rvu_get_pf(rvu->pdev, pcifunc);
5479 if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_PTP))
5480 return 0;
5481
5482 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
5483 if (blkaddr < 0)
5484 return NIX_AF_ERR_AF_LF_INVALID;
5485
5486 block = &hw->block[blkaddr];
5487 nixlf = rvu_get_lf(rvu, block, pcifunc, 0);
5488 if (nixlf < 0)
5489 return NIX_AF_ERR_AF_LF_INVALID;
5490
5491 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf));
5492
5493 if (enable)
5494 cfg |= NIX_AF_LFX_TX_CFG_PTP_EN;
5495 else
5496 cfg &= ~NIX_AF_LFX_TX_CFG_PTP_EN;
5497
5498 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf), cfg);
5499
5500 return 0;
5501 }
5502
rvu_mbox_handler_nix_lf_ptp_tx_enable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)5503 int rvu_mbox_handler_nix_lf_ptp_tx_enable(struct rvu *rvu, struct msg_req *req,
5504 struct msg_rsp *rsp)
5505 {
5506 return rvu_nix_lf_ptp_tx_cfg(rvu, req->hdr.pcifunc, true);
5507 }
5508
rvu_mbox_handler_nix_lf_ptp_tx_disable(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)5509 int rvu_mbox_handler_nix_lf_ptp_tx_disable(struct rvu *rvu, struct msg_req *req,
5510 struct msg_rsp *rsp)
5511 {
5512 return rvu_nix_lf_ptp_tx_cfg(rvu, req->hdr.pcifunc, false);
5513 }
5514
rvu_mbox_handler_nix_lso_format_cfg(struct rvu * rvu,struct nix_lso_format_cfg * req,struct nix_lso_format_cfg_rsp * rsp)5515 int rvu_mbox_handler_nix_lso_format_cfg(struct rvu *rvu,
5516 struct nix_lso_format_cfg *req,
5517 struct nix_lso_format_cfg_rsp *rsp)
5518 {
5519 u16 pcifunc = req->hdr.pcifunc;
5520 struct nix_hw *nix_hw;
5521 struct rvu_pfvf *pfvf;
5522 int blkaddr, idx, f;
5523 u64 reg;
5524
5525 pfvf = rvu_get_pfvf(rvu, pcifunc);
5526 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
5527 if (!pfvf->nixlf || blkaddr < 0)
5528 return NIX_AF_ERR_AF_LF_INVALID;
5529
5530 nix_hw = get_nix_hw(rvu->hw, blkaddr);
5531 if (!nix_hw)
5532 return NIX_AF_ERR_INVALID_NIXBLK;
5533
5534 /* Find existing matching LSO format, if any */
5535 for (idx = 0; idx < nix_hw->lso.in_use; idx++) {
5536 for (f = 0; f < NIX_LSO_FIELD_MAX; f++) {
5537 reg = rvu_read64(rvu, blkaddr,
5538 NIX_AF_LSO_FORMATX_FIELDX(idx, f));
5539 if (req->fields[f] != (reg & req->field_mask))
5540 break;
5541 }
5542
5543 if (f == NIX_LSO_FIELD_MAX)
5544 break;
5545 }
5546
5547 if (idx < nix_hw->lso.in_use) {
5548 /* Match found */
5549 rsp->lso_format_idx = idx;
5550 return 0;
5551 }
5552
5553 if (nix_hw->lso.in_use == nix_hw->lso.total)
5554 return NIX_AF_ERR_LSO_CFG_FAIL;
5555
5556 rsp->lso_format_idx = nix_hw->lso.in_use++;
5557
5558 for (f = 0; f < NIX_LSO_FIELD_MAX; f++)
5559 rvu_write64(rvu, blkaddr,
5560 NIX_AF_LSO_FORMATX_FIELDX(rsp->lso_format_idx, f),
5561 req->fields[f]);
5562
5563 return 0;
5564 }
5565
5566 #define IPSEC_GEN_CFG_EGRP GENMASK_ULL(50, 48)
5567 #define IPSEC_GEN_CFG_OPCODE GENMASK_ULL(47, 32)
5568 #define IPSEC_GEN_CFG_PARAM1 GENMASK_ULL(31, 16)
5569 #define IPSEC_GEN_CFG_PARAM2 GENMASK_ULL(15, 0)
5570
5571 #define CPT_INST_QSEL_BLOCK GENMASK_ULL(28, 24)
5572 #define CPT_INST_QSEL_PF_FUNC GENMASK_ULL(23, 8)
5573 #define CPT_INST_QSEL_SLOT GENMASK_ULL(7, 0)
5574
5575 #define CPT_INST_CREDIT_TH GENMASK_ULL(53, 32)
5576 #define CPT_INST_CREDIT_BPID GENMASK_ULL(30, 22)
5577 #define CPT_INST_CREDIT_CNT GENMASK_ULL(21, 0)
5578
nix_inline_ipsec_cfg(struct rvu * rvu,struct nix_inline_ipsec_cfg * req,int blkaddr)5579 static void nix_inline_ipsec_cfg(struct rvu *rvu, struct nix_inline_ipsec_cfg *req,
5580 int blkaddr)
5581 {
5582 u8 cpt_idx, cpt_blkaddr;
5583 u64 val;
5584
5585 cpt_idx = (blkaddr == BLKADDR_NIX0) ? 0 : 1;
5586 if (req->enable) {
5587 val = 0;
5588 /* Enable context prefetching */
5589 if (!is_rvu_otx2(rvu))
5590 val |= BIT_ULL(51);
5591
5592 /* Set OPCODE and EGRP */
5593 val |= FIELD_PREP(IPSEC_GEN_CFG_EGRP, req->gen_cfg.egrp);
5594 val |= FIELD_PREP(IPSEC_GEN_CFG_OPCODE, req->gen_cfg.opcode);
5595 val |= FIELD_PREP(IPSEC_GEN_CFG_PARAM1, req->gen_cfg.param1);
5596 val |= FIELD_PREP(IPSEC_GEN_CFG_PARAM2, req->gen_cfg.param2);
5597
5598 rvu_write64(rvu, blkaddr, NIX_AF_RX_IPSEC_GEN_CFG, val);
5599
5600 /* Set CPT queue for inline IPSec */
5601 val = FIELD_PREP(CPT_INST_QSEL_SLOT, req->inst_qsel.cpt_slot);
5602 val |= FIELD_PREP(CPT_INST_QSEL_PF_FUNC,
5603 req->inst_qsel.cpt_pf_func);
5604
5605 if (!is_rvu_otx2(rvu)) {
5606 cpt_blkaddr = (cpt_idx == 0) ? BLKADDR_CPT0 :
5607 BLKADDR_CPT1;
5608 val |= FIELD_PREP(CPT_INST_QSEL_BLOCK, cpt_blkaddr);
5609 }
5610
5611 rvu_write64(rvu, blkaddr, NIX_AF_RX_CPTX_INST_QSEL(cpt_idx),
5612 val);
5613
5614 /* Set CPT credit */
5615 val = rvu_read64(rvu, blkaddr, NIX_AF_RX_CPTX_CREDIT(cpt_idx));
5616 if ((val & 0x3FFFFF) != 0x3FFFFF)
5617 rvu_write64(rvu, blkaddr, NIX_AF_RX_CPTX_CREDIT(cpt_idx),
5618 0x3FFFFF - val);
5619
5620 val = FIELD_PREP(CPT_INST_CREDIT_CNT, req->cpt_credit);
5621 val |= FIELD_PREP(CPT_INST_CREDIT_BPID, req->bpid);
5622 val |= FIELD_PREP(CPT_INST_CREDIT_TH, req->credit_th);
5623 rvu_write64(rvu, blkaddr, NIX_AF_RX_CPTX_CREDIT(cpt_idx), val);
5624 } else {
5625 rvu_write64(rvu, blkaddr, NIX_AF_RX_IPSEC_GEN_CFG, 0x0);
5626 rvu_write64(rvu, blkaddr, NIX_AF_RX_CPTX_INST_QSEL(cpt_idx),
5627 0x0);
5628 val = rvu_read64(rvu, blkaddr, NIX_AF_RX_CPTX_CREDIT(cpt_idx));
5629 if ((val & 0x3FFFFF) != 0x3FFFFF)
5630 rvu_write64(rvu, blkaddr, NIX_AF_RX_CPTX_CREDIT(cpt_idx),
5631 0x3FFFFF - val);
5632 }
5633 }
5634
rvu_mbox_handler_nix_inline_ipsec_cfg(struct rvu * rvu,struct nix_inline_ipsec_cfg * req,struct msg_rsp * rsp)5635 int rvu_mbox_handler_nix_inline_ipsec_cfg(struct rvu *rvu,
5636 struct nix_inline_ipsec_cfg *req,
5637 struct msg_rsp *rsp)
5638 {
5639 if (!is_block_implemented(rvu->hw, BLKADDR_CPT0))
5640 return 0;
5641
5642 nix_inline_ipsec_cfg(rvu, req, BLKADDR_NIX0);
5643 if (is_block_implemented(rvu->hw, BLKADDR_CPT1))
5644 nix_inline_ipsec_cfg(rvu, req, BLKADDR_NIX1);
5645
5646 return 0;
5647 }
5648
rvu_mbox_handler_nix_read_inline_ipsec_cfg(struct rvu * rvu,struct msg_req * req,struct nix_inline_ipsec_cfg * rsp)5649 int rvu_mbox_handler_nix_read_inline_ipsec_cfg(struct rvu *rvu,
5650 struct msg_req *req,
5651 struct nix_inline_ipsec_cfg *rsp)
5652
5653 {
5654 u64 val;
5655
5656 if (!is_block_implemented(rvu->hw, BLKADDR_CPT0))
5657 return 0;
5658
5659 val = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_RX_IPSEC_GEN_CFG);
5660 rsp->gen_cfg.egrp = FIELD_GET(IPSEC_GEN_CFG_EGRP, val);
5661 rsp->gen_cfg.opcode = FIELD_GET(IPSEC_GEN_CFG_OPCODE, val);
5662 rsp->gen_cfg.param1 = FIELD_GET(IPSEC_GEN_CFG_PARAM1, val);
5663 rsp->gen_cfg.param2 = FIELD_GET(IPSEC_GEN_CFG_PARAM2, val);
5664
5665 val = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_RX_CPTX_CREDIT(0));
5666 rsp->cpt_credit = FIELD_GET(CPT_INST_CREDIT_CNT, val);
5667 rsp->credit_th = FIELD_GET(CPT_INST_CREDIT_TH, val);
5668 rsp->bpid = FIELD_GET(CPT_INST_CREDIT_BPID, val);
5669
5670 return 0;
5671 }
5672
rvu_mbox_handler_nix_inline_ipsec_lf_cfg(struct rvu * rvu,struct nix_inline_ipsec_lf_cfg * req,struct msg_rsp * rsp)5673 int rvu_mbox_handler_nix_inline_ipsec_lf_cfg(struct rvu *rvu,
5674 struct nix_inline_ipsec_lf_cfg *req,
5675 struct msg_rsp *rsp)
5676 {
5677 int lf, blkaddr, err;
5678 u64 val;
5679
5680 if (!is_block_implemented(rvu->hw, BLKADDR_CPT0))
5681 return 0;
5682
5683 err = nix_get_nixlf(rvu, req->hdr.pcifunc, &lf, &blkaddr);
5684 if (err)
5685 return err;
5686
5687 if (req->enable) {
5688 /* Set TT, TAG_CONST, SA_POW2_SIZE and LENM1_MAX */
5689 val = (u64)req->ipsec_cfg0.tt << 44 |
5690 (u64)req->ipsec_cfg0.tag_const << 20 |
5691 (u64)req->ipsec_cfg0.sa_pow2_size << 16 |
5692 req->ipsec_cfg0.lenm1_max;
5693
5694 if (blkaddr == BLKADDR_NIX1)
5695 val |= BIT_ULL(46);
5696
5697 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_CFG0(lf), val);
5698
5699 /* Set SA_IDX_W and SA_IDX_MAX */
5700 val = (u64)req->ipsec_cfg1.sa_idx_w << 32 |
5701 req->ipsec_cfg1.sa_idx_max;
5702 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_CFG1(lf), val);
5703
5704 /* Set SA base address */
5705 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_SA_BASE(lf),
5706 req->sa_base_addr);
5707 } else {
5708 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_CFG0(lf), 0x0);
5709 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_CFG1(lf), 0x0);
5710 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_IPSEC_SA_BASE(lf),
5711 0x0);
5712 }
5713
5714 return 0;
5715 }
5716
rvu_nix_reset_mac(struct rvu_pfvf * pfvf,int pcifunc)5717 void rvu_nix_reset_mac(struct rvu_pfvf *pfvf, int pcifunc)
5718 {
5719 bool from_vf = !!(pcifunc & RVU_PFVF_FUNC_MASK);
5720
5721 /* overwrite vf mac address with default_mac */
5722 if (from_vf)
5723 ether_addr_copy(pfvf->mac_addr, pfvf->default_mac);
5724 }
5725
5726 /* NIX ingress policers or bandwidth profiles APIs */
nix_config_rx_pkt_policer_precolor(struct rvu * rvu,int blkaddr)5727 static void nix_config_rx_pkt_policer_precolor(struct rvu *rvu, int blkaddr)
5728 {
5729 struct npc_lt_def_cfg defs, *ltdefs;
5730
5731 ltdefs = &defs;
5732 memcpy(ltdefs, rvu->kpu.lt_def, sizeof(struct npc_lt_def_cfg));
5733
5734 /* Extract PCP and DEI fields from outer VLAN from byte offset
5735 * 2 from the start of LB_PTR (ie TAG).
5736 * VLAN0 is Outer VLAN and VLAN1 is Inner VLAN. Inner VLAN
5737 * fields are considered when 'Tunnel enable' is set in profile.
5738 */
5739 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_VLAN0_PCP_DEI,
5740 (2UL << 12) | (ltdefs->ovlan.lid << 8) |
5741 (ltdefs->ovlan.ltype_match << 4) |
5742 ltdefs->ovlan.ltype_mask);
5743 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_VLAN1_PCP_DEI,
5744 (2UL << 12) | (ltdefs->ivlan.lid << 8) |
5745 (ltdefs->ivlan.ltype_match << 4) |
5746 ltdefs->ivlan.ltype_mask);
5747
5748 /* DSCP field in outer and tunneled IPv4 packets */
5749 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OIP4_DSCP,
5750 (1UL << 12) | (ltdefs->rx_oip4.lid << 8) |
5751 (ltdefs->rx_oip4.ltype_match << 4) |
5752 ltdefs->rx_oip4.ltype_mask);
5753 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_IIP4_DSCP,
5754 (1UL << 12) | (ltdefs->rx_iip4.lid << 8) |
5755 (ltdefs->rx_iip4.ltype_match << 4) |
5756 ltdefs->rx_iip4.ltype_mask);
5757
5758 /* DSCP field (traffic class) in outer and tunneled IPv6 packets */
5759 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OIP6_DSCP,
5760 (1UL << 11) | (ltdefs->rx_oip6.lid << 8) |
5761 (ltdefs->rx_oip6.ltype_match << 4) |
5762 ltdefs->rx_oip6.ltype_mask);
5763 rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_IIP6_DSCP,
5764 (1UL << 11) | (ltdefs->rx_iip6.lid << 8) |
5765 (ltdefs->rx_iip6.ltype_match << 4) |
5766 ltdefs->rx_iip6.ltype_mask);
5767 }
5768
nix_init_policer_context(struct rvu * rvu,struct nix_hw * nix_hw,int layer,int prof_idx)5769 static int nix_init_policer_context(struct rvu *rvu, struct nix_hw *nix_hw,
5770 int layer, int prof_idx)
5771 {
5772 struct nix_cn10k_aq_enq_req aq_req;
5773 int rc;
5774
5775 memset(&aq_req, 0, sizeof(struct nix_cn10k_aq_enq_req));
5776
5777 aq_req.qidx = (prof_idx & 0x3FFF) | (layer << 14);
5778 aq_req.ctype = NIX_AQ_CTYPE_BANDPROF;
5779 aq_req.op = NIX_AQ_INSTOP_INIT;
5780
5781 /* Context is all zeros, submit to AQ */
5782 rc = rvu_nix_blk_aq_enq_inst(rvu, nix_hw,
5783 (struct nix_aq_enq_req *)&aq_req, NULL);
5784 if (rc)
5785 dev_err(rvu->dev, "Failed to INIT bandwidth profile layer %d profile %d\n",
5786 layer, prof_idx);
5787 return rc;
5788 }
5789
nix_setup_ipolicers(struct rvu * rvu,struct nix_hw * nix_hw,int blkaddr)5790 static int nix_setup_ipolicers(struct rvu *rvu,
5791 struct nix_hw *nix_hw, int blkaddr)
5792 {
5793 struct rvu_hwinfo *hw = rvu->hw;
5794 struct nix_ipolicer *ipolicer;
5795 int err, layer, prof_idx;
5796 u64 cfg;
5797
5798 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
5799 if (!(cfg & BIT_ULL(61))) {
5800 hw->cap.ipolicer = false;
5801 return 0;
5802 }
5803
5804 hw->cap.ipolicer = true;
5805 nix_hw->ipolicer = devm_kcalloc(rvu->dev, BAND_PROF_NUM_LAYERS,
5806 sizeof(*ipolicer), GFP_KERNEL);
5807 if (!nix_hw->ipolicer)
5808 return -ENOMEM;
5809
5810 cfg = rvu_read64(rvu, blkaddr, NIX_AF_PL_CONST);
5811
5812 for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
5813 ipolicer = &nix_hw->ipolicer[layer];
5814 switch (layer) {
5815 case BAND_PROF_LEAF_LAYER:
5816 ipolicer->band_prof.max = cfg & 0XFFFF;
5817 break;
5818 case BAND_PROF_MID_LAYER:
5819 ipolicer->band_prof.max = (cfg >> 16) & 0XFFFF;
5820 break;
5821 case BAND_PROF_TOP_LAYER:
5822 ipolicer->band_prof.max = (cfg >> 32) & 0XFFFF;
5823 break;
5824 }
5825
5826 if (!ipolicer->band_prof.max)
5827 continue;
5828
5829 err = rvu_alloc_bitmap(&ipolicer->band_prof);
5830 if (err)
5831 return err;
5832
5833 ipolicer->pfvf_map = devm_kcalloc(rvu->dev,
5834 ipolicer->band_prof.max,
5835 sizeof(u16), GFP_KERNEL);
5836 if (!ipolicer->pfvf_map)
5837 return -ENOMEM;
5838
5839 ipolicer->match_id = devm_kcalloc(rvu->dev,
5840 ipolicer->band_prof.max,
5841 sizeof(u16), GFP_KERNEL);
5842 if (!ipolicer->match_id)
5843 return -ENOMEM;
5844
5845 for (prof_idx = 0;
5846 prof_idx < ipolicer->band_prof.max; prof_idx++) {
5847 /* Set AF as current owner for INIT ops to succeed */
5848 ipolicer->pfvf_map[prof_idx] = 0x00;
5849
5850 /* There is no enable bit in the profile context,
5851 * so no context disable. So let's INIT them here
5852 * so that PF/VF later on have to just do WRITE to
5853 * setup policer rates and config.
5854 */
5855 err = nix_init_policer_context(rvu, nix_hw,
5856 layer, prof_idx);
5857 if (err)
5858 return err;
5859 }
5860
5861 /* Allocate memory for maintaining ref_counts for MID level
5862 * profiles, this will be needed for leaf layer profiles'
5863 * aggregation.
5864 */
5865 if (layer != BAND_PROF_MID_LAYER)
5866 continue;
5867
5868 ipolicer->ref_count = devm_kcalloc(rvu->dev,
5869 ipolicer->band_prof.max,
5870 sizeof(u16), GFP_KERNEL);
5871 if (!ipolicer->ref_count)
5872 return -ENOMEM;
5873 }
5874
5875 /* Set policer timeunit to 2us ie (19 + 1) * 100 nsec = 2us */
5876 rvu_write64(rvu, blkaddr, NIX_AF_PL_TS, 19);
5877
5878 nix_config_rx_pkt_policer_precolor(rvu, blkaddr);
5879
5880 return 0;
5881 }
5882
nix_ipolicer_freemem(struct rvu * rvu,struct nix_hw * nix_hw)5883 static void nix_ipolicer_freemem(struct rvu *rvu, struct nix_hw *nix_hw)
5884 {
5885 struct nix_ipolicer *ipolicer;
5886 int layer;
5887
5888 if (!rvu->hw->cap.ipolicer)
5889 return;
5890
5891 for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
5892 ipolicer = &nix_hw->ipolicer[layer];
5893
5894 if (!ipolicer->band_prof.max)
5895 continue;
5896
5897 kfree(ipolicer->band_prof.bmap);
5898 }
5899 }
5900
5901 #define NIX_BW_PROF_HI_MASK GENMASK(10, 7)
5902
nix_verify_bandprof(struct nix_cn10k_aq_enq_req * req,struct nix_hw * nix_hw,u16 pcifunc)5903 static int nix_verify_bandprof(struct nix_cn10k_aq_enq_req *req,
5904 struct nix_hw *nix_hw, u16 pcifunc)
5905 {
5906 struct nix_ipolicer *ipolicer;
5907 int layer, hi_layer, prof_idx;
5908
5909 /* Bits [15:14] in profile index represent layer */
5910 layer = (req->qidx >> 14) & 0x03;
5911 prof_idx = req->qidx & 0x3FFF;
5912
5913 ipolicer = &nix_hw->ipolicer[layer];
5914 if (prof_idx >= ipolicer->band_prof.max)
5915 return -EINVAL;
5916
5917 /* Check if the profile is allocated to the requesting PCIFUNC or not
5918 * with the exception of AF. AF is allowed to read and update contexts.
5919 */
5920 if (pcifunc && ipolicer->pfvf_map[prof_idx] != pcifunc)
5921 return -EINVAL;
5922
5923 /* If this profile is linked to higher layer profile then check
5924 * if that profile is also allocated to the requesting PCIFUNC
5925 * or not.
5926 */
5927 if (!req->prof.hl_en)
5928 return 0;
5929
5930 /* Leaf layer profile can link only to mid layer and
5931 * mid layer to top layer.
5932 */
5933 if (layer == BAND_PROF_LEAF_LAYER)
5934 hi_layer = BAND_PROF_MID_LAYER;
5935 else if (layer == BAND_PROF_MID_LAYER)
5936 hi_layer = BAND_PROF_TOP_LAYER;
5937 else
5938 return -EINVAL;
5939
5940 ipolicer = &nix_hw->ipolicer[hi_layer];
5941 prof_idx = FIELD_PREP(NIX_BW_PROF_HI_MASK, req->prof.band_prof_id_h);
5942 prof_idx |= req->prof.band_prof_id;
5943 if (prof_idx >= ipolicer->band_prof.max ||
5944 ipolicer->pfvf_map[prof_idx] != pcifunc)
5945 return -EINVAL;
5946
5947 return 0;
5948 }
5949
rvu_mbox_handler_nix_bandprof_alloc(struct rvu * rvu,struct nix_bandprof_alloc_req * req,struct nix_bandprof_alloc_rsp * rsp)5950 int rvu_mbox_handler_nix_bandprof_alloc(struct rvu *rvu,
5951 struct nix_bandprof_alloc_req *req,
5952 struct nix_bandprof_alloc_rsp *rsp)
5953 {
5954 int blkaddr, layer, prof, idx, err;
5955 u16 pcifunc = req->hdr.pcifunc;
5956 struct nix_ipolicer *ipolicer;
5957 struct nix_hw *nix_hw;
5958
5959 if (!rvu->hw->cap.ipolicer)
5960 return NIX_AF_ERR_IPOLICER_NOTSUPP;
5961
5962 err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
5963 if (err)
5964 return err;
5965
5966 mutex_lock(&rvu->rsrc_lock);
5967 for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
5968 if (layer == BAND_PROF_INVAL_LAYER)
5969 continue;
5970 if (!req->prof_count[layer])
5971 continue;
5972
5973 ipolicer = &nix_hw->ipolicer[layer];
5974 for (idx = 0; idx < req->prof_count[layer]; idx++) {
5975 /* Allocate a max of 'MAX_BANDPROF_PER_PFFUNC' profiles */
5976 if (idx == MAX_BANDPROF_PER_PFFUNC)
5977 break;
5978
5979 prof = rvu_alloc_rsrc(&ipolicer->band_prof);
5980 if (prof < 0)
5981 break;
5982 rsp->prof_count[layer]++;
5983 rsp->prof_idx[layer][idx] = prof;
5984 ipolicer->pfvf_map[prof] = pcifunc;
5985 }
5986 }
5987 mutex_unlock(&rvu->rsrc_lock);
5988 return 0;
5989 }
5990
nix_free_all_bandprof(struct rvu * rvu,u16 pcifunc)5991 static int nix_free_all_bandprof(struct rvu *rvu, u16 pcifunc)
5992 {
5993 int blkaddr, layer, prof_idx, err;
5994 struct nix_ipolicer *ipolicer;
5995 struct nix_hw *nix_hw;
5996
5997 if (!rvu->hw->cap.ipolicer)
5998 return NIX_AF_ERR_IPOLICER_NOTSUPP;
5999
6000 err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
6001 if (err)
6002 return err;
6003
6004 mutex_lock(&rvu->rsrc_lock);
6005 /* Free all the profiles allocated to the PCIFUNC */
6006 for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
6007 if (layer == BAND_PROF_INVAL_LAYER)
6008 continue;
6009 ipolicer = &nix_hw->ipolicer[layer];
6010
6011 for (prof_idx = 0; prof_idx < ipolicer->band_prof.max; prof_idx++) {
6012 if (ipolicer->pfvf_map[prof_idx] != pcifunc)
6013 continue;
6014
6015 /* Clear ratelimit aggregation, if any */
6016 if (layer == BAND_PROF_LEAF_LAYER &&
6017 ipolicer->match_id[prof_idx])
6018 nix_clear_ratelimit_aggr(rvu, nix_hw, prof_idx);
6019
6020 ipolicer->pfvf_map[prof_idx] = 0x00;
6021 ipolicer->match_id[prof_idx] = 0;
6022 rvu_free_rsrc(&ipolicer->band_prof, prof_idx);
6023 }
6024 }
6025 mutex_unlock(&rvu->rsrc_lock);
6026 return 0;
6027 }
6028
rvu_mbox_handler_nix_bandprof_free(struct rvu * rvu,struct nix_bandprof_free_req * req,struct msg_rsp * rsp)6029 int rvu_mbox_handler_nix_bandprof_free(struct rvu *rvu,
6030 struct nix_bandprof_free_req *req,
6031 struct msg_rsp *rsp)
6032 {
6033 int blkaddr, layer, prof_idx, idx, err;
6034 u16 pcifunc = req->hdr.pcifunc;
6035 struct nix_ipolicer *ipolicer;
6036 struct nix_hw *nix_hw;
6037
6038 if (req->free_all)
6039 return nix_free_all_bandprof(rvu, pcifunc);
6040
6041 if (!rvu->hw->cap.ipolicer)
6042 return NIX_AF_ERR_IPOLICER_NOTSUPP;
6043
6044 err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
6045 if (err)
6046 return err;
6047
6048 mutex_lock(&rvu->rsrc_lock);
6049 /* Free the requested profile indices */
6050 for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
6051 if (layer == BAND_PROF_INVAL_LAYER)
6052 continue;
6053 if (!req->prof_count[layer])
6054 continue;
6055
6056 ipolicer = &nix_hw->ipolicer[layer];
6057 for (idx = 0; idx < req->prof_count[layer]; idx++) {
6058 if (idx == MAX_BANDPROF_PER_PFFUNC)
6059 break;
6060 prof_idx = req->prof_idx[layer][idx];
6061 if (prof_idx >= ipolicer->band_prof.max ||
6062 ipolicer->pfvf_map[prof_idx] != pcifunc)
6063 continue;
6064
6065 /* Clear ratelimit aggregation, if any */
6066 if (layer == BAND_PROF_LEAF_LAYER &&
6067 ipolicer->match_id[prof_idx])
6068 nix_clear_ratelimit_aggr(rvu, nix_hw, prof_idx);
6069
6070 ipolicer->pfvf_map[prof_idx] = 0x00;
6071 ipolicer->match_id[prof_idx] = 0;
6072 rvu_free_rsrc(&ipolicer->band_prof, prof_idx);
6073 }
6074 }
6075 mutex_unlock(&rvu->rsrc_lock);
6076 return 0;
6077 }
6078
nix_aq_context_read(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_cn10k_aq_enq_req * aq_req,struct nix_cn10k_aq_enq_rsp * aq_rsp,u16 pcifunc,u8 ctype,u32 qidx)6079 int nix_aq_context_read(struct rvu *rvu, struct nix_hw *nix_hw,
6080 struct nix_cn10k_aq_enq_req *aq_req,
6081 struct nix_cn10k_aq_enq_rsp *aq_rsp,
6082 u16 pcifunc, u8 ctype, u32 qidx)
6083 {
6084 memset(aq_req, 0, sizeof(struct nix_cn10k_aq_enq_req));
6085 aq_req->hdr.pcifunc = pcifunc;
6086 aq_req->ctype = ctype;
6087 aq_req->op = NIX_AQ_INSTOP_READ;
6088 aq_req->qidx = qidx;
6089
6090 return rvu_nix_blk_aq_enq_inst(rvu, nix_hw,
6091 (struct nix_aq_enq_req *)aq_req,
6092 (struct nix_aq_enq_rsp *)aq_rsp);
6093 }
6094
nix_ipolicer_map_leaf_midprofs(struct rvu * rvu,struct nix_hw * nix_hw,struct nix_cn10k_aq_enq_req * aq_req,struct nix_cn10k_aq_enq_rsp * aq_rsp,u32 leaf_prof,u16 mid_prof)6095 static int nix_ipolicer_map_leaf_midprofs(struct rvu *rvu,
6096 struct nix_hw *nix_hw,
6097 struct nix_cn10k_aq_enq_req *aq_req,
6098 struct nix_cn10k_aq_enq_rsp *aq_rsp,
6099 u32 leaf_prof, u16 mid_prof)
6100 {
6101 memset(aq_req, 0, sizeof(struct nix_cn10k_aq_enq_req));
6102 aq_req->hdr.pcifunc = 0x00;
6103 aq_req->ctype = NIX_AQ_CTYPE_BANDPROF;
6104 aq_req->op = NIX_AQ_INSTOP_WRITE;
6105 aq_req->qidx = leaf_prof;
6106
6107 aq_req->prof.band_prof_id = mid_prof & 0x7F;
6108 aq_req->prof_mask.band_prof_id = GENMASK(6, 0);
6109 aq_req->prof.band_prof_id_h = FIELD_GET(NIX_BW_PROF_HI_MASK, mid_prof);
6110 aq_req->prof_mask.band_prof_id_h = GENMASK(3, 0);
6111 aq_req->prof.hl_en = 1;
6112 aq_req->prof_mask.hl_en = 1;
6113
6114 return rvu_nix_blk_aq_enq_inst(rvu, nix_hw,
6115 (struct nix_aq_enq_req *)aq_req,
6116 (struct nix_aq_enq_rsp *)aq_rsp);
6117 }
6118
6119 #define NIX_RQ_PROF_HI_MASK GENMASK(13, 10)
6120
rvu_nix_setup_ratelimit_aggr(struct rvu * rvu,u16 pcifunc,u16 rq_idx,u16 match_id)6121 int rvu_nix_setup_ratelimit_aggr(struct rvu *rvu, u16 pcifunc,
6122 u16 rq_idx, u16 match_id)
6123 {
6124 int leaf_prof, mid_prof, leaf_match;
6125 struct nix_cn10k_aq_enq_req aq_req;
6126 struct nix_cn10k_aq_enq_rsp aq_rsp;
6127 struct nix_ipolicer *ipolicer;
6128 struct nix_hw *nix_hw;
6129 int blkaddr, idx, rc;
6130
6131 if (!rvu->hw->cap.ipolicer)
6132 return 0;
6133
6134 rc = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr);
6135 if (rc)
6136 return rc;
6137
6138 /* Fetch the RQ's context to see if policing is enabled */
6139 rc = nix_aq_context_read(rvu, nix_hw, &aq_req, &aq_rsp, pcifunc,
6140 NIX_AQ_CTYPE_RQ, rq_idx);
6141 if (rc) {
6142 dev_err(rvu->dev,
6143 "%s: Failed to fetch RQ%d context of PFFUNC 0x%x\n",
6144 __func__, rq_idx, pcifunc);
6145 return rc;
6146 }
6147
6148 if (!aq_rsp.rq.policer_ena)
6149 return 0;
6150
6151 /* Get the bandwidth profile ID mapped to this RQ */
6152 leaf_prof = FIELD_PREP(NIX_RQ_PROF_HI_MASK, aq_rsp.rq.band_prof_id_h);
6153 leaf_prof |= aq_rsp.rq.band_prof_id;
6154
6155 ipolicer = &nix_hw->ipolicer[BAND_PROF_LEAF_LAYER];
6156 ipolicer->match_id[leaf_prof] = match_id;
6157
6158 /* Check if any other leaf profile is marked with same match_id */
6159 for (idx = 0; idx < ipolicer->band_prof.max; idx++) {
6160 if (idx == leaf_prof)
6161 continue;
6162 if (ipolicer->match_id[idx] != match_id)
6163 continue;
6164
6165 leaf_match = idx;
6166 break;
6167 }
6168
6169 if (idx == ipolicer->band_prof.max)
6170 return 0;
6171
6172 /* Fetch the matching profile's context to check if it's already
6173 * mapped to a mid level profile.
6174 */
6175 rc = nix_aq_context_read(rvu, nix_hw, &aq_req, &aq_rsp, 0x00,
6176 NIX_AQ_CTYPE_BANDPROF, leaf_match);
6177 if (rc) {
6178 dev_err(rvu->dev,
6179 "%s: Failed to fetch context of leaf profile %d\n",
6180 __func__, leaf_match);
6181 return rc;
6182 }
6183
6184 ipolicer = &nix_hw->ipolicer[BAND_PROF_MID_LAYER];
6185 if (aq_rsp.prof.hl_en) {
6186 /* Get Mid layer prof index and map leaf_prof index
6187 * also such that flows that are being steered
6188 * to different RQs and marked with same match_id
6189 * are rate limited in a aggregate fashion
6190 */
6191 mid_prof = FIELD_PREP(NIX_BW_PROF_HI_MASK,
6192 aq_rsp.prof.band_prof_id_h);
6193 mid_prof |= aq_rsp.prof.band_prof_id;
6194
6195 rc = nix_ipolicer_map_leaf_midprofs(rvu, nix_hw,
6196 &aq_req, &aq_rsp,
6197 leaf_prof, mid_prof);
6198 if (rc) {
6199 dev_err(rvu->dev,
6200 "%s: Failed to map leaf(%d) and mid(%d) profiles\n",
6201 __func__, leaf_prof, mid_prof);
6202 goto exit;
6203 }
6204
6205 mutex_lock(&rvu->rsrc_lock);
6206 ipolicer->ref_count[mid_prof]++;
6207 mutex_unlock(&rvu->rsrc_lock);
6208 goto exit;
6209 }
6210
6211 /* Allocate a mid layer profile and
6212 * map both 'leaf_prof' and 'leaf_match' profiles to it.
6213 */
6214 mutex_lock(&rvu->rsrc_lock);
6215 mid_prof = rvu_alloc_rsrc(&ipolicer->band_prof);
6216 if (mid_prof < 0) {
6217 dev_err(rvu->dev,
6218 "%s: Unable to allocate mid layer profile\n", __func__);
6219 mutex_unlock(&rvu->rsrc_lock);
6220 goto exit;
6221 }
6222 mutex_unlock(&rvu->rsrc_lock);
6223 ipolicer->pfvf_map[mid_prof] = 0x00;
6224 ipolicer->ref_count[mid_prof] = 0;
6225
6226 /* Initialize mid layer profile same as 'leaf_prof' */
6227 rc = nix_aq_context_read(rvu, nix_hw, &aq_req, &aq_rsp, 0x00,
6228 NIX_AQ_CTYPE_BANDPROF, leaf_prof);
6229 if (rc) {
6230 dev_err(rvu->dev,
6231 "%s: Failed to fetch context of leaf profile %d\n",
6232 __func__, leaf_prof);
6233 goto exit;
6234 }
6235
6236 memset(&aq_req, 0, sizeof(struct nix_cn10k_aq_enq_req));
6237 aq_req.hdr.pcifunc = 0x00;
6238 aq_req.qidx = (mid_prof & 0x3FFF) | (BAND_PROF_MID_LAYER << 14);
6239 aq_req.ctype = NIX_AQ_CTYPE_BANDPROF;
6240 aq_req.op = NIX_AQ_INSTOP_WRITE;
6241 memcpy(&aq_req.prof, &aq_rsp.prof, sizeof(struct nix_bandprof_s));
6242 memset((char *)&aq_req.prof_mask, 0xff, sizeof(struct nix_bandprof_s));
6243 /* Clear higher layer enable bit in the mid profile, just in case */
6244 aq_req.prof.hl_en = 0;
6245 aq_req.prof_mask.hl_en = 1;
6246
6247 rc = rvu_nix_blk_aq_enq_inst(rvu, nix_hw,
6248 (struct nix_aq_enq_req *)&aq_req, NULL);
6249 if (rc) {
6250 dev_err(rvu->dev,
6251 "%s: Failed to INIT context of mid layer profile %d\n",
6252 __func__, mid_prof);
6253 goto exit;
6254 }
6255
6256 /* Map both leaf profiles to this mid layer profile */
6257 rc = nix_ipolicer_map_leaf_midprofs(rvu, nix_hw,
6258 &aq_req, &aq_rsp,
6259 leaf_prof, mid_prof);
6260 if (rc) {
6261 dev_err(rvu->dev,
6262 "%s: Failed to map leaf(%d) and mid(%d) profiles\n",
6263 __func__, leaf_prof, mid_prof);
6264 goto exit;
6265 }
6266
6267 mutex_lock(&rvu->rsrc_lock);
6268 ipolicer->ref_count[mid_prof]++;
6269 mutex_unlock(&rvu->rsrc_lock);
6270
6271 rc = nix_ipolicer_map_leaf_midprofs(rvu, nix_hw,
6272 &aq_req, &aq_rsp,
6273 leaf_match, mid_prof);
6274 if (rc) {
6275 dev_err(rvu->dev,
6276 "%s: Failed to map leaf(%d) and mid(%d) profiles\n",
6277 __func__, leaf_match, mid_prof);
6278 ipolicer->ref_count[mid_prof]--;
6279 goto exit;
6280 }
6281
6282 mutex_lock(&rvu->rsrc_lock);
6283 ipolicer->ref_count[mid_prof]++;
6284 mutex_unlock(&rvu->rsrc_lock);
6285
6286 exit:
6287 return rc;
6288 }
6289
6290 /* Called with mutex rsrc_lock */
nix_clear_ratelimit_aggr(struct rvu * rvu,struct nix_hw * nix_hw,u32 leaf_prof)6291 static void nix_clear_ratelimit_aggr(struct rvu *rvu, struct nix_hw *nix_hw,
6292 u32 leaf_prof)
6293 {
6294 struct nix_cn10k_aq_enq_req aq_req;
6295 struct nix_cn10k_aq_enq_rsp aq_rsp;
6296 struct nix_ipolicer *ipolicer;
6297 u16 mid_prof;
6298 int rc;
6299
6300 mutex_unlock(&rvu->rsrc_lock);
6301
6302 rc = nix_aq_context_read(rvu, nix_hw, &aq_req, &aq_rsp, 0x00,
6303 NIX_AQ_CTYPE_BANDPROF, leaf_prof);
6304
6305 mutex_lock(&rvu->rsrc_lock);
6306 if (rc) {
6307 dev_err(rvu->dev,
6308 "%s: Failed to fetch context of leaf profile %d\n",
6309 __func__, leaf_prof);
6310 return;
6311 }
6312
6313 if (!aq_rsp.prof.hl_en)
6314 return;
6315
6316 mid_prof = FIELD_PREP(NIX_BW_PROF_HI_MASK, aq_rsp.prof.band_prof_id_h);
6317 mid_prof |= aq_rsp.prof.band_prof_id;
6318 ipolicer = &nix_hw->ipolicer[BAND_PROF_MID_LAYER];
6319 ipolicer->ref_count[mid_prof]--;
6320 /* If ref_count is zero, free mid layer profile */
6321 if (!ipolicer->ref_count[mid_prof]) {
6322 ipolicer->pfvf_map[mid_prof] = 0x00;
6323 rvu_free_rsrc(&ipolicer->band_prof, mid_prof);
6324 }
6325 }
6326
rvu_mbox_handler_nix_bandprof_get_hwinfo(struct rvu * rvu,struct msg_req * req,struct nix_bandprof_get_hwinfo_rsp * rsp)6327 int rvu_mbox_handler_nix_bandprof_get_hwinfo(struct rvu *rvu, struct msg_req *req,
6328 struct nix_bandprof_get_hwinfo_rsp *rsp)
6329 {
6330 struct nix_ipolicer *ipolicer;
6331 int blkaddr, layer, err;
6332 struct nix_hw *nix_hw;
6333 u64 tu;
6334
6335 if (!rvu->hw->cap.ipolicer)
6336 return NIX_AF_ERR_IPOLICER_NOTSUPP;
6337
6338 err = nix_get_struct_ptrs(rvu, req->hdr.pcifunc, &nix_hw, &blkaddr);
6339 if (err)
6340 return err;
6341
6342 /* Return number of bandwidth profiles free at each layer */
6343 mutex_lock(&rvu->rsrc_lock);
6344 for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
6345 if (layer == BAND_PROF_INVAL_LAYER)
6346 continue;
6347
6348 ipolicer = &nix_hw->ipolicer[layer];
6349 rsp->prof_count[layer] = rvu_rsrc_free_count(&ipolicer->band_prof);
6350 }
6351 mutex_unlock(&rvu->rsrc_lock);
6352
6353 /* Set the policer timeunit in nanosec */
6354 tu = rvu_read64(rvu, blkaddr, NIX_AF_PL_TS) & GENMASK_ULL(9, 0);
6355 rsp->policer_timeunit = (tu + 1) * 100;
6356
6357 return 0;
6358 }
6359
rvu_mbox_handler_nix_rx_sw_sync(struct rvu * rvu,struct msg_req * req,struct msg_rsp * rsp)6360 int rvu_mbox_handler_nix_rx_sw_sync(struct rvu *rvu, struct msg_req *req,
6361 struct msg_rsp *rsp)
6362 {
6363 int blkaddr, nixlf, err;
6364
6365 /* NIX_AF_RX_SW_SYNC is global per NIX block; nix_rx_sync() serializes
6366 * access under rvu->rsrc_lock across mbox and teardown paths.
6367 */
6368 err = nix_get_nixlf(rvu, req->hdr.pcifunc, &nixlf, &blkaddr);
6369 if (err)
6370 return err;
6371
6372 err = nix_rx_sync(rvu, blkaddr);
6373 if (err)
6374 return NIX_AF_ERR_RX_SW_SYNC_FAIL;
6375
6376 return 0;
6377 }
6378
rvu_nix_mcast_find_grp_elem(struct nix_mcast_grp * mcast_grp,u32 mcast_grp_idx)6379 static struct nix_mcast_grp_elem *rvu_nix_mcast_find_grp_elem(struct nix_mcast_grp *mcast_grp,
6380 u32 mcast_grp_idx)
6381 {
6382 struct nix_mcast_grp_elem *iter;
6383 bool is_found = false;
6384
6385 list_for_each_entry(iter, &mcast_grp->mcast_grp_head, list) {
6386 if (iter->mcast_grp_idx == mcast_grp_idx) {
6387 is_found = true;
6388 break;
6389 }
6390 }
6391
6392 if (is_found)
6393 return iter;
6394
6395 return NULL;
6396 }
6397
rvu_nix_mcast_get_mce_index(struct rvu * rvu,u16 pcifunc,u32 mcast_grp_idx)6398 int rvu_nix_mcast_get_mce_index(struct rvu *rvu, u16 pcifunc, u32 mcast_grp_idx)
6399 {
6400 struct nix_mcast_grp_elem *elem;
6401 struct nix_mcast_grp *mcast_grp;
6402 struct nix_hw *nix_hw;
6403 int blkaddr, ret;
6404
6405 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
6406 nix_hw = get_nix_hw(rvu->hw, blkaddr);
6407 if (!nix_hw)
6408 return NIX_AF_ERR_INVALID_NIXBLK;
6409
6410 mcast_grp = &nix_hw->mcast_grp;
6411 mutex_lock(&mcast_grp->mcast_grp_lock);
6412 elem = rvu_nix_mcast_find_grp_elem(mcast_grp, mcast_grp_idx);
6413 if (!elem)
6414 ret = NIX_AF_ERR_INVALID_MCAST_GRP;
6415 else
6416 ret = elem->mce_start_index;
6417
6418 mutex_unlock(&mcast_grp->mcast_grp_lock);
6419 return ret;
6420 }
6421
rvu_nix_mcast_flr_free_entries(struct rvu * rvu,u16 pcifunc)6422 void rvu_nix_mcast_flr_free_entries(struct rvu *rvu, u16 pcifunc)
6423 {
6424 struct nix_mcast_grp_destroy_req dreq = { 0 };
6425 struct nix_mcast_grp_update_req ureq = { 0 };
6426 struct nix_mcast_grp_update_rsp ursp = { 0 };
6427 struct nix_mcast_grp_elem *elem, *tmp;
6428 struct nix_mcast_grp *mcast_grp;
6429 struct nix_hw *nix_hw;
6430 int blkaddr;
6431
6432 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
6433 nix_hw = get_nix_hw(rvu->hw, blkaddr);
6434 if (!nix_hw)
6435 return;
6436
6437 mcast_grp = &nix_hw->mcast_grp;
6438
6439 mutex_lock(&mcast_grp->mcast_grp_lock);
6440 list_for_each_entry_safe(elem, tmp, &mcast_grp->mcast_grp_head, list) {
6441 struct nix_mce_list *mce_list;
6442 struct hlist_node *tmp;
6443 struct mce *mce;
6444
6445 /* If the pcifunc which created the multicast/mirror
6446 * group received an FLR, then delete the entire group.
6447 */
6448 if (elem->pcifunc == pcifunc) {
6449 /* Delete group */
6450 dreq.hdr.pcifunc = elem->pcifunc;
6451 dreq.mcast_grp_idx = elem->mcast_grp_idx;
6452 dreq.is_af = 1;
6453 rvu_mbox_handler_nix_mcast_grp_destroy(rvu, &dreq, NULL);
6454 continue;
6455 }
6456
6457 /* Iterate the group elements and delete the element which
6458 * received the FLR.
6459 */
6460 mce_list = &elem->mcast_mce_list;
6461 hlist_for_each_entry_safe(mce, tmp, &mce_list->head, node) {
6462 if (mce->pcifunc == pcifunc) {
6463 ureq.hdr.pcifunc = pcifunc;
6464 ureq.num_mce_entry = 1;
6465 ureq.mcast_grp_idx = elem->mcast_grp_idx;
6466 ureq.op = NIX_MCAST_OP_DEL_ENTRY;
6467 ureq.pcifunc[0] = pcifunc;
6468 ureq.is_af = 1;
6469 rvu_mbox_handler_nix_mcast_grp_update(rvu, &ureq, &ursp);
6470 break;
6471 }
6472 }
6473 }
6474 mutex_unlock(&mcast_grp->mcast_grp_lock);
6475 }
6476
rvu_nix_mcast_update_mcam_entry(struct rvu * rvu,u16 pcifunc,u32 mcast_grp_idx,u16 mcam_index)6477 int rvu_nix_mcast_update_mcam_entry(struct rvu *rvu, u16 pcifunc,
6478 u32 mcast_grp_idx, u16 mcam_index)
6479 {
6480 struct nix_mcast_grp_elem *elem;
6481 struct nix_mcast_grp *mcast_grp;
6482 struct nix_hw *nix_hw;
6483 int blkaddr, ret = 0;
6484
6485 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
6486 nix_hw = get_nix_hw(rvu->hw, blkaddr);
6487 if (!nix_hw)
6488 return NIX_AF_ERR_INVALID_NIXBLK;
6489
6490 mcast_grp = &nix_hw->mcast_grp;
6491 mutex_lock(&mcast_grp->mcast_grp_lock);
6492 elem = rvu_nix_mcast_find_grp_elem(mcast_grp, mcast_grp_idx);
6493 if (!elem)
6494 ret = NIX_AF_ERR_INVALID_MCAST_GRP;
6495 else
6496 elem->mcam_index = mcam_index;
6497
6498 mutex_unlock(&mcast_grp->mcast_grp_lock);
6499 return ret;
6500 }
6501
rvu_mbox_handler_nix_mcast_grp_create(struct rvu * rvu,struct nix_mcast_grp_create_req * req,struct nix_mcast_grp_create_rsp * rsp)6502 int rvu_mbox_handler_nix_mcast_grp_create(struct rvu *rvu,
6503 struct nix_mcast_grp_create_req *req,
6504 struct nix_mcast_grp_create_rsp *rsp)
6505 {
6506 struct nix_mcast_grp_elem *elem;
6507 struct nix_mcast_grp *mcast_grp;
6508 struct nix_hw *nix_hw;
6509 int blkaddr, err;
6510
6511 err = nix_get_struct_ptrs(rvu, req->hdr.pcifunc, &nix_hw, &blkaddr);
6512 if (err)
6513 return err;
6514
6515 mcast_grp = &nix_hw->mcast_grp;
6516 elem = kzalloc_obj(*elem);
6517 if (!elem)
6518 return -ENOMEM;
6519
6520 INIT_HLIST_HEAD(&elem->mcast_mce_list.head);
6521 elem->mcam_index = -1;
6522 elem->mce_start_index = -1;
6523 elem->pcifunc = req->hdr.pcifunc;
6524 elem->dir = req->dir;
6525 elem->mcast_grp_idx = mcast_grp->next_grp_index++;
6526
6527 mutex_lock(&mcast_grp->mcast_grp_lock);
6528 list_add_tail(&elem->list, &mcast_grp->mcast_grp_head);
6529 mcast_grp->count++;
6530 mutex_unlock(&mcast_grp->mcast_grp_lock);
6531
6532 rsp->mcast_grp_idx = elem->mcast_grp_idx;
6533 return 0;
6534 }
6535
rvu_mbox_handler_nix_mcast_grp_destroy(struct rvu * rvu,struct nix_mcast_grp_destroy_req * req,struct msg_rsp * rsp)6536 int rvu_mbox_handler_nix_mcast_grp_destroy(struct rvu *rvu,
6537 struct nix_mcast_grp_destroy_req *req,
6538 struct msg_rsp *rsp)
6539 {
6540 struct npc_delete_flow_req uninstall_req = { 0 };
6541 struct npc_delete_flow_rsp uninstall_rsp = { 0 };
6542 struct nix_mcast_grp_elem *elem;
6543 struct nix_mcast_grp *mcast_grp;
6544 int blkaddr, err, ret = 0;
6545 struct nix_mcast *mcast;
6546 struct nix_hw *nix_hw;
6547
6548 err = nix_get_struct_ptrs(rvu, req->hdr.pcifunc, &nix_hw, &blkaddr);
6549 if (err)
6550 return err;
6551
6552 mcast_grp = &nix_hw->mcast_grp;
6553
6554 /* If AF is requesting for the deletion,
6555 * then AF is already taking the lock
6556 */
6557 if (!req->is_af)
6558 mutex_lock(&mcast_grp->mcast_grp_lock);
6559
6560 elem = rvu_nix_mcast_find_grp_elem(mcast_grp, req->mcast_grp_idx);
6561 if (!elem) {
6562 ret = NIX_AF_ERR_INVALID_MCAST_GRP;
6563 goto unlock_grp;
6564 }
6565
6566 /* If no mce entries are associated with the group
6567 * then just remove it from the global list.
6568 */
6569 if (!elem->mcast_mce_list.count)
6570 goto delete_grp;
6571
6572 /* Delete the associated mcam entry and
6573 * remove all mce entries from the group
6574 */
6575 mcast = &nix_hw->mcast;
6576 mutex_lock(&mcast->mce_lock);
6577 if (elem->mcam_index != -1) {
6578 uninstall_req.hdr.pcifunc = req->hdr.pcifunc;
6579 uninstall_req.entry = elem->mcam_index;
6580 rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &uninstall_rsp);
6581 }
6582
6583 nix_free_mce_list(mcast, elem->mcast_mce_list.count,
6584 elem->mce_start_index, elem->dir);
6585 nix_delete_mcast_mce_list(&elem->mcast_mce_list);
6586 mutex_unlock(&mcast->mce_lock);
6587
6588 delete_grp:
6589 list_del(&elem->list);
6590 kfree(elem);
6591 mcast_grp->count--;
6592
6593 unlock_grp:
6594 if (!req->is_af)
6595 mutex_unlock(&mcast_grp->mcast_grp_lock);
6596
6597 return ret;
6598 }
6599
rvu_mbox_handler_nix_mcast_grp_update(struct rvu * rvu,struct nix_mcast_grp_update_req * req,struct nix_mcast_grp_update_rsp * rsp)6600 int rvu_mbox_handler_nix_mcast_grp_update(struct rvu *rvu,
6601 struct nix_mcast_grp_update_req *req,
6602 struct nix_mcast_grp_update_rsp *rsp)
6603 {
6604 struct nix_mcast_grp_destroy_req dreq = { 0 };
6605 struct npc_mcam *mcam = &rvu->hw->mcam;
6606 struct nix_mcast_grp_elem *elem;
6607 struct nix_mcast_grp *mcast_grp;
6608 int blkaddr, err, npc_blkaddr;
6609 u16 prev_count, new_count;
6610 struct nix_mcast *mcast;
6611 struct nix_hw *nix_hw;
6612 int i, ret;
6613
6614 if (!req->num_mce_entry)
6615 return 0;
6616
6617 err = nix_get_struct_ptrs(rvu, req->hdr.pcifunc, &nix_hw, &blkaddr);
6618 if (err)
6619 return err;
6620
6621 mcast_grp = &nix_hw->mcast_grp;
6622
6623 /* If AF is requesting for the updation,
6624 * then AF is already taking the lock
6625 */
6626 if (!req->is_af)
6627 mutex_lock(&mcast_grp->mcast_grp_lock);
6628
6629 elem = rvu_nix_mcast_find_grp_elem(mcast_grp, req->mcast_grp_idx);
6630 if (!elem) {
6631 ret = NIX_AF_ERR_INVALID_MCAST_GRP;
6632 goto unlock_grp;
6633 }
6634
6635 /* If any pcifunc matches the group's pcifunc, then we can
6636 * delete the entire group.
6637 */
6638 if (req->op == NIX_MCAST_OP_DEL_ENTRY) {
6639 for (i = 0; i < req->num_mce_entry; i++) {
6640 if (elem->pcifunc == req->pcifunc[i]) {
6641 /* Delete group */
6642 dreq.hdr.pcifunc = elem->pcifunc;
6643 dreq.mcast_grp_idx = elem->mcast_grp_idx;
6644 dreq.is_af = 1;
6645 rvu_mbox_handler_nix_mcast_grp_destroy(rvu, &dreq, NULL);
6646 ret = 0;
6647 goto unlock_grp;
6648 }
6649 }
6650 }
6651
6652 mcast = &nix_hw->mcast;
6653 mutex_lock(&mcast->mce_lock);
6654 npc_blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
6655 if (elem->mcam_index != -1)
6656 npc_enable_mcam_entry(rvu, mcam, npc_blkaddr, elem->mcam_index, false);
6657
6658 prev_count = elem->mcast_mce_list.count;
6659 if (req->op == NIX_MCAST_OP_ADD_ENTRY) {
6660 new_count = prev_count + req->num_mce_entry;
6661 if (prev_count)
6662 nix_free_mce_list(mcast, prev_count, elem->mce_start_index, elem->dir);
6663
6664 elem->mce_start_index = nix_alloc_mce_list(mcast, new_count, elem->dir);
6665
6666 /* It is possible not to get contiguous memory */
6667 if (elem->mce_start_index < 0) {
6668 if (elem->mcam_index != -1) {
6669 npc_enable_mcam_entry(rvu, mcam, npc_blkaddr,
6670 elem->mcam_index, true);
6671 ret = NIX_AF_ERR_NON_CONTIG_MCE_LIST;
6672 goto unlock_mce;
6673 }
6674 }
6675
6676 ret = nix_add_mce_list_entry(rvu, nix_hw, elem, req);
6677 if (ret) {
6678 nix_free_mce_list(mcast, new_count, elem->mce_start_index, elem->dir);
6679 if (prev_count)
6680 elem->mce_start_index = nix_alloc_mce_list(mcast,
6681 prev_count,
6682 elem->dir);
6683
6684 if (elem->mcam_index != -1)
6685 npc_enable_mcam_entry(rvu, mcam, npc_blkaddr,
6686 elem->mcam_index, true);
6687
6688 goto unlock_mce;
6689 }
6690 } else {
6691 if (!prev_count || prev_count < req->num_mce_entry) {
6692 if (elem->mcam_index != -1)
6693 npc_enable_mcam_entry(rvu, mcam, npc_blkaddr,
6694 elem->mcam_index, true);
6695 ret = NIX_AF_ERR_INVALID_MCAST_DEL_REQ;
6696 goto unlock_mce;
6697 }
6698
6699 nix_free_mce_list(mcast, prev_count, elem->mce_start_index, elem->dir);
6700 new_count = prev_count - req->num_mce_entry;
6701 elem->mce_start_index = nix_alloc_mce_list(mcast, new_count, elem->dir);
6702 ret = nix_del_mce_list_entry(rvu, nix_hw, elem, req);
6703 if (ret) {
6704 nix_free_mce_list(mcast, new_count, elem->mce_start_index, elem->dir);
6705 elem->mce_start_index = nix_alloc_mce_list(mcast, prev_count, elem->dir);
6706 if (elem->mcam_index != -1)
6707 npc_enable_mcam_entry(rvu, mcam,
6708 npc_blkaddr,
6709 elem->mcam_index,
6710 true);
6711
6712 goto unlock_mce;
6713 }
6714 }
6715
6716 if (elem->mcam_index == -1) {
6717 rsp->mce_start_index = elem->mce_start_index;
6718 ret = 0;
6719 goto unlock_mce;
6720 }
6721
6722 nix_mcast_update_action(rvu, elem);
6723 npc_enable_mcam_entry(rvu, mcam, npc_blkaddr, elem->mcam_index, true);
6724 rsp->mce_start_index = elem->mce_start_index;
6725 ret = 0;
6726
6727 unlock_mce:
6728 mutex_unlock(&mcast->mce_lock);
6729
6730 unlock_grp:
6731 if (!req->is_af)
6732 mutex_unlock(&mcast_grp->mcast_grp_lock);
6733
6734 return ret;
6735 }
6736
6737 /* On CN10k and older series of silicons, hardware may incorrectly
6738 * assert XOFF on certain channels. Issue a write on NIX_AF_RX_CHANX_CFG
6739 * to broadcacst XON on the same.
6740 */
rvu_block_bcast_xon(struct rvu * rvu,int blkaddr)6741 void rvu_block_bcast_xon(struct rvu *rvu, int blkaddr)
6742 {
6743 struct rvu_block *block = &rvu->hw->block[blkaddr];
6744 u64 cfg;
6745
6746 if (!block->implemented || is_cn20k(rvu->pdev))
6747 return;
6748
6749 cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(0));
6750 rvu_write64(rvu, blkaddr, NIX_AF_RX_CHANX_CFG(0), cfg);
6751 }
6752