1 /* SPDX-License-Identifier: BSD-3-Clause
5 #include <rte_kvargs.h>
6 #include <rte_ethdev_vdev.h>
7 #include <rte_bus_vdev.h>
13 #define PFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/
14 #define PFE_VDEV_GEM_ID_ARG "intf"
16 struct pfe_vdev_init_params {
19 static struct pfe *g_pfe;
21 /* TODO: make pfe_svr a runtime option.
22 * Driver should be able to get the SVR
23 * information from HW.
25 unsigned int pfe_svr = SVR_LS1012A_REV1;
26 static void *cbus_emac_base[3];
27 static void *cbus_gpi_base[3];
34 pfe_gemac_init(struct pfe_eth_priv_s *priv)
38 cfg.speed = SPEED_1000M;
39 cfg.duplex = DUPLEX_FULL;
41 gemac_set_config(priv->EMAC_baseaddr, &cfg);
42 gemac_allow_broadcast(priv->EMAC_baseaddr);
43 gemac_enable_1536_rx(priv->EMAC_baseaddr);
44 gemac_enable_stacked_vlan(priv->EMAC_baseaddr);
45 gemac_enable_pause_rx(priv->EMAC_baseaddr);
46 gemac_set_bus_width(priv->EMAC_baseaddr, 64);
47 gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
53 pfe_soc_version_get(void)
55 FILE *svr_file = NULL;
56 unsigned int svr_ver = 0;
58 PMD_INIT_FUNC_TRACE();
60 svr_file = fopen(PFE_SOC_ID_FILE, "r");
62 PFE_PMD_ERR("Unable to open SoC device");
63 return; /* Not supported on this infra */
66 if (fscanf(svr_file, "svr:%x", &svr_ver) > 0)
69 PFE_PMD_ERR("Unable to read SoC device");
75 pfe_eth_open_cdev(struct pfe_eth_priv_s *priv)
82 pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY);
83 if (pfe_cdev_fd < 0) {
84 PFE_PMD_WARN("Unable to open PFE device file (%s).\n",
86 PFE_PMD_WARN("Link status update will not be available.\n");
87 priv->link_fd = PFE_CDEV_INVALID_FD;
91 priv->link_fd = pfe_cdev_fd;
97 pfe_eth_close_cdev(struct pfe_eth_priv_s *priv)
102 if (priv->link_fd != PFE_CDEV_INVALID_FD) {
103 close(priv->link_fd);
104 priv->link_fd = PFE_CDEV_INVALID_FD;
109 pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe)
111 PMD_INIT_FUNC_TRACE();
113 /* Close the device file for link status */
114 pfe_eth_close_cdev(dev->data->dev_private);
116 rte_free(dev->data->mac_addrs);
117 rte_eth_dev_release_port(dev);
122 pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id)
124 struct rte_eth_dev *eth_dev = NULL;
125 struct pfe_eth_priv_s *priv = NULL;
126 struct ls1012a_eth_platform_data *einfo;
127 struct ls1012a_pfe_platform_data *pfe_info;
130 eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv));
134 /* Extract pltform data */
135 pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data;
137 PFE_PMD_ERR("pfe missing additional platform data");
142 einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata;
144 /* einfo never be NULL, but no harm in having this check */
146 PFE_PMD_ERR("pfe missing additional gemacs platform data");
151 priv = eth_dev->data->dev_private;
152 priv->ndev = eth_dev;
153 priv->id = einfo[id].gem_id;
156 pfe->eth.eth_priv[id] = priv;
158 /* Set the info in the priv to the current info */
159 priv->einfo = &einfo[id];
160 priv->EMAC_baseaddr = cbus_emac_base[id];
161 priv->PHY_baseaddr = cbus_emac_base[id];
162 priv->GPI_baseaddr = cbus_gpi_base[id];
164 #define HIF_GEMAC_TMUQ_BASE 6
165 priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2);
166 priv->high_tmu_q = priv->low_tmu_q + 1;
168 rte_spinlock_init(&priv->lock);
170 /* Copy the station address into the dev structure, */
171 eth_dev->data->mac_addrs = rte_zmalloc("mac_addr",
172 ETHER_ADDR_LEN * PFE_MAX_MACS, 0);
173 if (eth_dev->data->mac_addrs == NULL) {
174 PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses",
175 ETHER_ADDR_LEN * PFE_MAX_MACS);
180 eth_dev->data->mtu = 1500;
181 pfe_gemac_init(priv);
183 eth_dev->data->nb_rx_queues = 1;
184 eth_dev->data->nb_tx_queues = 1;
186 /* For link status, open the PFE CDEV; Error from this function
187 * is silently ignored; In case of error, the link status will not
190 pfe_eth_open_cdev(priv);
191 rte_eth_dev_probing_finish(eth_dev);
195 rte_eth_dev_release_port(eth_dev);
200 pfe_get_gemac_if_proprties(struct pfe *pfe,
201 __rte_unused const struct device_node *parent,
202 unsigned int port, unsigned int if_cnt,
203 struct ls1012a_pfe_platform_data *pdata)
205 const struct device_node *gem = NULL;
207 unsigned int ii = 0, phy_id = 0;
209 const void *mac_addr;
211 for (ii = 0; ii < if_cnt; ii++) {
212 gem = of_get_next_child(parent, gem);
215 addr = of_get_property(gem, "reg", &size);
216 if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port))
221 PFE_PMD_ERR("Failed to find interface = %d", if_cnt);
225 pdata->ls1012a_eth_pdata[port].gem_id = port;
227 mac_addr = of_get_mac_address(gem);
230 memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr,
234 addr = of_get_property(gem, "fsl,mdio-mux-val", &size);
236 PFE_PMD_ERR("Invalid mdio-mux-val....");
238 phy_id = rte_be_to_cpu_32((unsigned int)*addr);
239 pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
241 if (pdata->ls1012a_eth_pdata[port].phy_id < 32)
242 pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] =
243 pdata->ls1012a_eth_pdata[port].mdio_muxval;
251 /* Parse integer from integer argument */
253 parse_integer_arg(const char *key __rte_unused,
254 const char *value, void *extra_args)
260 i = strtol(value, &end, 10);
261 if (*end != 0 || errno != 0 || i < 0 || i > 1) {
262 PFE_PMD_ERR("Supported Port IDS are 0 and 1");
266 *((uint32_t *)extra_args) = i;
272 pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params,
273 struct rte_vdev_device *dev)
275 struct rte_kvargs *kvlist = NULL;
278 static const char * const pfe_vdev_valid_params[] = {
283 const char *input_args = rte_vdev_device_args(dev);
288 kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params);
292 ret = rte_kvargs_process(kvlist,
296 rte_kvargs_free(kvlist);
301 pmd_pfe_probe(struct rte_vdev_device *vdev)
304 const struct device_node *np;
306 const uint32_t *addr;
307 uint64_t cbus_addr, ddr_size, cbus_size;
308 int rc = -1, fd = -1, gem_id;
309 unsigned int ii, interface_count = 0;
311 struct pfe_vdev_init_params init_params = {
315 name = rte_vdev_device_name(vdev);
316 rc = pfe_parse_vdev_init_params(&init_params, vdev);
320 RTE_LOG(INFO, PMD, "Initializing pmd_pfe for %s Given gem-id %d\n",
321 name, init_params.gem_id);
324 if (g_pfe->nb_devs >= g_pfe->max_intf) {
325 PFE_PMD_ERR("PFE %d dev already created Max is %d",
326 g_pfe->nb_devs, g_pfe->max_intf);
332 g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE);
336 /* Load the device-tree driver */
339 PFE_PMD_ERR("of_init failed with ret: %d", rc);
343 np = of_find_compatible_node(NULL, NULL, "fsl,pfe");
345 PFE_PMD_ERR("Invalid device node");
350 addr = of_get_address(np, 0, &cbus_size, NULL);
352 PFE_PMD_ERR("of_get_address cannot return qman address\n");
355 cbus_addr = of_translate_address(np, addr);
357 PFE_PMD_ERR("of_translate_address failed\n");
361 addr = of_get_address(np, 1, &ddr_size, NULL);
363 PFE_PMD_ERR("of_get_address cannot return qman address\n");
367 g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr);
368 if (!g_pfe->ddr_phys_baseaddr) {
369 PFE_PMD_ERR("of_translate_address failed\n");
373 g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr);
374 g_pfe->ddr_size = ddr_size;
375 g_pfe->cbus_size = cbus_size;
377 fd = open("/dev/mem", O_RDWR);
378 g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE,
379 MAP_SHARED, fd, cbus_addr);
381 if (g_pfe->cbus_baseaddr == MAP_FAILED) {
382 PFE_PMD_ERR("Can not map cbus base");
387 /* Read interface count */
388 prop = of_get_property(np, "fsl,pfe-num-interfaces", &size);
390 PFE_PMD_ERR("Failed to read number of interfaces");
395 interface_count = rte_be_to_cpu_32((unsigned int)*prop);
396 if (interface_count <= 0) {
397 PFE_PMD_ERR("No ethernet interface count : %d",
402 PFE_PMD_INFO("num interfaces = %d ", interface_count);
404 g_pfe->max_intf = interface_count;
405 g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
407 for (ii = 0; ii < interface_count; ii++) {
408 pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count,
409 &g_pfe->platform_data);
412 pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr,
413 g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size);
415 PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION));
416 PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION));
418 PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION));
419 PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION));
421 PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION));
422 PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION));
423 PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION));
425 PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION));
426 PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION));
428 cbus_emac_base[0] = EMAC1_BASE_ADDR;
429 cbus_emac_base[1] = EMAC2_BASE_ADDR;
431 cbus_gpi_base[0] = EGPI1_BASE_ADDR;
432 cbus_gpi_base[1] = EGPI2_BASE_ADDR;
434 rc = pfe_hif_lib_init(g_pfe);
438 rc = pfe_hif_init(g_pfe);
441 pfe_soc_version_get();
443 if (init_params.gem_id < 0)
444 gem_id = g_pfe->nb_devs;
446 gem_id = init_params.gem_id;
448 RTE_LOG(INFO, PMD, "Init pmd_pfe for %s gem-id %d(given =%d)\n",
449 name, gem_id, init_params.gem_id);
451 rc = pfe_eth_init(vdev, g_pfe, gem_id);
463 pfe_hif_lib_exit(g_pfe);
467 munmap(g_pfe->cbus_baseaddr, cbus_size);
474 pmd_pfe_remove(struct rte_vdev_device *vdev)
477 struct rte_eth_dev *eth_dev = NULL;
479 name = rte_vdev_device_name(vdev);
483 PFE_PMD_INFO("Closing eventdev sw device %s", name);
488 eth_dev = rte_eth_dev_allocated(name);
492 pfe_eth_exit(eth_dev, g_pfe);
493 munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size);
495 if (g_pfe->nb_devs == 0) {
497 pfe_hif_lib_exit(g_pfe);
505 struct rte_vdev_driver pmd_pfe_drv = {
506 .probe = pmd_pfe_probe,
507 .remove = pmd_pfe_remove,
510 RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv);
511 RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> ");
513 RTE_INIT(pfe_pmd_init_log)
515 pfe_logtype_pmd = rte_log_register("pmd.net.pfe");
516 if (pfe_logtype_pmd >= 0)
517 rte_log_set_level(pfe_logtype_pmd, RTE_LOG_NOTICE);