xref: /linux/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c (revision 3e20009988e2470063824c58b19d1c80816cc46d)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RVU Admin Function driver
3  *
4  * Copyright (C) 2024 Marvell.
5  *
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/types.h>
10 #include <linux/device.h>
11 #include <linux/module.h>
12 #include <linux/pci.h>
13 
14 #include "rvu.h"
15 #include "rvu_reg.h"
16 
17 #define M(_name, _id, _fn_name, _req_type, _rsp_type)			\
18 static struct _req_type __maybe_unused					\
19 *otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid)		\
20 {									\
21 	struct _req_type *req;						\
22 									\
23 	req = (struct _req_type *)otx2_mbox_alloc_msg_rsp(		\
24 		&rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \
25 		sizeof(struct _rsp_type));				\
26 	if (!req)							\
27 		return NULL;						\
28 	req->hdr.sig = OTX2_MBOX_REQ_SIG;				\
29 	req->hdr.id = _id;						\
30 	return req;							\
31 }
32 
33 MBOX_UP_REP_MESSAGES
34 #undef M
35 
rvu_rep_up_notify(struct rvu * rvu,struct rep_event * event)36 static int rvu_rep_up_notify(struct rvu *rvu, struct rep_event *event)
37 {
38 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, event->pcifunc);
39 	struct rep_event *msg;
40 	int pf;
41 
42 	pf = rvu_get_pf(rvu->pdev, event->pcifunc);
43 
44 	if (event->event & RVU_EVENT_MAC_ADDR_CHANGE)
45 		ether_addr_copy(pfvf->mac_addr, event->evt_data.mac);
46 
47 	mutex_lock(&rvu->mbox_lock);
48 	msg = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf);
49 	if (!msg) {
50 		mutex_unlock(&rvu->mbox_lock);
51 		return -ENOMEM;
52 	}
53 
54 	msg->hdr.pcifunc = event->pcifunc;
55 	msg->event = event->event;
56 
57 	memcpy(&msg->evt_data, &event->evt_data, sizeof(struct rep_evt_data));
58 
59 	otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
60 
61 	otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
62 
63 	otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pf);
64 
65 	mutex_unlock(&rvu->mbox_lock);
66 	return 0;
67 }
68 
rvu_rep_wq_handler(struct work_struct * work)69 static void rvu_rep_wq_handler(struct work_struct *work)
70 {
71 	struct rvu *rvu = container_of(work, struct rvu, rep_evt_work);
72 	struct rep_evtq_ent *qentry;
73 	struct rep_event *event;
74 	unsigned long flags;
75 
76 	do {
77 		spin_lock_irqsave(&rvu->rep_evtq_lock, flags);
78 		qentry = list_first_entry_or_null(&rvu->rep_evtq_head,
79 						  struct rep_evtq_ent,
80 						  node);
81 		if (qentry)
82 			list_del(&qentry->node);
83 
84 		spin_unlock_irqrestore(&rvu->rep_evtq_lock, flags);
85 		if (!qentry)
86 			break; /* nothing more to process */
87 
88 		event = &qentry->event;
89 
90 		rvu_rep_up_notify(rvu, event);
91 		kfree(qentry);
92 	} while (1);
93 }
94 
rvu_mbox_handler_rep_event_notify(struct rvu * rvu,struct rep_event * req,struct msg_rsp * rsp)95 int rvu_mbox_handler_rep_event_notify(struct rvu *rvu, struct rep_event *req,
96 				      struct msg_rsp *rsp)
97 {
98 	struct rep_evtq_ent *qentry;
99 
100 	/* The mailbox dispatcher normalises only the header pcifunc; the
101 	 * nested struct rep_event::pcifunc body field is sender-controlled
102 	 * and is later used by rvu_rep_up_notify() to index rvu->pf[] /
103 	 * rvu->hwvf[].  Reject out-of-range body selectors before queueing.
104 	 */
105 	if (!is_pf_func_valid(rvu, req->pcifunc))
106 		return -EINVAL;
107 
108 	qentry = kmalloc_obj(*qentry, GFP_ATOMIC);
109 	if (!qentry)
110 		return -ENOMEM;
111 
112 	qentry->event = *req;
113 	spin_lock(&rvu->rep_evtq_lock);
114 	list_add_tail(&qentry->node, &rvu->rep_evtq_head);
115 	spin_unlock(&rvu->rep_evtq_lock);
116 	queue_work(rvu->rep_evt_wq, &rvu->rep_evt_work);
117 	return 0;
118 }
119 
rvu_rep_notify_pfvf_state(struct rvu * rvu,u16 pcifunc,bool enable)120 int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable)
121 {
122 	struct rep_event *req;
123 	int pf;
124 
125 	if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)))
126 		return 0;
127 
128 	pf = rvu_get_pf(rvu->pdev, rvu->rep_pcifunc);
129 
130 	mutex_lock(&rvu->mbox_lock);
131 	req = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf);
132 	if (!req) {
133 		mutex_unlock(&rvu->mbox_lock);
134 		return -ENOMEM;
135 	}
136 
137 	req->hdr.pcifunc = rvu->rep_pcifunc;
138 	req->event |= RVU_EVENT_PFVF_STATE;
139 	req->pcifunc = pcifunc;
140 	req->evt_data.vf_state = enable;
141 
142 	otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
143 	otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
144 
145 	mutex_unlock(&rvu->mbox_lock);
146 	return 0;
147 }
148 
149 #define RVU_LF_RX_STATS(reg) \
150 		rvu_read64(rvu, blkaddr, NIX_AF_LFX_RX_STATX(nixlf, reg))
151 
152 #define RVU_LF_TX_STATS(reg) \
153 		rvu_read64(rvu, blkaddr, NIX_AF_LFX_TX_STATX(nixlf, reg))
154 
rvu_mbox_handler_nix_lf_stats(struct rvu * rvu,struct nix_stats_req * req,struct nix_stats_rsp * rsp)155 int rvu_mbox_handler_nix_lf_stats(struct rvu *rvu,
156 				  struct nix_stats_req *req,
157 				  struct nix_stats_rsp *rsp)
158 {
159 	u16 pcifunc = req->pcifunc;
160 	int nixlf, blkaddr, err;
161 	struct msg_req rst_req;
162 	struct msg_rsp rst_rsp;
163 
164 	err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
165 	if (err)
166 		return 0;
167 
168 	if (req->reset) {
169 		rst_req.hdr.pcifunc = pcifunc;
170 		return rvu_mbox_handler_nix_stats_rst(rvu, &rst_req, &rst_rsp);
171 	}
172 	rsp->rx.octs = RVU_LF_RX_STATS(RX_OCTS);
173 	rsp->rx.ucast = RVU_LF_RX_STATS(RX_UCAST);
174 	rsp->rx.bcast = RVU_LF_RX_STATS(RX_BCAST);
175 	rsp->rx.mcast = RVU_LF_RX_STATS(RX_MCAST);
176 	rsp->rx.drop = RVU_LF_RX_STATS(RX_DROP);
177 	rsp->rx.err = RVU_LF_RX_STATS(RX_ERR);
178 	rsp->rx.drop_octs = RVU_LF_RX_STATS(RX_DROP_OCTS);
179 	rsp->rx.drop_mcast = RVU_LF_RX_STATS(RX_DRP_MCAST);
180 	rsp->rx.drop_bcast = RVU_LF_RX_STATS(RX_DRP_BCAST);
181 
182 	rsp->tx.octs = RVU_LF_TX_STATS(TX_OCTS);
183 	rsp->tx.ucast = RVU_LF_TX_STATS(TX_UCAST);
184 	rsp->tx.bcast = RVU_LF_TX_STATS(TX_BCAST);
185 	rsp->tx.mcast = RVU_LF_TX_STATS(TX_MCAST);
186 	rsp->tx.drop = RVU_LF_TX_STATS(TX_DROP);
187 
188 	rsp->pcifunc = req->pcifunc;
189 	return 0;
190 }
191 
rvu_rep_get_vlan_id(struct rvu * rvu,u16 pcifunc)192 static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
193 {
194 	int id;
195 
196 	for (id = 0; id < rvu->rep_cnt; id++)
197 		if (rvu->rep2pfvf_map[id] == pcifunc)
198 			return id;
199 	return 0;
200 }
201 
rvu_rep_tx_vlan_cfg(struct rvu * rvu,u16 pcifunc,u16 vlan_tci,int * vidx)202 static int rvu_rep_tx_vlan_cfg(struct rvu *rvu,  u16 pcifunc,
203 			       u16 vlan_tci, int *vidx)
204 {
205 	struct nix_vtag_config_rsp rsp = {};
206 	struct nix_vtag_config req = {};
207 	u64 etype = ETH_P_8021Q;
208 	int err;
209 
210 	/* Insert vlan tag */
211 	req.hdr.pcifunc = pcifunc;
212 	req.vtag_size = VTAGSIZE_T4;
213 	req.cfg_type = 0; /* tx vlan cfg */
214 	req.tx.cfg_vtag0 = true;
215 	req.tx.vtag0 = FIELD_PREP(NIX_VLAN_ETYPE_MASK, etype) | vlan_tci;
216 
217 	err = rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
218 	if (err) {
219 		dev_err(rvu->dev, "Tx vlan config failed\n");
220 		return err;
221 	}
222 	*vidx = rsp.vtag0_idx;
223 	return 0;
224 }
225 
rvu_rep_rx_vlan_cfg(struct rvu * rvu,u16 pcifunc)226 static int rvu_rep_rx_vlan_cfg(struct rvu *rvu, u16 pcifunc)
227 {
228 	struct nix_vtag_config req = {};
229 	struct nix_vtag_config_rsp rsp;
230 
231 	/* config strip, capture and size */
232 	req.hdr.pcifunc = pcifunc;
233 	req.vtag_size = VTAGSIZE_T4;
234 	req.cfg_type = 1; /* rx vlan cfg */
235 	req.rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0;
236 	req.rx.strip_vtag = true;
237 	req.rx.capture_vtag = false;
238 
239 	return rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
240 }
241 
rvu_rep_install_rx_rule(struct rvu * rvu,u16 pcifunc,u16 entry,bool rte)242 static int rvu_rep_install_rx_rule(struct rvu *rvu, u16 pcifunc,
243 				   u16 entry, bool rte)
244 {
245 	struct npc_install_flow_req req = {};
246 	struct npc_install_flow_rsp rsp = {};
247 	struct rvu_pfvf *pfvf;
248 	u16 vlan_tci, rep_id;
249 
250 	pfvf = rvu_get_pfvf(rvu, pcifunc);
251 
252 	/* To steer the traffic from Representee to Representor */
253 	rep_id = rvu_rep_get_vlan_id(rvu, pcifunc);
254 	if (rte) {
255 		vlan_tci = rep_id | BIT_ULL(8);
256 		req.vf = rvu->rep_pcifunc;
257 		req.op = NIX_RX_ACTIONOP_UCAST;
258 		req.index = rep_id;
259 	} else {
260 		vlan_tci = rep_id;
261 		req.vf = pcifunc;
262 		req.op = NIX_RX_ACTION_DEFAULT;
263 	}
264 
265 	rvu_rep_rx_vlan_cfg(rvu, req.vf);
266 	req.entry = entry;
267 	req.hdr.pcifunc = 0; /* AF is requester */
268 	req.features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_VLAN_ETYPE_CTAG);
269 	req.vtag0_valid = true;
270 	req.vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0;
271 	req.packet.vlan_etype = cpu_to_be16(ETH_P_8021Q);
272 	req.mask.vlan_etype = cpu_to_be16(ETH_P_8021Q);
273 	req.packet.vlan_tci = cpu_to_be16(vlan_tci);
274 	req.mask.vlan_tci = cpu_to_be16(0xffff);
275 
276 	req.channel = RVU_SWITCH_LBK_CHAN;
277 	req.chan_mask = 0xffff;
278 	req.intf = pfvf->nix_rx_intf;
279 
280 	return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
281 }
282 
rvu_rep_install_tx_rule(struct rvu * rvu,u16 pcifunc,u16 entry,bool rte)283 static int rvu_rep_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry,
284 				   bool rte)
285 {
286 	struct npc_install_flow_req req = {};
287 	struct npc_install_flow_rsp rsp = {};
288 	struct rvu_pfvf *pfvf;
289 	int vidx, err;
290 	u16 vlan_tci;
291 	u8 lbkid;
292 
293 	pfvf = rvu_get_pfvf(rvu, pcifunc);
294 	vlan_tci = rvu_rep_get_vlan_id(rvu, pcifunc);
295 	if (rte)
296 		vlan_tci |= BIT_ULL(8);
297 
298 	err = rvu_rep_tx_vlan_cfg(rvu, pcifunc, vlan_tci, &vidx);
299 	if (err)
300 		return err;
301 
302 	lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1;
303 	req.hdr.pcifunc = 0; /* AF is requester */
304 	if (rte) {
305 		req.vf = pcifunc;
306 	} else {
307 		req.vf = rvu->rep_pcifunc;
308 		req.packet.sq_id = vlan_tci;
309 		req.mask.sq_id = 0xffff;
310 	}
311 
312 	req.entry = entry;
313 	req.intf = pfvf->nix_tx_intf;
314 	req.op = NIX_TX_ACTIONOP_UCAST_CHAN;
315 	req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN;
316 	req.set_cntr = 1;
317 	req.vtag0_def = vidx;
318 	req.vtag0_op = 1;
319 	return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
320 }
321 
rvu_rep_install_mcam_rules(struct rvu * rvu)322 int rvu_rep_install_mcam_rules(struct rvu *rvu)
323 {
324 	struct rvu_switch *rswitch = &rvu->rswitch;
325 	u16 start = rswitch->start_entry;
326 	struct rvu_hwinfo *hw = rvu->hw;
327 	u16 pcifunc, entry = 0;
328 	int pf, vf, numvfs;
329 	int err, nixlf, i;
330 	u8 rep;
331 
332 	for (pf = 1; pf < hw->total_pfs; pf++) {
333 		if (!is_pf_cgxmapped(rvu, pf))
334 			continue;
335 
336 		pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
337 		rvu_get_nix_blkaddr(rvu, pcifunc);
338 		rep = true;
339 		for (i = 0; i < 2; i++) {
340 			err = rvu_rep_install_rx_rule(rvu, pcifunc,
341 						      start + entry, rep);
342 			if (err)
343 				return err;
344 			rswitch->entry2pcifunc[entry++] = pcifunc;
345 
346 			err = rvu_rep_install_tx_rule(rvu, pcifunc,
347 						      start + entry, rep);
348 			if (err)
349 				return err;
350 			rswitch->entry2pcifunc[entry++] = pcifunc;
351 			rep = false;
352 		}
353 
354 		rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
355 		for (vf = 0; vf < numvfs; vf++) {
356 			pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf + 1);
357 			rvu_get_nix_blkaddr(rvu, pcifunc);
358 
359 			/* Skip installimg rules if nixlf is not attached */
360 			err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
361 			if (err)
362 				continue;
363 			rep = true;
364 			for (i = 0; i < 2; i++) {
365 				err = rvu_rep_install_rx_rule(rvu, pcifunc,
366 							      start + entry,
367 							      rep);
368 				if (err)
369 					return err;
370 				rswitch->entry2pcifunc[entry++] = pcifunc;
371 
372 				err = rvu_rep_install_tx_rule(rvu, pcifunc,
373 							      start + entry,
374 							      rep);
375 				if (err)
376 					return err;
377 				rswitch->entry2pcifunc[entry++] = pcifunc;
378 				rep = false;
379 			}
380 		}
381 	}
382 
383 	/* Initialize the wq for handling REP events */
384 	spin_lock_init(&rvu->rep_evtq_lock);
385 	INIT_LIST_HEAD(&rvu->rep_evtq_head);
386 	INIT_WORK(&rvu->rep_evt_work, rvu_rep_wq_handler);
387 	rvu->rep_evt_wq = alloc_workqueue("rep_evt_wq", WQ_PERCPU, 0);
388 	if (!rvu->rep_evt_wq) {
389 		dev_err(rvu->dev, "REP workqueue allocation failed\n");
390 		return -ENOMEM;
391 	}
392 	return 0;
393 }
394 
rvu_rep_update_rules(struct rvu * rvu,u16 pcifunc,bool ena)395 void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
396 {
397 	struct rvu_switch *rswitch = &rvu->rswitch;
398 	struct npc_mcam *mcam = &rvu->hw->mcam;
399 	u32 max = rswitch->used_entries;
400 	int blkaddr;
401 	u16 entry;
402 
403 	if (!rswitch->used_entries)
404 		return;
405 
406 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
407 
408 	if (blkaddr < 0)
409 		return;
410 
411 	rvu_switch_enable_lbk_link(rvu, pcifunc, ena);
412 	mutex_lock(&mcam->lock);
413 	for (entry = 0; entry < max; entry++) {
414 		if (rswitch->entry2pcifunc[entry] == pcifunc)
415 			npc_enable_mcam_entry(rvu, mcam, blkaddr, entry, ena);
416 	}
417 	mutex_unlock(&mcam->lock);
418 }
419 
rvu_rep_pf_init(struct rvu * rvu)420 int rvu_rep_pf_init(struct rvu *rvu)
421 {
422 	u16 pcifunc = rvu->rep_pcifunc;
423 	struct rvu_pfvf *pfvf;
424 
425 	pfvf = rvu_get_pfvf(rvu, pcifunc);
426 	set_bit(NIXLF_INITIALIZED, &pfvf->flags);
427 	rvu_switch_enable_lbk_link(rvu, pcifunc, true);
428 	rvu_rep_rx_vlan_cfg(rvu, pcifunc);
429 	return 0;
430 }
431 
rvu_mbox_handler_esw_cfg(struct rvu * rvu,struct esw_cfg_req * req,struct msg_rsp * rsp)432 int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
433 			     struct msg_rsp *rsp)
434 {
435 	if (req->hdr.pcifunc != rvu->rep_pcifunc)
436 		return 0;
437 
438 	rvu->rep_mode = req->ena;
439 
440 	if (!rvu->rep_mode)
441 		rvu_npc_free_mcam_entries(rvu, req->hdr.pcifunc, -1);
442 
443 	return 0;
444 }
445 
rvu_mbox_handler_get_rep_cnt(struct rvu * rvu,struct msg_req * req,struct get_rep_cnt_rsp * rsp)446 int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
447 				 struct get_rep_cnt_rsp *rsp)
448 {
449 	int pf, vf, numvfs, hwvf, rep = 0;
450 	u16 pcifunc;
451 
452 	rvu->rep_pcifunc = req->hdr.pcifunc;
453 	rsp->rep_cnt = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
454 	rvu->rep_cnt = rsp->rep_cnt;
455 
456 	rvu->rep2pfvf_map = devm_kzalloc(rvu->dev, rvu->rep_cnt *
457 					 sizeof(u16), GFP_KERNEL);
458 	if (!rvu->rep2pfvf_map)
459 		return -ENOMEM;
460 
461 	for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
462 		if (!is_pf_cgxmapped(rvu, pf))
463 			continue;
464 		pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
465 		rvu->rep2pfvf_map[rep] = pcifunc;
466 		rsp->rep_pf_map[rep] = pcifunc;
467 		rep++;
468 		rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvf);
469 		for (vf = 0; vf < numvfs; vf++) {
470 			rvu->rep2pfvf_map[rep] = pcifunc |
471 				((vf + 1) & RVU_PFVF_FUNC_MASK);
472 			rsp->rep_pf_map[rep] = rvu->rep2pfvf_map[rep];
473 			rep++;
474 		}
475 	}
476 	return 0;
477 }
478