blob: 6de5f30f6c874162db78522057f0bb358d3db572 [file] [log] [blame]
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -07001/*
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
16#include "ldpaa_eth.h"
17
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -070018#undef CONFIG_PHYLIB
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070019static int init_phy(struct eth_device *dev)
20{
21 /*TODO for external PHY */
22
23 return 0;
24}
25
26static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
27 const struct dpaa_fd *fd)
28{
29 u64 fd_addr;
30 uint16_t fd_offset;
31 uint32_t fd_length;
32 struct ldpaa_fas *fas;
33 uint32_t status, err;
34 struct qbman_release_desc releasedesc;
35 struct qbman_swp *swp = dflt_dpio->sw_portal;
36
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070037 fd_addr = ldpaa_fd_get_addr(fd);
38 fd_offset = ldpaa_fd_get_offset(fd);
39 fd_length = ldpaa_fd_get_len(fd);
40
41 debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
42
43 if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
44 /* Read the frame annotation status word and check for errors */
45 fas = (struct ldpaa_fas *)
46 ((uint8_t *)(fd_addr) +
47 priv->buf_layout.private_data_size);
48 status = le32_to_cpu(fas->status);
49 if (status & LDPAA_ETH_RX_ERR_MASK) {
50 printf("Rx frame error(s): 0x%08x\n",
51 status & LDPAA_ETH_RX_ERR_MASK);
52 goto error;
53 } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
54 printf("Unsupported feature in bitmask: 0x%08x\n",
55 status & LDPAA_ETH_RX_UNSUPP_MASK);
56 goto error;
57 }
58 }
59
60 debug("Rx frame: To Upper layer\n");
61 net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
62 fd_length);
63
64error:
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -070065 flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070066 qbman_release_desc_clear(&releasedesc);
67 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
68 do {
69 /* Release buffer into the QBMAN */
70 err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
71 } while (err == -EBUSY);
72 return;
73}
74
75static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
76{
77 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
78 const struct ldpaa_dq *dq;
79 const struct dpaa_fd *fd;
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +053080 int i = 5, err = 0, status;
81 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
82 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070083 static struct qbman_pull_desc pulldesc;
84 struct qbman_swp *swp = dflt_dpio->sw_portal;
85
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070086 while (--i) {
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -070087 qbman_pull_desc_clear(&pulldesc);
88 qbman_pull_desc_set_numframes(&pulldesc, 1);
89 qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
90
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070091 err = qbman_swp_pull(swp, &pulldesc);
92 if (err < 0) {
93 printf("Dequeue frames error:0x%08x\n", err);
94 continue;
95 }
96
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +053097 time_start = get_timer(0);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -070098
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +053099 do {
100 dq = qbman_swp_dqrr_next(swp);
101 } while (get_timer(time_start) < timeo && !dq);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700102
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700103 if (dq) {
104 /* Check for valid frame. If not sent a consume
105 * confirmation to QBMAN otherwise give it to NADK
106 * application and then send consume confirmation to
107 * QBMAN.
108 */
109 status = (uint8_t)ldpaa_dq_flags(dq);
110 if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
111 debug("Dequeue RX frames:");
112 debug("No frame delivered\n");
113
114 qbman_swp_dqrr_consume(swp, dq);
Prabhakar Kushwaha37ed1a62015-07-02 11:29:07 +0530115 continue;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700116 }
117
118 fd = ldpaa_dq_fd(dq);
119
120 /* Obtain FD and process it */
121 ldpaa_eth_rx(priv, fd);
122 qbman_swp_dqrr_consume(swp, dq);
123 break;
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530124 } else {
125 err = -ENODATA;
126 debug("No DQRR entries\n");
127 break;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700128 }
129 }
130
131 return err;
132}
133
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700134static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
135{
136 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
137 struct dpaa_fd fd;
138 u64 buffer_start;
139 int data_offset, err;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530140 u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
141 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700142 struct qbman_swp *swp = dflt_dpio->sw_portal;
143 struct qbman_eq_desc ed;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530144 struct qbman_release_desc releasedesc;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700145
146 /* Setup the FD fields */
147 memset(&fd, 0, sizeof(fd));
148
149 data_offset = priv->tx_data_offset;
150
151 do {
152 err = qbman_swp_acquire(dflt_dpio->sw_portal,
153 dflt_dpbp->dpbp_attr.bpid,
154 &buffer_start, 1);
155 } while (err == -EBUSY);
156
157 if (err < 0) {
158 printf("qbman_swp_acquire() failed\n");
159 return -ENOMEM;
160 }
161
162 debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
163
164 memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
165
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700166 flush_dcache_range(buffer_start, buffer_start +
167 LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700168
169 ldpaa_fd_set_addr(&fd, (u64)buffer_start);
170 ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
171 ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
172 ldpaa_fd_set_len(&fd, len);
173
174 fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
175 LDPAA_FD_CTRL_PTV1;
176
177 qbman_eq_desc_clear(&ed);
178 qbman_eq_desc_set_no_orp(&ed, 0);
179 qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530180
181 time_start = get_timer(0);
182
183 while (get_timer(time_start) < timeo) {
184 err = qbman_swp_enqueue(swp, &ed,
185 (const struct qbman_fd *)(&fd));
186 if (err != -EBUSY)
187 break;
188 }
189
190 if (err < 0) {
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700191 printf("error enqueueing Tx frame\n");
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530192 goto error;
193 }
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700194
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700195 return err;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530196
197error:
198 qbman_release_desc_clear(&releasedesc);
199 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
200 time_start = get_timer(0);
201 do {
202 /* Release buffer into the QBMAN */
203 err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
204 } while (get_timer(time_start) < timeo && err == -EBUSY);
205
206 if (err == -EBUSY)
207 printf("TX data: QBMAN buffer release fails\n");
208
209 return err;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700210}
211
212static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
213{
214 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
215 struct dpni_queue_attr rx_queue_attr;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700216 uint8_t mac_addr[6];
217 int err;
218
219 if (net_dev->state == ETH_STATE_ACTIVE)
220 return 0;
221
222 /* DPNI initialization */
223 err = ldpaa_dpni_setup(priv);
224 if (err < 0)
225 goto err_dpni_setup;
226
227 err = ldpaa_dpbp_setup();
228 if (err < 0)
229 goto err_dpbp_setup;
230
231 /* DPNI binding DPBP */
232 err = ldpaa_dpni_bind(priv);
233 if (err)
234 goto err_bind;
235
236 err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle,
237 mac_addr);
238 if (err) {
239 printf("dpni_get_primary_mac_addr() failed\n");
240 return err;
241 }
242
243 memcpy(net_dev->enetaddr, mac_addr, 0x6);
244
245 /* setup the MAC address */
246 if (net_dev->enetaddr[0] & 0x01) {
247 printf("%s: MacAddress is multcast address\n", __func__);
248 return 1;
249 }
250
251#ifdef CONFIG_PHYLIB
252 /* TODO Check this path */
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700253 err = phy_startup(priv->phydev);
254 if (err) {
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700255 printf("%s: Could not initialize\n", priv->phydev->dev->name);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700256 return err;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700257 }
258#else
259 priv->phydev->speed = SPEED_1000;
260 priv->phydev->link = 1;
261 priv->phydev->duplex = DUPLEX_FULL;
262#endif
263
264 err = dpni_enable(dflt_mc_io, priv->dpni_handle);
265 if (err < 0) {
266 printf("dpni_enable() failed\n");
267 return err;
268 }
269
270 /* TODO: support multiple Rx flows */
271 err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0,
272 &rx_queue_attr);
273 if (err) {
274 printf("dpni_get_rx_flow() failed\n");
275 goto err_rx_flow;
276 }
277
278 priv->rx_dflt_fqid = rx_queue_attr.fqid;
279
280 err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid);
281 if (err) {
282 printf("dpni_get_qdid() failed\n");
283 goto err_qdid;
284 }
285
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700286 if (!priv->phydev->link)
287 printf("%s: No link.\n", priv->phydev->dev->name);
288
289 return priv->phydev->link ? 0 : -1;
290
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700291err_qdid:
292err_rx_flow:
293 dpni_disable(dflt_mc_io, priv->dpni_handle);
294err_bind:
295 ldpaa_dpbp_free();
296err_dpbp_setup:
297 dpni_close(dflt_mc_io, priv->dpni_handle);
298err_dpni_setup:
299 return err;
300}
301
302static void ldpaa_eth_stop(struct eth_device *net_dev)
303{
304 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
305 int err = 0;
306
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700307 if ((net_dev->state == ETH_STATE_PASSIVE) ||
308 (net_dev->state == ETH_STATE_INIT))
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700309 return;
310 /* Stop Tx and Rx traffic */
311 err = dpni_disable(dflt_mc_io, priv->dpni_handle);
312 if (err < 0)
313 printf("dpni_disable() failed\n");
314
315#ifdef CONFIG_PHYLIB
316 phy_shutdown(priv->phydev);
317#endif
318
319 ldpaa_dpbp_free();
320 dpni_reset(dflt_mc_io, priv->dpni_handle);
321 dpni_close(dflt_mc_io, priv->dpni_handle);
322}
323
324static void ldpaa_dpbp_drain_cnt(int count)
325{
326 uint64_t buf_array[7];
327 void *addr;
328 int ret, i;
329
330 BUG_ON(count > 7);
331
332 do {
333 ret = qbman_swp_acquire(dflt_dpio->sw_portal,
334 dflt_dpbp->dpbp_attr.bpid,
335 buf_array, count);
336 if (ret < 0) {
337 printf("qbman_swp_acquire() failed\n");
338 return;
339 }
340 for (i = 0; i < ret; i++) {
341 addr = (void *)buf_array[i];
342 debug("Free: buffer addr =0x%p\n", addr);
343 free(addr);
344 }
345 } while (ret);
346}
347
348static void ldpaa_dpbp_drain(void)
349{
350 int i;
351 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
352 ldpaa_dpbp_drain_cnt(7);
353}
354
355static int ldpaa_bp_add_7(uint16_t bpid)
356{
357 uint64_t buf_array[7];
358 u8 *addr;
359 int i;
360 struct qbman_release_desc rd;
361
362 for (i = 0; i < 7; i++) {
363 addr = memalign(L1_CACHE_BYTES, LDPAA_ETH_RX_BUFFER_SIZE);
364 if (!addr) {
365 printf("addr allocation failed\n");
366 goto err_alloc;
367 }
368 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700369 flush_dcache_range((u64)addr,
370 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700371
372 buf_array[i] = (uint64_t)addr;
373 debug("Release: buffer addr =0x%p\n", addr);
374 }
375
376release_bufs:
377 /* In case the portal is busy, retry until successful.
378 * This function is guaranteed to succeed in a reasonable amount
379 * of time.
380 */
381
382 do {
383 mdelay(1);
384 qbman_release_desc_clear(&rd);
385 qbman_release_desc_set_bpid(&rd, bpid);
386 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
387
388 return i;
389
390err_alloc:
391 if (i)
392 goto release_bufs;
393
394 return 0;
395}
396
397static int ldpaa_dpbp_seed(uint16_t bpid)
398{
399 int i;
400 int count;
401
402 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
403 count = ldpaa_bp_add_7(bpid);
404 if (count < 7)
405 printf("Buffer Seed= %d\n", count);
406 }
407
408 return 0;
409}
410
411static int ldpaa_dpbp_setup(void)
412{
413 int err;
414
415 err = dpbp_open(dflt_mc_io, dflt_dpbp->dpbp_attr.id,
416 &dflt_dpbp->dpbp_handle);
417 if (err) {
418 printf("dpbp_open() failed\n");
419 goto err_open;
420 }
421
422 err = dpbp_enable(dflt_mc_io, dflt_dpbp->dpbp_handle);
423 if (err) {
424 printf("dpbp_enable() failed\n");
425 goto err_enable;
426 }
427
428 err = dpbp_get_attributes(dflt_mc_io, dflt_dpbp->dpbp_handle,
429 &dflt_dpbp->dpbp_attr);
430 if (err) {
431 printf("dpbp_get_attributes() failed\n");
432 goto err_get_attr;
433 }
434
435 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
436 if (err) {
437 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
438 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
439 goto err_seed;
440 }
441
442 return 0;
443
444err_seed:
445err_get_attr:
446 dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
447err_enable:
448 dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
449err_open:
450 return err;
451}
452
453static void ldpaa_dpbp_free(void)
454{
455 ldpaa_dpbp_drain();
456 dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
457 dpbp_reset(dflt_mc_io, dflt_dpbp->dpbp_handle);
458 dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
459}
460
461static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
462{
463 int err;
464
465 /* and get a handle for the DPNI this interface is associate with */
466 err = dpni_open(dflt_mc_io, priv->dpni_id, &priv->dpni_handle);
467 if (err) {
468 printf("dpni_open() failed\n");
469 goto err_open;
470 }
471
472 err = dpni_get_attributes(dflt_mc_io, priv->dpni_handle,
473 &priv->dpni_attrs);
474 if (err) {
475 printf("dpni_get_attributes() failed (err=%d)\n", err);
476 goto err_get_attr;
477 }
478
479 /* Configure our buffers' layout */
480 priv->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
481 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
482 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
483 priv->buf_layout.pass_parser_result = true;
484 priv->buf_layout.pass_frame_status = true;
485 priv->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
486 /* ...rx, ... */
487 err = dpni_set_rx_buffer_layout(dflt_mc_io, priv->dpni_handle,
488 &priv->buf_layout);
489 if (err) {
490 printf("dpni_set_rx_buffer_layout() failed");
491 goto err_buf_layout;
492 }
493
494 /* ... tx, ... */
495 priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT;
496 err = dpni_set_tx_buffer_layout(dflt_mc_io, priv->dpni_handle,
497 &priv->buf_layout);
498 if (err) {
499 printf("dpni_set_tx_buffer_layout() failed");
500 goto err_buf_layout;
501 }
502
503 /* ... tx-confirm. */
504 priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
505 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, priv->dpni_handle,
506 &priv->buf_layout);
507 if (err) {
508 printf("dpni_set_tx_conf_buffer_layout() failed");
509 goto err_buf_layout;
510 }
511
512 /* Now that we've set our tx buffer layout, retrieve the minimum
513 * required tx data offset.
514 */
515 err = dpni_get_tx_data_offset(dflt_mc_io, priv->dpni_handle,
516 &priv->tx_data_offset);
517 if (err) {
518 printf("dpni_get_tx_data_offset() failed\n");
519 goto err_data_offset;
520 }
521
522 /* Warn in case TX data offset is not multiple of 64 bytes. */
523 WARN_ON(priv->tx_data_offset % 64);
524
525 /* Accomodate SWA space. */
526 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
527 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
528
529 return 0;
530
531err_data_offset:
532err_buf_layout:
533err_get_attr:
534 dpni_close(dflt_mc_io, priv->dpni_handle);
535err_open:
536 return err;
537}
538
539static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
540{
541 struct dpni_pools_cfg pools_params;
542 struct dpni_tx_flow_cfg dflt_tx_flow;
543 int err = 0;
544
545 pools_params.num_dpbp = 1;
546 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
547 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
548 err = dpni_set_pools(dflt_mc_io, priv->dpni_handle, &pools_params);
549 if (err) {
550 printf("dpni_set_pools() failed\n");
551 return err;
552 }
553
554 priv->tx_flow_id = DPNI_NEW_FLOW_ID;
555 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
556
Prabhakar Kushwaha37ed1a62015-07-02 11:29:07 +0530557 dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR;
558 dflt_tx_flow.conf_err_cfg.use_default_queue = 0;
559 dflt_tx_flow.conf_err_cfg.errors_only = 1;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700560 err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle,
561 &priv->tx_flow_id, &dflt_tx_flow);
562 if (err) {
563 printf("dpni_set_tx_flow() failed\n");
564 return err;
565 }
566
567 return 0;
568}
569
570static int ldpaa_eth_netdev_init(struct eth_device *net_dev)
571{
572 int err;
573 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
574
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700575 sprintf(net_dev->name, "DPNI%d", priv->dpni_id);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700576
577 net_dev->iobase = 0;
578 net_dev->init = ldpaa_eth_open;
579 net_dev->halt = ldpaa_eth_stop;
580 net_dev->send = ldpaa_eth_tx;
581 net_dev->recv = ldpaa_eth_pull_dequeue_rx;
582/*
583 TODO: PHY MDIO information
584 priv->bus = info->bus;
585 priv->phyaddr = info->phy_addr;
586 priv->enet_if = info->enet_if;
587*/
588
589 if (init_phy(net_dev))
590 return 0;
591
592 err = eth_register(net_dev);
593 if (err < 0) {
594 printf("eth_register() = %d\n", err);
595 return err;
596 }
597
598 return 0;
599}
600
601int ldpaa_eth_init(struct dprc_obj_desc obj_desc)
602{
603 struct eth_device *net_dev = NULL;
604 struct ldpaa_eth_priv *priv = NULL;
605 int err = 0;
606
607
608 /* Net device */
609 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
610 if (!net_dev) {
611 printf("eth_device malloc() failed\n");
612 return -ENOMEM;
613 }
614 memset(net_dev, 0, sizeof(struct eth_device));
615
616 /* alloc the ldpaa ethernet private struct */
617 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
618 if (!priv) {
619 printf("ldpaa_eth_priv malloc() failed\n");
620 return -ENOMEM;
621 }
622 memset(priv, 0, sizeof(struct ldpaa_eth_priv));
623
624 net_dev->priv = (void *)priv;
625 priv->net_dev = (struct eth_device *)net_dev;
626 priv->dpni_id = obj_desc.id;
627
628 err = ldpaa_eth_netdev_init(net_dev);
629 if (err)
630 goto err_netdev_init;
631
632 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
633 return 0;
634
635err_netdev_init:
636 free(priv);
637 net_dev->priv = NULL;
638 free(net_dev);
639
640 return err;
641}