1 /* SPDX-License-Identifier: BSD-3-Clause
5 #include <rte_kvargs.h>
6 #include <rte_ethdev_vdev.h>
7 #include <rte_bus_vdev.h>
12 #define PFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/
13 #define PFE_VDEV_GEM_ID_ARG "intf"
15 struct pfe_vdev_init_params {
18 static struct pfe *g_pfe;
20 /* TODO: make pfe_svr a runtime option.
21 * Driver should be able to get the SVR
22 * information from HW.
24 unsigned int pfe_svr = SVR_LS1012A_REV1;
27 pfe_soc_version_get(void)
29 FILE *svr_file = NULL;
30 unsigned int svr_ver = 0;
32 svr_file = fopen(PFE_SOC_ID_FILE, "r");
34 return; /* Not supported on this infra */
36 if (fscanf(svr_file, "svr:%x", &svr_ver) > 0)
39 printf("Unable to read SoC device");
45 pfe_eth_open_cdev(struct pfe_eth_priv_s *priv)
52 pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY);
53 if (pfe_cdev_fd < 0) {
54 priv->link_fd = PFE_CDEV_INVALID_FD;
58 priv->link_fd = pfe_cdev_fd;
64 pfe_eth_close_cdev(struct pfe_eth_priv_s *priv)
69 if (priv->link_fd != PFE_CDEV_INVALID_FD) {
71 priv->link_fd = PFE_CDEV_INVALID_FD;
76 pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe)
78 /* Close the device file for link status */
79 pfe_eth_close_cdev(dev->data->dev_private);
81 rte_free(dev->data->mac_addrs);
82 rte_eth_dev_release_port(dev);
87 pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id)
89 struct rte_eth_dev *eth_dev = NULL;
90 struct pfe_eth_priv_s *priv = NULL;
93 eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv));
97 priv = eth_dev->data->dev_private;
101 pfe->eth.eth_priv[id] = priv;
103 #define HIF_GEMAC_TMUQ_BASE 6
104 priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2);
105 priv->high_tmu_q = priv->low_tmu_q + 1;
107 rte_spinlock_init(&priv->lock);
109 /* Copy the station address into the dev structure, */
110 eth_dev->data->mac_addrs = rte_zmalloc("mac_addr",
111 ETHER_ADDR_LEN * PFE_MAX_MACS, 0);
112 if (eth_dev->data->mac_addrs == NULL) {
117 eth_dev->data->mtu = 1500;
119 eth_dev->data->nb_rx_queues = 1;
120 eth_dev->data->nb_tx_queues = 1;
122 /* For link status, open the PFE CDEV; Error from this function
123 * is silently ignored; In case of error, the link status will not
126 pfe_eth_open_cdev(priv);
127 rte_eth_dev_probing_finish(eth_dev);
131 rte_eth_dev_release_port(eth_dev);
135 /* Parse integer from integer argument */
137 parse_integer_arg(const char *key __rte_unused,
138 const char *value, void *extra_args)
144 i = strtol(value, &end, 10);
145 if (*end != 0 || errno != 0 || i < 0 || i > 1)
148 *((uint32_t *)extra_args) = i;
154 pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params,
155 struct rte_vdev_device *dev)
157 struct rte_kvargs *kvlist = NULL;
160 static const char * const pfe_vdev_valid_params[] = {
165 const char *input_args = rte_vdev_device_args(dev);
170 kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params);
174 ret = rte_kvargs_process(kvlist,
178 rte_kvargs_free(kvlist);
183 pmd_pfe_probe(struct rte_vdev_device *vdev)
186 const struct device_node *np;
188 const uint32_t *addr;
189 uint64_t cbus_addr, ddr_size, cbus_size;
190 int rc = -1, fd = -1, gem_id;
191 unsigned int interface_count = 0;
193 struct pfe_vdev_init_params init_params = {
197 name = rte_vdev_device_name(vdev);
198 rc = pfe_parse_vdev_init_params(&init_params, vdev);
203 if (g_pfe->nb_devs >= g_pfe->max_intf)
209 g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE);
213 /* Load the device-tree driver */
218 np = of_find_compatible_node(NULL, NULL, "fsl,pfe");
224 addr = of_get_address(np, 0, &cbus_size, NULL);
228 cbus_addr = of_translate_address(np, addr);
233 addr = of_get_address(np, 1, &ddr_size, NULL);
237 g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr);
238 if (!g_pfe->ddr_phys_baseaddr)
241 g_pfe->ddr_size = ddr_size;
242 g_pfe->cbus_size = cbus_size;
244 fd = open("/dev/mem", O_RDWR);
245 g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE,
246 MAP_SHARED, fd, cbus_addr);
248 if (g_pfe->cbus_baseaddr == MAP_FAILED) {
253 /* Read interface count */
254 prop = of_get_property(np, "fsl,pfe-num-interfaces", &size);
260 interface_count = rte_be_to_cpu_32((unsigned int)*prop);
261 if (interface_count <= 0) {
265 g_pfe->max_intf = interface_count;
266 pfe_soc_version_get();
268 if (init_params.gem_id < 0)
269 gem_id = g_pfe->nb_devs;
271 gem_id = init_params.gem_id;
273 RTE_LOG(INFO, PMD, "Init pmd_pfe for %s gem-id %d(given =%d)\n",
274 name, gem_id, init_params.gem_id);
276 rc = pfe_eth_init(vdev, g_pfe, gem_id);
286 munmap(g_pfe->cbus_baseaddr, cbus_size);
293 pmd_pfe_remove(struct rte_vdev_device *vdev)
296 struct rte_eth_dev *eth_dev = NULL;
298 name = rte_vdev_device_name(vdev);
305 eth_dev = rte_eth_dev_allocated(name);
309 pfe_eth_exit(eth_dev, g_pfe);
310 munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size);
316 struct rte_vdev_driver pmd_pfe_drv = {
317 .probe = pmd_pfe_probe,
318 .remove = pmd_pfe_remove,
321 RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv);
322 RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> ");