167fc3ff9SGagandeep Singh /* SPDX-License-Identifier: BSD-3-Clause 2*f513f620SSachin 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> 867fc3ff9SGagandeep Singh #include <rte_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 upto 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 43b1bc1afaSGagandeep Singh int pfe_logtype_pmd; 44b1bc1afaSGagandeep Singh 455253fe37SGagandeep Singh /* pfe_gemac_init 465253fe37SGagandeep Singh */ 475253fe37SGagandeep Singh static int 485253fe37SGagandeep Singh pfe_gemac_init(struct pfe_eth_priv_s *priv) 495253fe37SGagandeep Singh { 505253fe37SGagandeep Singh struct gemac_cfg cfg; 515253fe37SGagandeep Singh 525253fe37SGagandeep Singh cfg.speed = SPEED_1000M; 535253fe37SGagandeep Singh cfg.duplex = DUPLEX_FULL; 545253fe37SGagandeep Singh 555253fe37SGagandeep Singh gemac_set_config(priv->EMAC_baseaddr, &cfg); 565253fe37SGagandeep Singh gemac_allow_broadcast(priv->EMAC_baseaddr); 575253fe37SGagandeep Singh gemac_enable_1536_rx(priv->EMAC_baseaddr); 585253fe37SGagandeep Singh gemac_enable_stacked_vlan(priv->EMAC_baseaddr); 595253fe37SGagandeep Singh gemac_enable_pause_rx(priv->EMAC_baseaddr); 605253fe37SGagandeep Singh gemac_set_bus_width(priv->EMAC_baseaddr, 64); 615253fe37SGagandeep Singh gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); 625253fe37SGagandeep Singh 635253fe37SGagandeep Singh return 0; 645253fe37SGagandeep Singh } 655253fe37SGagandeep Singh 6667fc3ff9SGagandeep Singh static void 6767fc3ff9SGagandeep Singh pfe_soc_version_get(void) 6867fc3ff9SGagandeep Singh { 6967fc3ff9SGagandeep Singh FILE *svr_file = NULL; 7067fc3ff9SGagandeep Singh unsigned int svr_ver = 0; 7167fc3ff9SGagandeep Singh 72b1bc1afaSGagandeep Singh PMD_INIT_FUNC_TRACE(); 73b1bc1afaSGagandeep Singh 7467fc3ff9SGagandeep Singh svr_file = fopen(PFE_SOC_ID_FILE, "r"); 75b1bc1afaSGagandeep Singh if (!svr_file) { 76b1bc1afaSGagandeep Singh PFE_PMD_ERR("Unable to open SoC device"); 7767fc3ff9SGagandeep Singh return; /* Not supported on this infra */ 78b1bc1afaSGagandeep Singh } 7967fc3ff9SGagandeep Singh 8067fc3ff9SGagandeep Singh if (fscanf(svr_file, "svr:%x", &svr_ver) > 0) 8167fc3ff9SGagandeep Singh pfe_svr = svr_ver; 8267fc3ff9SGagandeep Singh else 83b1bc1afaSGagandeep Singh PFE_PMD_ERR("Unable to read SoC device"); 8467fc3ff9SGagandeep Singh 8567fc3ff9SGagandeep Singh fclose(svr_file); 8667fc3ff9SGagandeep Singh } 8767fc3ff9SGagandeep Singh 88fe38ad9bSGagandeep Singh static int pfe_eth_start(struct pfe_eth_priv_s *priv) 89fe38ad9bSGagandeep Singh { 90fe38ad9bSGagandeep Singh gpi_enable(priv->GPI_baseaddr); 91fe38ad9bSGagandeep Singh gemac_enable(priv->EMAC_baseaddr); 92fe38ad9bSGagandeep Singh 93fe38ad9bSGagandeep Singh return 0; 94fe38ad9bSGagandeep Singh } 95fe38ad9bSGagandeep Singh 96fe38ad9bSGagandeep Singh static void 97fe38ad9bSGagandeep Singh pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int 98fe38ad9bSGagandeep Singh __rte_unused from_tx, __rte_unused int n_desc) 99fe38ad9bSGagandeep Singh { 100fe38ad9bSGagandeep Singh struct rte_mbuf *mbuf; 101fe38ad9bSGagandeep Singh unsigned int flags; 102fe38ad9bSGagandeep Singh 103fe38ad9bSGagandeep Singh /* Clean HIF and client queue */ 104fe38ad9bSGagandeep Singh while ((mbuf = hif_lib_tx_get_next_complete(&priv->client, 105fe38ad9bSGagandeep Singh tx_q_num, &flags, 106fe38ad9bSGagandeep Singh HIF_TX_DESC_NT))) { 107fe38ad9bSGagandeep Singh if (mbuf) { 108fe38ad9bSGagandeep Singh mbuf->next = NULL; 109fe38ad9bSGagandeep Singh mbuf->nb_segs = 1; 110fe38ad9bSGagandeep Singh rte_pktmbuf_free(mbuf); 111fe38ad9bSGagandeep Singh } 112fe38ad9bSGagandeep Singh } 113fe38ad9bSGagandeep Singh } 114fe38ad9bSGagandeep Singh 115fe38ad9bSGagandeep Singh 116fe38ad9bSGagandeep Singh static void 117fe38ad9bSGagandeep Singh pfe_eth_flush_tx(struct pfe_eth_priv_s *priv) 118fe38ad9bSGagandeep Singh { 119fe38ad9bSGagandeep Singh unsigned int ii; 120fe38ad9bSGagandeep Singh 121fe38ad9bSGagandeep Singh for (ii = 0; ii < emac_txq_cnt; ii++) 122fe38ad9bSGagandeep Singh pfe_eth_flush_txQ(priv, ii, 0, 0); 123fe38ad9bSGagandeep Singh } 124fe38ad9bSGagandeep Singh 125fe38ad9bSGagandeep Singh static int 126fe38ad9bSGagandeep Singh pfe_eth_event_handler(void *data, int event, __rte_unused int qno) 127fe38ad9bSGagandeep Singh { 128fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = data; 129fe38ad9bSGagandeep Singh 130fe38ad9bSGagandeep Singh switch (event) { 131fe38ad9bSGagandeep Singh case EVENT_TXDONE_IND: 132fe38ad9bSGagandeep Singh pfe_eth_flush_tx(priv); 133fe38ad9bSGagandeep Singh hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0); 134fe38ad9bSGagandeep Singh break; 135fe38ad9bSGagandeep Singh case EVENT_HIGH_RX_WM: 136fe38ad9bSGagandeep Singh default: 137fe38ad9bSGagandeep Singh break; 138fe38ad9bSGagandeep Singh } 139fe38ad9bSGagandeep Singh 140fe38ad9bSGagandeep Singh return 0; 141fe38ad9bSGagandeep Singh } 142fe38ad9bSGagandeep Singh 14336220514SGagandeep Singh static uint16_t 14436220514SGagandeep Singh pfe_recv_pkts_on_intr(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 14536220514SGagandeep Singh { 14636220514SGagandeep Singh struct hif_client_rx_queue *queue = rxq; 14736220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 14836220514SGagandeep Singh struct epoll_event epoll_ev; 14936220514SGagandeep Singh uint64_t ticks = 1; /* 1 msec */ 15036220514SGagandeep Singh int ret; 15136220514SGagandeep Singh int have_something, work_done; 15236220514SGagandeep Singh 15336220514SGagandeep Singh #define RESET_STATUS (HIF_INT | HIF_RXPKT_INT) 15436220514SGagandeep Singh 15536220514SGagandeep Singh /*TODO can we remove this cleanup from here?*/ 15636220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 15736220514SGagandeep Singh have_something = pfe_hif_rx_process(priv->pfe, nb_pkts); 15836220514SGagandeep Singh work_done = hif_lib_receive_pkt(rxq, priv->pfe->hif.shm->pool, 15936220514SGagandeep Singh rx_pkts, nb_pkts); 16036220514SGagandeep Singh 16136220514SGagandeep Singh if (!have_something || !work_done) { 16236220514SGagandeep Singh writel(RESET_STATUS, HIF_INT_SRC); 16336220514SGagandeep Singh writel(readl(HIF_INT_ENABLE) | HIF_RXPKT_INT, HIF_INT_ENABLE); 16436220514SGagandeep Singh ret = epoll_wait(priv->pfe->hif.epoll_fd, &epoll_ev, 1, ticks); 16536220514SGagandeep Singh if (ret < 0 && errno != EINTR) 16636220514SGagandeep Singh PFE_PMD_ERR("epoll_wait fails with %d\n", errno); 16736220514SGagandeep Singh } 16836220514SGagandeep Singh 16936220514SGagandeep Singh return work_done; 17036220514SGagandeep Singh } 17136220514SGagandeep Singh 17236220514SGagandeep Singh static uint16_t 17336220514SGagandeep Singh pfe_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 17436220514SGagandeep Singh { 17536220514SGagandeep Singh struct hif_client_rx_queue *queue = rxq; 17636220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 17736220514SGagandeep Singh struct rte_mempool *pool; 17836220514SGagandeep Singh 17936220514SGagandeep Singh /*TODO can we remove this cleanup from here?*/ 18036220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 18136220514SGagandeep Singh pfe_hif_rx_process(priv->pfe, nb_pkts); 18236220514SGagandeep Singh pool = priv->pfe->hif.shm->pool; 18336220514SGagandeep Singh 18436220514SGagandeep Singh return hif_lib_receive_pkt(rxq, pool, rx_pkts, nb_pkts); 18536220514SGagandeep Singh } 18636220514SGagandeep Singh 18736220514SGagandeep Singh static uint16_t 18836220514SGagandeep Singh pfe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 18936220514SGagandeep Singh { 19036220514SGagandeep Singh struct hif_client_tx_queue *queue = tx_queue; 19136220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 19236220514SGagandeep Singh struct rte_eth_stats *stats = &priv->stats; 19336220514SGagandeep Singh int i; 19436220514SGagandeep Singh 19536220514SGagandeep Singh for (i = 0; i < nb_pkts; i++) { 19636220514SGagandeep Singh if (tx_pkts[i]->nb_segs > 1) { 19736220514SGagandeep Singh struct rte_mbuf *mbuf; 19836220514SGagandeep Singh int j; 19936220514SGagandeep Singh 20036220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 20136220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 20236220514SGagandeep Singh tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 20336220514SGagandeep Singh tx_pkts[i]->data_len, 0x0, HIF_FIRST_BUFFER, 20436220514SGagandeep Singh tx_pkts[i]); 20536220514SGagandeep Singh 20636220514SGagandeep Singh mbuf = tx_pkts[i]->next; 20736220514SGagandeep Singh for (j = 0; j < (tx_pkts[i]->nb_segs - 2); j++) { 20836220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 20936220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(mbuf), 21036220514SGagandeep Singh mbuf->buf_addr + mbuf->data_off, 21136220514SGagandeep Singh mbuf->data_len, 21236220514SGagandeep Singh 0x0, 0x0, mbuf); 21336220514SGagandeep Singh mbuf = mbuf->next; 21436220514SGagandeep Singh } 21536220514SGagandeep Singh 21636220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 21736220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(mbuf), 21836220514SGagandeep Singh mbuf->buf_addr + mbuf->data_off, 21936220514SGagandeep Singh mbuf->data_len, 22036220514SGagandeep Singh 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID, 22136220514SGagandeep Singh mbuf); 22236220514SGagandeep Singh } else { 22336220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 22436220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 22536220514SGagandeep Singh tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 22636220514SGagandeep Singh tx_pkts[i]->pkt_len, 0 /*ctrl*/, 22736220514SGagandeep Singh HIF_FIRST_BUFFER | HIF_LAST_BUFFER | 22836220514SGagandeep Singh HIF_DATA_VALID, 22936220514SGagandeep Singh tx_pkts[i]); 23036220514SGagandeep Singh } 23136220514SGagandeep Singh stats->obytes += tx_pkts[i]->pkt_len; 23236220514SGagandeep Singh hif_tx_dma_start(); 23336220514SGagandeep Singh } 23436220514SGagandeep Singh stats->opackets += nb_pkts; 23536220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 23636220514SGagandeep Singh 23736220514SGagandeep Singh return nb_pkts; 23836220514SGagandeep Singh } 23936220514SGagandeep Singh 24036220514SGagandeep Singh static uint16_t 24136220514SGagandeep Singh pfe_dummy_xmit_pkts(__rte_unused void *tx_queue, 24236220514SGagandeep Singh __rte_unused struct rte_mbuf **tx_pkts, 24336220514SGagandeep Singh __rte_unused uint16_t nb_pkts) 24436220514SGagandeep Singh { 24536220514SGagandeep Singh return 0; 24636220514SGagandeep Singh } 24736220514SGagandeep Singh 24836220514SGagandeep Singh static uint16_t 24936220514SGagandeep Singh pfe_dummy_recv_pkts(__rte_unused void *rxq, 25036220514SGagandeep Singh __rte_unused struct rte_mbuf **rx_pkts, 25136220514SGagandeep Singh __rte_unused uint16_t nb_pkts) 25236220514SGagandeep Singh { 25336220514SGagandeep Singh return 0; 25436220514SGagandeep Singh } 25536220514SGagandeep Singh 256fe38ad9bSGagandeep Singh static int 257fe38ad9bSGagandeep Singh pfe_eth_open(struct rte_eth_dev *dev) 258fe38ad9bSGagandeep Singh { 259fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 260fe38ad9bSGagandeep Singh struct hif_client_s *client; 261fe38ad9bSGagandeep Singh struct hif_shm *hif_shm; 262fe38ad9bSGagandeep Singh int rc; 263fe38ad9bSGagandeep Singh 264fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 265fe38ad9bSGagandeep Singh client = &priv->client; 266fe38ad9bSGagandeep Singh 267fe38ad9bSGagandeep Singh if (client->pfe) { 268fe38ad9bSGagandeep Singh hif_shm = client->pfe->hif.shm; 269fe38ad9bSGagandeep Singh /* TODO please remove the below code of if block, once we add 270fe38ad9bSGagandeep Singh * the proper cleanup in eth_close 271fe38ad9bSGagandeep Singh */ 272fe38ad9bSGagandeep Singh if (!test_bit(PFE_CL_GEM0 + priv->id, 273fe38ad9bSGagandeep Singh &hif_shm->g_client_status[0])) { 274fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 275fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 276fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 277fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 278fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 279fe38ad9bSGagandeep Singh client->priv = priv; 280fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 281fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 282fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 283fe38ad9bSGagandeep Singh 284fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 285fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 286fe38ad9bSGagandeep Singh 287fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 288fe38ad9bSGagandeep Singh if (rc) { 289fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d)" 290fe38ad9bSGagandeep Singh " failed", client->id); 291fe38ad9bSGagandeep Singh goto err0; 292fe38ad9bSGagandeep Singh } 29336220514SGagandeep Singh } else { 29436220514SGagandeep Singh /* Freeing the packets if already exists */ 29536220514SGagandeep Singh int ret = 0; 29636220514SGagandeep Singh struct rte_mbuf *rx_pkts[32]; 29736220514SGagandeep Singh /* TODO multiqueue support */ 29836220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 29936220514SGagandeep Singh hif_shm->pool, rx_pkts, 32); 30036220514SGagandeep Singh while (ret) { 30136220514SGagandeep Singh int i; 30236220514SGagandeep Singh for (i = 0; i < ret; i++) 30336220514SGagandeep Singh rte_pktmbuf_free(rx_pkts[i]); 30436220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 30536220514SGagandeep Singh hif_shm->pool, 30636220514SGagandeep Singh rx_pkts, 32); 30736220514SGagandeep Singh } 308fe38ad9bSGagandeep Singh } 309fe38ad9bSGagandeep Singh } else { 310fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 311fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 312fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 313fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 314fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 315fe38ad9bSGagandeep Singh client->priv = priv; 316fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 317fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 318fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 319fe38ad9bSGagandeep Singh 320fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 321fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 322fe38ad9bSGagandeep Singh 323fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 324fe38ad9bSGagandeep Singh if (rc) { 325fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d) failed", 326fe38ad9bSGagandeep Singh client->id); 327fe38ad9bSGagandeep Singh goto err0; 328fe38ad9bSGagandeep Singh } 329fe38ad9bSGagandeep Singh } 330fe38ad9bSGagandeep Singh rc = pfe_eth_start(priv); 33136220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts; 33236220514SGagandeep Singh dev->tx_pkt_burst = &pfe_xmit_pkts; 33336220514SGagandeep Singh /* If no prefetch is configured. */ 33436220514SGagandeep Singh if (getenv("PFE_INTR_SUPPORT")) { 33536220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; 33636220514SGagandeep Singh PFE_PMD_INFO("PFE INTERRUPT Mode enabled"); 33736220514SGagandeep Singh } 33836220514SGagandeep Singh 339fe38ad9bSGagandeep Singh 340fe38ad9bSGagandeep Singh err0: 341fe38ad9bSGagandeep Singh return rc; 342fe38ad9bSGagandeep Singh } 343fe38ad9bSGagandeep Singh 34467fc3ff9SGagandeep Singh static int 34567fc3ff9SGagandeep Singh pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) 34667fc3ff9SGagandeep Singh { 34767fc3ff9SGagandeep Singh int pfe_cdev_fd; 34867fc3ff9SGagandeep Singh 34967fc3ff9SGagandeep Singh if (priv == NULL) 35067fc3ff9SGagandeep Singh return -1; 35167fc3ff9SGagandeep Singh 35267fc3ff9SGagandeep Singh pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); 35367fc3ff9SGagandeep Singh if (pfe_cdev_fd < 0) { 354b1bc1afaSGagandeep Singh PFE_PMD_WARN("Unable to open PFE device file (%s).\n", 355b1bc1afaSGagandeep Singh PFE_CDEV_PATH); 356b1bc1afaSGagandeep Singh PFE_PMD_WARN("Link status update will not be available.\n"); 35767fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 35867fc3ff9SGagandeep Singh return -1; 35967fc3ff9SGagandeep Singh } 36067fc3ff9SGagandeep Singh 36167fc3ff9SGagandeep Singh priv->link_fd = pfe_cdev_fd; 36267fc3ff9SGagandeep Singh 36367fc3ff9SGagandeep Singh return 0; 36467fc3ff9SGagandeep Singh } 36567fc3ff9SGagandeep Singh 36667fc3ff9SGagandeep Singh static void 36767fc3ff9SGagandeep Singh pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) 36867fc3ff9SGagandeep Singh { 36967fc3ff9SGagandeep Singh if (priv == NULL) 37067fc3ff9SGagandeep Singh return; 37167fc3ff9SGagandeep Singh 37267fc3ff9SGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 37367fc3ff9SGagandeep Singh close(priv->link_fd); 37467fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 37567fc3ff9SGagandeep Singh } 37667fc3ff9SGagandeep Singh } 37767fc3ff9SGagandeep Singh 37867fc3ff9SGagandeep Singh static void 379fe38ad9bSGagandeep Singh pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) 380fe38ad9bSGagandeep Singh { 381fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 382fe38ad9bSGagandeep Singh 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; 388fe38ad9bSGagandeep Singh } 389fe38ad9bSGagandeep Singh 390fe38ad9bSGagandeep Singh static void 39167fc3ff9SGagandeep Singh pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) 39267fc3ff9SGagandeep Singh { 393b1bc1afaSGagandeep Singh PMD_INIT_FUNC_TRACE(); 394b1bc1afaSGagandeep Singh 395fe38ad9bSGagandeep Singh pfe_eth_stop(dev); 39667fc3ff9SGagandeep Singh /* Close the device file for link status */ 39767fc3ff9SGagandeep Singh pfe_eth_close_cdev(dev->data->dev_private); 39867fc3ff9SGagandeep Singh 39967fc3ff9SGagandeep Singh rte_free(dev->data->mac_addrs); 40067fc3ff9SGagandeep Singh rte_eth_dev_release_port(dev); 40167fc3ff9SGagandeep Singh pfe->nb_devs--; 40267fc3ff9SGagandeep Singh } 40367fc3ff9SGagandeep Singh 404fe38ad9bSGagandeep Singh static void 405fe38ad9bSGagandeep Singh pfe_eth_close(struct rte_eth_dev *dev) 406fe38ad9bSGagandeep Singh { 407fe38ad9bSGagandeep Singh if (!dev) 408fe38ad9bSGagandeep Singh return; 409fe38ad9bSGagandeep Singh 410fe38ad9bSGagandeep Singh if (!g_pfe) 411fe38ad9bSGagandeep Singh return; 412fe38ad9bSGagandeep Singh 413fe38ad9bSGagandeep Singh pfe_eth_exit(dev, g_pfe); 414fe38ad9bSGagandeep Singh 415fe38ad9bSGagandeep Singh if (g_pfe->nb_devs == 0) { 416fe38ad9bSGagandeep Singh pfe_hif_exit(g_pfe); 417fe38ad9bSGagandeep Singh pfe_hif_lib_exit(g_pfe); 418fe38ad9bSGagandeep Singh rte_free(g_pfe); 419fe38ad9bSGagandeep Singh g_pfe = NULL; 420fe38ad9bSGagandeep Singh } 421fe38ad9bSGagandeep Singh } 422fe38ad9bSGagandeep Singh 423fe38ad9bSGagandeep Singh static int 424fe38ad9bSGagandeep Singh pfe_eth_configure(struct rte_eth_dev *dev __rte_unused) 425fe38ad9bSGagandeep Singh { 426fe38ad9bSGagandeep Singh return 0; 427fe38ad9bSGagandeep Singh } 428fe38ad9bSGagandeep Singh 429fe38ad9bSGagandeep Singh static int 430fe38ad9bSGagandeep Singh pfe_eth_info(struct rte_eth_dev *dev, 431fe38ad9bSGagandeep Singh struct rte_eth_dev_info *dev_info) 432fe38ad9bSGagandeep Singh { 433fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *internals = dev->data->dev_private; 434fe38ad9bSGagandeep Singh 435fe38ad9bSGagandeep Singh dev_info->if_index = internals->id; 436fe38ad9bSGagandeep Singh dev_info->max_mac_addrs = PFE_MAX_MACS; 437fe38ad9bSGagandeep Singh dev_info->max_rx_queues = dev->data->nb_rx_queues; 438fe38ad9bSGagandeep Singh dev_info->max_tx_queues = dev->data->nb_tx_queues; 439fe38ad9bSGagandeep Singh dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE; 440320ae324SGagandeep Singh dev_info->min_mtu = RTE_ETHER_MIN_MTU; 441592041a0SGagandeep Singh dev_info->rx_offload_capa = dev_rx_offloads_sup; 442592041a0SGagandeep Singh dev_info->tx_offload_capa = dev_tx_offloads_sup; 443320ae324SGagandeep Singh if (pfe_svr == SVR_LS1012A_REV1) { 444fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; 445320ae324SGagandeep Singh dev_info->max_mtu = MAX_MTU_ON_REV1; 446320ae324SGagandeep Singh } else { 447fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE; 448320ae324SGagandeep Singh dev_info->max_mtu = JUMBO_FRAME_SIZE - PFE_ETH_OVERHEAD; 449320ae324SGagandeep Singh } 450fe38ad9bSGagandeep Singh 451fe38ad9bSGagandeep Singh return 0; 452fe38ad9bSGagandeep Singh } 453fe38ad9bSGagandeep Singh 454592041a0SGagandeep Singh /* Only first mb_pool given on first call of this API will be used 455592041a0SGagandeep Singh * in whole system, also nb_rx_desc and rx_conf are unused params 456592041a0SGagandeep Singh */ 457592041a0SGagandeep Singh static int 458592041a0SGagandeep Singh pfe_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, 459592041a0SGagandeep Singh __rte_unused uint16_t nb_rx_desc, 460592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 461592041a0SGagandeep Singh __rte_unused const struct rte_eth_rxconf *rx_conf, 462592041a0SGagandeep Singh struct rte_mempool *mb_pool) 463592041a0SGagandeep Singh { 464592041a0SGagandeep Singh int rc = 0; 465592041a0SGagandeep Singh struct pfe *pfe; 466592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 467592041a0SGagandeep Singh 468592041a0SGagandeep Singh pfe = priv->pfe; 469592041a0SGagandeep Singh 470592041a0SGagandeep Singh if (queue_idx >= EMAC_RXQ_CNT) { 471592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 472592041a0SGagandeep Singh queue_idx, EMAC_RXQ_CNT); 473592041a0SGagandeep Singh return -1; 474592041a0SGagandeep Singh } 475592041a0SGagandeep Singh 476592041a0SGagandeep Singh if (!pfe->hif.setuped) { 477592041a0SGagandeep Singh rc = pfe_hif_shm_init(pfe->hif.shm, mb_pool); 478592041a0SGagandeep Singh if (rc) { 479592041a0SGagandeep Singh PFE_PMD_ERR("Could not allocate buffer descriptors"); 480592041a0SGagandeep Singh return -1; 481592041a0SGagandeep Singh } 482592041a0SGagandeep Singh 483592041a0SGagandeep Singh pfe->hif.shm->pool = mb_pool; 484592041a0SGagandeep Singh if (pfe_hif_init_buffers(&pfe->hif)) { 485592041a0SGagandeep Singh PFE_PMD_ERR("Could not initialize buffer descriptors"); 486592041a0SGagandeep Singh return -1; 487592041a0SGagandeep Singh } 488592041a0SGagandeep Singh hif_init(); 489592041a0SGagandeep Singh hif_rx_enable(); 490592041a0SGagandeep Singh hif_tx_enable(); 491592041a0SGagandeep Singh pfe->hif.setuped = 1; 492592041a0SGagandeep Singh } 493592041a0SGagandeep Singh dev->data->rx_queues[queue_idx] = &priv->client.rx_q[queue_idx]; 494592041a0SGagandeep Singh priv->client.rx_q[queue_idx].queue_id = queue_idx; 495592041a0SGagandeep Singh 496592041a0SGagandeep Singh return 0; 497592041a0SGagandeep Singh } 498592041a0SGagandeep Singh 499592041a0SGagandeep Singh static void 500592041a0SGagandeep Singh pfe_rx_queue_release(void *q __rte_unused) 501592041a0SGagandeep Singh { 502592041a0SGagandeep Singh PMD_INIT_FUNC_TRACE(); 503592041a0SGagandeep Singh } 504592041a0SGagandeep Singh 505592041a0SGagandeep Singh static void 506592041a0SGagandeep Singh pfe_tx_queue_release(void *q __rte_unused) 507592041a0SGagandeep Singh { 508592041a0SGagandeep Singh PMD_INIT_FUNC_TRACE(); 509592041a0SGagandeep Singh } 510592041a0SGagandeep Singh 511592041a0SGagandeep Singh static int 512592041a0SGagandeep Singh pfe_tx_queue_setup(struct rte_eth_dev *dev, 513592041a0SGagandeep Singh uint16_t queue_idx, 514592041a0SGagandeep Singh __rte_unused uint16_t nb_desc, 515592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 516592041a0SGagandeep Singh __rte_unused const struct rte_eth_txconf *tx_conf) 517592041a0SGagandeep Singh { 518592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 519592041a0SGagandeep Singh 520592041a0SGagandeep Singh if (queue_idx >= emac_txq_cnt) { 521592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 522592041a0SGagandeep Singh queue_idx, emac_txq_cnt); 523592041a0SGagandeep Singh return -1; 524592041a0SGagandeep Singh } 525592041a0SGagandeep Singh dev->data->tx_queues[queue_idx] = &priv->client.tx_q[queue_idx]; 526592041a0SGagandeep Singh priv->client.tx_q[queue_idx].queue_id = queue_idx; 527592041a0SGagandeep Singh return 0; 528592041a0SGagandeep Singh } 529592041a0SGagandeep Singh 530659b494dSGagandeep Singh static const uint32_t * 531659b494dSGagandeep Singh pfe_supported_ptypes_get(struct rte_eth_dev *dev) 532659b494dSGagandeep Singh { 533659b494dSGagandeep Singh static const uint32_t ptypes[] = { 534659b494dSGagandeep Singh /*todo -= add more types */ 535659b494dSGagandeep Singh RTE_PTYPE_L2_ETHER, 536659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4, 537659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4_EXT, 538659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6, 539659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6_EXT, 540659b494dSGagandeep Singh RTE_PTYPE_L4_TCP, 541659b494dSGagandeep Singh RTE_PTYPE_L4_UDP, 542659b494dSGagandeep Singh RTE_PTYPE_L4_SCTP 543659b494dSGagandeep Singh }; 544659b494dSGagandeep Singh 545659b494dSGagandeep Singh if (dev->rx_pkt_burst == pfe_recv_pkts || 546659b494dSGagandeep Singh dev->rx_pkt_burst == pfe_recv_pkts_on_intr) 547659b494dSGagandeep Singh return ptypes; 548659b494dSGagandeep Singh return NULL; 549659b494dSGagandeep Singh } 550659b494dSGagandeep Singh 551acd4818eSGagandeep Singh static inline int 552acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev, 553acd4818eSGagandeep Singh struct rte_eth_link *link) 554acd4818eSGagandeep Singh { 555acd4818eSGagandeep Singh struct rte_eth_link *dst = link; 556acd4818eSGagandeep Singh struct rte_eth_link *src = &dev->data->dev_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 inline int 566acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev, 567acd4818eSGagandeep Singh struct rte_eth_link *link) 568acd4818eSGagandeep Singh { 569acd4818eSGagandeep Singh struct rte_eth_link *dst = &dev->data->dev_link; 570acd4818eSGagandeep Singh struct rte_eth_link *src = link; 571acd4818eSGagandeep Singh 572acd4818eSGagandeep Singh if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 573acd4818eSGagandeep Singh *(uint64_t *)src) == 0) 574acd4818eSGagandeep Singh return -1; 575acd4818eSGagandeep Singh 576acd4818eSGagandeep Singh return 0; 577acd4818eSGagandeep Singh } 578acd4818eSGagandeep Singh 579acd4818eSGagandeep Singh static int 580acd4818eSGagandeep Singh pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) 581acd4818eSGagandeep Singh { 582acd4818eSGagandeep Singh int ret, ioctl_cmd = 0; 583acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 584acd4818eSGagandeep Singh struct rte_eth_link link, old; 585acd4818eSGagandeep Singh unsigned int lstatus = 1; 586acd4818eSGagandeep Singh 587acd4818eSGagandeep Singh if (dev == NULL) { 588acd4818eSGagandeep Singh PFE_PMD_ERR("Invalid device in link_update.\n"); 589acd4818eSGagandeep Singh return 0; 590acd4818eSGagandeep Singh } 591acd4818eSGagandeep Singh 592acd4818eSGagandeep Singh memset(&old, 0, sizeof(old)); 593acd4818eSGagandeep Singh memset(&link, 0, sizeof(struct rte_eth_link)); 594acd4818eSGagandeep Singh 595acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(dev, &old); 596acd4818eSGagandeep Singh 597acd4818eSGagandeep Singh /* Read from PFE CDEV, status of link, if file was successfully 598acd4818eSGagandeep Singh * opened. 599acd4818eSGagandeep Singh */ 600acd4818eSGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 601acd4818eSGagandeep Singh if (priv->id == 0) 602acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH0_STATE_GET; 603acd4818eSGagandeep Singh if (priv->id == 1) 604acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH1_STATE_GET; 605acd4818eSGagandeep Singh 606acd4818eSGagandeep Singh ret = ioctl(priv->link_fd, ioctl_cmd, &lstatus); 607acd4818eSGagandeep Singh if (ret != 0) { 608acd4818eSGagandeep Singh PFE_PMD_ERR("Unable to fetch link status (ioctl)\n"); 609acd4818eSGagandeep Singh /* use dummy link value */ 610acd4818eSGagandeep Singh link.link_status = 1; 611acd4818eSGagandeep Singh } 612acd4818eSGagandeep Singh PFE_PMD_DEBUG("Fetched link state (%d) for dev %d.\n", 613acd4818eSGagandeep Singh lstatus, priv->id); 614acd4818eSGagandeep Singh } 615acd4818eSGagandeep Singh 616acd4818eSGagandeep Singh if (old.link_status == lstatus) { 617acd4818eSGagandeep Singh /* no change in status */ 618acd4818eSGagandeep Singh PFE_PMD_DEBUG("No change in link status; Not updating.\n"); 619acd4818eSGagandeep Singh return -1; 620acd4818eSGagandeep Singh } 621acd4818eSGagandeep Singh 622acd4818eSGagandeep Singh link.link_status = lstatus; 623acd4818eSGagandeep Singh link.link_speed = ETH_LINK_SPEED_1G; 624acd4818eSGagandeep Singh link.link_duplex = ETH_LINK_FULL_DUPLEX; 625acd4818eSGagandeep Singh link.link_autoneg = ETH_LINK_AUTONEG; 626acd4818eSGagandeep Singh 627acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(dev, &link); 628acd4818eSGagandeep Singh 629acd4818eSGagandeep Singh PFE_PMD_INFO("Port (%d) link is %s\n", dev->data->port_id, 630acd4818eSGagandeep Singh link.link_status ? "up" : "down"); 631acd4818eSGagandeep Singh 632acd4818eSGagandeep Singh return 0; 633acd4818eSGagandeep Singh } 634acd4818eSGagandeep Singh 635659b494dSGagandeep Singh static int 636ff64beabSGagandeep Singh pfe_promiscuous_enable(struct rte_eth_dev *dev) 637ff64beabSGagandeep Singh { 638ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 639ff64beabSGagandeep Singh 640ff64beabSGagandeep Singh priv->promisc = 1; 641ff64beabSGagandeep Singh dev->data->promiscuous = 1; 642ff64beabSGagandeep Singh gemac_enable_copy_all(priv->EMAC_baseaddr); 643ff64beabSGagandeep Singh 644ff64beabSGagandeep Singh return 0; 645ff64beabSGagandeep Singh } 646ff64beabSGagandeep Singh 647ff64beabSGagandeep Singh static int 648ff64beabSGagandeep Singh pfe_promiscuous_disable(struct rte_eth_dev *dev) 649ff64beabSGagandeep Singh { 650ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 651ff64beabSGagandeep Singh 652ff64beabSGagandeep Singh priv->promisc = 0; 653ff64beabSGagandeep Singh dev->data->promiscuous = 0; 654ff64beabSGagandeep Singh gemac_disable_copy_all(priv->EMAC_baseaddr); 655ff64beabSGagandeep Singh 656ff64beabSGagandeep Singh return 0; 657ff64beabSGagandeep Singh } 658ff64beabSGagandeep Singh 659ff64beabSGagandeep Singh static int 660ff64beabSGagandeep Singh pfe_allmulticast_enable(struct rte_eth_dev *dev) 661ff64beabSGagandeep Singh { 662ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 663ff64beabSGagandeep Singh struct pfe_mac_addr hash_addr; /* hash register structure */ 664ff64beabSGagandeep Singh 665ff64beabSGagandeep Singh /* Set the hash to rx all multicast frames */ 666ff64beabSGagandeep Singh hash_addr.bottom = 0xFFFFFFFF; 667ff64beabSGagandeep Singh hash_addr.top = 0xFFFFFFFF; 668ff64beabSGagandeep Singh gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); 669ff64beabSGagandeep Singh dev->data->all_multicast = 1; 670ff64beabSGagandeep Singh 671ff64beabSGagandeep Singh return 0; 672ff64beabSGagandeep Singh } 673ff64beabSGagandeep Singh 674ff64beabSGagandeep Singh static int 675acd4818eSGagandeep Singh pfe_link_down(struct rte_eth_dev *dev) 676acd4818eSGagandeep Singh { 677acd4818eSGagandeep Singh pfe_eth_stop(dev); 678acd4818eSGagandeep Singh return 0; 679acd4818eSGagandeep Singh } 680acd4818eSGagandeep Singh 681acd4818eSGagandeep Singh static int 682acd4818eSGagandeep Singh pfe_link_up(struct rte_eth_dev *dev) 683acd4818eSGagandeep Singh { 684acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 685acd4818eSGagandeep Singh 686acd4818eSGagandeep Singh pfe_eth_start(priv); 687acd4818eSGagandeep Singh return 0; 688acd4818eSGagandeep Singh } 689acd4818eSGagandeep Singh 690acd4818eSGagandeep Singh static int 691320ae324SGagandeep Singh pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 692320ae324SGagandeep Singh { 693320ae324SGagandeep Singh int ret; 694320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 695320ae324SGagandeep Singh uint16_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 696320ae324SGagandeep Singh 697320ae324SGagandeep Singh /*TODO Support VLAN*/ 698320ae324SGagandeep Singh ret = gemac_set_rx(priv->EMAC_baseaddr, frame_size); 699320ae324SGagandeep Singh if (!ret) 700320ae324SGagandeep Singh dev->data->mtu = mtu; 701320ae324SGagandeep Singh 702320ae324SGagandeep Singh return ret; 703320ae324SGagandeep Singh } 704320ae324SGagandeep Singh 705320ae324SGagandeep Singh /* pfe_eth_enet_addr_byte_mac 706320ae324SGagandeep Singh */ 707320ae324SGagandeep Singh static int 708320ae324SGagandeep Singh pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, 709320ae324SGagandeep Singh struct pfe_mac_addr *enet_addr) 710320ae324SGagandeep Singh { 711320ae324SGagandeep Singh if (!enet_byte_addr || !enet_addr) { 712320ae324SGagandeep Singh return -1; 713320ae324SGagandeep Singh 714320ae324SGagandeep Singh } else { 715320ae324SGagandeep Singh enet_addr->bottom = enet_byte_addr[0] | 716320ae324SGagandeep Singh (enet_byte_addr[1] << 8) | 717320ae324SGagandeep Singh (enet_byte_addr[2] << 16) | 718320ae324SGagandeep Singh (enet_byte_addr[3] << 24); 719320ae324SGagandeep Singh enet_addr->top = enet_byte_addr[4] | 720320ae324SGagandeep Singh (enet_byte_addr[5] << 8); 721320ae324SGagandeep Singh return 0; 722320ae324SGagandeep Singh } 723320ae324SGagandeep Singh } 724320ae324SGagandeep Singh 725320ae324SGagandeep Singh static int 726320ae324SGagandeep Singh pfe_dev_set_mac_addr(struct rte_eth_dev *dev, 727320ae324SGagandeep Singh struct rte_ether_addr *addr) 728320ae324SGagandeep Singh { 729320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 730320ae324SGagandeep Singh struct pfe_mac_addr spec_addr; 731320ae324SGagandeep Singh int ret; 732320ae324SGagandeep Singh 733320ae324SGagandeep Singh ret = pfe_eth_enet_addr_byte_mac(addr->addr_bytes, &spec_addr); 734320ae324SGagandeep Singh if (ret) 735320ae324SGagandeep Singh return ret; 736320ae324SGagandeep Singh 737320ae324SGagandeep Singh gemac_set_laddrN(priv->EMAC_baseaddr, 738320ae324SGagandeep Singh (struct pfe_mac_addr *)&spec_addr, 1); 739320ae324SGagandeep Singh rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 740320ae324SGagandeep Singh return 0; 741320ae324SGagandeep Singh } 742320ae324SGagandeep Singh 743320ae324SGagandeep Singh static int 744659b494dSGagandeep Singh pfe_stats_get(struct rte_eth_dev *dev, 745659b494dSGagandeep Singh struct rte_eth_stats *stats) 746659b494dSGagandeep Singh { 747659b494dSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 748659b494dSGagandeep Singh struct rte_eth_stats *eth_stats = &priv->stats; 749659b494dSGagandeep Singh 750659b494dSGagandeep Singh if (stats == NULL) 751659b494dSGagandeep Singh return -1; 752659b494dSGagandeep Singh 753659b494dSGagandeep Singh memset(stats, 0, sizeof(struct rte_eth_stats)); 754659b494dSGagandeep Singh 755659b494dSGagandeep Singh stats->ipackets = eth_stats->ipackets; 756659b494dSGagandeep Singh stats->ibytes = eth_stats->ibytes; 757659b494dSGagandeep Singh stats->opackets = eth_stats->opackets; 758659b494dSGagandeep Singh stats->obytes = eth_stats->obytes; 759659b494dSGagandeep Singh 760659b494dSGagandeep Singh return 0; 761659b494dSGagandeep Singh } 762659b494dSGagandeep Singh 763fe38ad9bSGagandeep Singh static const struct eth_dev_ops ops = { 764fe38ad9bSGagandeep Singh .dev_start = pfe_eth_open, 765fe38ad9bSGagandeep Singh .dev_stop = pfe_eth_stop, 766fe38ad9bSGagandeep Singh .dev_close = pfe_eth_close, 767fe38ad9bSGagandeep Singh .dev_configure = pfe_eth_configure, 768fe38ad9bSGagandeep Singh .dev_infos_get = pfe_eth_info, 769592041a0SGagandeep Singh .rx_queue_setup = pfe_rx_queue_setup, 770592041a0SGagandeep Singh .rx_queue_release = pfe_rx_queue_release, 771592041a0SGagandeep Singh .tx_queue_setup = pfe_tx_queue_setup, 772592041a0SGagandeep Singh .tx_queue_release = pfe_tx_queue_release, 773659b494dSGagandeep Singh .dev_supported_ptypes_get = pfe_supported_ptypes_get, 774acd4818eSGagandeep Singh .link_update = pfe_eth_link_update, 775ff64beabSGagandeep Singh .promiscuous_enable = pfe_promiscuous_enable, 776ff64beabSGagandeep Singh .promiscuous_disable = pfe_promiscuous_disable, 777ff64beabSGagandeep Singh .allmulticast_enable = pfe_allmulticast_enable, 778acd4818eSGagandeep Singh .dev_set_link_down = pfe_link_down, 779acd4818eSGagandeep Singh .dev_set_link_up = pfe_link_up, 780320ae324SGagandeep Singh .mtu_set = pfe_mtu_set, 781320ae324SGagandeep Singh .mac_addr_set = pfe_dev_set_mac_addr, 782659b494dSGagandeep Singh .stats_get = pfe_stats_get, 783fe38ad9bSGagandeep Singh }; 784fe38ad9bSGagandeep Singh 78567fc3ff9SGagandeep Singh static int 78667fc3ff9SGagandeep Singh pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) 78767fc3ff9SGagandeep Singh { 78867fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 78967fc3ff9SGagandeep Singh struct pfe_eth_priv_s *priv = NULL; 7905253fe37SGagandeep Singh struct ls1012a_eth_platform_data *einfo; 7915253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pfe_info; 792320ae324SGagandeep Singh struct rte_ether_addr addr; 79367fc3ff9SGagandeep Singh int err; 79467fc3ff9SGagandeep Singh 79567fc3ff9SGagandeep Singh eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); 79667fc3ff9SGagandeep Singh if (eth_dev == NULL) 79767fc3ff9SGagandeep Singh return -ENOMEM; 79867fc3ff9SGagandeep Singh 7995253fe37SGagandeep Singh /* Extract pltform data */ 8005253fe37SGagandeep Singh pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data; 8015253fe37SGagandeep Singh if (!pfe_info) { 8025253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional platform data"); 8035253fe37SGagandeep Singh err = -ENODEV; 8045253fe37SGagandeep Singh goto err0; 8055253fe37SGagandeep Singh } 8065253fe37SGagandeep Singh 8075253fe37SGagandeep Singh einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata; 8085253fe37SGagandeep Singh 8095253fe37SGagandeep Singh /* einfo never be NULL, but no harm in having this check */ 8105253fe37SGagandeep Singh if (!einfo) { 8115253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional gemacs platform data"); 8125253fe37SGagandeep Singh err = -ENODEV; 8135253fe37SGagandeep Singh goto err0; 8145253fe37SGagandeep Singh } 8155253fe37SGagandeep Singh 81667fc3ff9SGagandeep Singh priv = eth_dev->data->dev_private; 81767fc3ff9SGagandeep Singh priv->ndev = eth_dev; 8185253fe37SGagandeep Singh priv->id = einfo[id].gem_id; 81967fc3ff9SGagandeep Singh priv->pfe = pfe; 82067fc3ff9SGagandeep Singh 82167fc3ff9SGagandeep Singh pfe->eth.eth_priv[id] = priv; 82267fc3ff9SGagandeep Singh 8235253fe37SGagandeep Singh /* Set the info in the priv to the current info */ 8245253fe37SGagandeep Singh priv->einfo = &einfo[id]; 8255253fe37SGagandeep Singh priv->EMAC_baseaddr = cbus_emac_base[id]; 8265253fe37SGagandeep Singh priv->PHY_baseaddr = cbus_emac_base[id]; 8275253fe37SGagandeep Singh priv->GPI_baseaddr = cbus_gpi_base[id]; 8285253fe37SGagandeep Singh 82967fc3ff9SGagandeep Singh #define HIF_GEMAC_TMUQ_BASE 6 83067fc3ff9SGagandeep Singh priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); 83167fc3ff9SGagandeep Singh priv->high_tmu_q = priv->low_tmu_q + 1; 83267fc3ff9SGagandeep Singh 83367fc3ff9SGagandeep Singh rte_spinlock_init(&priv->lock); 83467fc3ff9SGagandeep Singh 83567fc3ff9SGagandeep Singh /* Copy the station address into the dev structure, */ 83667fc3ff9SGagandeep Singh eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", 83767fc3ff9SGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS, 0); 83867fc3ff9SGagandeep Singh if (eth_dev->data->mac_addrs == NULL) { 839b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses", 840b1bc1afaSGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS); 84167fc3ff9SGagandeep Singh err = -ENOMEM; 84267fc3ff9SGagandeep Singh goto err0; 84367fc3ff9SGagandeep Singh } 84467fc3ff9SGagandeep Singh 845320ae324SGagandeep Singh memcpy(addr.addr_bytes, priv->einfo->mac_addr, 846320ae324SGagandeep Singh ETH_ALEN); 847320ae324SGagandeep Singh 848320ae324SGagandeep Singh pfe_dev_set_mac_addr(eth_dev, &addr); 849320ae324SGagandeep Singh rte_ether_addr_copy(&addr, ð_dev->data->mac_addrs[0]); 850320ae324SGagandeep Singh 85167fc3ff9SGagandeep Singh eth_dev->data->mtu = 1500; 852fe38ad9bSGagandeep Singh eth_dev->dev_ops = &ops; 853fe38ad9bSGagandeep Singh pfe_eth_stop(eth_dev); 8545253fe37SGagandeep Singh pfe_gemac_init(priv); 85567fc3ff9SGagandeep Singh 85667fc3ff9SGagandeep Singh eth_dev->data->nb_rx_queues = 1; 85767fc3ff9SGagandeep Singh eth_dev->data->nb_tx_queues = 1; 85867fc3ff9SGagandeep Singh 85967fc3ff9SGagandeep Singh /* For link status, open the PFE CDEV; Error from this function 86067fc3ff9SGagandeep Singh * is silently ignored; In case of error, the link status will not 86167fc3ff9SGagandeep Singh * be available. 86267fc3ff9SGagandeep Singh */ 86367fc3ff9SGagandeep Singh pfe_eth_open_cdev(priv); 86467fc3ff9SGagandeep Singh rte_eth_dev_probing_finish(eth_dev); 86567fc3ff9SGagandeep Singh 86667fc3ff9SGagandeep Singh return 0; 86767fc3ff9SGagandeep Singh err0: 86867fc3ff9SGagandeep Singh rte_eth_dev_release_port(eth_dev); 86967fc3ff9SGagandeep Singh return err; 87067fc3ff9SGagandeep Singh } 87167fc3ff9SGagandeep Singh 8725253fe37SGagandeep Singh static int 8735253fe37SGagandeep Singh pfe_get_gemac_if_proprties(struct pfe *pfe, 8745253fe37SGagandeep Singh __rte_unused const struct device_node *parent, 8755253fe37SGagandeep Singh unsigned int port, unsigned int if_cnt, 8765253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pdata) 8775253fe37SGagandeep Singh { 8785253fe37SGagandeep Singh const struct device_node *gem = NULL; 8795253fe37SGagandeep Singh size_t size; 8805253fe37SGagandeep Singh unsigned int ii = 0, phy_id = 0; 8815253fe37SGagandeep Singh const u32 *addr; 8825253fe37SGagandeep Singh const void *mac_addr; 8835253fe37SGagandeep Singh 8845253fe37SGagandeep Singh for (ii = 0; ii < if_cnt; ii++) { 8855253fe37SGagandeep Singh gem = of_get_next_child(parent, gem); 8865253fe37SGagandeep Singh if (!gem) 8875253fe37SGagandeep Singh goto err; 8885253fe37SGagandeep Singh addr = of_get_property(gem, "reg", &size); 8895253fe37SGagandeep Singh if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port)) 8905253fe37SGagandeep Singh break; 8915253fe37SGagandeep Singh } 8925253fe37SGagandeep Singh 8935253fe37SGagandeep Singh if (ii >= if_cnt) { 8945253fe37SGagandeep Singh PFE_PMD_ERR("Failed to find interface = %d", if_cnt); 8955253fe37SGagandeep Singh goto err; 8965253fe37SGagandeep Singh } 8975253fe37SGagandeep Singh 8985253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].gem_id = port; 8995253fe37SGagandeep Singh 9005253fe37SGagandeep Singh mac_addr = of_get_mac_address(gem); 9015253fe37SGagandeep Singh 9025253fe37SGagandeep Singh if (mac_addr) { 9035253fe37SGagandeep Singh memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, 9045253fe37SGagandeep Singh ETH_ALEN); 9055253fe37SGagandeep Singh } 9065253fe37SGagandeep Singh 9075253fe37SGagandeep Singh addr = of_get_property(gem, "fsl,mdio-mux-val", &size); 9085253fe37SGagandeep Singh if (!addr) { 9095253fe37SGagandeep Singh PFE_PMD_ERR("Invalid mdio-mux-val...."); 9105253fe37SGagandeep Singh } else { 9115253fe37SGagandeep Singh phy_id = rte_be_to_cpu_32((unsigned int)*addr); 9125253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; 9135253fe37SGagandeep Singh } 9145253fe37SGagandeep Singh if (pdata->ls1012a_eth_pdata[port].phy_id < 32) 9155253fe37SGagandeep Singh pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = 9165253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval; 9175253fe37SGagandeep Singh 9185253fe37SGagandeep Singh return 0; 9195253fe37SGagandeep Singh 9205253fe37SGagandeep Singh err: 9215253fe37SGagandeep Singh return -1; 9225253fe37SGagandeep Singh } 9235253fe37SGagandeep Singh 92467fc3ff9SGagandeep Singh /* Parse integer from integer argument */ 92567fc3ff9SGagandeep Singh static int 92667fc3ff9SGagandeep Singh parse_integer_arg(const char *key __rte_unused, 92767fc3ff9SGagandeep Singh const char *value, void *extra_args) 92867fc3ff9SGagandeep Singh { 92967fc3ff9SGagandeep Singh int i; 93067fc3ff9SGagandeep Singh char *end; 93167fc3ff9SGagandeep Singh errno = 0; 93267fc3ff9SGagandeep Singh 93367fc3ff9SGagandeep Singh i = strtol(value, &end, 10); 934b1bc1afaSGagandeep Singh if (*end != 0 || errno != 0 || i < 0 || i > 1) { 935b1bc1afaSGagandeep Singh PFE_PMD_ERR("Supported Port IDS are 0 and 1"); 93667fc3ff9SGagandeep Singh return -EINVAL; 937b1bc1afaSGagandeep Singh } 93867fc3ff9SGagandeep Singh 93967fc3ff9SGagandeep Singh *((uint32_t *)extra_args) = i; 94067fc3ff9SGagandeep Singh 94167fc3ff9SGagandeep Singh return 0; 94267fc3ff9SGagandeep Singh } 94367fc3ff9SGagandeep Singh 94467fc3ff9SGagandeep Singh static int 94567fc3ff9SGagandeep Singh pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params, 94667fc3ff9SGagandeep Singh struct rte_vdev_device *dev) 94767fc3ff9SGagandeep Singh { 94867fc3ff9SGagandeep Singh struct rte_kvargs *kvlist = NULL; 94967fc3ff9SGagandeep Singh int ret = 0; 95067fc3ff9SGagandeep Singh 95167fc3ff9SGagandeep Singh static const char * const pfe_vdev_valid_params[] = { 95267fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 95367fc3ff9SGagandeep Singh NULL 95467fc3ff9SGagandeep Singh }; 95567fc3ff9SGagandeep Singh 95667fc3ff9SGagandeep Singh const char *input_args = rte_vdev_device_args(dev); 95767fc3ff9SGagandeep Singh 95867fc3ff9SGagandeep Singh if (!input_args) 95967fc3ff9SGagandeep Singh return -1; 96067fc3ff9SGagandeep Singh 96167fc3ff9SGagandeep Singh kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params); 96267fc3ff9SGagandeep Singh if (kvlist == NULL) 96367fc3ff9SGagandeep Singh return -1; 96467fc3ff9SGagandeep Singh 96567fc3ff9SGagandeep Singh ret = rte_kvargs_process(kvlist, 96667fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 96767fc3ff9SGagandeep Singh &parse_integer_arg, 96867fc3ff9SGagandeep Singh ¶ms->gem_id); 96967fc3ff9SGagandeep Singh rte_kvargs_free(kvlist); 97067fc3ff9SGagandeep Singh return ret; 97167fc3ff9SGagandeep Singh } 97267fc3ff9SGagandeep Singh 97367fc3ff9SGagandeep Singh static int 97467fc3ff9SGagandeep Singh pmd_pfe_probe(struct rte_vdev_device *vdev) 97567fc3ff9SGagandeep Singh { 97667fc3ff9SGagandeep Singh const u32 *prop; 97767fc3ff9SGagandeep Singh const struct device_node *np; 97867fc3ff9SGagandeep Singh const char *name; 97967fc3ff9SGagandeep Singh const uint32_t *addr; 98067fc3ff9SGagandeep Singh uint64_t cbus_addr, ddr_size, cbus_size; 98167fc3ff9SGagandeep Singh int rc = -1, fd = -1, gem_id; 9825253fe37SGagandeep Singh unsigned int ii, interface_count = 0; 98367fc3ff9SGagandeep Singh size_t size = 0; 98467fc3ff9SGagandeep Singh struct pfe_vdev_init_params init_params = { 98567fc3ff9SGagandeep Singh .gem_id = -1 98667fc3ff9SGagandeep Singh }; 98767fc3ff9SGagandeep Singh 98867fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 98967fc3ff9SGagandeep Singh rc = pfe_parse_vdev_init_params(&init_params, vdev); 99067fc3ff9SGagandeep Singh if (rc < 0) 99167fc3ff9SGagandeep Singh return -EINVAL; 99267fc3ff9SGagandeep Singh 993b1bc1afaSGagandeep Singh RTE_LOG(INFO, PMD, "Initializing pmd_pfe for %s Given gem-id %d\n", 994b1bc1afaSGagandeep Singh name, init_params.gem_id); 99567fc3ff9SGagandeep Singh 996b1bc1afaSGagandeep Singh if (g_pfe) { 997b1bc1afaSGagandeep Singh if (g_pfe->nb_devs >= g_pfe->max_intf) { 998b1bc1afaSGagandeep Singh PFE_PMD_ERR("PFE %d dev already created Max is %d", 999b1bc1afaSGagandeep Singh g_pfe->nb_devs, g_pfe->max_intf); 1000b1bc1afaSGagandeep Singh return -EINVAL; 1001b1bc1afaSGagandeep Singh } 100267fc3ff9SGagandeep Singh goto eth_init; 100367fc3ff9SGagandeep Singh } 100467fc3ff9SGagandeep Singh 100567fc3ff9SGagandeep Singh g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE); 100667fc3ff9SGagandeep Singh if (g_pfe == NULL) 100767fc3ff9SGagandeep Singh return -EINVAL; 100867fc3ff9SGagandeep Singh 100967fc3ff9SGagandeep Singh /* Load the device-tree driver */ 101067fc3ff9SGagandeep Singh rc = of_init(); 1011b1bc1afaSGagandeep Singh if (rc) { 1012b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_init failed with ret: %d", rc); 101367fc3ff9SGagandeep Singh goto err; 1014b1bc1afaSGagandeep Singh } 101567fc3ff9SGagandeep Singh 101667fc3ff9SGagandeep Singh np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); 101767fc3ff9SGagandeep Singh if (!np) { 1018b1bc1afaSGagandeep Singh PFE_PMD_ERR("Invalid device node"); 101967fc3ff9SGagandeep Singh rc = -EINVAL; 102067fc3ff9SGagandeep Singh goto err; 102167fc3ff9SGagandeep Singh } 102267fc3ff9SGagandeep Singh 102367fc3ff9SGagandeep Singh addr = of_get_address(np, 0, &cbus_size, NULL); 1024b1bc1afaSGagandeep Singh if (!addr) { 1025b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_get_address cannot return qman address\n"); 102667fc3ff9SGagandeep Singh goto err; 1027b1bc1afaSGagandeep Singh } 102867fc3ff9SGagandeep Singh cbus_addr = of_translate_address(np, addr); 1029b1bc1afaSGagandeep Singh if (!cbus_addr) { 1030b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_translate_address failed\n"); 103167fc3ff9SGagandeep Singh goto err; 1032b1bc1afaSGagandeep Singh } 103367fc3ff9SGagandeep Singh 103467fc3ff9SGagandeep Singh addr = of_get_address(np, 1, &ddr_size, NULL); 1035b1bc1afaSGagandeep Singh if (!addr) { 1036b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_get_address cannot return qman address\n"); 103767fc3ff9SGagandeep Singh goto err; 1038b1bc1afaSGagandeep Singh } 103967fc3ff9SGagandeep Singh 104067fc3ff9SGagandeep Singh g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); 1041b1bc1afaSGagandeep Singh if (!g_pfe->ddr_phys_baseaddr) { 1042b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_translate_address failed\n"); 104367fc3ff9SGagandeep Singh goto err; 1044b1bc1afaSGagandeep Singh } 104567fc3ff9SGagandeep Singh 10465253fe37SGagandeep Singh g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr); 104767fc3ff9SGagandeep Singh g_pfe->ddr_size = ddr_size; 104867fc3ff9SGagandeep Singh g_pfe->cbus_size = cbus_size; 104967fc3ff9SGagandeep Singh 105067fc3ff9SGagandeep Singh fd = open("/dev/mem", O_RDWR); 105167fc3ff9SGagandeep Singh g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, 105267fc3ff9SGagandeep Singh MAP_SHARED, fd, cbus_addr); 105367fc3ff9SGagandeep Singh close(fd); 105467fc3ff9SGagandeep Singh if (g_pfe->cbus_baseaddr == MAP_FAILED) { 1055b1bc1afaSGagandeep Singh PFE_PMD_ERR("Can not map cbus base"); 105667fc3ff9SGagandeep Singh rc = -EINVAL; 105767fc3ff9SGagandeep Singh goto err; 105867fc3ff9SGagandeep Singh } 105967fc3ff9SGagandeep Singh 106067fc3ff9SGagandeep Singh /* Read interface count */ 106167fc3ff9SGagandeep Singh prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); 106267fc3ff9SGagandeep Singh if (!prop) { 1063b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to read number of interfaces"); 106467fc3ff9SGagandeep Singh rc = -ENXIO; 106567fc3ff9SGagandeep Singh goto err_prop; 106667fc3ff9SGagandeep Singh } 106767fc3ff9SGagandeep Singh 106867fc3ff9SGagandeep Singh interface_count = rte_be_to_cpu_32((unsigned int)*prop); 106967fc3ff9SGagandeep Singh if (interface_count <= 0) { 1070b1bc1afaSGagandeep Singh PFE_PMD_ERR("No ethernet interface count : %d", 1071b1bc1afaSGagandeep Singh interface_count); 107267fc3ff9SGagandeep Singh rc = -ENXIO; 107367fc3ff9SGagandeep Singh goto err_prop; 107467fc3ff9SGagandeep Singh } 1075b1bc1afaSGagandeep Singh PFE_PMD_INFO("num interfaces = %d ", interface_count); 1076b1bc1afaSGagandeep Singh 107767fc3ff9SGagandeep Singh g_pfe->max_intf = interface_count; 10785253fe37SGagandeep Singh g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; 10795253fe37SGagandeep Singh 10805253fe37SGagandeep Singh for (ii = 0; ii < interface_count; ii++) { 10815253fe37SGagandeep Singh pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count, 10825253fe37SGagandeep Singh &g_pfe->platform_data); 10835253fe37SGagandeep Singh } 10845253fe37SGagandeep Singh 10855253fe37SGagandeep Singh pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr, 10865253fe37SGagandeep Singh g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size); 10875253fe37SGagandeep Singh 10885253fe37SGagandeep Singh PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION)); 10895253fe37SGagandeep Singh PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION)); 10905253fe37SGagandeep Singh 10915253fe37SGagandeep Singh PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION)); 10925253fe37SGagandeep Singh PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION)); 10935253fe37SGagandeep Singh 10945253fe37SGagandeep Singh PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION)); 10955253fe37SGagandeep Singh PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION)); 10965253fe37SGagandeep Singh PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION)); 10975253fe37SGagandeep Singh 10985253fe37SGagandeep Singh PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION)); 10995253fe37SGagandeep Singh PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION)); 11005253fe37SGagandeep Singh 11015253fe37SGagandeep Singh cbus_emac_base[0] = EMAC1_BASE_ADDR; 11025253fe37SGagandeep Singh cbus_emac_base[1] = EMAC2_BASE_ADDR; 11035253fe37SGagandeep Singh 11045253fe37SGagandeep Singh cbus_gpi_base[0] = EGPI1_BASE_ADDR; 11055253fe37SGagandeep Singh cbus_gpi_base[1] = EGPI2_BASE_ADDR; 11065253fe37SGagandeep Singh 11075253fe37SGagandeep Singh rc = pfe_hif_lib_init(g_pfe); 11085253fe37SGagandeep Singh if (rc < 0) 11095253fe37SGagandeep Singh goto err_hif_lib; 11105253fe37SGagandeep Singh 11115253fe37SGagandeep Singh rc = pfe_hif_init(g_pfe); 11125253fe37SGagandeep Singh if (rc < 0) 11135253fe37SGagandeep Singh goto err_hif; 111467fc3ff9SGagandeep Singh pfe_soc_version_get(); 111567fc3ff9SGagandeep Singh eth_init: 111667fc3ff9SGagandeep Singh if (init_params.gem_id < 0) 111767fc3ff9SGagandeep Singh gem_id = g_pfe->nb_devs; 111867fc3ff9SGagandeep Singh else 111967fc3ff9SGagandeep Singh gem_id = init_params.gem_id; 112067fc3ff9SGagandeep Singh 112167fc3ff9SGagandeep Singh RTE_LOG(INFO, PMD, "Init pmd_pfe for %s gem-id %d(given =%d)\n", 112267fc3ff9SGagandeep Singh name, gem_id, init_params.gem_id); 112367fc3ff9SGagandeep Singh 112467fc3ff9SGagandeep Singh rc = pfe_eth_init(vdev, g_pfe, gem_id); 112567fc3ff9SGagandeep Singh if (rc < 0) 112667fc3ff9SGagandeep Singh goto err_eth; 112767fc3ff9SGagandeep Singh else 112867fc3ff9SGagandeep Singh g_pfe->nb_devs++; 112967fc3ff9SGagandeep Singh 113067fc3ff9SGagandeep Singh return 0; 113167fc3ff9SGagandeep Singh 113267fc3ff9SGagandeep Singh err_eth: 11335253fe37SGagandeep Singh pfe_hif_exit(g_pfe); 11345253fe37SGagandeep Singh 11355253fe37SGagandeep Singh err_hif: 11365253fe37SGagandeep Singh pfe_hif_lib_exit(g_pfe); 11375253fe37SGagandeep Singh 11385253fe37SGagandeep Singh err_hif_lib: 113967fc3ff9SGagandeep Singh err_prop: 114067fc3ff9SGagandeep Singh munmap(g_pfe->cbus_baseaddr, cbus_size); 114167fc3ff9SGagandeep Singh err: 114267fc3ff9SGagandeep Singh rte_free(g_pfe); 114367fc3ff9SGagandeep Singh return rc; 114467fc3ff9SGagandeep Singh } 114567fc3ff9SGagandeep Singh 114667fc3ff9SGagandeep Singh static int 114767fc3ff9SGagandeep Singh pmd_pfe_remove(struct rte_vdev_device *vdev) 114867fc3ff9SGagandeep Singh { 114967fc3ff9SGagandeep Singh const char *name; 115067fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 115167fc3ff9SGagandeep Singh 115267fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 115367fc3ff9SGagandeep Singh if (name == NULL) 115467fc3ff9SGagandeep Singh return -EINVAL; 115567fc3ff9SGagandeep Singh 1156b1bc1afaSGagandeep Singh PFE_PMD_INFO("Closing eventdev sw device %s", name); 1157b1bc1afaSGagandeep Singh 115867fc3ff9SGagandeep Singh if (!g_pfe) 115967fc3ff9SGagandeep Singh return 0; 116067fc3ff9SGagandeep Singh 116167fc3ff9SGagandeep Singh eth_dev = rte_eth_dev_allocated(name); 116267fc3ff9SGagandeep Singh if (eth_dev == NULL) 116367fc3ff9SGagandeep Singh return -ENODEV; 116467fc3ff9SGagandeep Singh 116567fc3ff9SGagandeep Singh pfe_eth_exit(eth_dev, g_pfe); 116667fc3ff9SGagandeep Singh munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size); 116767fc3ff9SGagandeep Singh 11685253fe37SGagandeep Singh if (g_pfe->nb_devs == 0) { 11695253fe37SGagandeep Singh pfe_hif_exit(g_pfe); 11705253fe37SGagandeep Singh pfe_hif_lib_exit(g_pfe); 11715253fe37SGagandeep Singh rte_free(g_pfe); 11725253fe37SGagandeep Singh g_pfe = NULL; 11735253fe37SGagandeep Singh } 117467fc3ff9SGagandeep Singh return 0; 117567fc3ff9SGagandeep Singh } 117667fc3ff9SGagandeep Singh 117767fc3ff9SGagandeep Singh static 117867fc3ff9SGagandeep Singh struct rte_vdev_driver pmd_pfe_drv = { 117967fc3ff9SGagandeep Singh .probe = pmd_pfe_probe, 118067fc3ff9SGagandeep Singh .remove = pmd_pfe_remove, 118167fc3ff9SGagandeep Singh }; 118267fc3ff9SGagandeep Singh 118367fc3ff9SGagandeep Singh RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); 118467fc3ff9SGagandeep Singh RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> "); 1185b1bc1afaSGagandeep Singh 1186b1bc1afaSGagandeep Singh RTE_INIT(pfe_pmd_init_log) 1187b1bc1afaSGagandeep Singh { 1188b1bc1afaSGagandeep Singh pfe_logtype_pmd = rte_log_register("pmd.net.pfe"); 1189b1bc1afaSGagandeep Singh if (pfe_logtype_pmd >= 0) 1190b1bc1afaSGagandeep Singh rte_log_set_level(pfe_logtype_pmd, RTE_LOG_NOTICE); 1191b1bc1afaSGagandeep Singh } 1192