167fc3ff9SGagandeep Singh /* SPDX-License-Identifier: BSD-3-Clause 2f513f620SSachin Saxena * Copyright 2018-2019 NXP 367fc3ff9SGagandeep Singh */ 467fc3ff9SGagandeep Singh 5acd4818eSGagandeep Singh #include <sys/ioctl.h> 636220514SGagandeep Singh #include <sys/epoll.h> 767fc3ff9SGagandeep Singh #include <rte_kvargs.h> 8df96fd0dSBruce Richardson #include <ethdev_vdev.h> 967fc3ff9SGagandeep Singh #include <rte_bus_vdev.h> 10320ae324SGagandeep Singh #include <rte_ether.h> 1167fc3ff9SGagandeep Singh #include <dpaa_of.h> 1267fc3ff9SGagandeep Singh 13b1bc1afaSGagandeep Singh #include "pfe_logs.h" 1467fc3ff9SGagandeep Singh #include "pfe_mod.h" 1567fc3ff9SGagandeep Singh 1667fc3ff9SGagandeep Singh #define PFE_MAX_MACS 1 /* we can support up to 4 MACs per IF */ 1767fc3ff9SGagandeep Singh #define PFE_VDEV_GEM_ID_ARG "intf" 1867fc3ff9SGagandeep Singh 1967fc3ff9SGagandeep Singh struct pfe_vdev_init_params { 2067fc3ff9SGagandeep Singh int8_t gem_id; 2167fc3ff9SGagandeep Singh }; 2267fc3ff9SGagandeep Singh static struct pfe *g_pfe; 23592041a0SGagandeep Singh /* Supported Rx offloads */ 24592041a0SGagandeep Singh static uint64_t dev_rx_offloads_sup = 25592041a0SGagandeep Singh DEV_RX_OFFLOAD_IPV4_CKSUM | 26592041a0SGagandeep Singh DEV_RX_OFFLOAD_UDP_CKSUM | 27592041a0SGagandeep Singh DEV_RX_OFFLOAD_TCP_CKSUM; 28592041a0SGagandeep Singh 29592041a0SGagandeep Singh /* Supported Tx offloads */ 30592041a0SGagandeep Singh static uint64_t dev_tx_offloads_sup = 31592041a0SGagandeep Singh DEV_TX_OFFLOAD_IPV4_CKSUM | 32592041a0SGagandeep Singh DEV_TX_OFFLOAD_UDP_CKSUM | 33592041a0SGagandeep Singh DEV_TX_OFFLOAD_TCP_CKSUM; 3467fc3ff9SGagandeep Singh 3567fc3ff9SGagandeep Singh /* TODO: make pfe_svr a runtime option. 3667fc3ff9SGagandeep Singh * Driver should be able to get the SVR 3767fc3ff9SGagandeep Singh * information from HW. 3867fc3ff9SGagandeep Singh */ 3967fc3ff9SGagandeep Singh unsigned int pfe_svr = SVR_LS1012A_REV1; 405253fe37SGagandeep Singh static void *cbus_emac_base[3]; 415253fe37SGagandeep Singh static void *cbus_gpi_base[3]; 4267fc3ff9SGagandeep Singh 435253fe37SGagandeep Singh /* pfe_gemac_init 445253fe37SGagandeep Singh */ 455253fe37SGagandeep Singh static int 465253fe37SGagandeep Singh pfe_gemac_init(struct pfe_eth_priv_s *priv) 475253fe37SGagandeep Singh { 485253fe37SGagandeep Singh struct gemac_cfg cfg; 495253fe37SGagandeep Singh 505253fe37SGagandeep Singh cfg.speed = SPEED_1000M; 515253fe37SGagandeep Singh cfg.duplex = DUPLEX_FULL; 525253fe37SGagandeep Singh 535253fe37SGagandeep Singh gemac_set_config(priv->EMAC_baseaddr, &cfg); 545253fe37SGagandeep Singh gemac_allow_broadcast(priv->EMAC_baseaddr); 555253fe37SGagandeep Singh gemac_enable_1536_rx(priv->EMAC_baseaddr); 565253fe37SGagandeep Singh gemac_enable_stacked_vlan(priv->EMAC_baseaddr); 575253fe37SGagandeep Singh gemac_enable_pause_rx(priv->EMAC_baseaddr); 585253fe37SGagandeep Singh gemac_set_bus_width(priv->EMAC_baseaddr, 64); 595253fe37SGagandeep Singh gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); 605253fe37SGagandeep Singh 615253fe37SGagandeep Singh return 0; 625253fe37SGagandeep Singh } 635253fe37SGagandeep Singh 6467fc3ff9SGagandeep Singh static void 6567fc3ff9SGagandeep Singh pfe_soc_version_get(void) 6667fc3ff9SGagandeep Singh { 6767fc3ff9SGagandeep Singh FILE *svr_file = NULL; 6867fc3ff9SGagandeep Singh unsigned int svr_ver = 0; 6967fc3ff9SGagandeep Singh 70b1bc1afaSGagandeep Singh PMD_INIT_FUNC_TRACE(); 71b1bc1afaSGagandeep Singh 7267fc3ff9SGagandeep Singh svr_file = fopen(PFE_SOC_ID_FILE, "r"); 73b1bc1afaSGagandeep Singh if (!svr_file) { 74b1bc1afaSGagandeep Singh PFE_PMD_ERR("Unable to open SoC device"); 7567fc3ff9SGagandeep Singh return; /* Not supported on this infra */ 76b1bc1afaSGagandeep Singh } 7767fc3ff9SGagandeep Singh 7867fc3ff9SGagandeep Singh if (fscanf(svr_file, "svr:%x", &svr_ver) > 0) 7967fc3ff9SGagandeep Singh pfe_svr = svr_ver; 8067fc3ff9SGagandeep Singh else 81b1bc1afaSGagandeep Singh PFE_PMD_ERR("Unable to read SoC device"); 8267fc3ff9SGagandeep Singh 8367fc3ff9SGagandeep Singh fclose(svr_file); 8467fc3ff9SGagandeep Singh } 8567fc3ff9SGagandeep Singh 86fe38ad9bSGagandeep Singh static int pfe_eth_start(struct pfe_eth_priv_s *priv) 87fe38ad9bSGagandeep Singh { 88fe38ad9bSGagandeep Singh gpi_enable(priv->GPI_baseaddr); 89fe38ad9bSGagandeep Singh gemac_enable(priv->EMAC_baseaddr); 90fe38ad9bSGagandeep Singh 91fe38ad9bSGagandeep Singh return 0; 92fe38ad9bSGagandeep Singh } 93fe38ad9bSGagandeep Singh 94fe38ad9bSGagandeep Singh static void 95fe38ad9bSGagandeep Singh pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int 96fe38ad9bSGagandeep Singh __rte_unused from_tx, __rte_unused int n_desc) 97fe38ad9bSGagandeep Singh { 98fe38ad9bSGagandeep Singh struct rte_mbuf *mbuf; 99fe38ad9bSGagandeep Singh unsigned int flags; 100fe38ad9bSGagandeep Singh 101fe38ad9bSGagandeep Singh /* Clean HIF and client queue */ 102fe38ad9bSGagandeep Singh while ((mbuf = hif_lib_tx_get_next_complete(&priv->client, 103fe38ad9bSGagandeep Singh tx_q_num, &flags, 104fe38ad9bSGagandeep Singh HIF_TX_DESC_NT))) { 105fe38ad9bSGagandeep Singh if (mbuf) { 106fe38ad9bSGagandeep Singh mbuf->next = NULL; 107fe38ad9bSGagandeep Singh mbuf->nb_segs = 1; 108fe38ad9bSGagandeep Singh rte_pktmbuf_free(mbuf); 109fe38ad9bSGagandeep Singh } 110fe38ad9bSGagandeep Singh } 111fe38ad9bSGagandeep Singh } 112fe38ad9bSGagandeep Singh 113fe38ad9bSGagandeep Singh 114fe38ad9bSGagandeep Singh static void 115fe38ad9bSGagandeep Singh pfe_eth_flush_tx(struct pfe_eth_priv_s *priv) 116fe38ad9bSGagandeep Singh { 117fe38ad9bSGagandeep Singh unsigned int ii; 118fe38ad9bSGagandeep Singh 119fe38ad9bSGagandeep Singh for (ii = 0; ii < emac_txq_cnt; ii++) 120fe38ad9bSGagandeep Singh pfe_eth_flush_txQ(priv, ii, 0, 0); 121fe38ad9bSGagandeep Singh } 122fe38ad9bSGagandeep Singh 123fe38ad9bSGagandeep Singh static int 124fe38ad9bSGagandeep Singh pfe_eth_event_handler(void *data, int event, __rte_unused int qno) 125fe38ad9bSGagandeep Singh { 126fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = data; 127fe38ad9bSGagandeep Singh 128fe38ad9bSGagandeep Singh switch (event) { 129fe38ad9bSGagandeep Singh case EVENT_TXDONE_IND: 130fe38ad9bSGagandeep Singh pfe_eth_flush_tx(priv); 131fe38ad9bSGagandeep Singh hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0); 132fe38ad9bSGagandeep Singh break; 133fe38ad9bSGagandeep Singh case EVENT_HIGH_RX_WM: 134fe38ad9bSGagandeep Singh default: 135fe38ad9bSGagandeep Singh break; 136fe38ad9bSGagandeep Singh } 137fe38ad9bSGagandeep Singh 138fe38ad9bSGagandeep Singh return 0; 139fe38ad9bSGagandeep Singh } 140fe38ad9bSGagandeep Singh 14136220514SGagandeep Singh static uint16_t 14236220514SGagandeep Singh pfe_recv_pkts_on_intr(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 14336220514SGagandeep Singh { 14436220514SGagandeep Singh struct hif_client_rx_queue *queue = rxq; 14536220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 14636220514SGagandeep Singh struct epoll_event epoll_ev; 14736220514SGagandeep Singh uint64_t ticks = 1; /* 1 msec */ 14836220514SGagandeep Singh int ret; 14936220514SGagandeep Singh int have_something, work_done; 15036220514SGagandeep Singh 15136220514SGagandeep Singh #define RESET_STATUS (HIF_INT | HIF_RXPKT_INT) 15236220514SGagandeep Singh 15336220514SGagandeep Singh /*TODO can we remove this cleanup from here?*/ 15436220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 15536220514SGagandeep Singh have_something = pfe_hif_rx_process(priv->pfe, nb_pkts); 15636220514SGagandeep Singh work_done = hif_lib_receive_pkt(rxq, priv->pfe->hif.shm->pool, 15736220514SGagandeep Singh rx_pkts, nb_pkts); 15836220514SGagandeep Singh 15936220514SGagandeep Singh if (!have_something || !work_done) { 16036220514SGagandeep Singh writel(RESET_STATUS, HIF_INT_SRC); 16136220514SGagandeep Singh writel(readl(HIF_INT_ENABLE) | HIF_RXPKT_INT, HIF_INT_ENABLE); 16236220514SGagandeep Singh ret = epoll_wait(priv->pfe->hif.epoll_fd, &epoll_ev, 1, ticks); 16336220514SGagandeep Singh if (ret < 0 && errno != EINTR) 16436220514SGagandeep Singh PFE_PMD_ERR("epoll_wait fails with %d\n", errno); 16536220514SGagandeep Singh } 16636220514SGagandeep Singh 16736220514SGagandeep Singh return work_done; 16836220514SGagandeep Singh } 16936220514SGagandeep Singh 17036220514SGagandeep Singh static uint16_t 17136220514SGagandeep Singh pfe_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 17236220514SGagandeep Singh { 17336220514SGagandeep Singh struct hif_client_rx_queue *queue = rxq; 17436220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 17536220514SGagandeep Singh struct rte_mempool *pool; 17636220514SGagandeep Singh 17736220514SGagandeep Singh /*TODO can we remove this cleanup from here?*/ 17836220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 17936220514SGagandeep Singh pfe_hif_rx_process(priv->pfe, nb_pkts); 18036220514SGagandeep Singh pool = priv->pfe->hif.shm->pool; 18136220514SGagandeep Singh 18236220514SGagandeep Singh return hif_lib_receive_pkt(rxq, pool, rx_pkts, nb_pkts); 18336220514SGagandeep Singh } 18436220514SGagandeep Singh 18536220514SGagandeep Singh static uint16_t 18636220514SGagandeep Singh pfe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 18736220514SGagandeep Singh { 18836220514SGagandeep Singh struct hif_client_tx_queue *queue = tx_queue; 18936220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 19036220514SGagandeep Singh struct rte_eth_stats *stats = &priv->stats; 19136220514SGagandeep Singh int i; 19236220514SGagandeep Singh 19336220514SGagandeep Singh for (i = 0; i < nb_pkts; i++) { 19436220514SGagandeep Singh if (tx_pkts[i]->nb_segs > 1) { 19536220514SGagandeep Singh struct rte_mbuf *mbuf; 19636220514SGagandeep Singh int j; 19736220514SGagandeep Singh 19836220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 19936220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 20036220514SGagandeep Singh tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 20136220514SGagandeep Singh tx_pkts[i]->data_len, 0x0, HIF_FIRST_BUFFER, 20236220514SGagandeep Singh tx_pkts[i]); 20336220514SGagandeep Singh 20436220514SGagandeep Singh mbuf = tx_pkts[i]->next; 20536220514SGagandeep Singh for (j = 0; j < (tx_pkts[i]->nb_segs - 2); j++) { 20636220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 20736220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(mbuf), 20836220514SGagandeep Singh mbuf->buf_addr + mbuf->data_off, 20936220514SGagandeep Singh mbuf->data_len, 21036220514SGagandeep Singh 0x0, 0x0, mbuf); 21136220514SGagandeep Singh mbuf = mbuf->next; 21236220514SGagandeep Singh } 21336220514SGagandeep Singh 21436220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 21536220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(mbuf), 21636220514SGagandeep Singh mbuf->buf_addr + mbuf->data_off, 21736220514SGagandeep Singh mbuf->data_len, 21836220514SGagandeep Singh 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID, 21936220514SGagandeep Singh mbuf); 22036220514SGagandeep Singh } else { 22136220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 22236220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 22336220514SGagandeep Singh tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 22436220514SGagandeep Singh tx_pkts[i]->pkt_len, 0 /*ctrl*/, 22536220514SGagandeep Singh HIF_FIRST_BUFFER | HIF_LAST_BUFFER | 22636220514SGagandeep Singh HIF_DATA_VALID, 22736220514SGagandeep Singh tx_pkts[i]); 22836220514SGagandeep Singh } 22936220514SGagandeep Singh stats->obytes += tx_pkts[i]->pkt_len; 23036220514SGagandeep Singh hif_tx_dma_start(); 23136220514SGagandeep Singh } 23236220514SGagandeep Singh stats->opackets += nb_pkts; 23336220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 23436220514SGagandeep Singh 23536220514SGagandeep Singh return nb_pkts; 23636220514SGagandeep Singh } 23736220514SGagandeep Singh 23836220514SGagandeep Singh static uint16_t 23936220514SGagandeep Singh pfe_dummy_xmit_pkts(__rte_unused void *tx_queue, 24036220514SGagandeep Singh __rte_unused struct rte_mbuf **tx_pkts, 24136220514SGagandeep Singh __rte_unused uint16_t nb_pkts) 24236220514SGagandeep Singh { 24336220514SGagandeep Singh return 0; 24436220514SGagandeep Singh } 24536220514SGagandeep Singh 24636220514SGagandeep Singh static uint16_t 24736220514SGagandeep Singh pfe_dummy_recv_pkts(__rte_unused void *rxq, 24836220514SGagandeep Singh __rte_unused struct rte_mbuf **rx_pkts, 24936220514SGagandeep Singh __rte_unused uint16_t nb_pkts) 25036220514SGagandeep Singh { 25136220514SGagandeep Singh return 0; 25236220514SGagandeep Singh } 25336220514SGagandeep Singh 254fe38ad9bSGagandeep Singh static int 255fe38ad9bSGagandeep Singh pfe_eth_open(struct rte_eth_dev *dev) 256fe38ad9bSGagandeep Singh { 257fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 258fe38ad9bSGagandeep Singh struct hif_client_s *client; 259fe38ad9bSGagandeep Singh struct hif_shm *hif_shm; 260fe38ad9bSGagandeep Singh int rc; 261fe38ad9bSGagandeep Singh 262fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 263fe38ad9bSGagandeep Singh client = &priv->client; 264fe38ad9bSGagandeep Singh 265fe38ad9bSGagandeep Singh if (client->pfe) { 266fe38ad9bSGagandeep Singh hif_shm = client->pfe->hif.shm; 267fe38ad9bSGagandeep Singh /* TODO please remove the below code of if block, once we add 268fe38ad9bSGagandeep Singh * the proper cleanup in eth_close 269fe38ad9bSGagandeep Singh */ 270fe38ad9bSGagandeep Singh if (!test_bit(PFE_CL_GEM0 + priv->id, 271fe38ad9bSGagandeep Singh &hif_shm->g_client_status[0])) { 272fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 273fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 274fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 275fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 276fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 277fe38ad9bSGagandeep Singh client->priv = priv; 278fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 279fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 280fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 281fe38ad9bSGagandeep Singh 282fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 283fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 284fe38ad9bSGagandeep Singh 285fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 286fe38ad9bSGagandeep Singh if (rc) { 287fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d)" 288fe38ad9bSGagandeep Singh " failed", client->id); 289fe38ad9bSGagandeep Singh goto err0; 290fe38ad9bSGagandeep Singh } 29136220514SGagandeep Singh } else { 29236220514SGagandeep Singh /* Freeing the packets if already exists */ 29336220514SGagandeep Singh int ret = 0; 29436220514SGagandeep Singh struct rte_mbuf *rx_pkts[32]; 29536220514SGagandeep Singh /* TODO multiqueue support */ 29636220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 29736220514SGagandeep Singh hif_shm->pool, rx_pkts, 32); 29836220514SGagandeep Singh while (ret) { 29936220514SGagandeep Singh int i; 30036220514SGagandeep Singh for (i = 0; i < ret; i++) 30136220514SGagandeep Singh rte_pktmbuf_free(rx_pkts[i]); 30236220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 30336220514SGagandeep Singh hif_shm->pool, 30436220514SGagandeep Singh rx_pkts, 32); 30536220514SGagandeep Singh } 306fe38ad9bSGagandeep Singh } 307fe38ad9bSGagandeep Singh } else { 308fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 309fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 310fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 311fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 312fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 313fe38ad9bSGagandeep Singh client->priv = priv; 314fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 315fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 316fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 317fe38ad9bSGagandeep Singh 318fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 319fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 320fe38ad9bSGagandeep Singh 321fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 322fe38ad9bSGagandeep Singh if (rc) { 323fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d) failed", 324fe38ad9bSGagandeep Singh client->id); 325fe38ad9bSGagandeep Singh goto err0; 326fe38ad9bSGagandeep Singh } 327fe38ad9bSGagandeep Singh } 328fe38ad9bSGagandeep Singh rc = pfe_eth_start(priv); 32936220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts; 33036220514SGagandeep Singh dev->tx_pkt_burst = &pfe_xmit_pkts; 33136220514SGagandeep Singh /* If no prefetch is configured. */ 33236220514SGagandeep Singh if (getenv("PFE_INTR_SUPPORT")) { 33336220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; 33436220514SGagandeep Singh PFE_PMD_INFO("PFE INTERRUPT Mode enabled"); 33536220514SGagandeep Singh } 33636220514SGagandeep Singh 337fe38ad9bSGagandeep Singh 338fe38ad9bSGagandeep Singh err0: 339fe38ad9bSGagandeep Singh return rc; 340fe38ad9bSGagandeep Singh } 341fe38ad9bSGagandeep Singh 34267fc3ff9SGagandeep Singh static int 34367fc3ff9SGagandeep Singh pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) 34467fc3ff9SGagandeep Singh { 34567fc3ff9SGagandeep Singh int pfe_cdev_fd; 34667fc3ff9SGagandeep Singh 34767fc3ff9SGagandeep Singh if (priv == NULL) 34867fc3ff9SGagandeep Singh return -1; 34967fc3ff9SGagandeep Singh 35067fc3ff9SGagandeep Singh pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); 35167fc3ff9SGagandeep Singh if (pfe_cdev_fd < 0) { 352b1bc1afaSGagandeep Singh PFE_PMD_WARN("Unable to open PFE device file (%s).\n", 353b1bc1afaSGagandeep Singh PFE_CDEV_PATH); 354b1bc1afaSGagandeep Singh PFE_PMD_WARN("Link status update will not be available.\n"); 35567fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 35667fc3ff9SGagandeep Singh return -1; 35767fc3ff9SGagandeep Singh } 35867fc3ff9SGagandeep Singh 35967fc3ff9SGagandeep Singh priv->link_fd = pfe_cdev_fd; 36067fc3ff9SGagandeep Singh 36167fc3ff9SGagandeep Singh return 0; 36267fc3ff9SGagandeep Singh } 36367fc3ff9SGagandeep Singh 36467fc3ff9SGagandeep Singh static void 36567fc3ff9SGagandeep Singh pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) 36667fc3ff9SGagandeep Singh { 36767fc3ff9SGagandeep Singh if (priv == NULL) 36867fc3ff9SGagandeep Singh return; 36967fc3ff9SGagandeep Singh 37067fc3ff9SGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 37167fc3ff9SGagandeep Singh close(priv->link_fd); 37267fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 37367fc3ff9SGagandeep Singh } 37467fc3ff9SGagandeep Singh } 37567fc3ff9SGagandeep Singh 37662024eb8SIvan Ilchenko static int 377fe38ad9bSGagandeep Singh pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) 378fe38ad9bSGagandeep Singh { 379fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 380fe38ad9bSGagandeep Singh 381b8f5d2aeSThomas Monjalon dev->data->dev_started = 0; 382b8f5d2aeSThomas Monjalon 383fe38ad9bSGagandeep Singh gemac_disable(priv->EMAC_baseaddr); 384fe38ad9bSGagandeep Singh gpi_disable(priv->GPI_baseaddr); 38536220514SGagandeep Singh 38636220514SGagandeep Singh dev->rx_pkt_burst = &pfe_dummy_recv_pkts; 38736220514SGagandeep Singh dev->tx_pkt_burst = &pfe_dummy_xmit_pkts; 38862024eb8SIvan Ilchenko 38962024eb8SIvan Ilchenko return 0; 390fe38ad9bSGagandeep Singh } 391fe38ad9bSGagandeep Singh 392b142387bSThomas Monjalon static int 393fe38ad9bSGagandeep Singh pfe_eth_close(struct rte_eth_dev *dev) 394fe38ad9bSGagandeep Singh { 39562024eb8SIvan Ilchenko int ret; 39657803c5eSSachin Saxena PMD_INIT_FUNC_TRACE(); 39757803c5eSSachin Saxena 398fe38ad9bSGagandeep Singh if (!dev) 399b142387bSThomas Monjalon return -1; 400fe38ad9bSGagandeep Singh 401fe38ad9bSGagandeep Singh if (!g_pfe) 402b142387bSThomas Monjalon return -1; 403fe38ad9bSGagandeep Singh 40430410493SThomas Monjalon if (rte_eal_process_type() != RTE_PROC_PRIMARY) 40530410493SThomas Monjalon return 0; 40630410493SThomas Monjalon 40762024eb8SIvan Ilchenko ret = pfe_eth_stop(dev); 40857803c5eSSachin Saxena /* Close the device file for link status */ 40957803c5eSSachin Saxena pfe_eth_close_cdev(dev->data->dev_private); 41057803c5eSSachin Saxena 41157803c5eSSachin Saxena munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size); 41257803c5eSSachin Saxena g_pfe->nb_devs--; 413fe38ad9bSGagandeep Singh 414fe38ad9bSGagandeep Singh if (g_pfe->nb_devs == 0) { 415fe38ad9bSGagandeep Singh pfe_hif_exit(g_pfe); 416fe38ad9bSGagandeep Singh pfe_hif_lib_exit(g_pfe); 417fe38ad9bSGagandeep Singh rte_free(g_pfe); 418fe38ad9bSGagandeep Singh g_pfe = NULL; 419fe38ad9bSGagandeep Singh } 420b142387bSThomas Monjalon 42162024eb8SIvan Ilchenko return ret; 422fe38ad9bSGagandeep Singh } 423fe38ad9bSGagandeep Singh 424fe38ad9bSGagandeep Singh static int 425fe38ad9bSGagandeep Singh pfe_eth_configure(struct rte_eth_dev *dev __rte_unused) 426fe38ad9bSGagandeep Singh { 427fe38ad9bSGagandeep Singh return 0; 428fe38ad9bSGagandeep Singh } 429fe38ad9bSGagandeep Singh 430fe38ad9bSGagandeep Singh static int 431fe38ad9bSGagandeep Singh pfe_eth_info(struct rte_eth_dev *dev, 432fe38ad9bSGagandeep Singh struct rte_eth_dev_info *dev_info) 433fe38ad9bSGagandeep Singh { 434fe38ad9bSGagandeep Singh dev_info->max_mac_addrs = PFE_MAX_MACS; 435fe38ad9bSGagandeep Singh dev_info->max_rx_queues = dev->data->nb_rx_queues; 436fe38ad9bSGagandeep Singh dev_info->max_tx_queues = dev->data->nb_tx_queues; 437fe38ad9bSGagandeep Singh dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE; 438320ae324SGagandeep Singh dev_info->min_mtu = RTE_ETHER_MIN_MTU; 439592041a0SGagandeep Singh dev_info->rx_offload_capa = dev_rx_offloads_sup; 440592041a0SGagandeep Singh dev_info->tx_offload_capa = dev_tx_offloads_sup; 441320ae324SGagandeep Singh if (pfe_svr == SVR_LS1012A_REV1) { 442fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; 443320ae324SGagandeep Singh dev_info->max_mtu = MAX_MTU_ON_REV1; 444320ae324SGagandeep Singh } else { 445fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE; 446320ae324SGagandeep Singh dev_info->max_mtu = JUMBO_FRAME_SIZE - PFE_ETH_OVERHEAD; 447320ae324SGagandeep Singh } 448fe38ad9bSGagandeep Singh 449fe38ad9bSGagandeep Singh return 0; 450fe38ad9bSGagandeep Singh } 451fe38ad9bSGagandeep Singh 452592041a0SGagandeep Singh /* Only first mb_pool given on first call of this API will be used 453592041a0SGagandeep Singh * in whole system, also nb_rx_desc and rx_conf are unused params 454592041a0SGagandeep Singh */ 455592041a0SGagandeep Singh static int 456592041a0SGagandeep Singh pfe_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, 457592041a0SGagandeep Singh __rte_unused uint16_t nb_rx_desc, 458592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 459592041a0SGagandeep Singh __rte_unused const struct rte_eth_rxconf *rx_conf, 460592041a0SGagandeep Singh struct rte_mempool *mb_pool) 461592041a0SGagandeep Singh { 462592041a0SGagandeep Singh int rc = 0; 463592041a0SGagandeep Singh struct pfe *pfe; 464592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 465592041a0SGagandeep Singh 466592041a0SGagandeep Singh pfe = priv->pfe; 467592041a0SGagandeep Singh 468592041a0SGagandeep Singh if (queue_idx >= EMAC_RXQ_CNT) { 469592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 470592041a0SGagandeep Singh queue_idx, EMAC_RXQ_CNT); 471592041a0SGagandeep Singh return -1; 472592041a0SGagandeep Singh } 473592041a0SGagandeep Singh 474592041a0SGagandeep Singh if (!pfe->hif.setuped) { 475592041a0SGagandeep Singh rc = pfe_hif_shm_init(pfe->hif.shm, mb_pool); 476592041a0SGagandeep Singh if (rc) { 477592041a0SGagandeep Singh PFE_PMD_ERR("Could not allocate buffer descriptors"); 478592041a0SGagandeep Singh return -1; 479592041a0SGagandeep Singh } 480592041a0SGagandeep Singh 481592041a0SGagandeep Singh pfe->hif.shm->pool = mb_pool; 482592041a0SGagandeep Singh if (pfe_hif_init_buffers(&pfe->hif)) { 483592041a0SGagandeep Singh PFE_PMD_ERR("Could not initialize buffer descriptors"); 484592041a0SGagandeep Singh return -1; 485592041a0SGagandeep Singh } 486592041a0SGagandeep Singh hif_init(); 487592041a0SGagandeep Singh hif_rx_enable(); 488592041a0SGagandeep Singh hif_tx_enable(); 489592041a0SGagandeep Singh pfe->hif.setuped = 1; 490592041a0SGagandeep Singh } 491592041a0SGagandeep Singh dev->data->rx_queues[queue_idx] = &priv->client.rx_q[queue_idx]; 492592041a0SGagandeep Singh priv->client.rx_q[queue_idx].queue_id = queue_idx; 493592041a0SGagandeep Singh 494592041a0SGagandeep Singh return 0; 495592041a0SGagandeep Singh } 496592041a0SGagandeep Singh 497592041a0SGagandeep Singh static int 498592041a0SGagandeep Singh pfe_tx_queue_setup(struct rte_eth_dev *dev, 499592041a0SGagandeep Singh uint16_t queue_idx, 500592041a0SGagandeep Singh __rte_unused uint16_t nb_desc, 501592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 502592041a0SGagandeep Singh __rte_unused const struct rte_eth_txconf *tx_conf) 503592041a0SGagandeep Singh { 504592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 505592041a0SGagandeep Singh 506592041a0SGagandeep Singh if (queue_idx >= emac_txq_cnt) { 507592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 508592041a0SGagandeep Singh queue_idx, emac_txq_cnt); 509592041a0SGagandeep Singh return -1; 510592041a0SGagandeep Singh } 511592041a0SGagandeep Singh dev->data->tx_queues[queue_idx] = &priv->client.tx_q[queue_idx]; 512592041a0SGagandeep Singh priv->client.tx_q[queue_idx].queue_id = queue_idx; 513592041a0SGagandeep Singh return 0; 514592041a0SGagandeep Singh } 515592041a0SGagandeep Singh 516659b494dSGagandeep Singh static const uint32_t * 517659b494dSGagandeep Singh pfe_supported_ptypes_get(struct rte_eth_dev *dev) 518659b494dSGagandeep Singh { 519659b494dSGagandeep Singh static const uint32_t ptypes[] = { 520659b494dSGagandeep Singh /*todo -= add more types */ 521659b494dSGagandeep Singh RTE_PTYPE_L2_ETHER, 522659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4, 523659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4_EXT, 524659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6, 525659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6_EXT, 526659b494dSGagandeep Singh RTE_PTYPE_L4_TCP, 527659b494dSGagandeep Singh RTE_PTYPE_L4_UDP, 528659b494dSGagandeep Singh RTE_PTYPE_L4_SCTP 529659b494dSGagandeep Singh }; 530659b494dSGagandeep Singh 531659b494dSGagandeep Singh if (dev->rx_pkt_burst == pfe_recv_pkts || 532659b494dSGagandeep Singh dev->rx_pkt_burst == pfe_recv_pkts_on_intr) 533659b494dSGagandeep Singh return ptypes; 534659b494dSGagandeep Singh return NULL; 535659b494dSGagandeep Singh } 536659b494dSGagandeep Singh 537acd4818eSGagandeep Singh static inline int 538acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev, 539acd4818eSGagandeep Singh struct rte_eth_link *link) 540acd4818eSGagandeep Singh { 541acd4818eSGagandeep Singh struct rte_eth_link *dst = link; 542acd4818eSGagandeep Singh struct rte_eth_link *src = &dev->data->dev_link; 543acd4818eSGagandeep Singh 544acd4818eSGagandeep Singh if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 545acd4818eSGagandeep Singh *(uint64_t *)src) == 0) 546acd4818eSGagandeep Singh return -1; 547acd4818eSGagandeep Singh 548acd4818eSGagandeep Singh return 0; 549acd4818eSGagandeep Singh } 550acd4818eSGagandeep Singh 551acd4818eSGagandeep Singh static inline int 552acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev, 553acd4818eSGagandeep Singh struct rte_eth_link *link) 554acd4818eSGagandeep Singh { 555acd4818eSGagandeep Singh struct rte_eth_link *dst = &dev->data->dev_link; 556acd4818eSGagandeep Singh struct rte_eth_link *src = link; 557acd4818eSGagandeep Singh 558acd4818eSGagandeep Singh if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 559acd4818eSGagandeep Singh *(uint64_t *)src) == 0) 560acd4818eSGagandeep Singh return -1; 561acd4818eSGagandeep Singh 562acd4818eSGagandeep Singh return 0; 563acd4818eSGagandeep Singh } 564acd4818eSGagandeep Singh 565acd4818eSGagandeep Singh static int 566acd4818eSGagandeep Singh pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) 567acd4818eSGagandeep Singh { 568acd4818eSGagandeep Singh int ret, ioctl_cmd = 0; 569acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 570acd4818eSGagandeep Singh struct rte_eth_link link, old; 571acd4818eSGagandeep Singh unsigned int lstatus = 1; 572acd4818eSGagandeep Singh 573acd4818eSGagandeep Singh memset(&old, 0, sizeof(old)); 574acd4818eSGagandeep Singh memset(&link, 0, sizeof(struct rte_eth_link)); 575acd4818eSGagandeep Singh 576acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(dev, &old); 577acd4818eSGagandeep Singh 578acd4818eSGagandeep Singh /* Read from PFE CDEV, status of link, if file was successfully 579acd4818eSGagandeep Singh * opened. 580acd4818eSGagandeep Singh */ 581acd4818eSGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 582acd4818eSGagandeep Singh if (priv->id == 0) 583acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH0_STATE_GET; 584acd4818eSGagandeep Singh if (priv->id == 1) 585acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH1_STATE_GET; 586acd4818eSGagandeep Singh 587acd4818eSGagandeep Singh ret = ioctl(priv->link_fd, ioctl_cmd, &lstatus); 588acd4818eSGagandeep Singh if (ret != 0) { 589acd4818eSGagandeep Singh PFE_PMD_ERR("Unable to fetch link status (ioctl)\n"); 590acd4818eSGagandeep Singh /* use dummy link value */ 591acd4818eSGagandeep Singh link.link_status = 1; 592acd4818eSGagandeep Singh } 593acd4818eSGagandeep Singh PFE_PMD_DEBUG("Fetched link state (%d) for dev %d.\n", 594acd4818eSGagandeep Singh lstatus, priv->id); 595acd4818eSGagandeep Singh } 596acd4818eSGagandeep Singh 597acd4818eSGagandeep Singh if (old.link_status == lstatus) { 598acd4818eSGagandeep Singh /* no change in status */ 599acd4818eSGagandeep Singh PFE_PMD_DEBUG("No change in link status; Not updating.\n"); 600acd4818eSGagandeep Singh return -1; 601acd4818eSGagandeep Singh } 602acd4818eSGagandeep Singh 603acd4818eSGagandeep Singh link.link_status = lstatus; 604acd4818eSGagandeep Singh link.link_speed = ETH_LINK_SPEED_1G; 605acd4818eSGagandeep Singh link.link_duplex = ETH_LINK_FULL_DUPLEX; 606acd4818eSGagandeep Singh link.link_autoneg = ETH_LINK_AUTONEG; 607acd4818eSGagandeep Singh 608acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(dev, &link); 609acd4818eSGagandeep Singh 610acd4818eSGagandeep Singh PFE_PMD_INFO("Port (%d) link is %s\n", dev->data->port_id, 611acd4818eSGagandeep Singh link.link_status ? "up" : "down"); 612acd4818eSGagandeep Singh 613acd4818eSGagandeep Singh return 0; 614acd4818eSGagandeep Singh } 615acd4818eSGagandeep Singh 616659b494dSGagandeep Singh static int 617ff64beabSGagandeep Singh pfe_promiscuous_enable(struct rte_eth_dev *dev) 618ff64beabSGagandeep Singh { 619ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 620ff64beabSGagandeep Singh 621ff64beabSGagandeep Singh priv->promisc = 1; 622ff64beabSGagandeep Singh dev->data->promiscuous = 1; 623ff64beabSGagandeep Singh gemac_enable_copy_all(priv->EMAC_baseaddr); 624ff64beabSGagandeep Singh 625ff64beabSGagandeep Singh return 0; 626ff64beabSGagandeep Singh } 627ff64beabSGagandeep Singh 628ff64beabSGagandeep Singh static int 629ff64beabSGagandeep Singh pfe_promiscuous_disable(struct rte_eth_dev *dev) 630ff64beabSGagandeep Singh { 631ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 632ff64beabSGagandeep Singh 633ff64beabSGagandeep Singh priv->promisc = 0; 634ff64beabSGagandeep Singh dev->data->promiscuous = 0; 635ff64beabSGagandeep Singh gemac_disable_copy_all(priv->EMAC_baseaddr); 636ff64beabSGagandeep Singh 637ff64beabSGagandeep Singh return 0; 638ff64beabSGagandeep Singh } 639ff64beabSGagandeep Singh 640ff64beabSGagandeep Singh static int 641ff64beabSGagandeep Singh pfe_allmulticast_enable(struct rte_eth_dev *dev) 642ff64beabSGagandeep Singh { 643ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 644ff64beabSGagandeep Singh struct pfe_mac_addr hash_addr; /* hash register structure */ 645ff64beabSGagandeep Singh 646ff64beabSGagandeep Singh /* Set the hash to rx all multicast frames */ 647ff64beabSGagandeep Singh hash_addr.bottom = 0xFFFFFFFF; 648ff64beabSGagandeep Singh hash_addr.top = 0xFFFFFFFF; 649ff64beabSGagandeep Singh gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); 650ff64beabSGagandeep Singh dev->data->all_multicast = 1; 651ff64beabSGagandeep Singh 652ff64beabSGagandeep Singh return 0; 653ff64beabSGagandeep Singh } 654ff64beabSGagandeep Singh 655ff64beabSGagandeep Singh static int 656acd4818eSGagandeep Singh pfe_link_down(struct rte_eth_dev *dev) 657acd4818eSGagandeep Singh { 65862024eb8SIvan Ilchenko return pfe_eth_stop(dev); 659acd4818eSGagandeep Singh } 660acd4818eSGagandeep Singh 661acd4818eSGagandeep Singh static int 662acd4818eSGagandeep Singh pfe_link_up(struct rte_eth_dev *dev) 663acd4818eSGagandeep Singh { 664acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 665acd4818eSGagandeep Singh 666acd4818eSGagandeep Singh pfe_eth_start(priv); 667acd4818eSGagandeep Singh return 0; 668acd4818eSGagandeep Singh } 669acd4818eSGagandeep Singh 670acd4818eSGagandeep Singh static int 671320ae324SGagandeep Singh pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 672320ae324SGagandeep Singh { 673320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 674320ae324SGagandeep Singh uint16_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 675320ae324SGagandeep Singh 676320ae324SGagandeep Singh /*TODO Support VLAN*/ 677*1bb4a528SFerruh Yigit return gemac_set_rx(priv->EMAC_baseaddr, frame_size); 678320ae324SGagandeep Singh } 679320ae324SGagandeep Singh 680320ae324SGagandeep Singh /* pfe_eth_enet_addr_byte_mac 681320ae324SGagandeep Singh */ 682320ae324SGagandeep Singh static int 683320ae324SGagandeep Singh pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, 684320ae324SGagandeep Singh struct pfe_mac_addr *enet_addr) 685320ae324SGagandeep Singh { 686320ae324SGagandeep Singh if (!enet_byte_addr || !enet_addr) { 687320ae324SGagandeep Singh return -1; 688320ae324SGagandeep Singh 689320ae324SGagandeep Singh } else { 690320ae324SGagandeep Singh enet_addr->bottom = enet_byte_addr[0] | 691320ae324SGagandeep Singh (enet_byte_addr[1] << 8) | 692320ae324SGagandeep Singh (enet_byte_addr[2] << 16) | 693320ae324SGagandeep Singh (enet_byte_addr[3] << 24); 694320ae324SGagandeep Singh enet_addr->top = enet_byte_addr[4] | 695320ae324SGagandeep Singh (enet_byte_addr[5] << 8); 696320ae324SGagandeep Singh return 0; 697320ae324SGagandeep Singh } 698320ae324SGagandeep Singh } 699320ae324SGagandeep Singh 700320ae324SGagandeep Singh static int 701320ae324SGagandeep Singh pfe_dev_set_mac_addr(struct rte_eth_dev *dev, 702320ae324SGagandeep Singh struct rte_ether_addr *addr) 703320ae324SGagandeep Singh { 704320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 705320ae324SGagandeep Singh struct pfe_mac_addr spec_addr; 706320ae324SGagandeep Singh int ret; 707320ae324SGagandeep Singh 708320ae324SGagandeep Singh ret = pfe_eth_enet_addr_byte_mac(addr->addr_bytes, &spec_addr); 709320ae324SGagandeep Singh if (ret) 710320ae324SGagandeep Singh return ret; 711320ae324SGagandeep Singh 712320ae324SGagandeep Singh gemac_set_laddrN(priv->EMAC_baseaddr, 713320ae324SGagandeep Singh (struct pfe_mac_addr *)&spec_addr, 1); 714320ae324SGagandeep Singh rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 715320ae324SGagandeep Singh return 0; 716320ae324SGagandeep Singh } 717320ae324SGagandeep Singh 718320ae324SGagandeep Singh static int 719659b494dSGagandeep Singh pfe_stats_get(struct rte_eth_dev *dev, 720659b494dSGagandeep Singh struct rte_eth_stats *stats) 721659b494dSGagandeep Singh { 722659b494dSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 723659b494dSGagandeep Singh struct rte_eth_stats *eth_stats = &priv->stats; 724659b494dSGagandeep Singh 725659b494dSGagandeep Singh if (stats == NULL) 726659b494dSGagandeep Singh return -1; 727659b494dSGagandeep Singh 728659b494dSGagandeep Singh memset(stats, 0, sizeof(struct rte_eth_stats)); 729659b494dSGagandeep Singh 730659b494dSGagandeep Singh stats->ipackets = eth_stats->ipackets; 731659b494dSGagandeep Singh stats->ibytes = eth_stats->ibytes; 732659b494dSGagandeep Singh stats->opackets = eth_stats->opackets; 733659b494dSGagandeep Singh stats->obytes = eth_stats->obytes; 734659b494dSGagandeep Singh 735659b494dSGagandeep Singh return 0; 736659b494dSGagandeep Singh } 737659b494dSGagandeep Singh 738fe38ad9bSGagandeep Singh static const struct eth_dev_ops ops = { 739fe38ad9bSGagandeep Singh .dev_start = pfe_eth_open, 740fe38ad9bSGagandeep Singh .dev_stop = pfe_eth_stop, 741fe38ad9bSGagandeep Singh .dev_close = pfe_eth_close, 742fe38ad9bSGagandeep Singh .dev_configure = pfe_eth_configure, 743fe38ad9bSGagandeep Singh .dev_infos_get = pfe_eth_info, 744592041a0SGagandeep Singh .rx_queue_setup = pfe_rx_queue_setup, 745592041a0SGagandeep Singh .tx_queue_setup = pfe_tx_queue_setup, 746659b494dSGagandeep Singh .dev_supported_ptypes_get = pfe_supported_ptypes_get, 747acd4818eSGagandeep Singh .link_update = pfe_eth_link_update, 748ff64beabSGagandeep Singh .promiscuous_enable = pfe_promiscuous_enable, 749ff64beabSGagandeep Singh .promiscuous_disable = pfe_promiscuous_disable, 750ff64beabSGagandeep Singh .allmulticast_enable = pfe_allmulticast_enable, 751acd4818eSGagandeep Singh .dev_set_link_down = pfe_link_down, 752acd4818eSGagandeep Singh .dev_set_link_up = pfe_link_up, 753320ae324SGagandeep Singh .mtu_set = pfe_mtu_set, 754320ae324SGagandeep Singh .mac_addr_set = pfe_dev_set_mac_addr, 755659b494dSGagandeep Singh .stats_get = pfe_stats_get, 756fe38ad9bSGagandeep Singh }; 757fe38ad9bSGagandeep Singh 75867fc3ff9SGagandeep Singh static int 75967fc3ff9SGagandeep Singh pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) 76067fc3ff9SGagandeep Singh { 76167fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 76267fc3ff9SGagandeep Singh struct pfe_eth_priv_s *priv = NULL; 7635253fe37SGagandeep Singh struct ls1012a_eth_platform_data *einfo; 7645253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pfe_info; 765320ae324SGagandeep Singh struct rte_ether_addr addr; 76667fc3ff9SGagandeep Singh int err; 76767fc3ff9SGagandeep Singh 76867fc3ff9SGagandeep Singh eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); 76967fc3ff9SGagandeep Singh if (eth_dev == NULL) 77067fc3ff9SGagandeep Singh return -ENOMEM; 77167fc3ff9SGagandeep Singh 7725253fe37SGagandeep Singh /* Extract pltform data */ 7735253fe37SGagandeep Singh pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data; 7745253fe37SGagandeep Singh if (!pfe_info) { 7755253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional platform data"); 7765253fe37SGagandeep Singh err = -ENODEV; 7775253fe37SGagandeep Singh goto err0; 7785253fe37SGagandeep Singh } 7795253fe37SGagandeep Singh 7805253fe37SGagandeep Singh einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata; 7815253fe37SGagandeep Singh 7825253fe37SGagandeep Singh /* einfo never be NULL, but no harm in having this check */ 7835253fe37SGagandeep Singh if (!einfo) { 7845253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional gemacs platform data"); 7855253fe37SGagandeep Singh err = -ENODEV; 7865253fe37SGagandeep Singh goto err0; 7875253fe37SGagandeep Singh } 7885253fe37SGagandeep Singh 78967fc3ff9SGagandeep Singh priv = eth_dev->data->dev_private; 79067fc3ff9SGagandeep Singh priv->ndev = eth_dev; 7915253fe37SGagandeep Singh priv->id = einfo[id].gem_id; 79267fc3ff9SGagandeep Singh priv->pfe = pfe; 79367fc3ff9SGagandeep Singh 79467fc3ff9SGagandeep Singh pfe->eth.eth_priv[id] = priv; 79567fc3ff9SGagandeep Singh 7965253fe37SGagandeep Singh /* Set the info in the priv to the current info */ 7975253fe37SGagandeep Singh priv->einfo = &einfo[id]; 7985253fe37SGagandeep Singh priv->EMAC_baseaddr = cbus_emac_base[id]; 7995253fe37SGagandeep Singh priv->PHY_baseaddr = cbus_emac_base[id]; 8005253fe37SGagandeep Singh priv->GPI_baseaddr = cbus_gpi_base[id]; 8015253fe37SGagandeep Singh 80267fc3ff9SGagandeep Singh #define HIF_GEMAC_TMUQ_BASE 6 80367fc3ff9SGagandeep Singh priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); 80467fc3ff9SGagandeep Singh priv->high_tmu_q = priv->low_tmu_q + 1; 80567fc3ff9SGagandeep Singh 80667fc3ff9SGagandeep Singh rte_spinlock_init(&priv->lock); 80767fc3ff9SGagandeep Singh 80867fc3ff9SGagandeep Singh /* Copy the station address into the dev structure, */ 80967fc3ff9SGagandeep Singh eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", 81067fc3ff9SGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS, 0); 81167fc3ff9SGagandeep Singh if (eth_dev->data->mac_addrs == NULL) { 812b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses", 813b1bc1afaSGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS); 81467fc3ff9SGagandeep Singh err = -ENOMEM; 81567fc3ff9SGagandeep Singh goto err0; 81667fc3ff9SGagandeep Singh } 81767fc3ff9SGagandeep Singh 818320ae324SGagandeep Singh memcpy(addr.addr_bytes, priv->einfo->mac_addr, 819320ae324SGagandeep Singh ETH_ALEN); 820320ae324SGagandeep Singh 821320ae324SGagandeep Singh pfe_dev_set_mac_addr(eth_dev, &addr); 822320ae324SGagandeep Singh rte_ether_addr_copy(&addr, ð_dev->data->mac_addrs[0]); 823320ae324SGagandeep Singh 82467fc3ff9SGagandeep Singh eth_dev->data->mtu = 1500; 825fe38ad9bSGagandeep Singh eth_dev->dev_ops = &ops; 82662024eb8SIvan Ilchenko err = pfe_eth_stop(eth_dev); 82762024eb8SIvan Ilchenko if (err != 0) 82862024eb8SIvan Ilchenko goto err0; 8295253fe37SGagandeep Singh pfe_gemac_init(priv); 83067fc3ff9SGagandeep Singh 83167fc3ff9SGagandeep Singh eth_dev->data->nb_rx_queues = 1; 83267fc3ff9SGagandeep Singh eth_dev->data->nb_tx_queues = 1; 83367fc3ff9SGagandeep Singh 83467fc3ff9SGagandeep Singh /* For link status, open the PFE CDEV; Error from this function 83567fc3ff9SGagandeep Singh * is silently ignored; In case of error, the link status will not 83667fc3ff9SGagandeep Singh * be available. 83767fc3ff9SGagandeep Singh */ 83867fc3ff9SGagandeep Singh pfe_eth_open_cdev(priv); 83967fc3ff9SGagandeep Singh rte_eth_dev_probing_finish(eth_dev); 84067fc3ff9SGagandeep Singh 84167fc3ff9SGagandeep Singh return 0; 84267fc3ff9SGagandeep Singh err0: 84367fc3ff9SGagandeep Singh rte_eth_dev_release_port(eth_dev); 84467fc3ff9SGagandeep Singh return err; 84567fc3ff9SGagandeep Singh } 84667fc3ff9SGagandeep Singh 8475253fe37SGagandeep Singh static int 8485253fe37SGagandeep Singh pfe_get_gemac_if_proprties(struct pfe *pfe, 8495253fe37SGagandeep Singh __rte_unused const struct device_node *parent, 8505253fe37SGagandeep Singh unsigned int port, unsigned int if_cnt, 8515253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pdata) 8525253fe37SGagandeep Singh { 8535253fe37SGagandeep Singh const struct device_node *gem = NULL; 8545253fe37SGagandeep Singh size_t size; 8555253fe37SGagandeep Singh unsigned int ii = 0, phy_id = 0; 8565253fe37SGagandeep Singh const u32 *addr; 8575253fe37SGagandeep Singh const void *mac_addr; 8585253fe37SGagandeep Singh 8595253fe37SGagandeep Singh for (ii = 0; ii < if_cnt; ii++) { 8605253fe37SGagandeep Singh gem = of_get_next_child(parent, gem); 8615253fe37SGagandeep Singh if (!gem) 8625253fe37SGagandeep Singh goto err; 8635253fe37SGagandeep Singh addr = of_get_property(gem, "reg", &size); 8645253fe37SGagandeep Singh if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port)) 8655253fe37SGagandeep Singh break; 8665253fe37SGagandeep Singh } 8675253fe37SGagandeep Singh 8685253fe37SGagandeep Singh if (ii >= if_cnt) { 8695253fe37SGagandeep Singh PFE_PMD_ERR("Failed to find interface = %d", if_cnt); 8705253fe37SGagandeep Singh goto err; 8715253fe37SGagandeep Singh } 8725253fe37SGagandeep Singh 8735253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].gem_id = port; 8745253fe37SGagandeep Singh 8755253fe37SGagandeep Singh mac_addr = of_get_mac_address(gem); 8765253fe37SGagandeep Singh 8775253fe37SGagandeep Singh if (mac_addr) { 8785253fe37SGagandeep Singh memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, 8795253fe37SGagandeep Singh ETH_ALEN); 8805253fe37SGagandeep Singh } 8815253fe37SGagandeep Singh 8825253fe37SGagandeep Singh addr = of_get_property(gem, "fsl,mdio-mux-val", &size); 8835253fe37SGagandeep Singh if (!addr) { 8845253fe37SGagandeep Singh PFE_PMD_ERR("Invalid mdio-mux-val...."); 8855253fe37SGagandeep Singh } else { 8865253fe37SGagandeep Singh phy_id = rte_be_to_cpu_32((unsigned int)*addr); 8875253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; 8885253fe37SGagandeep Singh } 8895253fe37SGagandeep Singh if (pdata->ls1012a_eth_pdata[port].phy_id < 32) 8905253fe37SGagandeep Singh pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = 8915253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval; 8925253fe37SGagandeep Singh 8935253fe37SGagandeep Singh return 0; 8945253fe37SGagandeep Singh 8955253fe37SGagandeep Singh err: 8965253fe37SGagandeep Singh return -1; 8975253fe37SGagandeep Singh } 8985253fe37SGagandeep Singh 89967fc3ff9SGagandeep Singh /* Parse integer from integer argument */ 90067fc3ff9SGagandeep Singh static int 90167fc3ff9SGagandeep Singh parse_integer_arg(const char *key __rte_unused, 90267fc3ff9SGagandeep Singh const char *value, void *extra_args) 90367fc3ff9SGagandeep Singh { 90467fc3ff9SGagandeep Singh int i; 90567fc3ff9SGagandeep Singh char *end; 90667fc3ff9SGagandeep Singh errno = 0; 90767fc3ff9SGagandeep Singh 90867fc3ff9SGagandeep Singh i = strtol(value, &end, 10); 909b1bc1afaSGagandeep Singh if (*end != 0 || errno != 0 || i < 0 || i > 1) { 910b1bc1afaSGagandeep Singh PFE_PMD_ERR("Supported Port IDS are 0 and 1"); 91167fc3ff9SGagandeep Singh return -EINVAL; 912b1bc1afaSGagandeep Singh } 91367fc3ff9SGagandeep Singh 91467fc3ff9SGagandeep Singh *((uint32_t *)extra_args) = i; 91567fc3ff9SGagandeep Singh 91667fc3ff9SGagandeep Singh return 0; 91767fc3ff9SGagandeep Singh } 91867fc3ff9SGagandeep Singh 91967fc3ff9SGagandeep Singh static int 92067fc3ff9SGagandeep Singh pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params, 92167fc3ff9SGagandeep Singh struct rte_vdev_device *dev) 92267fc3ff9SGagandeep Singh { 92367fc3ff9SGagandeep Singh struct rte_kvargs *kvlist = NULL; 92467fc3ff9SGagandeep Singh int ret = 0; 92567fc3ff9SGagandeep Singh 92667fc3ff9SGagandeep Singh static const char * const pfe_vdev_valid_params[] = { 92767fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 92867fc3ff9SGagandeep Singh NULL 92967fc3ff9SGagandeep Singh }; 93067fc3ff9SGagandeep Singh 93167fc3ff9SGagandeep Singh const char *input_args = rte_vdev_device_args(dev); 93267fc3ff9SGagandeep Singh 93367fc3ff9SGagandeep Singh if (!input_args) 93467fc3ff9SGagandeep Singh return -1; 93567fc3ff9SGagandeep Singh 93667fc3ff9SGagandeep Singh kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params); 93767fc3ff9SGagandeep Singh if (kvlist == NULL) 93867fc3ff9SGagandeep Singh return -1; 93967fc3ff9SGagandeep Singh 94067fc3ff9SGagandeep Singh ret = rte_kvargs_process(kvlist, 94167fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 94267fc3ff9SGagandeep Singh &parse_integer_arg, 94367fc3ff9SGagandeep Singh ¶ms->gem_id); 94467fc3ff9SGagandeep Singh rte_kvargs_free(kvlist); 94567fc3ff9SGagandeep Singh return ret; 94667fc3ff9SGagandeep Singh } 94767fc3ff9SGagandeep Singh 94867fc3ff9SGagandeep Singh static int 94967fc3ff9SGagandeep Singh pmd_pfe_probe(struct rte_vdev_device *vdev) 95067fc3ff9SGagandeep Singh { 95167fc3ff9SGagandeep Singh const u32 *prop; 95267fc3ff9SGagandeep Singh const struct device_node *np; 95367fc3ff9SGagandeep Singh const char *name; 95467fc3ff9SGagandeep Singh const uint32_t *addr; 95567fc3ff9SGagandeep Singh uint64_t cbus_addr, ddr_size, cbus_size; 95667fc3ff9SGagandeep Singh int rc = -1, fd = -1, gem_id; 9575253fe37SGagandeep Singh unsigned int ii, interface_count = 0; 95867fc3ff9SGagandeep Singh size_t size = 0; 95967fc3ff9SGagandeep Singh struct pfe_vdev_init_params init_params = { 96067fc3ff9SGagandeep Singh .gem_id = -1 96167fc3ff9SGagandeep Singh }; 96267fc3ff9SGagandeep Singh 96367fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 96467fc3ff9SGagandeep Singh rc = pfe_parse_vdev_init_params(&init_params, vdev); 96567fc3ff9SGagandeep Singh if (rc < 0) 96667fc3ff9SGagandeep Singh return -EINVAL; 96767fc3ff9SGagandeep Singh 968b8907ccfSStephen Hemminger PFE_PMD_LOG(INFO, "Initializing pmd_pfe for %s Given gem-id %d", 969b1bc1afaSGagandeep Singh name, init_params.gem_id); 97067fc3ff9SGagandeep Singh 971b1bc1afaSGagandeep Singh if (g_pfe) { 972b1bc1afaSGagandeep Singh if (g_pfe->nb_devs >= g_pfe->max_intf) { 973b1bc1afaSGagandeep Singh PFE_PMD_ERR("PFE %d dev already created Max is %d", 974b1bc1afaSGagandeep Singh g_pfe->nb_devs, g_pfe->max_intf); 975b1bc1afaSGagandeep Singh return -EINVAL; 976b1bc1afaSGagandeep Singh } 97767fc3ff9SGagandeep Singh goto eth_init; 97867fc3ff9SGagandeep Singh } 97967fc3ff9SGagandeep Singh 98067fc3ff9SGagandeep Singh g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE); 98167fc3ff9SGagandeep Singh if (g_pfe == NULL) 98267fc3ff9SGagandeep Singh return -EINVAL; 98367fc3ff9SGagandeep Singh 98467fc3ff9SGagandeep Singh /* Load the device-tree driver */ 98567fc3ff9SGagandeep Singh rc = of_init(); 986b1bc1afaSGagandeep Singh if (rc) { 987b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_init failed with ret: %d", rc); 98867fc3ff9SGagandeep Singh goto err; 989b1bc1afaSGagandeep Singh } 99067fc3ff9SGagandeep Singh 99167fc3ff9SGagandeep Singh np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); 99267fc3ff9SGagandeep Singh if (!np) { 993b1bc1afaSGagandeep Singh PFE_PMD_ERR("Invalid device node"); 99467fc3ff9SGagandeep Singh rc = -EINVAL; 99567fc3ff9SGagandeep Singh goto err; 99667fc3ff9SGagandeep Singh } 99767fc3ff9SGagandeep Singh 99867fc3ff9SGagandeep Singh addr = of_get_address(np, 0, &cbus_size, NULL); 999b1bc1afaSGagandeep Singh if (!addr) { 1000b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_get_address cannot return qman address\n"); 100167fc3ff9SGagandeep Singh goto err; 1002b1bc1afaSGagandeep Singh } 100367fc3ff9SGagandeep Singh cbus_addr = of_translate_address(np, addr); 1004b1bc1afaSGagandeep Singh if (!cbus_addr) { 1005b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_translate_address failed\n"); 100667fc3ff9SGagandeep Singh goto err; 1007b1bc1afaSGagandeep Singh } 100867fc3ff9SGagandeep Singh 100967fc3ff9SGagandeep Singh addr = of_get_address(np, 1, &ddr_size, NULL); 1010b1bc1afaSGagandeep Singh if (!addr) { 1011b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_get_address cannot return qman address\n"); 101267fc3ff9SGagandeep Singh goto err; 1013b1bc1afaSGagandeep Singh } 101467fc3ff9SGagandeep Singh 101567fc3ff9SGagandeep Singh g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); 1016b1bc1afaSGagandeep Singh if (!g_pfe->ddr_phys_baseaddr) { 1017b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_translate_address failed\n"); 101867fc3ff9SGagandeep Singh goto err; 1019b1bc1afaSGagandeep Singh } 102067fc3ff9SGagandeep Singh 10215253fe37SGagandeep Singh g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr); 102267fc3ff9SGagandeep Singh g_pfe->ddr_size = ddr_size; 102367fc3ff9SGagandeep Singh g_pfe->cbus_size = cbus_size; 102467fc3ff9SGagandeep Singh 102567fc3ff9SGagandeep Singh fd = open("/dev/mem", O_RDWR); 102667fc3ff9SGagandeep Singh g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, 102767fc3ff9SGagandeep Singh MAP_SHARED, fd, cbus_addr); 102867fc3ff9SGagandeep Singh close(fd); 102967fc3ff9SGagandeep Singh if (g_pfe->cbus_baseaddr == MAP_FAILED) { 1030b1bc1afaSGagandeep Singh PFE_PMD_ERR("Can not map cbus base"); 103167fc3ff9SGagandeep Singh rc = -EINVAL; 103267fc3ff9SGagandeep Singh goto err; 103367fc3ff9SGagandeep Singh } 103467fc3ff9SGagandeep Singh 103567fc3ff9SGagandeep Singh /* Read interface count */ 103667fc3ff9SGagandeep Singh prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); 103767fc3ff9SGagandeep Singh if (!prop) { 1038b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to read number of interfaces"); 103967fc3ff9SGagandeep Singh rc = -ENXIO; 104067fc3ff9SGagandeep Singh goto err_prop; 104167fc3ff9SGagandeep Singh } 104267fc3ff9SGagandeep Singh 104367fc3ff9SGagandeep Singh interface_count = rte_be_to_cpu_32((unsigned int)*prop); 104467fc3ff9SGagandeep Singh if (interface_count <= 0) { 1045b1bc1afaSGagandeep Singh PFE_PMD_ERR("No ethernet interface count : %d", 1046b1bc1afaSGagandeep Singh interface_count); 104767fc3ff9SGagandeep Singh rc = -ENXIO; 104867fc3ff9SGagandeep Singh goto err_prop; 104967fc3ff9SGagandeep Singh } 1050b1bc1afaSGagandeep Singh PFE_PMD_INFO("num interfaces = %d ", interface_count); 1051b1bc1afaSGagandeep Singh 105267fc3ff9SGagandeep Singh g_pfe->max_intf = interface_count; 10535253fe37SGagandeep Singh g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; 10545253fe37SGagandeep Singh 10555253fe37SGagandeep Singh for (ii = 0; ii < interface_count; ii++) { 10565253fe37SGagandeep Singh pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count, 10575253fe37SGagandeep Singh &g_pfe->platform_data); 10585253fe37SGagandeep Singh } 10595253fe37SGagandeep Singh 10605253fe37SGagandeep Singh pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr, 10615253fe37SGagandeep Singh g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size); 10625253fe37SGagandeep Singh 10635253fe37SGagandeep Singh PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION)); 10645253fe37SGagandeep Singh PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION)); 10655253fe37SGagandeep Singh 10665253fe37SGagandeep Singh PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION)); 10675253fe37SGagandeep Singh PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION)); 10685253fe37SGagandeep Singh 10695253fe37SGagandeep Singh PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION)); 10705253fe37SGagandeep Singh PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION)); 10715253fe37SGagandeep Singh PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION)); 10725253fe37SGagandeep Singh 10735253fe37SGagandeep Singh PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION)); 10745253fe37SGagandeep Singh PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION)); 10755253fe37SGagandeep Singh 10765253fe37SGagandeep Singh cbus_emac_base[0] = EMAC1_BASE_ADDR; 10775253fe37SGagandeep Singh cbus_emac_base[1] = EMAC2_BASE_ADDR; 10785253fe37SGagandeep Singh 10795253fe37SGagandeep Singh cbus_gpi_base[0] = EGPI1_BASE_ADDR; 10805253fe37SGagandeep Singh cbus_gpi_base[1] = EGPI2_BASE_ADDR; 10815253fe37SGagandeep Singh 10825253fe37SGagandeep Singh rc = pfe_hif_lib_init(g_pfe); 10835253fe37SGagandeep Singh if (rc < 0) 10845253fe37SGagandeep Singh goto err_hif_lib; 10855253fe37SGagandeep Singh 10865253fe37SGagandeep Singh rc = pfe_hif_init(g_pfe); 10875253fe37SGagandeep Singh if (rc < 0) 10885253fe37SGagandeep Singh goto err_hif; 108967fc3ff9SGagandeep Singh pfe_soc_version_get(); 109067fc3ff9SGagandeep Singh eth_init: 109167fc3ff9SGagandeep Singh if (init_params.gem_id < 0) 109267fc3ff9SGagandeep Singh gem_id = g_pfe->nb_devs; 109367fc3ff9SGagandeep Singh else 109467fc3ff9SGagandeep Singh gem_id = init_params.gem_id; 109567fc3ff9SGagandeep Singh 1096b8907ccfSStephen Hemminger PFE_PMD_LOG(INFO, "Init pmd_pfe for %s gem-id %d(given =%d)", 109767fc3ff9SGagandeep Singh name, gem_id, init_params.gem_id); 109867fc3ff9SGagandeep Singh 109967fc3ff9SGagandeep Singh rc = pfe_eth_init(vdev, g_pfe, gem_id); 110067fc3ff9SGagandeep Singh if (rc < 0) 110167fc3ff9SGagandeep Singh goto err_eth; 110267fc3ff9SGagandeep Singh else 110367fc3ff9SGagandeep Singh g_pfe->nb_devs++; 110467fc3ff9SGagandeep Singh 110567fc3ff9SGagandeep Singh return 0; 110667fc3ff9SGagandeep Singh 110767fc3ff9SGagandeep Singh err_eth: 11085253fe37SGagandeep Singh pfe_hif_exit(g_pfe); 11095253fe37SGagandeep Singh 11105253fe37SGagandeep Singh err_hif: 11115253fe37SGagandeep Singh pfe_hif_lib_exit(g_pfe); 11125253fe37SGagandeep Singh 11135253fe37SGagandeep Singh err_hif_lib: 111467fc3ff9SGagandeep Singh err_prop: 111567fc3ff9SGagandeep Singh munmap(g_pfe->cbus_baseaddr, cbus_size); 111667fc3ff9SGagandeep Singh err: 111767fc3ff9SGagandeep Singh rte_free(g_pfe); 111867fc3ff9SGagandeep Singh return rc; 111967fc3ff9SGagandeep Singh } 112067fc3ff9SGagandeep Singh 112167fc3ff9SGagandeep Singh static int 112267fc3ff9SGagandeep Singh pmd_pfe_remove(struct rte_vdev_device *vdev) 112367fc3ff9SGagandeep Singh { 112467fc3ff9SGagandeep Singh const char *name; 112567fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 112657803c5eSSachin Saxena int ret = 0; 112767fc3ff9SGagandeep Singh 112867fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 112967fc3ff9SGagandeep Singh if (name == NULL) 113067fc3ff9SGagandeep Singh return -EINVAL; 113167fc3ff9SGagandeep Singh 1132b1bc1afaSGagandeep Singh PFE_PMD_INFO("Closing eventdev sw device %s", name); 1133b1bc1afaSGagandeep Singh 113467fc3ff9SGagandeep Singh if (!g_pfe) 113567fc3ff9SGagandeep Singh return 0; 113667fc3ff9SGagandeep Singh 113767fc3ff9SGagandeep Singh eth_dev = rte_eth_dev_allocated(name); 113857803c5eSSachin Saxena if (eth_dev) { 113957803c5eSSachin Saxena pfe_eth_close(eth_dev); 114057803c5eSSachin Saxena ret = rte_eth_dev_release_port(eth_dev); 11415253fe37SGagandeep Singh } 114257803c5eSSachin Saxena 114357803c5eSSachin Saxena return ret; 114467fc3ff9SGagandeep Singh } 114567fc3ff9SGagandeep Singh 114667fc3ff9SGagandeep Singh static 114767fc3ff9SGagandeep Singh struct rte_vdev_driver pmd_pfe_drv = { 114867fc3ff9SGagandeep Singh .probe = pmd_pfe_probe, 114967fc3ff9SGagandeep Singh .remove = pmd_pfe_remove, 115067fc3ff9SGagandeep Singh }; 115167fc3ff9SGagandeep Singh 115267fc3ff9SGagandeep Singh RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); 115367fc3ff9SGagandeep Singh RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> "); 1154eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(pfe_logtype_pmd, NOTICE); 1155