blob: 75b2b6b04966bbdb2e9dc3fedba04a4204858e3a [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
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +053017#include <fsl-mc/ldpaa_wriop.h>
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070018#include "ldpaa_eth.h"
19
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +053020#ifdef CONFIG_PHYLIB
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070021static int init_phy(struct eth_device *dev)
22{
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +053023 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
24 struct phy_device *phydev = NULL;
25 struct mii_dev *bus;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070026
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +053027 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);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070041}
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +053042#endif
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -070043
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +053044#ifdef DEBUG
45static 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}
Prabhakar Kushwaha314aa552015-12-24 15:33:37 +0530120
121static 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}
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530197#endif
198
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700199static 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;
Prabhakar Kushwahac7d10d82015-07-02 11:29:08 +0530207 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
208 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700209 struct qbman_release_desc releasedesc;
210 struct qbman_swp *swp = dflt_dpio->sw_portal;
211
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700212 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) +
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530222 dflt_dpni->buf_layout.private_data_size);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700223 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
239error:
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700240 flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700241 qbman_release_desc_clear(&releasedesc);
242 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
Prabhakar Kushwahac7d10d82015-07-02 11:29:08 +0530243 time_start = get_timer(0);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700244 do {
245 /* Release buffer into the QBMAN */
246 err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
Prabhakar Kushwahac7d10d82015-07-02 11:29:08 +0530247 } while (get_timer(time_start) < timeo && err == -EBUSY);
248
249 if (err == -EBUSY)
250 printf("Rx frame: QBMAN buffer release fails\n");
251
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700252 return;
253}
254
255static 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;
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530260 int i = 5, err = 0, status;
261 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
262 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700263 static struct qbman_pull_desc pulldesc;
264 struct qbman_swp *swp = dflt_dpio->sw_portal;
265
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700266 while (--i) {
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700267 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
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700271 err = qbman_swp_pull(swp, &pulldesc);
272 if (err < 0) {
273 printf("Dequeue frames error:0x%08x\n", err);
274 continue;
275 }
276
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530277 time_start = get_timer(0);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700278
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530279 do {
280 dq = qbman_swp_dqrr_next(swp);
281 } while (get_timer(time_start) < timeo && !dq);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700282
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700283 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);
Prabhakar Kushwaha37ed1a62015-07-02 11:29:07 +0530295 continue;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700296 }
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;
Prabhakar Kushwahabe0c9552015-07-02 11:29:06 +0530304 } else {
305 err = -ENODATA;
306 debug("No DQRR entries\n");
307 break;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700308 }
309 }
310
311 return err;
312}
313
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700314static 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;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530320 u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
321 u32 time_start;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700322 struct qbman_swp *swp = dflt_dpio->sw_portal;
323 struct qbman_eq_desc ed;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530324 struct qbman_release_desc releasedesc;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700325
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
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700346 flush_dcache_range(buffer_start, buffer_start +
347 LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700348
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);
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530360
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) {
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700371 printf("error enqueueing Tx frame\n");
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530372 goto error;
373 }
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700374
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700375 return err;
Prabhakar Kushwaha20c30102015-07-02 11:29:05 +0530376
377error:
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;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700390}
391
392static 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;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530396 struct dpmac_link_state dpmac_link_state = { 0 };
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530397#ifdef DEBUG
398 struct dpni_link_state link_state;
399#endif
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530400 int err = 0;
401 struct mii_dev *bus;
402 phy_interface_t enet_if;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700403
404 if (net_dev->state == ETH_STATE_ACTIVE)
405 return 0;
406
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530407 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 }
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530416
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530417 /* DPMAC initialization */
418 err = ldpaa_dpmac_setup(priv);
419 if (err < 0)
420 goto err_dpmac_setup;
421
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530422#ifdef CONFIG_PHYLIB
423 if (priv->phydev)
424 err = phy_startup(priv->phydev);
425 if (err) {
426 printf("%s: Could not initialize\n",
427 priv->phydev->dev->name);
428 goto err_dpamc_bind;
429 }
430#else
431 priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
432 memset(priv->phydev, 0, sizeof(struct phy_device));
433
434 priv->phydev->speed = SPEED_1000;
435 priv->phydev->link = 1;
436 priv->phydev->duplex = DUPLEX_FULL;
437#endif
438
439 bus = wriop_get_mdio(priv->dpmac_id);
440 enet_if = wriop_get_enet_if(priv->dpmac_id);
441 if ((bus == NULL) &&
442 (enet_if == PHY_INTERFACE_MODE_XGMII)) {
443 priv->phydev = (struct phy_device *)
444 malloc(sizeof(struct phy_device));
445 memset(priv->phydev, 0, sizeof(struct phy_device));
446
447 priv->phydev->speed = SPEED_10000;
448 priv->phydev->link = 1;
449 priv->phydev->duplex = DUPLEX_FULL;
450 }
451
452 if (!priv->phydev->link) {
453 printf("%s: No link.\n", priv->phydev->dev->name);
454 err = -1;
455 goto err_dpamc_bind;
456 }
457
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530458 /* DPMAC binding DPNI */
459 err = ldpaa_dpmac_bind(priv);
460 if (err)
461 goto err_dpamc_bind;
462
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700463 /* DPNI initialization */
464 err = ldpaa_dpni_setup(priv);
465 if (err < 0)
466 goto err_dpni_setup;
467
468 err = ldpaa_dpbp_setup();
469 if (err < 0)
470 goto err_dpbp_setup;
471
472 /* DPNI binding DPBP */
473 err = ldpaa_dpni_bind(priv);
474 if (err)
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530475 goto err_dpni_bind;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700476
Prabhakar Kushwahad2c20a32015-10-07 16:29:58 +0530477 err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530478 dflt_dpni->dpni_handle, net_dev->enetaddr);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700479 if (err) {
Prabhakar Kushwahad2c20a32015-10-07 16:29:58 +0530480 printf("dpni_add_mac_addr() failed\n");
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700481 return err;
482 }
483
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530484 err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700485 if (err < 0) {
486 printf("dpni_enable() failed\n");
487 return err;
488 }
489
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530490 dpmac_link_state.rate = priv->phydev->speed;
491
492 if (priv->phydev->autoneg == AUTONEG_DISABLE)
493 dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
494 else
495 dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
496
497 if (priv->phydev->duplex == DUPLEX_HALF)
498 dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
499
500 dpmac_link_state.up = priv->phydev->link;
501
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530502 err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
503 priv->dpmac_handle, &dpmac_link_state);
504 if (err < 0) {
505 printf("dpmac_set_link_state() failed\n");
506 return err;
507 }
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530508
509#ifdef DEBUG
510 err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
511 dflt_dpni->dpni_handle, &link_state);
512 if (err < 0) {
513 printf("dpni_get_link_state() failed\n");
514 return err;
515 }
516
517 printf("link status: %d - ", link_state.up);
518 link_state.up == 0 ? printf("down\n") :
519 link_state.up == 1 ? printf("up\n") : printf("error state\n");
520#endif
521
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700522 /* TODO: support multiple Rx flows */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530523 err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
524 dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700525 if (err) {
526 printf("dpni_get_rx_flow() failed\n");
527 goto err_rx_flow;
528 }
529
530 priv->rx_dflt_fqid = rx_queue_attr.fqid;
531
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530532 err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530533 &priv->tx_qdid);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700534 if (err) {
535 printf("dpni_get_qdid() failed\n");
536 goto err_qdid;
537 }
538
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530539 return priv->phydev->link;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700540
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700541err_qdid:
542err_rx_flow:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530543 dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
544err_dpni_bind:
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700545 ldpaa_dpbp_free();
546err_dpbp_setup:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530547 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700548err_dpni_setup:
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530549err_dpamc_bind:
550 dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530551err_dpmac_setup:
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700552 return err;
553}
554
555static void ldpaa_eth_stop(struct eth_device *net_dev)
556{
557 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
558 int err = 0;
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530559#ifdef CONFIG_PHYLIB
560 struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
561#endif
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700562
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700563 if ((net_dev->state == ETH_STATE_PASSIVE) ||
564 (net_dev->state == ETH_STATE_INIT))
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700565 return;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530566
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530567#ifdef DEBUG
568 ldpaa_eth_get_dpni_counter();
Prabhakar Kushwaha314aa552015-12-24 15:33:37 +0530569 ldpaa_eth_get_dpmac_counter(net_dev);
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530570#endif
571
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530572 err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
573 dflt_dprc_handle, &dpmac_endpoint);
574 if (err < 0)
575 printf("dprc_disconnect() failed dpmac_endpoint\n");
576
577 err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
578 if (err < 0)
579 printf("dpmac_destroy() failed\n");
580
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700581 /* Stop Tx and Rx traffic */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530582 err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700583 if (err < 0)
584 printf("dpni_disable() failed\n");
585
586#ifdef CONFIG_PHYLIB
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530587 if (priv->phydev && bus != NULL)
588 phy_shutdown(priv->phydev);
589 else
590 free(priv->phydev);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700591#endif
592
593 ldpaa_dpbp_free();
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530594 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
595 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700596}
597
598static void ldpaa_dpbp_drain_cnt(int count)
599{
600 uint64_t buf_array[7];
601 void *addr;
602 int ret, i;
603
604 BUG_ON(count > 7);
605
606 do {
607 ret = qbman_swp_acquire(dflt_dpio->sw_portal,
608 dflt_dpbp->dpbp_attr.bpid,
609 buf_array, count);
610 if (ret < 0) {
611 printf("qbman_swp_acquire() failed\n");
612 return;
613 }
614 for (i = 0; i < ret; i++) {
615 addr = (void *)buf_array[i];
616 debug("Free: buffer addr =0x%p\n", addr);
617 free(addr);
618 }
619 } while (ret);
620}
621
622static void ldpaa_dpbp_drain(void)
623{
624 int i;
625 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
626 ldpaa_dpbp_drain_cnt(7);
627}
628
629static int ldpaa_bp_add_7(uint16_t bpid)
630{
631 uint64_t buf_array[7];
632 u8 *addr;
633 int i;
634 struct qbman_release_desc rd;
635
636 for (i = 0; i < 7; i++) {
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530637 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700638 if (!addr) {
639 printf("addr allocation failed\n");
640 goto err_alloc;
641 }
642 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700643 flush_dcache_range((u64)addr,
644 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700645
646 buf_array[i] = (uint64_t)addr;
647 debug("Release: buffer addr =0x%p\n", addr);
648 }
649
650release_bufs:
651 /* In case the portal is busy, retry until successful.
652 * This function is guaranteed to succeed in a reasonable amount
653 * of time.
654 */
655
656 do {
657 mdelay(1);
658 qbman_release_desc_clear(&rd);
659 qbman_release_desc_set_bpid(&rd, bpid);
660 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
661
662 return i;
663
664err_alloc:
665 if (i)
666 goto release_bufs;
667
668 return 0;
669}
670
671static int ldpaa_dpbp_seed(uint16_t bpid)
672{
673 int i;
674 int count;
675
676 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
677 count = ldpaa_bp_add_7(bpid);
678 if (count < 7)
679 printf("Buffer Seed= %d\n", count);
680 }
681
682 return 0;
683}
684
685static int ldpaa_dpbp_setup(void)
686{
687 int err;
688
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530689 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700690 &dflt_dpbp->dpbp_handle);
691 if (err) {
692 printf("dpbp_open() failed\n");
693 goto err_open;
694 }
695
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530696 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700697 if (err) {
698 printf("dpbp_enable() failed\n");
699 goto err_enable;
700 }
701
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530702 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
703 dflt_dpbp->dpbp_handle,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700704 &dflt_dpbp->dpbp_attr);
705 if (err) {
706 printf("dpbp_get_attributes() failed\n");
707 goto err_get_attr;
708 }
709
710 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
711 if (err) {
712 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
713 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
714 goto err_seed;
715 }
716
717 return 0;
718
719err_seed:
720err_get_attr:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530721 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700722err_enable:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530723 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700724err_open:
725 return err;
726}
727
728static void ldpaa_dpbp_free(void)
729{
730 ldpaa_dpbp_drain();
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530731 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
732 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
733 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700734}
735
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530736static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
737 struct ldpaa_eth_priv *priv)
738{
739 struct dpmac_attr attr;
740 int error;
741
742 memset(&attr, 0, sizeof(struct dpmac_attr));
743 error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS,
744 priv->dpmac_handle,
745 &attr);
746 if (error == 0) {
747 if ((attr.version.major != DPMAC_VER_MAJOR) ||
748 (attr.version.minor != DPMAC_VER_MINOR)) {
749 printf("DPMAC version mismatch found %u.%u,",
750 attr.version.major, attr.version.minor);
751 printf("supported version is %u.%u\n",
752 DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
753 }
754 }
755
756 return error;
757}
758
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530759static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
760{
761 int err = 0;
762 struct dpmac_cfg dpmac_cfg;
763
764 dpmac_cfg.mac_id = priv->dpmac_id;
765 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg,
766 &priv->dpmac_handle);
767 if (err)
768 printf("dpmac_create() failed\n");
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530769
770 err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
771 if (err < 0)
772 printf("ldpaa_dpmac_version_check() failed: %d\n", err);
773
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530774 return err;
775}
776
777static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
778{
779 int err = 0;
780 struct dprc_connection_cfg dprc_connection_cfg = {
781 /* If both rates are zero the connection */
782 /* will be configured in "best effort" mode. */
783 .committed_rate = 0,
784 .max_rate = 0
785 };
786
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530787#ifdef DEBUG
788 struct dprc_endpoint dbg_endpoint;
789 int state = 0;
790#endif
791
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530792 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000793 strcpy(dpmac_endpoint.type, "dpmac");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530794 dpmac_endpoint.id = priv->dpmac_id;
795
796 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000797 strcpy(dpni_endpoint.type, "dpni");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530798 dpni_endpoint.id = dflt_dpni->dpni_id;
799
800 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
801 dflt_dprc_handle,
802 &dpmac_endpoint,
803 &dpni_endpoint,
804 &dprc_connection_cfg);
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530805 if (err)
806 printf("dprc_connect() failed\n");
807
808#ifdef DEBUG
809 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
810 dflt_dprc_handle, &dpni_endpoint,
811 &dbg_endpoint, &state);
812 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
813 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
814 printf("%s, DPMAC State= %d\n", __func__, state);
815
816 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
817 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
818 dflt_dprc_handle, &dpmac_endpoint,
819 &dbg_endpoint, &state);
820 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
821 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
822 printf("%s, DPNI State= %d\n", __func__, state);
823#endif
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530824 return err;
825}
826
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700827static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
828{
829 int err;
830
831 /* and get a handle for the DPNI this interface is associate with */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530832 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
833 &dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700834 if (err) {
835 printf("dpni_open() failed\n");
836 goto err_open;
837 }
838
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530839 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530840 dflt_dpni->dpni_handle,
841 &dflt_dpni->dpni_attrs);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700842 if (err) {
843 printf("dpni_get_attributes() failed (err=%d)\n", err);
844 goto err_get_attr;
845 }
846
847 /* Configure our buffers' layout */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530848 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700849 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530850 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
851 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530852 dflt_dpni->buf_layout.pass_parser_result = true;
853 dflt_dpni->buf_layout.pass_frame_status = true;
854 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530855 /* HW erratum mandates data alignment in multiples of 256 */
856 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700857 /* ...rx, ... */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530858 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530859 dflt_dpni->dpni_handle,
860 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700861 if (err) {
862 printf("dpni_set_rx_buffer_layout() failed");
863 goto err_buf_layout;
864 }
865
866 /* ... tx, ... */
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530867 /* remove Rx-only options */
868 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
869 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530870 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530871 dflt_dpni->dpni_handle,
872 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700873 if (err) {
874 printf("dpni_set_tx_buffer_layout() failed");
875 goto err_buf_layout;
876 }
877
878 /* ... tx-confirm. */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530879 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530880 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530881 dflt_dpni->dpni_handle,
882 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700883 if (err) {
884 printf("dpni_set_tx_conf_buffer_layout() failed");
885 goto err_buf_layout;
886 }
887
888 /* Now that we've set our tx buffer layout, retrieve the minimum
889 * required tx data offset.
890 */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530891 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530892 dflt_dpni->dpni_handle,
893 &priv->tx_data_offset);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700894 if (err) {
895 printf("dpni_get_tx_data_offset() failed\n");
896 goto err_data_offset;
897 }
898
899 /* Warn in case TX data offset is not multiple of 64 bytes. */
900 WARN_ON(priv->tx_data_offset % 64);
901
902 /* Accomodate SWA space. */
903 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
904 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
905
906 return 0;
907
908err_data_offset:
909err_buf_layout:
910err_get_attr:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530911 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700912err_open:
913 return err;
914}
915
916static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
917{
918 struct dpni_pools_cfg pools_params;
919 struct dpni_tx_flow_cfg dflt_tx_flow;
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530920 struct dpni_tx_conf_cfg tx_conf_cfg;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700921 int err = 0;
922
Prabhakar Kushwahaa7992322016-03-28 14:11:05 +0530923 memset(&pools_params, 0, sizeof(pools_params));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700924 pools_params.num_dpbp = 1;
925 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
926 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530927 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
928 dflt_dpni->dpni_handle, &pools_params);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700929 if (err) {
930 printf("dpni_set_pools() failed\n");
931 return err;
932 }
933
934 priv->tx_flow_id = DPNI_NEW_FLOW_ID;
935 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
936
Prabhakar Kushwahac3d06e32015-12-24 15:32:49 +0530937 dflt_tx_flow.use_common_tx_conf_queue = 0;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530938 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
939 dflt_dpni->dpni_handle, &priv->tx_flow_id,
940 &dflt_tx_flow);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700941 if (err) {
942 printf("dpni_set_tx_flow() failed\n");
943 return err;
944 }
945
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530946 memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg));
947 tx_conf_cfg.errors_only = true;
948 /*Set tx-conf and error configuration*/
949 err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS,
950 dflt_dpni->dpni_handle,
951 priv->tx_flow_id, &tx_conf_cfg);
952 if (err) {
953 printf("dpni_set_tx_conf() failed\n");
954 return err;
955 }
956
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700957 return 0;
958}
959
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530960static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
961 phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700962{
963 int err;
964 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
965
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530966 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id,
967 phy_interface_strings[enet_if]);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700968
969 net_dev->iobase = 0;
970 net_dev->init = ldpaa_eth_open;
971 net_dev->halt = ldpaa_eth_stop;
972 net_dev->send = ldpaa_eth_tx;
973 net_dev->recv = ldpaa_eth_pull_dequeue_rx;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700974
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530975#ifdef CONFIG_PHYLIB
976 err = init_phy(net_dev);
977 if (err < 0)
978 return err;
979#endif
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700980
981 err = eth_register(net_dev);
982 if (err < 0) {
983 printf("eth_register() = %d\n", err);
984 return err;
985 }
986
987 return 0;
988}
989
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530990int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700991{
992 struct eth_device *net_dev = NULL;
993 struct ldpaa_eth_priv *priv = NULL;
994 int err = 0;
995
996
997 /* Net device */
998 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
999 if (!net_dev) {
1000 printf("eth_device malloc() failed\n");
1001 return -ENOMEM;
1002 }
1003 memset(net_dev, 0, sizeof(struct eth_device));
1004
1005 /* alloc the ldpaa ethernet private struct */
1006 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1007 if (!priv) {
1008 printf("ldpaa_eth_priv malloc() failed\n");
1009 return -ENOMEM;
1010 }
1011 memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1012
1013 net_dev->priv = (void *)priv;
1014 priv->net_dev = (struct eth_device *)net_dev;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +05301015 priv->dpmac_id = dpmac_id;
1016 debug("%s dpmac_id=%d\n", __func__, dpmac_id);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -07001017
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +05301018 err = ldpaa_eth_netdev_init(net_dev, enet_if);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -07001019 if (err)
1020 goto err_netdev_init;
1021
1022 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1023 return 0;
1024
1025err_netdev_init:
1026 free(priv);
1027 net_dev->priv = NULL;
1028 free(net_dev);
1029
1030 return err;
1031}