1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2014-2016 Freescale Semiconductor, Inc. 4 * Copyright 2017 NXP 5 */ 6 7 #include <common.h> 8 #include <asm/io.h> 9 #include <asm/types.h> 10 #include <malloc.h> 11 #include <net.h> 12 #include <hwconfig.h> 13 #include <phy.h> 14 #include <linux/compat.h> 15 #include <fsl-mc/fsl_dpmac.h> 16 17 #include <fsl-mc/ldpaa_wriop.h> 18 #include "ldpaa_eth.h" 19 20 #ifdef CONFIG_PHYLIB 21 static int init_phy(struct eth_device *dev) 22 { 23 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 24 struct phy_device *phydev = NULL; 25 struct mii_dev *bus; 26 int phy_addr, phy_num; 27 int ret = 0; 28 29 bus = wriop_get_mdio(priv->dpmac_id); 30 if (bus == NULL) 31 return 0; 32 33 for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 34 phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num); 35 if (phy_addr < 0) 36 continue; 37 38 phydev = phy_connect(bus, phy_addr, dev, 39 wriop_get_enet_if(priv->dpmac_id)); 40 if (!phydev) { 41 printf("Failed to connect\n"); 42 ret = -ENODEV; 43 break; 44 } 45 wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev); 46 ret = phy_config(phydev); 47 if (ret) 48 break; 49 } 50 51 if (ret) { 52 for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 53 phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); 54 if (!phydev) 55 continue; 56 57 free(phydev); 58 wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL); 59 } 60 } 61 62 return ret; 63 } 64 #endif 65 66 #ifdef DEBUG 67 68 #define DPNI_STATS_PER_PAGE 6 69 70 static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = { 71 { 72 "DPNI_CNT_ING_ALL_FRAMES", 73 "DPNI_CNT_ING_ALL_BYTES", 74 "DPNI_CNT_ING_MCAST_FRAMES", 75 "DPNI_CNT_ING_MCAST_BYTES", 76 "DPNI_CNT_ING_BCAST_FRAMES", 77 "DPNI_CNT_ING_BCAST_BYTES", 78 }, { 79 "DPNI_CNT_EGR_ALL_FRAMES", 80 "DPNI_CNT_EGR_ALL_BYTES", 81 "DPNI_CNT_EGR_MCAST_FRAMES", 82 "DPNI_CNT_EGR_MCAST_BYTES", 83 "DPNI_CNT_EGR_BCAST_FRAMES", 84 "DPNI_CNT_EGR_BCAST_BYTES", 85 }, { 86 "DPNI_CNT_ING_FILTERED_FRAMES", 87 "DPNI_CNT_ING_DISCARDED_FRAMES", 88 "DPNI_CNT_ING_NOBUFFER_DISCARDS", 89 "DPNI_CNT_EGR_DISCARDED_FRAMES", 90 "DPNI_CNT_EGR_CNF_FRAMES", 91 "" 92 }, 93 }; 94 95 static void print_dpni_stats(const char *strings[], 96 struct dpni_statistics dpni_stats) 97 { 98 uint64_t *stat; 99 int i; 100 101 stat = (uint64_t *)&dpni_stats; 102 for (i = 0; i < DPNI_STATS_PER_PAGE; i++) { 103 if (strcmp(strings[i], "\0") == 0) 104 break; 105 printf("%s= %llu\n", strings[i], *stat); 106 stat++; 107 } 108 } 109 110 static void ldpaa_eth_get_dpni_counter(void) 111 { 112 int err = 0; 113 unsigned int page = 0; 114 struct dpni_statistics dpni_stats; 115 116 printf("DPNI counters ..\n"); 117 for (page = 0; page < 3; page++) { 118 err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS, 119 dflt_dpni->dpni_handle, page, 120 &dpni_stats); 121 if (err < 0) { 122 printf("dpni_get_statistics: failed:"); 123 printf("%d for page[%d]\n", err, page); 124 return; 125 } 126 print_dpni_stats(dpni_statistics[page], dpni_stats); 127 } 128 } 129 130 static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev) 131 { 132 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 133 int err = 0; 134 u64 value; 135 136 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 137 priv->dpmac_handle, 138 DPMAC_CNT_ING_BYTE, 139 &value); 140 if (err < 0) { 141 printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 142 return; 143 } 144 printf("\nDPMAC counters ..\n"); 145 printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 146 147 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 148 priv->dpmac_handle, 149 DPMAC_CNT_ING_FRAME_DISCARD, 150 &value); 151 if (err < 0) { 152 printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n"); 153 return; 154 } 155 printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value); 156 157 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 158 priv->dpmac_handle, 159 DPMAC_CNT_ING_ALIGN_ERR, 160 &value); 161 if (err < 0) { 162 printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n"); 163 return; 164 } 165 printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value); 166 167 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 168 priv->dpmac_handle, 169 DPMAC_CNT_ING_BYTE, 170 &value); 171 if (err < 0) { 172 printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 173 return; 174 } 175 printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 176 177 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 178 priv->dpmac_handle, 179 DPMAC_CNT_ING_ERR_FRAME, 180 &value); 181 if (err < 0) { 182 printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n"); 183 return; 184 } 185 printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value); 186 187 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 188 priv->dpmac_handle, 189 DPMAC_CNT_EGR_BYTE , 190 &value); 191 if (err < 0) { 192 printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n"); 193 return; 194 } 195 printf("DPMAC_CNT_EGR_BYTE =%lld\n", value); 196 197 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 198 priv->dpmac_handle, 199 DPMAC_CNT_EGR_ERR_FRAME , 200 &value); 201 if (err < 0) { 202 printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n"); 203 return; 204 } 205 printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value); 206 } 207 #endif 208 209 static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, 210 const struct dpaa_fd *fd) 211 { 212 u64 fd_addr; 213 uint16_t fd_offset; 214 uint32_t fd_length; 215 struct ldpaa_fas *fas; 216 uint32_t status, err; 217 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 218 u32 time_start; 219 struct qbman_release_desc releasedesc; 220 struct qbman_swp *swp = dflt_dpio->sw_portal; 221 222 fd_addr = ldpaa_fd_get_addr(fd); 223 fd_offset = ldpaa_fd_get_offset(fd); 224 fd_length = ldpaa_fd_get_len(fd); 225 226 debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); 227 228 if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 229 /* Read the frame annotation status word and check for errors */ 230 fas = (struct ldpaa_fas *) 231 ((uint8_t *)(fd_addr) + 232 dflt_dpni->buf_layout.private_data_size); 233 status = le32_to_cpu(fas->status); 234 if (status & LDPAA_ETH_RX_ERR_MASK) { 235 printf("Rx frame error(s): 0x%08x\n", 236 status & LDPAA_ETH_RX_ERR_MASK); 237 goto error; 238 } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { 239 printf("Unsupported feature in bitmask: 0x%08x\n", 240 status & LDPAA_ETH_RX_UNSUPP_MASK); 241 goto error; 242 } 243 } 244 245 debug("Rx frame: To Upper layer\n"); 246 net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, 247 fd_length); 248 249 error: 250 flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); 251 qbman_release_desc_clear(&releasedesc); 252 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 253 time_start = get_timer(0); 254 do { 255 /* Release buffer into the QBMAN */ 256 err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 257 } while (get_timer(time_start) < timeo && err == -EBUSY); 258 259 if (err == -EBUSY) 260 printf("Rx frame: QBMAN buffer release fails\n"); 261 262 return; 263 } 264 265 static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) 266 { 267 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 268 const struct ldpaa_dq *dq; 269 const struct dpaa_fd *fd; 270 int i = 5, err = 0, status; 271 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 272 u32 time_start; 273 static struct qbman_pull_desc pulldesc; 274 struct qbman_swp *swp = dflt_dpio->sw_portal; 275 276 while (--i) { 277 qbman_pull_desc_clear(&pulldesc); 278 qbman_pull_desc_set_numframes(&pulldesc, 1); 279 qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); 280 281 err = qbman_swp_pull(swp, &pulldesc); 282 if (err < 0) { 283 printf("Dequeue frames error:0x%08x\n", err); 284 continue; 285 } 286 287 time_start = get_timer(0); 288 289 do { 290 dq = qbman_swp_dqrr_next(swp); 291 } while (get_timer(time_start) < timeo && !dq); 292 293 if (dq) { 294 /* Check for valid frame. If not sent a consume 295 * confirmation to QBMAN otherwise give it to NADK 296 * application and then send consume confirmation to 297 * QBMAN. 298 */ 299 status = (uint8_t)ldpaa_dq_flags(dq); 300 if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 301 debug("Dequeue RX frames:"); 302 debug("No frame delivered\n"); 303 304 qbman_swp_dqrr_consume(swp, dq); 305 continue; 306 } 307 308 fd = ldpaa_dq_fd(dq); 309 310 /* Obtain FD and process it */ 311 ldpaa_eth_rx(priv, fd); 312 qbman_swp_dqrr_consume(swp, dq); 313 break; 314 } else { 315 err = -ENODATA; 316 debug("No DQRR entries\n"); 317 break; 318 } 319 } 320 321 return err; 322 } 323 324 static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) 325 { 326 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 327 struct dpaa_fd fd; 328 u64 buffer_start; 329 int data_offset, err; 330 u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; 331 u32 time_start; 332 struct qbman_swp *swp = dflt_dpio->sw_portal; 333 struct qbman_eq_desc ed; 334 struct qbman_release_desc releasedesc; 335 336 /* Setup the FD fields */ 337 memset(&fd, 0, sizeof(fd)); 338 339 data_offset = priv->tx_data_offset; 340 341 do { 342 err = qbman_swp_acquire(dflt_dpio->sw_portal, 343 dflt_dpbp->dpbp_attr.bpid, 344 &buffer_start, 1); 345 } while (err == -EBUSY); 346 347 if (err <= 0) { 348 printf("qbman_swp_acquire() failed\n"); 349 return -ENOMEM; 350 } 351 352 debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); 353 354 memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); 355 356 flush_dcache_range(buffer_start, buffer_start + 357 LDPAA_ETH_RX_BUFFER_SIZE); 358 359 ldpaa_fd_set_addr(&fd, (u64)buffer_start); 360 ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); 361 ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); 362 ldpaa_fd_set_len(&fd, len); 363 364 fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | 365 LDPAA_FD_CTRL_PTV1; 366 367 qbman_eq_desc_clear(&ed); 368 qbman_eq_desc_set_no_orp(&ed, 0); 369 qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); 370 371 time_start = get_timer(0); 372 373 while (get_timer(time_start) < timeo) { 374 err = qbman_swp_enqueue(swp, &ed, 375 (const struct qbman_fd *)(&fd)); 376 if (err != -EBUSY) 377 break; 378 } 379 380 if (err < 0) { 381 printf("error enqueueing Tx frame\n"); 382 goto error; 383 } 384 385 return err; 386 387 error: 388 qbman_release_desc_clear(&releasedesc); 389 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 390 time_start = get_timer(0); 391 do { 392 /* Release buffer into the QBMAN */ 393 err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); 394 } while (get_timer(time_start) < timeo && err == -EBUSY); 395 396 if (err == -EBUSY) 397 printf("TX data: QBMAN buffer release fails\n"); 398 399 return err; 400 } 401 402 static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv, 403 struct dpmac_link_state *state) 404 { 405 phy_interface_t enet_if; 406 int phys_detected; 407 #ifdef CONFIG_PHYLIB 408 struct phy_device *phydev = NULL; 409 int err, phy_num; 410 #endif 411 412 /* let's start off with maximum capabilities */ 413 enet_if = wriop_get_enet_if(priv->dpmac_id); 414 switch (enet_if) { 415 case PHY_INTERFACE_MODE_XGMII: 416 state->rate = SPEED_10000; 417 break; 418 default: 419 state->rate = SPEED_1000; 420 break; 421 } 422 state->up = 1; 423 424 phys_detected = 0; 425 #ifdef CONFIG_PHYLIB 426 state->options |= DPMAC_LINK_OPT_AUTONEG; 427 428 /* start the phy devices one by one and update the dpmac state */ 429 for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 430 phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); 431 if (!phydev) 432 continue; 433 434 phys_detected++; 435 err = phy_startup(phydev); 436 if (err) { 437 printf("%s: Could not initialize\n", phydev->dev->name); 438 state->up = 0; 439 break; 440 } 441 if (phydev->link) { 442 state->rate = min(state->rate, (uint32_t)phydev->speed); 443 if (!phydev->duplex) 444 state->options |= DPMAC_LINK_OPT_HALF_DUPLEX; 445 if (!phydev->autoneg) 446 state->options &= ~DPMAC_LINK_OPT_AUTONEG; 447 } else { 448 /* break out of loop even if one phy is down */ 449 state->up = 0; 450 break; 451 } 452 } 453 #endif 454 if (!phys_detected) 455 state->options &= ~DPMAC_LINK_OPT_AUTONEG; 456 457 if (!state->up) { 458 state->rate = 0; 459 state->options = 0; 460 return -ENOLINK; 461 } 462 463 return 0; 464 } 465 466 static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) 467 { 468 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 469 struct dpmac_link_state dpmac_link_state = { 0 }; 470 #ifdef DEBUG 471 struct dpni_link_state link_state; 472 #endif 473 int err = 0; 474 struct dpni_queue d_queue; 475 476 if (net_dev->state == ETH_STATE_ACTIVE) 477 return 0; 478 479 if (get_mc_boot_status() != 0) { 480 printf("ERROR (MC is not booted)\n"); 481 return -ENODEV; 482 } 483 484 if (get_dpl_apply_status() == 0) { 485 printf("ERROR (DPL is deployed. No device available)\n"); 486 return -ENODEV; 487 } 488 489 /* DPMAC initialization */ 490 err = ldpaa_dpmac_setup(priv); 491 if (err < 0) 492 goto err_dpmac_setup; 493 494 err = ldpaa_get_dpmac_state(priv, &dpmac_link_state); 495 if (err < 0) 496 goto err_dpmac_bind; 497 498 /* DPMAC binding DPNI */ 499 err = ldpaa_dpmac_bind(priv); 500 if (err) 501 goto err_dpmac_bind; 502 503 /* DPNI initialization */ 504 err = ldpaa_dpni_setup(priv); 505 if (err < 0) 506 goto err_dpni_setup; 507 508 err = ldpaa_dpbp_setup(); 509 if (err < 0) 510 goto err_dpbp_setup; 511 512 /* DPNI binding DPBP */ 513 err = ldpaa_dpni_bind(priv); 514 if (err) 515 goto err_dpni_bind; 516 517 err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, 518 dflt_dpni->dpni_handle, net_dev->enetaddr); 519 if (err) { 520 printf("dpni_add_mac_addr() failed\n"); 521 return err; 522 } 523 524 err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 525 if (err < 0) { 526 printf("dpni_enable() failed\n"); 527 return err; 528 } 529 530 err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 531 priv->dpmac_handle, &dpmac_link_state); 532 if (err < 0) { 533 printf("dpmac_set_link_state() failed\n"); 534 return err; 535 } 536 537 #ifdef DEBUG 538 printf("DPMAC link status: %d - ", dpmac_link_state.up); 539 dpmac_link_state.up == 0 ? printf("down\n") : 540 dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n"); 541 542 err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 543 dflt_dpni->dpni_handle, &link_state); 544 if (err < 0) { 545 printf("dpni_get_link_state() failed\n"); 546 return err; 547 } 548 549 printf("DPNI link status: %d - ", link_state.up); 550 link_state.up == 0 ? printf("down\n") : 551 link_state.up == 1 ? printf("up\n") : printf("error state\n"); 552 #endif 553 554 memset(&d_queue, 0, sizeof(struct dpni_queue)); 555 err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS, 556 dflt_dpni->dpni_handle, DPNI_QUEUE_RX, 557 0, 0, &d_queue); 558 if (err) { 559 printf("dpni_get_queue failed\n"); 560 goto err_get_queue; 561 } 562 563 priv->rx_dflt_fqid = d_queue.fqid; 564 565 err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 566 &priv->tx_qdid); 567 if (err) { 568 printf("dpni_get_qdid() failed\n"); 569 goto err_qdid; 570 } 571 572 return dpmac_link_state.up; 573 574 err_qdid: 575 err_get_queue: 576 dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 577 err_dpni_bind: 578 ldpaa_dpbp_free(); 579 err_dpbp_setup: 580 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 581 err_dpni_setup: 582 err_dpmac_bind: 583 dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 584 dpmac_destroy(dflt_mc_io, 585 dflt_dprc_handle, 586 MC_CMD_NO_FLAGS, priv->dpmac_id); 587 err_dpmac_setup: 588 return err; 589 } 590 591 static void ldpaa_eth_stop(struct eth_device *net_dev) 592 { 593 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 594 int err = 0; 595 #ifdef CONFIG_PHYLIB 596 struct phy_device *phydev = NULL; 597 int phy_num; 598 #endif 599 600 if ((net_dev->state == ETH_STATE_PASSIVE) || 601 (net_dev->state == ETH_STATE_INIT)) 602 return; 603 604 #ifdef DEBUG 605 ldpaa_eth_get_dpni_counter(); 606 ldpaa_eth_get_dpmac_counter(net_dev); 607 #endif 608 609 err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, 610 dflt_dprc_handle, &dpmac_endpoint); 611 if (err < 0) 612 printf("dprc_disconnect() failed dpmac_endpoint\n"); 613 614 err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 615 if (err < 0) 616 printf("dpmac_close() failed\n"); 617 618 err = dpmac_destroy(dflt_mc_io, 619 dflt_dprc_handle, 620 MC_CMD_NO_FLAGS, 621 priv->dpmac_id); 622 if (err < 0) 623 printf("dpmac_destroy() failed\n"); 624 625 /* Stop Tx and Rx traffic */ 626 err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 627 if (err < 0) 628 printf("dpni_disable() failed\n"); 629 630 #ifdef CONFIG_PHYLIB 631 for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 632 phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); 633 if (phydev) 634 phy_shutdown(phydev); 635 } 636 #endif 637 638 /* Free DPBP handle and reset. */ 639 ldpaa_dpbp_free(); 640 641 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 642 if (err < 0) 643 printf("dpni_reset() failed\n"); 644 645 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 646 if (err < 0) 647 printf("dpni_close() failed\n"); 648 } 649 650 static void ldpaa_dpbp_drain_cnt(int count) 651 { 652 uint64_t buf_array[7]; 653 void *addr; 654 int ret, i; 655 656 BUG_ON(count > 7); 657 658 do { 659 ret = qbman_swp_acquire(dflt_dpio->sw_portal, 660 dflt_dpbp->dpbp_attr.bpid, 661 buf_array, count); 662 if (ret < 0) { 663 printf("qbman_swp_acquire() failed\n"); 664 return; 665 } 666 for (i = 0; i < ret; i++) { 667 addr = (void *)buf_array[i]; 668 debug("Free: buffer addr =0x%p\n", addr); 669 free(addr); 670 } 671 } while (ret); 672 } 673 674 static void ldpaa_dpbp_drain(void) 675 { 676 int i; 677 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 678 ldpaa_dpbp_drain_cnt(7); 679 } 680 681 static int ldpaa_bp_add_7(uint16_t bpid) 682 { 683 uint64_t buf_array[7]; 684 u8 *addr; 685 int i; 686 struct qbman_release_desc rd; 687 688 for (i = 0; i < 7; i++) { 689 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); 690 if (!addr) { 691 printf("addr allocation failed\n"); 692 goto err_alloc; 693 } 694 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 695 flush_dcache_range((u64)addr, 696 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 697 698 buf_array[i] = (uint64_t)addr; 699 debug("Release: buffer addr =0x%p\n", addr); 700 } 701 702 release_bufs: 703 /* In case the portal is busy, retry until successful. 704 * This function is guaranteed to succeed in a reasonable amount 705 * of time. 706 */ 707 708 do { 709 mdelay(1); 710 qbman_release_desc_clear(&rd); 711 qbman_release_desc_set_bpid(&rd, bpid); 712 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 713 714 return i; 715 716 err_alloc: 717 if (i) 718 goto release_bufs; 719 720 return 0; 721 } 722 723 static int ldpaa_dpbp_seed(uint16_t bpid) 724 { 725 int i; 726 int count; 727 728 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 729 count = ldpaa_bp_add_7(bpid); 730 if (count < 7) 731 printf("Buffer Seed= %d\n", count); 732 } 733 734 return 0; 735 } 736 737 static int ldpaa_dpbp_setup(void) 738 { 739 int err; 740 741 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 742 &dflt_dpbp->dpbp_handle); 743 if (err) { 744 printf("dpbp_open() failed\n"); 745 goto err_open; 746 } 747 748 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 749 if (err) { 750 printf("dpbp_enable() failed\n"); 751 goto err_enable; 752 } 753 754 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 755 dflt_dpbp->dpbp_handle, 756 &dflt_dpbp->dpbp_attr); 757 if (err) { 758 printf("dpbp_get_attributes() failed\n"); 759 goto err_get_attr; 760 } 761 762 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 763 764 if (err) { 765 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 766 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 767 goto err_seed; 768 } 769 770 return 0; 771 772 err_seed: 773 err_get_attr: 774 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 775 err_enable: 776 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 777 err_open: 778 return err; 779 } 780 781 static void ldpaa_dpbp_free(void) 782 { 783 ldpaa_dpbp_drain(); 784 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 785 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 786 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 787 } 788 789 static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io, 790 struct ldpaa_eth_priv *priv) 791 { 792 int error; 793 uint16_t major_ver, minor_ver; 794 795 error = dpmac_get_api_version(dflt_mc_io, 0, 796 &major_ver, 797 &minor_ver); 798 if ((major_ver < DPMAC_VER_MAJOR) || 799 (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) { 800 printf("DPMAC version mismatch found %u.%u,", 801 major_ver, minor_ver); 802 printf("supported version is %u.%u\n", 803 DPMAC_VER_MAJOR, DPMAC_VER_MINOR); 804 return error; 805 } 806 807 return error; 808 } 809 810 static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 811 { 812 int err = 0; 813 struct dpmac_cfg dpmac_cfg; 814 815 dpmac_cfg.mac_id = priv->dpmac_id; 816 817 err = dpmac_create(dflt_mc_io, 818 dflt_dprc_handle, 819 MC_CMD_NO_FLAGS, &dpmac_cfg, 820 &priv->dpmac_id); 821 if (err) 822 printf("dpmac_create() failed\n"); 823 824 err = ldpaa_dpmac_version_check(dflt_mc_io, priv); 825 if (err < 0) { 826 printf("ldpaa_dpmac_version_check() failed: %d\n", err); 827 goto err_version_check; 828 } 829 830 err = dpmac_open(dflt_mc_io, 831 MC_CMD_NO_FLAGS, 832 priv->dpmac_id, 833 &priv->dpmac_handle); 834 if (err < 0) { 835 printf("dpmac_open() failed: %d\n", err); 836 goto err_open; 837 } 838 839 return err; 840 841 err_open: 842 err_version_check: 843 dpmac_destroy(dflt_mc_io, 844 dflt_dprc_handle, 845 MC_CMD_NO_FLAGS, priv->dpmac_id); 846 847 return err; 848 } 849 850 static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 851 { 852 int err = 0; 853 struct dprc_connection_cfg dprc_connection_cfg = { 854 /* If both rates are zero the connection */ 855 /* will be configured in "best effort" mode. */ 856 .committed_rate = 0, 857 .max_rate = 0 858 }; 859 860 #ifdef DEBUG 861 struct dprc_endpoint dbg_endpoint; 862 int state = 0; 863 #endif 864 865 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 866 strcpy(dpmac_endpoint.type, "dpmac"); 867 dpmac_endpoint.id = priv->dpmac_id; 868 869 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 870 strcpy(dpni_endpoint.type, "dpni"); 871 dpni_endpoint.id = dflt_dpni->dpni_id; 872 873 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 874 dflt_dprc_handle, 875 &dpmac_endpoint, 876 &dpni_endpoint, 877 &dprc_connection_cfg); 878 if (err) 879 printf("dprc_connect() failed\n"); 880 881 #ifdef DEBUG 882 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 883 dflt_dprc_handle, &dpni_endpoint, 884 &dbg_endpoint, &state); 885 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); 886 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); 887 printf("%s, DPMAC State= %d\n", __func__, state); 888 889 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); 890 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 891 dflt_dprc_handle, &dpmac_endpoint, 892 &dbg_endpoint, &state); 893 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); 894 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); 895 printf("%s, DPNI State= %d\n", __func__, state); 896 #endif 897 return err; 898 } 899 900 static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 901 { 902 int err; 903 904 /* and get a handle for the DPNI this interface is associate with */ 905 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 906 &dflt_dpni->dpni_handle); 907 if (err) { 908 printf("dpni_open() failed\n"); 909 goto err_open; 910 } 911 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 912 dflt_dpni->dpni_handle, 913 &dflt_dpni->dpni_attrs); 914 if (err) { 915 printf("dpni_get_attributes() failed (err=%d)\n", err); 916 goto err_get_attr; 917 } 918 919 /* Configure our buffers' layout */ 920 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 921 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 922 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | 923 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; 924 dflt_dpni->buf_layout.pass_parser_result = true; 925 dflt_dpni->buf_layout.pass_frame_status = true; 926 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 927 /* HW erratum mandates data alignment in multiples of 256 */ 928 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; 929 930 /* ...rx, ... */ 931 err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 932 dflt_dpni->dpni_handle, 933 &dflt_dpni->buf_layout, DPNI_QUEUE_RX); 934 if (err) { 935 printf("dpni_set_buffer_layout() failed"); 936 goto err_buf_layout; 937 } 938 939 /* ... tx, ... */ 940 /* remove Rx-only options */ 941 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | 942 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); 943 err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 944 dflt_dpni->dpni_handle, 945 &dflt_dpni->buf_layout, DPNI_QUEUE_TX); 946 if (err) { 947 printf("dpni_set_buffer_layout() failed"); 948 goto err_buf_layout; 949 } 950 951 /* ... tx-confirm. */ 952 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 953 err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 954 dflt_dpni->dpni_handle, 955 &dflt_dpni->buf_layout, 956 DPNI_QUEUE_TX_CONFIRM); 957 if (err) { 958 printf("dpni_set_buffer_layout() failed"); 959 goto err_buf_layout; 960 } 961 962 /* Now that we've set our tx buffer layout, retrieve the minimum 963 * required tx data offset. 964 */ 965 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 966 dflt_dpni->dpni_handle, 967 &priv->tx_data_offset); 968 if (err) { 969 printf("dpni_get_tx_data_offset() failed\n"); 970 goto err_data_offset; 971 } 972 973 /* Warn in case TX data offset is not multiple of 64 bytes. */ 974 WARN_ON(priv->tx_data_offset % 64); 975 976 /* Accomodate SWA space. */ 977 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 978 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 979 980 return 0; 981 982 err_data_offset: 983 err_buf_layout: 984 err_get_attr: 985 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 986 err_open: 987 return err; 988 } 989 990 static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 991 { 992 struct dpni_pools_cfg pools_params; 993 struct dpni_queue tx_queue; 994 int err = 0; 995 996 memset(&pools_params, 0, sizeof(pools_params)); 997 pools_params.num_dpbp = 1; 998 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 999 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 1000 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 1001 dflt_dpni->dpni_handle, &pools_params); 1002 if (err) { 1003 printf("dpni_set_pools() failed\n"); 1004 return err; 1005 } 1006 1007 memset(&tx_queue, 0, sizeof(struct dpni_queue)); 1008 1009 err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS, 1010 dflt_dpni->dpni_handle, 1011 DPNI_QUEUE_TX, 0, 0, &tx_queue); 1012 1013 if (err) { 1014 printf("dpni_set_queue() failed\n"); 1015 return err; 1016 } 1017 1018 err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS, 1019 dflt_dpni->dpni_handle, 1020 DPNI_CONF_DISABLE); 1021 if (err) { 1022 printf("dpni_set_tx_confirmation_mode() failed\n"); 1023 return err; 1024 } 1025 1026 return 0; 1027 } 1028 1029 static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 1030 phy_interface_t enet_if) 1031 { 1032 int err; 1033 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 1034 1035 snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id, 1036 phy_interface_strings[enet_if]); 1037 1038 net_dev->iobase = 0; 1039 net_dev->init = ldpaa_eth_open; 1040 net_dev->halt = ldpaa_eth_stop; 1041 net_dev->send = ldpaa_eth_tx; 1042 net_dev->recv = ldpaa_eth_pull_dequeue_rx; 1043 1044 #ifdef CONFIG_PHYLIB 1045 err = init_phy(net_dev); 1046 if (err < 0) 1047 return err; 1048 #endif 1049 1050 err = eth_register(net_dev); 1051 if (err < 0) { 1052 printf("eth_register() = %d\n", err); 1053 return err; 1054 } 1055 1056 return 0; 1057 } 1058 1059 int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 1060 { 1061 struct eth_device *net_dev = NULL; 1062 struct ldpaa_eth_priv *priv = NULL; 1063 int err = 0; 1064 1065 /* Net device */ 1066 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 1067 if (!net_dev) { 1068 printf("eth_device malloc() failed\n"); 1069 return -ENOMEM; 1070 } 1071 memset(net_dev, 0, sizeof(struct eth_device)); 1072 1073 /* alloc the ldpaa ethernet private struct */ 1074 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 1075 if (!priv) { 1076 printf("ldpaa_eth_priv malloc() failed\n"); 1077 return -ENOMEM; 1078 } 1079 memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 1080 1081 net_dev->priv = (void *)priv; 1082 priv->net_dev = (struct eth_device *)net_dev; 1083 priv->dpmac_id = dpmac_id; 1084 debug("%s dpmac_id=%d\n", __func__, dpmac_id); 1085 1086 err = ldpaa_eth_netdev_init(net_dev, enet_if); 1087 if (err) 1088 goto err_netdev_init; 1089 1090 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 1091 return 0; 1092 1093 err_netdev_init: 1094 free(priv); 1095 net_dev->priv = NULL; 1096 free(net_dev); 1097 1098 return err; 1099 } 1100