2 * Copyright (C) 2014 Freescale Semiconductor
4 * SPDX-License-Identifier: GPL-2.0+
14 #include <linux/compat.h>
15 #include <fsl-mc/fsl_dpmac.h>
17 #include "ldpaa_eth.h"
20 static int init_phy(struct eth_device *dev)
22 /*TODO for external PHY */
28 static void ldpaa_eth_get_dpni_counter(void)
33 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
34 dflt_dpni->dpni_handle,
38 printf("dpni_get_counter: DPNI_CNT_ING_FRAME failed\n");
41 printf("DPNI_CNT_ING_FRAME=%lld\n", value);
43 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
44 dflt_dpni->dpni_handle,
48 printf("dpni_get_counter: DPNI_CNT_ING_BYTE failed\n");
51 printf("DPNI_CNT_ING_BYTE=%lld\n", value);
53 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
54 dflt_dpni->dpni_handle,
55 DPNI_CNT_ING_FRAME_DROP ,
58 printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DROP failed\n");
61 printf("DPNI_CNT_ING_FRAME_DROP =%lld\n", value);
63 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
64 dflt_dpni->dpni_handle,
65 DPNI_CNT_ING_FRAME_DISCARD,
68 printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DISCARD failed\n");
71 printf("DPNI_CNT_ING_FRAME_DISCARD=%lld\n", value);
73 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
74 dflt_dpni->dpni_handle,
78 printf("dpni_get_counter: DPNI_CNT_EGR_FRAME failed\n");
81 printf("DPNI_CNT_EGR_FRAME=%lld\n", value);
83 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
84 dflt_dpni->dpni_handle,
88 printf("dpni_get_counter: DPNI_CNT_EGR_BYTE failed\n");
91 printf("DPNI_CNT_EGR_BYTE =%lld\n", value);
93 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
94 dflt_dpni->dpni_handle,
95 DPNI_CNT_EGR_FRAME_DISCARD ,
98 printf("dpni_get_counter: DPNI_CNT_EGR_FRAME_DISCARD failed\n");
101 printf("DPNI_CNT_EGR_FRAME_DISCARD =%lld\n", value);
105 static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
106 const struct dpaa_fd *fd)
111 struct ldpaa_fas *fas;
112 uint32_t status, err;
113 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
115 struct qbman_release_desc releasedesc;
116 struct qbman_swp *swp = dflt_dpio->sw_portal;
118 fd_addr = ldpaa_fd_get_addr(fd);
119 fd_offset = ldpaa_fd_get_offset(fd);
120 fd_length = ldpaa_fd_get_len(fd);
122 debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
124 if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
125 /* Read the frame annotation status word and check for errors */
126 fas = (struct ldpaa_fas *)
127 ((uint8_t *)(fd_addr) +
128 dflt_dpni->buf_layout.private_data_size);
129 status = le32_to_cpu(fas->status);
130 if (status & LDPAA_ETH_RX_ERR_MASK) {
131 printf("Rx frame error(s): 0x%08x\n",
132 status & LDPAA_ETH_RX_ERR_MASK);
134 } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
135 printf("Unsupported feature in bitmask: 0x%08x\n",
136 status & LDPAA_ETH_RX_UNSUPP_MASK);
141 debug("Rx frame: To Upper layer\n");
142 net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
146 flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
147 qbman_release_desc_clear(&releasedesc);
148 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
149 time_start = get_timer(0);
151 /* Release buffer into the QBMAN */
152 err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
153 } while (get_timer(time_start) < timeo && err == -EBUSY);
156 printf("Rx frame: QBMAN buffer release fails\n");
161 static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
163 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
164 const struct ldpaa_dq *dq;
165 const struct dpaa_fd *fd;
166 int i = 5, err = 0, status;
167 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
169 static struct qbman_pull_desc pulldesc;
170 struct qbman_swp *swp = dflt_dpio->sw_portal;
173 qbman_pull_desc_clear(&pulldesc);
174 qbman_pull_desc_set_numframes(&pulldesc, 1);
175 qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
177 err = qbman_swp_pull(swp, &pulldesc);
179 printf("Dequeue frames error:0x%08x\n", err);
183 time_start = get_timer(0);
186 dq = qbman_swp_dqrr_next(swp);
187 } while (get_timer(time_start) < timeo && !dq);
190 /* Check for valid frame. If not sent a consume
191 * confirmation to QBMAN otherwise give it to NADK
192 * application and then send consume confirmation to
195 status = (uint8_t)ldpaa_dq_flags(dq);
196 if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
197 debug("Dequeue RX frames:");
198 debug("No frame delivered\n");
200 qbman_swp_dqrr_consume(swp, dq);
204 fd = ldpaa_dq_fd(dq);
206 /* Obtain FD and process it */
207 ldpaa_eth_rx(priv, fd);
208 qbman_swp_dqrr_consume(swp, dq);
212 debug("No DQRR entries\n");
220 static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
222 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
225 int data_offset, err;
226 u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
228 struct qbman_swp *swp = dflt_dpio->sw_portal;
229 struct qbman_eq_desc ed;
230 struct qbman_release_desc releasedesc;
232 /* Setup the FD fields */
233 memset(&fd, 0, sizeof(fd));
235 data_offset = priv->tx_data_offset;
238 err = qbman_swp_acquire(dflt_dpio->sw_portal,
239 dflt_dpbp->dpbp_attr.bpid,
241 } while (err == -EBUSY);
244 printf("qbman_swp_acquire() failed\n");
248 debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
250 memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
252 flush_dcache_range(buffer_start, buffer_start +
253 LDPAA_ETH_RX_BUFFER_SIZE);
255 ldpaa_fd_set_addr(&fd, (u64)buffer_start);
256 ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
257 ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
258 ldpaa_fd_set_len(&fd, len);
260 fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
263 qbman_eq_desc_clear(&ed);
264 qbman_eq_desc_set_no_orp(&ed, 0);
265 qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
267 time_start = get_timer(0);
269 while (get_timer(time_start) < timeo) {
270 err = qbman_swp_enqueue(swp, &ed,
271 (const struct qbman_fd *)(&fd));
277 printf("error enqueueing Tx frame\n");
284 qbman_release_desc_clear(&releasedesc);
285 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
286 time_start = get_timer(0);
288 /* Release buffer into the QBMAN */
289 err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
290 } while (get_timer(time_start) < timeo && err == -EBUSY);
293 printf("TX data: QBMAN buffer release fails\n");
298 static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
300 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
301 struct dpni_queue_attr rx_queue_attr;
302 struct dpmac_link_state dpmac_link_state = { 0 };
304 struct dpni_link_state link_state;
308 if (net_dev->state == ETH_STATE_ACTIVE)
311 if (get_mc_boot_status() != 0) {
312 printf("ERROR (MC is not booted)\n");
316 if (get_dpl_apply_status() == 0) {
317 printf("ERROR (DPL is deployed. No device available)\n");
320 /* DPMAC initialization */
321 err = ldpaa_dpmac_setup(priv);
323 goto err_dpmac_setup;
325 /* DPMAC binding DPNI */
326 err = ldpaa_dpmac_bind(priv);
330 /* DPNI initialization */
331 err = ldpaa_dpni_setup(priv);
335 err = ldpaa_dpbp_setup();
339 /* DPNI binding DPBP */
340 err = ldpaa_dpni_bind(priv);
344 err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
345 dflt_dpni->dpni_handle, net_dev->enetaddr);
347 printf("dpni_add_mac_addr() failed\n");
352 /* TODO Check this path */
353 err = phy_startup(priv->phydev);
355 printf("%s: Could not initialize\n", priv->phydev->dev->name);
359 priv->phydev->speed = SPEED_1000;
360 priv->phydev->link = 1;
361 priv->phydev->duplex = DUPLEX_FULL;
364 err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
366 printf("dpni_enable() failed\n");
370 dpmac_link_state.rate = SPEED_1000;
371 dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG;
372 dpmac_link_state.up = 1;
373 err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
374 priv->dpmac_handle, &dpmac_link_state);
376 printf("dpmac_set_link_state() failed\n");
381 err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
382 dflt_dpni->dpni_handle, &link_state);
384 printf("dpni_get_link_state() failed\n");
388 printf("link status: %d - ", link_state.up);
389 link_state.up == 0 ? printf("down\n") :
390 link_state.up == 1 ? printf("up\n") : printf("error state\n");
393 /* TODO: support multiple Rx flows */
394 err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
395 dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr);
397 printf("dpni_get_rx_flow() failed\n");
401 priv->rx_dflt_fqid = rx_queue_attr.fqid;
403 err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
406 printf("dpni_get_qdid() failed\n");
410 if (!priv->phydev->link)
411 printf("%s: No link.\n", priv->phydev->dev->name);
413 return priv->phydev->link ? 0 : -1;
417 dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
422 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
428 static void ldpaa_eth_stop(struct eth_device *net_dev)
430 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
433 if ((net_dev->state == ETH_STATE_PASSIVE) ||
434 (net_dev->state == ETH_STATE_INIT))
438 ldpaa_eth_get_dpni_counter();
441 err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
442 dflt_dprc_handle, &dpmac_endpoint);
444 printf("dprc_disconnect() failed dpmac_endpoint\n");
446 err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
448 printf("dpmac_destroy() failed\n");
450 /* Stop Tx and Rx traffic */
451 err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
453 printf("dpni_disable() failed\n");
456 phy_shutdown(priv->phydev);
460 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
461 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
464 static void ldpaa_dpbp_drain_cnt(int count)
466 uint64_t buf_array[7];
473 ret = qbman_swp_acquire(dflt_dpio->sw_portal,
474 dflt_dpbp->dpbp_attr.bpid,
477 printf("qbman_swp_acquire() failed\n");
480 for (i = 0; i < ret; i++) {
481 addr = (void *)buf_array[i];
482 debug("Free: buffer addr =0x%p\n", addr);
488 static void ldpaa_dpbp_drain(void)
491 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
492 ldpaa_dpbp_drain_cnt(7);
495 static int ldpaa_bp_add_7(uint16_t bpid)
497 uint64_t buf_array[7];
500 struct qbman_release_desc rd;
502 for (i = 0; i < 7; i++) {
503 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
505 printf("addr allocation failed\n");
508 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
509 flush_dcache_range((u64)addr,
510 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
512 buf_array[i] = (uint64_t)addr;
513 debug("Release: buffer addr =0x%p\n", addr);
517 /* In case the portal is busy, retry until successful.
518 * This function is guaranteed to succeed in a reasonable amount
524 qbman_release_desc_clear(&rd);
525 qbman_release_desc_set_bpid(&rd, bpid);
526 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
537 static int ldpaa_dpbp_seed(uint16_t bpid)
542 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
543 count = ldpaa_bp_add_7(bpid);
545 printf("Buffer Seed= %d\n", count);
551 static int ldpaa_dpbp_setup(void)
555 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
556 &dflt_dpbp->dpbp_handle);
558 printf("dpbp_open() failed\n");
562 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
564 printf("dpbp_enable() failed\n");
568 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
569 dflt_dpbp->dpbp_handle,
570 &dflt_dpbp->dpbp_attr);
572 printf("dpbp_get_attributes() failed\n");
576 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
578 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
579 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
587 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
589 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
594 static void ldpaa_dpbp_free(void)
597 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
598 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
599 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
602 static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
605 struct dpmac_cfg dpmac_cfg;
607 dpmac_cfg.mac_id = priv->dpmac_id;
608 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg,
609 &priv->dpmac_handle);
611 printf("dpmac_create() failed\n");
615 static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
618 struct dprc_connection_cfg dprc_connection_cfg = {
619 /* If both rates are zero the connection */
620 /* will be configured in "best effort" mode. */
626 struct dprc_endpoint dbg_endpoint;
630 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
631 sprintf(dpmac_endpoint.type, "dpmac");
632 dpmac_endpoint.id = priv->dpmac_id;
634 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
635 sprintf(dpni_endpoint.type, "dpni");
636 dpni_endpoint.id = dflt_dpni->dpni_id;
638 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
642 &dprc_connection_cfg);
644 printf("dprc_connect() failed\n");
647 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
648 dflt_dprc_handle, &dpni_endpoint,
649 &dbg_endpoint, &state);
650 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
651 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
652 printf("%s, DPMAC State= %d\n", __func__, state);
654 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
655 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
656 dflt_dprc_handle, &dpmac_endpoint,
657 &dbg_endpoint, &state);
658 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
659 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
660 printf("%s, DPNI State= %d\n", __func__, state);
665 static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
669 /* and get a handle for the DPNI this interface is associate with */
670 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
671 &dflt_dpni->dpni_handle);
673 printf("dpni_open() failed\n");
677 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
678 dflt_dpni->dpni_handle,
679 &dflt_dpni->dpni_attrs);
681 printf("dpni_get_attributes() failed (err=%d)\n", err);
685 /* Configure our buffers' layout */
686 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
687 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
688 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
689 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
690 dflt_dpni->buf_layout.pass_parser_result = true;
691 dflt_dpni->buf_layout.pass_frame_status = true;
692 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
693 /* HW erratum mandates data alignment in multiples of 256 */
694 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
696 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
697 dflt_dpni->dpni_handle,
698 &dflt_dpni->buf_layout);
700 printf("dpni_set_rx_buffer_layout() failed");
705 /* remove Rx-only options */
706 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
707 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
708 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
709 dflt_dpni->dpni_handle,
710 &dflt_dpni->buf_layout);
712 printf("dpni_set_tx_buffer_layout() failed");
716 /* ... tx-confirm. */
717 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
718 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
719 dflt_dpni->dpni_handle,
720 &dflt_dpni->buf_layout);
722 printf("dpni_set_tx_conf_buffer_layout() failed");
726 /* Now that we've set our tx buffer layout, retrieve the minimum
727 * required tx data offset.
729 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
730 dflt_dpni->dpni_handle,
731 &priv->tx_data_offset);
733 printf("dpni_get_tx_data_offset() failed\n");
734 goto err_data_offset;
737 /* Warn in case TX data offset is not multiple of 64 bytes. */
738 WARN_ON(priv->tx_data_offset % 64);
740 /* Accomodate SWA space. */
741 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
742 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
749 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
754 static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
756 struct dpni_pools_cfg pools_params;
757 struct dpni_tx_flow_cfg dflt_tx_flow;
760 pools_params.num_dpbp = 1;
761 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
762 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
763 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
764 dflt_dpni->dpni_handle, &pools_params);
766 printf("dpni_set_pools() failed\n");
770 priv->tx_flow_id = DPNI_NEW_FLOW_ID;
771 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
773 dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR;
774 dflt_tx_flow.conf_err_cfg.use_default_queue = 0;
775 dflt_tx_flow.conf_err_cfg.errors_only = 1;
776 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
777 dflt_dpni->dpni_handle, &priv->tx_flow_id,
780 printf("dpni_set_tx_flow() failed\n");
787 static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
788 phy_interface_t enet_if)
791 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
793 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id,
794 phy_interface_strings[enet_if]);
797 net_dev->init = ldpaa_eth_open;
798 net_dev->halt = ldpaa_eth_stop;
799 net_dev->send = ldpaa_eth_tx;
800 net_dev->recv = ldpaa_eth_pull_dequeue_rx;
802 TODO: PHY MDIO information
803 priv->bus = info->bus;
804 priv->phyaddr = info->phy_addr;
805 priv->enet_if = info->enet_if;
808 if (init_phy(net_dev))
811 err = eth_register(net_dev);
813 printf("eth_register() = %d\n", err);
820 int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
822 struct eth_device *net_dev = NULL;
823 struct ldpaa_eth_priv *priv = NULL;
828 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
830 printf("eth_device malloc() failed\n");
833 memset(net_dev, 0, sizeof(struct eth_device));
835 /* alloc the ldpaa ethernet private struct */
836 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
838 printf("ldpaa_eth_priv malloc() failed\n");
841 memset(priv, 0, sizeof(struct ldpaa_eth_priv));
843 net_dev->priv = (void *)priv;
844 priv->net_dev = (struct eth_device *)net_dev;
845 priv->dpmac_id = dpmac_id;
846 debug("%s dpmac_id=%d\n", __func__, dpmac_id);
848 err = ldpaa_eth_netdev_init(net_dev, enet_if);
850 goto err_netdev_init;
852 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
857 net_dev->priv = NULL;