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 #endif 593 594 ldpaa_dpbp_free(); 595 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 596 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 597 } 598 599 static void ldpaa_dpbp_drain_cnt(int count) 600 { 601 uint64_t buf_array[7]; 602 void *addr; 603 int ret, i; 604 605 BUG_ON(count > 7); 606 607 do { 608 ret = qbman_swp_acquire(dflt_dpio->sw_portal, 609 dflt_dpbp->dpbp_attr.bpid, 610 buf_array, count); 611 if (ret < 0) { 612 printf("qbman_swp_acquire() failed\n"); 613 return; 614 } 615 for (i = 0; i < ret; i++) { 616 addr = (void *)buf_array[i]; 617 debug("Free: buffer addr =0x%p\n", addr); 618 free(addr); 619 } 620 } while (ret); 621 } 622 623 static void ldpaa_dpbp_drain(void) 624 { 625 int i; 626 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 627 ldpaa_dpbp_drain_cnt(7); 628 } 629 630 static int ldpaa_bp_add_7(uint16_t bpid) 631 { 632 uint64_t buf_array[7]; 633 u8 *addr; 634 int i; 635 struct qbman_release_desc rd; 636 637 for (i = 0; i < 7; i++) { 638 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); 639 if (!addr) { 640 printf("addr allocation failed\n"); 641 goto err_alloc; 642 } 643 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 644 flush_dcache_range((u64)addr, 645 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 646 647 buf_array[i] = (uint64_t)addr; 648 debug("Release: buffer addr =0x%p\n", addr); 649 } 650 651 release_bufs: 652 /* In case the portal is busy, retry until successful. 653 * This function is guaranteed to succeed in a reasonable amount 654 * of time. 655 */ 656 657 do { 658 mdelay(1); 659 qbman_release_desc_clear(&rd); 660 qbman_release_desc_set_bpid(&rd, bpid); 661 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 662 663 return i; 664 665 err_alloc: 666 if (i) 667 goto release_bufs; 668 669 return 0; 670 } 671 672 static int ldpaa_dpbp_seed(uint16_t bpid) 673 { 674 int i; 675 int count; 676 677 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 678 count = ldpaa_bp_add_7(bpid); 679 if (count < 7) 680 printf("Buffer Seed= %d\n", count); 681 } 682 683 return 0; 684 } 685 686 static int ldpaa_dpbp_setup(void) 687 { 688 int err; 689 690 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 691 &dflt_dpbp->dpbp_handle); 692 if (err) { 693 printf("dpbp_open() failed\n"); 694 goto err_open; 695 } 696 697 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 698 if (err) { 699 printf("dpbp_enable() failed\n"); 700 goto err_enable; 701 } 702 703 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 704 dflt_dpbp->dpbp_handle, 705 &dflt_dpbp->dpbp_attr); 706 if (err) { 707 printf("dpbp_get_attributes() failed\n"); 708 goto err_get_attr; 709 } 710 711 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 712 if (err) { 713 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 714 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 715 goto err_seed; 716 } 717 718 return 0; 719 720 err_seed: 721 err_get_attr: 722 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 723 err_enable: 724 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 725 err_open: 726 return err; 727 } 728 729 static void ldpaa_dpbp_free(void) 730 { 731 ldpaa_dpbp_drain(); 732 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 733 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 734 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 735 } 736 737 static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io, 738 struct ldpaa_eth_priv *priv) 739 { 740 struct dpmac_attr attr; 741 int error; 742 743 memset(&attr, 0, sizeof(struct dpmac_attr)); 744 error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS, 745 priv->dpmac_handle, 746 &attr); 747 if (error == 0) { 748 if ((attr.version.major != DPMAC_VER_MAJOR) || 749 (attr.version.minor != DPMAC_VER_MINOR)) { 750 printf("DPMAC version mismatch found %u.%u,", 751 attr.version.major, attr.version.minor); 752 printf("supported version is %u.%u\n", 753 DPMAC_VER_MAJOR, DPMAC_VER_MINOR); 754 } 755 } 756 757 return error; 758 } 759 760 static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 761 { 762 int err = 0; 763 struct dpmac_cfg dpmac_cfg; 764 765 dpmac_cfg.mac_id = priv->dpmac_id; 766 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg, 767 &priv->dpmac_handle); 768 if (err) 769 printf("dpmac_create() failed\n"); 770 771 err = ldpaa_dpmac_version_check(dflt_mc_io, priv); 772 if (err < 0) 773 printf("ldpaa_dpmac_version_check() failed: %d\n", err); 774 775 return err; 776 } 777 778 static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 779 { 780 int err = 0; 781 struct dprc_connection_cfg dprc_connection_cfg = { 782 /* If both rates are zero the connection */ 783 /* will be configured in "best effort" mode. */ 784 .committed_rate = 0, 785 .max_rate = 0 786 }; 787 788 #ifdef DEBUG 789 struct dprc_endpoint dbg_endpoint; 790 int state = 0; 791 #endif 792 793 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 794 strcpy(dpmac_endpoint.type, "dpmac"); 795 dpmac_endpoint.id = priv->dpmac_id; 796 797 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 798 strcpy(dpni_endpoint.type, "dpni"); 799 dpni_endpoint.id = dflt_dpni->dpni_id; 800 801 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 802 dflt_dprc_handle, 803 &dpmac_endpoint, 804 &dpni_endpoint, 805 &dprc_connection_cfg); 806 if (err) 807 printf("dprc_connect() failed\n"); 808 809 #ifdef DEBUG 810 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 811 dflt_dprc_handle, &dpni_endpoint, 812 &dbg_endpoint, &state); 813 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); 814 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); 815 printf("%s, DPMAC State= %d\n", __func__, state); 816 817 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); 818 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 819 dflt_dprc_handle, &dpmac_endpoint, 820 &dbg_endpoint, &state); 821 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); 822 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); 823 printf("%s, DPNI State= %d\n", __func__, state); 824 #endif 825 return err; 826 } 827 828 static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 829 { 830 int err; 831 832 /* and get a handle for the DPNI this interface is associate with */ 833 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 834 &dflt_dpni->dpni_handle); 835 if (err) { 836 printf("dpni_open() failed\n"); 837 goto err_open; 838 } 839 840 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 841 dflt_dpni->dpni_handle, 842 &dflt_dpni->dpni_attrs); 843 if (err) { 844 printf("dpni_get_attributes() failed (err=%d)\n", err); 845 goto err_get_attr; 846 } 847 848 /* Configure our buffers' layout */ 849 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 850 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 851 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | 852 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; 853 dflt_dpni->buf_layout.pass_parser_result = true; 854 dflt_dpni->buf_layout.pass_frame_status = true; 855 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 856 /* HW erratum mandates data alignment in multiples of 256 */ 857 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; 858 /* ...rx, ... */ 859 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 860 dflt_dpni->dpni_handle, 861 &dflt_dpni->buf_layout); 862 if (err) { 863 printf("dpni_set_rx_buffer_layout() failed"); 864 goto err_buf_layout; 865 } 866 867 /* ... tx, ... */ 868 /* remove Rx-only options */ 869 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | 870 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); 871 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 872 dflt_dpni->dpni_handle, 873 &dflt_dpni->buf_layout); 874 if (err) { 875 printf("dpni_set_tx_buffer_layout() failed"); 876 goto err_buf_layout; 877 } 878 879 /* ... tx-confirm. */ 880 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 881 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 882 dflt_dpni->dpni_handle, 883 &dflt_dpni->buf_layout); 884 if (err) { 885 printf("dpni_set_tx_conf_buffer_layout() failed"); 886 goto err_buf_layout; 887 } 888 889 /* Now that we've set our tx buffer layout, retrieve the minimum 890 * required tx data offset. 891 */ 892 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 893 dflt_dpni->dpni_handle, 894 &priv->tx_data_offset); 895 if (err) { 896 printf("dpni_get_tx_data_offset() failed\n"); 897 goto err_data_offset; 898 } 899 900 /* Warn in case TX data offset is not multiple of 64 bytes. */ 901 WARN_ON(priv->tx_data_offset % 64); 902 903 /* Accomodate SWA space. */ 904 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 905 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 906 907 return 0; 908 909 err_data_offset: 910 err_buf_layout: 911 err_get_attr: 912 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 913 err_open: 914 return err; 915 } 916 917 static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 918 { 919 struct dpni_pools_cfg pools_params; 920 struct dpni_tx_flow_cfg dflt_tx_flow; 921 struct dpni_tx_conf_cfg tx_conf_cfg; 922 int err = 0; 923 924 memset(&pools_params, 0, sizeof(pools_params)); 925 pools_params.num_dpbp = 1; 926 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 927 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 928 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 929 dflt_dpni->dpni_handle, &pools_params); 930 if (err) { 931 printf("dpni_set_pools() failed\n"); 932 return err; 933 } 934 935 priv->tx_flow_id = DPNI_NEW_FLOW_ID; 936 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); 937 938 dflt_tx_flow.use_common_tx_conf_queue = 0; 939 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 940 dflt_dpni->dpni_handle, &priv->tx_flow_id, 941 &dflt_tx_flow); 942 if (err) { 943 printf("dpni_set_tx_flow() failed\n"); 944 return err; 945 } 946 947 memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg)); 948 tx_conf_cfg.errors_only = true; 949 /*Set tx-conf and error configuration*/ 950 err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS, 951 dflt_dpni->dpni_handle, 952 priv->tx_flow_id, &tx_conf_cfg); 953 if (err) { 954 printf("dpni_set_tx_conf() failed\n"); 955 return err; 956 } 957 958 return 0; 959 } 960 961 static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 962 phy_interface_t enet_if) 963 { 964 int err; 965 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 966 967 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id, 968 phy_interface_strings[enet_if]); 969 970 net_dev->iobase = 0; 971 net_dev->init = ldpaa_eth_open; 972 net_dev->halt = ldpaa_eth_stop; 973 net_dev->send = ldpaa_eth_tx; 974 net_dev->recv = ldpaa_eth_pull_dequeue_rx; 975 976 #ifdef CONFIG_PHYLIB 977 err = init_phy(net_dev); 978 if (err < 0) 979 return err; 980 #endif 981 982 err = eth_register(net_dev); 983 if (err < 0) { 984 printf("eth_register() = %d\n", err); 985 return err; 986 } 987 988 return 0; 989 } 990 991 int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 992 { 993 struct eth_device *net_dev = NULL; 994 struct ldpaa_eth_priv *priv = NULL; 995 int err = 0; 996 997 998 /* Net device */ 999 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 1000 if (!net_dev) { 1001 printf("eth_device malloc() failed\n"); 1002 return -ENOMEM; 1003 } 1004 memset(net_dev, 0, sizeof(struct eth_device)); 1005 1006 /* alloc the ldpaa ethernet private struct */ 1007 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 1008 if (!priv) { 1009 printf("ldpaa_eth_priv malloc() failed\n"); 1010 return -ENOMEM; 1011 } 1012 memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 1013 1014 net_dev->priv = (void *)priv; 1015 priv->net_dev = (struct eth_device *)net_dev; 1016 priv->dpmac_id = dpmac_id; 1017 debug("%s dpmac_id=%d\n", __func__, dpmac_id); 1018 1019 err = ldpaa_eth_netdev_init(net_dev, enet_if); 1020 if (err) 1021 goto err_netdev_init; 1022 1023 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 1024 return 0; 1025 1026 err_netdev_init: 1027 free(priv); 1028 net_dev->priv = NULL; 1029 free(net_dev); 1030 1031 return err; 1032 } 1033