xref: /dpdk/drivers/net/ionic/ionic_dev_vdev.c (revision fffea1aeb08985c93e2d785c1637f765d638537d)
1*fffea1aeSAndrew Boyer /* SPDX-License-Identifier: BSD-3-Clause
2*fffea1aeSAndrew Boyer  * Copyright 2019-2024 Advanced Micro Devices, Inc.
3*fffea1aeSAndrew Boyer  */
4*fffea1aeSAndrew Boyer 
5*fffea1aeSAndrew Boyer #include <stdint.h>
6*fffea1aeSAndrew Boyer #include <stdlib.h>
7*fffea1aeSAndrew Boyer #include <errno.h>
8*fffea1aeSAndrew Boyer 
9*fffea1aeSAndrew Boyer #include <rte_errno.h>
10*fffea1aeSAndrew Boyer #include <rte_common.h>
11*fffea1aeSAndrew Boyer #include <rte_log.h>
12*fffea1aeSAndrew Boyer #include <rte_eal.h>
13*fffea1aeSAndrew Boyer #include <bus_vdev_driver.h>
14*fffea1aeSAndrew Boyer #include <rte_dev.h>
15*fffea1aeSAndrew Boyer #include <rte_string_fns.h>
16*fffea1aeSAndrew Boyer #include <rte_kvargs.h>
17*fffea1aeSAndrew Boyer 
18*fffea1aeSAndrew Boyer #include "ionic.h"
19*fffea1aeSAndrew Boyer #include "ionic_common.h"
20*fffea1aeSAndrew Boyer #include "ionic_logs.h"
21*fffea1aeSAndrew Boyer #include "ionic_ethdev.h"
22*fffea1aeSAndrew Boyer 
23*fffea1aeSAndrew Boyer #define IONIC_VDEV_DEV_BAR          0
24*fffea1aeSAndrew Boyer #define IONIC_VDEV_INTR_CTL_BAR     1
25*fffea1aeSAndrew Boyer #define IONIC_VDEV_INTR_CFG_BAR     2
26*fffea1aeSAndrew Boyer #define IONIC_VDEV_DB_BAR           3
27*fffea1aeSAndrew Boyer #define IONIC_VDEV_BARS_MAX         4
28*fffea1aeSAndrew Boyer 
29*fffea1aeSAndrew Boyer #define IONIC_VDEV_DEV_INFO_REGS_OFFSET      0x0000
30*fffea1aeSAndrew Boyer #define IONIC_VDEV_DEV_CMD_REGS_OFFSET       0x0800
31*fffea1aeSAndrew Boyer 
32*fffea1aeSAndrew Boyer #define IONIC_VDEV_FW_WAIT_US       1000     /* 1ms */
33*fffea1aeSAndrew Boyer #define IONIC_VDEV_FW_WAIT_MAX      5000     /* 5s */
34*fffea1aeSAndrew Boyer 
35*fffea1aeSAndrew Boyer static int
ionic_vdev_setup(struct ionic_adapter * adapter)36*fffea1aeSAndrew Boyer ionic_vdev_setup(struct ionic_adapter *adapter)
37*fffea1aeSAndrew Boyer {
38*fffea1aeSAndrew Boyer 	struct ionic_bars *bars = &adapter->bars;
39*fffea1aeSAndrew Boyer 	struct ionic_dev *idev = &adapter->idev;
40*fffea1aeSAndrew Boyer 	uint8_t *bar0_base;
41*fffea1aeSAndrew Boyer 	uint32_t sig;
42*fffea1aeSAndrew Boyer 	uint32_t fw_waits = 0;
43*fffea1aeSAndrew Boyer 	uint8_t fw;
44*fffea1aeSAndrew Boyer 
45*fffea1aeSAndrew Boyer 	IONIC_PRINT_CALL();
46*fffea1aeSAndrew Boyer 
47*fffea1aeSAndrew Boyer 	/* BAR0: dev_cmd and interrupts */
48*fffea1aeSAndrew Boyer 	if (bars->num_bars < 1) {
49*fffea1aeSAndrew Boyer 		IONIC_PRINT(ERR, "No bars found, aborting");
50*fffea1aeSAndrew Boyer 		return -EFAULT;
51*fffea1aeSAndrew Boyer 	}
52*fffea1aeSAndrew Boyer 
53*fffea1aeSAndrew Boyer 	bar0_base = bars->bar[IONIC_VDEV_DEV_BAR].vaddr;
54*fffea1aeSAndrew Boyer 	idev->dev_info = (union ionic_dev_info_regs *)
55*fffea1aeSAndrew Boyer 		&bar0_base[IONIC_VDEV_DEV_INFO_REGS_OFFSET];
56*fffea1aeSAndrew Boyer 	idev->dev_cmd = (union ionic_dev_cmd_regs *)
57*fffea1aeSAndrew Boyer 		&bar0_base[IONIC_VDEV_DEV_CMD_REGS_OFFSET];
58*fffea1aeSAndrew Boyer 	idev->intr_ctrl = (void *)bars->bar[IONIC_VDEV_INTR_CTL_BAR].vaddr;
59*fffea1aeSAndrew Boyer 	idev->db_pages = (void *)bars->bar[IONIC_VDEV_DB_BAR].vaddr;
60*fffea1aeSAndrew Boyer 
61*fffea1aeSAndrew Boyer 	sig = ioread32(&idev->dev_info->signature);
62*fffea1aeSAndrew Boyer 	if (sig != IONIC_DEV_INFO_SIGNATURE) {
63*fffea1aeSAndrew Boyer 		IONIC_PRINT(ERR, "Incompatible firmware signature %x", sig);
64*fffea1aeSAndrew Boyer 		return -EFAULT;
65*fffea1aeSAndrew Boyer 	}
66*fffea1aeSAndrew Boyer 
67*fffea1aeSAndrew Boyer 	/* Wait for the FW to indicate readiness */
68*fffea1aeSAndrew Boyer 	while (1) {
69*fffea1aeSAndrew Boyer 		fw = ioread8(&idev->dev_info->fw_status);
70*fffea1aeSAndrew Boyer 		if ((fw & IONIC_FW_STS_F_RUNNING) != 0)
71*fffea1aeSAndrew Boyer 			break;
72*fffea1aeSAndrew Boyer 
73*fffea1aeSAndrew Boyer 		if (fw_waits > IONIC_VDEV_FW_WAIT_MAX) {
74*fffea1aeSAndrew Boyer 			IONIC_PRINT(ERR, "Firmware readiness bit not set");
75*fffea1aeSAndrew Boyer 			return -ETIMEDOUT;
76*fffea1aeSAndrew Boyer 		}
77*fffea1aeSAndrew Boyer 
78*fffea1aeSAndrew Boyer 		fw_waits++;
79*fffea1aeSAndrew Boyer 		rte_delay_us_block(IONIC_VDEV_FW_WAIT_US);
80*fffea1aeSAndrew Boyer 	}
81*fffea1aeSAndrew Boyer 	IONIC_PRINT(DEBUG, "Firmware ready (%u waits)", fw_waits);
82*fffea1aeSAndrew Boyer 
83*fffea1aeSAndrew Boyer 	adapter->name = rte_vdev_device_name(adapter->bus_dev);
84*fffea1aeSAndrew Boyer 
85*fffea1aeSAndrew Boyer 	return 0;
86*fffea1aeSAndrew Boyer }
87*fffea1aeSAndrew Boyer 
88*fffea1aeSAndrew Boyer static void
ionic_vdev_poll(struct ionic_adapter * adapter)89*fffea1aeSAndrew Boyer ionic_vdev_poll(struct ionic_adapter *adapter)
90*fffea1aeSAndrew Boyer {
91*fffea1aeSAndrew Boyer 	ionic_dev_interrupt_handler(adapter);
92*fffea1aeSAndrew Boyer }
93*fffea1aeSAndrew Boyer 
94*fffea1aeSAndrew Boyer static void
ionic_vdev_unmap_bars(struct ionic_adapter * adapter)95*fffea1aeSAndrew Boyer ionic_vdev_unmap_bars(struct ionic_adapter *adapter)
96*fffea1aeSAndrew Boyer {
97*fffea1aeSAndrew Boyer 	struct ionic_bars *bars = &adapter->bars;
98*fffea1aeSAndrew Boyer 	uint32_t i;
99*fffea1aeSAndrew Boyer 
100*fffea1aeSAndrew Boyer 	for (i = 0; i < IONIC_VDEV_BARS_MAX; i++)
101*fffea1aeSAndrew Boyer 		ionic_uio_rel_rsrc(adapter->name, i, &bars->bar[i]);
102*fffea1aeSAndrew Boyer }
103*fffea1aeSAndrew Boyer 
104*fffea1aeSAndrew Boyer static const struct ionic_dev_intf ionic_vdev_intf = {
105*fffea1aeSAndrew Boyer 	.setup = ionic_vdev_setup,
106*fffea1aeSAndrew Boyer 	.poll = ionic_vdev_poll,
107*fffea1aeSAndrew Boyer 	.unmap_bars = ionic_vdev_unmap_bars,
108*fffea1aeSAndrew Boyer };
109*fffea1aeSAndrew Boyer 
110*fffea1aeSAndrew Boyer static int
eth_ionic_vdev_probe(struct rte_vdev_device * vdev)111*fffea1aeSAndrew Boyer eth_ionic_vdev_probe(struct rte_vdev_device *vdev)
112*fffea1aeSAndrew Boyer {
113*fffea1aeSAndrew Boyer 	struct ionic_bars bars = {};
114*fffea1aeSAndrew Boyer 	const char *name = rte_vdev_device_name(vdev);
115*fffea1aeSAndrew Boyer 	unsigned int i;
116*fffea1aeSAndrew Boyer 
117*fffea1aeSAndrew Boyer 	IONIC_PRINT(NOTICE, "Initializing device %s",
118*fffea1aeSAndrew Boyer 		rte_eal_process_type() == RTE_PROC_SECONDARY ?
119*fffea1aeSAndrew Boyer 			"[SECONDARY]" : "");
120*fffea1aeSAndrew Boyer 
121*fffea1aeSAndrew Boyer 	ionic_uio_scan_mnet_devices();
122*fffea1aeSAndrew Boyer 
123*fffea1aeSAndrew Boyer 	for (i = 0; i < IONIC_VDEV_BARS_MAX; i++)
124*fffea1aeSAndrew Boyer 		ionic_uio_get_rsrc(name, i, &bars.bar[i]);
125*fffea1aeSAndrew Boyer 
126*fffea1aeSAndrew Boyer 	bars.num_bars = IONIC_VDEV_BARS_MAX;
127*fffea1aeSAndrew Boyer 
128*fffea1aeSAndrew Boyer 	return eth_ionic_dev_probe((void *)vdev,
129*fffea1aeSAndrew Boyer 			&vdev->device,
130*fffea1aeSAndrew Boyer 			&bars,
131*fffea1aeSAndrew Boyer 			&ionic_vdev_intf,
132*fffea1aeSAndrew Boyer 			IONIC_DEV_ID_ETH_VF,
133*fffea1aeSAndrew Boyer 			IONIC_PENSANDO_VENDOR_ID);
134*fffea1aeSAndrew Boyer }
135*fffea1aeSAndrew Boyer 
136*fffea1aeSAndrew Boyer static int
eth_ionic_vdev_remove(struct rte_vdev_device * vdev)137*fffea1aeSAndrew Boyer eth_ionic_vdev_remove(struct rte_vdev_device *vdev)
138*fffea1aeSAndrew Boyer {
139*fffea1aeSAndrew Boyer 	return eth_ionic_dev_remove(&vdev->device);
140*fffea1aeSAndrew Boyer }
141*fffea1aeSAndrew Boyer 
142*fffea1aeSAndrew Boyer static struct rte_vdev_driver rte_vdev_ionic_pmd = {
143*fffea1aeSAndrew Boyer 	.probe = eth_ionic_vdev_probe,
144*fffea1aeSAndrew Boyer 	.remove = eth_ionic_vdev_remove,
145*fffea1aeSAndrew Boyer };
146*fffea1aeSAndrew Boyer 
147*fffea1aeSAndrew Boyer RTE_PMD_REGISTER_VDEV(net_ionic, rte_vdev_ionic_pmd);
148