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> 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 up to 4 MACs per IF */ 1767fc3ff9SGagandeep Singh #define PFE_VDEV_GEM_ID_ARG "intf" 1867fc3ff9SGagandeep Singh 1967fc3ff9SGagandeep Singh struct pfe_vdev_init_params { 2067fc3ff9SGagandeep Singh int8_t gem_id; 2167fc3ff9SGagandeep Singh }; 2267fc3ff9SGagandeep Singh static struct pfe *g_pfe; 23592041a0SGagandeep Singh /* Supported Rx offloads */ 24592041a0SGagandeep Singh static uint64_t dev_rx_offloads_sup = 25592041a0SGagandeep Singh DEV_RX_OFFLOAD_IPV4_CKSUM | 26592041a0SGagandeep Singh DEV_RX_OFFLOAD_UDP_CKSUM | 27592041a0SGagandeep Singh DEV_RX_OFFLOAD_TCP_CKSUM; 28592041a0SGagandeep Singh 29592041a0SGagandeep Singh /* Supported Tx offloads */ 30592041a0SGagandeep Singh static uint64_t dev_tx_offloads_sup = 31592041a0SGagandeep Singh DEV_TX_OFFLOAD_IPV4_CKSUM | 32592041a0SGagandeep Singh DEV_TX_OFFLOAD_UDP_CKSUM | 33592041a0SGagandeep Singh DEV_TX_OFFLOAD_TCP_CKSUM; 3467fc3ff9SGagandeep Singh 3567fc3ff9SGagandeep Singh /* TODO: make pfe_svr a runtime option. 3667fc3ff9SGagandeep Singh * Driver should be able to get the SVR 3767fc3ff9SGagandeep Singh * information from HW. 3867fc3ff9SGagandeep Singh */ 3967fc3ff9SGagandeep Singh unsigned int pfe_svr = SVR_LS1012A_REV1; 405253fe37SGagandeep Singh static void *cbus_emac_base[3]; 415253fe37SGagandeep Singh static void *cbus_gpi_base[3]; 4267fc3ff9SGagandeep Singh 435253fe37SGagandeep Singh /* pfe_gemac_init 445253fe37SGagandeep Singh */ 455253fe37SGagandeep Singh static int 465253fe37SGagandeep Singh pfe_gemac_init(struct pfe_eth_priv_s *priv) 475253fe37SGagandeep Singh { 485253fe37SGagandeep Singh struct gemac_cfg cfg; 495253fe37SGagandeep Singh 505253fe37SGagandeep Singh cfg.speed = SPEED_1000M; 515253fe37SGagandeep Singh cfg.duplex = DUPLEX_FULL; 525253fe37SGagandeep Singh 535253fe37SGagandeep Singh gemac_set_config(priv->EMAC_baseaddr, &cfg); 545253fe37SGagandeep Singh gemac_allow_broadcast(priv->EMAC_baseaddr); 555253fe37SGagandeep Singh gemac_enable_1536_rx(priv->EMAC_baseaddr); 565253fe37SGagandeep Singh gemac_enable_stacked_vlan(priv->EMAC_baseaddr); 575253fe37SGagandeep Singh gemac_enable_pause_rx(priv->EMAC_baseaddr); 585253fe37SGagandeep Singh gemac_set_bus_width(priv->EMAC_baseaddr, 64); 595253fe37SGagandeep Singh gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); 605253fe37SGagandeep Singh 615253fe37SGagandeep Singh return 0; 625253fe37SGagandeep Singh } 635253fe37SGagandeep Singh 6467fc3ff9SGagandeep Singh static void 6567fc3ff9SGagandeep Singh pfe_soc_version_get(void) 6667fc3ff9SGagandeep Singh { 6767fc3ff9SGagandeep Singh FILE *svr_file = NULL; 6867fc3ff9SGagandeep Singh unsigned int svr_ver = 0; 6967fc3ff9SGagandeep Singh 70b1bc1afaSGagandeep Singh PMD_INIT_FUNC_TRACE(); 71b1bc1afaSGagandeep Singh 7267fc3ff9SGagandeep Singh svr_file = fopen(PFE_SOC_ID_FILE, "r"); 73b1bc1afaSGagandeep Singh if (!svr_file) { 74b1bc1afaSGagandeep Singh PFE_PMD_ERR("Unable to open SoC device"); 7567fc3ff9SGagandeep Singh return; /* Not supported on this infra */ 76b1bc1afaSGagandeep Singh } 7767fc3ff9SGagandeep Singh 7867fc3ff9SGagandeep Singh if (fscanf(svr_file, "svr:%x", &svr_ver) > 0) 7967fc3ff9SGagandeep Singh pfe_svr = svr_ver; 8067fc3ff9SGagandeep Singh else 81b1bc1afaSGagandeep Singh PFE_PMD_ERR("Unable to read SoC device"); 8267fc3ff9SGagandeep Singh 8367fc3ff9SGagandeep Singh fclose(svr_file); 8467fc3ff9SGagandeep Singh } 8567fc3ff9SGagandeep Singh 86fe38ad9bSGagandeep Singh static int pfe_eth_start(struct pfe_eth_priv_s *priv) 87fe38ad9bSGagandeep Singh { 88fe38ad9bSGagandeep Singh gpi_enable(priv->GPI_baseaddr); 89fe38ad9bSGagandeep Singh gemac_enable(priv->EMAC_baseaddr); 90fe38ad9bSGagandeep Singh 91fe38ad9bSGagandeep Singh return 0; 92fe38ad9bSGagandeep Singh } 93fe38ad9bSGagandeep Singh 94fe38ad9bSGagandeep Singh static void 95fe38ad9bSGagandeep Singh pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int 96fe38ad9bSGagandeep Singh __rte_unused from_tx, __rte_unused int n_desc) 97fe38ad9bSGagandeep Singh { 98fe38ad9bSGagandeep Singh struct rte_mbuf *mbuf; 99fe38ad9bSGagandeep Singh unsigned int flags; 100fe38ad9bSGagandeep Singh 101fe38ad9bSGagandeep Singh /* Clean HIF and client queue */ 102fe38ad9bSGagandeep Singh while ((mbuf = hif_lib_tx_get_next_complete(&priv->client, 103fe38ad9bSGagandeep Singh tx_q_num, &flags, 104fe38ad9bSGagandeep Singh HIF_TX_DESC_NT))) { 105fe38ad9bSGagandeep Singh if (mbuf) { 106fe38ad9bSGagandeep Singh mbuf->next = NULL; 107fe38ad9bSGagandeep Singh mbuf->nb_segs = 1; 108fe38ad9bSGagandeep Singh rte_pktmbuf_free(mbuf); 109fe38ad9bSGagandeep Singh } 110fe38ad9bSGagandeep Singh } 111fe38ad9bSGagandeep Singh } 112fe38ad9bSGagandeep Singh 113fe38ad9bSGagandeep Singh 114fe38ad9bSGagandeep Singh static void 115fe38ad9bSGagandeep Singh pfe_eth_flush_tx(struct pfe_eth_priv_s *priv) 116fe38ad9bSGagandeep Singh { 117fe38ad9bSGagandeep Singh unsigned int ii; 118fe38ad9bSGagandeep Singh 119fe38ad9bSGagandeep Singh for (ii = 0; ii < emac_txq_cnt; ii++) 120fe38ad9bSGagandeep Singh pfe_eth_flush_txQ(priv, ii, 0, 0); 121fe38ad9bSGagandeep Singh } 122fe38ad9bSGagandeep Singh 123fe38ad9bSGagandeep Singh static int 124fe38ad9bSGagandeep Singh pfe_eth_event_handler(void *data, int event, __rte_unused int qno) 125fe38ad9bSGagandeep Singh { 126fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = data; 127fe38ad9bSGagandeep Singh 128fe38ad9bSGagandeep Singh switch (event) { 129fe38ad9bSGagandeep Singh case EVENT_TXDONE_IND: 130fe38ad9bSGagandeep Singh pfe_eth_flush_tx(priv); 131fe38ad9bSGagandeep Singh hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0); 132fe38ad9bSGagandeep Singh break; 133fe38ad9bSGagandeep Singh case EVENT_HIGH_RX_WM: 134fe38ad9bSGagandeep Singh default: 135fe38ad9bSGagandeep Singh break; 136fe38ad9bSGagandeep Singh } 137fe38ad9bSGagandeep Singh 138fe38ad9bSGagandeep Singh return 0; 139fe38ad9bSGagandeep Singh } 140fe38ad9bSGagandeep Singh 14136220514SGagandeep Singh static uint16_t 14236220514SGagandeep Singh pfe_recv_pkts_on_intr(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 14336220514SGagandeep Singh { 14436220514SGagandeep Singh struct hif_client_rx_queue *queue = rxq; 14536220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 14636220514SGagandeep Singh struct epoll_event epoll_ev; 14736220514SGagandeep Singh uint64_t ticks = 1; /* 1 msec */ 14836220514SGagandeep Singh int ret; 14936220514SGagandeep Singh int have_something, work_done; 15036220514SGagandeep Singh 15136220514SGagandeep Singh #define RESET_STATUS (HIF_INT | HIF_RXPKT_INT) 15236220514SGagandeep Singh 15336220514SGagandeep Singh /*TODO can we remove this cleanup from here?*/ 15436220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 15536220514SGagandeep Singh have_something = pfe_hif_rx_process(priv->pfe, nb_pkts); 15636220514SGagandeep Singh work_done = hif_lib_receive_pkt(rxq, priv->pfe->hif.shm->pool, 15736220514SGagandeep Singh rx_pkts, nb_pkts); 15836220514SGagandeep Singh 15936220514SGagandeep Singh if (!have_something || !work_done) { 16036220514SGagandeep Singh writel(RESET_STATUS, HIF_INT_SRC); 16136220514SGagandeep Singh writel(readl(HIF_INT_ENABLE) | HIF_RXPKT_INT, HIF_INT_ENABLE); 16236220514SGagandeep Singh ret = epoll_wait(priv->pfe->hif.epoll_fd, &epoll_ev, 1, ticks); 16336220514SGagandeep Singh if (ret < 0 && errno != EINTR) 16436220514SGagandeep Singh PFE_PMD_ERR("epoll_wait fails with %d\n", errno); 16536220514SGagandeep Singh } 16636220514SGagandeep Singh 16736220514SGagandeep Singh return work_done; 16836220514SGagandeep Singh } 16936220514SGagandeep Singh 17036220514SGagandeep Singh static uint16_t 17136220514SGagandeep Singh pfe_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 17236220514SGagandeep Singh { 17336220514SGagandeep Singh struct hif_client_rx_queue *queue = rxq; 17436220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 17536220514SGagandeep Singh struct rte_mempool *pool; 17636220514SGagandeep Singh 17736220514SGagandeep Singh /*TODO can we remove this cleanup from here?*/ 17836220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 17936220514SGagandeep Singh pfe_hif_rx_process(priv->pfe, nb_pkts); 18036220514SGagandeep Singh pool = priv->pfe->hif.shm->pool; 18136220514SGagandeep Singh 18236220514SGagandeep Singh return hif_lib_receive_pkt(rxq, pool, rx_pkts, nb_pkts); 18336220514SGagandeep Singh } 18436220514SGagandeep Singh 18536220514SGagandeep Singh static uint16_t 18636220514SGagandeep Singh pfe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 18736220514SGagandeep Singh { 18836220514SGagandeep Singh struct hif_client_tx_queue *queue = tx_queue; 18936220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 19036220514SGagandeep Singh struct rte_eth_stats *stats = &priv->stats; 19136220514SGagandeep Singh int i; 19236220514SGagandeep Singh 19336220514SGagandeep Singh for (i = 0; i < nb_pkts; i++) { 19436220514SGagandeep Singh if (tx_pkts[i]->nb_segs > 1) { 19536220514SGagandeep Singh struct rte_mbuf *mbuf; 19636220514SGagandeep Singh int j; 19736220514SGagandeep Singh 19836220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 19936220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 20036220514SGagandeep Singh tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 20136220514SGagandeep Singh tx_pkts[i]->data_len, 0x0, HIF_FIRST_BUFFER, 20236220514SGagandeep Singh tx_pkts[i]); 20336220514SGagandeep Singh 20436220514SGagandeep Singh mbuf = tx_pkts[i]->next; 20536220514SGagandeep Singh for (j = 0; j < (tx_pkts[i]->nb_segs - 2); j++) { 20636220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 20736220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(mbuf), 20836220514SGagandeep Singh mbuf->buf_addr + mbuf->data_off, 20936220514SGagandeep Singh mbuf->data_len, 21036220514SGagandeep Singh 0x0, 0x0, mbuf); 21136220514SGagandeep Singh mbuf = mbuf->next; 21236220514SGagandeep Singh } 21336220514SGagandeep Singh 21436220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 21536220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(mbuf), 21636220514SGagandeep Singh mbuf->buf_addr + mbuf->data_off, 21736220514SGagandeep Singh mbuf->data_len, 21836220514SGagandeep Singh 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID, 21936220514SGagandeep Singh mbuf); 22036220514SGagandeep Singh } else { 22136220514SGagandeep Singh hif_lib_xmit_pkt(&priv->client, queue->queue_id, 22236220514SGagandeep Singh (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 22336220514SGagandeep Singh tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 22436220514SGagandeep Singh tx_pkts[i]->pkt_len, 0 /*ctrl*/, 22536220514SGagandeep Singh HIF_FIRST_BUFFER | HIF_LAST_BUFFER | 22636220514SGagandeep Singh HIF_DATA_VALID, 22736220514SGagandeep Singh tx_pkts[i]); 22836220514SGagandeep Singh } 22936220514SGagandeep Singh stats->obytes += tx_pkts[i]->pkt_len; 23036220514SGagandeep Singh hif_tx_dma_start(); 23136220514SGagandeep Singh } 23236220514SGagandeep Singh stats->opackets += nb_pkts; 23336220514SGagandeep Singh pfe_tx_do_cleanup(priv->pfe); 23436220514SGagandeep Singh 23536220514SGagandeep Singh return nb_pkts; 23636220514SGagandeep Singh } 23736220514SGagandeep Singh 23836220514SGagandeep Singh static uint16_t 23936220514SGagandeep Singh pfe_dummy_xmit_pkts(__rte_unused void *tx_queue, 24036220514SGagandeep Singh __rte_unused struct rte_mbuf **tx_pkts, 24136220514SGagandeep Singh __rte_unused uint16_t nb_pkts) 24236220514SGagandeep Singh { 24336220514SGagandeep Singh return 0; 24436220514SGagandeep Singh } 24536220514SGagandeep Singh 24636220514SGagandeep Singh static uint16_t 24736220514SGagandeep Singh pfe_dummy_recv_pkts(__rte_unused void *rxq, 24836220514SGagandeep Singh __rte_unused struct rte_mbuf **rx_pkts, 24936220514SGagandeep Singh __rte_unused uint16_t nb_pkts) 25036220514SGagandeep Singh { 25136220514SGagandeep Singh return 0; 25236220514SGagandeep Singh } 25336220514SGagandeep Singh 254fe38ad9bSGagandeep Singh static int 255fe38ad9bSGagandeep Singh pfe_eth_open(struct rte_eth_dev *dev) 256fe38ad9bSGagandeep Singh { 257fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 258fe38ad9bSGagandeep Singh struct hif_client_s *client; 259fe38ad9bSGagandeep Singh struct hif_shm *hif_shm; 260fe38ad9bSGagandeep Singh int rc; 261fe38ad9bSGagandeep Singh 262fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 263fe38ad9bSGagandeep Singh client = &priv->client; 264fe38ad9bSGagandeep Singh 265fe38ad9bSGagandeep Singh if (client->pfe) { 266fe38ad9bSGagandeep Singh hif_shm = client->pfe->hif.shm; 267fe38ad9bSGagandeep Singh /* TODO please remove the below code of if block, once we add 268fe38ad9bSGagandeep Singh * the proper cleanup in eth_close 269fe38ad9bSGagandeep Singh */ 270fe38ad9bSGagandeep Singh if (!test_bit(PFE_CL_GEM0 + priv->id, 271fe38ad9bSGagandeep Singh &hif_shm->g_client_status[0])) { 272fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 273fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 274fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 275fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 276fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 277fe38ad9bSGagandeep Singh client->priv = priv; 278fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 279fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 280fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 281fe38ad9bSGagandeep Singh 282fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 283fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 284fe38ad9bSGagandeep Singh 285fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 286fe38ad9bSGagandeep Singh if (rc) { 287fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d)" 288fe38ad9bSGagandeep Singh " failed", client->id); 289fe38ad9bSGagandeep Singh goto err0; 290fe38ad9bSGagandeep Singh } 29136220514SGagandeep Singh } else { 29236220514SGagandeep Singh /* Freeing the packets if already exists */ 29336220514SGagandeep Singh int ret = 0; 29436220514SGagandeep Singh struct rte_mbuf *rx_pkts[32]; 29536220514SGagandeep Singh /* TODO multiqueue support */ 29636220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 29736220514SGagandeep Singh hif_shm->pool, rx_pkts, 32); 29836220514SGagandeep Singh while (ret) { 29936220514SGagandeep Singh int i; 30036220514SGagandeep Singh for (i = 0; i < ret; i++) 30136220514SGagandeep Singh rte_pktmbuf_free(rx_pkts[i]); 30236220514SGagandeep Singh ret = hif_lib_receive_pkt(&client->rx_q[0], 30336220514SGagandeep Singh hif_shm->pool, 30436220514SGagandeep Singh rx_pkts, 32); 30536220514SGagandeep Singh } 306fe38ad9bSGagandeep Singh } 307fe38ad9bSGagandeep Singh } else { 308fe38ad9bSGagandeep Singh /* Register client driver with HIF */ 309fe38ad9bSGagandeep Singh memset(client, 0, sizeof(*client)); 310fe38ad9bSGagandeep Singh client->id = PFE_CL_GEM0 + priv->id; 311fe38ad9bSGagandeep Singh client->tx_qn = emac_txq_cnt; 312fe38ad9bSGagandeep Singh client->rx_qn = EMAC_RXQ_CNT; 313fe38ad9bSGagandeep Singh client->priv = priv; 314fe38ad9bSGagandeep Singh client->pfe = priv->pfe; 315fe38ad9bSGagandeep Singh client->port_id = dev->data->port_id; 316fe38ad9bSGagandeep Singh client->event_handler = pfe_eth_event_handler; 317fe38ad9bSGagandeep Singh 318fe38ad9bSGagandeep Singh client->tx_qsize = EMAC_TXQ_DEPTH; 319fe38ad9bSGagandeep Singh client->rx_qsize = EMAC_RXQ_DEPTH; 320fe38ad9bSGagandeep Singh 321fe38ad9bSGagandeep Singh rc = hif_lib_client_register(client); 322fe38ad9bSGagandeep Singh if (rc) { 323fe38ad9bSGagandeep Singh PFE_PMD_ERR("hif_lib_client_register(%d) failed", 324fe38ad9bSGagandeep Singh client->id); 325fe38ad9bSGagandeep Singh goto err0; 326fe38ad9bSGagandeep Singh } 327fe38ad9bSGagandeep Singh } 328fe38ad9bSGagandeep Singh rc = pfe_eth_start(priv); 32936220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts; 33036220514SGagandeep Singh dev->tx_pkt_burst = &pfe_xmit_pkts; 33136220514SGagandeep Singh /* If no prefetch is configured. */ 33236220514SGagandeep Singh if (getenv("PFE_INTR_SUPPORT")) { 33336220514SGagandeep Singh dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; 33436220514SGagandeep Singh PFE_PMD_INFO("PFE INTERRUPT Mode enabled"); 33536220514SGagandeep Singh } 33636220514SGagandeep Singh 337fe38ad9bSGagandeep Singh 338fe38ad9bSGagandeep Singh err0: 339fe38ad9bSGagandeep Singh return rc; 340fe38ad9bSGagandeep Singh } 341fe38ad9bSGagandeep Singh 34267fc3ff9SGagandeep Singh static int 34367fc3ff9SGagandeep Singh pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) 34467fc3ff9SGagandeep Singh { 34567fc3ff9SGagandeep Singh int pfe_cdev_fd; 34667fc3ff9SGagandeep Singh 34767fc3ff9SGagandeep Singh if (priv == NULL) 34867fc3ff9SGagandeep Singh return -1; 34967fc3ff9SGagandeep Singh 35067fc3ff9SGagandeep Singh pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); 35167fc3ff9SGagandeep Singh if (pfe_cdev_fd < 0) { 352b1bc1afaSGagandeep Singh PFE_PMD_WARN("Unable to open PFE device file (%s).\n", 353b1bc1afaSGagandeep Singh PFE_CDEV_PATH); 354b1bc1afaSGagandeep Singh PFE_PMD_WARN("Link status update will not be available.\n"); 35567fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 35667fc3ff9SGagandeep Singh return -1; 35767fc3ff9SGagandeep Singh } 35867fc3ff9SGagandeep Singh 35967fc3ff9SGagandeep Singh priv->link_fd = pfe_cdev_fd; 36067fc3ff9SGagandeep Singh 36167fc3ff9SGagandeep Singh return 0; 36267fc3ff9SGagandeep Singh } 36367fc3ff9SGagandeep Singh 36467fc3ff9SGagandeep Singh static void 36567fc3ff9SGagandeep Singh pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) 36667fc3ff9SGagandeep Singh { 36767fc3ff9SGagandeep Singh if (priv == NULL) 36867fc3ff9SGagandeep Singh return; 36967fc3ff9SGagandeep Singh 37067fc3ff9SGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 37167fc3ff9SGagandeep Singh close(priv->link_fd); 37267fc3ff9SGagandeep Singh priv->link_fd = PFE_CDEV_INVALID_FD; 37367fc3ff9SGagandeep Singh } 37467fc3ff9SGagandeep Singh } 37567fc3ff9SGagandeep Singh 37667fc3ff9SGagandeep Singh static void 377fe38ad9bSGagandeep Singh pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) 378fe38ad9bSGagandeep Singh { 379fe38ad9bSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 380fe38ad9bSGagandeep Singh 381*b8f5d2aeSThomas Monjalon dev->data->dev_started = 0; 382*b8f5d2aeSThomas Monjalon 383fe38ad9bSGagandeep Singh gemac_disable(priv->EMAC_baseaddr); 384fe38ad9bSGagandeep Singh gpi_disable(priv->GPI_baseaddr); 38536220514SGagandeep Singh 38636220514SGagandeep Singh dev->rx_pkt_burst = &pfe_dummy_recv_pkts; 38736220514SGagandeep Singh dev->tx_pkt_burst = &pfe_dummy_xmit_pkts; 388fe38ad9bSGagandeep Singh } 389fe38ad9bSGagandeep Singh 390b142387bSThomas Monjalon static int 391fe38ad9bSGagandeep Singh pfe_eth_close(struct rte_eth_dev *dev) 392fe38ad9bSGagandeep Singh { 39357803c5eSSachin Saxena PMD_INIT_FUNC_TRACE(); 39457803c5eSSachin Saxena 395fe38ad9bSGagandeep Singh if (!dev) 396b142387bSThomas Monjalon return -1; 397fe38ad9bSGagandeep Singh 398fe38ad9bSGagandeep Singh if (!g_pfe) 399b142387bSThomas Monjalon return -1; 400fe38ad9bSGagandeep Singh 40130410493SThomas Monjalon if (rte_eal_process_type() != RTE_PROC_PRIMARY) 40230410493SThomas Monjalon return 0; 40330410493SThomas Monjalon 40457803c5eSSachin Saxena pfe_eth_stop(dev); 40557803c5eSSachin Saxena /* Close the device file for link status */ 40657803c5eSSachin Saxena pfe_eth_close_cdev(dev->data->dev_private); 40757803c5eSSachin Saxena 40857803c5eSSachin Saxena munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size); 40957803c5eSSachin Saxena g_pfe->nb_devs--; 410fe38ad9bSGagandeep Singh 411fe38ad9bSGagandeep Singh if (g_pfe->nb_devs == 0) { 412fe38ad9bSGagandeep Singh pfe_hif_exit(g_pfe); 413fe38ad9bSGagandeep Singh pfe_hif_lib_exit(g_pfe); 414fe38ad9bSGagandeep Singh rte_free(g_pfe); 415fe38ad9bSGagandeep Singh g_pfe = NULL; 416fe38ad9bSGagandeep Singh } 417b142387bSThomas Monjalon 418b142387bSThomas Monjalon return 0; 419fe38ad9bSGagandeep Singh } 420fe38ad9bSGagandeep Singh 421fe38ad9bSGagandeep Singh static int 422fe38ad9bSGagandeep Singh pfe_eth_configure(struct rte_eth_dev *dev __rte_unused) 423fe38ad9bSGagandeep Singh { 424fe38ad9bSGagandeep Singh return 0; 425fe38ad9bSGagandeep Singh } 426fe38ad9bSGagandeep Singh 427fe38ad9bSGagandeep Singh static int 428fe38ad9bSGagandeep Singh pfe_eth_info(struct rte_eth_dev *dev, 429fe38ad9bSGagandeep Singh struct rte_eth_dev_info *dev_info) 430fe38ad9bSGagandeep Singh { 431fe38ad9bSGagandeep Singh dev_info->max_mac_addrs = PFE_MAX_MACS; 432fe38ad9bSGagandeep Singh dev_info->max_rx_queues = dev->data->nb_rx_queues; 433fe38ad9bSGagandeep Singh dev_info->max_tx_queues = dev->data->nb_tx_queues; 434fe38ad9bSGagandeep Singh dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE; 435320ae324SGagandeep Singh dev_info->min_mtu = RTE_ETHER_MIN_MTU; 436592041a0SGagandeep Singh dev_info->rx_offload_capa = dev_rx_offloads_sup; 437592041a0SGagandeep Singh dev_info->tx_offload_capa = dev_tx_offloads_sup; 438320ae324SGagandeep Singh if (pfe_svr == SVR_LS1012A_REV1) { 439fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; 440320ae324SGagandeep Singh dev_info->max_mtu = MAX_MTU_ON_REV1; 441320ae324SGagandeep Singh } else { 442fe38ad9bSGagandeep Singh dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE; 443320ae324SGagandeep Singh dev_info->max_mtu = JUMBO_FRAME_SIZE - PFE_ETH_OVERHEAD; 444320ae324SGagandeep Singh } 445fe38ad9bSGagandeep Singh 446fe38ad9bSGagandeep Singh return 0; 447fe38ad9bSGagandeep Singh } 448fe38ad9bSGagandeep Singh 449592041a0SGagandeep Singh /* Only first mb_pool given on first call of this API will be used 450592041a0SGagandeep Singh * in whole system, also nb_rx_desc and rx_conf are unused params 451592041a0SGagandeep Singh */ 452592041a0SGagandeep Singh static int 453592041a0SGagandeep Singh pfe_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, 454592041a0SGagandeep Singh __rte_unused uint16_t nb_rx_desc, 455592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 456592041a0SGagandeep Singh __rte_unused const struct rte_eth_rxconf *rx_conf, 457592041a0SGagandeep Singh struct rte_mempool *mb_pool) 458592041a0SGagandeep Singh { 459592041a0SGagandeep Singh int rc = 0; 460592041a0SGagandeep Singh struct pfe *pfe; 461592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 462592041a0SGagandeep Singh 463592041a0SGagandeep Singh pfe = priv->pfe; 464592041a0SGagandeep Singh 465592041a0SGagandeep Singh if (queue_idx >= EMAC_RXQ_CNT) { 466592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 467592041a0SGagandeep Singh queue_idx, EMAC_RXQ_CNT); 468592041a0SGagandeep Singh return -1; 469592041a0SGagandeep Singh } 470592041a0SGagandeep Singh 471592041a0SGagandeep Singh if (!pfe->hif.setuped) { 472592041a0SGagandeep Singh rc = pfe_hif_shm_init(pfe->hif.shm, mb_pool); 473592041a0SGagandeep Singh if (rc) { 474592041a0SGagandeep Singh PFE_PMD_ERR("Could not allocate buffer descriptors"); 475592041a0SGagandeep Singh return -1; 476592041a0SGagandeep Singh } 477592041a0SGagandeep Singh 478592041a0SGagandeep Singh pfe->hif.shm->pool = mb_pool; 479592041a0SGagandeep Singh if (pfe_hif_init_buffers(&pfe->hif)) { 480592041a0SGagandeep Singh PFE_PMD_ERR("Could not initialize buffer descriptors"); 481592041a0SGagandeep Singh return -1; 482592041a0SGagandeep Singh } 483592041a0SGagandeep Singh hif_init(); 484592041a0SGagandeep Singh hif_rx_enable(); 485592041a0SGagandeep Singh hif_tx_enable(); 486592041a0SGagandeep Singh pfe->hif.setuped = 1; 487592041a0SGagandeep Singh } 488592041a0SGagandeep Singh dev->data->rx_queues[queue_idx] = &priv->client.rx_q[queue_idx]; 489592041a0SGagandeep Singh priv->client.rx_q[queue_idx].queue_id = queue_idx; 490592041a0SGagandeep Singh 491592041a0SGagandeep Singh return 0; 492592041a0SGagandeep Singh } 493592041a0SGagandeep Singh 494592041a0SGagandeep Singh static void 495592041a0SGagandeep Singh pfe_rx_queue_release(void *q __rte_unused) 496592041a0SGagandeep Singh { 497592041a0SGagandeep Singh PMD_INIT_FUNC_TRACE(); 498592041a0SGagandeep Singh } 499592041a0SGagandeep Singh 500592041a0SGagandeep Singh static void 501592041a0SGagandeep Singh pfe_tx_queue_release(void *q __rte_unused) 502592041a0SGagandeep Singh { 503592041a0SGagandeep Singh PMD_INIT_FUNC_TRACE(); 504592041a0SGagandeep Singh } 505592041a0SGagandeep Singh 506592041a0SGagandeep Singh static int 507592041a0SGagandeep Singh pfe_tx_queue_setup(struct rte_eth_dev *dev, 508592041a0SGagandeep Singh uint16_t queue_idx, 509592041a0SGagandeep Singh __rte_unused uint16_t nb_desc, 510592041a0SGagandeep Singh __rte_unused unsigned int socket_id, 511592041a0SGagandeep Singh __rte_unused const struct rte_eth_txconf *tx_conf) 512592041a0SGagandeep Singh { 513592041a0SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 514592041a0SGagandeep Singh 515592041a0SGagandeep Singh if (queue_idx >= emac_txq_cnt) { 516592041a0SGagandeep Singh PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 517592041a0SGagandeep Singh queue_idx, emac_txq_cnt); 518592041a0SGagandeep Singh return -1; 519592041a0SGagandeep Singh } 520592041a0SGagandeep Singh dev->data->tx_queues[queue_idx] = &priv->client.tx_q[queue_idx]; 521592041a0SGagandeep Singh priv->client.tx_q[queue_idx].queue_id = queue_idx; 522592041a0SGagandeep Singh return 0; 523592041a0SGagandeep Singh } 524592041a0SGagandeep Singh 525659b494dSGagandeep Singh static const uint32_t * 526659b494dSGagandeep Singh pfe_supported_ptypes_get(struct rte_eth_dev *dev) 527659b494dSGagandeep Singh { 528659b494dSGagandeep Singh static const uint32_t ptypes[] = { 529659b494dSGagandeep Singh /*todo -= add more types */ 530659b494dSGagandeep Singh RTE_PTYPE_L2_ETHER, 531659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4, 532659b494dSGagandeep Singh RTE_PTYPE_L3_IPV4_EXT, 533659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6, 534659b494dSGagandeep Singh RTE_PTYPE_L3_IPV6_EXT, 535659b494dSGagandeep Singh RTE_PTYPE_L4_TCP, 536659b494dSGagandeep Singh RTE_PTYPE_L4_UDP, 537659b494dSGagandeep Singh RTE_PTYPE_L4_SCTP 538659b494dSGagandeep Singh }; 539659b494dSGagandeep Singh 540659b494dSGagandeep Singh if (dev->rx_pkt_burst == pfe_recv_pkts || 541659b494dSGagandeep Singh dev->rx_pkt_burst == pfe_recv_pkts_on_intr) 542659b494dSGagandeep Singh return ptypes; 543659b494dSGagandeep Singh return NULL; 544659b494dSGagandeep Singh } 545659b494dSGagandeep Singh 546acd4818eSGagandeep Singh static inline int 547acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev, 548acd4818eSGagandeep Singh struct rte_eth_link *link) 549acd4818eSGagandeep Singh { 550acd4818eSGagandeep Singh struct rte_eth_link *dst = link; 551acd4818eSGagandeep Singh struct rte_eth_link *src = &dev->data->dev_link; 552acd4818eSGagandeep Singh 553acd4818eSGagandeep Singh if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 554acd4818eSGagandeep Singh *(uint64_t *)src) == 0) 555acd4818eSGagandeep Singh return -1; 556acd4818eSGagandeep Singh 557acd4818eSGagandeep Singh return 0; 558acd4818eSGagandeep Singh } 559acd4818eSGagandeep Singh 560acd4818eSGagandeep Singh static inline int 561acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev, 562acd4818eSGagandeep Singh struct rte_eth_link *link) 563acd4818eSGagandeep Singh { 564acd4818eSGagandeep Singh struct rte_eth_link *dst = &dev->data->dev_link; 565acd4818eSGagandeep Singh struct rte_eth_link *src = link; 566acd4818eSGagandeep Singh 567acd4818eSGagandeep Singh if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 568acd4818eSGagandeep Singh *(uint64_t *)src) == 0) 569acd4818eSGagandeep Singh return -1; 570acd4818eSGagandeep Singh 571acd4818eSGagandeep Singh return 0; 572acd4818eSGagandeep Singh } 573acd4818eSGagandeep Singh 574acd4818eSGagandeep Singh static int 575acd4818eSGagandeep Singh pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) 576acd4818eSGagandeep Singh { 577acd4818eSGagandeep Singh int ret, ioctl_cmd = 0; 578acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 579acd4818eSGagandeep Singh struct rte_eth_link link, old; 580acd4818eSGagandeep Singh unsigned int lstatus = 1; 581acd4818eSGagandeep Singh 582acd4818eSGagandeep Singh if (dev == NULL) { 583acd4818eSGagandeep Singh PFE_PMD_ERR("Invalid device in link_update.\n"); 584acd4818eSGagandeep Singh return 0; 585acd4818eSGagandeep Singh } 586acd4818eSGagandeep Singh 587acd4818eSGagandeep Singh memset(&old, 0, sizeof(old)); 588acd4818eSGagandeep Singh memset(&link, 0, sizeof(struct rte_eth_link)); 589acd4818eSGagandeep Singh 590acd4818eSGagandeep Singh pfe_eth_atomic_read_link_status(dev, &old); 591acd4818eSGagandeep Singh 592acd4818eSGagandeep Singh /* Read from PFE CDEV, status of link, if file was successfully 593acd4818eSGagandeep Singh * opened. 594acd4818eSGagandeep Singh */ 595acd4818eSGagandeep Singh if (priv->link_fd != PFE_CDEV_INVALID_FD) { 596acd4818eSGagandeep Singh if (priv->id == 0) 597acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH0_STATE_GET; 598acd4818eSGagandeep Singh if (priv->id == 1) 599acd4818eSGagandeep Singh ioctl_cmd = PFE_CDEV_ETH1_STATE_GET; 600acd4818eSGagandeep Singh 601acd4818eSGagandeep Singh ret = ioctl(priv->link_fd, ioctl_cmd, &lstatus); 602acd4818eSGagandeep Singh if (ret != 0) { 603acd4818eSGagandeep Singh PFE_PMD_ERR("Unable to fetch link status (ioctl)\n"); 604acd4818eSGagandeep Singh /* use dummy link value */ 605acd4818eSGagandeep Singh link.link_status = 1; 606acd4818eSGagandeep Singh } 607acd4818eSGagandeep Singh PFE_PMD_DEBUG("Fetched link state (%d) for dev %d.\n", 608acd4818eSGagandeep Singh lstatus, priv->id); 609acd4818eSGagandeep Singh } 610acd4818eSGagandeep Singh 611acd4818eSGagandeep Singh if (old.link_status == lstatus) { 612acd4818eSGagandeep Singh /* no change in status */ 613acd4818eSGagandeep Singh PFE_PMD_DEBUG("No change in link status; Not updating.\n"); 614acd4818eSGagandeep Singh return -1; 615acd4818eSGagandeep Singh } 616acd4818eSGagandeep Singh 617acd4818eSGagandeep Singh link.link_status = lstatus; 618acd4818eSGagandeep Singh link.link_speed = ETH_LINK_SPEED_1G; 619acd4818eSGagandeep Singh link.link_duplex = ETH_LINK_FULL_DUPLEX; 620acd4818eSGagandeep Singh link.link_autoneg = ETH_LINK_AUTONEG; 621acd4818eSGagandeep Singh 622acd4818eSGagandeep Singh pfe_eth_atomic_write_link_status(dev, &link); 623acd4818eSGagandeep Singh 624acd4818eSGagandeep Singh PFE_PMD_INFO("Port (%d) link is %s\n", dev->data->port_id, 625acd4818eSGagandeep Singh link.link_status ? "up" : "down"); 626acd4818eSGagandeep Singh 627acd4818eSGagandeep Singh return 0; 628acd4818eSGagandeep Singh } 629acd4818eSGagandeep Singh 630659b494dSGagandeep Singh static int 631ff64beabSGagandeep Singh pfe_promiscuous_enable(struct rte_eth_dev *dev) 632ff64beabSGagandeep Singh { 633ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 634ff64beabSGagandeep Singh 635ff64beabSGagandeep Singh priv->promisc = 1; 636ff64beabSGagandeep Singh dev->data->promiscuous = 1; 637ff64beabSGagandeep Singh gemac_enable_copy_all(priv->EMAC_baseaddr); 638ff64beabSGagandeep Singh 639ff64beabSGagandeep Singh return 0; 640ff64beabSGagandeep Singh } 641ff64beabSGagandeep Singh 642ff64beabSGagandeep Singh static int 643ff64beabSGagandeep Singh pfe_promiscuous_disable(struct rte_eth_dev *dev) 644ff64beabSGagandeep Singh { 645ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 646ff64beabSGagandeep Singh 647ff64beabSGagandeep Singh priv->promisc = 0; 648ff64beabSGagandeep Singh dev->data->promiscuous = 0; 649ff64beabSGagandeep Singh gemac_disable_copy_all(priv->EMAC_baseaddr); 650ff64beabSGagandeep Singh 651ff64beabSGagandeep Singh return 0; 652ff64beabSGagandeep Singh } 653ff64beabSGagandeep Singh 654ff64beabSGagandeep Singh static int 655ff64beabSGagandeep Singh pfe_allmulticast_enable(struct rte_eth_dev *dev) 656ff64beabSGagandeep Singh { 657ff64beabSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 658ff64beabSGagandeep Singh struct pfe_mac_addr hash_addr; /* hash register structure */ 659ff64beabSGagandeep Singh 660ff64beabSGagandeep Singh /* Set the hash to rx all multicast frames */ 661ff64beabSGagandeep Singh hash_addr.bottom = 0xFFFFFFFF; 662ff64beabSGagandeep Singh hash_addr.top = 0xFFFFFFFF; 663ff64beabSGagandeep Singh gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); 664ff64beabSGagandeep Singh dev->data->all_multicast = 1; 665ff64beabSGagandeep Singh 666ff64beabSGagandeep Singh return 0; 667ff64beabSGagandeep Singh } 668ff64beabSGagandeep Singh 669ff64beabSGagandeep Singh static int 670acd4818eSGagandeep Singh pfe_link_down(struct rte_eth_dev *dev) 671acd4818eSGagandeep Singh { 672acd4818eSGagandeep Singh pfe_eth_stop(dev); 673acd4818eSGagandeep Singh return 0; 674acd4818eSGagandeep Singh } 675acd4818eSGagandeep Singh 676acd4818eSGagandeep Singh static int 677acd4818eSGagandeep Singh pfe_link_up(struct rte_eth_dev *dev) 678acd4818eSGagandeep Singh { 679acd4818eSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 680acd4818eSGagandeep Singh 681acd4818eSGagandeep Singh pfe_eth_start(priv); 682acd4818eSGagandeep Singh return 0; 683acd4818eSGagandeep Singh } 684acd4818eSGagandeep Singh 685acd4818eSGagandeep Singh static int 686320ae324SGagandeep Singh pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 687320ae324SGagandeep Singh { 688320ae324SGagandeep Singh int ret; 689320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 690320ae324SGagandeep Singh uint16_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 691320ae324SGagandeep Singh 692320ae324SGagandeep Singh /*TODO Support VLAN*/ 693320ae324SGagandeep Singh ret = gemac_set_rx(priv->EMAC_baseaddr, frame_size); 694320ae324SGagandeep Singh if (!ret) 695320ae324SGagandeep Singh dev->data->mtu = mtu; 696320ae324SGagandeep Singh 697320ae324SGagandeep Singh return ret; 698320ae324SGagandeep Singh } 699320ae324SGagandeep Singh 700320ae324SGagandeep Singh /* pfe_eth_enet_addr_byte_mac 701320ae324SGagandeep Singh */ 702320ae324SGagandeep Singh static int 703320ae324SGagandeep Singh pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, 704320ae324SGagandeep Singh struct pfe_mac_addr *enet_addr) 705320ae324SGagandeep Singh { 706320ae324SGagandeep Singh if (!enet_byte_addr || !enet_addr) { 707320ae324SGagandeep Singh return -1; 708320ae324SGagandeep Singh 709320ae324SGagandeep Singh } else { 710320ae324SGagandeep Singh enet_addr->bottom = enet_byte_addr[0] | 711320ae324SGagandeep Singh (enet_byte_addr[1] << 8) | 712320ae324SGagandeep Singh (enet_byte_addr[2] << 16) | 713320ae324SGagandeep Singh (enet_byte_addr[3] << 24); 714320ae324SGagandeep Singh enet_addr->top = enet_byte_addr[4] | 715320ae324SGagandeep Singh (enet_byte_addr[5] << 8); 716320ae324SGagandeep Singh return 0; 717320ae324SGagandeep Singh } 718320ae324SGagandeep Singh } 719320ae324SGagandeep Singh 720320ae324SGagandeep Singh static int 721320ae324SGagandeep Singh pfe_dev_set_mac_addr(struct rte_eth_dev *dev, 722320ae324SGagandeep Singh struct rte_ether_addr *addr) 723320ae324SGagandeep Singh { 724320ae324SGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 725320ae324SGagandeep Singh struct pfe_mac_addr spec_addr; 726320ae324SGagandeep Singh int ret; 727320ae324SGagandeep Singh 728320ae324SGagandeep Singh ret = pfe_eth_enet_addr_byte_mac(addr->addr_bytes, &spec_addr); 729320ae324SGagandeep Singh if (ret) 730320ae324SGagandeep Singh return ret; 731320ae324SGagandeep Singh 732320ae324SGagandeep Singh gemac_set_laddrN(priv->EMAC_baseaddr, 733320ae324SGagandeep Singh (struct pfe_mac_addr *)&spec_addr, 1); 734320ae324SGagandeep Singh rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 735320ae324SGagandeep Singh return 0; 736320ae324SGagandeep Singh } 737320ae324SGagandeep Singh 738320ae324SGagandeep Singh static int 739659b494dSGagandeep Singh pfe_stats_get(struct rte_eth_dev *dev, 740659b494dSGagandeep Singh struct rte_eth_stats *stats) 741659b494dSGagandeep Singh { 742659b494dSGagandeep Singh struct pfe_eth_priv_s *priv = dev->data->dev_private; 743659b494dSGagandeep Singh struct rte_eth_stats *eth_stats = &priv->stats; 744659b494dSGagandeep Singh 745659b494dSGagandeep Singh if (stats == NULL) 746659b494dSGagandeep Singh return -1; 747659b494dSGagandeep Singh 748659b494dSGagandeep Singh memset(stats, 0, sizeof(struct rte_eth_stats)); 749659b494dSGagandeep Singh 750659b494dSGagandeep Singh stats->ipackets = eth_stats->ipackets; 751659b494dSGagandeep Singh stats->ibytes = eth_stats->ibytes; 752659b494dSGagandeep Singh stats->opackets = eth_stats->opackets; 753659b494dSGagandeep Singh stats->obytes = eth_stats->obytes; 754659b494dSGagandeep Singh 755659b494dSGagandeep Singh return 0; 756659b494dSGagandeep Singh } 757659b494dSGagandeep Singh 758fe38ad9bSGagandeep Singh static const struct eth_dev_ops ops = { 759fe38ad9bSGagandeep Singh .dev_start = pfe_eth_open, 760fe38ad9bSGagandeep Singh .dev_stop = pfe_eth_stop, 761fe38ad9bSGagandeep Singh .dev_close = pfe_eth_close, 762fe38ad9bSGagandeep Singh .dev_configure = pfe_eth_configure, 763fe38ad9bSGagandeep Singh .dev_infos_get = pfe_eth_info, 764592041a0SGagandeep Singh .rx_queue_setup = pfe_rx_queue_setup, 765592041a0SGagandeep Singh .rx_queue_release = pfe_rx_queue_release, 766592041a0SGagandeep Singh .tx_queue_setup = pfe_tx_queue_setup, 767592041a0SGagandeep Singh .tx_queue_release = pfe_tx_queue_release, 768659b494dSGagandeep Singh .dev_supported_ptypes_get = pfe_supported_ptypes_get, 769acd4818eSGagandeep Singh .link_update = pfe_eth_link_update, 770ff64beabSGagandeep Singh .promiscuous_enable = pfe_promiscuous_enable, 771ff64beabSGagandeep Singh .promiscuous_disable = pfe_promiscuous_disable, 772ff64beabSGagandeep Singh .allmulticast_enable = pfe_allmulticast_enable, 773acd4818eSGagandeep Singh .dev_set_link_down = pfe_link_down, 774acd4818eSGagandeep Singh .dev_set_link_up = pfe_link_up, 775320ae324SGagandeep Singh .mtu_set = pfe_mtu_set, 776320ae324SGagandeep Singh .mac_addr_set = pfe_dev_set_mac_addr, 777659b494dSGagandeep Singh .stats_get = pfe_stats_get, 778fe38ad9bSGagandeep Singh }; 779fe38ad9bSGagandeep Singh 78067fc3ff9SGagandeep Singh static int 78167fc3ff9SGagandeep Singh pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) 78267fc3ff9SGagandeep Singh { 78367fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 78467fc3ff9SGagandeep Singh struct pfe_eth_priv_s *priv = NULL; 7855253fe37SGagandeep Singh struct ls1012a_eth_platform_data *einfo; 7865253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pfe_info; 787320ae324SGagandeep Singh struct rte_ether_addr addr; 78867fc3ff9SGagandeep Singh int err; 78967fc3ff9SGagandeep Singh 79067fc3ff9SGagandeep Singh eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); 79167fc3ff9SGagandeep Singh if (eth_dev == NULL) 79267fc3ff9SGagandeep Singh return -ENOMEM; 79367fc3ff9SGagandeep Singh 7945253fe37SGagandeep Singh /* Extract pltform data */ 7955253fe37SGagandeep Singh pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data; 7965253fe37SGagandeep Singh if (!pfe_info) { 7975253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional platform data"); 7985253fe37SGagandeep Singh err = -ENODEV; 7995253fe37SGagandeep Singh goto err0; 8005253fe37SGagandeep Singh } 8015253fe37SGagandeep Singh 8025253fe37SGagandeep Singh einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata; 8035253fe37SGagandeep Singh 8045253fe37SGagandeep Singh /* einfo never be NULL, but no harm in having this check */ 8055253fe37SGagandeep Singh if (!einfo) { 8065253fe37SGagandeep Singh PFE_PMD_ERR("pfe missing additional gemacs platform data"); 8075253fe37SGagandeep Singh err = -ENODEV; 8085253fe37SGagandeep Singh goto err0; 8095253fe37SGagandeep Singh } 8105253fe37SGagandeep Singh 81167fc3ff9SGagandeep Singh priv = eth_dev->data->dev_private; 81267fc3ff9SGagandeep Singh priv->ndev = eth_dev; 8135253fe37SGagandeep Singh priv->id = einfo[id].gem_id; 81467fc3ff9SGagandeep Singh priv->pfe = pfe; 81567fc3ff9SGagandeep Singh 81667fc3ff9SGagandeep Singh pfe->eth.eth_priv[id] = priv; 81767fc3ff9SGagandeep Singh 8185253fe37SGagandeep Singh /* Set the info in the priv to the current info */ 8195253fe37SGagandeep Singh priv->einfo = &einfo[id]; 8205253fe37SGagandeep Singh priv->EMAC_baseaddr = cbus_emac_base[id]; 8215253fe37SGagandeep Singh priv->PHY_baseaddr = cbus_emac_base[id]; 8225253fe37SGagandeep Singh priv->GPI_baseaddr = cbus_gpi_base[id]; 8235253fe37SGagandeep Singh 82467fc3ff9SGagandeep Singh #define HIF_GEMAC_TMUQ_BASE 6 82567fc3ff9SGagandeep Singh priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); 82667fc3ff9SGagandeep Singh priv->high_tmu_q = priv->low_tmu_q + 1; 82767fc3ff9SGagandeep Singh 82867fc3ff9SGagandeep Singh rte_spinlock_init(&priv->lock); 82967fc3ff9SGagandeep Singh 83067fc3ff9SGagandeep Singh /* Copy the station address into the dev structure, */ 83167fc3ff9SGagandeep Singh eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", 83267fc3ff9SGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS, 0); 83367fc3ff9SGagandeep Singh if (eth_dev->data->mac_addrs == NULL) { 834b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses", 835b1bc1afaSGagandeep Singh ETHER_ADDR_LEN * PFE_MAX_MACS); 83667fc3ff9SGagandeep Singh err = -ENOMEM; 83767fc3ff9SGagandeep Singh goto err0; 83867fc3ff9SGagandeep Singh } 83967fc3ff9SGagandeep Singh 840320ae324SGagandeep Singh memcpy(addr.addr_bytes, priv->einfo->mac_addr, 841320ae324SGagandeep Singh ETH_ALEN); 842320ae324SGagandeep Singh 843320ae324SGagandeep Singh pfe_dev_set_mac_addr(eth_dev, &addr); 844320ae324SGagandeep Singh rte_ether_addr_copy(&addr, ð_dev->data->mac_addrs[0]); 845320ae324SGagandeep Singh 84667fc3ff9SGagandeep Singh eth_dev->data->mtu = 1500; 847fe38ad9bSGagandeep Singh eth_dev->dev_ops = &ops; 848fe38ad9bSGagandeep Singh pfe_eth_stop(eth_dev); 8495253fe37SGagandeep Singh pfe_gemac_init(priv); 85067fc3ff9SGagandeep Singh 85167fc3ff9SGagandeep Singh eth_dev->data->nb_rx_queues = 1; 85267fc3ff9SGagandeep Singh eth_dev->data->nb_tx_queues = 1; 85367fc3ff9SGagandeep Singh 85467fc3ff9SGagandeep Singh /* For link status, open the PFE CDEV; Error from this function 85567fc3ff9SGagandeep Singh * is silently ignored; In case of error, the link status will not 85667fc3ff9SGagandeep Singh * be available. 85767fc3ff9SGagandeep Singh */ 85867fc3ff9SGagandeep Singh pfe_eth_open_cdev(priv); 85967fc3ff9SGagandeep Singh rte_eth_dev_probing_finish(eth_dev); 86067fc3ff9SGagandeep Singh 86167fc3ff9SGagandeep Singh return 0; 86267fc3ff9SGagandeep Singh err0: 86367fc3ff9SGagandeep Singh rte_eth_dev_release_port(eth_dev); 86467fc3ff9SGagandeep Singh return err; 86567fc3ff9SGagandeep Singh } 86667fc3ff9SGagandeep Singh 8675253fe37SGagandeep Singh static int 8685253fe37SGagandeep Singh pfe_get_gemac_if_proprties(struct pfe *pfe, 8695253fe37SGagandeep Singh __rte_unused const struct device_node *parent, 8705253fe37SGagandeep Singh unsigned int port, unsigned int if_cnt, 8715253fe37SGagandeep Singh struct ls1012a_pfe_platform_data *pdata) 8725253fe37SGagandeep Singh { 8735253fe37SGagandeep Singh const struct device_node *gem = NULL; 8745253fe37SGagandeep Singh size_t size; 8755253fe37SGagandeep Singh unsigned int ii = 0, phy_id = 0; 8765253fe37SGagandeep Singh const u32 *addr; 8775253fe37SGagandeep Singh const void *mac_addr; 8785253fe37SGagandeep Singh 8795253fe37SGagandeep Singh for (ii = 0; ii < if_cnt; ii++) { 8805253fe37SGagandeep Singh gem = of_get_next_child(parent, gem); 8815253fe37SGagandeep Singh if (!gem) 8825253fe37SGagandeep Singh goto err; 8835253fe37SGagandeep Singh addr = of_get_property(gem, "reg", &size); 8845253fe37SGagandeep Singh if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port)) 8855253fe37SGagandeep Singh break; 8865253fe37SGagandeep Singh } 8875253fe37SGagandeep Singh 8885253fe37SGagandeep Singh if (ii >= if_cnt) { 8895253fe37SGagandeep Singh PFE_PMD_ERR("Failed to find interface = %d", if_cnt); 8905253fe37SGagandeep Singh goto err; 8915253fe37SGagandeep Singh } 8925253fe37SGagandeep Singh 8935253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].gem_id = port; 8945253fe37SGagandeep Singh 8955253fe37SGagandeep Singh mac_addr = of_get_mac_address(gem); 8965253fe37SGagandeep Singh 8975253fe37SGagandeep Singh if (mac_addr) { 8985253fe37SGagandeep Singh memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, 8995253fe37SGagandeep Singh ETH_ALEN); 9005253fe37SGagandeep Singh } 9015253fe37SGagandeep Singh 9025253fe37SGagandeep Singh addr = of_get_property(gem, "fsl,mdio-mux-val", &size); 9035253fe37SGagandeep Singh if (!addr) { 9045253fe37SGagandeep Singh PFE_PMD_ERR("Invalid mdio-mux-val...."); 9055253fe37SGagandeep Singh } else { 9065253fe37SGagandeep Singh phy_id = rte_be_to_cpu_32((unsigned int)*addr); 9075253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; 9085253fe37SGagandeep Singh } 9095253fe37SGagandeep Singh if (pdata->ls1012a_eth_pdata[port].phy_id < 32) 9105253fe37SGagandeep Singh pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = 9115253fe37SGagandeep Singh pdata->ls1012a_eth_pdata[port].mdio_muxval; 9125253fe37SGagandeep Singh 9135253fe37SGagandeep Singh return 0; 9145253fe37SGagandeep Singh 9155253fe37SGagandeep Singh err: 9165253fe37SGagandeep Singh return -1; 9175253fe37SGagandeep Singh } 9185253fe37SGagandeep Singh 91967fc3ff9SGagandeep Singh /* Parse integer from integer argument */ 92067fc3ff9SGagandeep Singh static int 92167fc3ff9SGagandeep Singh parse_integer_arg(const char *key __rte_unused, 92267fc3ff9SGagandeep Singh const char *value, void *extra_args) 92367fc3ff9SGagandeep Singh { 92467fc3ff9SGagandeep Singh int i; 92567fc3ff9SGagandeep Singh char *end; 92667fc3ff9SGagandeep Singh errno = 0; 92767fc3ff9SGagandeep Singh 92867fc3ff9SGagandeep Singh i = strtol(value, &end, 10); 929b1bc1afaSGagandeep Singh if (*end != 0 || errno != 0 || i < 0 || i > 1) { 930b1bc1afaSGagandeep Singh PFE_PMD_ERR("Supported Port IDS are 0 and 1"); 93167fc3ff9SGagandeep Singh return -EINVAL; 932b1bc1afaSGagandeep Singh } 93367fc3ff9SGagandeep Singh 93467fc3ff9SGagandeep Singh *((uint32_t *)extra_args) = i; 93567fc3ff9SGagandeep Singh 93667fc3ff9SGagandeep Singh return 0; 93767fc3ff9SGagandeep Singh } 93867fc3ff9SGagandeep Singh 93967fc3ff9SGagandeep Singh static int 94067fc3ff9SGagandeep Singh pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params, 94167fc3ff9SGagandeep Singh struct rte_vdev_device *dev) 94267fc3ff9SGagandeep Singh { 94367fc3ff9SGagandeep Singh struct rte_kvargs *kvlist = NULL; 94467fc3ff9SGagandeep Singh int ret = 0; 94567fc3ff9SGagandeep Singh 94667fc3ff9SGagandeep Singh static const char * const pfe_vdev_valid_params[] = { 94767fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 94867fc3ff9SGagandeep Singh NULL 94967fc3ff9SGagandeep Singh }; 95067fc3ff9SGagandeep Singh 95167fc3ff9SGagandeep Singh const char *input_args = rte_vdev_device_args(dev); 95267fc3ff9SGagandeep Singh 95367fc3ff9SGagandeep Singh if (!input_args) 95467fc3ff9SGagandeep Singh return -1; 95567fc3ff9SGagandeep Singh 95667fc3ff9SGagandeep Singh kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params); 95767fc3ff9SGagandeep Singh if (kvlist == NULL) 95867fc3ff9SGagandeep Singh return -1; 95967fc3ff9SGagandeep Singh 96067fc3ff9SGagandeep Singh ret = rte_kvargs_process(kvlist, 96167fc3ff9SGagandeep Singh PFE_VDEV_GEM_ID_ARG, 96267fc3ff9SGagandeep Singh &parse_integer_arg, 96367fc3ff9SGagandeep Singh ¶ms->gem_id); 96467fc3ff9SGagandeep Singh rte_kvargs_free(kvlist); 96567fc3ff9SGagandeep Singh return ret; 96667fc3ff9SGagandeep Singh } 96767fc3ff9SGagandeep Singh 96867fc3ff9SGagandeep Singh static int 96967fc3ff9SGagandeep Singh pmd_pfe_probe(struct rte_vdev_device *vdev) 97067fc3ff9SGagandeep Singh { 97167fc3ff9SGagandeep Singh const u32 *prop; 97267fc3ff9SGagandeep Singh const struct device_node *np; 97367fc3ff9SGagandeep Singh const char *name; 97467fc3ff9SGagandeep Singh const uint32_t *addr; 97567fc3ff9SGagandeep Singh uint64_t cbus_addr, ddr_size, cbus_size; 97667fc3ff9SGagandeep Singh int rc = -1, fd = -1, gem_id; 9775253fe37SGagandeep Singh unsigned int ii, interface_count = 0; 97867fc3ff9SGagandeep Singh size_t size = 0; 97967fc3ff9SGagandeep Singh struct pfe_vdev_init_params init_params = { 98067fc3ff9SGagandeep Singh .gem_id = -1 98167fc3ff9SGagandeep Singh }; 98267fc3ff9SGagandeep Singh 98367fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 98467fc3ff9SGagandeep Singh rc = pfe_parse_vdev_init_params(&init_params, vdev); 98567fc3ff9SGagandeep Singh if (rc < 0) 98667fc3ff9SGagandeep Singh return -EINVAL; 98767fc3ff9SGagandeep Singh 988b8907ccfSStephen Hemminger PFE_PMD_LOG(INFO, "Initializing pmd_pfe for %s Given gem-id %d", 989b1bc1afaSGagandeep Singh name, init_params.gem_id); 99067fc3ff9SGagandeep Singh 991b1bc1afaSGagandeep Singh if (g_pfe) { 992b1bc1afaSGagandeep Singh if (g_pfe->nb_devs >= g_pfe->max_intf) { 993b1bc1afaSGagandeep Singh PFE_PMD_ERR("PFE %d dev already created Max is %d", 994b1bc1afaSGagandeep Singh g_pfe->nb_devs, g_pfe->max_intf); 995b1bc1afaSGagandeep Singh return -EINVAL; 996b1bc1afaSGagandeep Singh } 99767fc3ff9SGagandeep Singh goto eth_init; 99867fc3ff9SGagandeep Singh } 99967fc3ff9SGagandeep Singh 100067fc3ff9SGagandeep Singh g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE); 100167fc3ff9SGagandeep Singh if (g_pfe == NULL) 100267fc3ff9SGagandeep Singh return -EINVAL; 100367fc3ff9SGagandeep Singh 100467fc3ff9SGagandeep Singh /* Load the device-tree driver */ 100567fc3ff9SGagandeep Singh rc = of_init(); 1006b1bc1afaSGagandeep Singh if (rc) { 1007b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_init failed with ret: %d", rc); 100867fc3ff9SGagandeep Singh goto err; 1009b1bc1afaSGagandeep Singh } 101067fc3ff9SGagandeep Singh 101167fc3ff9SGagandeep Singh np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); 101267fc3ff9SGagandeep Singh if (!np) { 1013b1bc1afaSGagandeep Singh PFE_PMD_ERR("Invalid device node"); 101467fc3ff9SGagandeep Singh rc = -EINVAL; 101567fc3ff9SGagandeep Singh goto err; 101667fc3ff9SGagandeep Singh } 101767fc3ff9SGagandeep Singh 101867fc3ff9SGagandeep Singh addr = of_get_address(np, 0, &cbus_size, NULL); 1019b1bc1afaSGagandeep Singh if (!addr) { 1020b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_get_address cannot return qman address\n"); 102167fc3ff9SGagandeep Singh goto err; 1022b1bc1afaSGagandeep Singh } 102367fc3ff9SGagandeep Singh cbus_addr = of_translate_address(np, addr); 1024b1bc1afaSGagandeep Singh if (!cbus_addr) { 1025b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_translate_address failed\n"); 102667fc3ff9SGagandeep Singh goto err; 1027b1bc1afaSGagandeep Singh } 102867fc3ff9SGagandeep Singh 102967fc3ff9SGagandeep Singh addr = of_get_address(np, 1, &ddr_size, NULL); 1030b1bc1afaSGagandeep Singh if (!addr) { 1031b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_get_address cannot return qman address\n"); 103267fc3ff9SGagandeep Singh goto err; 1033b1bc1afaSGagandeep Singh } 103467fc3ff9SGagandeep Singh 103567fc3ff9SGagandeep Singh g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); 1036b1bc1afaSGagandeep Singh if (!g_pfe->ddr_phys_baseaddr) { 1037b1bc1afaSGagandeep Singh PFE_PMD_ERR("of_translate_address failed\n"); 103867fc3ff9SGagandeep Singh goto err; 1039b1bc1afaSGagandeep Singh } 104067fc3ff9SGagandeep Singh 10415253fe37SGagandeep Singh g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr); 104267fc3ff9SGagandeep Singh g_pfe->ddr_size = ddr_size; 104367fc3ff9SGagandeep Singh g_pfe->cbus_size = cbus_size; 104467fc3ff9SGagandeep Singh 104567fc3ff9SGagandeep Singh fd = open("/dev/mem", O_RDWR); 104667fc3ff9SGagandeep Singh g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, 104767fc3ff9SGagandeep Singh MAP_SHARED, fd, cbus_addr); 104867fc3ff9SGagandeep Singh close(fd); 104967fc3ff9SGagandeep Singh if (g_pfe->cbus_baseaddr == MAP_FAILED) { 1050b1bc1afaSGagandeep Singh PFE_PMD_ERR("Can not map cbus base"); 105167fc3ff9SGagandeep Singh rc = -EINVAL; 105267fc3ff9SGagandeep Singh goto err; 105367fc3ff9SGagandeep Singh } 105467fc3ff9SGagandeep Singh 105567fc3ff9SGagandeep Singh /* Read interface count */ 105667fc3ff9SGagandeep Singh prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); 105767fc3ff9SGagandeep Singh if (!prop) { 1058b1bc1afaSGagandeep Singh PFE_PMD_ERR("Failed to read number of interfaces"); 105967fc3ff9SGagandeep Singh rc = -ENXIO; 106067fc3ff9SGagandeep Singh goto err_prop; 106167fc3ff9SGagandeep Singh } 106267fc3ff9SGagandeep Singh 106367fc3ff9SGagandeep Singh interface_count = rte_be_to_cpu_32((unsigned int)*prop); 106467fc3ff9SGagandeep Singh if (interface_count <= 0) { 1065b1bc1afaSGagandeep Singh PFE_PMD_ERR("No ethernet interface count : %d", 1066b1bc1afaSGagandeep Singh interface_count); 106767fc3ff9SGagandeep Singh rc = -ENXIO; 106867fc3ff9SGagandeep Singh goto err_prop; 106967fc3ff9SGagandeep Singh } 1070b1bc1afaSGagandeep Singh PFE_PMD_INFO("num interfaces = %d ", interface_count); 1071b1bc1afaSGagandeep Singh 107267fc3ff9SGagandeep Singh g_pfe->max_intf = interface_count; 10735253fe37SGagandeep Singh g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; 10745253fe37SGagandeep Singh 10755253fe37SGagandeep Singh for (ii = 0; ii < interface_count; ii++) { 10765253fe37SGagandeep Singh pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count, 10775253fe37SGagandeep Singh &g_pfe->platform_data); 10785253fe37SGagandeep Singh } 10795253fe37SGagandeep Singh 10805253fe37SGagandeep Singh pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr, 10815253fe37SGagandeep Singh g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size); 10825253fe37SGagandeep Singh 10835253fe37SGagandeep Singh PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION)); 10845253fe37SGagandeep Singh PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION)); 10855253fe37SGagandeep Singh 10865253fe37SGagandeep Singh PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION)); 10875253fe37SGagandeep Singh PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION)); 10885253fe37SGagandeep Singh 10895253fe37SGagandeep Singh PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION)); 10905253fe37SGagandeep Singh PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION)); 10915253fe37SGagandeep Singh PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION)); 10925253fe37SGagandeep Singh 10935253fe37SGagandeep Singh PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION)); 10945253fe37SGagandeep Singh PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION)); 10955253fe37SGagandeep Singh 10965253fe37SGagandeep Singh cbus_emac_base[0] = EMAC1_BASE_ADDR; 10975253fe37SGagandeep Singh cbus_emac_base[1] = EMAC2_BASE_ADDR; 10985253fe37SGagandeep Singh 10995253fe37SGagandeep Singh cbus_gpi_base[0] = EGPI1_BASE_ADDR; 11005253fe37SGagandeep Singh cbus_gpi_base[1] = EGPI2_BASE_ADDR; 11015253fe37SGagandeep Singh 11025253fe37SGagandeep Singh rc = pfe_hif_lib_init(g_pfe); 11035253fe37SGagandeep Singh if (rc < 0) 11045253fe37SGagandeep Singh goto err_hif_lib; 11055253fe37SGagandeep Singh 11065253fe37SGagandeep Singh rc = pfe_hif_init(g_pfe); 11075253fe37SGagandeep Singh if (rc < 0) 11085253fe37SGagandeep Singh goto err_hif; 110967fc3ff9SGagandeep Singh pfe_soc_version_get(); 111067fc3ff9SGagandeep Singh eth_init: 111167fc3ff9SGagandeep Singh if (init_params.gem_id < 0) 111267fc3ff9SGagandeep Singh gem_id = g_pfe->nb_devs; 111367fc3ff9SGagandeep Singh else 111467fc3ff9SGagandeep Singh gem_id = init_params.gem_id; 111567fc3ff9SGagandeep Singh 1116b8907ccfSStephen Hemminger PFE_PMD_LOG(INFO, "Init pmd_pfe for %s gem-id %d(given =%d)", 111767fc3ff9SGagandeep Singh name, gem_id, init_params.gem_id); 111867fc3ff9SGagandeep Singh 111967fc3ff9SGagandeep Singh rc = pfe_eth_init(vdev, g_pfe, gem_id); 112067fc3ff9SGagandeep Singh if (rc < 0) 112167fc3ff9SGagandeep Singh goto err_eth; 112267fc3ff9SGagandeep Singh else 112367fc3ff9SGagandeep Singh g_pfe->nb_devs++; 112467fc3ff9SGagandeep Singh 112567fc3ff9SGagandeep Singh return 0; 112667fc3ff9SGagandeep Singh 112767fc3ff9SGagandeep Singh err_eth: 11285253fe37SGagandeep Singh pfe_hif_exit(g_pfe); 11295253fe37SGagandeep Singh 11305253fe37SGagandeep Singh err_hif: 11315253fe37SGagandeep Singh pfe_hif_lib_exit(g_pfe); 11325253fe37SGagandeep Singh 11335253fe37SGagandeep Singh err_hif_lib: 113467fc3ff9SGagandeep Singh err_prop: 113567fc3ff9SGagandeep Singh munmap(g_pfe->cbus_baseaddr, cbus_size); 113667fc3ff9SGagandeep Singh err: 113767fc3ff9SGagandeep Singh rte_free(g_pfe); 113867fc3ff9SGagandeep Singh return rc; 113967fc3ff9SGagandeep Singh } 114067fc3ff9SGagandeep Singh 114167fc3ff9SGagandeep Singh static int 114267fc3ff9SGagandeep Singh pmd_pfe_remove(struct rte_vdev_device *vdev) 114367fc3ff9SGagandeep Singh { 114467fc3ff9SGagandeep Singh const char *name; 114567fc3ff9SGagandeep Singh struct rte_eth_dev *eth_dev = NULL; 114657803c5eSSachin Saxena int ret = 0; 114767fc3ff9SGagandeep Singh 114867fc3ff9SGagandeep Singh name = rte_vdev_device_name(vdev); 114967fc3ff9SGagandeep Singh if (name == NULL) 115067fc3ff9SGagandeep Singh return -EINVAL; 115167fc3ff9SGagandeep Singh 1152b1bc1afaSGagandeep Singh PFE_PMD_INFO("Closing eventdev sw device %s", name); 1153b1bc1afaSGagandeep Singh 115467fc3ff9SGagandeep Singh if (!g_pfe) 115567fc3ff9SGagandeep Singh return 0; 115667fc3ff9SGagandeep Singh 115767fc3ff9SGagandeep Singh eth_dev = rte_eth_dev_allocated(name); 115857803c5eSSachin Saxena if (eth_dev) { 115957803c5eSSachin Saxena pfe_eth_close(eth_dev); 116057803c5eSSachin Saxena ret = rte_eth_dev_release_port(eth_dev); 11615253fe37SGagandeep Singh } 116257803c5eSSachin Saxena 116357803c5eSSachin Saxena return ret; 116467fc3ff9SGagandeep Singh } 116567fc3ff9SGagandeep Singh 116667fc3ff9SGagandeep Singh static 116767fc3ff9SGagandeep Singh struct rte_vdev_driver pmd_pfe_drv = { 116867fc3ff9SGagandeep Singh .probe = pmd_pfe_probe, 116967fc3ff9SGagandeep Singh .remove = pmd_pfe_remove, 117067fc3ff9SGagandeep Singh }; 117167fc3ff9SGagandeep Singh 117267fc3ff9SGagandeep Singh RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); 117367fc3ff9SGagandeep Singh RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> "); 11749c99878aSJerin Jacob RTE_LOG_REGISTER(pfe_logtype_pmd, pmd.net.pfe, NOTICE); 1175