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