Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include <arpa/inet.h>
6 : :
7 : : #include "roc_api.h"
8 : : #include "roc_priv.h"
9 : :
10 : : static int
11 : 0 : eswitch_vlan_rx_cfg(uint16_t pcifunc, struct mbox *mbox)
12 : : {
13 : : struct nix_vtag_config *vtag_cfg;
14 : : int rc;
15 : :
16 : 0 : vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox_get(mbox));
17 [ # # ]: 0 : if (!vtag_cfg) {
18 : : rc = -EINVAL;
19 : 0 : goto exit;
20 : : }
21 : :
22 : : /* config strip, capture and size */
23 : 0 : vtag_cfg->hdr.pcifunc = pcifunc;
24 : 0 : vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
25 : 0 : vtag_cfg->cfg_type = VTAG_RX; /* rx vlan cfg */
26 : 0 : vtag_cfg->rx.vtag_type = NIX_RX_VTAG_TYPE0;
27 : 0 : vtag_cfg->rx.strip_vtag = true;
28 : 0 : vtag_cfg->rx.capture_vtag = true;
29 : :
30 : 0 : rc = mbox_process(mbox);
31 [ # # ]: 0 : if (rc)
32 : 0 : goto exit;
33 : :
34 : : rc = 0;
35 : 0 : exit:
36 : : mbox_put(mbox);
37 : 0 : return rc;
38 : : }
39 : :
40 : : static int
41 : 0 : eswitch_vlan_tx_cfg(struct roc_npc_flow *flow, uint16_t pcifunc, struct mbox *mbox,
42 : : uint16_t vlan_tci, uint16_t *vidx)
43 : : {
44 : : struct nix_vtag_config *vtag_cfg;
45 : : struct nix_vtag_config_rsp *rsp;
46 : : int rc;
47 : :
48 : : union {
49 : : uint64_t reg;
50 : : struct nix_tx_vtag_action_s act;
51 : : } tx_vtag_action;
52 : :
53 : 0 : vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox_get(mbox));
54 [ # # ]: 0 : if (!vtag_cfg) {
55 : : rc = -EINVAL;
56 : 0 : goto exit;
57 : : }
58 : :
59 : : /* Insert vlan tag */
60 : 0 : vtag_cfg->hdr.pcifunc = pcifunc;
61 : 0 : vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
62 : 0 : vtag_cfg->cfg_type = VTAG_TX; /* tx vlan cfg */
63 : 0 : vtag_cfg->tx.cfg_vtag0 = true;
64 : 0 : vtag_cfg->tx.vtag0 = (((uint32_t)ROC_ESWITCH_VLAN_TPID << 16) | vlan_tci);
65 : :
66 : : rc = mbox_process_msg(mbox, (void *)&rsp);
67 [ # # ]: 0 : if (rc)
68 : 0 : goto exit;
69 : :
70 [ # # ]: 0 : if (rsp->vtag0_idx < 0) {
71 : 0 : plt_err("Failed to config TX VTAG action");
72 : : rc = -EINVAL;
73 : 0 : goto exit;
74 : : }
75 : :
76 : 0 : *vidx = rsp->vtag0_idx;
77 : 0 : tx_vtag_action.reg = 0;
78 : 0 : tx_vtag_action.act.vtag0_def = rsp->vtag0_idx;
79 : : tx_vtag_action.act.vtag0_lid = NPC_LID_LA;
80 : 0 : tx_vtag_action.act.vtag0_op = NIX_TX_VTAGOP_INSERT;
81 : 0 : tx_vtag_action.act.vtag0_relptr = NIX_TX_VTAGACTION_VTAG0_RELPTR;
82 : :
83 : 0 : flow->vtag_action = tx_vtag_action.reg;
84 : :
85 : : rc = 0;
86 : 0 : exit:
87 : : mbox_put(mbox);
88 : 0 : return rc;
89 : : }
90 : :
91 : : int
92 : 0 : roc_eswitch_npc_mcam_tx_rule(struct roc_npc *roc_npc, struct roc_npc_flow *flow, uint16_t pcifunc,
93 : : uint32_t vlan_tci)
94 : : {
95 : : struct npc *npc = roc_npc_to_npc_priv(roc_npc);
96 : : struct npc_install_flow_req *req;
97 : : struct npc_install_flow_rsp *rsp;
98 : 0 : struct mbox *mbox = npc->mbox;
99 : 0 : uint16_t vidx = 0, lbkid;
100 : : int rc;
101 : :
102 : 0 : rc = eswitch_vlan_tx_cfg(flow, roc_npc->pf_func, mbox, vlan_tci, &vidx);
103 [ # # ]: 0 : if (rc) {
104 : 0 : plt_err("Failed to configure VLAN TX, err %d", rc);
105 : 0 : goto fail;
106 : : }
107 : :
108 : 0 : req = mbox_alloc_msg_npc_install_flow(mbox_get(mbox));
109 [ # # ]: 0 : if (!req) {
110 : : rc = -EINVAL;
111 : 0 : goto exit;
112 : : }
113 : :
114 : : lbkid = 0;
115 : 0 : req->hdr.pcifunc = roc_npc->pf_func; /* Eswitch PF is requester */
116 : 0 : req->vf = pcifunc;
117 : 0 : req->entry = flow->mcam_id;
118 : 0 : req->intf = NPC_MCAM_TX;
119 : 0 : req->op = NIX_TX_ACTIONOP_UCAST_CHAN;
120 : 0 : req->index = (lbkid << 8) | ROC_ESWITCH_LBK_CHAN;
121 : 0 : req->set_cntr = 1;
122 : 0 : req->vtag0_def = vidx;
123 : 0 : req->vtag0_op = 1;
124 : : rc = mbox_process_msg(mbox, (void *)&rsp);
125 [ # # ]: 0 : if (rc)
126 : 0 : goto exit;
127 : :
128 : 0 : flow->nix_intf = NIX_INTF_TX;
129 : 0 : exit:
130 : : mbox_put(mbox);
131 : 0 : fail:
132 : 0 : return rc;
133 : : }
134 : :
135 : : static int
136 : 0 : eswitch_vtag_cfg_delete(struct roc_npc *roc_npc, struct roc_npc_flow *flow)
137 : : {
138 : : struct npc *npc = roc_npc_to_npc_priv(roc_npc);
139 : : struct nix_vtag_config *vtag_cfg;
140 : : struct nix_vtag_config_rsp *rsp;
141 : 0 : struct mbox *mbox = npc->mbox;
142 : : int rc = 0;
143 : :
144 : : union {
145 : : uint64_t reg;
146 : : struct nix_tx_vtag_action_s act;
147 : : } tx_vtag_action;
148 : :
149 : 0 : tx_vtag_action.reg = flow->vtag_action;
150 : 0 : vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox_get(mbox));
151 : :
152 [ # # ]: 0 : if (vtag_cfg == NULL) {
153 : : rc = -ENOSPC;
154 : 0 : goto exit;
155 : : }
156 : :
157 : 0 : vtag_cfg->cfg_type = VTAG_TX;
158 : 0 : vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
159 : 0 : vtag_cfg->tx.vtag0_idx = tx_vtag_action.act.vtag0_def;
160 : 0 : vtag_cfg->tx.free_vtag0 = true;
161 : :
162 : : rc = mbox_process_msg(mbox, (void *)&rsp);
163 [ # # ]: 0 : if (rc)
164 : 0 : goto exit;
165 : :
166 : 0 : rc = rsp->hdr.rc;
167 : 0 : exit:
168 : : mbox_put(mbox);
169 : 0 : return rc;
170 : : }
171 : :
172 : : int
173 : 0 : roc_eswitch_npc_mcam_delete_rule(struct roc_npc *roc_npc, struct roc_npc_flow *flow,
174 : : uint16_t pcifunc)
175 : : {
176 : : struct npc *npc = roc_npc_to_npc_priv(roc_npc);
177 : : struct npc_delete_flow_req *req;
178 : : struct msg_rsp *rsp;
179 : 0 : struct mbox *mbox = npc->mbox;
180 : : int rc = 0;
181 : :
182 : : /* Removing the VLAN TX config */
183 [ # # ]: 0 : if (flow->nix_intf == NIX_INTF_TX) {
184 : 0 : rc = eswitch_vtag_cfg_delete(roc_npc, flow);
185 [ # # ]: 0 : if (rc)
186 : 0 : plt_err("Failed to delete TX vtag config");
187 : : }
188 : :
189 : 0 : req = mbox_alloc_msg_npc_delete_flow(mbox_get(mbox));
190 [ # # ]: 0 : if (!req) {
191 : : rc = -EINVAL;
192 : 0 : goto exit;
193 : : }
194 : :
195 : 0 : req->entry = flow->mcam_id;
196 : 0 : req->vf = pcifunc;
197 : : rc = mbox_process_msg(mbox, (void *)&rsp);
198 [ # # ]: 0 : if (rc)
199 : 0 : goto exit;
200 : :
201 : 0 : rc = rsp->hdr.rc;
202 : 0 : exit:
203 : : mbox_put(mbox);
204 : 0 : return rc;
205 : : }
206 : :
207 : : int
208 : 0 : roc_eswitch_npc_mcam_rx_rule(struct roc_npc *roc_npc, struct roc_npc_flow *flow, uint16_t pcifunc,
209 : : uint16_t vlan_tci, uint16_t vlan_tci_mask)
210 : : {
211 : : struct npc *npc = roc_npc_to_npc_priv(roc_npc);
212 : : struct npc_install_flow_req *req;
213 : : struct npc_install_flow_rsp *rsp;
214 : 0 : struct mbox *mbox = npc->mbox;
215 : : bool is_esw_dev;
216 : : int rc;
217 : :
218 : : /* For ESW PF/VF */
219 [ # # ]: 0 : is_esw_dev = (dev_get_pf(roc_npc->pf_func) == dev_get_pf(pcifunc));
220 : : /* VLAN Rx config */
221 [ # # ]: 0 : if (is_esw_dev) {
222 : 0 : rc = eswitch_vlan_rx_cfg(roc_npc->pf_func, mbox);
223 [ # # ]: 0 : if (rc) {
224 : 0 : plt_err("Failed to configure VLAN RX rule, err %d", rc);
225 : 0 : goto fail;
226 : : }
227 : : }
228 : :
229 : 0 : req = mbox_alloc_msg_npc_install_flow(mbox_get(mbox));
230 [ # # ]: 0 : if (!req) {
231 : : rc = -EINVAL;
232 : 0 : goto exit;
233 : : }
234 : :
235 : 0 : req->vf = pcifunc;
236 : : /* Action */
237 : 0 : req->op = NIX_RX_ACTIONOP_DEFAULT;
238 : 0 : req->index = 0;
239 : 0 : req->entry = flow->mcam_id;
240 : 0 : req->hdr.pcifunc = roc_npc->pf_func; /* Eswitch PF is requester */
241 : 0 : req->features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_VLAN_ETYPE_CTAG);
242 : 0 : req->vtag0_valid = true;
243 : : /* For ESW PF/VF using configured vlan rx cfg while for other
244 : : * representees using standard vlan_type = 7 which is strip.
245 : : */
246 [ # # ]: 0 : req->vtag0_type = is_esw_dev ? NIX_RX_VTAG_TYPE0 : NIX_RX_VTAG_TYPE7;
247 : 0 : req->packet.vlan_etype = ROC_ESWITCH_VLAN_TPID;
248 : 0 : req->mask.vlan_etype = 0xFFFF;
249 : 0 : req->packet.vlan_tci = ntohs(vlan_tci & 0xFFFF);
250 : 0 : req->mask.vlan_tci = ntohs(vlan_tci_mask);
251 : :
252 : 0 : req->channel = ROC_ESWITCH_LBK_CHAN;
253 : 0 : req->chan_mask = 0xffff;
254 : 0 : req->intf = NPC_MCAM_RX;
255 : 0 : req->set_cntr = 1;
256 : 0 : req->cntr_val = flow->ctr_id;
257 : :
258 : : rc = mbox_process_msg(mbox, (void *)&rsp);
259 [ # # ]: 0 : if (rc)
260 : 0 : goto exit;
261 : :
262 : 0 : flow->nix_intf = NIX_INTF_RX;
263 : 0 : exit:
264 : : mbox_put(mbox);
265 : 0 : fail:
266 : 0 : return rc;
267 : : }
268 : :
269 : : int
270 : 0 : roc_eswitch_npc_rss_action_configure(struct roc_npc *roc_npc, struct roc_npc_flow *flow,
271 : : uint32_t flowkey_cfg, uint16_t *reta_tbl)
272 : : {
273 : : struct npc *npc = roc_npc_to_npc_priv(roc_npc);
274 : 0 : struct roc_nix *roc_nix = roc_npc->roc_nix;
275 : : uint32_t rss_grp_idx;
276 : : uint8_t flowkey_algx;
277 : : int rc;
278 : :
279 : 0 : rc = npc_rss_free_grp_get(npc, &rss_grp_idx);
280 : : /* RSS group :0 is not usable for flow rss action */
281 [ # # # # ]: 0 : if (rc < 0 || rss_grp_idx == 0)
282 : : return -ENOSPC;
283 : :
284 : : /* Populating reta table for the specific RSS group */
285 : 0 : rc = roc_nix_rss_reta_set(roc_nix, rss_grp_idx, reta_tbl);
286 [ # # ]: 0 : if (rc) {
287 : 0 : plt_err("Failed to init rss table rc = %d", rc);
288 : 0 : return rc;
289 : : }
290 : :
291 : 0 : rc = roc_nix_rss_flowkey_set(roc_nix, &flowkey_algx, flowkey_cfg, rss_grp_idx,
292 : 0 : flow->mcam_id);
293 [ # # ]: 0 : if (rc) {
294 : 0 : plt_err("Failed to set rss hash function rc = %d", rc);
295 : 0 : return rc;
296 : : }
297 : :
298 : 0 : plt_bitmap_set(npc->rss_grp_entries, rss_grp_idx);
299 : :
300 : 0 : flow->npc_action &= (~(0xfULL));
301 : 0 : flow->npc_action |= NIX_RX_ACTIONOP_RSS;
302 : 0 : flow->npc_action |=
303 : 0 : ((uint64_t)(flowkey_algx & NPC_RSS_ACT_ALG_MASK) << NPC_RSS_ACT_ALG_OFFSET) |
304 : 0 : ((uint64_t)(rss_grp_idx & NPC_RSS_ACT_GRP_MASK) << NPC_RSS_ACT_GRP_OFFSET);
305 : 0 : return 0;
306 : : }
307 : :
308 : : int
309 : 0 : roc_eswitch_nix_vlan_tpid_set(struct roc_nix *roc_nix, uint32_t type, uint16_t tpid, bool is_vf)
310 : : {
311 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
312 : : struct dev *dev = &nix->dev;
313 : : int rc;
314 : :
315 : : /* Configuring for PF/VF */
316 : 0 : rc = nix_vlan_tpid_set(dev->mbox, dev->pf_func | is_vf, type, tpid);
317 [ # # ]: 0 : if (rc)
318 : 0 : plt_err("Failed to set tpid for PF, rc %d", rc);
319 : :
320 : 0 : return rc;
321 : : }
322 : :
323 : : int
324 : 0 : roc_eswitch_nix_process_repte_notify_cb_register(struct roc_nix *roc_nix,
325 : : process_repte_notify_t proc_repte_nt)
326 : : {
327 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
328 : : struct dev *dev = &nix->dev;
329 : :
330 [ # # ]: 0 : if (proc_repte_nt == NULL)
331 : : return NIX_ERR_PARAM;
332 : :
333 : 0 : dev->ops->repte_notify = (repte_notify_t)proc_repte_nt;
334 : 0 : return 0;
335 : : }
336 : :
337 : : void
338 : 0 : roc_eswitch_nix_process_repte_notify_cb_unregister(struct roc_nix *roc_nix)
339 : : {
340 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
341 : : struct dev *dev = &nix->dev;
342 : :
343 : 0 : dev->ops->repte_notify = NULL;
344 : 0 : }
345 : :
346 : : int
347 : 0 : roc_eswitch_nix_repte_stats(struct roc_nix *roc_nix, uint16_t pf_func, struct roc_nix_stats *stats)
348 : : {
349 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
350 : : struct dev *dev = &nix->dev;
351 : : struct nix_get_lf_stats_req *req;
352 : : struct nix_lf_stats_rsp *rsp;
353 : : struct mbox *mbox;
354 : : int rc;
355 : :
356 : 0 : mbox = mbox_get(dev->mbox);
357 : 0 : req = mbox_alloc_msg_nix_get_lf_stats(mbox);
358 [ # # ]: 0 : if (!req) {
359 : : rc = -ENOSPC;
360 : 0 : goto exit;
361 : : }
362 : :
363 : 0 : req->hdr.pcifunc = roc_nix_get_pf_func(roc_nix);
364 : 0 : req->pcifunc = pf_func;
365 : :
366 : : rc = mbox_process_msg(mbox, (void *)&rsp);
367 [ # # ]: 0 : if (rc)
368 : 0 : goto exit;
369 : :
370 : 0 : stats->rx_octs = rsp->rx.octs;
371 : 0 : stats->rx_ucast = rsp->rx.ucast;
372 : 0 : stats->rx_bcast = rsp->rx.bcast;
373 : 0 : stats->rx_mcast = rsp->rx.mcast;
374 : 0 : stats->rx_drop = rsp->rx.drop;
375 : 0 : stats->rx_drop_octs = rsp->rx.drop_octs;
376 : 0 : stats->rx_drop_bcast = rsp->rx.drop_bcast;
377 : 0 : stats->rx_drop_mcast = rsp->rx.drop_mcast;
378 : 0 : stats->rx_err = rsp->rx.err;
379 : :
380 : 0 : stats->tx_ucast = rsp->tx.ucast;
381 : 0 : stats->tx_bcast = rsp->tx.bcast;
382 : 0 : stats->tx_mcast = rsp->tx.mcast;
383 : 0 : stats->tx_drop = rsp->tx.drop;
384 : 0 : stats->tx_octs = rsp->tx.octs;
385 : :
386 : 0 : exit:
387 : : mbox_put(mbox);
388 : 0 : return rc;
389 : : }
390 : :
391 : : int
392 [ # # ]: 0 : roc_eswitch_is_repte_pfs_vf(uint16_t rep_pffunc, uint16_t pf_pffunc)
393 : : {
394 : : uint16_t rep_pf = dev_get_pf(rep_pffunc);
395 : :
396 [ # # ]: 0 : if (roc_model_is_cn20k())
397 : 0 : return ((rep_pf << RVU_PFVF_PF_SHIFT_CN20K) == pf_pffunc);
398 : : else
399 : 0 : return ((rep_pf << RVU_PFVF_PF_SHIFT) == pf_pffunc);
400 : : }
|