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 #else 431 priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device)); 432 memset(priv->phydev, 0, sizeof(struct phy_device)); 433 434 priv->phydev->speed = SPEED_1000; 435 priv->phydev->link = 1; 436 priv->phydev->duplex = DUPLEX_FULL; 437 #endif 438 439 bus = wriop_get_mdio(priv->dpmac_id); 440 enet_if = wriop_get_enet_if(priv->dpmac_id); 441 if ((bus == NULL) && 442 (enet_if == PHY_INTERFACE_MODE_XGMII)) { 443 priv->phydev = (struct phy_device *) 444 malloc(sizeof(struct phy_device)); 445 memset(priv->phydev, 0, sizeof(struct phy_device)); 446 447 priv->phydev->speed = SPEED_10000; 448 priv->phydev->link = 1; 449 priv->phydev->duplex = DUPLEX_FULL; 450 } 451 452 if (!priv->phydev->link) { 453 printf("%s: No link.\n", priv->phydev->dev->name); 454 err = -1; 455 goto err_dpamc_bind; 456 } 457 458 /* DPMAC binding DPNI */ 459 err = ldpaa_dpmac_bind(priv); 460 if (err) 461 goto err_dpamc_bind; 462 463 /* DPNI initialization */ 464 err = ldpaa_dpni_setup(priv); 465 if (err < 0) 466 goto err_dpni_setup; 467 468 err = ldpaa_dpbp_setup(); 469 if (err < 0) 470 goto err_dpbp_setup; 471 472 /* DPNI binding DPBP */ 473 err = ldpaa_dpni_bind(priv); 474 if (err) 475 goto err_dpni_bind; 476 477 err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, 478 dflt_dpni->dpni_handle, net_dev->enetaddr); 479 if (err) { 480 printf("dpni_add_mac_addr() failed\n"); 481 return err; 482 } 483 484 err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 485 if (err < 0) { 486 printf("dpni_enable() failed\n"); 487 return err; 488 } 489 490 dpmac_link_state.rate = priv->phydev->speed; 491 492 if (priv->phydev->autoneg == AUTONEG_DISABLE) 493 dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG; 494 else 495 dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG; 496 497 if (priv->phydev->duplex == DUPLEX_HALF) 498 dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX; 499 500 dpmac_link_state.up = priv->phydev->link; 501 502 err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 503 priv->dpmac_handle, &dpmac_link_state); 504 if (err < 0) { 505 printf("dpmac_set_link_state() failed\n"); 506 return err; 507 } 508 509 #ifdef DEBUG 510 err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 511 dflt_dpni->dpni_handle, &link_state); 512 if (err < 0) { 513 printf("dpni_get_link_state() failed\n"); 514 return err; 515 } 516 517 printf("link status: %d - ", link_state.up); 518 link_state.up == 0 ? printf("down\n") : 519 link_state.up == 1 ? printf("up\n") : printf("error state\n"); 520 #endif 521 522 /* TODO: support multiple Rx flows */ 523 err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 524 dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); 525 if (err) { 526 printf("dpni_get_rx_flow() failed\n"); 527 goto err_rx_flow; 528 } 529 530 priv->rx_dflt_fqid = rx_queue_attr.fqid; 531 532 err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 533 &priv->tx_qdid); 534 if (err) { 535 printf("dpni_get_qdid() failed\n"); 536 goto err_qdid; 537 } 538 539 return priv->phydev->link; 540 541 err_qdid: 542 err_rx_flow: 543 dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 544 err_dpni_bind: 545 ldpaa_dpbp_free(); 546 err_dpbp_setup: 547 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 548 err_dpni_setup: 549 err_dpamc_bind: 550 dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 551 err_dpmac_setup: 552 return err; 553 } 554 555 static void ldpaa_eth_stop(struct eth_device *net_dev) 556 { 557 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 558 int err = 0; 559 #ifdef CONFIG_PHYLIB 560 struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id); 561 #endif 562 563 if ((net_dev->state == ETH_STATE_PASSIVE) || 564 (net_dev->state == ETH_STATE_INIT)) 565 return; 566 567 #ifdef DEBUG 568 ldpaa_eth_get_dpni_counter(); 569 ldpaa_eth_get_dpmac_counter(net_dev); 570 #endif 571 572 err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, 573 dflt_dprc_handle, &dpmac_endpoint); 574 if (err < 0) 575 printf("dprc_disconnect() failed dpmac_endpoint\n"); 576 577 err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 578 if (err < 0) 579 printf("dpmac_destroy() failed\n"); 580 581 /* Stop Tx and Rx traffic */ 582 err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 583 if (err < 0) 584 printf("dpni_disable() failed\n"); 585 586 #ifdef CONFIG_PHYLIB 587 if (priv->phydev && bus != NULL) 588 phy_shutdown(priv->phydev); 589 else 590 free(priv->phydev); 591 #endif 592 593 ldpaa_dpbp_free(); 594 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 595 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 596 } 597 598 static void ldpaa_dpbp_drain_cnt(int count) 599 { 600 uint64_t buf_array[7]; 601 void *addr; 602 int ret, i; 603 604 BUG_ON(count > 7); 605 606 do { 607 ret = qbman_swp_acquire(dflt_dpio->sw_portal, 608 dflt_dpbp->dpbp_attr.bpid, 609 buf_array, count); 610 if (ret < 0) { 611 printf("qbman_swp_acquire() failed\n"); 612 return; 613 } 614 for (i = 0; i < ret; i++) { 615 addr = (void *)buf_array[i]; 616 debug("Free: buffer addr =0x%p\n", addr); 617 free(addr); 618 } 619 } while (ret); 620 } 621 622 static void ldpaa_dpbp_drain(void) 623 { 624 int i; 625 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 626 ldpaa_dpbp_drain_cnt(7); 627 } 628 629 static int ldpaa_bp_add_7(uint16_t bpid) 630 { 631 uint64_t buf_array[7]; 632 u8 *addr; 633 int i; 634 struct qbman_release_desc rd; 635 636 for (i = 0; i < 7; i++) { 637 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); 638 if (!addr) { 639 printf("addr allocation failed\n"); 640 goto err_alloc; 641 } 642 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 643 flush_dcache_range((u64)addr, 644 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 645 646 buf_array[i] = (uint64_t)addr; 647 debug("Release: buffer addr =0x%p\n", addr); 648 } 649 650 release_bufs: 651 /* In case the portal is busy, retry until successful. 652 * This function is guaranteed to succeed in a reasonable amount 653 * of time. 654 */ 655 656 do { 657 mdelay(1); 658 qbman_release_desc_clear(&rd); 659 qbman_release_desc_set_bpid(&rd, bpid); 660 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 661 662 return i; 663 664 err_alloc: 665 if (i) 666 goto release_bufs; 667 668 return 0; 669 } 670 671 static int ldpaa_dpbp_seed(uint16_t bpid) 672 { 673 int i; 674 int count; 675 676 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 677 count = ldpaa_bp_add_7(bpid); 678 if (count < 7) 679 printf("Buffer Seed= %d\n", count); 680 } 681 682 return 0; 683 } 684 685 static int ldpaa_dpbp_setup(void) 686 { 687 int err; 688 689 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 690 &dflt_dpbp->dpbp_handle); 691 if (err) { 692 printf("dpbp_open() failed\n"); 693 goto err_open; 694 } 695 696 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 697 if (err) { 698 printf("dpbp_enable() failed\n"); 699 goto err_enable; 700 } 701 702 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 703 dflt_dpbp->dpbp_handle, 704 &dflt_dpbp->dpbp_attr); 705 if (err) { 706 printf("dpbp_get_attributes() failed\n"); 707 goto err_get_attr; 708 } 709 710 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 711 if (err) { 712 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 713 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 714 goto err_seed; 715 } 716 717 return 0; 718 719 err_seed: 720 err_get_attr: 721 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 722 err_enable: 723 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 724 err_open: 725 return err; 726 } 727 728 static void ldpaa_dpbp_free(void) 729 { 730 ldpaa_dpbp_drain(); 731 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 732 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 733 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 734 } 735 736 static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io, 737 struct ldpaa_eth_priv *priv) 738 { 739 struct dpmac_attr attr; 740 int error; 741 742 memset(&attr, 0, sizeof(struct dpmac_attr)); 743 error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS, 744 priv->dpmac_handle, 745 &attr); 746 if (error == 0) { 747 if ((attr.version.major != DPMAC_VER_MAJOR) || 748 (attr.version.minor != DPMAC_VER_MINOR)) { 749 printf("DPMAC version mismatch found %u.%u,", 750 attr.version.major, attr.version.minor); 751 printf("supported version is %u.%u\n", 752 DPMAC_VER_MAJOR, DPMAC_VER_MINOR); 753 } 754 } 755 756 return error; 757 } 758 759 static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 760 { 761 int err = 0; 762 struct dpmac_cfg dpmac_cfg; 763 764 dpmac_cfg.mac_id = priv->dpmac_id; 765 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg, 766 &priv->dpmac_handle); 767 if (err) 768 printf("dpmac_create() failed\n"); 769 770 err = ldpaa_dpmac_version_check(dflt_mc_io, priv); 771 if (err < 0) 772 printf("ldpaa_dpmac_version_check() failed: %d\n", err); 773 774 return err; 775 } 776 777 static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 778 { 779 int err = 0; 780 struct dprc_connection_cfg dprc_connection_cfg = { 781 /* If both rates are zero the connection */ 782 /* will be configured in "best effort" mode. */ 783 .committed_rate = 0, 784 .max_rate = 0 785 }; 786 787 #ifdef DEBUG 788 struct dprc_endpoint dbg_endpoint; 789 int state = 0; 790 #endif 791 792 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 793 strcpy(dpmac_endpoint.type, "dpmac"); 794 dpmac_endpoint.id = priv->dpmac_id; 795 796 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 797 strcpy(dpni_endpoint.type, "dpni"); 798 dpni_endpoint.id = dflt_dpni->dpni_id; 799 800 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 801 dflt_dprc_handle, 802 &dpmac_endpoint, 803 &dpni_endpoint, 804 &dprc_connection_cfg); 805 if (err) 806 printf("dprc_connect() failed\n"); 807 808 #ifdef DEBUG 809 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 810 dflt_dprc_handle, &dpni_endpoint, 811 &dbg_endpoint, &state); 812 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); 813 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); 814 printf("%s, DPMAC State= %d\n", __func__, state); 815 816 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); 817 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 818 dflt_dprc_handle, &dpmac_endpoint, 819 &dbg_endpoint, &state); 820 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); 821 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); 822 printf("%s, DPNI State= %d\n", __func__, state); 823 #endif 824 return err; 825 } 826 827 static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 828 { 829 int err; 830 831 /* and get a handle for the DPNI this interface is associate with */ 832 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 833 &dflt_dpni->dpni_handle); 834 if (err) { 835 printf("dpni_open() failed\n"); 836 goto err_open; 837 } 838 839 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 840 dflt_dpni->dpni_handle, 841 &dflt_dpni->dpni_attrs); 842 if (err) { 843 printf("dpni_get_attributes() failed (err=%d)\n", err); 844 goto err_get_attr; 845 } 846 847 /* Configure our buffers' layout */ 848 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 849 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 850 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | 851 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; 852 dflt_dpni->buf_layout.pass_parser_result = true; 853 dflt_dpni->buf_layout.pass_frame_status = true; 854 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 855 /* HW erratum mandates data alignment in multiples of 256 */ 856 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; 857 /* ...rx, ... */ 858 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 859 dflt_dpni->dpni_handle, 860 &dflt_dpni->buf_layout); 861 if (err) { 862 printf("dpni_set_rx_buffer_layout() failed"); 863 goto err_buf_layout; 864 } 865 866 /* ... tx, ... */ 867 /* remove Rx-only options */ 868 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | 869 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); 870 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 871 dflt_dpni->dpni_handle, 872 &dflt_dpni->buf_layout); 873 if (err) { 874 printf("dpni_set_tx_buffer_layout() failed"); 875 goto err_buf_layout; 876 } 877 878 /* ... tx-confirm. */ 879 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 880 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 881 dflt_dpni->dpni_handle, 882 &dflt_dpni->buf_layout); 883 if (err) { 884 printf("dpni_set_tx_conf_buffer_layout() failed"); 885 goto err_buf_layout; 886 } 887 888 /* Now that we've set our tx buffer layout, retrieve the minimum 889 * required tx data offset. 890 */ 891 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 892 dflt_dpni->dpni_handle, 893 &priv->tx_data_offset); 894 if (err) { 895 printf("dpni_get_tx_data_offset() failed\n"); 896 goto err_data_offset; 897 } 898 899 /* Warn in case TX data offset is not multiple of 64 bytes. */ 900 WARN_ON(priv->tx_data_offset % 64); 901 902 /* Accomodate SWA space. */ 903 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 904 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 905 906 return 0; 907 908 err_data_offset: 909 err_buf_layout: 910 err_get_attr: 911 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 912 err_open: 913 return err; 914 } 915 916 static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 917 { 918 struct dpni_pools_cfg pools_params; 919 struct dpni_tx_flow_cfg dflt_tx_flow; 920 struct dpni_tx_conf_cfg tx_conf_cfg; 921 int err = 0; 922 923 memset(&pools_params, 0, sizeof(pools_params)); 924 pools_params.num_dpbp = 1; 925 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 926 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 927 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 928 dflt_dpni->dpni_handle, &pools_params); 929 if (err) { 930 printf("dpni_set_pools() failed\n"); 931 return err; 932 } 933 934 priv->tx_flow_id = DPNI_NEW_FLOW_ID; 935 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); 936 937 dflt_tx_flow.use_common_tx_conf_queue = 0; 938 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 939 dflt_dpni->dpni_handle, &priv->tx_flow_id, 940 &dflt_tx_flow); 941 if (err) { 942 printf("dpni_set_tx_flow() failed\n"); 943 return err; 944 } 945 946 memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg)); 947 tx_conf_cfg.errors_only = true; 948 /*Set tx-conf and error configuration*/ 949 err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS, 950 dflt_dpni->dpni_handle, 951 priv->tx_flow_id, &tx_conf_cfg); 952 if (err) { 953 printf("dpni_set_tx_conf() failed\n"); 954 return err; 955 } 956 957 return 0; 958 } 959 960 static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 961 phy_interface_t enet_if) 962 { 963 int err; 964 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 965 966 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id, 967 phy_interface_strings[enet_if]); 968 969 net_dev->iobase = 0; 970 net_dev->init = ldpaa_eth_open; 971 net_dev->halt = ldpaa_eth_stop; 972 net_dev->send = ldpaa_eth_tx; 973 net_dev->recv = ldpaa_eth_pull_dequeue_rx; 974 975 #ifdef CONFIG_PHYLIB 976 err = init_phy(net_dev); 977 if (err < 0) 978 return err; 979 #endif 980 981 err = eth_register(net_dev); 982 if (err < 0) { 983 printf("eth_register() = %d\n", err); 984 return err; 985 } 986 987 return 0; 988 } 989 990 int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 991 { 992 struct eth_device *net_dev = NULL; 993 struct ldpaa_eth_priv *priv = NULL; 994 int err = 0; 995 996 997 /* Net device */ 998 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 999 if (!net_dev) { 1000 printf("eth_device malloc() failed\n"); 1001 return -ENOMEM; 1002 } 1003 memset(net_dev, 0, sizeof(struct eth_device)); 1004 1005 /* alloc the ldpaa ethernet private struct */ 1006 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 1007 if (!priv) { 1008 printf("ldpaa_eth_priv malloc() failed\n"); 1009 return -ENOMEM; 1010 } 1011 memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 1012 1013 net_dev->priv = (void *)priv; 1014 priv->net_dev = (struct eth_device *)net_dev; 1015 priv->dpmac_id = dpmac_id; 1016 debug("%s dpmac_id=%d\n", __func__, dpmac_id); 1017 1018 err = ldpaa_eth_netdev_init(net_dev, enet_if); 1019 if (err) 1020 goto err_netdev_init; 1021 1022 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 1023 return 0; 1024 1025 err_netdev_init: 1026 free(priv); 1027 net_dev->priv = NULL; 1028 free(net_dev); 1029 1030 return err; 1031 } 1032