blob: 4e61700d5d11423ab67402f22d8407194d850450 [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
Priyanka Jainbc3e7eb2016-11-03 18:05:09 +0530423 if (priv->phydev) {
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530424 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 }
Priyanka Jainbc3e7eb2016-11-03 18:05:09 +0530430 }
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530431#else
432 priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
433 memset(priv->phydev, 0, sizeof(struct phy_device));
434
435 priv->phydev->speed = SPEED_1000;
436 priv->phydev->link = 1;
437 priv->phydev->duplex = DUPLEX_FULL;
438#endif
439
440 bus = wriop_get_mdio(priv->dpmac_id);
441 enet_if = wriop_get_enet_if(priv->dpmac_id);
442 if ((bus == NULL) &&
443 (enet_if == PHY_INTERFACE_MODE_XGMII)) {
444 priv->phydev = (struct phy_device *)
445 malloc(sizeof(struct phy_device));
446 memset(priv->phydev, 0, sizeof(struct phy_device));
447
448 priv->phydev->speed = SPEED_10000;
449 priv->phydev->link = 1;
450 priv->phydev->duplex = DUPLEX_FULL;
451 }
452
453 if (!priv->phydev->link) {
454 printf("%s: No link.\n", priv->phydev->dev->name);
455 err = -1;
456 goto err_dpamc_bind;
457 }
458
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530459 /* DPMAC binding DPNI */
460 err = ldpaa_dpmac_bind(priv);
461 if (err)
462 goto err_dpamc_bind;
463
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700464 /* DPNI initialization */
465 err = ldpaa_dpni_setup(priv);
466 if (err < 0)
467 goto err_dpni_setup;
468
469 err = ldpaa_dpbp_setup();
470 if (err < 0)
471 goto err_dpbp_setup;
472
473 /* DPNI binding DPBP */
474 err = ldpaa_dpni_bind(priv);
475 if (err)
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530476 goto err_dpni_bind;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700477
Prabhakar Kushwahad2c20a32015-10-07 16:29:58 +0530478 err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530479 dflt_dpni->dpni_handle, net_dev->enetaddr);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700480 if (err) {
Prabhakar Kushwahad2c20a32015-10-07 16:29:58 +0530481 printf("dpni_add_mac_addr() failed\n");
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700482 return err;
483 }
484
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530485 err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700486 if (err < 0) {
487 printf("dpni_enable() failed\n");
488 return err;
489 }
490
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530491 dpmac_link_state.rate = priv->phydev->speed;
492
493 if (priv->phydev->autoneg == AUTONEG_DISABLE)
494 dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
495 else
496 dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
497
498 if (priv->phydev->duplex == DUPLEX_HALF)
499 dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
500
501 dpmac_link_state.up = priv->phydev->link;
502
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530503 err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
504 priv->dpmac_handle, &dpmac_link_state);
505 if (err < 0) {
506 printf("dpmac_set_link_state() failed\n");
507 return err;
508 }
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530509
510#ifdef DEBUG
511 err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
512 dflt_dpni->dpni_handle, &link_state);
513 if (err < 0) {
514 printf("dpni_get_link_state() failed\n");
515 return err;
516 }
517
518 printf("link status: %d - ", link_state.up);
519 link_state.up == 0 ? printf("down\n") :
520 link_state.up == 1 ? printf("up\n") : printf("error state\n");
521#endif
522
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700523 /* TODO: support multiple Rx flows */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530524 err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
525 dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700526 if (err) {
527 printf("dpni_get_rx_flow() failed\n");
528 goto err_rx_flow;
529 }
530
531 priv->rx_dflt_fqid = rx_queue_attr.fqid;
532
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530533 err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530534 &priv->tx_qdid);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700535 if (err) {
536 printf("dpni_get_qdid() failed\n");
537 goto err_qdid;
538 }
539
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530540 return priv->phydev->link;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700541
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700542err_qdid:
543err_rx_flow:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530544 dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
545err_dpni_bind:
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700546 ldpaa_dpbp_free();
547err_dpbp_setup:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530548 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700549err_dpni_setup:
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530550err_dpamc_bind:
551 dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530552err_dpmac_setup:
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700553 return err;
554}
555
556static void ldpaa_eth_stop(struct eth_device *net_dev)
557{
558 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
559 int err = 0;
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530560#ifdef CONFIG_PHYLIB
561 struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
562#endif
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700563
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700564 if ((net_dev->state == ETH_STATE_PASSIVE) ||
565 (net_dev->state == ETH_STATE_INIT))
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700566 return;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530567
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530568#ifdef DEBUG
569 ldpaa_eth_get_dpni_counter();
Prabhakar Kushwaha314aa552015-12-24 15:33:37 +0530570 ldpaa_eth_get_dpmac_counter(net_dev);
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530571#endif
572
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530573 err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
574 dflt_dprc_handle, &dpmac_endpoint);
575 if (err < 0)
576 printf("dprc_disconnect() failed dpmac_endpoint\n");
577
578 err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
579 if (err < 0)
580 printf("dpmac_destroy() failed\n");
581
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700582 /* Stop Tx and Rx traffic */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530583 err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700584 if (err < 0)
585 printf("dpni_disable() failed\n");
586
587#ifdef CONFIG_PHYLIB
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530588 if (priv->phydev && bus != NULL)
589 phy_shutdown(priv->phydev);
590 else
591 free(priv->phydev);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700592#endif
593
594 ldpaa_dpbp_free();
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530595 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
596 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700597}
598
599static void ldpaa_dpbp_drain_cnt(int count)
600{
601 uint64_t buf_array[7];
602 void *addr;
603 int ret, i;
604
605 BUG_ON(count > 7);
606
607 do {
608 ret = qbman_swp_acquire(dflt_dpio->sw_portal,
609 dflt_dpbp->dpbp_attr.bpid,
610 buf_array, count);
611 if (ret < 0) {
612 printf("qbman_swp_acquire() failed\n");
613 return;
614 }
615 for (i = 0; i < ret; i++) {
616 addr = (void *)buf_array[i];
617 debug("Free: buffer addr =0x%p\n", addr);
618 free(addr);
619 }
620 } while (ret);
621}
622
623static void ldpaa_dpbp_drain(void)
624{
625 int i;
626 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
627 ldpaa_dpbp_drain_cnt(7);
628}
629
630static int ldpaa_bp_add_7(uint16_t bpid)
631{
632 uint64_t buf_array[7];
633 u8 *addr;
634 int i;
635 struct qbman_release_desc rd;
636
637 for (i = 0; i < 7; i++) {
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530638 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700639 if (!addr) {
640 printf("addr allocation failed\n");
641 goto err_alloc;
642 }
643 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700644 flush_dcache_range((u64)addr,
645 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700646
647 buf_array[i] = (uint64_t)addr;
648 debug("Release: buffer addr =0x%p\n", addr);
649 }
650
651release_bufs:
652 /* In case the portal is busy, retry until successful.
653 * This function is guaranteed to succeed in a reasonable amount
654 * of time.
655 */
656
657 do {
658 mdelay(1);
659 qbman_release_desc_clear(&rd);
660 qbman_release_desc_set_bpid(&rd, bpid);
661 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
662
663 return i;
664
665err_alloc:
666 if (i)
667 goto release_bufs;
668
669 return 0;
670}
671
672static int ldpaa_dpbp_seed(uint16_t bpid)
673{
674 int i;
675 int count;
676
677 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
678 count = ldpaa_bp_add_7(bpid);
679 if (count < 7)
680 printf("Buffer Seed= %d\n", count);
681 }
682
683 return 0;
684}
685
686static int ldpaa_dpbp_setup(void)
687{
688 int err;
689
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530690 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700691 &dflt_dpbp->dpbp_handle);
692 if (err) {
693 printf("dpbp_open() failed\n");
694 goto err_open;
695 }
696
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530697 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700698 if (err) {
699 printf("dpbp_enable() failed\n");
700 goto err_enable;
701 }
702
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530703 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
704 dflt_dpbp->dpbp_handle,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700705 &dflt_dpbp->dpbp_attr);
706 if (err) {
707 printf("dpbp_get_attributes() failed\n");
708 goto err_get_attr;
709 }
710
711 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
712 if (err) {
713 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
714 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
715 goto err_seed;
716 }
717
718 return 0;
719
720err_seed:
721err_get_attr:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530722 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700723err_enable:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530724 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700725err_open:
726 return err;
727}
728
729static void ldpaa_dpbp_free(void)
730{
731 ldpaa_dpbp_drain();
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530732 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
733 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
734 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700735}
736
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530737static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
738 struct ldpaa_eth_priv *priv)
739{
740 struct dpmac_attr attr;
741 int error;
742
743 memset(&attr, 0, sizeof(struct dpmac_attr));
744 error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS,
745 priv->dpmac_handle,
746 &attr);
747 if (error == 0) {
748 if ((attr.version.major != DPMAC_VER_MAJOR) ||
749 (attr.version.minor != DPMAC_VER_MINOR)) {
750 printf("DPMAC version mismatch found %u.%u,",
751 attr.version.major, attr.version.minor);
752 printf("supported version is %u.%u\n",
753 DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
754 }
755 }
756
757 return error;
758}
759
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530760static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
761{
762 int err = 0;
763 struct dpmac_cfg dpmac_cfg;
764
765 dpmac_cfg.mac_id = priv->dpmac_id;
766 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg,
767 &priv->dpmac_handle);
768 if (err)
769 printf("dpmac_create() failed\n");
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530770
771 err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
772 if (err < 0)
773 printf("ldpaa_dpmac_version_check() failed: %d\n", err);
774
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530775 return err;
776}
777
778static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
779{
780 int err = 0;
781 struct dprc_connection_cfg dprc_connection_cfg = {
782 /* If both rates are zero the connection */
783 /* will be configured in "best effort" mode. */
784 .committed_rate = 0,
785 .max_rate = 0
786 };
787
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530788#ifdef DEBUG
789 struct dprc_endpoint dbg_endpoint;
790 int state = 0;
791#endif
792
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530793 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000794 strcpy(dpmac_endpoint.type, "dpmac");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530795 dpmac_endpoint.id = priv->dpmac_id;
796
797 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000798 strcpy(dpni_endpoint.type, "dpni");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530799 dpni_endpoint.id = dflt_dpni->dpni_id;
800
801 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
802 dflt_dprc_handle,
803 &dpmac_endpoint,
804 &dpni_endpoint,
805 &dprc_connection_cfg);
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530806 if (err)
807 printf("dprc_connect() failed\n");
808
809#ifdef DEBUG
810 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
811 dflt_dprc_handle, &dpni_endpoint,
812 &dbg_endpoint, &state);
813 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
814 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
815 printf("%s, DPMAC State= %d\n", __func__, state);
816
817 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
818 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
819 dflt_dprc_handle, &dpmac_endpoint,
820 &dbg_endpoint, &state);
821 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
822 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
823 printf("%s, DPNI State= %d\n", __func__, state);
824#endif
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530825 return err;
826}
827
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700828static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
829{
830 int err;
831
832 /* and get a handle for the DPNI this interface is associate with */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530833 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
834 &dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700835 if (err) {
836 printf("dpni_open() failed\n");
837 goto err_open;
838 }
839
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530840 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530841 dflt_dpni->dpni_handle,
842 &dflt_dpni->dpni_attrs);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700843 if (err) {
844 printf("dpni_get_attributes() failed (err=%d)\n", err);
845 goto err_get_attr;
846 }
847
848 /* Configure our buffers' layout */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530849 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700850 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530851 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
852 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530853 dflt_dpni->buf_layout.pass_parser_result = true;
854 dflt_dpni->buf_layout.pass_frame_status = true;
855 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530856 /* HW erratum mandates data alignment in multiples of 256 */
857 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700858 /* ...rx, ... */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530859 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530860 dflt_dpni->dpni_handle,
861 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700862 if (err) {
863 printf("dpni_set_rx_buffer_layout() failed");
864 goto err_buf_layout;
865 }
866
867 /* ... tx, ... */
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530868 /* remove Rx-only options */
869 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
870 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530871 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530872 dflt_dpni->dpni_handle,
873 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700874 if (err) {
875 printf("dpni_set_tx_buffer_layout() failed");
876 goto err_buf_layout;
877 }
878
879 /* ... tx-confirm. */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530880 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530881 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530882 dflt_dpni->dpni_handle,
883 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700884 if (err) {
885 printf("dpni_set_tx_conf_buffer_layout() failed");
886 goto err_buf_layout;
887 }
888
889 /* Now that we've set our tx buffer layout, retrieve the minimum
890 * required tx data offset.
891 */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530892 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530893 dflt_dpni->dpni_handle,
894 &priv->tx_data_offset);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700895 if (err) {
896 printf("dpni_get_tx_data_offset() failed\n");
897 goto err_data_offset;
898 }
899
900 /* Warn in case TX data offset is not multiple of 64 bytes. */
901 WARN_ON(priv->tx_data_offset % 64);
902
903 /* Accomodate SWA space. */
904 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
905 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
906
907 return 0;
908
909err_data_offset:
910err_buf_layout:
911err_get_attr:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530912 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700913err_open:
914 return err;
915}
916
917static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
918{
919 struct dpni_pools_cfg pools_params;
920 struct dpni_tx_flow_cfg dflt_tx_flow;
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530921 struct dpni_tx_conf_cfg tx_conf_cfg;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700922 int err = 0;
923
Prabhakar Kushwahaa7992322016-03-28 14:11:05 +0530924 memset(&pools_params, 0, sizeof(pools_params));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700925 pools_params.num_dpbp = 1;
926 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
927 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530928 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
929 dflt_dpni->dpni_handle, &pools_params);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700930 if (err) {
931 printf("dpni_set_pools() failed\n");
932 return err;
933 }
934
935 priv->tx_flow_id = DPNI_NEW_FLOW_ID;
936 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
937
Prabhakar Kushwahac3d06e32015-12-24 15:32:49 +0530938 dflt_tx_flow.use_common_tx_conf_queue = 0;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530939 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
940 dflt_dpni->dpni_handle, &priv->tx_flow_id,
941 &dflt_tx_flow);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700942 if (err) {
943 printf("dpni_set_tx_flow() failed\n");
944 return err;
945 }
946
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530947 memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg));
948 tx_conf_cfg.errors_only = true;
949 /*Set tx-conf and error configuration*/
950 err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS,
951 dflt_dpni->dpni_handle,
952 priv->tx_flow_id, &tx_conf_cfg);
953 if (err) {
954 printf("dpni_set_tx_conf() failed\n");
955 return err;
956 }
957
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700958 return 0;
959}
960
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530961static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
962 phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700963{
964 int err;
965 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
966
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530967 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id,
968 phy_interface_strings[enet_if]);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700969
970 net_dev->iobase = 0;
971 net_dev->init = ldpaa_eth_open;
972 net_dev->halt = ldpaa_eth_stop;
973 net_dev->send = ldpaa_eth_tx;
974 net_dev->recv = ldpaa_eth_pull_dequeue_rx;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700975
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530976#ifdef CONFIG_PHYLIB
977 err = init_phy(net_dev);
978 if (err < 0)
979 return err;
980#endif
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700981
982 err = eth_register(net_dev);
983 if (err < 0) {
984 printf("eth_register() = %d\n", err);
985 return err;
986 }
987
988 return 0;
989}
990
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530991int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700992{
993 struct eth_device *net_dev = NULL;
994 struct ldpaa_eth_priv *priv = NULL;
995 int err = 0;
996
997
998 /* Net device */
999 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
1000 if (!net_dev) {
1001 printf("eth_device malloc() failed\n");
1002 return -ENOMEM;
1003 }
1004 memset(net_dev, 0, sizeof(struct eth_device));
1005
1006 /* alloc the ldpaa ethernet private struct */
1007 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1008 if (!priv) {
1009 printf("ldpaa_eth_priv malloc() failed\n");
1010 return -ENOMEM;
1011 }
1012 memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1013
1014 net_dev->priv = (void *)priv;
1015 priv->net_dev = (struct eth_device *)net_dev;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +05301016 priv->dpmac_id = dpmac_id;
1017 debug("%s dpmac_id=%d\n", __func__, dpmac_id);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -07001018
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +05301019 err = ldpaa_eth_netdev_init(net_dev, enet_if);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -07001020 if (err)
1021 goto err_netdev_init;
1022
1023 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1024 return 0;
1025
1026err_netdev_init:
1027 free(priv);
1028 net_dev->priv = NULL;
1029 free(net_dev);
1030
1031 return err;
1032}