xref: /linux/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c (revision 056994563935e049093f100efaad7e63ad113814)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RVU Ethernet driver
3  *
4  * Copyright (C) 2024 Marvell.
5  *
6  */
7 
8 #include "otx2_common.h"
9 #include "otx2_reg.h"
10 #include "otx2_struct.h"
11 #include "cn10k.h"
12 
13 /* CN20K mbox AF => PFx irq handler */
14 irqreturn_t cn20k_pfaf_mbox_intr_handler(int irq, void *pf_irq)
15 {
16 	struct otx2_nic *pf = pf_irq;
17 	struct mbox *mw = &pf->mbox;
18 	struct otx2_mbox_dev *mdev;
19 	struct otx2_mbox *mbox;
20 	struct mbox_hdr *hdr;
21 	u64 pf_trig_val;
22 
23 	pf_trig_val = otx2_read64(pf, RVU_PF_INT) & 0x3ULL;
24 
25 	/* Clear the IRQ */
26 	otx2_write64(pf, RVU_PF_INT, pf_trig_val);
27 
28 	if (pf_trig_val & BIT_ULL(0)) {
29 		mbox = &mw->mbox_up;
30 		mdev = &mbox->dev[0];
31 		otx2_sync_mbox_bbuf(mbox, 0);
32 
33 		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
34 		if (hdr->num_msgs)
35 			queue_work(pf->mbox_wq, &mw->mbox_up_wrk);
36 
37 		trace_otx2_msg_interrupt(pf->pdev, "UP message from AF to PF",
38 					 BIT_ULL(0));
39 	}
40 
41 	if (pf_trig_val & BIT_ULL(1)) {
42 		mbox = &mw->mbox;
43 		mdev = &mbox->dev[0];
44 		otx2_sync_mbox_bbuf(mbox, 0);
45 
46 		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
47 		if (hdr->num_msgs)
48 			queue_work(pf->mbox_wq, &mw->mbox_wrk);
49 		trace_otx2_msg_interrupt(pf->pdev, "DOWN reply from AF to PF",
50 					 BIT_ULL(1));
51 	}
52 
53 	return IRQ_HANDLED;
54 }
55 
56 irqreturn_t cn20k_vfaf_mbox_intr_handler(int irq, void *vf_irq)
57 {
58 	struct otx2_nic *vf = vf_irq;
59 	struct otx2_mbox_dev *mdev;
60 	struct otx2_mbox *mbox;
61 	struct mbox_hdr *hdr;
62 	u64 vf_trig_val;
63 
64 	vf_trig_val = otx2_read64(vf, RVU_VF_INT) & 0x3ULL;
65 	/* Clear the IRQ */
66 	otx2_write64(vf, RVU_VF_INT, vf_trig_val);
67 
68 	/* Read latest mbox data */
69 	smp_rmb();
70 
71 	if (vf_trig_val & BIT_ULL(1)) {
72 		/* Check for PF => VF response messages */
73 		mbox = &vf->mbox.mbox;
74 		mdev = &mbox->dev[0];
75 		otx2_sync_mbox_bbuf(mbox, 0);
76 
77 		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
78 		if (hdr->num_msgs)
79 			queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
80 
81 		trace_otx2_msg_interrupt(mbox->pdev, "DOWN reply from PF0 to VF",
82 					 BIT_ULL(1));
83 	}
84 
85 	if (vf_trig_val & BIT_ULL(0)) {
86 		/* Check for PF => VF notification messages */
87 		mbox = &vf->mbox.mbox_up;
88 		mdev = &mbox->dev[0];
89 		otx2_sync_mbox_bbuf(mbox, 0);
90 
91 		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
92 		if (hdr->num_msgs)
93 			queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
94 
95 		trace_otx2_msg_interrupt(mbox->pdev, "UP message from PF0 to VF",
96 					 BIT_ULL(0));
97 	}
98 
99 	return IRQ_HANDLED;
100 }
101 
102 void cn20k_enable_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
103 {
104 	/* Clear PF <=> VF mailbox IRQ */
105 	otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(0), ~0ull);
106 	otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(1), ~0ull);
107 	otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(0), ~0ull);
108 	otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(1), ~0ull);
109 
110 	/* Enable PF <=> VF mailbox IRQ */
111 	otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(0), INTR_MASK(numvfs));
112 	otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(0), INTR_MASK(numvfs));
113 	if (numvfs > 64) {
114 		numvfs -= 64;
115 		otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(1),
116 			     INTR_MASK(numvfs));
117 		otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(1),
118 			     INTR_MASK(numvfs));
119 	}
120 }
121 
122 void cn20k_disable_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
123 {
124 	int vector, intr_vec, vec = 0;
125 
126 	/* Disable PF <=> VF mailbox IRQ */
127 	otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(0), ~0ull);
128 	otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(1), ~0ull);
129 	otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(0), ~0ull);
130 	otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(1), ~0ull);
131 
132 	otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(0), ~0ull);
133 	otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(0), ~0ull);
134 
135 	if (numvfs > 64) {
136 		otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(1), ~0ull);
137 		otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(1), ~0ull);
138 	}
139 
140 	for (intr_vec = RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <=
141 			RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1; intr_vec++, vec++) {
142 		vector = pci_irq_vector(pf->pdev, intr_vec);
143 		free_irq(vector, pf->hw.pfvf_irq_devid[vec]);
144 	}
145 }
146 
147 irqreturn_t cn20k_pfvf_mbox_intr_handler(int irq, void *pf_irq)
148 {
149 	struct pf_irq_data *irq_data = pf_irq;
150 	struct otx2_nic *pf = irq_data->pf;
151 	struct mbox *mbox;
152 	u64 intr;
153 
154 	/* Sync with mbox memory region */
155 	rmb();
156 
157 	/* Clear interrupts */
158 	intr = otx2_read64(pf, irq_data->intr_status);
159 	otx2_write64(pf, irq_data->intr_status, intr);
160 	mbox = pf->mbox_pfvf;
161 
162 	if (intr)
163 		trace_otx2_msg_interrupt(pf->pdev, "VF(s) to PF", intr);
164 
165 	irq_data->pf_queue_work_hdlr(mbox, pf->mbox_pfvf_wq, irq_data->start,
166 				     irq_data->mdevs, intr);
167 
168 	return IRQ_HANDLED;
169 }
170 
171 int cn20k_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
172 {
173 	struct otx2_hw *hw = &pf->hw;
174 	struct pf_irq_data *irq_data;
175 	int intr_vec, ret, vec = 0;
176 	char *irq_name;
177 
178 	/* irq data for 4 PF intr vectors */
179 	irq_data = devm_kcalloc(pf->dev, 4,
180 				sizeof(struct pf_irq_data), GFP_KERNEL);
181 	if (!irq_data)
182 		return -ENOMEM;
183 
184 	for (intr_vec = RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <=
185 			RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1; intr_vec++, vec++) {
186 		switch (intr_vec) {
187 		case RVU_MBOX_PF_INT_VEC_VFPF_MBOX0:
188 			irq_data[vec].intr_status =
189 						RVU_MBOX_PF_VFPF_INTX(0);
190 			irq_data[vec].start = 0;
191 			irq_data[vec].mdevs = 64;
192 			break;
193 		case RVU_MBOX_PF_INT_VEC_VFPF_MBOX1:
194 			irq_data[vec].intr_status =
195 						RVU_MBOX_PF_VFPF_INTX(1);
196 			irq_data[vec].start = 64;
197 			irq_data[vec].mdevs = 96;
198 			break;
199 		case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0:
200 			irq_data[vec].intr_status =
201 						RVU_MBOX_PF_VFPF1_INTX(0);
202 			irq_data[vec].start = 0;
203 			irq_data[vec].mdevs = 64;
204 			break;
205 		case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1:
206 			irq_data[vec].intr_status =
207 						RVU_MBOX_PF_VFPF1_INTX(1);
208 			irq_data[vec].start = 64;
209 			irq_data[vec].mdevs = 96;
210 			break;
211 		}
212 		irq_data[vec].pf_queue_work_hdlr = otx2_queue_vf_work;
213 		irq_data[vec].vec_num = intr_vec;
214 		irq_data[vec].pf = pf;
215 
216 		/* Register mailbox interrupt handler */
217 		irq_name = &hw->irq_name[intr_vec * NAME_SIZE];
218 		if (pf->pcifunc)
219 			snprintf(irq_name, NAME_SIZE,
220 				 "RVUPF%d_VF%d Mbox%d", rvu_get_pf(pf->pdev,
221 				 pf->pcifunc), vec / 2, vec % 2);
222 		else
223 			snprintf(irq_name, NAME_SIZE, "RVUPF_VF%d Mbox%d",
224 				 vec / 2, vec % 2);
225 
226 		hw->pfvf_irq_devid[vec] = &irq_data[vec];
227 		ret = request_irq(pci_irq_vector(pf->pdev, intr_vec),
228 				  pf->hw_ops->pfvf_mbox_intr_handler, 0,
229 				  irq_name,
230 				  &irq_data[vec]);
231 		if (ret) {
232 			dev_err(pf->dev,
233 				"RVUPF: IRQ registration failed for PFVF mbox0 irq\n");
234 			return ret;
235 		}
236 	}
237 
238 	cn20k_enable_pfvf_mbox_intr(pf, numvfs);
239 
240 	return 0;
241 }
242 
243 #define RQ_BP_LVL_AURA   (255 - ((85 * 256) / 100)) /* BP when 85% is full */
244 
245 static int cn20k_tc_get_entry_index(struct otx2_flow_config *flow_cfg,
246 				    struct otx2_tc_flow *node)
247 {
248 	struct otx2_tc_flow *tmp;
249 	int index = 0;
250 
251 	list_for_each_entry(tmp, &flow_cfg->flow_list_tc, list) {
252 		if (tmp == node)
253 			return index;
254 
255 		index++;
256 	}
257 
258 	return -1;
259 }
260 
261 int cn20k_tc_free_mcam_entry(struct otx2_nic *nic, u16 entry)
262 {
263 	struct npc_mcam_free_entry_req *req;
264 	int err;
265 
266 	mutex_lock(&nic->mbox.lock);
267 	req = otx2_mbox_alloc_msg_npc_mcam_free_entry(&nic->mbox);
268 	if (!req) {
269 		mutex_unlock(&nic->mbox.lock);
270 		return -ENOMEM;
271 	}
272 
273 	req->entry = entry;
274 	/* Send message to AF to free MCAM entries */
275 	err = otx2_sync_mbox_msg(&nic->mbox);
276 	if (err) {
277 		mutex_unlock(&nic->mbox.lock);
278 		return err;
279 	}
280 
281 	mutex_unlock(&nic->mbox.lock);
282 
283 	return 0;
284 }
285 
286 static bool cn20k_tc_check_entry_shiftable(struct otx2_nic *nic,
287 					   struct otx2_flow_config *flow_cfg,
288 					   struct otx2_tc_flow *node, int index,
289 					   bool error)
290 {
291 	struct otx2_tc_flow *first, *tmp, *n;
292 	u32 prio = 0;
293 	int i = 0;
294 	u8 type;
295 
296 	first = list_first_entry(&flow_cfg->flow_list_tc, struct otx2_tc_flow,
297 				 list);
298 	type = first->kw_type;
299 
300 	/* Check all the nodes from start to given index (including index) has
301 	 * same type i.e, either X2 or X4
302 	 */
303 	list_for_each_entry_safe(tmp, n, &flow_cfg->flow_list_tc, list) {
304 		if (i > index)
305 			break;
306 
307 		if (type != tmp->kw_type) {
308 			/* List has both X2 and X4 entries so entries cannot be
309 			 * shifted to save MCAM space.
310 			 */
311 			if (error)
312 				dev_err(nic->dev, "Rule %d cannot be shifted to %d\n",
313 					tmp->prio, prio);
314 			return false;
315 		}
316 
317 		type = tmp->kw_type;
318 		prio = tmp->prio;
319 		i++;
320 	}
321 
322 	return true;
323 }
324 
325 void cn20k_tc_update_mcam_table_del_req(struct otx2_nic *nic,
326 					struct otx2_flow_config *flow_cfg,
327 					struct otx2_tc_flow *node)
328 {
329 	struct otx2_tc_flow *first, *tmp, *n;
330 	int i = 0, index;
331 	u16 cntr_val = 0;
332 	u16 entry;
333 
334 	index = cn20k_tc_get_entry_index(flow_cfg, node);
335 	if (index < 0) {
336 		netdev_dbg(nic->netdev, "Could not find node\n");
337 		return;
338 	}
339 
340 	first = list_first_entry(&flow_cfg->flow_list_tc, struct otx2_tc_flow,
341 				 list);
342 	entry = first->entry;
343 
344 	/* If entries cannot be shifted then delete given entry
345 	 * and free it to AF too.
346 	 */
347 	if (!cn20k_tc_check_entry_shiftable(nic, flow_cfg, node,
348 					    index, false)) {
349 		list_del(&node->list);
350 		entry = node->entry;
351 		goto free_mcam_entry;
352 	}
353 
354 	/* Find and delete the entry from the list and re-install
355 	 * all the entries from beginning to the index of the
356 	 * deleted entry to higher mcam indexes.
357 	 */
358 	list_for_each_entry_safe(tmp, n, &flow_cfg->flow_list_tc, list) {
359 		if (node == tmp) {
360 			list_del(&tmp->list);
361 			break;
362 		}
363 
364 		otx2_del_mcam_flow_entry(nic, tmp->entry, &cntr_val);
365 		tmp->entry = (list_next_entry(tmp, list))->entry;
366 		tmp->req.entry = tmp->entry;
367 		tmp->req.cntr_val = cntr_val;
368 	}
369 
370 	list_for_each_entry_safe(tmp, n, &flow_cfg->flow_list_tc, list) {
371 		if (i == index)
372 			break;
373 
374 		otx2_add_mcam_flow_entry(nic, &tmp->req);
375 		i++;
376 	}
377 
378 free_mcam_entry:
379 	if (cn20k_tc_free_mcam_entry(nic, entry))
380 		netdev_err(nic->netdev, "Freeing entry %d to AF failed\n",
381 			   entry);
382 }
383 
384 int cn20k_tc_update_mcam_table_add_req(struct otx2_nic *nic,
385 				       struct otx2_flow_config *flow_cfg,
386 				       struct otx2_tc_flow *node)
387 {
388 	struct otx2_tc_flow *tmp;
389 	u16 cntr_val = 0;
390 	int list_idx, i;
391 	int entry, prev;
392 
393 	/* Find the index of the entry(list_idx) whose priority
394 	 * is greater than the new entry and re-install all
395 	 * the entries from beginning to list_idx to higher
396 	 * mcam indexes.
397 	 */
398 	list_idx = otx2_tc_add_to_flow_list(flow_cfg, node);
399 	entry = node->entry;
400 	if (!cn20k_tc_check_entry_shiftable(nic, flow_cfg, node,
401 					    list_idx, true))
402 		/* Due to mix of X2 and X4, entries cannot be shifted.
403 		 * In this case free the entry allocated for this rule.
404 		 */
405 		return -EINVAL;
406 
407 	for (i = 0; i < list_idx; i++) {
408 		tmp = otx2_tc_get_entry_by_index(flow_cfg, i);
409 		if (!tmp)
410 			return -ENOMEM;
411 
412 		otx2_del_mcam_flow_entry(nic, tmp->entry, &cntr_val);
413 		prev = tmp->entry;
414 		tmp->entry = entry;
415 		tmp->req.entry = tmp->entry;
416 		tmp->req.cntr_val = cntr_val;
417 		otx2_add_mcam_flow_entry(nic, &tmp->req);
418 		entry = prev;
419 	}
420 
421 	return entry;
422 }
423 
424 #define MAX_TC_HW_PRIORITY		125
425 #define MAX_TC_VF_PRIORITY		126
426 #define MAX_TC_PF_PRIORITY		127
427 
428 static int __cn20k_tc_alloc_entry(struct otx2_nic *nic,
429 				  struct npc_install_flow_req *flow_req,
430 				  u16 *entry, u8 *type,
431 				  u32 tc_priority, bool hw_priority)
432 {
433 	struct otx2_flow_config *flow_cfg = nic->flow_cfg;
434 	struct npc_install_flow_req *req;
435 	struct npc_install_flow_rsp *rsp;
436 	struct otx2_tc_flow *tmp;
437 	int ret = 0;
438 
439 	req = otx2_mbox_alloc_msg_npc_install_flow(&nic->mbox);
440 	if (!req)
441 		return -ENOMEM;
442 
443 	memcpy(&flow_req->hdr, &req->hdr, sizeof(struct mbox_msghdr));
444 	memcpy(req, flow_req, sizeof(struct npc_install_flow_req));
445 	req->alloc_entry = 1;
446 
447 	/* Allocate very least priority for first rule */
448 	if (hw_priority || list_empty(&flow_cfg->flow_list_tc)) {
449 		req->ref_prio = NPC_MCAM_LEAST_PRIO;
450 	} else {
451 		req->ref_prio = NPC_MCAM_HIGHER_PRIO;
452 		tmp = list_first_entry(&flow_cfg->flow_list_tc,
453 				       struct otx2_tc_flow, list);
454 		req->ref_entry = tmp->entry;
455 	}
456 
457 	ret = otx2_sync_mbox_msg(&nic->mbox);
458 	if (ret)
459 		return ret;
460 
461 	rsp = (struct npc_install_flow_rsp *)otx2_mbox_get_rsp(&nic->mbox.mbox,
462 							       0, &req->hdr);
463 	if (IS_ERR(rsp))
464 		return -EFAULT;
465 
466 	if (entry)
467 		*entry = rsp->entry;
468 	if (type)
469 		*type = rsp->kw_type;
470 
471 	return ret;
472 }
473 
474 int cn20k_tc_alloc_entry(struct otx2_nic *nic,
475 			 struct flow_cls_offload *tc_flow_cmd,
476 			 struct otx2_tc_flow *new_node,
477 			 struct npc_install_flow_req *flow_req)
478 {
479 	bool hw_priority = false;
480 	u16 entry_from_af;
481 	u8 entry_type;
482 	int ret;
483 
484 	if (is_otx2_vf(nic->pcifunc))
485 		flow_req->hw_prio = MAX_TC_VF_PRIORITY;
486 	else
487 		flow_req->hw_prio = MAX_TC_PF_PRIORITY;
488 
489 	if (new_node->prio <= MAX_TC_HW_PRIORITY) {
490 		flow_req->hw_prio = new_node->prio;
491 		hw_priority = true;
492 	}
493 
494 	mutex_lock(&nic->mbox.lock);
495 
496 	ret = __cn20k_tc_alloc_entry(nic, flow_req, &entry_from_af, &entry_type,
497 				     new_node->prio, hw_priority);
498 	if (ret) {
499 		mutex_unlock(&nic->mbox.lock);
500 		return ret;
501 	}
502 
503 	new_node->kw_type = entry_type;
504 	new_node->entry = entry_from_af;
505 
506 	mutex_unlock(&nic->mbox.lock);
507 
508 	return 0;
509 }
510 
511 static int cn20k_aura_aq_init(struct otx2_nic *pfvf, int aura_id,
512 			      int pool_id, int numptrs)
513 {
514 	struct npa_cn20k_aq_enq_req *aq;
515 	struct otx2_pool *pool;
516 	u8 bpid_idx;
517 	int err;
518 
519 	pool = &pfvf->qset.pool[pool_id];
520 
521 	/* Allocate memory for HW to update Aura count.
522 	 * Alloc one cache line, so that it fits all FC_STYPE modes.
523 	 */
524 	if (!pool->fc_addr) {
525 		err = qmem_alloc(pfvf->dev, &pool->fc_addr, 1, OTX2_ALIGN);
526 		if (err)
527 			return err;
528 	}
529 
530 	/* Initialize this aura's context via AF */
531 	aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
532 	if (!aq) {
533 		/* Shared mbox memory buffer is full, flush it and retry */
534 		err = otx2_sync_mbox_msg(&pfvf->mbox);
535 		if (err)
536 			return err;
537 		aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
538 		if (!aq)
539 			return -ENOMEM;
540 	}
541 
542 	aq->aura_id = aura_id;
543 
544 	/* Will be filled by AF with correct pool context address */
545 	aq->aura.pool_addr = pool_id;
546 	aq->aura.pool_caching = 1;
547 	aq->aura.shift = ilog2(numptrs) - 8;
548 	aq->aura.count = numptrs;
549 	aq->aura.limit = numptrs;
550 	aq->aura.avg_level = 255;
551 	aq->aura.ena = 1;
552 	aq->aura.fc_ena = 1;
553 	aq->aura.fc_addr = pool->fc_addr->iova;
554 	aq->aura.fc_hyst_bits = 0; /* Store count on all updates */
555 
556 	/* Enable backpressure for RQ aura */
557 	if (aura_id < pfvf->hw.rqpool_cnt && !is_otx2_lbkvf(pfvf->pdev)) {
558 		aq->aura.bp_ena = 0;
559 		/* If NIX1 LF is attached then specify NIX1_RX.
560 		 *
561 		 * Below NPA_AURA_S[BP_ENA] is set according to the
562 		 * NPA_BPINTF_E enumeration given as:
563 		 * 0x0 + a*0x1 where 'a' is 0 for NIX0_RX and 1 for NIX1_RX so
564 		 * NIX0_RX is 0x0 + 0*0x1 = 0
565 		 * NIX1_RX is 0x0 + 1*0x1 = 1
566 		 * But in HRM it is given that
567 		 * "NPA_AURA_S[BP_ENA](w1[33:32]) - Enable aura backpressure to
568 		 * NIX-RX based on [BP] level. One bit per NIX-RX; index
569 		 * enumerated by NPA_BPINTF_E."
570 		 */
571 		if (pfvf->nix_blkaddr == BLKADDR_NIX1)
572 			aq->aura.bp_ena = 1;
573 
574 		bpid_idx = otx2_get_bpid_idx(pfvf, aura_id);
575 		aq->aura.bpid = pfvf->bpid[bpid_idx];
576 
577 		/* Set backpressure level for RQ's Aura */
578 		aq->aura.bp = RQ_BP_LVL_AURA;
579 	}
580 
581 	/* Fill AQ info */
582 	aq->ctype = NPA_AQ_CTYPE_AURA;
583 	aq->op = NPA_AQ_INSTOP_INIT;
584 
585 	return 0;
586 }
587 
588 static int cn20k_pool_aq_init(struct otx2_nic *pfvf, u16 pool_id,
589 			      int stack_pages, int numptrs, int buf_size,
590 			      int type)
591 {
592 	struct page_pool_params pp_params = { 0 };
593 	struct npa_cn20k_aq_enq_req *aq;
594 	struct otx2_pool *pool;
595 	int err, sz;
596 
597 	pool = &pfvf->qset.pool[pool_id];
598 	/* Alloc memory for stack which is used to store buffer pointers */
599 	err = qmem_alloc(pfvf->dev, &pool->stack,
600 			 stack_pages, pfvf->hw.stack_pg_bytes);
601 	if (err)
602 		return err;
603 
604 	pool->rbsize = buf_size;
605 
606 	/* Initialize this pool's context via AF */
607 	aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
608 	if (!aq) {
609 		/* Shared mbox memory buffer is full, flush it and retry */
610 		err = otx2_sync_mbox_msg(&pfvf->mbox);
611 		if (err) {
612 			qmem_free(pfvf->dev, pool->stack);
613 			pool->stack = NULL;
614 			return err;
615 		}
616 		aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
617 		if (!aq) {
618 			qmem_free(pfvf->dev, pool->stack);
619 			pool->stack = NULL;
620 			return -ENOMEM;
621 		}
622 	}
623 
624 	aq->aura_id = pool_id;
625 	aq->pool.stack_base = pool->stack->iova;
626 	aq->pool.stack_caching = 1;
627 	aq->pool.ena = 1;
628 	aq->pool.buf_size = buf_size / 128;
629 	aq->pool.stack_max_pages = stack_pages;
630 	aq->pool.shift = ilog2(numptrs) - 8;
631 	aq->pool.ptr_start = 0;
632 	aq->pool.ptr_end = ~0ULL;
633 
634 	/* Fill AQ info */
635 	aq->ctype = NPA_AQ_CTYPE_POOL;
636 	aq->op = NPA_AQ_INSTOP_INIT;
637 
638 	if (type != AURA_NIX_RQ) {
639 		pool->page_pool = NULL;
640 		return 0;
641 	}
642 
643 	sz = ALIGN(ALIGN(SKB_DATA_ALIGN(buf_size), OTX2_ALIGN), PAGE_SIZE);
644 	pp_params.order = get_order(sz);
645 	pp_params.flags = PP_FLAG_DMA_MAP;
646 	pp_params.pool_size = min(OTX2_PAGE_POOL_SZ, numptrs);
647 	pp_params.nid = NUMA_NO_NODE;
648 	pp_params.dev = pfvf->dev;
649 	pp_params.dma_dir = DMA_FROM_DEVICE;
650 	pp_params.netdev = pfvf->netdev;
651 	pool->page_pool = page_pool_create(&pp_params);
652 	if (IS_ERR(pool->page_pool)) {
653 		netdev_err(pfvf->netdev, "Creation of page pool failed\n");
654 		return PTR_ERR(pool->page_pool);
655 	}
656 
657 	return 0;
658 }
659 
660 static int cn20k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura)
661 {
662 	struct nix_cn20k_aq_enq_req *aq;
663 	struct otx2_nic *pfvf = dev;
664 
665 	/* Get memory to put this msg */
666 	aq = otx2_mbox_alloc_msg_nix_cn20k_aq_enq(&pfvf->mbox);
667 	if (!aq)
668 		return -ENOMEM;
669 
670 	aq->sq.cq = pfvf->hw.rx_queues + qidx;
671 	aq->sq.max_sqe_size = NIX_MAXSQESZ_W16; /* 128 byte */
672 	aq->sq.cq_ena = 1;
673 	aq->sq.ena = 1;
674 	aq->sq.smq = otx2_get_smq_idx(pfvf, qidx);
675 	aq->sq.smq_rr_weight = mtu_to_dwrr_weight(pfvf, pfvf->tx_max_pktlen);
676 	aq->sq.default_chan = pfvf->hw.tx_chan_base + chan_offset;
677 	aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */
678 	aq->sq.sqb_aura = sqb_aura;
679 	aq->sq.sq_int_ena = NIX_SQINT_BITS;
680 	aq->sq.qint_idx = 0;
681 	/* Due pipelining impact minimum 2000 unused SQ CQE's
682 	 * need to maintain to avoid CQ overflow.
683 	 */
684 	aq->sq.cq_limit = (SEND_CQ_SKID * 256) / (pfvf->qset.sqe_cnt);
685 
686 	/* Fill AQ info */
687 	aq->qidx = qidx;
688 	aq->ctype = NIX_AQ_CTYPE_SQ;
689 	aq->op = NIX_AQ_INSTOP_INIT;
690 
691 	return otx2_sync_mbox_msg(&pfvf->mbox);
692 }
693 
694 static struct dev_hw_ops cn20k_hw_ops = {
695 	.pfaf_mbox_intr_handler = cn20k_pfaf_mbox_intr_handler,
696 	.vfaf_mbox_intr_handler = cn20k_vfaf_mbox_intr_handler,
697 	.pfvf_mbox_intr_handler = cn20k_pfvf_mbox_intr_handler,
698 	.sq_aq_init = cn20k_sq_aq_init,
699 	.sqe_flush = cn10k_sqe_flush,
700 	.aura_freeptr = cn10k_aura_freeptr,
701 	.refill_pool_ptrs = cn10k_refill_pool_ptrs,
702 	.aura_aq_init = cn20k_aura_aq_init,
703 	.pool_aq_init = cn20k_pool_aq_init,
704 };
705 
706 void cn20k_init(struct otx2_nic *pfvf)
707 {
708 	pfvf->hw_ops = &cn20k_hw_ops;
709 }
710 EXPORT_SYMBOL(cn20k_init);
711