blob: f235b622b6f39489ddbdce0cc13d3d428b470705 [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);
Prabhakar Kushwaha41f65142017-02-15 20:56:03 +0530590 else {
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530591 free(priv->phydev);
Prabhakar Kushwaha41f65142017-02-15 20:56:03 +0530592 priv->phydev = NULL;
593 }
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700594#endif
595
596 ldpaa_dpbp_free();
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530597 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
598 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700599}
600
601static void ldpaa_dpbp_drain_cnt(int count)
602{
603 uint64_t buf_array[7];
604 void *addr;
605 int ret, i;
606
607 BUG_ON(count > 7);
608
609 do {
610 ret = qbman_swp_acquire(dflt_dpio->sw_portal,
611 dflt_dpbp->dpbp_attr.bpid,
612 buf_array, count);
613 if (ret < 0) {
614 printf("qbman_swp_acquire() failed\n");
615 return;
616 }
617 for (i = 0; i < ret; i++) {
618 addr = (void *)buf_array[i];
619 debug("Free: buffer addr =0x%p\n", addr);
620 free(addr);
621 }
622 } while (ret);
623}
624
625static void ldpaa_dpbp_drain(void)
626{
627 int i;
628 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
629 ldpaa_dpbp_drain_cnt(7);
630}
631
632static int ldpaa_bp_add_7(uint16_t bpid)
633{
634 uint64_t buf_array[7];
635 u8 *addr;
636 int i;
637 struct qbman_release_desc rd;
638
639 for (i = 0; i < 7; i++) {
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530640 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700641 if (!addr) {
642 printf("addr allocation failed\n");
643 goto err_alloc;
644 }
645 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
Prabhakar Kushwahadbe0f2a2015-03-20 19:28:15 -0700646 flush_dcache_range((u64)addr,
647 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700648
649 buf_array[i] = (uint64_t)addr;
650 debug("Release: buffer addr =0x%p\n", addr);
651 }
652
653release_bufs:
654 /* In case the portal is busy, retry until successful.
655 * This function is guaranteed to succeed in a reasonable amount
656 * of time.
657 */
658
659 do {
660 mdelay(1);
661 qbman_release_desc_clear(&rd);
662 qbman_release_desc_set_bpid(&rd, bpid);
663 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
664
665 return i;
666
667err_alloc:
668 if (i)
669 goto release_bufs;
670
671 return 0;
672}
673
674static int ldpaa_dpbp_seed(uint16_t bpid)
675{
676 int i;
677 int count;
678
679 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
680 count = ldpaa_bp_add_7(bpid);
681 if (count < 7)
682 printf("Buffer Seed= %d\n", count);
683 }
684
685 return 0;
686}
687
688static int ldpaa_dpbp_setup(void)
689{
690 int err;
691
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530692 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700693 &dflt_dpbp->dpbp_handle);
694 if (err) {
695 printf("dpbp_open() failed\n");
696 goto err_open;
697 }
698
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530699 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700700 if (err) {
701 printf("dpbp_enable() failed\n");
702 goto err_enable;
703 }
704
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530705 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
706 dflt_dpbp->dpbp_handle,
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700707 &dflt_dpbp->dpbp_attr);
708 if (err) {
709 printf("dpbp_get_attributes() failed\n");
710 goto err_get_attr;
711 }
712
713 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
714 if (err) {
715 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
716 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
717 goto err_seed;
718 }
719
720 return 0;
721
722err_seed:
723err_get_attr:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530724 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700725err_enable:
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530726 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700727err_open:
728 return err;
729}
730
731static void ldpaa_dpbp_free(void)
732{
733 ldpaa_dpbp_drain();
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530734 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
735 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
736 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700737}
738
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530739static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
740 struct ldpaa_eth_priv *priv)
741{
742 struct dpmac_attr attr;
743 int error;
744
745 memset(&attr, 0, sizeof(struct dpmac_attr));
746 error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS,
747 priv->dpmac_handle,
748 &attr);
749 if (error == 0) {
750 if ((attr.version.major != DPMAC_VER_MAJOR) ||
751 (attr.version.minor != DPMAC_VER_MINOR)) {
752 printf("DPMAC version mismatch found %u.%u,",
753 attr.version.major, attr.version.minor);
754 printf("supported version is %u.%u\n",
755 DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
756 }
757 }
758
759 return error;
760}
761
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530762static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
763{
764 int err = 0;
765 struct dpmac_cfg dpmac_cfg;
766
767 dpmac_cfg.mac_id = priv->dpmac_id;
768 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg,
769 &priv->dpmac_handle);
770 if (err)
771 printf("dpmac_create() failed\n");
Prabhakar Kushwaha0a4156c2015-12-24 15:32:37 +0530772
773 err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
774 if (err < 0)
775 printf("ldpaa_dpmac_version_check() failed: %d\n", err);
776
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530777 return err;
778}
779
780static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
781{
782 int err = 0;
783 struct dprc_connection_cfg dprc_connection_cfg = {
784 /* If both rates are zero the connection */
785 /* will be configured in "best effort" mode. */
786 .committed_rate = 0,
787 .max_rate = 0
788 };
789
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530790#ifdef DEBUG
791 struct dprc_endpoint dbg_endpoint;
792 int state = 0;
793#endif
794
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530795 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000796 strcpy(dpmac_endpoint.type, "dpmac");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530797 dpmac_endpoint.id = priv->dpmac_id;
798
799 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
Ben Whitten34fd6c92015-12-30 13:05:58 +0000800 strcpy(dpni_endpoint.type, "dpni");
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530801 dpni_endpoint.id = dflt_dpni->dpni_id;
802
803 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
804 dflt_dprc_handle,
805 &dpmac_endpoint,
806 &dpni_endpoint,
807 &dprc_connection_cfg);
Prabhakar Kushwahab4af96f2015-11-04 12:26:01 +0530808 if (err)
809 printf("dprc_connect() failed\n");
810
811#ifdef DEBUG
812 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
813 dflt_dprc_handle, &dpni_endpoint,
814 &dbg_endpoint, &state);
815 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
816 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
817 printf("%s, DPMAC State= %d\n", __func__, state);
818
819 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
820 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
821 dflt_dprc_handle, &dpmac_endpoint,
822 &dbg_endpoint, &state);
823 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
824 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
825 printf("%s, DPNI State= %d\n", __func__, state);
826#endif
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530827 return err;
828}
829
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700830static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
831{
832 int err;
833
834 /* and get a handle for the DPNI this interface is associate with */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530835 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
836 &dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700837 if (err) {
838 printf("dpni_open() failed\n");
839 goto err_open;
840 }
841
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530842 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530843 dflt_dpni->dpni_handle,
844 &dflt_dpni->dpni_attrs);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700845 if (err) {
846 printf("dpni_get_attributes() failed (err=%d)\n", err);
847 goto err_get_attr;
848 }
849
850 /* Configure our buffers' layout */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530851 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700852 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530853 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
854 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530855 dflt_dpni->buf_layout.pass_parser_result = true;
856 dflt_dpni->buf_layout.pass_frame_status = true;
857 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530858 /* HW erratum mandates data alignment in multiples of 256 */
859 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700860 /* ...rx, ... */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530861 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530862 dflt_dpni->dpni_handle,
863 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700864 if (err) {
865 printf("dpni_set_rx_buffer_layout() failed");
866 goto err_buf_layout;
867 }
868
869 /* ... tx, ... */
Prabhakar Kushwaha9a934802015-11-04 12:26:02 +0530870 /* remove Rx-only options */
871 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
872 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530873 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530874 dflt_dpni->dpni_handle,
875 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700876 if (err) {
877 printf("dpni_set_tx_buffer_layout() failed");
878 goto err_buf_layout;
879 }
880
881 /* ... tx-confirm. */
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530882 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530883 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530884 dflt_dpni->dpni_handle,
885 &dflt_dpni->buf_layout);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700886 if (err) {
887 printf("dpni_set_tx_conf_buffer_layout() failed");
888 goto err_buf_layout;
889 }
890
891 /* Now that we've set our tx buffer layout, retrieve the minimum
892 * required tx data offset.
893 */
Prabhakar Kushwaha9564df62015-07-07 15:40:06 +0530894 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530895 dflt_dpni->dpni_handle,
896 &priv->tx_data_offset);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700897 if (err) {
898 printf("dpni_get_tx_data_offset() failed\n");
899 goto err_data_offset;
900 }
901
902 /* Warn in case TX data offset is not multiple of 64 bytes. */
903 WARN_ON(priv->tx_data_offset % 64);
904
905 /* Accomodate SWA space. */
906 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
907 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
908
909 return 0;
910
911err_data_offset:
912err_buf_layout:
913err_get_attr:
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530914 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700915err_open:
916 return err;
917}
918
919static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
920{
921 struct dpni_pools_cfg pools_params;
922 struct dpni_tx_flow_cfg dflt_tx_flow;
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530923 struct dpni_tx_conf_cfg tx_conf_cfg;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700924 int err = 0;
925
Prabhakar Kushwahaa7992322016-03-28 14:11:05 +0530926 memset(&pools_params, 0, sizeof(pools_params));
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700927 pools_params.num_dpbp = 1;
928 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
929 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530930 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
931 dflt_dpni->dpni_handle, &pools_params);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700932 if (err) {
933 printf("dpni_set_pools() failed\n");
934 return err;
935 }
936
937 priv->tx_flow_id = DPNI_NEW_FLOW_ID;
938 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
939
Prabhakar Kushwahac3d06e32015-12-24 15:32:49 +0530940 dflt_tx_flow.use_common_tx_conf_queue = 0;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530941 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
942 dflt_dpni->dpni_handle, &priv->tx_flow_id,
943 &dflt_tx_flow);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700944 if (err) {
945 printf("dpni_set_tx_flow() failed\n");
946 return err;
947 }
948
Prabhakar Kushwahab0efba72015-12-24 15:33:13 +0530949 memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg));
950 tx_conf_cfg.errors_only = true;
951 /*Set tx-conf and error configuration*/
952 err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS,
953 dflt_dpni->dpni_handle,
954 priv->tx_flow_id, &tx_conf_cfg);
955 if (err) {
956 printf("dpni_set_tx_conf() failed\n");
957 return err;
958 }
959
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700960 return 0;
961}
962
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530963static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
964 phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700965{
966 int err;
967 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
968
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530969 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id,
970 phy_interface_strings[enet_if]);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700971
972 net_dev->iobase = 0;
973 net_dev->init = ldpaa_eth_open;
974 net_dev->halt = ldpaa_eth_stop;
975 net_dev->send = ldpaa_eth_tx;
976 net_dev->recv = ldpaa_eth_pull_dequeue_rx;
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700977
Prabhakar Kushwahaef9329a2016-02-24 17:02:11 +0530978#ifdef CONFIG_PHYLIB
979 err = init_phy(net_dev);
980 if (err < 0)
981 return err;
982#endif
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700983
984 err = eth_register(net_dev);
985 if (err < 0) {
986 printf("eth_register() = %d\n", err);
987 return err;
988 }
989
990 return 0;
991}
992
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +0530993int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -0700994{
995 struct eth_device *net_dev = NULL;
996 struct ldpaa_eth_priv *priv = NULL;
997 int err = 0;
998
999
1000 /* Net device */
1001 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
1002 if (!net_dev) {
1003 printf("eth_device malloc() failed\n");
1004 return -ENOMEM;
1005 }
1006 memset(net_dev, 0, sizeof(struct eth_device));
1007
1008 /* alloc the ldpaa ethernet private struct */
1009 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1010 if (!priv) {
1011 printf("ldpaa_eth_priv malloc() failed\n");
1012 return -ENOMEM;
1013 }
1014 memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1015
1016 net_dev->priv = (void *)priv;
1017 priv->net_dev = (struct eth_device *)net_dev;
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +05301018 priv->dpmac_id = dpmac_id;
1019 debug("%s dpmac_id=%d\n", __func__, dpmac_id);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -07001020
Prabhakar Kushwaha52d2e2c2015-11-04 12:26:00 +05301021 err = ldpaa_eth_netdev_init(net_dev, enet_if);
Prabhakar Kushwaha5350b992015-03-19 09:20:46 -07001022 if (err)
1023 goto err_netdev_init;
1024
1025 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1026 return 0;
1027
1028err_netdev_init:
1029 free(priv);
1030 net_dev->priv = NULL;
1031 free(net_dev);
1032
1033 return err;
1034}