1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2018-2019 NXP 3 */ 4 5 #include <sys/ioctl.h> 6 #include <sys/epoll.h> 7 #include <rte_kvargs.h> 8 #include <ethdev_vdev.h> 9 #include <bus_vdev_driver.h> 10 #include <rte_ether.h> 11 #include <dpaa_of.h> 12 13 #include "pfe_logs.h" 14 #include "pfe_mod.h" 15 16 #define PFE_MAX_MACS 1 /* we can support up to 4 MACs per IF */ 17 #define PFE_VDEV_GEM_ID_ARG "intf" 18 19 struct pfe_vdev_init_params { 20 int8_t gem_id; 21 }; 22 static struct pfe *g_pfe; 23 /* Supported Rx offloads */ 24 static uint64_t dev_rx_offloads_sup = 25 RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | 26 RTE_ETH_RX_OFFLOAD_UDP_CKSUM | 27 RTE_ETH_RX_OFFLOAD_TCP_CKSUM; 28 29 /* Supported Tx offloads */ 30 static uint64_t dev_tx_offloads_sup = 31 RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | 32 RTE_ETH_TX_OFFLOAD_UDP_CKSUM | 33 RTE_ETH_TX_OFFLOAD_TCP_CKSUM; 34 35 /* TODO: make pfe_svr a runtime option. 36 * Driver should be able to get the SVR 37 * information from HW. 38 */ 39 unsigned int pfe_svr = SVR_LS1012A_REV1; 40 static void *cbus_emac_base[3]; 41 static void *cbus_gpi_base[3]; 42 43 /* pfe_gemac_init 44 */ 45 static int 46 pfe_gemac_init(struct pfe_eth_priv_s *priv) 47 { 48 struct gemac_cfg cfg; 49 50 cfg.speed = SPEED_1000M; 51 cfg.duplex = DUPLEX_FULL; 52 53 gemac_set_config(priv->EMAC_baseaddr, &cfg); 54 gemac_allow_broadcast(priv->EMAC_baseaddr); 55 gemac_enable_1536_rx(priv->EMAC_baseaddr); 56 gemac_enable_stacked_vlan(priv->EMAC_baseaddr); 57 gemac_enable_pause_rx(priv->EMAC_baseaddr); 58 gemac_set_bus_width(priv->EMAC_baseaddr, 64); 59 gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); 60 61 return 0; 62 } 63 64 static void 65 pfe_soc_version_get(void) 66 { 67 FILE *svr_file = NULL; 68 unsigned int svr_ver = 0; 69 70 PMD_INIT_FUNC_TRACE(); 71 72 svr_file = fopen(PFE_SOC_ID_FILE, "r"); 73 if (!svr_file) { 74 PFE_PMD_ERR("Unable to open SoC device"); 75 return; /* Not supported on this infra */ 76 } 77 78 if (fscanf(svr_file, "svr:%x", &svr_ver) > 0) 79 pfe_svr = svr_ver; 80 else 81 PFE_PMD_ERR("Unable to read SoC device"); 82 83 fclose(svr_file); 84 } 85 86 static int pfe_eth_start(struct pfe_eth_priv_s *priv) 87 { 88 gpi_enable(priv->GPI_baseaddr); 89 gemac_enable(priv->EMAC_baseaddr); 90 91 return 0; 92 } 93 94 static void 95 pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int 96 __rte_unused from_tx, __rte_unused int n_desc) 97 { 98 struct rte_mbuf *mbuf; 99 unsigned int flags; 100 101 /* Clean HIF and client queue */ 102 while ((mbuf = hif_lib_tx_get_next_complete(&priv->client, 103 tx_q_num, &flags, 104 HIF_TX_DESC_NT))) { 105 if (mbuf) { 106 mbuf->next = NULL; 107 mbuf->nb_segs = 1; 108 rte_pktmbuf_free(mbuf); 109 } 110 } 111 } 112 113 114 static void 115 pfe_eth_flush_tx(struct pfe_eth_priv_s *priv) 116 { 117 unsigned int ii; 118 119 for (ii = 0; ii < emac_txq_cnt; ii++) 120 pfe_eth_flush_txQ(priv, ii, 0, 0); 121 } 122 123 static int 124 pfe_eth_event_handler(void *data, int event, __rte_unused int qno) 125 { 126 struct pfe_eth_priv_s *priv = data; 127 128 switch (event) { 129 case EVENT_TXDONE_IND: 130 pfe_eth_flush_tx(priv); 131 hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0); 132 break; 133 case EVENT_HIGH_RX_WM: 134 default: 135 break; 136 } 137 138 return 0; 139 } 140 141 static uint16_t 142 pfe_recv_pkts_on_intr(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 143 { 144 struct hif_client_rx_queue *queue = rxq; 145 struct pfe_eth_priv_s *priv = queue->priv; 146 struct epoll_event epoll_ev; 147 uint64_t ticks = 1; /* 1 msec */ 148 int ret; 149 int have_something, work_done; 150 151 #define RESET_STATUS (HIF_INT | HIF_RXPKT_INT) 152 153 /*TODO can we remove this cleanup from here?*/ 154 pfe_tx_do_cleanup(priv->pfe); 155 have_something = pfe_hif_rx_process(priv->pfe, nb_pkts); 156 work_done = hif_lib_receive_pkt(rxq, priv->pfe->hif.shm->pool, 157 rx_pkts, nb_pkts); 158 159 if (!have_something || !work_done) { 160 writel(RESET_STATUS, HIF_INT_SRC); 161 writel(readl(HIF_INT_ENABLE) | HIF_RXPKT_INT, HIF_INT_ENABLE); 162 ret = epoll_wait(priv->pfe->hif.epoll_fd, &epoll_ev, 1, ticks); 163 if (ret < 0 && errno != EINTR) 164 PFE_PMD_ERR("epoll_wait fails with %d", errno); 165 } 166 167 return work_done; 168 } 169 170 static uint16_t 171 pfe_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 172 { 173 struct hif_client_rx_queue *queue = rxq; 174 struct pfe_eth_priv_s *priv = queue->priv; 175 struct rte_mempool *pool; 176 177 /*TODO can we remove this cleanup from here?*/ 178 pfe_tx_do_cleanup(priv->pfe); 179 pfe_hif_rx_process(priv->pfe, nb_pkts); 180 pool = priv->pfe->hif.shm->pool; 181 182 return hif_lib_receive_pkt(rxq, pool, rx_pkts, nb_pkts); 183 } 184 185 static uint16_t 186 pfe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 187 { 188 struct hif_client_tx_queue *queue = tx_queue; 189 struct pfe_eth_priv_s *priv = queue->priv; 190 struct rte_eth_stats *stats = &priv->stats; 191 int i; 192 193 for (i = 0; i < nb_pkts; i++) { 194 if (tx_pkts[i]->nb_segs > 1) { 195 struct rte_mbuf *mbuf; 196 int j; 197 198 hif_lib_xmit_pkt(&priv->client, queue->queue_id, 199 (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 200 tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 201 tx_pkts[i]->data_len, 0x0, HIF_FIRST_BUFFER, 202 tx_pkts[i]); 203 204 mbuf = tx_pkts[i]->next; 205 for (j = 0; j < (tx_pkts[i]->nb_segs - 2); j++) { 206 hif_lib_xmit_pkt(&priv->client, queue->queue_id, 207 (void *)(size_t)rte_pktmbuf_iova(mbuf), 208 mbuf->buf_addr + mbuf->data_off, 209 mbuf->data_len, 210 0x0, 0x0, mbuf); 211 mbuf = mbuf->next; 212 } 213 214 hif_lib_xmit_pkt(&priv->client, queue->queue_id, 215 (void *)(size_t)rte_pktmbuf_iova(mbuf), 216 mbuf->buf_addr + mbuf->data_off, 217 mbuf->data_len, 218 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID, 219 mbuf); 220 } else { 221 hif_lib_xmit_pkt(&priv->client, queue->queue_id, 222 (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), 223 tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, 224 tx_pkts[i]->pkt_len, 0 /*ctrl*/, 225 HIF_FIRST_BUFFER | HIF_LAST_BUFFER | 226 HIF_DATA_VALID, 227 tx_pkts[i]); 228 } 229 stats->obytes += tx_pkts[i]->pkt_len; 230 hif_tx_dma_start(); 231 } 232 stats->opackets += nb_pkts; 233 pfe_tx_do_cleanup(priv->pfe); 234 235 return nb_pkts; 236 } 237 238 static int 239 pfe_eth_open(struct rte_eth_dev *dev) 240 { 241 struct pfe_eth_priv_s *priv = dev->data->dev_private; 242 struct hif_client_s *client; 243 struct hif_shm *hif_shm; 244 uint16_t i; 245 int rc; 246 247 /* Register client driver with HIF */ 248 client = &priv->client; 249 250 if (client->pfe) { 251 hif_shm = client->pfe->hif.shm; 252 /* TODO please remove the below code of if block, once we add 253 * the proper cleanup in eth_close 254 */ 255 if (!test_bit(PFE_CL_GEM0 + priv->id, 256 &hif_shm->g_client_status[0])) { 257 /* Register client driver with HIF */ 258 memset(client, 0, sizeof(*client)); 259 client->id = PFE_CL_GEM0 + priv->id; 260 client->tx_qn = emac_txq_cnt; 261 client->rx_qn = EMAC_RXQ_CNT; 262 client->priv = priv; 263 client->pfe = priv->pfe; 264 client->port_id = dev->data->port_id; 265 client->event_handler = pfe_eth_event_handler; 266 267 client->tx_qsize = EMAC_TXQ_DEPTH; 268 client->rx_qsize = EMAC_RXQ_DEPTH; 269 270 rc = hif_lib_client_register(client); 271 if (rc) { 272 PFE_PMD_ERR("hif_lib_client_register(%d)" 273 " failed", client->id); 274 goto err0; 275 } 276 } else { 277 /* Freeing the packets if already exists */ 278 int ret = 0; 279 struct rte_mbuf *rx_pkts[32]; 280 /* TODO multiqueue support */ 281 ret = hif_lib_receive_pkt(&client->rx_q[0], 282 hif_shm->pool, rx_pkts, 32); 283 while (ret) { 284 int i; 285 for (i = 0; i < ret; i++) 286 rte_pktmbuf_free(rx_pkts[i]); 287 ret = hif_lib_receive_pkt(&client->rx_q[0], 288 hif_shm->pool, 289 rx_pkts, 32); 290 } 291 } 292 } else { 293 /* Register client driver with HIF */ 294 memset(client, 0, sizeof(*client)); 295 client->id = PFE_CL_GEM0 + priv->id; 296 client->tx_qn = emac_txq_cnt; 297 client->rx_qn = EMAC_RXQ_CNT; 298 client->priv = priv; 299 client->pfe = priv->pfe; 300 client->port_id = dev->data->port_id; 301 client->event_handler = pfe_eth_event_handler; 302 303 client->tx_qsize = EMAC_TXQ_DEPTH; 304 client->rx_qsize = EMAC_RXQ_DEPTH; 305 306 rc = hif_lib_client_register(client); 307 if (rc) { 308 PFE_PMD_ERR("hif_lib_client_register(%d) failed", 309 client->id); 310 goto err0; 311 } 312 } 313 rc = pfe_eth_start(priv); 314 dev->rx_pkt_burst = &pfe_recv_pkts; 315 dev->tx_pkt_burst = &pfe_xmit_pkts; 316 /* If no prefetch is configured. */ 317 if (getenv("PFE_INTR_SUPPORT")) { 318 dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; 319 PFE_PMD_INFO("PFE INTERRUPT Mode enabled"); 320 } 321 322 for (i = 0; i < dev->data->nb_rx_queues; i++) 323 dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 324 for (i = 0; i < dev->data->nb_tx_queues; i++) 325 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 326 327 err0: 328 return rc; 329 } 330 331 static int 332 pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) 333 { 334 int pfe_cdev_fd; 335 336 if (priv == NULL) 337 return -1; 338 339 pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); 340 if (pfe_cdev_fd < 0) { 341 PFE_PMD_WARN("Unable to open PFE device file (%s).", 342 PFE_CDEV_PATH); 343 PFE_PMD_WARN("Link status update will not be available."); 344 priv->link_fd = PFE_CDEV_INVALID_FD; 345 return -1; 346 } 347 348 priv->link_fd = pfe_cdev_fd; 349 350 return 0; 351 } 352 353 static void 354 pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) 355 { 356 if (priv == NULL) 357 return; 358 359 if (priv->link_fd != PFE_CDEV_INVALID_FD) { 360 close(priv->link_fd); 361 priv->link_fd = PFE_CDEV_INVALID_FD; 362 } 363 } 364 365 static int 366 pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) 367 { 368 struct pfe_eth_priv_s *priv = dev->data->dev_private; 369 uint16_t i; 370 371 dev->data->dev_started = 0; 372 373 gemac_disable(priv->EMAC_baseaddr); 374 gpi_disable(priv->GPI_baseaddr); 375 376 dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; 377 dev->tx_pkt_burst = rte_eth_pkt_burst_dummy; 378 379 for (i = 0; i < dev->data->nb_rx_queues; i++) 380 dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 381 for (i = 0; i < dev->data->nb_tx_queues; i++) 382 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 383 384 return 0; 385 } 386 387 static int 388 pfe_eth_close(struct rte_eth_dev *dev) 389 { 390 int ret; 391 PMD_INIT_FUNC_TRACE(); 392 393 if (!dev) 394 return -1; 395 396 if (!g_pfe) 397 return -1; 398 399 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 400 return 0; 401 402 ret = pfe_eth_stop(dev); 403 /* Close the device file for link status */ 404 pfe_eth_close_cdev(dev->data->dev_private); 405 406 munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size); 407 g_pfe->nb_devs--; 408 409 if (g_pfe->nb_devs == 0) { 410 pfe_hif_exit(g_pfe); 411 pfe_hif_lib_exit(g_pfe); 412 rte_free(g_pfe); 413 g_pfe = NULL; 414 } 415 416 return ret; 417 } 418 419 static int 420 pfe_eth_configure(struct rte_eth_dev *dev __rte_unused) 421 { 422 return 0; 423 } 424 425 static int 426 pfe_eth_info(struct rte_eth_dev *dev, 427 struct rte_eth_dev_info *dev_info) 428 { 429 dev_info->max_mac_addrs = PFE_MAX_MACS; 430 dev_info->max_rx_queues = dev->data->nb_rx_queues; 431 dev_info->max_tx_queues = dev->data->nb_tx_queues; 432 dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE; 433 dev_info->min_mtu = RTE_ETHER_MIN_MTU; 434 dev_info->rx_offload_capa = dev_rx_offloads_sup; 435 dev_info->tx_offload_capa = dev_tx_offloads_sup; 436 if (pfe_svr == SVR_LS1012A_REV1) { 437 dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; 438 dev_info->max_mtu = MAX_MTU_ON_REV1; 439 } else { 440 dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE; 441 dev_info->max_mtu = JUMBO_FRAME_SIZE - PFE_ETH_OVERHEAD; 442 } 443 444 return 0; 445 } 446 447 /* Only first mb_pool given on first call of this API will be used 448 * in whole system, also nb_rx_desc and rx_conf are unused params 449 */ 450 static int 451 pfe_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, 452 __rte_unused uint16_t nb_rx_desc, 453 __rte_unused unsigned int socket_id, 454 __rte_unused const struct rte_eth_rxconf *rx_conf, 455 struct rte_mempool *mb_pool) 456 { 457 int rc = 0; 458 struct pfe *pfe; 459 struct pfe_eth_priv_s *priv = dev->data->dev_private; 460 461 pfe = priv->pfe; 462 463 if (queue_idx >= EMAC_RXQ_CNT) { 464 PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 465 queue_idx, EMAC_RXQ_CNT); 466 return -1; 467 } 468 469 if (!pfe->hif.setuped) { 470 rc = pfe_hif_shm_init(pfe->hif.shm, mb_pool); 471 if (rc) { 472 PFE_PMD_ERR("Could not allocate buffer descriptors"); 473 return -1; 474 } 475 476 pfe->hif.shm->pool = mb_pool; 477 if (pfe_hif_init_buffers(&pfe->hif)) { 478 PFE_PMD_ERR("Could not initialize buffer descriptors"); 479 return -1; 480 } 481 hif_init(); 482 hif_rx_enable(); 483 hif_tx_enable(); 484 pfe->hif.setuped = 1; 485 } 486 dev->data->rx_queues[queue_idx] = &priv->client.rx_q[queue_idx]; 487 priv->client.rx_q[queue_idx].queue_id = queue_idx; 488 489 return 0; 490 } 491 492 static int 493 pfe_tx_queue_setup(struct rte_eth_dev *dev, 494 uint16_t queue_idx, 495 __rte_unused uint16_t nb_desc, 496 __rte_unused unsigned int socket_id, 497 __rte_unused const struct rte_eth_txconf *tx_conf) 498 { 499 struct pfe_eth_priv_s *priv = dev->data->dev_private; 500 501 if (queue_idx >= emac_txq_cnt) { 502 PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 503 queue_idx, emac_txq_cnt); 504 return -1; 505 } 506 dev->data->tx_queues[queue_idx] = &priv->client.tx_q[queue_idx]; 507 priv->client.tx_q[queue_idx].queue_id = queue_idx; 508 return 0; 509 } 510 511 static const uint32_t * 512 pfe_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements) 513 { 514 static const uint32_t ptypes[] = { 515 /*todo -= add more types */ 516 RTE_PTYPE_L2_ETHER, 517 RTE_PTYPE_L3_IPV4, 518 RTE_PTYPE_L3_IPV4_EXT, 519 RTE_PTYPE_L3_IPV6, 520 RTE_PTYPE_L3_IPV6_EXT, 521 RTE_PTYPE_L4_TCP, 522 RTE_PTYPE_L4_UDP, 523 RTE_PTYPE_L4_SCTP, 524 }; 525 526 if (dev->rx_pkt_burst == pfe_recv_pkts || 527 dev->rx_pkt_burst == pfe_recv_pkts_on_intr) { 528 *no_of_elements = RTE_DIM(ptypes); 529 return ptypes; 530 } 531 return NULL; 532 } 533 534 static inline int 535 pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev, 536 struct rte_eth_link *link) 537 { 538 struct rte_eth_link *dst = link; 539 struct rte_eth_link *src = &dev->data->dev_link; 540 541 if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 542 *(uint64_t *)src) == 0) 543 return -1; 544 545 return 0; 546 } 547 548 static inline int 549 pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev, 550 struct rte_eth_link *link) 551 { 552 struct rte_eth_link *dst = &dev->data->dev_link; 553 struct rte_eth_link *src = link; 554 555 if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 556 *(uint64_t *)src) == 0) 557 return -1; 558 559 return 0; 560 } 561 562 static int 563 pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) 564 { 565 int ret, ioctl_cmd = 0; 566 struct pfe_eth_priv_s *priv = dev->data->dev_private; 567 struct rte_eth_link link, old; 568 unsigned int lstatus = 1; 569 570 memset(&old, 0, sizeof(old)); 571 memset(&link, 0, sizeof(struct rte_eth_link)); 572 573 pfe_eth_atomic_read_link_status(dev, &old); 574 575 /* Read from PFE CDEV, status of link, if file was successfully 576 * opened. 577 */ 578 if (priv->link_fd != PFE_CDEV_INVALID_FD) { 579 if (priv->id == 0) 580 ioctl_cmd = PFE_CDEV_ETH0_STATE_GET; 581 if (priv->id == 1) 582 ioctl_cmd = PFE_CDEV_ETH1_STATE_GET; 583 584 ret = ioctl(priv->link_fd, ioctl_cmd, &lstatus); 585 if (ret != 0) { 586 PFE_PMD_ERR("Unable to fetch link status (ioctl)"); 587 return -1; 588 } 589 PFE_PMD_DEBUG("Fetched link state (%d) for dev %d.", 590 lstatus, priv->id); 591 } 592 593 if (old.link_status == lstatus) { 594 /* no change in status */ 595 PFE_PMD_DEBUG("No change in link status; Not updating."); 596 return -1; 597 } 598 599 link.link_status = lstatus; 600 link.link_speed = RTE_ETH_LINK_SPEED_1G; 601 link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX; 602 link.link_autoneg = RTE_ETH_LINK_AUTONEG; 603 604 pfe_eth_atomic_write_link_status(dev, &link); 605 606 PFE_PMD_INFO("Port (%d) link is %s", dev->data->port_id, 607 link.link_status ? "up" : "down"); 608 609 return 0; 610 } 611 612 static int 613 pfe_promiscuous_enable(struct rte_eth_dev *dev) 614 { 615 struct pfe_eth_priv_s *priv = dev->data->dev_private; 616 617 priv->promisc = 1; 618 dev->data->promiscuous = 1; 619 gemac_enable_copy_all(priv->EMAC_baseaddr); 620 621 return 0; 622 } 623 624 static int 625 pfe_promiscuous_disable(struct rte_eth_dev *dev) 626 { 627 struct pfe_eth_priv_s *priv = dev->data->dev_private; 628 629 priv->promisc = 0; 630 dev->data->promiscuous = 0; 631 gemac_disable_copy_all(priv->EMAC_baseaddr); 632 633 return 0; 634 } 635 636 static int 637 pfe_allmulticast_enable(struct rte_eth_dev *dev) 638 { 639 struct pfe_eth_priv_s *priv = dev->data->dev_private; 640 struct pfe_mac_addr hash_addr; /* hash register structure */ 641 642 /* Set the hash to rx all multicast frames */ 643 hash_addr.bottom = 0xFFFFFFFF; 644 hash_addr.top = 0xFFFFFFFF; 645 gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); 646 dev->data->all_multicast = 1; 647 648 return 0; 649 } 650 651 static int 652 pfe_link_down(struct rte_eth_dev *dev) 653 { 654 return pfe_eth_stop(dev); 655 } 656 657 static int 658 pfe_link_up(struct rte_eth_dev *dev) 659 { 660 struct pfe_eth_priv_s *priv = dev->data->dev_private; 661 662 pfe_eth_start(priv); 663 return 0; 664 } 665 666 static int 667 pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 668 { 669 struct pfe_eth_priv_s *priv = dev->data->dev_private; 670 uint16_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 671 672 /*TODO Support VLAN*/ 673 return gemac_set_rx(priv->EMAC_baseaddr, frame_size); 674 } 675 676 /* pfe_eth_enet_addr_byte_mac 677 */ 678 static int 679 pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, 680 struct pfe_mac_addr *enet_addr) 681 { 682 if (!enet_byte_addr || !enet_addr) { 683 return -1; 684 685 } else { 686 enet_addr->bottom = enet_byte_addr[0] | 687 (enet_byte_addr[1] << 8) | 688 (enet_byte_addr[2] << 16) | 689 (enet_byte_addr[3] << 24); 690 enet_addr->top = enet_byte_addr[4] | 691 (enet_byte_addr[5] << 8); 692 return 0; 693 } 694 } 695 696 static int 697 pfe_dev_set_mac_addr(struct rte_eth_dev *dev, 698 struct rte_ether_addr *addr) 699 { 700 struct pfe_eth_priv_s *priv = dev->data->dev_private; 701 struct pfe_mac_addr spec_addr; 702 int ret; 703 704 ret = pfe_eth_enet_addr_byte_mac(addr->addr_bytes, &spec_addr); 705 if (ret) 706 return ret; 707 708 gemac_set_laddrN(priv->EMAC_baseaddr, 709 (struct pfe_mac_addr *)&spec_addr, 1); 710 rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 711 return 0; 712 } 713 714 static int 715 pfe_stats_get(struct rte_eth_dev *dev, 716 struct rte_eth_stats *stats) 717 { 718 struct pfe_eth_priv_s *priv = dev->data->dev_private; 719 struct rte_eth_stats *eth_stats = &priv->stats; 720 721 if (stats == NULL) 722 return -1; 723 724 memset(stats, 0, sizeof(struct rte_eth_stats)); 725 726 stats->ipackets = eth_stats->ipackets; 727 stats->ibytes = eth_stats->ibytes; 728 stats->opackets = eth_stats->opackets; 729 stats->obytes = eth_stats->obytes; 730 731 return 0; 732 } 733 734 static const struct eth_dev_ops ops = { 735 .dev_start = pfe_eth_open, 736 .dev_stop = pfe_eth_stop, 737 .dev_close = pfe_eth_close, 738 .dev_configure = pfe_eth_configure, 739 .dev_infos_get = pfe_eth_info, 740 .rx_queue_setup = pfe_rx_queue_setup, 741 .tx_queue_setup = pfe_tx_queue_setup, 742 .dev_supported_ptypes_get = pfe_supported_ptypes_get, 743 .link_update = pfe_eth_link_update, 744 .promiscuous_enable = pfe_promiscuous_enable, 745 .promiscuous_disable = pfe_promiscuous_disable, 746 .allmulticast_enable = pfe_allmulticast_enable, 747 .dev_set_link_down = pfe_link_down, 748 .dev_set_link_up = pfe_link_up, 749 .mtu_set = pfe_mtu_set, 750 .mac_addr_set = pfe_dev_set_mac_addr, 751 .stats_get = pfe_stats_get, 752 }; 753 754 static int 755 pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) 756 { 757 struct rte_eth_dev *eth_dev = NULL; 758 struct pfe_eth_priv_s *priv = NULL; 759 struct ls1012a_eth_platform_data *einfo; 760 struct ls1012a_pfe_platform_data *pfe_info; 761 struct rte_ether_addr addr; 762 int err; 763 764 eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); 765 if (eth_dev == NULL) 766 return -ENOMEM; 767 768 /* Extract platform data */ 769 pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data; 770 if (!pfe_info) { 771 PFE_PMD_ERR("pfe missing additional platform data"); 772 err = -ENODEV; 773 goto err0; 774 } 775 776 einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata; 777 778 /* einfo never be NULL, but no harm in having this check */ 779 if (!einfo) { 780 PFE_PMD_ERR("pfe missing additional gemacs platform data"); 781 err = -ENODEV; 782 goto err0; 783 } 784 785 priv = eth_dev->data->dev_private; 786 priv->ndev = eth_dev; 787 priv->id = einfo[id].gem_id; 788 priv->pfe = pfe; 789 790 pfe->eth.eth_priv[id] = priv; 791 792 /* Set the info in the priv to the current info */ 793 priv->einfo = &einfo[id]; 794 priv->EMAC_baseaddr = cbus_emac_base[id]; 795 priv->PHY_baseaddr = cbus_emac_base[id]; 796 priv->GPI_baseaddr = cbus_gpi_base[id]; 797 798 #define HIF_GEMAC_TMUQ_BASE 6 799 priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); 800 priv->high_tmu_q = priv->low_tmu_q + 1; 801 802 rte_spinlock_init(&priv->lock); 803 804 /* Copy the station address into the dev structure, */ 805 eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", 806 ETHER_ADDR_LEN * PFE_MAX_MACS, 0); 807 if (eth_dev->data->mac_addrs == NULL) { 808 PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses", 809 ETHER_ADDR_LEN * PFE_MAX_MACS); 810 err = -ENOMEM; 811 goto err0; 812 } 813 814 memcpy(addr.addr_bytes, priv->einfo->mac_addr, 815 ETH_ALEN); 816 817 pfe_dev_set_mac_addr(eth_dev, &addr); 818 rte_ether_addr_copy(&addr, ð_dev->data->mac_addrs[0]); 819 820 eth_dev->data->mtu = 1500; 821 eth_dev->dev_ops = &ops; 822 err = pfe_eth_stop(eth_dev); 823 if (err != 0) 824 goto err0; 825 pfe_gemac_init(priv); 826 827 eth_dev->data->nb_rx_queues = 1; 828 eth_dev->data->nb_tx_queues = 1; 829 830 /* For link status, open the PFE CDEV; Error from this function 831 * is silently ignored; In case of error, the link status will not 832 * be available. 833 */ 834 pfe_eth_open_cdev(priv); 835 rte_eth_dev_probing_finish(eth_dev); 836 837 return 0; 838 err0: 839 rte_eth_dev_release_port(eth_dev); 840 return err; 841 } 842 843 static int 844 pfe_get_gemac_if_proprties(struct pfe *pfe, 845 __rte_unused const struct device_node *parent, 846 unsigned int port, unsigned int if_cnt, 847 struct ls1012a_pfe_platform_data *pdata) 848 { 849 const struct device_node *gem = NULL; 850 size_t size; 851 unsigned int ii = 0, phy_id = 0; 852 const u32 *addr; 853 const void *mac_addr; 854 855 for (ii = 0; ii < if_cnt; ii++) { 856 gem = of_get_next_child(parent, gem); 857 if (!gem) 858 goto err; 859 addr = of_get_property(gem, "reg", &size); 860 if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port)) 861 break; 862 } 863 864 if (ii >= if_cnt) { 865 PFE_PMD_ERR("Failed to find interface = %d", if_cnt); 866 goto err; 867 } 868 869 pdata->ls1012a_eth_pdata[port].gem_id = port; 870 871 mac_addr = of_get_mac_address(gem); 872 873 if (mac_addr) { 874 memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, 875 ETH_ALEN); 876 } 877 878 addr = of_get_property(gem, "fsl,mdio-mux-val", &size); 879 if (!addr) { 880 PFE_PMD_ERR("Invalid mdio-mux-val...."); 881 } else { 882 phy_id = rte_be_to_cpu_32((unsigned int)*addr); 883 pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; 884 } 885 if (pdata->ls1012a_eth_pdata[port].phy_id < 32) 886 pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = 887 pdata->ls1012a_eth_pdata[port].mdio_muxval; 888 889 return 0; 890 891 err: 892 return -1; 893 } 894 895 /* Parse integer from integer argument */ 896 static int 897 parse_integer_arg(const char *key __rte_unused, 898 const char *value, void *extra_args) 899 { 900 int i; 901 char *end; 902 errno = 0; 903 904 i = strtol(value, &end, 10); 905 if (*end != 0 || errno != 0 || i < 0 || i > 1) { 906 PFE_PMD_ERR("Supported Port IDS are 0 and 1"); 907 return -EINVAL; 908 } 909 910 *((uint32_t *)extra_args) = i; 911 912 return 0; 913 } 914 915 static int 916 pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params, 917 struct rte_vdev_device *dev) 918 { 919 struct rte_kvargs *kvlist = NULL; 920 int ret = 0; 921 922 static const char * const pfe_vdev_valid_params[] = { 923 PFE_VDEV_GEM_ID_ARG, 924 NULL 925 }; 926 927 const char *input_args = rte_vdev_device_args(dev); 928 929 if (!input_args) 930 return -1; 931 932 kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params); 933 if (kvlist == NULL) 934 return -1; 935 936 ret = rte_kvargs_process(kvlist, 937 PFE_VDEV_GEM_ID_ARG, 938 &parse_integer_arg, 939 ¶ms->gem_id); 940 rte_kvargs_free(kvlist); 941 return ret; 942 } 943 944 static int 945 pmd_pfe_probe(struct rte_vdev_device *vdev) 946 { 947 const u32 *prop; 948 const struct device_node *np; 949 const char *name; 950 const uint32_t *addr; 951 uint64_t cbus_addr, ddr_size, cbus_size; 952 int rc = -1, fd = -1, gem_id; 953 unsigned int ii, interface_count = 0; 954 size_t size = 0; 955 struct pfe_vdev_init_params init_params = { 956 .gem_id = -1 957 }; 958 959 name = rte_vdev_device_name(vdev); 960 rc = pfe_parse_vdev_init_params(&init_params, vdev); 961 if (rc < 0) 962 return -EINVAL; 963 964 PFE_PMD_LOG(INFO, "Initializing pmd_pfe for %s Given gem-id %d", 965 name, init_params.gem_id); 966 967 if (g_pfe) { 968 if (g_pfe->nb_devs >= g_pfe->max_intf) { 969 PFE_PMD_ERR("PFE %d dev already created Max is %d", 970 g_pfe->nb_devs, g_pfe->max_intf); 971 return -EINVAL; 972 } 973 goto eth_init; 974 } 975 976 g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE); 977 if (g_pfe == NULL) 978 return -EINVAL; 979 980 /* Load the device-tree driver */ 981 rc = of_init(); 982 if (rc) { 983 PFE_PMD_ERR("of_init failed with ret: %d", rc); 984 goto err; 985 } 986 987 np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); 988 if (!np) { 989 PFE_PMD_ERR("Invalid device node"); 990 rc = -EINVAL; 991 goto err; 992 } 993 994 addr = of_get_address(np, 0, &cbus_size, NULL); 995 if (!addr) { 996 PFE_PMD_ERR("of_get_address cannot return qman address"); 997 goto err; 998 } 999 cbus_addr = of_translate_address(np, addr); 1000 if (!cbus_addr) { 1001 PFE_PMD_ERR("of_translate_address failed"); 1002 goto err; 1003 } 1004 1005 addr = of_get_address(np, 1, &ddr_size, NULL); 1006 if (!addr) { 1007 PFE_PMD_ERR("of_get_address cannot return qman address"); 1008 goto err; 1009 } 1010 1011 g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); 1012 if (!g_pfe->ddr_phys_baseaddr) { 1013 PFE_PMD_ERR("of_translate_address failed"); 1014 goto err; 1015 } 1016 1017 g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr); 1018 g_pfe->ddr_size = ddr_size; 1019 g_pfe->cbus_size = cbus_size; 1020 1021 fd = open("/dev/mem", O_RDWR); 1022 g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, 1023 MAP_SHARED, fd, cbus_addr); 1024 close(fd); 1025 if (g_pfe->cbus_baseaddr == MAP_FAILED) { 1026 PFE_PMD_ERR("Can not map cbus base"); 1027 rc = -EINVAL; 1028 goto err; 1029 } 1030 1031 /* Read interface count */ 1032 prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); 1033 if (!prop) { 1034 PFE_PMD_ERR("Failed to read number of interfaces"); 1035 rc = -ENXIO; 1036 goto err_prop; 1037 } 1038 1039 interface_count = rte_be_to_cpu_32((unsigned int)*prop); 1040 if (interface_count <= 0) { 1041 PFE_PMD_ERR("No ethernet interface count : %d", 1042 interface_count); 1043 rc = -ENXIO; 1044 goto err_prop; 1045 } 1046 PFE_PMD_INFO("num interfaces = %d ", interface_count); 1047 1048 g_pfe->max_intf = interface_count; 1049 g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; 1050 1051 for (ii = 0; ii < interface_count; ii++) { 1052 pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count, 1053 &g_pfe->platform_data); 1054 } 1055 1056 pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr, 1057 g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size); 1058 1059 PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION)); 1060 PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION)); 1061 1062 PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION)); 1063 PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION)); 1064 1065 PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION)); 1066 PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION)); 1067 PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION)); 1068 1069 PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION)); 1070 PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION)); 1071 1072 cbus_emac_base[0] = EMAC1_BASE_ADDR; 1073 cbus_emac_base[1] = EMAC2_BASE_ADDR; 1074 1075 cbus_gpi_base[0] = EGPI1_BASE_ADDR; 1076 cbus_gpi_base[1] = EGPI2_BASE_ADDR; 1077 1078 rc = pfe_hif_lib_init(g_pfe); 1079 if (rc < 0) 1080 goto err_hif_lib; 1081 1082 rc = pfe_hif_init(g_pfe); 1083 if (rc < 0) 1084 goto err_hif; 1085 pfe_soc_version_get(); 1086 eth_init: 1087 if (init_params.gem_id < 0) 1088 gem_id = g_pfe->nb_devs; 1089 else 1090 gem_id = init_params.gem_id; 1091 1092 PFE_PMD_LOG(INFO, "Init pmd_pfe for %s gem-id %d(given =%d)", 1093 name, gem_id, init_params.gem_id); 1094 1095 rc = pfe_eth_init(vdev, g_pfe, gem_id); 1096 if (rc < 0) 1097 goto err_eth; 1098 else 1099 g_pfe->nb_devs++; 1100 1101 return 0; 1102 1103 err_eth: 1104 pfe_hif_exit(g_pfe); 1105 1106 err_hif: 1107 pfe_hif_lib_exit(g_pfe); 1108 1109 err_hif_lib: 1110 err_prop: 1111 munmap(g_pfe->cbus_baseaddr, cbus_size); 1112 err: 1113 rte_free(g_pfe); 1114 return rc; 1115 } 1116 1117 static int 1118 pmd_pfe_remove(struct rte_vdev_device *vdev) 1119 { 1120 const char *name; 1121 struct rte_eth_dev *eth_dev = NULL; 1122 int ret = 0; 1123 1124 name = rte_vdev_device_name(vdev); 1125 if (name == NULL) 1126 return -EINVAL; 1127 1128 PFE_PMD_INFO("Closing eventdev sw device %s", name); 1129 1130 if (!g_pfe) 1131 return 0; 1132 1133 eth_dev = rte_eth_dev_allocated(name); 1134 if (eth_dev) { 1135 pfe_eth_close(eth_dev); 1136 ret = rte_eth_dev_release_port(eth_dev); 1137 } 1138 1139 return ret; 1140 } 1141 1142 static 1143 struct rte_vdev_driver pmd_pfe_drv = { 1144 .probe = pmd_pfe_probe, 1145 .remove = pmd_pfe_remove, 1146 }; 1147 1148 RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); 1149 RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> "); 1150 RTE_LOG_REGISTER_DEFAULT(pfe_logtype_pmd, NOTICE); 1151