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> 94851ef2bSDavid Marchand #include <bus_vdev_driver.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 = 25295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | 26295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_UDP_CKSUM | 27295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_TCP_CKSUM; 28592041a0SGagandeep Singh 29592041a0SGagandeep Singh /* Supported Tx offloads */ 30592041a0SGagandeep Singh static uint64_t dev_tx_offloads_sup = 31295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | 32295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_UDP_CKSUM | 33295968d1SFerruh Yigit RTE_ETH_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) 164*f665790aSDavid Marchand PFE_PMD_ERR("epoll_wait fails with %d", 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 238fe38ad9bSGagandeep Singh static int 239fe38ad9bSGagandeep Singh pfe_eth_open(struct rte_eth_dev *dev) 240fe38ad9bSGagandeep Singh { 241fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 242fe38ad9bSGagandeep Singh struct hif_client_s *client; 243fe38ad9bSGagandeep Singh struct hif_shm *hif_shm; 2446e7d7f57SJie Hai uint16_t i; 245fe38ad9bSGagandeep Singh int rc; 246fe38ad9bSGagandeep Singh 247fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 248fe38ad9bSGagandeep Singh client = &priv->client; 249fe38ad9bSGagandeep Singh 250fe38ad9bSGagandeep Singh if (client->pfe) { 251fe38ad9bSGagandeep Singh hif_shm = client->pfe->hif.shm; 252fe38ad9bSGagandeep Singh /* TODO please remove the below code of if block, once we add 253fe38ad9bSGagandeep Singh * the proper cleanup in eth_close 254fe38ad9bSGagandeep Singh */ 255fe38ad9bSGagandeep Singh if (!test_bit(PFE_CL_GEM0 + priv->id, 256fe38ad9bSGagandeep Singh &hif_shm->g_client_status[0])) { 257fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 258fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 259fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 260fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 261fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 262fe38ad9bSGagandeep Singh client->priv = priv; 263fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 264fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 265fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 266fe38ad9bSGagandeep Singh 267fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 268fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 269fe38ad9bSGagandeep Singh 270fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 271fe38ad9bSGagandeep Singh if (rc) { 272fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d)" 273fe38ad9bSGagandeep Singh " failed", client->id); 274fe38ad9bSGagandeep Singh goto err0; 275fe38ad9bSGagandeep Singh } 27636220514SGagandeep Singh } else { 27736220514SGagandeep Singh /* Freeing the packets if already exists */ 27836220514SGagandeep Singh int ret = 0; 27936220514SGagandeep Singh struct rte_mbuf *rx_pkts[32]; 28036220514SGagandeep Singh /* TODO multiqueue support */ 28136220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 28236220514SGagandeep Singh hif_shm->pool, rx_pkts, 32); 28336220514SGagandeep Singh while (ret) { 28436220514SGagandeep Singh int i; 28536220514SGagandeep Singh for (i = 0; i < ret; i++) 28636220514SGagandeep Singh rte_pktmbuf_free(rx_pkts[i]); 28736220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 28836220514SGagandeep Singh hif_shm->pool, 28936220514SGagandeep Singh rx_pkts, 32); 29036220514SGagandeep Singh } 291fe38ad9bSGagandeep Singh } 292fe38ad9bSGagandeep Singh } else { 293fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 294fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 295fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 296fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 297fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 298fe38ad9bSGagandeep Singh client->priv = priv; 299fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 300fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 301fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 302fe38ad9bSGagandeep Singh 303fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 304fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 305fe38ad9bSGagandeep Singh 306fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 307fe38ad9bSGagandeep Singh if (rc) { 308fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d) failed", 309fe38ad9bSGagandeep Singh client->id); 310fe38ad9bSGagandeep Singh goto err0; 311fe38ad9bSGagandeep Singh } 312fe38ad9bSGagandeep Singh } 313fe38ad9bSGagandeep Singh rc = pfe_eth_start(priv); 31436220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts; 31536220514SGagandeep Singh dev->tx_pkt_burst = &pfe_xmit_pkts; 31636220514SGagandeep Singh /* If no prefetch is configured. */ 31736220514SGagandeep Singh if (getenv("PFE_INTR_SUPPORT")) { 31836220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; 31936220514SGagandeep Singh PFE_PMD_INFO("PFE INTERRUPT Mode enabled"); 32036220514SGagandeep Singh } 32136220514SGagandeep Singh 3226e7d7f57SJie Hai for (i = 0; i < dev->data->nb_rx_queues; i++) 3236e7d7f57SJie Hai dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 3246e7d7f57SJie Hai for (i = 0; i < dev->data->nb_tx_queues; i++) 3256e7d7f57SJie Hai dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 326fe38ad9bSGagandeep Singh 327fe38ad9bSGagandeep Singh err0: 328fe38ad9bSGagandeep Singh return rc; 329fe38ad9bSGagandeep Singh } 330fe38ad9bSGagandeep Singh 33167fc3ff9SGagandeep Singh static int 33267fc3ff9SGagandeep Singh pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) 33367fc3ff9SGagandeep Singh { 33467fc3ff9SGagandeep Singh int pfe_cdev_fd; 33567fc3ff9SGagandeep Singh 33667fc3ff9SGagandeep Singh if (priv == NULL) 33767fc3ff9SGagandeep Singh return -1; 33867fc3ff9SGagandeep Singh 33967fc3ff9SGagandeep Singh pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); 34067fc3ff9SGagandeep Singh if (pfe_cdev_fd < 0) { 341*f665790aSDavid Marchand PFE_PMD_WARN("Unable to open PFE device file (%s).", 342b1bc1afaSGagandeep Singh PFE_CDEV_PATH); 343*f665790aSDavid Marchand PFE_PMD_WARN("Link status update will not be available."); 34467fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 34567fc3ff9SGagandeep Singh return -1; 34667fc3ff9SGagandeep Singh } 34767fc3ff9SGagandeep Singh 34867fc3ff9SGagandeep Singh priv->link_fd = pfe_cdev_fd; 34967fc3ff9SGagandeep Singh 35067fc3ff9SGagandeep Singh return 0; 35167fc3ff9SGagandeep Singh } 35267fc3ff9SGagandeep Singh 35367fc3ff9SGagandeep Singh static void 35467fc3ff9SGagandeep Singh pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) 35567fc3ff9SGagandeep Singh { 35667fc3ff9SGagandeep Singh if (priv == NULL) 35767fc3ff9SGagandeep Singh return; 35867fc3ff9SGagandeep Singh 35967fc3ff9SGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 36067fc3ff9SGagandeep Singh close(priv->link_fd); 36167fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 36267fc3ff9SGagandeep Singh } 36367fc3ff9SGagandeep Singh } 36467fc3ff9SGagandeep Singh 36562024eb8SIvan Ilchenko static int 366fe38ad9bSGagandeep Singh pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) 367fe38ad9bSGagandeep Singh { 368fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 3696e7d7f57SJie Hai uint16_t i; 370fe38ad9bSGagandeep Singh 371b8f5d2aeSThomas Monjalon dev->data->dev_started = 0; 372b8f5d2aeSThomas Monjalon 373fe38ad9bSGagandeep Singh gemac_disable(priv->EMAC_baseaddr); 374fe38ad9bSGagandeep Singh gpi_disable(priv->GPI_baseaddr); 37536220514SGagandeep Singh 376a41f593fSFerruh Yigit dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; 377a41f593fSFerruh Yigit dev->tx_pkt_burst = rte_eth_pkt_burst_dummy; 37862024eb8SIvan Ilchenko 3796e7d7f57SJie Hai for (i = 0; i < dev->data->nb_rx_queues; i++) 3806e7d7f57SJie Hai dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 3816e7d7f57SJie Hai for (i = 0; i < dev->data->nb_tx_queues; i++) 3826e7d7f57SJie Hai dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 3836e7d7f57SJie Hai 38462024eb8SIvan Ilchenko return 0; 385fe38ad9bSGagandeep Singh } 386fe38ad9bSGagandeep Singh 387b142387bSThomas Monjalon static int 388fe38ad9bSGagandeep Singh pfe_eth_close(struct rte_eth_dev *dev) 389fe38ad9bSGagandeep Singh { 39062024eb8SIvan Ilchenko int ret; 39157803c5eSSachin Saxena PMD_INIT_FUNC_TRACE(); 39257803c5eSSachin Saxena 393fe38ad9bSGagandeep Singh if (!dev) 394b142387bSThomas Monjalon return -1; 395fe38ad9bSGagandeep Singh 396fe38ad9bSGagandeep Singh if (!g_pfe) 397b142387bSThomas Monjalon return -1; 398fe38ad9bSGagandeep Singh 39930410493SThomas Monjalon if (rte_eal_process_type() != RTE_PROC_PRIMARY) 40030410493SThomas Monjalon return 0; 40130410493SThomas Monjalon 40262024eb8SIvan Ilchenko ret = pfe_eth_stop(dev); 40357803c5eSSachin Saxena /* Close the device file for link status */ 40457803c5eSSachin Saxena pfe_eth_close_cdev(dev->data->dev_private); 40557803c5eSSachin Saxena 40657803c5eSSachin Saxena munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size); 40757803c5eSSachin Saxena g_pfe->nb_devs--; 408fe38ad9bSGagandeep Singh 409fe38ad9bSGagandeep Singh if (g_pfe->nb_devs == 0) { 410fe38ad9bSGagandeep Singh pfe_hif_exit(g_pfe); 411fe38ad9bSGagandeep Singh pfe_hif_lib_exit(g_pfe); 412fe38ad9bSGagandeep Singh rte_free(g_pfe); 413fe38ad9bSGagandeep Singh g_pfe = NULL; 414fe38ad9bSGagandeep Singh } 415b142387bSThomas Monjalon 41662024eb8SIvan Ilchenko return ret; 417fe38ad9bSGagandeep Singh } 418fe38ad9bSGagandeep Singh 419fe38ad9bSGagandeep Singh static int 420fe38ad9bSGagandeep Singh pfe_eth_configure(struct rte_eth_dev *dev __rte_unused) 421fe38ad9bSGagandeep Singh { 422fe38ad9bSGagandeep Singh return 0; 423fe38ad9bSGagandeep Singh } 424fe38ad9bSGagandeep Singh 425fe38ad9bSGagandeep Singh static int 426fe38ad9bSGagandeep Singh pfe_eth_info(struct rte_eth_dev *dev, 427fe38ad9bSGagandeep Singh struct rte_eth_dev_info *dev_info) 428fe38ad9bSGagandeep Singh { 429fe38ad9bSGagandeep Singh dev_info->max_mac_addrs = PFE_MAX_MACS; 430fe38ad9bSGagandeep Singh dev_info->max_rx_queues = dev->data->nb_rx_queues; 431fe38ad9bSGagandeep Singh dev_info->max_tx_queues = dev->data->nb_tx_queues; 432fe38ad9bSGagandeep Singh dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE; 433320ae324SGagandeep Singh dev_info->min_mtu = RTE_ETHER_MIN_MTU; 434592041a0SGagandeep Singh dev_info->rx_offload_capa = dev_rx_offloads_sup; 435592041a0SGagandeep Singh dev_info->tx_offload_capa = dev_tx_offloads_sup; 436320ae324SGagandeep Singh if (pfe_svr == SVR_LS1012A_REV1) { 437fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; 438320ae324SGagandeep Singh dev_info->max_mtu = MAX_MTU_ON_REV1; 439320ae324SGagandeep Singh } else { 440fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE; 441320ae324SGagandeep Singh dev_info->max_mtu = JUMBO_FRAME_SIZE - PFE_ETH_OVERHEAD; 442320ae324SGagandeep Singh } 443fe38ad9bSGagandeep Singh 444fe38ad9bSGagandeep Singh return 0; 445fe38ad9bSGagandeep Singh } 446fe38ad9bSGagandeep Singh 447592041a0SGagandeep Singh /* Only first mb_pool given on first call of this API will be used 448592041a0SGagandeep Singh * in whole system, also nb_rx_desc and rx_conf are unused params 449592041a0SGagandeep Singh */ 450592041a0SGagandeep Singh static int 451592041a0SGagandeep Singh pfe_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, 452592041a0SGagandeep Singh __rte_unused uint16_t nb_rx_desc, 453592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 454592041a0SGagandeep Singh __rte_unused const struct rte_eth_rxconf *rx_conf, 455592041a0SGagandeep Singh struct rte_mempool *mb_pool) 456592041a0SGagandeep Singh { 457592041a0SGagandeep Singh int rc = 0; 458592041a0SGagandeep Singh struct pfe *pfe; 459592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 460592041a0SGagandeep Singh 461592041a0SGagandeep Singh pfe = priv->pfe; 462592041a0SGagandeep Singh 463592041a0SGagandeep Singh if (queue_idx >= EMAC_RXQ_CNT) { 464592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 465592041a0SGagandeep Singh queue_idx, EMAC_RXQ_CNT); 466592041a0SGagandeep Singh return -1; 467592041a0SGagandeep Singh } 468592041a0SGagandeep Singh 469592041a0SGagandeep Singh if (!pfe->hif.setuped) { 470592041a0SGagandeep Singh rc = pfe_hif_shm_init(pfe->hif.shm, mb_pool); 471592041a0SGagandeep Singh if (rc) { 472592041a0SGagandeep Singh PFE_PMD_ERR("Could not allocate buffer descriptors"); 473592041a0SGagandeep Singh return -1; 474592041a0SGagandeep Singh } 475592041a0SGagandeep Singh 476592041a0SGagandeep Singh pfe->hif.shm->pool = mb_pool; 477592041a0SGagandeep Singh if (pfe_hif_init_buffers(&pfe->hif)) { 478592041a0SGagandeep Singh PFE_PMD_ERR("Could not initialize buffer descriptors"); 479592041a0SGagandeep Singh return -1; 480592041a0SGagandeep Singh } 481592041a0SGagandeep Singh hif_init(); 482592041a0SGagandeep Singh hif_rx_enable(); 483592041a0SGagandeep Singh hif_tx_enable(); 484592041a0SGagandeep Singh pfe->hif.setuped = 1; 485592041a0SGagandeep Singh } 486592041a0SGagandeep Singh dev->data->rx_queues[queue_idx] = &priv->client.rx_q[queue_idx]; 487592041a0SGagandeep Singh priv->client.rx_q[queue_idx].queue_id = queue_idx; 488592041a0SGagandeep Singh 489592041a0SGagandeep Singh return 0; 490592041a0SGagandeep Singh } 491592041a0SGagandeep Singh 492592041a0SGagandeep Singh static int 493592041a0SGagandeep Singh pfe_tx_queue_setup(struct rte_eth_dev *dev, 494592041a0SGagandeep Singh uint16_t queue_idx, 495592041a0SGagandeep Singh __rte_unused uint16_t nb_desc, 496592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 497592041a0SGagandeep Singh __rte_unused const struct rte_eth_txconf *tx_conf) 498592041a0SGagandeep Singh { 499592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 500592041a0SGagandeep Singh 501592041a0SGagandeep Singh if (queue_idx >= emac_txq_cnt) { 502592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 503592041a0SGagandeep Singh queue_idx, emac_txq_cnt); 504592041a0SGagandeep Singh return -1; 505592041a0SGagandeep Singh } 506592041a0SGagandeep Singh dev->data->tx_queues[queue_idx] = &priv->client.tx_q[queue_idx]; 507592041a0SGagandeep Singh priv->client.tx_q[queue_idx].queue_id = queue_idx; 508592041a0SGagandeep Singh return 0; 509592041a0SGagandeep Singh } 510592041a0SGagandeep Singh 511659b494dSGagandeep Singh static const uint32_t * 512ba6a168aSSivaramakrishnan Venkat pfe_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements) 513659b494dSGagandeep Singh { 514659b494dSGagandeep Singh static const uint32_t ptypes[] = { 515659b494dSGagandeep Singh /*todo -= add more types */ 516659b494dSGagandeep Singh RTE_PTYPE_L2_ETHER, 517659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4, 518659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4_EXT, 519659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6, 520659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6_EXT, 521659b494dSGagandeep Singh RTE_PTYPE_L4_TCP, 522659b494dSGagandeep Singh RTE_PTYPE_L4_UDP, 5232e3ddb56SSivaramakrishnan Venkat RTE_PTYPE_L4_SCTP, 524659b494dSGagandeep Singh }; 525659b494dSGagandeep Singh 526659b494dSGagandeep Singh if (dev->rx_pkt_burst == pfe_recv_pkts || 527ba6a168aSSivaramakrishnan Venkat dev->rx_pkt_burst == pfe_recv_pkts_on_intr) { 528ba6a168aSSivaramakrishnan Venkat *no_of_elements = RTE_DIM(ptypes); 529659b494dSGagandeep Singh return ptypes; 530ba6a168aSSivaramakrishnan Venkat } 531659b494dSGagandeep Singh return NULL; 532659b494dSGagandeep Singh } 533659b494dSGagandeep Singh 534acd4818eSGagandeep Singh static inline int 535acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev, 536acd4818eSGagandeep Singh struct rte_eth_link *link) 537acd4818eSGagandeep Singh { 538acd4818eSGagandeep Singh struct rte_eth_link *dst = link; 539acd4818eSGagandeep Singh struct rte_eth_link *src = &dev->data->dev_link; 540acd4818eSGagandeep Singh 541acd4818eSGagandeep Singh if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 542acd4818eSGagandeep Singh *(uint64_t *)src) == 0) 543acd4818eSGagandeep Singh return -1; 544acd4818eSGagandeep Singh 545acd4818eSGagandeep Singh return 0; 546acd4818eSGagandeep Singh } 547acd4818eSGagandeep Singh 548acd4818eSGagandeep Singh static inline int 549acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev, 550acd4818eSGagandeep Singh struct rte_eth_link *link) 551acd4818eSGagandeep Singh { 552acd4818eSGagandeep Singh struct rte_eth_link *dst = &dev->data->dev_link; 553acd4818eSGagandeep Singh struct rte_eth_link *src = link; 554acd4818eSGagandeep Singh 555acd4818eSGagandeep Singh if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 556acd4818eSGagandeep Singh *(uint64_t *)src) == 0) 557acd4818eSGagandeep Singh return -1; 558acd4818eSGagandeep Singh 559acd4818eSGagandeep Singh return 0; 560acd4818eSGagandeep Singh } 561acd4818eSGagandeep Singh 562acd4818eSGagandeep Singh static int 563acd4818eSGagandeep Singh pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) 564acd4818eSGagandeep Singh { 565acd4818eSGagandeep Singh int ret, ioctl_cmd = 0; 566acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 567acd4818eSGagandeep Singh struct rte_eth_link link, old; 568acd4818eSGagandeep Singh unsigned int lstatus = 1; 569acd4818eSGagandeep Singh 570acd4818eSGagandeep Singh memset(&old, 0, sizeof(old)); 571acd4818eSGagandeep Singh memset(&link, 0, sizeof(struct rte_eth_link)); 572acd4818eSGagandeep Singh 573acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(dev, &old); 574acd4818eSGagandeep Singh 575acd4818eSGagandeep Singh /* Read from PFE CDEV, status of link, if file was successfully 576acd4818eSGagandeep Singh * opened. 577acd4818eSGagandeep Singh */ 578acd4818eSGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 579acd4818eSGagandeep Singh if (priv->id == 0) 580acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH0_STATE_GET; 581acd4818eSGagandeep Singh if (priv->id == 1) 582acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH1_STATE_GET; 583acd4818eSGagandeep Singh 584acd4818eSGagandeep Singh ret = ioctl(priv->link_fd, ioctl_cmd, &lstatus); 585acd4818eSGagandeep Singh if (ret != 0) { 586*f665790aSDavid Marchand PFE_PMD_ERR("Unable to fetch link status (ioctl)"); 587a7380933SApeksha Gupta return -1; 588acd4818eSGagandeep Singh } 589*f665790aSDavid Marchand PFE_PMD_DEBUG("Fetched link state (%d) for dev %d.", 590acd4818eSGagandeep Singh lstatus, priv->id); 591acd4818eSGagandeep Singh } 592acd4818eSGagandeep Singh 593acd4818eSGagandeep Singh if (old.link_status == lstatus) { 594acd4818eSGagandeep Singh /* no change in status */ 595*f665790aSDavid Marchand PFE_PMD_DEBUG("No change in link status; Not updating."); 596acd4818eSGagandeep Singh return -1; 597acd4818eSGagandeep Singh } 598acd4818eSGagandeep Singh 599acd4818eSGagandeep Singh link.link_status = lstatus; 600295968d1SFerruh Yigit link.link_speed = RTE_ETH_LINK_SPEED_1G; 601295968d1SFerruh Yigit link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX; 602295968d1SFerruh Yigit link.link_autoneg = RTE_ETH_LINK_AUTONEG; 603acd4818eSGagandeep Singh 604acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(dev, &link); 605acd4818eSGagandeep Singh 606*f665790aSDavid Marchand PFE_PMD_INFO("Port (%d) link is %s", dev->data->port_id, 607acd4818eSGagandeep Singh link.link_status ? "up" : "down"); 608acd4818eSGagandeep Singh 609acd4818eSGagandeep Singh return 0; 610acd4818eSGagandeep Singh } 611acd4818eSGagandeep Singh 612659b494dSGagandeep Singh static int 613ff64beabSGagandeep Singh pfe_promiscuous_enable(struct rte_eth_dev *dev) 614ff64beabSGagandeep Singh { 615ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 616ff64beabSGagandeep Singh 617ff64beabSGagandeep Singh priv->promisc = 1; 618ff64beabSGagandeep Singh dev->data->promiscuous = 1; 619ff64beabSGagandeep Singh gemac_enable_copy_all(priv->EMAC_baseaddr); 620ff64beabSGagandeep Singh 621ff64beabSGagandeep Singh return 0; 622ff64beabSGagandeep Singh } 623ff64beabSGagandeep Singh 624ff64beabSGagandeep Singh static int 625ff64beabSGagandeep Singh pfe_promiscuous_disable(struct rte_eth_dev *dev) 626ff64beabSGagandeep Singh { 627ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 628ff64beabSGagandeep Singh 629ff64beabSGagandeep Singh priv->promisc = 0; 630ff64beabSGagandeep Singh dev->data->promiscuous = 0; 631ff64beabSGagandeep Singh gemac_disable_copy_all(priv->EMAC_baseaddr); 632ff64beabSGagandeep Singh 633ff64beabSGagandeep Singh return 0; 634ff64beabSGagandeep Singh } 635ff64beabSGagandeep Singh 636ff64beabSGagandeep Singh static int 637ff64beabSGagandeep Singh pfe_allmulticast_enable(struct rte_eth_dev *dev) 638ff64beabSGagandeep Singh { 639ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 640ff64beabSGagandeep Singh struct pfe_mac_addr hash_addr; /* hash register structure */ 641ff64beabSGagandeep Singh 642ff64beabSGagandeep Singh /* Set the hash to rx all multicast frames */ 643ff64beabSGagandeep Singh hash_addr.bottom = 0xFFFFFFFF; 644ff64beabSGagandeep Singh hash_addr.top = 0xFFFFFFFF; 645ff64beabSGagandeep Singh gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); 646ff64beabSGagandeep Singh dev->data->all_multicast = 1; 647ff64beabSGagandeep Singh 648ff64beabSGagandeep Singh return 0; 649ff64beabSGagandeep Singh } 650ff64beabSGagandeep Singh 651ff64beabSGagandeep Singh static int 652acd4818eSGagandeep Singh pfe_link_down(struct rte_eth_dev *dev) 653acd4818eSGagandeep Singh { 65462024eb8SIvan Ilchenko return pfe_eth_stop(dev); 655acd4818eSGagandeep Singh } 656acd4818eSGagandeep Singh 657acd4818eSGagandeep Singh static int 658acd4818eSGagandeep Singh pfe_link_up(struct rte_eth_dev *dev) 659acd4818eSGagandeep Singh { 660acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 661acd4818eSGagandeep Singh 662acd4818eSGagandeep Singh pfe_eth_start(priv); 663acd4818eSGagandeep Singh return 0; 664acd4818eSGagandeep Singh } 665acd4818eSGagandeep Singh 666acd4818eSGagandeep Singh static int 667320ae324SGagandeep Singh pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 668320ae324SGagandeep Singh { 669320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 670320ae324SGagandeep Singh uint16_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 671320ae324SGagandeep Singh 672320ae324SGagandeep Singh /*TODO Support VLAN*/ 6731bb4a528SFerruh Yigit return gemac_set_rx(priv->EMAC_baseaddr, frame_size); 674320ae324SGagandeep Singh } 675320ae324SGagandeep Singh 676320ae324SGagandeep Singh /* pfe_eth_enet_addr_byte_mac 677320ae324SGagandeep Singh */ 678320ae324SGagandeep Singh static int 679320ae324SGagandeep Singh pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, 680320ae324SGagandeep Singh struct pfe_mac_addr *enet_addr) 681320ae324SGagandeep Singh { 682320ae324SGagandeep Singh if (!enet_byte_addr || !enet_addr) { 683320ae324SGagandeep Singh return -1; 684320ae324SGagandeep Singh 685320ae324SGagandeep Singh } else { 686320ae324SGagandeep Singh enet_addr->bottom = enet_byte_addr[0] | 687320ae324SGagandeep Singh (enet_byte_addr[1] << 8) | 688320ae324SGagandeep Singh (enet_byte_addr[2] << 16) | 689320ae324SGagandeep Singh (enet_byte_addr[3] << 24); 690320ae324SGagandeep Singh enet_addr->top = enet_byte_addr[4] | 691320ae324SGagandeep Singh (enet_byte_addr[5] << 8); 692320ae324SGagandeep Singh return 0; 693320ae324SGagandeep Singh } 694320ae324SGagandeep Singh } 695320ae324SGagandeep Singh 696320ae324SGagandeep Singh static int 697320ae324SGagandeep Singh pfe_dev_set_mac_addr(struct rte_eth_dev *dev, 698320ae324SGagandeep Singh struct rte_ether_addr *addr) 699320ae324SGagandeep Singh { 700320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 701320ae324SGagandeep Singh struct pfe_mac_addr spec_addr; 702320ae324SGagandeep Singh int ret; 703320ae324SGagandeep Singh 704320ae324SGagandeep Singh ret = pfe_eth_enet_addr_byte_mac(addr->addr_bytes, &spec_addr); 705320ae324SGagandeep Singh if (ret) 706320ae324SGagandeep Singh return ret; 707320ae324SGagandeep Singh 708320ae324SGagandeep Singh gemac_set_laddrN(priv->EMAC_baseaddr, 709320ae324SGagandeep Singh (struct pfe_mac_addr *)&spec_addr, 1); 710320ae324SGagandeep Singh rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 711320ae324SGagandeep Singh return 0; 712320ae324SGagandeep Singh } 713320ae324SGagandeep Singh 714320ae324SGagandeep Singh static int 715659b494dSGagandeep Singh pfe_stats_get(struct rte_eth_dev *dev, 716659b494dSGagandeep Singh struct rte_eth_stats *stats) 717659b494dSGagandeep Singh { 718659b494dSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 719659b494dSGagandeep Singh struct rte_eth_stats *eth_stats = &priv->stats; 720659b494dSGagandeep Singh 721659b494dSGagandeep Singh if (stats == NULL) 722659b494dSGagandeep Singh return -1; 723659b494dSGagandeep Singh 724659b494dSGagandeep Singh memset(stats, 0, sizeof(struct rte_eth_stats)); 725659b494dSGagandeep Singh 726659b494dSGagandeep Singh stats->ipackets = eth_stats->ipackets; 727659b494dSGagandeep Singh stats->ibytes = eth_stats->ibytes; 728659b494dSGagandeep Singh stats->opackets = eth_stats->opackets; 729659b494dSGagandeep Singh stats->obytes = eth_stats->obytes; 730659b494dSGagandeep Singh 731659b494dSGagandeep Singh return 0; 732659b494dSGagandeep Singh } 733659b494dSGagandeep Singh 734fe38ad9bSGagandeep Singh static const struct eth_dev_ops ops = { 735fe38ad9bSGagandeep Singh .dev_start = pfe_eth_open, 736fe38ad9bSGagandeep Singh .dev_stop = pfe_eth_stop, 737fe38ad9bSGagandeep Singh .dev_close = pfe_eth_close, 738fe38ad9bSGagandeep Singh .dev_configure = pfe_eth_configure, 739fe38ad9bSGagandeep Singh .dev_infos_get = pfe_eth_info, 740592041a0SGagandeep Singh .rx_queue_setup = pfe_rx_queue_setup, 741592041a0SGagandeep Singh .tx_queue_setup = pfe_tx_queue_setup, 742659b494dSGagandeep Singh .dev_supported_ptypes_get = pfe_supported_ptypes_get, 743acd4818eSGagandeep Singh .link_update = pfe_eth_link_update, 744ff64beabSGagandeep Singh .promiscuous_enable = pfe_promiscuous_enable, 745ff64beabSGagandeep Singh .promiscuous_disable = pfe_promiscuous_disable, 746ff64beabSGagandeep Singh .allmulticast_enable = pfe_allmulticast_enable, 747acd4818eSGagandeep Singh .dev_set_link_down = pfe_link_down, 748acd4818eSGagandeep Singh .dev_set_link_up = pfe_link_up, 749320ae324SGagandeep Singh .mtu_set = pfe_mtu_set, 750320ae324SGagandeep Singh .mac_addr_set = pfe_dev_set_mac_addr, 751659b494dSGagandeep Singh .stats_get = pfe_stats_get, 752fe38ad9bSGagandeep Singh }; 753fe38ad9bSGagandeep Singh 75467fc3ff9SGagandeep Singh static int 75567fc3ff9SGagandeep Singh pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) 75667fc3ff9SGagandeep Singh { 75767fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 75867fc3ff9SGagandeep Singh struct pfe_eth_priv_s *priv = NULL; 7595253fe37SGagandeep Singh struct ls1012a_eth_platform_data *einfo; 7605253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pfe_info; 761320ae324SGagandeep Singh struct rte_ether_addr addr; 76267fc3ff9SGagandeep Singh int err; 76367fc3ff9SGagandeep Singh 76467fc3ff9SGagandeep Singh eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); 76567fc3ff9SGagandeep Singh if (eth_dev == NULL) 76667fc3ff9SGagandeep Singh return -ENOMEM; 76767fc3ff9SGagandeep Singh 7687be78d02SJosh Soref /* Extract platform data */ 7695253fe37SGagandeep Singh pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data; 7705253fe37SGagandeep Singh if (!pfe_info) { 7715253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional platform data"); 7725253fe37SGagandeep Singh err = -ENODEV; 7735253fe37SGagandeep Singh goto err0; 7745253fe37SGagandeep Singh } 7755253fe37SGagandeep Singh 7765253fe37SGagandeep Singh einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata; 7775253fe37SGagandeep Singh 7785253fe37SGagandeep Singh /* einfo never be NULL, but no harm in having this check */ 7795253fe37SGagandeep Singh if (!einfo) { 7805253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional gemacs platform data"); 7815253fe37SGagandeep Singh err = -ENODEV; 7825253fe37SGagandeep Singh goto err0; 7835253fe37SGagandeep Singh } 7845253fe37SGagandeep Singh 78567fc3ff9SGagandeep Singh priv = eth_dev->data->dev_private; 78667fc3ff9SGagandeep Singh priv->ndev = eth_dev; 7875253fe37SGagandeep Singh priv->id = einfo[id].gem_id; 78867fc3ff9SGagandeep Singh priv->pfe = pfe; 78967fc3ff9SGagandeep Singh 79067fc3ff9SGagandeep Singh pfe->eth.eth_priv[id] = priv; 79167fc3ff9SGagandeep Singh 7925253fe37SGagandeep Singh /* Set the info in the priv to the current info */ 7935253fe37SGagandeep Singh priv->einfo = &einfo[id]; 7945253fe37SGagandeep Singh priv->EMAC_baseaddr = cbus_emac_base[id]; 7955253fe37SGagandeep Singh priv->PHY_baseaddr = cbus_emac_base[id]; 7965253fe37SGagandeep Singh priv->GPI_baseaddr = cbus_gpi_base[id]; 7975253fe37SGagandeep Singh 79867fc3ff9SGagandeep Singh #define HIF_GEMAC_TMUQ_BASE 6 79967fc3ff9SGagandeep Singh priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); 80067fc3ff9SGagandeep Singh priv->high_tmu_q = priv->low_tmu_q + 1; 80167fc3ff9SGagandeep Singh 80267fc3ff9SGagandeep Singh rte_spinlock_init(&priv->lock); 80367fc3ff9SGagandeep Singh 80467fc3ff9SGagandeep Singh /* Copy the station address into the dev structure, */ 80567fc3ff9SGagandeep Singh eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", 80667fc3ff9SGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS, 0); 80767fc3ff9SGagandeep Singh if (eth_dev->data->mac_addrs == NULL) { 808b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses", 809b1bc1afaSGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS); 81067fc3ff9SGagandeep Singh err = -ENOMEM; 81167fc3ff9SGagandeep Singh goto err0; 81267fc3ff9SGagandeep Singh } 81367fc3ff9SGagandeep Singh 814320ae324SGagandeep Singh memcpy(addr.addr_bytes, priv->einfo->mac_addr, 815320ae324SGagandeep Singh ETH_ALEN); 816320ae324SGagandeep Singh 817320ae324SGagandeep Singh pfe_dev_set_mac_addr(eth_dev, &addr); 818320ae324SGagandeep Singh rte_ether_addr_copy(&addr, ð_dev->data->mac_addrs[0]); 819320ae324SGagandeep Singh 82067fc3ff9SGagandeep Singh eth_dev->data->mtu = 1500; 821fe38ad9bSGagandeep Singh eth_dev->dev_ops = &ops; 82262024eb8SIvan Ilchenko err = pfe_eth_stop(eth_dev); 82362024eb8SIvan Ilchenko if (err != 0) 82462024eb8SIvan Ilchenko goto err0; 8255253fe37SGagandeep Singh pfe_gemac_init(priv); 82667fc3ff9SGagandeep Singh 82767fc3ff9SGagandeep Singh eth_dev->data->nb_rx_queues = 1; 82867fc3ff9SGagandeep Singh eth_dev->data->nb_tx_queues = 1; 82967fc3ff9SGagandeep Singh 83067fc3ff9SGagandeep Singh /* For link status, open the PFE CDEV; Error from this function 83167fc3ff9SGagandeep Singh * is silently ignored; In case of error, the link status will not 83267fc3ff9SGagandeep Singh * be available. 83367fc3ff9SGagandeep Singh */ 83467fc3ff9SGagandeep Singh pfe_eth_open_cdev(priv); 83567fc3ff9SGagandeep Singh rte_eth_dev_probing_finish(eth_dev); 83667fc3ff9SGagandeep Singh 83767fc3ff9SGagandeep Singh return 0; 83867fc3ff9SGagandeep Singh err0: 83967fc3ff9SGagandeep Singh rte_eth_dev_release_port(eth_dev); 84067fc3ff9SGagandeep Singh return err; 84167fc3ff9SGagandeep Singh } 84267fc3ff9SGagandeep Singh 8435253fe37SGagandeep Singh static int 8445253fe37SGagandeep Singh pfe_get_gemac_if_proprties(struct pfe *pfe, 8455253fe37SGagandeep Singh __rte_unused const struct device_node *parent, 8465253fe37SGagandeep Singh unsigned int port, unsigned int if_cnt, 8475253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pdata) 8485253fe37SGagandeep Singh { 8495253fe37SGagandeep Singh const struct device_node *gem = NULL; 8505253fe37SGagandeep Singh size_t size; 8515253fe37SGagandeep Singh unsigned int ii = 0, phy_id = 0; 8525253fe37SGagandeep Singh const u32 *addr; 8535253fe37SGagandeep Singh const void *mac_addr; 8545253fe37SGagandeep Singh 8555253fe37SGagandeep Singh for (ii = 0; ii < if_cnt; ii++) { 8565253fe37SGagandeep Singh gem = of_get_next_child(parent, gem); 8575253fe37SGagandeep Singh if (!gem) 8585253fe37SGagandeep Singh goto err; 8595253fe37SGagandeep Singh addr = of_get_property(gem, "reg", &size); 8605253fe37SGagandeep Singh if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port)) 8615253fe37SGagandeep Singh break; 8625253fe37SGagandeep Singh } 8635253fe37SGagandeep Singh 8645253fe37SGagandeep Singh if (ii >= if_cnt) { 8655253fe37SGagandeep Singh PFE_PMD_ERR("Failed to find interface = %d", if_cnt); 8665253fe37SGagandeep Singh goto err; 8675253fe37SGagandeep Singh } 8685253fe37SGagandeep Singh 8695253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].gem_id = port; 8705253fe37SGagandeep Singh 8715253fe37SGagandeep Singh mac_addr = of_get_mac_address(gem); 8725253fe37SGagandeep Singh 8735253fe37SGagandeep Singh if (mac_addr) { 8745253fe37SGagandeep Singh memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, 8755253fe37SGagandeep Singh ETH_ALEN); 8765253fe37SGagandeep Singh } 8775253fe37SGagandeep Singh 8785253fe37SGagandeep Singh addr = of_get_property(gem, "fsl,mdio-mux-val", &size); 8795253fe37SGagandeep Singh if (!addr) { 8805253fe37SGagandeep Singh PFE_PMD_ERR("Invalid mdio-mux-val...."); 8815253fe37SGagandeep Singh } else { 8825253fe37SGagandeep Singh phy_id = rte_be_to_cpu_32((unsigned int)*addr); 8835253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; 8845253fe37SGagandeep Singh } 8855253fe37SGagandeep Singh if (pdata->ls1012a_eth_pdata[port].phy_id < 32) 8865253fe37SGagandeep Singh pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = 8875253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval; 8885253fe37SGagandeep Singh 8895253fe37SGagandeep Singh return 0; 8905253fe37SGagandeep Singh 8915253fe37SGagandeep Singh err: 8925253fe37SGagandeep Singh return -1; 8935253fe37SGagandeep Singh } 8945253fe37SGagandeep Singh 89567fc3ff9SGagandeep Singh /* Parse integer from integer argument */ 89667fc3ff9SGagandeep Singh static int 89767fc3ff9SGagandeep Singh parse_integer_arg(const char *key __rte_unused, 89867fc3ff9SGagandeep Singh const char *value, void *extra_args) 89967fc3ff9SGagandeep Singh { 90067fc3ff9SGagandeep Singh int i; 90167fc3ff9SGagandeep Singh char *end; 90267fc3ff9SGagandeep Singh errno = 0; 90367fc3ff9SGagandeep Singh 90467fc3ff9SGagandeep Singh i = strtol(value, &end, 10); 905b1bc1afaSGagandeep Singh if (*end != 0 || errno != 0 || i < 0 || i > 1) { 906b1bc1afaSGagandeep Singh PFE_PMD_ERR("Supported Port IDS are 0 and 1"); 90767fc3ff9SGagandeep Singh return -EINVAL; 908b1bc1afaSGagandeep Singh } 90967fc3ff9SGagandeep Singh 91067fc3ff9SGagandeep Singh *((uint32_t *)extra_args) = i; 91167fc3ff9SGagandeep Singh 91267fc3ff9SGagandeep Singh return 0; 91367fc3ff9SGagandeep Singh } 91467fc3ff9SGagandeep Singh 91567fc3ff9SGagandeep Singh static int 91667fc3ff9SGagandeep Singh pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params, 91767fc3ff9SGagandeep Singh struct rte_vdev_device *dev) 91867fc3ff9SGagandeep Singh { 91967fc3ff9SGagandeep Singh struct rte_kvargs *kvlist = NULL; 92067fc3ff9SGagandeep Singh int ret = 0; 92167fc3ff9SGagandeep Singh 92267fc3ff9SGagandeep Singh static const char * const pfe_vdev_valid_params[] = { 92367fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 92467fc3ff9SGagandeep Singh NULL 92567fc3ff9SGagandeep Singh }; 92667fc3ff9SGagandeep Singh 92767fc3ff9SGagandeep Singh const char *input_args = rte_vdev_device_args(dev); 92867fc3ff9SGagandeep Singh 92967fc3ff9SGagandeep Singh if (!input_args) 93067fc3ff9SGagandeep Singh return -1; 93167fc3ff9SGagandeep Singh 93267fc3ff9SGagandeep Singh kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params); 93367fc3ff9SGagandeep Singh if (kvlist == NULL) 93467fc3ff9SGagandeep Singh return -1; 93567fc3ff9SGagandeep Singh 93667fc3ff9SGagandeep Singh ret = rte_kvargs_process(kvlist, 93767fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 93867fc3ff9SGagandeep Singh &parse_integer_arg, 93967fc3ff9SGagandeep Singh ¶ms->gem_id); 94067fc3ff9SGagandeep Singh rte_kvargs_free(kvlist); 94167fc3ff9SGagandeep Singh return ret; 94267fc3ff9SGagandeep Singh } 94367fc3ff9SGagandeep Singh 94467fc3ff9SGagandeep Singh static int 94567fc3ff9SGagandeep Singh pmd_pfe_probe(struct rte_vdev_device *vdev) 94667fc3ff9SGagandeep Singh { 94767fc3ff9SGagandeep Singh const u32 *prop; 94867fc3ff9SGagandeep Singh const struct device_node *np; 94967fc3ff9SGagandeep Singh const char *name; 95067fc3ff9SGagandeep Singh const uint32_t *addr; 95167fc3ff9SGagandeep Singh uint64_t cbus_addr, ddr_size, cbus_size; 95267fc3ff9SGagandeep Singh int rc = -1, fd = -1, gem_id; 9535253fe37SGagandeep Singh unsigned int ii, interface_count = 0; 95467fc3ff9SGagandeep Singh size_t size = 0; 95567fc3ff9SGagandeep Singh struct pfe_vdev_init_params init_params = { 95667fc3ff9SGagandeep Singh .gem_id = -1 95767fc3ff9SGagandeep Singh }; 95867fc3ff9SGagandeep Singh 95967fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 96067fc3ff9SGagandeep Singh rc = pfe_parse_vdev_init_params(&init_params, vdev); 96167fc3ff9SGagandeep Singh if (rc < 0) 96267fc3ff9SGagandeep Singh return -EINVAL; 96367fc3ff9SGagandeep Singh 964b8907ccfSStephen Hemminger PFE_PMD_LOG(INFO, "Initializing pmd_pfe for %s Given gem-id %d", 965b1bc1afaSGagandeep Singh name, init_params.gem_id); 96667fc3ff9SGagandeep Singh 967b1bc1afaSGagandeep Singh if (g_pfe) { 968b1bc1afaSGagandeep Singh if (g_pfe->nb_devs >= g_pfe->max_intf) { 969b1bc1afaSGagandeep Singh PFE_PMD_ERR("PFE %d dev already created Max is %d", 970b1bc1afaSGagandeep Singh g_pfe->nb_devs, g_pfe->max_intf); 971b1bc1afaSGagandeep Singh return -EINVAL; 972b1bc1afaSGagandeep Singh } 97367fc3ff9SGagandeep Singh goto eth_init; 97467fc3ff9SGagandeep Singh } 97567fc3ff9SGagandeep Singh 97667fc3ff9SGagandeep Singh g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE); 97767fc3ff9SGagandeep Singh if (g_pfe == NULL) 97867fc3ff9SGagandeep Singh return -EINVAL; 97967fc3ff9SGagandeep Singh 98067fc3ff9SGagandeep Singh /* Load the device-tree driver */ 98167fc3ff9SGagandeep Singh rc = of_init(); 982b1bc1afaSGagandeep Singh if (rc) { 983b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_init failed with ret: %d", rc); 98467fc3ff9SGagandeep Singh goto err; 985b1bc1afaSGagandeep Singh } 98667fc3ff9SGagandeep Singh 98767fc3ff9SGagandeep Singh np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); 98867fc3ff9SGagandeep Singh if (!np) { 989b1bc1afaSGagandeep Singh PFE_PMD_ERR("Invalid device node"); 99067fc3ff9SGagandeep Singh rc = -EINVAL; 99167fc3ff9SGagandeep Singh goto err; 99267fc3ff9SGagandeep Singh } 99367fc3ff9SGagandeep Singh 99467fc3ff9SGagandeep Singh addr = of_get_address(np, 0, &cbus_size, NULL); 995b1bc1afaSGagandeep Singh if (!addr) { 996*f665790aSDavid Marchand PFE_PMD_ERR("of_get_address cannot return qman address"); 99767fc3ff9SGagandeep Singh goto err; 998b1bc1afaSGagandeep Singh } 99967fc3ff9SGagandeep Singh cbus_addr = of_translate_address(np, addr); 1000b1bc1afaSGagandeep Singh if (!cbus_addr) { 1001*f665790aSDavid Marchand PFE_PMD_ERR("of_translate_address failed"); 100267fc3ff9SGagandeep Singh goto err; 1003b1bc1afaSGagandeep Singh } 100467fc3ff9SGagandeep Singh 100567fc3ff9SGagandeep Singh addr = of_get_address(np, 1, &ddr_size, NULL); 1006b1bc1afaSGagandeep Singh if (!addr) { 1007*f665790aSDavid Marchand PFE_PMD_ERR("of_get_address cannot return qman address"); 100867fc3ff9SGagandeep Singh goto err; 1009b1bc1afaSGagandeep Singh } 101067fc3ff9SGagandeep Singh 101167fc3ff9SGagandeep Singh g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); 1012b1bc1afaSGagandeep Singh if (!g_pfe->ddr_phys_baseaddr) { 1013*f665790aSDavid Marchand PFE_PMD_ERR("of_translate_address failed"); 101467fc3ff9SGagandeep Singh goto err; 1015b1bc1afaSGagandeep Singh } 101667fc3ff9SGagandeep Singh 10175253fe37SGagandeep Singh g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr); 101867fc3ff9SGagandeep Singh g_pfe->ddr_size = ddr_size; 101967fc3ff9SGagandeep Singh g_pfe->cbus_size = cbus_size; 102067fc3ff9SGagandeep Singh 102167fc3ff9SGagandeep Singh fd = open("/dev/mem", O_RDWR); 102267fc3ff9SGagandeep Singh g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, 102367fc3ff9SGagandeep Singh MAP_SHARED, fd, cbus_addr); 102467fc3ff9SGagandeep Singh close(fd); 102567fc3ff9SGagandeep Singh if (g_pfe->cbus_baseaddr == MAP_FAILED) { 1026b1bc1afaSGagandeep Singh PFE_PMD_ERR("Can not map cbus base"); 102767fc3ff9SGagandeep Singh rc = -EINVAL; 102867fc3ff9SGagandeep Singh goto err; 102967fc3ff9SGagandeep Singh } 103067fc3ff9SGagandeep Singh 103167fc3ff9SGagandeep Singh /* Read interface count */ 103267fc3ff9SGagandeep Singh prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); 103367fc3ff9SGagandeep Singh if (!prop) { 1034b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to read number of interfaces"); 103567fc3ff9SGagandeep Singh rc = -ENXIO; 103667fc3ff9SGagandeep Singh goto err_prop; 103767fc3ff9SGagandeep Singh } 103867fc3ff9SGagandeep Singh 103967fc3ff9SGagandeep Singh interface_count = rte_be_to_cpu_32((unsigned int)*prop); 104067fc3ff9SGagandeep Singh if (interface_count <= 0) { 1041b1bc1afaSGagandeep Singh PFE_PMD_ERR("No ethernet interface count : %d", 1042b1bc1afaSGagandeep Singh interface_count); 104367fc3ff9SGagandeep Singh rc = -ENXIO; 104467fc3ff9SGagandeep Singh goto err_prop; 104567fc3ff9SGagandeep Singh } 1046b1bc1afaSGagandeep Singh PFE_PMD_INFO("num interfaces = %d ", interface_count); 1047b1bc1afaSGagandeep Singh 104867fc3ff9SGagandeep Singh g_pfe->max_intf = interface_count; 10495253fe37SGagandeep Singh g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; 10505253fe37SGagandeep Singh 10515253fe37SGagandeep Singh for (ii = 0; ii < interface_count; ii++) { 10525253fe37SGagandeep Singh pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count, 10535253fe37SGagandeep Singh &g_pfe->platform_data); 10545253fe37SGagandeep Singh } 10555253fe37SGagandeep Singh 10565253fe37SGagandeep Singh pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr, 10575253fe37SGagandeep Singh g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size); 10585253fe37SGagandeep Singh 10595253fe37SGagandeep Singh PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION)); 10605253fe37SGagandeep Singh PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION)); 10615253fe37SGagandeep Singh 10625253fe37SGagandeep Singh PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION)); 10635253fe37SGagandeep Singh PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION)); 10645253fe37SGagandeep Singh 10655253fe37SGagandeep Singh PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION)); 10665253fe37SGagandeep Singh PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION)); 10675253fe37SGagandeep Singh PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION)); 10685253fe37SGagandeep Singh 10695253fe37SGagandeep Singh PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION)); 10705253fe37SGagandeep Singh PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION)); 10715253fe37SGagandeep Singh 10725253fe37SGagandeep Singh cbus_emac_base[0] = EMAC1_BASE_ADDR; 10735253fe37SGagandeep Singh cbus_emac_base[1] = EMAC2_BASE_ADDR; 10745253fe37SGagandeep Singh 10755253fe37SGagandeep Singh cbus_gpi_base[0] = EGPI1_BASE_ADDR; 10765253fe37SGagandeep Singh cbus_gpi_base[1] = EGPI2_BASE_ADDR; 10775253fe37SGagandeep Singh 10785253fe37SGagandeep Singh rc = pfe_hif_lib_init(g_pfe); 10795253fe37SGagandeep Singh if (rc < 0) 10805253fe37SGagandeep Singh goto err_hif_lib; 10815253fe37SGagandeep Singh 10825253fe37SGagandeep Singh rc = pfe_hif_init(g_pfe); 10835253fe37SGagandeep Singh if (rc < 0) 10845253fe37SGagandeep Singh goto err_hif; 108567fc3ff9SGagandeep Singh pfe_soc_version_get(); 108667fc3ff9SGagandeep Singh eth_init: 108767fc3ff9SGagandeep Singh if (init_params.gem_id < 0) 108867fc3ff9SGagandeep Singh gem_id = g_pfe->nb_devs; 108967fc3ff9SGagandeep Singh else 109067fc3ff9SGagandeep Singh gem_id = init_params.gem_id; 109167fc3ff9SGagandeep Singh 1092b8907ccfSStephen Hemminger PFE_PMD_LOG(INFO, "Init pmd_pfe for %s gem-id %d(given =%d)", 109367fc3ff9SGagandeep Singh name, gem_id, init_params.gem_id); 109467fc3ff9SGagandeep Singh 109567fc3ff9SGagandeep Singh rc = pfe_eth_init(vdev, g_pfe, gem_id); 109667fc3ff9SGagandeep Singh if (rc < 0) 109767fc3ff9SGagandeep Singh goto err_eth; 109867fc3ff9SGagandeep Singh else 109967fc3ff9SGagandeep Singh g_pfe->nb_devs++; 110067fc3ff9SGagandeep Singh 110167fc3ff9SGagandeep Singh return 0; 110267fc3ff9SGagandeep Singh 110367fc3ff9SGagandeep Singh err_eth: 11045253fe37SGagandeep Singh pfe_hif_exit(g_pfe); 11055253fe37SGagandeep Singh 11065253fe37SGagandeep Singh err_hif: 11075253fe37SGagandeep Singh pfe_hif_lib_exit(g_pfe); 11085253fe37SGagandeep Singh 11095253fe37SGagandeep Singh err_hif_lib: 111067fc3ff9SGagandeep Singh err_prop: 111167fc3ff9SGagandeep Singh munmap(g_pfe->cbus_baseaddr, cbus_size); 111267fc3ff9SGagandeep Singh err: 111367fc3ff9SGagandeep Singh rte_free(g_pfe); 111467fc3ff9SGagandeep Singh return rc; 111567fc3ff9SGagandeep Singh } 111667fc3ff9SGagandeep Singh 111767fc3ff9SGagandeep Singh static int 111867fc3ff9SGagandeep Singh pmd_pfe_remove(struct rte_vdev_device *vdev) 111967fc3ff9SGagandeep Singh { 112067fc3ff9SGagandeep Singh const char *name; 112167fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 112257803c5eSSachin Saxena int ret = 0; 112367fc3ff9SGagandeep Singh 112467fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 112567fc3ff9SGagandeep Singh if (name == NULL) 112667fc3ff9SGagandeep Singh return -EINVAL; 112767fc3ff9SGagandeep Singh 1128b1bc1afaSGagandeep Singh PFE_PMD_INFO("Closing eventdev sw device %s", name); 1129b1bc1afaSGagandeep Singh 113067fc3ff9SGagandeep Singh if (!g_pfe) 113167fc3ff9SGagandeep Singh return 0; 113267fc3ff9SGagandeep Singh 113367fc3ff9SGagandeep Singh eth_dev = rte_eth_dev_allocated(name); 113457803c5eSSachin Saxena if (eth_dev) { 113557803c5eSSachin Saxena pfe_eth_close(eth_dev); 113657803c5eSSachin Saxena ret = rte_eth_dev_release_port(eth_dev); 11375253fe37SGagandeep Singh } 113857803c5eSSachin Saxena 113957803c5eSSachin Saxena return ret; 114067fc3ff9SGagandeep Singh } 114167fc3ff9SGagandeep Singh 114267fc3ff9SGagandeep Singh static 114367fc3ff9SGagandeep Singh struct rte_vdev_driver pmd_pfe_drv = { 114467fc3ff9SGagandeep Singh .probe = pmd_pfe_probe, 114567fc3ff9SGagandeep Singh .remove = pmd_pfe_remove, 114667fc3ff9SGagandeep Singh }; 114767fc3ff9SGagandeep Singh 114867fc3ff9SGagandeep Singh RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); 114967fc3ff9SGagandeep Singh RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> "); 1150eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(pfe_logtype_pmd, NOTICE); 1151