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 <rte_ethdev_vdev.h> 9 #include <rte_bus_vdev.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 DEV_RX_OFFLOAD_IPV4_CKSUM | 26 DEV_RX_OFFLOAD_UDP_CKSUM | 27 DEV_RX_OFFLOAD_TCP_CKSUM; 28 29 /* Supported Tx offloads */ 30 static uint64_t dev_tx_offloads_sup = 31 DEV_TX_OFFLOAD_IPV4_CKSUM | 32 DEV_TX_OFFLOAD_UDP_CKSUM | 33 DEV_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\n", 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 uint16_t 239 pfe_dummy_xmit_pkts(__rte_unused void *tx_queue, 240 __rte_unused struct rte_mbuf **tx_pkts, 241 __rte_unused uint16_t nb_pkts) 242 { 243 return 0; 244 } 245 246 static uint16_t 247 pfe_dummy_recv_pkts(__rte_unused void *rxq, 248 __rte_unused struct rte_mbuf **rx_pkts, 249 __rte_unused uint16_t nb_pkts) 250 { 251 return 0; 252 } 253 254 static int 255 pfe_eth_open(struct rte_eth_dev *dev) 256 { 257 struct pfe_eth_priv_s *priv = dev->data->dev_private; 258 struct hif_client_s *client; 259 struct hif_shm *hif_shm; 260 int rc; 261 262 /* Register client driver with HIF */ 263 client = &priv->client; 264 265 if (client->pfe) { 266 hif_shm = client->pfe->hif.shm; 267 /* TODO please remove the below code of if block, once we add 268 * the proper cleanup in eth_close 269 */ 270 if (!test_bit(PFE_CL_GEM0 + priv->id, 271 &hif_shm->g_client_status[0])) { 272 /* Register client driver with HIF */ 273 memset(client, 0, sizeof(*client)); 274 client->id = PFE_CL_GEM0 + priv->id; 275 client->tx_qn = emac_txq_cnt; 276 client->rx_qn = EMAC_RXQ_CNT; 277 client->priv = priv; 278 client->pfe = priv->pfe; 279 client->port_id = dev->data->port_id; 280 client->event_handler = pfe_eth_event_handler; 281 282 client->tx_qsize = EMAC_TXQ_DEPTH; 283 client->rx_qsize = EMAC_RXQ_DEPTH; 284 285 rc = hif_lib_client_register(client); 286 if (rc) { 287 PFE_PMD_ERR("hif_lib_client_register(%d)" 288 " failed", client->id); 289 goto err0; 290 } 291 } else { 292 /* Freeing the packets if already exists */ 293 int ret = 0; 294 struct rte_mbuf *rx_pkts[32]; 295 /* TODO multiqueue support */ 296 ret = hif_lib_receive_pkt(&client->rx_q[0], 297 hif_shm->pool, rx_pkts, 32); 298 while (ret) { 299 int i; 300 for (i = 0; i < ret; i++) 301 rte_pktmbuf_free(rx_pkts[i]); 302 ret = hif_lib_receive_pkt(&client->rx_q[0], 303 hif_shm->pool, 304 rx_pkts, 32); 305 } 306 } 307 } else { 308 /* Register client driver with HIF */ 309 memset(client, 0, sizeof(*client)); 310 client->id = PFE_CL_GEM0 + priv->id; 311 client->tx_qn = emac_txq_cnt; 312 client->rx_qn = EMAC_RXQ_CNT; 313 client->priv = priv; 314 client->pfe = priv->pfe; 315 client->port_id = dev->data->port_id; 316 client->event_handler = pfe_eth_event_handler; 317 318 client->tx_qsize = EMAC_TXQ_DEPTH; 319 client->rx_qsize = EMAC_RXQ_DEPTH; 320 321 rc = hif_lib_client_register(client); 322 if (rc) { 323 PFE_PMD_ERR("hif_lib_client_register(%d) failed", 324 client->id); 325 goto err0; 326 } 327 } 328 rc = pfe_eth_start(priv); 329 dev->rx_pkt_burst = &pfe_recv_pkts; 330 dev->tx_pkt_burst = &pfe_xmit_pkts; 331 /* If no prefetch is configured. */ 332 if (getenv("PFE_INTR_SUPPORT")) { 333 dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; 334 PFE_PMD_INFO("PFE INTERRUPT Mode enabled"); 335 } 336 337 338 err0: 339 return rc; 340 } 341 342 static int 343 pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) 344 { 345 int pfe_cdev_fd; 346 347 if (priv == NULL) 348 return -1; 349 350 pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); 351 if (pfe_cdev_fd < 0) { 352 PFE_PMD_WARN("Unable to open PFE device file (%s).\n", 353 PFE_CDEV_PATH); 354 PFE_PMD_WARN("Link status update will not be available.\n"); 355 priv->link_fd = PFE_CDEV_INVALID_FD; 356 return -1; 357 } 358 359 priv->link_fd = pfe_cdev_fd; 360 361 return 0; 362 } 363 364 static void 365 pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) 366 { 367 if (priv == NULL) 368 return; 369 370 if (priv->link_fd != PFE_CDEV_INVALID_FD) { 371 close(priv->link_fd); 372 priv->link_fd = PFE_CDEV_INVALID_FD; 373 } 374 } 375 376 static void 377 pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) 378 { 379 struct pfe_eth_priv_s *priv = dev->data->dev_private; 380 381 gemac_disable(priv->EMAC_baseaddr); 382 gpi_disable(priv->GPI_baseaddr); 383 384 dev->rx_pkt_burst = &pfe_dummy_recv_pkts; 385 dev->tx_pkt_burst = &pfe_dummy_xmit_pkts; 386 } 387 388 static int 389 pfe_eth_close(struct rte_eth_dev *dev) 390 { 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 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 0; 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 void 493 pfe_rx_queue_release(void *q __rte_unused) 494 { 495 PMD_INIT_FUNC_TRACE(); 496 } 497 498 static void 499 pfe_tx_queue_release(void *q __rte_unused) 500 { 501 PMD_INIT_FUNC_TRACE(); 502 } 503 504 static int 505 pfe_tx_queue_setup(struct rte_eth_dev *dev, 506 uint16_t queue_idx, 507 __rte_unused uint16_t nb_desc, 508 __rte_unused unsigned int socket_id, 509 __rte_unused const struct rte_eth_txconf *tx_conf) 510 { 511 struct pfe_eth_priv_s *priv = dev->data->dev_private; 512 513 if (queue_idx >= emac_txq_cnt) { 514 PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", 515 queue_idx, emac_txq_cnt); 516 return -1; 517 } 518 dev->data->tx_queues[queue_idx] = &priv->client.tx_q[queue_idx]; 519 priv->client.tx_q[queue_idx].queue_id = queue_idx; 520 return 0; 521 } 522 523 static const uint32_t * 524 pfe_supported_ptypes_get(struct rte_eth_dev *dev) 525 { 526 static const uint32_t ptypes[] = { 527 /*todo -= add more types */ 528 RTE_PTYPE_L2_ETHER, 529 RTE_PTYPE_L3_IPV4, 530 RTE_PTYPE_L3_IPV4_EXT, 531 RTE_PTYPE_L3_IPV6, 532 RTE_PTYPE_L3_IPV6_EXT, 533 RTE_PTYPE_L4_TCP, 534 RTE_PTYPE_L4_UDP, 535 RTE_PTYPE_L4_SCTP 536 }; 537 538 if (dev->rx_pkt_burst == pfe_recv_pkts || 539 dev->rx_pkt_burst == pfe_recv_pkts_on_intr) 540 return ptypes; 541 return NULL; 542 } 543 544 static inline int 545 pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev, 546 struct rte_eth_link *link) 547 { 548 struct rte_eth_link *dst = link; 549 struct rte_eth_link *src = &dev->data->dev_link; 550 551 if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 552 *(uint64_t *)src) == 0) 553 return -1; 554 555 return 0; 556 } 557 558 static inline int 559 pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev, 560 struct rte_eth_link *link) 561 { 562 struct rte_eth_link *dst = &dev->data->dev_link; 563 struct rte_eth_link *src = link; 564 565 if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 566 *(uint64_t *)src) == 0) 567 return -1; 568 569 return 0; 570 } 571 572 static int 573 pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) 574 { 575 int ret, ioctl_cmd = 0; 576 struct pfe_eth_priv_s *priv = dev->data->dev_private; 577 struct rte_eth_link link, old; 578 unsigned int lstatus = 1; 579 580 if (dev == NULL) { 581 PFE_PMD_ERR("Invalid device in link_update.\n"); 582 return 0; 583 } 584 585 memset(&old, 0, sizeof(old)); 586 memset(&link, 0, sizeof(struct rte_eth_link)); 587 588 pfe_eth_atomic_read_link_status(dev, &old); 589 590 /* Read from PFE CDEV, status of link, if file was successfully 591 * opened. 592 */ 593 if (priv->link_fd != PFE_CDEV_INVALID_FD) { 594 if (priv->id == 0) 595 ioctl_cmd = PFE_CDEV_ETH0_STATE_GET; 596 if (priv->id == 1) 597 ioctl_cmd = PFE_CDEV_ETH1_STATE_GET; 598 599 ret = ioctl(priv->link_fd, ioctl_cmd, &lstatus); 600 if (ret != 0) { 601 PFE_PMD_ERR("Unable to fetch link status (ioctl)\n"); 602 /* use dummy link value */ 603 link.link_status = 1; 604 } 605 PFE_PMD_DEBUG("Fetched link state (%d) for dev %d.\n", 606 lstatus, priv->id); 607 } 608 609 if (old.link_status == lstatus) { 610 /* no change in status */ 611 PFE_PMD_DEBUG("No change in link status; Not updating.\n"); 612 return -1; 613 } 614 615 link.link_status = lstatus; 616 link.link_speed = ETH_LINK_SPEED_1G; 617 link.link_duplex = ETH_LINK_FULL_DUPLEX; 618 link.link_autoneg = ETH_LINK_AUTONEG; 619 620 pfe_eth_atomic_write_link_status(dev, &link); 621 622 PFE_PMD_INFO("Port (%d) link is %s\n", dev->data->port_id, 623 link.link_status ? "up" : "down"); 624 625 return 0; 626 } 627 628 static int 629 pfe_promiscuous_enable(struct rte_eth_dev *dev) 630 { 631 struct pfe_eth_priv_s *priv = dev->data->dev_private; 632 633 priv->promisc = 1; 634 dev->data->promiscuous = 1; 635 gemac_enable_copy_all(priv->EMAC_baseaddr); 636 637 return 0; 638 } 639 640 static int 641 pfe_promiscuous_disable(struct rte_eth_dev *dev) 642 { 643 struct pfe_eth_priv_s *priv = dev->data->dev_private; 644 645 priv->promisc = 0; 646 dev->data->promiscuous = 0; 647 gemac_disable_copy_all(priv->EMAC_baseaddr); 648 649 return 0; 650 } 651 652 static int 653 pfe_allmulticast_enable(struct rte_eth_dev *dev) 654 { 655 struct pfe_eth_priv_s *priv = dev->data->dev_private; 656 struct pfe_mac_addr hash_addr; /* hash register structure */ 657 658 /* Set the hash to rx all multicast frames */ 659 hash_addr.bottom = 0xFFFFFFFF; 660 hash_addr.top = 0xFFFFFFFF; 661 gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); 662 dev->data->all_multicast = 1; 663 664 return 0; 665 } 666 667 static int 668 pfe_link_down(struct rte_eth_dev *dev) 669 { 670 pfe_eth_stop(dev); 671 return 0; 672 } 673 674 static int 675 pfe_link_up(struct rte_eth_dev *dev) 676 { 677 struct pfe_eth_priv_s *priv = dev->data->dev_private; 678 679 pfe_eth_start(priv); 680 return 0; 681 } 682 683 static int 684 pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 685 { 686 int ret; 687 struct pfe_eth_priv_s *priv = dev->data->dev_private; 688 uint16_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 689 690 /*TODO Support VLAN*/ 691 ret = gemac_set_rx(priv->EMAC_baseaddr, frame_size); 692 if (!ret) 693 dev->data->mtu = mtu; 694 695 return ret; 696 } 697 698 /* pfe_eth_enet_addr_byte_mac 699 */ 700 static int 701 pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, 702 struct pfe_mac_addr *enet_addr) 703 { 704 if (!enet_byte_addr || !enet_addr) { 705 return -1; 706 707 } else { 708 enet_addr->bottom = enet_byte_addr[0] | 709 (enet_byte_addr[1] << 8) | 710 (enet_byte_addr[2] << 16) | 711 (enet_byte_addr[3] << 24); 712 enet_addr->top = enet_byte_addr[4] | 713 (enet_byte_addr[5] << 8); 714 return 0; 715 } 716 } 717 718 static int 719 pfe_dev_set_mac_addr(struct rte_eth_dev *dev, 720 struct rte_ether_addr *addr) 721 { 722 struct pfe_eth_priv_s *priv = dev->data->dev_private; 723 struct pfe_mac_addr spec_addr; 724 int ret; 725 726 ret = pfe_eth_enet_addr_byte_mac(addr->addr_bytes, &spec_addr); 727 if (ret) 728 return ret; 729 730 gemac_set_laddrN(priv->EMAC_baseaddr, 731 (struct pfe_mac_addr *)&spec_addr, 1); 732 rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); 733 return 0; 734 } 735 736 static int 737 pfe_stats_get(struct rte_eth_dev *dev, 738 struct rte_eth_stats *stats) 739 { 740 struct pfe_eth_priv_s *priv = dev->data->dev_private; 741 struct rte_eth_stats *eth_stats = &priv->stats; 742 743 if (stats == NULL) 744 return -1; 745 746 memset(stats, 0, sizeof(struct rte_eth_stats)); 747 748 stats->ipackets = eth_stats->ipackets; 749 stats->ibytes = eth_stats->ibytes; 750 stats->opackets = eth_stats->opackets; 751 stats->obytes = eth_stats->obytes; 752 753 return 0; 754 } 755 756 static const struct eth_dev_ops ops = { 757 .dev_start = pfe_eth_open, 758 .dev_stop = pfe_eth_stop, 759 .dev_close = pfe_eth_close, 760 .dev_configure = pfe_eth_configure, 761 .dev_infos_get = pfe_eth_info, 762 .rx_queue_setup = pfe_rx_queue_setup, 763 .rx_queue_release = pfe_rx_queue_release, 764 .tx_queue_setup = pfe_tx_queue_setup, 765 .tx_queue_release = pfe_tx_queue_release, 766 .dev_supported_ptypes_get = pfe_supported_ptypes_get, 767 .link_update = pfe_eth_link_update, 768 .promiscuous_enable = pfe_promiscuous_enable, 769 .promiscuous_disable = pfe_promiscuous_disable, 770 .allmulticast_enable = pfe_allmulticast_enable, 771 .dev_set_link_down = pfe_link_down, 772 .dev_set_link_up = pfe_link_up, 773 .mtu_set = pfe_mtu_set, 774 .mac_addr_set = pfe_dev_set_mac_addr, 775 .stats_get = pfe_stats_get, 776 }; 777 778 static int 779 pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) 780 { 781 struct rte_eth_dev *eth_dev = NULL; 782 struct pfe_eth_priv_s *priv = NULL; 783 struct ls1012a_eth_platform_data *einfo; 784 struct ls1012a_pfe_platform_data *pfe_info; 785 struct rte_ether_addr addr; 786 int err; 787 788 eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); 789 if (eth_dev == NULL) 790 return -ENOMEM; 791 792 /* Extract pltform data */ 793 pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data; 794 if (!pfe_info) { 795 PFE_PMD_ERR("pfe missing additional platform data"); 796 err = -ENODEV; 797 goto err0; 798 } 799 800 einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata; 801 802 /* einfo never be NULL, but no harm in having this check */ 803 if (!einfo) { 804 PFE_PMD_ERR("pfe missing additional gemacs platform data"); 805 err = -ENODEV; 806 goto err0; 807 } 808 809 priv = eth_dev->data->dev_private; 810 priv->ndev = eth_dev; 811 priv->id = einfo[id].gem_id; 812 priv->pfe = pfe; 813 814 pfe->eth.eth_priv[id] = priv; 815 816 /* Set the info in the priv to the current info */ 817 priv->einfo = &einfo[id]; 818 priv->EMAC_baseaddr = cbus_emac_base[id]; 819 priv->PHY_baseaddr = cbus_emac_base[id]; 820 priv->GPI_baseaddr = cbus_gpi_base[id]; 821 822 #define HIF_GEMAC_TMUQ_BASE 6 823 priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); 824 priv->high_tmu_q = priv->low_tmu_q + 1; 825 826 rte_spinlock_init(&priv->lock); 827 828 /* Copy the station address into the dev structure, */ 829 eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", 830 ETHER_ADDR_LEN * PFE_MAX_MACS, 0); 831 if (eth_dev->data->mac_addrs == NULL) { 832 PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses", 833 ETHER_ADDR_LEN * PFE_MAX_MACS); 834 err = -ENOMEM; 835 goto err0; 836 } 837 838 memcpy(addr.addr_bytes, priv->einfo->mac_addr, 839 ETH_ALEN); 840 841 pfe_dev_set_mac_addr(eth_dev, &addr); 842 rte_ether_addr_copy(&addr, ð_dev->data->mac_addrs[0]); 843 844 eth_dev->data->mtu = 1500; 845 eth_dev->dev_ops = &ops; 846 pfe_eth_stop(eth_dev); 847 pfe_gemac_init(priv); 848 849 eth_dev->data->nb_rx_queues = 1; 850 eth_dev->data->nb_tx_queues = 1; 851 852 /* For link status, open the PFE CDEV; Error from this function 853 * is silently ignored; In case of error, the link status will not 854 * be available. 855 */ 856 pfe_eth_open_cdev(priv); 857 rte_eth_dev_probing_finish(eth_dev); 858 859 return 0; 860 err0: 861 rte_eth_dev_release_port(eth_dev); 862 return err; 863 } 864 865 static int 866 pfe_get_gemac_if_proprties(struct pfe *pfe, 867 __rte_unused const struct device_node *parent, 868 unsigned int port, unsigned int if_cnt, 869 struct ls1012a_pfe_platform_data *pdata) 870 { 871 const struct device_node *gem = NULL; 872 size_t size; 873 unsigned int ii = 0, phy_id = 0; 874 const u32 *addr; 875 const void *mac_addr; 876 877 for (ii = 0; ii < if_cnt; ii++) { 878 gem = of_get_next_child(parent, gem); 879 if (!gem) 880 goto err; 881 addr = of_get_property(gem, "reg", &size); 882 if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port)) 883 break; 884 } 885 886 if (ii >= if_cnt) { 887 PFE_PMD_ERR("Failed to find interface = %d", if_cnt); 888 goto err; 889 } 890 891 pdata->ls1012a_eth_pdata[port].gem_id = port; 892 893 mac_addr = of_get_mac_address(gem); 894 895 if (mac_addr) { 896 memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, 897 ETH_ALEN); 898 } 899 900 addr = of_get_property(gem, "fsl,mdio-mux-val", &size); 901 if (!addr) { 902 PFE_PMD_ERR("Invalid mdio-mux-val...."); 903 } else { 904 phy_id = rte_be_to_cpu_32((unsigned int)*addr); 905 pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; 906 } 907 if (pdata->ls1012a_eth_pdata[port].phy_id < 32) 908 pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = 909 pdata->ls1012a_eth_pdata[port].mdio_muxval; 910 911 return 0; 912 913 err: 914 return -1; 915 } 916 917 /* Parse integer from integer argument */ 918 static int 919 parse_integer_arg(const char *key __rte_unused, 920 const char *value, void *extra_args) 921 { 922 int i; 923 char *end; 924 errno = 0; 925 926 i = strtol(value, &end, 10); 927 if (*end != 0 || errno != 0 || i < 0 || i > 1) { 928 PFE_PMD_ERR("Supported Port IDS are 0 and 1"); 929 return -EINVAL; 930 } 931 932 *((uint32_t *)extra_args) = i; 933 934 return 0; 935 } 936 937 static int 938 pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params, 939 struct rte_vdev_device *dev) 940 { 941 struct rte_kvargs *kvlist = NULL; 942 int ret = 0; 943 944 static const char * const pfe_vdev_valid_params[] = { 945 PFE_VDEV_GEM_ID_ARG, 946 NULL 947 }; 948 949 const char *input_args = rte_vdev_device_args(dev); 950 951 if (!input_args) 952 return -1; 953 954 kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params); 955 if (kvlist == NULL) 956 return -1; 957 958 ret = rte_kvargs_process(kvlist, 959 PFE_VDEV_GEM_ID_ARG, 960 &parse_integer_arg, 961 ¶ms->gem_id); 962 rte_kvargs_free(kvlist); 963 return ret; 964 } 965 966 static int 967 pmd_pfe_probe(struct rte_vdev_device *vdev) 968 { 969 const u32 *prop; 970 const struct device_node *np; 971 const char *name; 972 const uint32_t *addr; 973 uint64_t cbus_addr, ddr_size, cbus_size; 974 int rc = -1, fd = -1, gem_id; 975 unsigned int ii, interface_count = 0; 976 size_t size = 0; 977 struct pfe_vdev_init_params init_params = { 978 .gem_id = -1 979 }; 980 981 name = rte_vdev_device_name(vdev); 982 rc = pfe_parse_vdev_init_params(&init_params, vdev); 983 if (rc < 0) 984 return -EINVAL; 985 986 PFE_PMD_LOG(INFO, "Initializing pmd_pfe for %s Given gem-id %d", 987 name, init_params.gem_id); 988 989 if (g_pfe) { 990 if (g_pfe->nb_devs >= g_pfe->max_intf) { 991 PFE_PMD_ERR("PFE %d dev already created Max is %d", 992 g_pfe->nb_devs, g_pfe->max_intf); 993 return -EINVAL; 994 } 995 goto eth_init; 996 } 997 998 g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE); 999 if (g_pfe == NULL) 1000 return -EINVAL; 1001 1002 /* Load the device-tree driver */ 1003 rc = of_init(); 1004 if (rc) { 1005 PFE_PMD_ERR("of_init failed with ret: %d", rc); 1006 goto err; 1007 } 1008 1009 np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); 1010 if (!np) { 1011 PFE_PMD_ERR("Invalid device node"); 1012 rc = -EINVAL; 1013 goto err; 1014 } 1015 1016 addr = of_get_address(np, 0, &cbus_size, NULL); 1017 if (!addr) { 1018 PFE_PMD_ERR("of_get_address cannot return qman address\n"); 1019 goto err; 1020 } 1021 cbus_addr = of_translate_address(np, addr); 1022 if (!cbus_addr) { 1023 PFE_PMD_ERR("of_translate_address failed\n"); 1024 goto err; 1025 } 1026 1027 addr = of_get_address(np, 1, &ddr_size, NULL); 1028 if (!addr) { 1029 PFE_PMD_ERR("of_get_address cannot return qman address\n"); 1030 goto err; 1031 } 1032 1033 g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); 1034 if (!g_pfe->ddr_phys_baseaddr) { 1035 PFE_PMD_ERR("of_translate_address failed\n"); 1036 goto err; 1037 } 1038 1039 g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr); 1040 g_pfe->ddr_size = ddr_size; 1041 g_pfe->cbus_size = cbus_size; 1042 1043 fd = open("/dev/mem", O_RDWR); 1044 g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, 1045 MAP_SHARED, fd, cbus_addr); 1046 close(fd); 1047 if (g_pfe->cbus_baseaddr == MAP_FAILED) { 1048 PFE_PMD_ERR("Can not map cbus base"); 1049 rc = -EINVAL; 1050 goto err; 1051 } 1052 1053 /* Read interface count */ 1054 prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); 1055 if (!prop) { 1056 PFE_PMD_ERR("Failed to read number of interfaces"); 1057 rc = -ENXIO; 1058 goto err_prop; 1059 } 1060 1061 interface_count = rte_be_to_cpu_32((unsigned int)*prop); 1062 if (interface_count <= 0) { 1063 PFE_PMD_ERR("No ethernet interface count : %d", 1064 interface_count); 1065 rc = -ENXIO; 1066 goto err_prop; 1067 } 1068 PFE_PMD_INFO("num interfaces = %d ", interface_count); 1069 1070 g_pfe->max_intf = interface_count; 1071 g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; 1072 1073 for (ii = 0; ii < interface_count; ii++) { 1074 pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count, 1075 &g_pfe->platform_data); 1076 } 1077 1078 pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr, 1079 g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size); 1080 1081 PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION)); 1082 PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION)); 1083 1084 PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION)); 1085 PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION)); 1086 1087 PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION)); 1088 PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION)); 1089 PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION)); 1090 1091 PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION)); 1092 PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION)); 1093 1094 cbus_emac_base[0] = EMAC1_BASE_ADDR; 1095 cbus_emac_base[1] = EMAC2_BASE_ADDR; 1096 1097 cbus_gpi_base[0] = EGPI1_BASE_ADDR; 1098 cbus_gpi_base[1] = EGPI2_BASE_ADDR; 1099 1100 rc = pfe_hif_lib_init(g_pfe); 1101 if (rc < 0) 1102 goto err_hif_lib; 1103 1104 rc = pfe_hif_init(g_pfe); 1105 if (rc < 0) 1106 goto err_hif; 1107 pfe_soc_version_get(); 1108 eth_init: 1109 if (init_params.gem_id < 0) 1110 gem_id = g_pfe->nb_devs; 1111 else 1112 gem_id = init_params.gem_id; 1113 1114 PFE_PMD_LOG(INFO, "Init pmd_pfe for %s gem-id %d(given =%d)", 1115 name, gem_id, init_params.gem_id); 1116 1117 rc = pfe_eth_init(vdev, g_pfe, gem_id); 1118 if (rc < 0) 1119 goto err_eth; 1120 else 1121 g_pfe->nb_devs++; 1122 1123 return 0; 1124 1125 err_eth: 1126 pfe_hif_exit(g_pfe); 1127 1128 err_hif: 1129 pfe_hif_lib_exit(g_pfe); 1130 1131 err_hif_lib: 1132 err_prop: 1133 munmap(g_pfe->cbus_baseaddr, cbus_size); 1134 err: 1135 rte_free(g_pfe); 1136 return rc; 1137 } 1138 1139 static int 1140 pmd_pfe_remove(struct rte_vdev_device *vdev) 1141 { 1142 const char *name; 1143 struct rte_eth_dev *eth_dev = NULL; 1144 int ret = 0; 1145 1146 name = rte_vdev_device_name(vdev); 1147 if (name == NULL) 1148 return -EINVAL; 1149 1150 PFE_PMD_INFO("Closing eventdev sw device %s", name); 1151 1152 if (!g_pfe) 1153 return 0; 1154 1155 eth_dev = rte_eth_dev_allocated(name); 1156 if (eth_dev) { 1157 pfe_eth_close(eth_dev); 1158 ret = rte_eth_dev_release_port(eth_dev); 1159 } 1160 1161 return ret; 1162 } 1163 1164 static 1165 struct rte_vdev_driver pmd_pfe_drv = { 1166 .probe = pmd_pfe_probe, 1167 .remove = pmd_pfe_remove, 1168 }; 1169 1170 RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); 1171 RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> "); 1172 RTE_LOG_REGISTER(pfe_logtype_pmd, pmd.net.pfe, NOTICE); 1173