blob: 7f96883d347de6a1a44c0f4f07d666b515dc7164 [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>
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +053015#include <fsl-mc/fsl_dpmac.h>
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070016
17#include "ldpaa_eth.h"
18
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -070019#undef CONFIG_PHYLIB
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070020static int init_phy(struct eth_device *dev)
21{
22 /*TODO for external PHY */
23
24 return 0;
25}
26
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +053027#ifdef DEBUG
28static void ldpaa_eth_get_dpni_counter(void)
29{
30 int err = 0;
31 u64 value;
32
33 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
34 dflt_dpni->dpni_handle,
35 DPNI_CNT_ING_FRAME,
36 &value);
37 if (err < 0) {
38 printf("dpni_get_counter: DPNI_CNT_ING_FRAME failed\n");
39 return;
40 }
41 printf("DPNI_CNT_ING_FRAME=%lld\n", value);
42
43 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
44 dflt_dpni->dpni_handle,
45 DPNI_CNT_ING_BYTE,
46 &value);
47 if (err < 0) {
48 printf("dpni_get_counter: DPNI_CNT_ING_BYTE failed\n");
49 return;
50 }
51 printf("DPNI_CNT_ING_BYTE=%lld\n", value);
52
53 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
54 dflt_dpni->dpni_handle,
55 DPNI_CNT_ING_FRAME_DROP ,
56 &value);
57 if (err < 0) {
58 printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DROP failed\n");
59 return;
60 }
61 printf("DPNI_CNT_ING_FRAME_DROP =%lld\n", value);
62
63 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
64 dflt_dpni->dpni_handle,
65 DPNI_CNT_ING_FRAME_DISCARD,
66 &value);
67 if (err < 0) {
68 printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DISCARD failed\n");
69 return;
70 }
71 printf("DPNI_CNT_ING_FRAME_DISCARD=%lld\n", value);
72
73 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
74 dflt_dpni->dpni_handle,
75 DPNI_CNT_EGR_FRAME,
76 &value);
77 if (err < 0) {
78 printf("dpni_get_counter: DPNI_CNT_EGR_FRAME failed\n");
79 return;
80 }
81 printf("DPNI_CNT_EGR_FRAME=%lld\n", value);
82
83 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
84 dflt_dpni->dpni_handle,
85 DPNI_CNT_EGR_BYTE ,
86 &value);
87 if (err < 0) {
88 printf("dpni_get_counter: DPNI_CNT_EGR_BYTE failed\n");
89 return;
90 }
91 printf("DPNI_CNT_EGR_BYTE =%lld\n", value);
92
93 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
94 dflt_dpni->dpni_handle,
95 DPNI_CNT_EGR_FRAME_DISCARD ,
96 &value);
97 if (err < 0) {
98 printf("dpni_get_counter: DPNI_CNT_EGR_FRAME_DISCARD failed\n");
99 return;
100 }
101 printf("DPNI_CNT_EGR_FRAME_DISCARD =%lld\n", value);
102}
Prabhakar Kushwaha314aa552015-12-24 15:33:37 +0530103
104static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev)
105{
106 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
107 int err = 0;
108 u64 value;
109
110 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
111 priv->dpmac_handle,
112 DPMAC_CNT_ING_BYTE,
113 &value);
114 if (err < 0) {
115 printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
116 return;
117 }
118 printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
119
120 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
121 priv->dpmac_handle,
122 DPMAC_CNT_ING_FRAME_DISCARD,
123 &value);
124 if (err < 0) {
125 printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
126 return;
127 }
128 printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value);
129
130 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
131 priv->dpmac_handle,
132 DPMAC_CNT_ING_ALIGN_ERR,
133 &value);
134 if (err < 0) {
135 printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
136 return;
137 }
138 printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value);
139
140 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
141 priv->dpmac_handle,
142 DPMAC_CNT_ING_BYTE,
143 &value);
144 if (err < 0) {
145 printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
146 return;
147 }
148 printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
149
150 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
151 priv->dpmac_handle,
152 DPMAC_CNT_ING_ERR_FRAME,
153 &value);
154 if (err < 0) {
155 printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
156 return;
157 }
158 printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value);
159
160 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
161 priv->dpmac_handle,
162 DPMAC_CNT_EGR_BYTE ,
163 &value);
164 if (err < 0) {
165 printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
166 return;
167 }
168 printf("DPMAC_CNT_EGR_BYTE =%lld\n", value);
169
170 err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
171 priv->dpmac_handle,
172 DPMAC_CNT_EGR_ERR_FRAME ,
173 &value);
174 if (err < 0) {
175 printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
176 return;
177 }
178 printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
179}
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530180#endif
181
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700182static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
183 const struct dpaa_fd *fd)
184{
185 u64 fd_addr;
186 uint16_t fd_offset;
187 uint32_t fd_length;
188 struct ldpaa_fas *fas;
189 uint32_t status, err;
Prabhakar Kushwahac7d10d82015-07-02 11:29:08 +0530190 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
191 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700192 struct qbman_release_desc releasedesc;
193 struct qbman_swp *swp = dflt_dpio->sw_portal;
194
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700195 fd_addr = ldpaa_fd_get_addr(fd);
196 fd_offset = ldpaa_fd_get_offset(fd);
197 fd_length = ldpaa_fd_get_len(fd);
198
199 debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
200
201 if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
202 /* Read the frame annotation status word and check for errors */
203 fas = (struct ldpaa_fas *)
204 ((uint8_t *)(fd_addr) +
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530205 dflt_dpni->buf_layout.private_data_size);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700206 status = le32_to_cpu(fas->status);
207 if (status & LDPAA_ETH_RX_ERR_MASK) {
208 printf("Rx frame error(s): 0x%08x\n",
209 status & LDPAA_ETH_RX_ERR_MASK);
210 goto error;
211 } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
212 printf("Unsupported feature in bitmask: 0x%08x\n",
213 status & LDPAA_ETH_RX_UNSUPP_MASK);
214 goto error;
215 }
216 }
217
218 debug("Rx frame: To Upper layer\n");
219 net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
220 fd_length);
221
222error:
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700223 flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700224 qbman_release_desc_clear(&releasedesc);
225 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
Prabhakar Kushwahac7d10d82015-07-02 11:29:08 +0530226 time_start = get_timer(0);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700227 do {
228 /* Release buffer into the QBMAN */
229 err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
Prabhakar Kushwahac7d10d82015-07-02 11:29:08 +0530230 } while (get_timer(time_start) < timeo && err == -EBUSY);
231
232 if (err == -EBUSY)
233 printf("Rx frame: QBMAN buffer release fails\n");
234
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700235 return;
236}
237
238static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
239{
240 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
241 const struct ldpaa_dq *dq;
242 const struct dpaa_fd *fd;
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530243 int i = 5, err = 0, status;
244 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
245 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700246 static struct qbman_pull_desc pulldesc;
247 struct qbman_swp *swp = dflt_dpio->sw_portal;
248
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700249 while (--i) {
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700250 qbman_pull_desc_clear(&pulldesc);
251 qbman_pull_desc_set_numframes(&pulldesc, 1);
252 qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
253
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700254 err = qbman_swp_pull(swp, &pulldesc);
255 if (err < 0) {
256 printf("Dequeue frames error:0x%08x\n", err);
257 continue;
258 }
259
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530260 time_start = get_timer(0);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700261
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530262 do {
263 dq = qbman_swp_dqrr_next(swp);
264 } while (get_timer(time_start) < timeo && !dq);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700265
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700266 if (dq) {
267 /* Check for valid frame. If not sent a consume
268 * confirmation to QBMAN otherwise give it to NADK
269 * application and then send consume confirmation to
270 * QBMAN.
271 */
272 status = (uint8_t)ldpaa_dq_flags(dq);
273 if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
274 debug("Dequeue RX frames:");
275 debug("No frame delivered\n");
276
277 qbman_swp_dqrr_consume(swp, dq);
Prabhakar Kushwaha37ed1a62015-07-02 11:29:07 +0530278 continue;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700279 }
280
281 fd = ldpaa_dq_fd(dq);
282
283 /* Obtain FD and process it */
284 ldpaa_eth_rx(priv, fd);
285 qbman_swp_dqrr_consume(swp, dq);
286 break;
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530287 } else {
288 err = -ENODATA;
289 debug("No DQRR entries\n");
290 break;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700291 }
292 }
293
294 return err;
295}
296
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700297static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
298{
299 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
300 struct dpaa_fd fd;
301 u64 buffer_start;
302 int data_offset, err;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530303 u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
304 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700305 struct qbman_swp *swp = dflt_dpio->sw_portal;
306 struct qbman_eq_desc ed;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530307 struct qbman_release_desc releasedesc;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700308
309 /* Setup the FD fields */
310 memset(&fd, 0, sizeof(fd));
311
312 data_offset = priv->tx_data_offset;
313
314 do {
315 err = qbman_swp_acquire(dflt_dpio->sw_portal,
316 dflt_dpbp->dpbp_attr.bpid,
317 &buffer_start, 1);
318 } while (err == -EBUSY);
319
320 if (err < 0) {
321 printf("qbman_swp_acquire() failed\n");
322 return -ENOMEM;
323 }
324
325 debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
326
327 memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
328
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700329 flush_dcache_range(buffer_start, buffer_start +
330 LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700331
332 ldpaa_fd_set_addr(&fd, (u64)buffer_start);
333 ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
334 ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
335 ldpaa_fd_set_len(&fd, len);
336
337 fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
338 LDPAA_FD_CTRL_PTV1;
339
340 qbman_eq_desc_clear(&ed);
341 qbman_eq_desc_set_no_orp(&ed, 0);
342 qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530343
344 time_start = get_timer(0);
345
346 while (get_timer(time_start) < timeo) {
347 err = qbman_swp_enqueue(swp, &ed,
348 (const struct qbman_fd *)(&fd));
349 if (err != -EBUSY)
350 break;
351 }
352
353 if (err < 0) {
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700354 printf("error enqueueing Tx frame\n");
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530355 goto error;
356 }
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700357
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700358 return err;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530359
360error:
361 qbman_release_desc_clear(&releasedesc);
362 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
363 time_start = get_timer(0);
364 do {
365 /* Release buffer into the QBMAN */
366 err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
367 } while (get_timer(time_start) < timeo && err == -EBUSY);
368
369 if (err == -EBUSY)
370 printf("TX data: QBMAN buffer release fails\n");
371
372 return err;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700373}
374
375static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
376{
377 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
378 struct dpni_queue_attr rx_queue_attr;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530379 struct dpmac_link_state dpmac_link_state = { 0 };
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530380#ifdef DEBUG
381 struct dpni_link_state link_state;
382#endif
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700383 int err;
384
385 if (net_dev->state == ETH_STATE_ACTIVE)
386 return 0;
387
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530388 if (get_mc_boot_status() != 0) {
389 printf("ERROR (MC is not booted)\n");
390 return -ENODEV;
391 }
392
393 if (get_dpl_apply_status() == 0) {
394 printf("ERROR (DPL is deployed. No device available)\n");
395 return -ENODEV;
396 }
397 /* DPMAC initialization */
398 err = ldpaa_dpmac_setup(priv);
399 if (err < 0)
400 goto err_dpmac_setup;
401
402 /* DPMAC binding DPNI */
403 err = ldpaa_dpmac_bind(priv);
404 if (err)
405 goto err_dpamc_bind;
406
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700407 /* DPNI initialization */
408 err = ldpaa_dpni_setup(priv);
409 if (err < 0)
410 goto err_dpni_setup;
411
412 err = ldpaa_dpbp_setup();
413 if (err < 0)
414 goto err_dpbp_setup;
415
416 /* DPNI binding DPBP */
417 err = ldpaa_dpni_bind(priv);
418 if (err)
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530419 goto err_dpni_bind;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700420
Prabhakar Kushwahad2c20a32015-10-07 16:29:58 +0530421 err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530422 dflt_dpni->dpni_handle, net_dev->enetaddr);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700423 if (err) {
Prabhakar Kushwahad2c20a32015-10-07 16:29:58 +0530424 printf("dpni_add_mac_addr() failed\n");
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700425 return err;
426 }
427
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700428#ifdef CONFIG_PHYLIB
429 /* TODO Check this path */
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700430 err = phy_startup(priv->phydev);
431 if (err) {
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700432 printf("%s: Could not initialize\n", priv->phydev->dev->name);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700433 return err;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700434 }
435#else
436 priv->phydev->speed = SPEED_1000;
437 priv->phydev->link = 1;
438 priv->phydev->duplex = DUPLEX_FULL;
439#endif
440
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530441 err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700442 if (err < 0) {
443 printf("dpni_enable() failed\n");
444 return err;
445 }
446
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530447 dpmac_link_state.rate = SPEED_1000;
448 dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG;
449 dpmac_link_state.up = 1;
450 err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
451 priv->dpmac_handle, &dpmac_link_state);
452 if (err < 0) {
453 printf("dpmac_set_link_state() failed\n");
454 return err;
455 }
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530456
457#ifdef DEBUG
458 err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
459 dflt_dpni->dpni_handle, &link_state);
460 if (err < 0) {
461 printf("dpni_get_link_state() failed\n");
462 return err;
463 }
464
465 printf("link status: %d - ", link_state.up);
466 link_state.up == 0 ? printf("down\n") :
467 link_state.up == 1 ? printf("up\n") : printf("error state\n");
468#endif
469
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700470 /* TODO: support multiple Rx flows */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530471 err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
472 dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700473 if (err) {
474 printf("dpni_get_rx_flow() failed\n");
475 goto err_rx_flow;
476 }
477
478 priv->rx_dflt_fqid = rx_queue_attr.fqid;
479
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530480 err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530481 &priv->tx_qdid);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700482 if (err) {
483 printf("dpni_get_qdid() failed\n");
484 goto err_qdid;
485 }
486
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700487 if (!priv->phydev->link)
488 printf("%s: No link.\n", priv->phydev->dev->name);
489
490 return priv->phydev->link ? 0 : -1;
491
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700492err_qdid:
493err_rx_flow:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530494 dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
495err_dpni_bind:
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700496 ldpaa_dpbp_free();
497err_dpbp_setup:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530498err_dpamc_bind:
499 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700500err_dpni_setup:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530501err_dpmac_setup:
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700502 return err;
503}
504
505static void ldpaa_eth_stop(struct eth_device *net_dev)
506{
507 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
508 int err = 0;
509
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700510 if ((net_dev->state == ETH_STATE_PASSIVE) ||
511 (net_dev->state == ETH_STATE_INIT))
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700512 return;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530513
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530514#ifdef DEBUG
515 ldpaa_eth_get_dpni_counter();
Prabhakar Kushwaha314aa552015-12-24 15:33:37 +0530516 ldpaa_eth_get_dpmac_counter(net_dev);
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530517#endif
518
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530519 err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
520 dflt_dprc_handle, &dpmac_endpoint);
521 if (err < 0)
522 printf("dprc_disconnect() failed dpmac_endpoint\n");
523
524 err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
525 if (err < 0)
526 printf("dpmac_destroy() failed\n");
527
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700528 /* Stop Tx and Rx traffic */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530529 err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700530 if (err < 0)
531 printf("dpni_disable() failed\n");
532
533#ifdef CONFIG_PHYLIB
534 phy_shutdown(priv->phydev);
535#endif
536
537 ldpaa_dpbp_free();
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530538 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
539 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700540}
541
542static void ldpaa_dpbp_drain_cnt(int count)
543{
544 uint64_t buf_array[7];
545 void *addr;
546 int ret, i;
547
548 BUG_ON(count > 7);
549
550 do {
551 ret = qbman_swp_acquire(dflt_dpio->sw_portal,
552 dflt_dpbp->dpbp_attr.bpid,
553 buf_array, count);
554 if (ret < 0) {
555 printf("qbman_swp_acquire() failed\n");
556 return;
557 }
558 for (i = 0; i < ret; i++) {
559 addr = (void *)buf_array[i];
560 debug("Free: buffer addr =0x%p\n", addr);
561 free(addr);
562 }
563 } while (ret);
564}
565
566static void ldpaa_dpbp_drain(void)
567{
568 int i;
569 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
570 ldpaa_dpbp_drain_cnt(7);
571}
572
573static int ldpaa_bp_add_7(uint16_t bpid)
574{
575 uint64_t buf_array[7];
576 u8 *addr;
577 int i;
578 struct qbman_release_desc rd;
579
580 for (i = 0; i < 7; i++) {
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530581 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700582 if (!addr) {
583 printf("addr allocation failed\n");
584 goto err_alloc;
585 }
586 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700587 flush_dcache_range((u64)addr,
588 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700589
590 buf_array[i] = (uint64_t)addr;
591 debug("Release: buffer addr =0x%p\n", addr);
592 }
593
594release_bufs:
595 /* In case the portal is busy, retry until successful.
596 * This function is guaranteed to succeed in a reasonable amount
597 * of time.
598 */
599
600 do {
601 mdelay(1);
602 qbman_release_desc_clear(&rd);
603 qbman_release_desc_set_bpid(&rd, bpid);
604 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
605
606 return i;
607
608err_alloc:
609 if (i)
610 goto release_bufs;
611
612 return 0;
613}
614
615static int ldpaa_dpbp_seed(uint16_t bpid)
616{
617 int i;
618 int count;
619
620 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
621 count = ldpaa_bp_add_7(bpid);
622 if (count < 7)
623 printf("Buffer Seed= %d\n", count);
624 }
625
626 return 0;
627}
628
629static int ldpaa_dpbp_setup(void)
630{
631 int err;
632
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530633 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700634 &dflt_dpbp->dpbp_handle);
635 if (err) {
636 printf("dpbp_open() failed\n");
637 goto err_open;
638 }
639
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530640 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700641 if (err) {
642 printf("dpbp_enable() failed\n");
643 goto err_enable;
644 }
645
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530646 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
647 dflt_dpbp->dpbp_handle,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700648 &dflt_dpbp->dpbp_attr);
649 if (err) {
650 printf("dpbp_get_attributes() failed\n");
651 goto err_get_attr;
652 }
653
654 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
655 if (err) {
656 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
657 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
658 goto err_seed;
659 }
660
661 return 0;
662
663err_seed:
664err_get_attr:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530665 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700666err_enable:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530667 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700668err_open:
669 return err;
670}
671
672static void ldpaa_dpbp_free(void)
673{
674 ldpaa_dpbp_drain();
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530675 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
676 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
677 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700678}
679
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530680static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
681 struct ldpaa_eth_priv *priv)
682{
683 struct dpmac_attr attr;
684 int error;
685
686 memset(&attr, 0, sizeof(struct dpmac_attr));
687 error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS,
688 priv->dpmac_handle,
689 &attr);
690 if (error == 0) {
691 if ((attr.version.major != DPMAC_VER_MAJOR) ||
692 (attr.version.minor != DPMAC_VER_MINOR)) {
693 printf("DPMAC version mismatch found %u.%u,",
694 attr.version.major, attr.version.minor);
695 printf("supported version is %u.%u\n",
696 DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
697 }
698 }
699
700 return error;
701}
702
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530703static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
704{
705 int err = 0;
706 struct dpmac_cfg dpmac_cfg;
707
708 dpmac_cfg.mac_id = priv->dpmac_id;
709 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg,
710 &priv->dpmac_handle);
711 if (err)
712 printf("dpmac_create() failed\n");
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530713
714 err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
715 if (err < 0)
716 printf("ldpaa_dpmac_version_check() failed: %d\n", err);
717
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530718 return err;
719}
720
721static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
722{
723 int err = 0;
724 struct dprc_connection_cfg dprc_connection_cfg = {
725 /* If both rates are zero the connection */
726 /* will be configured in "best effort" mode. */
727 .committed_rate = 0,
728 .max_rate = 0
729 };
730
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530731#ifdef DEBUG
732 struct dprc_endpoint dbg_endpoint;
733 int state = 0;
734#endif
735
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530736 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000737 strcpy(dpmac_endpoint.type, "dpmac");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530738 dpmac_endpoint.id = priv->dpmac_id;
739
740 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000741 strcpy(dpni_endpoint.type, "dpni");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530742 dpni_endpoint.id = dflt_dpni->dpni_id;
743
744 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
745 dflt_dprc_handle,
746 &dpmac_endpoint,
747 &dpni_endpoint,
748 &dprc_connection_cfg);
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530749 if (err)
750 printf("dprc_connect() failed\n");
751
752#ifdef DEBUG
753 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
754 dflt_dprc_handle, &dpni_endpoint,
755 &dbg_endpoint, &state);
756 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
757 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
758 printf("%s, DPMAC State= %d\n", __func__, state);
759
760 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
761 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
762 dflt_dprc_handle, &dpmac_endpoint,
763 &dbg_endpoint, &state);
764 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
765 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
766 printf("%s, DPNI State= %d\n", __func__, state);
767#endif
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530768 return err;
769}
770
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700771static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
772{
773 int err;
774
775 /* and get a handle for the DPNI this interface is associate with */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530776 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
777 &dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700778 if (err) {
779 printf("dpni_open() failed\n");
780 goto err_open;
781 }
782
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530783 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530784 dflt_dpni->dpni_handle,
785 &dflt_dpni->dpni_attrs);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700786 if (err) {
787 printf("dpni_get_attributes() failed (err=%d)\n", err);
788 goto err_get_attr;
789 }
790
791 /* Configure our buffers' layout */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530792 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700793 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530794 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
795 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530796 dflt_dpni->buf_layout.pass_parser_result = true;
797 dflt_dpni->buf_layout.pass_frame_status = true;
798 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530799 /* HW erratum mandates data alignment in multiples of 256 */
800 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700801 /* ...rx, ... */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530802 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530803 dflt_dpni->dpni_handle,
804 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700805 if (err) {
806 printf("dpni_set_rx_buffer_layout() failed");
807 goto err_buf_layout;
808 }
809
810 /* ... tx, ... */
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530811 /* remove Rx-only options */
812 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
813 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530814 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530815 dflt_dpni->dpni_handle,
816 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700817 if (err) {
818 printf("dpni_set_tx_buffer_layout() failed");
819 goto err_buf_layout;
820 }
821
822 /* ... tx-confirm. */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530823 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530824 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530825 dflt_dpni->dpni_handle,
826 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700827 if (err) {
828 printf("dpni_set_tx_conf_buffer_layout() failed");
829 goto err_buf_layout;
830 }
831
832 /* Now that we've set our tx buffer layout, retrieve the minimum
833 * required tx data offset.
834 */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530835 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530836 dflt_dpni->dpni_handle,
837 &priv->tx_data_offset);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700838 if (err) {
839 printf("dpni_get_tx_data_offset() failed\n");
840 goto err_data_offset;
841 }
842
843 /* Warn in case TX data offset is not multiple of 64 bytes. */
844 WARN_ON(priv->tx_data_offset % 64);
845
846 /* Accomodate SWA space. */
847 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
848 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
849
850 return 0;
851
852err_data_offset:
853err_buf_layout:
854err_get_attr:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530855 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700856err_open:
857 return err;
858}
859
860static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
861{
862 struct dpni_pools_cfg pools_params;
863 struct dpni_tx_flow_cfg dflt_tx_flow;
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530864 struct dpni_tx_conf_cfg tx_conf_cfg;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700865 int err = 0;
866
867 pools_params.num_dpbp = 1;
868 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
869 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530870 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
871 dflt_dpni->dpni_handle, &pools_params);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700872 if (err) {
873 printf("dpni_set_pools() failed\n");
874 return err;
875 }
876
877 priv->tx_flow_id = DPNI_NEW_FLOW_ID;
878 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
879
Prabhakar Kushwahac3d06e32015-12-24 15:32:49 +0530880 dflt_tx_flow.use_common_tx_conf_queue = 0;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530881 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
882 dflt_dpni->dpni_handle, &priv->tx_flow_id,
883 &dflt_tx_flow);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700884 if (err) {
885 printf("dpni_set_tx_flow() failed\n");
886 return err;
887 }
888
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530889 memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg));
890 tx_conf_cfg.errors_only = true;
891 /*Set tx-conf and error configuration*/
892 err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS,
893 dflt_dpni->dpni_handle,
894 priv->tx_flow_id, &tx_conf_cfg);
895 if (err) {
896 printf("dpni_set_tx_conf() failed\n");
897 return err;
898 }
899
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700900 return 0;
901}
902
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530903static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
904 phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700905{
906 int err;
907 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
908
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530909 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id,
910 phy_interface_strings[enet_if]);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700911
912 net_dev->iobase = 0;
913 net_dev->init = ldpaa_eth_open;
914 net_dev->halt = ldpaa_eth_stop;
915 net_dev->send = ldpaa_eth_tx;
916 net_dev->recv = ldpaa_eth_pull_dequeue_rx;
917/*
918 TODO: PHY MDIO information
919 priv->bus = info->bus;
920 priv->phyaddr = info->phy_addr;
921 priv->enet_if = info->enet_if;
922*/
923
924 if (init_phy(net_dev))
925 return 0;
926
927 err = eth_register(net_dev);
928 if (err < 0) {
929 printf("eth_register() = %d\n", err);
930 return err;
931 }
932
933 return 0;
934}
935
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530936int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700937{
938 struct eth_device *net_dev = NULL;
939 struct ldpaa_eth_priv *priv = NULL;
940 int err = 0;
941
942
943 /* Net device */
944 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
945 if (!net_dev) {
946 printf("eth_device malloc() failed\n");
947 return -ENOMEM;
948 }
949 memset(net_dev, 0, sizeof(struct eth_device));
950
951 /* alloc the ldpaa ethernet private struct */
952 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
953 if (!priv) {
954 printf("ldpaa_eth_priv malloc() failed\n");
955 return -ENOMEM;
956 }
957 memset(priv, 0, sizeof(struct ldpaa_eth_priv));
958
959 net_dev->priv = (void *)priv;
960 priv->net_dev = (struct eth_device *)net_dev;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530961 priv->dpmac_id = dpmac_id;
962 debug("%s dpmac_id=%d\n", __func__, dpmac_id);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700963
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530964 err = ldpaa_eth_netdev_init(net_dev, enet_if);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700965 if (err)
966 goto err_netdev_init;
967
968 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
969 return 0;
970
971err_netdev_init:
972 free(priv);
973 net_dev->priv = NULL;
974 free(net_dev);
975
976 return err;
977}