xref: /dpdk/drivers/net/bnxt/bnxt_reps.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2021 Broadcom
3  * All rights reserved.
4  */
5 
6 #include "bnxt.h"
7 #include "bnxt_ring.h"
8 #include "bnxt_reps.h"
9 #include "bnxt_rxq.h"
10 #include "bnxt_rxr.h"
11 #include "bnxt_txq.h"
12 #include "bnxt_txr.h"
13 #include "bnxt_hwrm.h"
14 #include "hsi_struct_def_dpdk.h"
15 #include "bnxt_tf_common.h"
16 #include "ulp_port_db.h"
17 #include "ulp_flow_db.h"
18 
19 static const struct eth_dev_ops bnxt_rep_dev_ops = {
20 	.dev_infos_get = bnxt_rep_dev_info_get_op,
21 	.dev_configure = bnxt_rep_dev_configure_op,
22 	.dev_start = bnxt_rep_dev_start_op,
23 	.rx_queue_setup = bnxt_rep_rx_queue_setup_op,
24 	.rx_queue_release = bnxt_rep_rx_queue_release_op,
25 	.tx_queue_setup = bnxt_rep_tx_queue_setup_op,
26 	.tx_queue_release = bnxt_rep_tx_queue_release_op,
27 	.link_update = bnxt_rep_link_update_op,
28 	.dev_close = bnxt_rep_dev_close_op,
29 	.dev_stop = bnxt_rep_dev_stop_op,
30 	.stats_get = bnxt_rep_stats_get_op,
31 	.stats_reset = bnxt_rep_stats_reset_op,
32 	.flow_ops_get = bnxt_flow_ops_get_op
33 };
34 
35 uint16_t
36 bnxt_vfr_recv(uint16_t port_id, uint16_t queue_id, struct rte_mbuf *mbuf)
37 {
38 	struct rte_mbuf **prod_rx_buf;
39 	struct bnxt_rx_ring_info *rep_rxr;
40 	struct bnxt_rx_queue *rep_rxq;
41 	struct rte_eth_dev *vfr_eth_dev;
42 	struct bnxt_representor *vfr_bp;
43 	uint16_t mask;
44 	uint8_t que;
45 
46 	vfr_eth_dev = &rte_eth_devices[port_id];
47 	vfr_bp = vfr_eth_dev->data->dev_private;
48 	/* If rxq_id happens to be > nr_rings, use ring 0 */
49 	que = queue_id < vfr_bp->rx_nr_rings ? queue_id : 0;
50 	rep_rxq = vfr_bp->rx_queues[que];
51 	/* Ideally should not happen now, paranoid check */
52 	if (!rep_rxq)
53 		return 1;
54 	rep_rxr = rep_rxq->rx_ring;
55 	mask = rep_rxr->rx_ring_struct->ring_mask;
56 
57 	/* Put this mbuf on the RxQ of the Representor */
58 	prod_rx_buf = &rep_rxr->rx_buf_ring[rep_rxr->rx_raw_prod & mask];
59 	if (*prod_rx_buf == NULL) {
60 		*prod_rx_buf = mbuf;
61 		vfr_bp->rx_bytes[que] += mbuf->pkt_len;
62 		vfr_bp->rx_pkts[que]++;
63 		rep_rxr->rx_raw_prod++;
64 	} else {
65 		/* Representor Rx ring full, drop pkt */
66 		vfr_bp->rx_drop_bytes[que] += mbuf->pkt_len;
67 		vfr_bp->rx_drop_pkts[que]++;
68 		rte_mbuf_raw_free(mbuf);
69 	}
70 
71 	return 0;
72 }
73 
74 static uint16_t
75 bnxt_rep_rx_burst(void *rx_queue,
76 		     struct rte_mbuf **rx_pkts,
77 		     uint16_t nb_pkts)
78 {
79 	struct bnxt_rx_queue *rxq = rx_queue;
80 	struct rte_mbuf **cons_rx_buf;
81 	struct bnxt_rx_ring_info *rxr;
82 	uint16_t nb_rx_pkts = 0;
83 	uint16_t mask, i;
84 
85 	if (!rxq)
86 		return 0;
87 
88 	rxr = rxq->rx_ring;
89 	mask = rxr->rx_ring_struct->ring_mask;
90 	for (i = 0; i < nb_pkts; i++) {
91 		cons_rx_buf = &rxr->rx_buf_ring[rxr->rx_cons & mask];
92 		if (*cons_rx_buf == NULL)
93 			return nb_rx_pkts;
94 		rx_pkts[nb_rx_pkts] = *cons_rx_buf;
95 		rx_pkts[nb_rx_pkts]->port = rxq->port_id;
96 		*cons_rx_buf = NULL;
97 		nb_rx_pkts++;
98 		rxr->rx_cons++;
99 	}
100 
101 	return nb_rx_pkts;
102 }
103 
104 static uint16_t
105 bnxt_rep_tx_burst(void *tx_queue,
106 		     struct rte_mbuf **tx_pkts,
107 		     __rte_unused uint16_t nb_pkts)
108 {
109 	struct bnxt_vf_rep_tx_queue *vfr_txq = tx_queue;
110 	struct bnxt_tx_queue *ptxq;
111 	struct bnxt *parent;
112 	struct  bnxt_representor *vf_rep_bp;
113 	int qid;
114 	int rc;
115 	int i;
116 
117 	if (!vfr_txq)
118 		return 0;
119 
120 	qid = vfr_txq->txq->queue_id;
121 	vf_rep_bp = vfr_txq->bp;
122 	parent = vf_rep_bp->parent_dev->data->dev_private;
123 	pthread_mutex_lock(&parent->rep_info->vfr_lock);
124 	ptxq = parent->tx_queues[qid];
125 
126 	ptxq->vfr_tx_cfa_action = vf_rep_bp->vfr_tx_cfa_action;
127 
128 	for (i = 0; i < nb_pkts; i++) {
129 		vf_rep_bp->tx_bytes[qid] += tx_pkts[i]->pkt_len;
130 		vf_rep_bp->tx_pkts[qid]++;
131 	}
132 
133 	rc = bnxt_xmit_pkts(ptxq, tx_pkts, nb_pkts);
134 	ptxq->vfr_tx_cfa_action = 0;
135 	pthread_mutex_unlock(&parent->rep_info->vfr_lock);
136 
137 	return rc;
138 }
139 
140 static int
141 bnxt_get_dflt_vnic_svif(struct bnxt *bp, struct bnxt_representor *vf_rep_bp)
142 {
143 	struct bnxt_rep_info *rep_info;
144 	int rc;
145 
146 	rc = bnxt_hwrm_get_dflt_vnic_svif(bp, vf_rep_bp->fw_fid,
147 					  &vf_rep_bp->dflt_vnic_id,
148 					  &vf_rep_bp->svif);
149 	if (rc) {
150 		PMD_DRV_LOG(ERR, "Failed to get default vnic id of VF\n");
151 		vf_rep_bp->dflt_vnic_id = BNXT_DFLT_VNIC_ID_INVALID;
152 		vf_rep_bp->svif = BNXT_SVIF_INVALID;
153 	} else {
154 		PMD_DRV_LOG(INFO, "vf_rep->dflt_vnic_id = %d\n",
155 				vf_rep_bp->dflt_vnic_id);
156 	}
157 	if (vf_rep_bp->dflt_vnic_id != BNXT_DFLT_VNIC_ID_INVALID &&
158 	    vf_rep_bp->svif != BNXT_SVIF_INVALID) {
159 		rep_info = &bp->rep_info[vf_rep_bp->vf_id];
160 		rep_info->conduit_valid = true;
161 	}
162 
163 	return rc;
164 }
165 
166 int bnxt_representor_init(struct rte_eth_dev *eth_dev, void *params)
167 {
168 	struct bnxt_representor *vf_rep_bp = eth_dev->data->dev_private;
169 	struct bnxt_representor *rep_params =
170 				 (struct bnxt_representor *)params;
171 	struct rte_eth_link *link;
172 	struct bnxt *parent_bp;
173 	uint16_t first_vf_id;
174 	int rc = 0;
175 
176 	PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR init\n", eth_dev->data->port_id);
177 	vf_rep_bp->vf_id = rep_params->vf_id;
178 	vf_rep_bp->switch_domain_id = rep_params->switch_domain_id;
179 	vf_rep_bp->parent_dev = rep_params->parent_dev;
180 	vf_rep_bp->rep_based_pf = rep_params->rep_based_pf;
181 	vf_rep_bp->flags = rep_params->flags;
182 	vf_rep_bp->rep_q_r2f = rep_params->rep_q_r2f;
183 	vf_rep_bp->rep_q_f2r = rep_params->rep_q_f2r;
184 	vf_rep_bp->rep_fc_r2f = rep_params->rep_fc_r2f;
185 	vf_rep_bp->rep_fc_f2r = rep_params->rep_fc_f2r;
186 
187 	eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR |
188 					RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
189 	eth_dev->data->representor_id = rep_params->vf_id;
190 
191 	rte_eth_random_addr(vf_rep_bp->dflt_mac_addr);
192 	memcpy(vf_rep_bp->mac_addr, vf_rep_bp->dflt_mac_addr,
193 	       sizeof(vf_rep_bp->mac_addr));
194 	eth_dev->data->mac_addrs =
195 		(struct rte_ether_addr *)&vf_rep_bp->mac_addr;
196 	eth_dev->dev_ops = &bnxt_rep_dev_ops;
197 
198 	/* No data-path, but need stub Rx/Tx functions to avoid crash
199 	 * when testing with ovs-dpdk
200 	 */
201 	eth_dev->rx_pkt_burst = bnxt_rep_rx_burst;
202 	eth_dev->tx_pkt_burst = bnxt_rep_tx_burst;
203 	/* Link state. Inherited from PF or trusted VF */
204 	parent_bp = vf_rep_bp->parent_dev->data->dev_private;
205 	link = &parent_bp->eth_dev->data->dev_link;
206 
207 	eth_dev->data->dev_link.link_speed = link->link_speed;
208 	eth_dev->data->dev_link.link_duplex = link->link_duplex;
209 	eth_dev->data->dev_link.link_status = link->link_status;
210 	eth_dev->data->dev_link.link_autoneg = link->link_autoneg;
211 
212 	PMD_DRV_LOG(INFO, "calling bnxt_print_link_info\n");
213 	bnxt_print_link_info(eth_dev);
214 
215 	PMD_DRV_LOG(INFO,
216 		    "Switch domain id %d: Representor Device %d init done\n",
217 		    vf_rep_bp->switch_domain_id, vf_rep_bp->vf_id);
218 
219 	if (BNXT_REP_BASED_PF(vf_rep_bp)) {
220 		vf_rep_bp->fw_fid = vf_rep_bp->rep_based_pf + 1;
221 		vf_rep_bp->parent_pf_idx = vf_rep_bp->rep_based_pf;
222 		if (!(BNXT_REP_PF(vf_rep_bp))) {
223 			/* VF representor for the remote PF,get first_vf_id */
224 			rc = bnxt_hwrm_first_vf_id_query(parent_bp,
225 							 vf_rep_bp->fw_fid,
226 							 &first_vf_id);
227 			if (rc)
228 				return rc;
229 			if (first_vf_id == 0xffff) {
230 				PMD_DRV_LOG(ERR,
231 					    "Invalid first_vf_id fid:%x\n",
232 					    vf_rep_bp->fw_fid);
233 				return -EINVAL;
234 			}
235 			PMD_DRV_LOG(INFO, "first_vf_id = %x parent_fid:%x\n",
236 				    first_vf_id, vf_rep_bp->fw_fid);
237 			vf_rep_bp->fw_fid = rep_params->vf_id + first_vf_id;
238 		}
239 	}  else {
240 		vf_rep_bp->fw_fid = rep_params->vf_id + parent_bp->first_vf_id;
241 		if (BNXT_VF_IS_TRUSTED(parent_bp))
242 			vf_rep_bp->parent_pf_idx = parent_bp->parent->fid - 1;
243 		else
244 			vf_rep_bp->parent_pf_idx = parent_bp->fw_fid - 1;
245 	}
246 
247 	PMD_DRV_LOG(INFO, "vf_rep->fw_fid = %d\n", vf_rep_bp->fw_fid);
248 
249 	return 0;
250 }
251 
252 int bnxt_representor_uninit(struct rte_eth_dev *eth_dev)
253 {
254 	struct bnxt *parent_bp;
255 	struct bnxt_representor *rep =
256 		(struct bnxt_representor *)eth_dev->data->dev_private;
257 	uint16_t vf_id;
258 
259 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
260 		return 0;
261 
262 	PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR uninit\n", eth_dev->data->port_id);
263 	eth_dev->data->mac_addrs = NULL;
264 
265 	parent_bp = rep->parent_dev->data->dev_private;
266 	if (!parent_bp) {
267 		PMD_DRV_LOG(DEBUG, "BNXT Port:%d already freed\n",
268 			    eth_dev->data->port_id);
269 		return 0;
270 	}
271 
272 	parent_bp->num_reps--;
273 	vf_id = rep->vf_id;
274 	if (parent_bp->rep_info)
275 		memset(&parent_bp->rep_info[vf_id], 0,
276 		       sizeof(parent_bp->rep_info[vf_id]));
277 		/* mark that this representor has been freed */
278 	return 0;
279 }
280 
281 int bnxt_rep_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_compl)
282 {
283 	struct bnxt *parent_bp;
284 	struct bnxt_representor *rep =
285 		(struct bnxt_representor *)eth_dev->data->dev_private;
286 	struct rte_eth_link *link;
287 	int rc;
288 
289 	parent_bp = rep->parent_dev->data->dev_private;
290 	if (!parent_bp)
291 		return 0;
292 
293 	rc = bnxt_link_update_op(parent_bp->eth_dev, wait_to_compl);
294 
295 	/* Link state. Inherited from PF or trusted VF */
296 	link = &parent_bp->eth_dev->data->dev_link;
297 
298 	eth_dev->data->dev_link.link_speed = link->link_speed;
299 	eth_dev->data->dev_link.link_duplex = link->link_duplex;
300 	eth_dev->data->dev_link.link_status = link->link_status;
301 	eth_dev->data->dev_link.link_autoneg = link->link_autoneg;
302 	bnxt_print_link_info(eth_dev);
303 
304 	return rc;
305 }
306 
307 static int bnxt_tf_vfr_alloc(struct rte_eth_dev *vfr_ethdev)
308 {
309 	int rc;
310 	struct bnxt_representor *vfr = vfr_ethdev->data->dev_private;
311 	struct rte_eth_dev *parent_dev = vfr->parent_dev;
312 	struct bnxt *parent_bp = parent_dev->data->dev_private;
313 
314 	if (!parent_bp || !parent_bp->ulp_ctx) {
315 		BNXT_TF_DBG(ERR, "Invalid arguments\n");
316 		return 0;
317 	}
318 
319 	/* Update the ULP portdata base with the new VFR interface */
320 	rc = ulp_port_db_dev_port_intf_update(parent_bp->ulp_ctx, vfr_ethdev);
321 	if (rc) {
322 		BNXT_TF_DBG(ERR, "Failed to update ulp port details vfr:%u\n",
323 			    vfr->vf_id);
324 		return rc;
325 	}
326 
327 	/* Create the default rules for the VFR */
328 	rc = bnxt_ulp_create_vfr_default_rules(vfr_ethdev);
329 	if (rc) {
330 		BNXT_TF_DBG(ERR, "Failed to create VFR default rules vfr:%u\n",
331 			    vfr->vf_id);
332 		return rc;
333 	}
334 	/* update the port id so you can backtrack to ethdev */
335 	vfr->dpdk_port_id = vfr_ethdev->data->port_id;
336 
337 	rc = bnxt_hwrm_cfa_pair_alloc(parent_bp, vfr);
338 	if (rc) {
339 		BNXT_TF_DBG(ERR, "Failed in hwrm vfr alloc vfr:%u rc=%d\n",
340 			    vfr->vf_id, rc);
341 		(void)bnxt_ulp_delete_vfr_default_rules(vfr);
342 	}
343 	BNXT_TF_DBG(DEBUG, "BNXT Port:%d VFR created and initialized\n",
344 		    vfr->dpdk_port_id);
345 	return rc;
346 }
347 
348 static int bnxt_vfr_alloc(struct rte_eth_dev *vfr_ethdev)
349 {
350 	int rc = 0;
351 	struct bnxt_representor *vfr = vfr_ethdev->data->dev_private;
352 	struct bnxt *parent_bp;
353 
354 	if (!vfr || !vfr->parent_dev) {
355 		PMD_DRV_LOG(ERR,
356 				"No memory allocated for representor\n");
357 		return -ENOMEM;
358 	}
359 
360 	parent_bp = vfr->parent_dev->data->dev_private;
361 	if (parent_bp && !parent_bp->ulp_ctx) {
362 		PMD_DRV_LOG(ERR,
363 			    "ulp context not allocated for parent\n");
364 		return -EIO;
365 	}
366 
367 	/* Check if representor has been already allocated in FW */
368 	if (vfr->vfr_tx_cfa_action)
369 		return 0;
370 
371 	/*
372 	 * Alloc VF rep rules in CFA after default VNIC is created.
373 	 * Otherwise the FW will create the VF-rep rules with
374 	 * default drop action.
375 	 */
376 	rc = bnxt_tf_vfr_alloc(vfr_ethdev);
377 	if (!rc)
378 		PMD_DRV_LOG(DEBUG, "allocated representor %d in FW\n",
379 			    vfr->vf_id);
380 	else
381 		PMD_DRV_LOG(ERR,
382 			    "Failed to alloc representor %d in FW\n",
383 			    vfr->vf_id);
384 
385 	return rc;
386 }
387 
388 static void bnxt_rep_free_rx_mbufs(struct bnxt_representor *rep_bp)
389 {
390 	struct bnxt_rx_queue *rxq;
391 	unsigned int i;
392 
393 	for (i = 0; i < rep_bp->rx_nr_rings; i++) {
394 		rxq = rep_bp->rx_queues[i];
395 		bnxt_rx_queue_release_mbufs(rxq);
396 	}
397 }
398 
399 int bnxt_rep_dev_start_op(struct rte_eth_dev *eth_dev)
400 {
401 	struct bnxt_representor *rep_bp = eth_dev->data->dev_private;
402 	struct bnxt_rep_info *rep_info;
403 	struct bnxt *parent_bp;
404 	int rc;
405 
406 	parent_bp = rep_bp->parent_dev->data->dev_private;
407 	rep_info = &parent_bp->rep_info[rep_bp->vf_id];
408 
409 	BNXT_TF_DBG(DEBUG, "BNXT Port:%d VFR start\n", eth_dev->data->port_id);
410 	pthread_mutex_lock(&rep_info->vfr_start_lock);
411 	if (!rep_info->conduit_valid) {
412 		rc = bnxt_get_dflt_vnic_svif(parent_bp, rep_bp);
413 		if (rc || !rep_info->conduit_valid) {
414 			pthread_mutex_unlock(&rep_info->vfr_start_lock);
415 			return rc;
416 		}
417 	}
418 	pthread_mutex_unlock(&rep_info->vfr_start_lock);
419 
420 	rc = bnxt_vfr_alloc(eth_dev);
421 	if (rc) {
422 		eth_dev->data->dev_link.link_status = 0;
423 		bnxt_rep_free_rx_mbufs(rep_bp);
424 		return rc;
425 	}
426 	eth_dev->rx_pkt_burst = &bnxt_rep_rx_burst;
427 	eth_dev->tx_pkt_burst = &bnxt_rep_tx_burst;
428 	bnxt_rep_link_update_op(eth_dev, 1);
429 
430 	return 0;
431 }
432 
433 static int bnxt_tf_vfr_free(struct bnxt_representor *vfr)
434 {
435 	BNXT_TF_DBG(DEBUG, "BNXT Port:%d VFR ulp free\n", vfr->dpdk_port_id);
436 	return bnxt_ulp_delete_vfr_default_rules(vfr);
437 }
438 
439 static int bnxt_vfr_free(struct bnxt_representor *vfr)
440 {
441 	int rc = 0;
442 	struct bnxt *parent_bp;
443 
444 	if (!vfr || !vfr->parent_dev) {
445 		PMD_DRV_LOG(ERR,
446 			    "No memory allocated for representor\n");
447 		return -ENOMEM;
448 	}
449 
450 	parent_bp = vfr->parent_dev->data->dev_private;
451 	if (!parent_bp) {
452 		PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR already freed\n",
453 			    vfr->dpdk_port_id);
454 		return 0;
455 	}
456 
457 	/* Check if representor has been already freed in FW */
458 	if (!vfr->vfr_tx_cfa_action)
459 		return 0;
460 
461 	rc = bnxt_tf_vfr_free(vfr);
462 	if (rc) {
463 		PMD_DRV_LOG(ERR,
464 			    "Failed to free representor %d in FW\n",
465 			    vfr->vf_id);
466 	}
467 
468 	PMD_DRV_LOG(DEBUG, "freed representor %d in FW\n",
469 		    vfr->vf_id);
470 	vfr->vfr_tx_cfa_action = 0;
471 
472 	rc = bnxt_hwrm_cfa_pair_free(parent_bp, vfr);
473 
474 	return rc;
475 }
476 
477 int bnxt_rep_dev_stop_op(struct rte_eth_dev *eth_dev)
478 {
479 	struct bnxt_representor *vfr_bp = eth_dev->data->dev_private;
480 
481 	/* Avoid crashes as we are about to free queues */
482 	eth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts;
483 	eth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts;
484 
485 	BNXT_TF_DBG(DEBUG, "BNXT Port:%d VFR stop\n", eth_dev->data->port_id);
486 
487 	bnxt_vfr_free(vfr_bp);
488 
489 	if (eth_dev->data->dev_started)
490 		eth_dev->data->dev_link.link_status = 0;
491 
492 	bnxt_rep_free_rx_mbufs(vfr_bp);
493 
494 	return 0;
495 }
496 
497 int bnxt_rep_dev_close_op(struct rte_eth_dev *eth_dev)
498 {
499 	BNXT_TF_DBG(DEBUG, "BNXT Port:%d VFR close\n", eth_dev->data->port_id);
500 	bnxt_representor_uninit(eth_dev);
501 	return 0;
502 }
503 
504 int bnxt_rep_dev_info_get_op(struct rte_eth_dev *eth_dev,
505 				struct rte_eth_dev_info *dev_info)
506 {
507 	struct bnxt_representor *rep_bp = eth_dev->data->dev_private;
508 	struct bnxt *parent_bp;
509 	unsigned int max_rx_rings;
510 	int rc = 0;
511 
512 	/* MAC Specifics */
513 	parent_bp = rep_bp->parent_dev->data->dev_private;
514 	if (!parent_bp) {
515 		PMD_DRV_LOG(ERR, "Rep parent NULL!\n");
516 		return rc;
517 	}
518 	PMD_DRV_LOG(DEBUG, "Representor dev_info_get_op\n");
519 	dev_info->max_mac_addrs = parent_bp->max_l2_ctx;
520 	dev_info->max_hash_mac_addrs = 0;
521 
522 	max_rx_rings = BNXT_MAX_VF_REP_RINGS;
523 	/* For the sake of symmetry, max_rx_queues = max_tx_queues */
524 	dev_info->max_rx_queues = max_rx_rings;
525 	dev_info->max_tx_queues = max_rx_rings;
526 	dev_info->reta_size = bnxt_rss_hash_tbl_size(parent_bp);
527 	dev_info->hash_key_size = 40;
528 
529 	/* MTU specifics */
530 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
531 	dev_info->max_mtu = BNXT_MAX_MTU;
532 
533 	/* Fast path specifics */
534 	dev_info->min_rx_bufsize = 1;
535 	dev_info->max_rx_pktlen = BNXT_MAX_PKT_LEN;
536 
537 	dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT;
538 	if (parent_bp->flags & BNXT_FLAG_PTP_SUPPORTED)
539 		dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP;
540 	dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT;
541 	dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
542 
543 	dev_info->switch_info.name = eth_dev->device->name;
544 	dev_info->switch_info.domain_id = rep_bp->switch_domain_id;
545 	dev_info->switch_info.port_id =
546 			rep_bp->vf_id & BNXT_SWITCH_PORT_ID_VF_MASK;
547 
548 	return 0;
549 }
550 
551 int bnxt_rep_dev_configure_op(__rte_unused struct rte_eth_dev *eth_dev)
552 {
553 	struct bnxt_representor *rep_bp = eth_dev->data->dev_private;
554 
555 	PMD_DRV_LOG(DEBUG, "Representor dev_configure_op\n");
556 	rep_bp->rx_queues = (void *)eth_dev->data->rx_queues;
557 	rep_bp->tx_nr_rings = eth_dev->data->nb_tx_queues;
558 	rep_bp->rx_nr_rings = eth_dev->data->nb_rx_queues;
559 
560 	return 0;
561 }
562 
563 static int bnxt_init_rep_rx_ring(struct bnxt_rx_queue *rxq,
564 				 unsigned int socket_id)
565 {
566 	struct bnxt_rx_ring_info *rxr;
567 	struct bnxt_ring *ring;
568 
569 	rxr = rte_zmalloc_socket("bnxt_rep_rx_ring",
570 				 sizeof(struct bnxt_rx_ring_info),
571 				 RTE_CACHE_LINE_SIZE, socket_id);
572 	if (rxr == NULL)
573 		return -ENOMEM;
574 	rxq->rx_ring = rxr;
575 
576 	ring = rte_zmalloc_socket("bnxt_rep_rx_ring_struct",
577 				  sizeof(struct bnxt_ring),
578 				  RTE_CACHE_LINE_SIZE, socket_id);
579 	if (ring == NULL)
580 		return -ENOMEM;
581 	rxr->rx_ring_struct = ring;
582 	ring->ring_size = rte_align32pow2(rxq->nb_rx_desc);
583 	ring->ring_mask = ring->ring_size - 1;
584 
585 	return 0;
586 }
587 
588 int bnxt_rep_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
589 			       uint16_t queue_idx,
590 			       uint16_t nb_desc,
591 			       unsigned int socket_id,
592 			       __rte_unused const struct rte_eth_rxconf *rx_conf,
593 			       __rte_unused struct rte_mempool *mp)
594 {
595 	struct bnxt_representor *rep_bp = eth_dev->data->dev_private;
596 	struct bnxt *parent_bp = rep_bp->parent_dev->data->dev_private;
597 	struct bnxt_rx_queue *parent_rxq;
598 	struct bnxt_rx_queue *rxq;
599 	struct rte_mbuf **buf_ring;
600 	int rc = 0;
601 
602 	if (queue_idx >= BNXT_MAX_VF_REP_RINGS) {
603 		PMD_DRV_LOG(ERR,
604 			    "Cannot create Rx ring %d. %d rings available\n",
605 			    queue_idx, BNXT_MAX_VF_REP_RINGS);
606 		return -EINVAL;
607 	}
608 
609 	if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
610 		PMD_DRV_LOG(ERR, "nb_desc %d is invalid\n", nb_desc);
611 		return -EINVAL;
612 	}
613 
614 	if (!parent_bp->rx_queues) {
615 		PMD_DRV_LOG(ERR, "Parent Rx qs not configured yet\n");
616 		return -EINVAL;
617 	}
618 
619 	parent_rxq = parent_bp->rx_queues[queue_idx];
620 	if (!parent_rxq) {
621 		PMD_DRV_LOG(ERR, "Parent RxQ has not been configured yet\n");
622 		return -EINVAL;
623 	}
624 
625 	if (nb_desc != parent_rxq->nb_rx_desc) {
626 		PMD_DRV_LOG(ERR, "nb_desc %d do not match parent rxq", nb_desc);
627 		return -EINVAL;
628 	}
629 
630 	if (eth_dev->data->rx_queues) {
631 		rxq = eth_dev->data->rx_queues[queue_idx];
632 		if (rxq)
633 			bnxt_rx_queue_release_op(rxq);
634 	}
635 
636 	rxq = rte_zmalloc_socket("bnxt_vfr_rx_queue",
637 				 sizeof(struct bnxt_rx_queue),
638 				 RTE_CACHE_LINE_SIZE, socket_id);
639 	if (!rxq) {
640 		PMD_DRV_LOG(ERR, "bnxt_vfr_rx_queue allocation failed!\n");
641 		return -ENOMEM;
642 	}
643 
644 	rxq->nb_rx_desc = nb_desc;
645 
646 	rc = bnxt_init_rep_rx_ring(rxq, socket_id);
647 	if (rc)
648 		goto out;
649 
650 	buf_ring = rte_zmalloc_socket("bnxt_rx_vfr_buf_ring",
651 				      sizeof(struct rte_mbuf *) *
652 				      rxq->rx_ring->rx_ring_struct->ring_size,
653 				      RTE_CACHE_LINE_SIZE, socket_id);
654 	if (!buf_ring) {
655 		PMD_DRV_LOG(ERR, "bnxt_rx_vfr_buf_ring allocation failed!\n");
656 		rc = -ENOMEM;
657 		goto out;
658 	}
659 
660 	rxq->rx_ring->rx_buf_ring = buf_ring;
661 	rxq->queue_id = queue_idx;
662 	rxq->port_id = eth_dev->data->port_id;
663 	eth_dev->data->rx_queues[queue_idx] = rxq;
664 
665 	return 0;
666 
667 out:
668 	if (rxq)
669 		bnxt_rep_rx_queue_release_op(rxq);
670 
671 	return rc;
672 }
673 
674 void bnxt_rep_rx_queue_release_op(void *rx_queue)
675 {
676 	struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue;
677 
678 	if (!rxq)
679 		return;
680 
681 	bnxt_rx_queue_release_mbufs(rxq);
682 
683 	bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
684 	rte_free(rxq->rx_ring->rx_ring_struct);
685 	rte_free(rxq->rx_ring);
686 
687 	rte_free(rxq);
688 }
689 
690 int bnxt_rep_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
691 			       uint16_t queue_idx,
692 			       uint16_t nb_desc,
693 			       unsigned int socket_id,
694 			       __rte_unused const struct rte_eth_txconf *tx_conf)
695 {
696 	struct bnxt_representor *rep_bp = eth_dev->data->dev_private;
697 	struct bnxt *parent_bp = rep_bp->parent_dev->data->dev_private;
698 	struct bnxt_tx_queue *parent_txq, *txq;
699 	struct bnxt_vf_rep_tx_queue *vfr_txq;
700 
701 	if (queue_idx >= BNXT_MAX_VF_REP_RINGS) {
702 		PMD_DRV_LOG(ERR,
703 			    "Cannot create Tx rings %d. %d rings available\n",
704 			    queue_idx, BNXT_MAX_VF_REP_RINGS);
705 		return -EINVAL;
706 	}
707 
708 	if (!nb_desc || nb_desc > MAX_TX_DESC_CNT) {
709 		PMD_DRV_LOG(ERR, "nb_desc %d is invalid", nb_desc);
710 		return -EINVAL;
711 	}
712 
713 	if (!parent_bp->tx_queues) {
714 		PMD_DRV_LOG(ERR, "Parent Tx qs not configured yet\n");
715 		return -EINVAL;
716 	}
717 
718 	parent_txq = parent_bp->tx_queues[queue_idx];
719 	if (!parent_txq) {
720 		PMD_DRV_LOG(ERR, "Parent TxQ has not been configured yet\n");
721 		return -EINVAL;
722 	}
723 
724 	if (nb_desc != parent_txq->nb_tx_desc) {
725 		PMD_DRV_LOG(ERR, "nb_desc %d do not match parent txq", nb_desc);
726 		return -EINVAL;
727 	}
728 
729 	if (eth_dev->data->tx_queues) {
730 		vfr_txq = eth_dev->data->tx_queues[queue_idx];
731 		bnxt_rep_tx_queue_release_op(vfr_txq);
732 		vfr_txq = NULL;
733 	}
734 
735 	vfr_txq = rte_zmalloc_socket("bnxt_vfr_tx_queue",
736 				     sizeof(struct bnxt_vf_rep_tx_queue),
737 				     RTE_CACHE_LINE_SIZE, socket_id);
738 	if (!vfr_txq) {
739 		PMD_DRV_LOG(ERR, "bnxt_vfr_tx_queue allocation failed!");
740 		return -ENOMEM;
741 	}
742 	txq = rte_zmalloc_socket("bnxt_tx_queue",
743 				 sizeof(struct bnxt_tx_queue),
744 				 RTE_CACHE_LINE_SIZE, socket_id);
745 	if (!txq) {
746 		PMD_DRV_LOG(ERR, "bnxt_tx_queue allocation failed!");
747 		rte_free(vfr_txq);
748 		return -ENOMEM;
749 	}
750 
751 	txq->nb_tx_desc = nb_desc;
752 	txq->queue_id = queue_idx;
753 	txq->port_id = eth_dev->data->port_id;
754 	vfr_txq->txq = txq;
755 	vfr_txq->bp = rep_bp;
756 	eth_dev->data->tx_queues[queue_idx] = vfr_txq;
757 
758 	return 0;
759 }
760 
761 void bnxt_rep_tx_queue_release_op(void *tx_queue)
762 {
763 	struct bnxt_vf_rep_tx_queue *vfr_txq = tx_queue;
764 
765 	if (!vfr_txq)
766 		return;
767 
768 	rte_free(vfr_txq->txq);
769 	rte_free(vfr_txq);
770 }
771 
772 int bnxt_rep_stats_get_op(struct rte_eth_dev *eth_dev,
773 			     struct rte_eth_stats *stats)
774 {
775 	struct bnxt_representor *rep_bp = eth_dev->data->dev_private;
776 	int i;
777 
778 	memset(stats, 0, sizeof(*stats));
779 	for (i = 0; i < BNXT_MAX_VF_REP_RINGS; i++) {
780 		stats->obytes += rep_bp->tx_bytes[i];
781 		stats->opackets += rep_bp->tx_pkts[i];
782 		stats->ibytes += rep_bp->rx_bytes[i];
783 		stats->ipackets += rep_bp->rx_pkts[i];
784 		stats->imissed += rep_bp->rx_drop_pkts[i];
785 
786 		stats->q_ipackets[i] = rep_bp->rx_pkts[i];
787 		stats->q_ibytes[i] = rep_bp->rx_bytes[i];
788 		stats->q_opackets[i] = rep_bp->tx_pkts[i];
789 		stats->q_obytes[i] = rep_bp->tx_bytes[i];
790 		stats->q_errors[i] = rep_bp->rx_drop_pkts[i];
791 	}
792 
793 	return 0;
794 }
795 
796 int bnxt_rep_stats_reset_op(struct rte_eth_dev *eth_dev)
797 {
798 	struct bnxt_representor *rep_bp = eth_dev->data->dev_private;
799 	int i;
800 
801 	for (i = 0; i < BNXT_MAX_VF_REP_RINGS; i++) {
802 		rep_bp->tx_pkts[i] = 0;
803 		rep_bp->tx_bytes[i] = 0;
804 		rep_bp->rx_pkts[i] = 0;
805 		rep_bp->rx_bytes[i] = 0;
806 		rep_bp->rx_drop_pkts[i] = 0;
807 	}
808 	return 0;
809 }
810 
811 int bnxt_rep_stop_all(struct bnxt *bp)
812 {
813 	uint16_t vf_id;
814 	struct rte_eth_dev *rep_eth_dev;
815 	int ret;
816 
817 	/* No vfrep ports just exit */
818 	if (!bp->rep_info)
819 		return 0;
820 
821 	for (vf_id = 0; vf_id < BNXT_MAX_VF_REPS; vf_id++) {
822 		rep_eth_dev = bp->rep_info[vf_id].vfr_eth_dev;
823 		if (!rep_eth_dev)
824 			continue;
825 		ret = bnxt_rep_dev_stop_op(rep_eth_dev);
826 		if (ret != 0)
827 			return ret;
828 	}
829 
830 	return 0;
831 }
832