layerscape: add ls1088ardb device support
[openwrt/staging/lynxis/omap.git] / target / linux / layerscape / patches-4.4 / 7208-staging-fsl-dpaa2-mac-Added-MAC-PHY-interface-driver.patch
1 From ecaf55d2907835cd0580903e134cdf08416ff694 Mon Sep 17 00:00:00 2001
2 From: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
3 Date: Tue, 15 Sep 2015 10:27:19 -0500
4 Subject: [PATCH 208/226] staging: fsl-dpaa2: mac: Added MAC / PHY interface
5 driver
6
7 This is a commit of the cummulative, squashed dpmac patches.
8 All the commit logs are preserved below.
9
10 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
11
12 --------------------------------------------------------------
13
14 flib,dpmac: add dpmac files (Rebasing onto kernel 3.19, MC 0.6)
15
16 patches moved from 4.0 kernel
17
18 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
19 [Stuart: cherry-picked patch and split it up]
20 Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
21
22 staging: fsl-dpaa2: mac: Added MAC / PHY interface driver.
23
24 This driver works as a proxy between phylib including phy drivers and
25 the MC firmware. It receives updates on link state changes from PHY
26 lib and forwards them to MC and receives interrupt from MC whenever
27 a request is made to change the link state.
28
29 Signed-off-by: Alex Marginean <alexandru.marginean@freescale.com>
30 Change-Id: I8097ea69ea8effded3bddd43b9d326bbb59ba6c8
31 Reviewed-on: http://git.am.freescale.net:8181/35113
32 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
33 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
34
35 fsl-dpaa2: mac: Change IRQ flags
36
37 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
38 Change-Id: Ia86570858f9cf7f673089cd7c2078662d56b2f01
39 Reviewed-on: http://git.am.freescale.net:8181/35581
40 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
41 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
42
43 fsl-dpaa2: mac: Check for actual link state change
44
45 Do not invoke the MC firmware if the link state hasn't changed.
46
47 Signed-off-by: Alex Marginean <alexandru.marginean@freescale.com>
48 Change-Id: Iba59d8b52c72334efa28f6126e50ec821c802852
49 Reviewed-on: http://git.am.freescale.net:8181/35582
50 Reviewed-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
51 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
52 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
53
54 fsl-dpaa2: mac: Fix "dpmac netdevs" probing
55
56 Fixup code under DPAA2_MAC_NETDEVS to probe again. In particular, remove
57 the temporary addition of "fixed.c" in the mac/ folder.
58
59 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
60 Change-Id: Iea6768f3c5cd9b2de2c8421c03ecebf155b9792b
61 Reviewed-on: http://git.am.freescale.net:8181/37673
62 Reviewed-by: Ruxandra Ioana Radulescu <ruxandra.radulescu@freescale.com>
63 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
64 Tested-by: Stuart Yoder <stuart.yoder@freescale.com>
65
66 flib: Remove duplicate header files
67
68 These files are included by the DPAA2 mac driver files.
69
70 Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
71 Change-Id: Ieff56e3c34393ef65a5ac1123aaf00bacefa050c
72 Reviewed-on: http://git.am.freescale.net:8181/37257
73 Reviewed-by: Alexandru Marginean <Alexandru.Marginean@freescale.com>
74 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
75 Tested-by: Stuart Yoder <stuart.yoder@freescale.com>
76
77 fsl-dpaa2: mac: Add dependency on CONFIG_FIXED_PHY
78
79 The DPAA2 DPMAC driver currently relies on fixed links, so it will fail
80 to probe in unusual ways if CONFIG_FIXED_PHY is not enabled.
81
82 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
83 Change-Id: Ibc53226a215ed85a2ba22c55b18595fb939e7418
84 Reviewed-on: http://git.am.freescale.net:8181/37687
85 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
86 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
87
88 fsl-dpaa2: mac: Fix macro
89
90 Remove macro ending backslash.
91
92 Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
93 Change-Id: Ib0c4a41eee8fbe4aa7c991fc7fdb87771d3bf594
94 Reviewed-on: http://git.am.freescale.net:8181/37254
95 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
96 Reviewed-by: Alexandru Marginean <Alexandru.Marginean@freescale.com>
97 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
98
99 fsl-dpaa2: mac: migrated remaining flibs for MC fw 8.0.0
100
101 Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
102 [Stuart: split mac part out of original patch, updated subject]
103 Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
104
105 staging: fsl-dpaa2: mac: Port to MC-0.7 Flibs
106
107 Change-Id: Ief731e245bdc207f1bf8e7ff4dfdabb445d6010e
108 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
109 Reviewed-on: http://git.am.freescale.net:8181/39151
110 Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
111 Tested-by: Stuart Yoder <stuart.yoder@freescale.com>
112
113 staging: fsl-dpaa2: mac: Do programing of MSIs in devm_request_threaded_irq()
114
115 With the new dprc_set_obj_irq() we can now program MSIS in the device
116 in the callback invoked from devm_request_threaded_irq().
117 Since this callback is invoked with interrupts disabled, we need to
118 use an atomic portal, instead of the root DPRC's built-in portal
119 which is non-atomic.
120
121 Signed-off-by: Itai Katz <itai.katz@freescale.com>
122 Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
123 [Stuart: split original patch up by component]
124 Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
125
126 fsl-dpaa2: mac: Fix driver probing
127
128 The DPMAC probing function was broken in many ways. This patch adds
129 the following fixes:
130 - Look up PHY nodes based on the phy-handle property of the respective
131 DPMAC node;
132 - Defer DPMAC device probing until the MDIO MUX driver probes first (we
133 depend on that for configuring the PHYs on PCIe riser cards on
134 LS2085A QDS boards.
135 - Add Kconfig dependencies on XGMAC_MDIO and MDIO_BUS_MUX_MMIOREG.
136
137 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
138
139 fsl-dpaa2: mac: Fix interrupt handling
140
141 The DPMAC has two interrupt events muxed on a single interrupt line.
142 Both the PHY and the DPNI can initiate a link event.
143
144 When the link event is initiated by the PHY (possibly as the effect of an
145 earlier link change request initiated by a DPNI), we must make sure
146 dpmac_set_link_state() is explicitly called in order for the event to be
147 propagated (back) to the DPNI.
148
149 Finally, DPMAC interrupt mask has to be explicitly specified before calling
150 dpmac_set_irq_enabled().
151
152 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
153
154 fsl-dpaa2: mac: Fix print in case device is not initialized
155
156 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
157
158 fsl-dpaa2: mac: Fix error paths at probe
159
160 Merge error condition checks. Add error codes to the early exit paths.
161 Fix swapped goto labels.
162
163 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
164
165 fsl-dpaa2: mac: Remove unused function prototype
166
167 fixed_phy_register_2() was a leftover since we had to backport fixed PHY
168 implementation on kernel v3.10.
169
170 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
171
172 fsl-dpaa2/mac: Update dpmac binary interface to v3.2
173
174 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
175
176 fsl-dpaa2: mac: Update Flib to MC 0.8.1
177
178 In practice, this adds a counter for "good" egress frames.
179
180 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
181
182 fsl-dpaa2: mac: Add counter for "good" egress frames
183
184 Now available with the 0.8.1 Flibs.
185
186 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
187
188 fsl-dpaa2: mac: Update dpmac_set_link_state() error checking
189
190 As of 0.8.1 Flibs, dpmac_set_link_state() no longer returns what we'd
191 consider spurious errors. This allows for cleaner error checking on
192 DPMAC-side.
193
194 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
195
196 fsl-dpaa2: mac: Remove __cold attribute
197
198 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
199
200 fsl-dpaa2: mac: Check DPMAC FLIB version
201
202 Make sure we support the DPMAC version, otherwise abort probing
203 early on and provide an error message.
204
205 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
206
207 fsl-dpaa2: mac: Replace uintX_t with uX
208
209 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
210
211 fsl-dpaa2: mac: Fix crash on error path
212
213 If the fixed-phy cannot be correctly registered, unregister_netdev()
214 receives a non-NULL, yet invalid phydev. Force the phydev reference to
215 NULL to avoid a crash on the probe routine's error path.
216
217 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
218
219 fsl-dpaa2: mac: Remove TODOs comments from the code
220
221 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
222
223 fsl-dpaa2: mac: Fix ppx_eth_iface_mode order
224
225 ppx_eth_iface_mode must be kept in sync with enum dpmac_eth_if, but some
226 array values weren't in the right order.
227
228 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
229
230 fsl-dpaa2: mac: Remove forward declarations of functions
231
232 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
233
234 fsl-dpaa2: mac: Remove ppx_{err,warn,info} macros
235
236 Replace with their straighforward equivalents, their contexts being
237 non-ambiguous.
238
239 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
240
241 fsl-dpaa2: mac: Use non-atomic MC portal
242
243 The DPMAC driver does not make MC calls from atomic contexts, so it is
244 safe to request non-atomic MC portals.
245
246 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
247
248 fsl-dpaa2: mac: Replace "ppx" prefix with "dpaa2_mac"
249
250 Use a similar naming convention as for the Ethernet driver,
251 replacing "ppx" with "dpaa2_mac" as prefix for functions and
252 structures.
253
254 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
255
256 fsl-dpaa2: mac: Remove unnecessary blank line
257
258 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
259
260 fsl-dpaa2: mac: Do not handle link change confirmation interrupt
261
262 The need for that interrupt is more about debugging.
263
264 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
265
266 fsl-dpaa2: mac: resolve compile issues on uprev to 4.5
267
268 -interrupt info in mc struct changed upstream
269 -fixed_phy_register() had new argument
270
271 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
272 ---
273 MAINTAINERS | 6 +
274 drivers/staging/fsl-dpaa2/Kconfig | 1 +
275 drivers/staging/fsl-dpaa2/Makefile | 1 +
276 drivers/staging/fsl-dpaa2/mac/Kconfig | 24 +
277 drivers/staging/fsl-dpaa2/mac/Makefile | 10 +
278 drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h | 195 ++++++++
279 drivers/staging/fsl-dpaa2/mac/dpmac.c | 422 ++++++++++++++++
280 drivers/staging/fsl-dpaa2/mac/dpmac.h | 593 ++++++++++++++++++++++
281 drivers/staging/fsl-dpaa2/mac/mac.c | 767 +++++++++++++++++++++++++++++
282 9 files changed, 2019 insertions(+)
283 create mode 100644 drivers/staging/fsl-dpaa2/mac/Kconfig
284 create mode 100644 drivers/staging/fsl-dpaa2/mac/Makefile
285 create mode 100644 drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h
286 create mode 100644 drivers/staging/fsl-dpaa2/mac/dpmac.c
287 create mode 100644 drivers/staging/fsl-dpaa2/mac/dpmac.h
288 create mode 100644 drivers/staging/fsl-dpaa2/mac/mac.c
289
290 --- a/MAINTAINERS
291 +++ b/MAINTAINERS
292 @@ -4554,6 +4554,12 @@ S: Maintained
293 F: drivers/staging/fsl-mc/bus/mc-ioctl.h
294 F: drivers/staging/fsl-mc/bus/mc-restool.c
295
296 +FREESCALE DPAA2 MAC/PHY INTERFACE DRIVER
297 +M: Alex Marginean <Alexandru.Marginean@freescale.com>
298 +L: linux-kernel@vger.kernel.org
299 +S: Maintained
300 +F: drivers/staging/fsl-dpaa2/mac/
301 +
302 FREEVXFS FILESYSTEM
303 M: Christoph Hellwig <hch@infradead.org>
304 W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
305 --- a/drivers/staging/fsl-dpaa2/Kconfig
306 +++ b/drivers/staging/fsl-dpaa2/Kconfig
307 @@ -9,3 +9,4 @@ config FSL_DPAA2
308 Build drivers for Freescale DataPath Acceleration Architecture (DPAA2) family of SoCs.
309 # TODO move DPIO driver in-here?
310 source "drivers/staging/fsl-dpaa2/ethernet/Kconfig"
311 +source "drivers/staging/fsl-dpaa2/mac/Kconfig"
312 --- a/drivers/staging/fsl-dpaa2/Makefile
313 +++ b/drivers/staging/fsl-dpaa2/Makefile
314 @@ -3,3 +3,4 @@
315 #
316
317 obj-$(CONFIG_FSL_DPAA2_ETH) += ethernet/
318 +obj-$(CONFIG_FSL_DPAA2_MAC) += mac/
319 --- /dev/null
320 +++ b/drivers/staging/fsl-dpaa2/mac/Kconfig
321 @@ -0,0 +1,24 @@
322 +config FSL_DPAA2_MAC
323 + tristate "DPAA2 MAC / PHY interface"
324 + depends on FSL_MC_BUS && FSL_DPAA2
325 + select MDIO_BUS_MUX_MMIOREG
326 + select FSL_XGMAC_MDIO
327 + select FIXED_PHY
328 + ---help---
329 + Prototype driver for DPAA2 MAC / PHY interface object.
330 + This driver works as a proxy between phylib including phy drivers and
331 + the MC firmware. It receives updates on link state changes from PHY
332 + lib and forwards them to MC and receives interrupt from MC whenever
333 + a request is made to change the link state.
334 +
335 +
336 +config FSL_DPAA2_MAC_NETDEVS
337 + bool "Expose net interfaces for PHYs"
338 + default n
339 + depends on FSL_DPAA2_MAC
340 + ---help---
341 + Exposes macX net interfaces which allow direct control over MACs and
342 + PHYs.
343 + .
344 + Leave disabled if unsure.
345 +
346 --- /dev/null
347 +++ b/drivers/staging/fsl-dpaa2/mac/Makefile
348 @@ -0,0 +1,10 @@
349 +
350 +obj-$(CONFIG_FSL_DPAA2_MAC) += dpaa2-mac.o
351 +
352 +dpaa2-mac-objs := mac.o dpmac.o
353 +
354 +all:
355 + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
356 +
357 +clean:
358 + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
359 --- /dev/null
360 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h
361 @@ -0,0 +1,195 @@
362 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
363 + *
364 + * Redistribution and use in source and binary forms, with or without
365 + * modification, are permitted provided that the following conditions are met:
366 + * * Redistributions of source code must retain the above copyright
367 + * notice, this list of conditions and the following disclaimer.
368 + * * Redistributions in binary form must reproduce the above copyright
369 + * notice, this list of conditions and the following disclaimer in the
370 + * documentation and/or other materials provided with the distribution.
371 + * * Neither the name of the above-listed copyright holders nor the
372 + * names of any contributors may be used to endorse or promote products
373 + * derived from this software without specific prior written permission.
374 + *
375 + *
376 + * ALTERNATIVELY, this software may be distributed under the terms of the
377 + * GNU General Public License ("GPL") as published by the Free Software
378 + * Foundation, either version 2 of that License or (at your option) any
379 + * later version.
380 + *
381 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
382 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
383 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
384 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
385 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
386 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
387 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
388 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
389 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
390 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
391 + * POSSIBILITY OF SUCH DAMAGE.
392 + */
393 +#ifndef _FSL_DPMAC_CMD_H
394 +#define _FSL_DPMAC_CMD_H
395 +
396 +/* DPMAC Version */
397 +#define DPMAC_VER_MAJOR 3
398 +#define DPMAC_VER_MINOR 2
399 +
400 +/* Command IDs */
401 +#define DPMAC_CMDID_CLOSE 0x800
402 +#define DPMAC_CMDID_OPEN 0x80c
403 +#define DPMAC_CMDID_CREATE 0x90c
404 +#define DPMAC_CMDID_DESTROY 0x900
405 +
406 +#define DPMAC_CMDID_GET_ATTR 0x004
407 +#define DPMAC_CMDID_RESET 0x005
408 +
409 +#define DPMAC_CMDID_SET_IRQ 0x010
410 +#define DPMAC_CMDID_GET_IRQ 0x011
411 +#define DPMAC_CMDID_SET_IRQ_ENABLE 0x012
412 +#define DPMAC_CMDID_GET_IRQ_ENABLE 0x013
413 +#define DPMAC_CMDID_SET_IRQ_MASK 0x014
414 +#define DPMAC_CMDID_GET_IRQ_MASK 0x015
415 +#define DPMAC_CMDID_GET_IRQ_STATUS 0x016
416 +#define DPMAC_CMDID_CLEAR_IRQ_STATUS 0x017
417 +
418 +#define DPMAC_CMDID_MDIO_READ 0x0c0
419 +#define DPMAC_CMDID_MDIO_WRITE 0x0c1
420 +#define DPMAC_CMDID_GET_LINK_CFG 0x0c2
421 +#define DPMAC_CMDID_SET_LINK_STATE 0x0c3
422 +#define DPMAC_CMDID_GET_COUNTER 0x0c4
423 +
424 +/* cmd, param, offset, width, type, arg_name */
425 +#define DPMAC_CMD_CREATE(cmd, cfg) \
426 + MC_CMD_OP(cmd, 0, 0, 32, int, cfg->mac_id)
427 +
428 +/* cmd, param, offset, width, type, arg_name */
429 +#define DPMAC_CMD_OPEN(cmd, dpmac_id) \
430 + MC_CMD_OP(cmd, 0, 0, 32, int, dpmac_id)
431 +
432 +/* cmd, param, offset, width, type, arg_name */
433 +#define DPMAC_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
434 +do { \
435 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
436 + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
437 + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr); \
438 + MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
439 +} while (0)
440 +
441 +/* cmd, param, offset, width, type, arg_name */
442 +#define DPMAC_CMD_GET_IRQ(cmd, irq_index) \
443 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
444 +
445 +/* cmd, param, offset, width, type, arg_name */
446 +#define DPMAC_RSP_GET_IRQ(cmd, type, irq_cfg) \
447 +do { \
448 + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \
449 + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr); \
450 + MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
451 + MC_RSP_OP(cmd, 2, 32, 32, int, type); \
452 +} while (0)
453 +
454 +/* cmd, param, offset, width, type, arg_name */
455 +#define DPMAC_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \
456 +do { \
457 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, en); \
458 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
459 +} while (0)
460 +
461 +/* cmd, param, offset, width, type, arg_name */
462 +#define DPMAC_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
463 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
464 +
465 +/* cmd, param, offset, width, type, arg_name */
466 +#define DPMAC_RSP_GET_IRQ_ENABLE(cmd, en) \
467 + MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en)
468 +
469 +/* cmd, param, offset, width, type, arg_name */
470 +#define DPMAC_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
471 +do { \
472 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask);\
473 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
474 +} while (0)
475 +
476 +/* cmd, param, offset, width, type, arg_name */
477 +#define DPMAC_CMD_GET_IRQ_MASK(cmd, irq_index) \
478 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
479 +
480 +/* cmd, param, offset, width, type, arg_name */
481 +#define DPMAC_RSP_GET_IRQ_MASK(cmd, mask) \
482 + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
483 +
484 +/* cmd, param, offset, width, type, arg_name */
485 +#define DPMAC_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
486 +do { \
487 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
488 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
489 +} while (0)
490 +
491 +/* cmd, param, offset, width, type, arg_name */
492 +#define DPMAC_RSP_GET_IRQ_STATUS(cmd, status) \
493 + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
494 +
495 +/* cmd, param, offset, width, type, arg_name */
496 +#define DPMAC_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
497 +do { \
498 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
499 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
500 +} while (0)
501 +
502 +/* cmd, param, offset, width, type, arg_name */
503 +#define DPMAC_RSP_GET_ATTRIBUTES(cmd, attr) \
504 +do { \
505 + MC_RSP_OP(cmd, 0, 0, 32, int, attr->phy_id);\
506 + MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\
507 + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\
508 + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
509 + MC_RSP_OP(cmd, 1, 32, 8, enum dpmac_link_type, attr->link_type);\
510 + MC_RSP_OP(cmd, 1, 40, 8, enum dpmac_eth_if, attr->eth_if);\
511 + MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->max_rate);\
512 +} while (0)
513 +
514 +/* cmd, param, offset, width, type, arg_name */
515 +#define DPMAC_CMD_MDIO_READ(cmd, cfg) \
516 +do { \
517 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->phy_addr); \
518 + MC_CMD_OP(cmd, 0, 8, 8, uint8_t, cfg->reg); \
519 +} while (0)
520 +
521 +/* cmd, param, offset, width, type, arg_name */
522 +#define DPMAC_RSP_MDIO_READ(cmd, data) \
523 + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, data)
524 +
525 +/* cmd, param, offset, width, type, arg_name */
526 +#define DPMAC_CMD_MDIO_WRITE(cmd, cfg) \
527 +do { \
528 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->phy_addr); \
529 + MC_CMD_OP(cmd, 0, 8, 8, uint8_t, cfg->reg); \
530 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->data); \
531 +} while (0)
532 +
533 +/* cmd, param, offset, width, type, arg_name */
534 +#define DPMAC_RSP_GET_LINK_CFG(cmd, cfg) \
535 +do { \
536 + MC_RSP_OP(cmd, 0, 0, 64, uint64_t, cfg->options); \
537 + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, cfg->rate); \
538 +} while (0)
539 +
540 +/* cmd, param, offset, width, type, arg_name */
541 +#define DPMAC_CMD_SET_LINK_STATE(cmd, cfg) \
542 +do { \
543 + MC_CMD_OP(cmd, 0, 0, 64, uint64_t, cfg->options); \
544 + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->rate); \
545 + MC_CMD_OP(cmd, 2, 0, 1, int, cfg->up); \
546 +} while (0)
547 +
548 +/* cmd, param, offset, width, type, arg_name */
549 +#define DPMAC_CMD_GET_COUNTER(cmd, type) \
550 + MC_CMD_OP(cmd, 0, 0, 8, enum dpmac_counter, type)
551 +
552 +/* cmd, param, offset, width, type, arg_name */
553 +#define DPMAC_RSP_GET_COUNTER(cmd, counter) \
554 + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, counter)
555 +
556 +#endif /* _FSL_DPMAC_CMD_H */
557 --- /dev/null
558 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c
559 @@ -0,0 +1,422 @@
560 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
561 + *
562 + * Redistribution and use in source and binary forms, with or without
563 + * modification, are permitted provided that the following conditions are met:
564 + * * Redistributions of source code must retain the above copyright
565 + * notice, this list of conditions and the following disclaimer.
566 + * * Redistributions in binary form must reproduce the above copyright
567 + * notice, this list of conditions and the following disclaimer in the
568 + * documentation and/or other materials provided with the distribution.
569 + * * Neither the name of the above-listed copyright holders nor the
570 + * names of any contributors may be used to endorse or promote products
571 + * derived from this software without specific prior written permission.
572 + *
573 + *
574 + * ALTERNATIVELY, this software may be distributed under the terms of the
575 + * GNU General Public License ("GPL") as published by the Free Software
576 + * Foundation, either version 2 of that License or (at your option) any
577 + * later version.
578 + *
579 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
580 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
581 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
582 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
583 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
584 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
585 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
586 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
587 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
588 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
589 + * POSSIBILITY OF SUCH DAMAGE.
590 + */
591 +#include "../../fsl-mc/include/mc-sys.h"
592 +#include "../../fsl-mc/include/mc-cmd.h"
593 +#include "dpmac.h"
594 +#include "dpmac-cmd.h"
595 +
596 +int dpmac_open(struct fsl_mc_io *mc_io,
597 + uint32_t cmd_flags,
598 + int dpmac_id,
599 + uint16_t *token)
600 +{
601 + struct mc_command cmd = { 0 };
602 + int err;
603 +
604 + /* prepare command */
605 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_OPEN,
606 + cmd_flags,
607 + 0);
608 + DPMAC_CMD_OPEN(cmd, dpmac_id);
609 +
610 + /* send command to mc*/
611 + err = mc_send_command(mc_io, &cmd);
612 + if (err)
613 + return err;
614 +
615 + /* retrieve response parameters */
616 + *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
617 +
618 + return err;
619 +}
620 +
621 +int dpmac_close(struct fsl_mc_io *mc_io,
622 + uint32_t cmd_flags,
623 + uint16_t token)
624 +{
625 + struct mc_command cmd = { 0 };
626 +
627 + /* prepare command */
628 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags,
629 + token);
630 +
631 + /* send command to mc*/
632 + return mc_send_command(mc_io, &cmd);
633 +}
634 +
635 +int dpmac_create(struct fsl_mc_io *mc_io,
636 + uint32_t cmd_flags,
637 + const struct dpmac_cfg *cfg,
638 + uint16_t *token)
639 +{
640 + struct mc_command cmd = { 0 };
641 + int err;
642 +
643 + /* prepare command */
644 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CREATE,
645 + cmd_flags,
646 + 0);
647 + DPMAC_CMD_CREATE(cmd, cfg);
648 +
649 + /* send command to mc*/
650 + err = mc_send_command(mc_io, &cmd);
651 + if (err)
652 + return err;
653 +
654 + /* retrieve response parameters */
655 + *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
656 +
657 + return 0;
658 +}
659 +
660 +int dpmac_destroy(struct fsl_mc_io *mc_io,
661 + uint32_t cmd_flags,
662 + uint16_t token)
663 +{
664 + struct mc_command cmd = { 0 };
665 +
666 + /* prepare command */
667 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_DESTROY,
668 + cmd_flags,
669 + token);
670 +
671 + /* send command to mc*/
672 + return mc_send_command(mc_io, &cmd);
673 +}
674 +
675 +int dpmac_set_irq(struct fsl_mc_io *mc_io,
676 + uint32_t cmd_flags,
677 + uint16_t token,
678 + uint8_t irq_index,
679 + struct dpmac_irq_cfg *irq_cfg)
680 +{
681 + struct mc_command cmd = { 0 };
682 +
683 + /* prepare command */
684 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ,
685 + cmd_flags,
686 + token);
687 + DPMAC_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
688 +
689 + /* send command to mc*/
690 + return mc_send_command(mc_io, &cmd);
691 +}
692 +
693 +int dpmac_get_irq(struct fsl_mc_io *mc_io,
694 + uint32_t cmd_flags,
695 + uint16_t token,
696 + uint8_t irq_index,
697 + int *type,
698 + struct dpmac_irq_cfg *irq_cfg)
699 +{
700 + struct mc_command cmd = { 0 };
701 + int err;
702 +
703 + /* prepare command */
704 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ,
705 + cmd_flags,
706 + token);
707 + DPMAC_CMD_GET_IRQ(cmd, irq_index);
708 +
709 + /* send command to mc*/
710 + err = mc_send_command(mc_io, &cmd);
711 + if (err)
712 + return err;
713 +
714 + /* retrieve response parameters */
715 + DPMAC_RSP_GET_IRQ(cmd, *type, irq_cfg);
716 +
717 + return 0;
718 +}
719 +
720 +int dpmac_set_irq_enable(struct fsl_mc_io *mc_io,
721 + uint32_t cmd_flags,
722 + uint16_t token,
723 + uint8_t irq_index,
724 + uint8_t en)
725 +{
726 + struct mc_command cmd = { 0 };
727 +
728 + /* prepare command */
729 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_ENABLE,
730 + cmd_flags,
731 + token);
732 + DPMAC_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
733 +
734 + /* send command to mc*/
735 + return mc_send_command(mc_io, &cmd);
736 +}
737 +
738 +int dpmac_get_irq_enable(struct fsl_mc_io *mc_io,
739 + uint32_t cmd_flags,
740 + uint16_t token,
741 + uint8_t irq_index,
742 + uint8_t *en)
743 +{
744 + struct mc_command cmd = { 0 };
745 + int err;
746 +
747 + /* prepare command */
748 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_ENABLE,
749 + cmd_flags,
750 + token);
751 + DPMAC_CMD_GET_IRQ_ENABLE(cmd, irq_index);
752 +
753 + /* send command to mc*/
754 + err = mc_send_command(mc_io, &cmd);
755 + if (err)
756 + return err;
757 +
758 + /* retrieve response parameters */
759 + DPMAC_RSP_GET_IRQ_ENABLE(cmd, *en);
760 +
761 + return 0;
762 +}
763 +
764 +int dpmac_set_irq_mask(struct fsl_mc_io *mc_io,
765 + uint32_t cmd_flags,
766 + uint16_t token,
767 + uint8_t irq_index,
768 + uint32_t mask)
769 +{
770 + struct mc_command cmd = { 0 };
771 +
772 + /* prepare command */
773 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_MASK,
774 + cmd_flags,
775 + token);
776 + DPMAC_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
777 +
778 + /* send command to mc*/
779 + return mc_send_command(mc_io, &cmd);
780 +}
781 +
782 +int dpmac_get_irq_mask(struct fsl_mc_io *mc_io,
783 + uint32_t cmd_flags,
784 + uint16_t token,
785 + uint8_t irq_index,
786 + uint32_t *mask)
787 +{
788 + struct mc_command cmd = { 0 };
789 + int err;
790 +
791 + /* prepare command */
792 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_MASK,
793 + cmd_flags,
794 + token);
795 + DPMAC_CMD_GET_IRQ_MASK(cmd, irq_index);
796 +
797 + /* send command to mc*/
798 + err = mc_send_command(mc_io, &cmd);
799 + if (err)
800 + return err;
801 +
802 + /* retrieve response parameters */
803 + DPMAC_RSP_GET_IRQ_MASK(cmd, *mask);
804 +
805 + return 0;
806 +}
807 +
808 +int dpmac_get_irq_status(struct fsl_mc_io *mc_io,
809 + uint32_t cmd_flags,
810 + uint16_t token,
811 + uint8_t irq_index,
812 + uint32_t *status)
813 +{
814 + struct mc_command cmd = { 0 };
815 + int err;
816 +
817 + /* prepare command */
818 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_STATUS,
819 + cmd_flags,
820 + token);
821 + DPMAC_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
822 +
823 + /* send command to mc*/
824 + err = mc_send_command(mc_io, &cmd);
825 + if (err)
826 + return err;
827 +
828 + /* retrieve response parameters */
829 + DPMAC_RSP_GET_IRQ_STATUS(cmd, *status);
830 +
831 + return 0;
832 +}
833 +
834 +int dpmac_clear_irq_status(struct fsl_mc_io *mc_io,
835 + uint32_t cmd_flags,
836 + uint16_t token,
837 + uint8_t irq_index,
838 + uint32_t status)
839 +{
840 + struct mc_command cmd = { 0 };
841 +
842 + /* prepare command */
843 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLEAR_IRQ_STATUS,
844 + cmd_flags,
845 + token);
846 + DPMAC_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
847 +
848 + /* send command to mc*/
849 + return mc_send_command(mc_io, &cmd);
850 +}
851 +
852 +int dpmac_get_attributes(struct fsl_mc_io *mc_io,
853 + uint32_t cmd_flags,
854 + uint16_t token,
855 + struct dpmac_attr *attr)
856 +{
857 + struct mc_command cmd = { 0 };
858 + int err;
859 +
860 + /* prepare command */
861 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_ATTR,
862 + cmd_flags,
863 + token);
864 +
865 + /* send command to mc*/
866 + err = mc_send_command(mc_io, &cmd);
867 + if (err)
868 + return err;
869 +
870 + /* retrieve response parameters */
871 + DPMAC_RSP_GET_ATTRIBUTES(cmd, attr);
872 +
873 + return 0;
874 +}
875 +
876 +int dpmac_mdio_read(struct fsl_mc_io *mc_io,
877 + uint32_t cmd_flags,
878 + uint16_t token,
879 + struct dpmac_mdio_cfg *cfg)
880 +{
881 + struct mc_command cmd = { 0 };
882 + int err;
883 +
884 + /* prepare command */
885 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_MDIO_READ,
886 + cmd_flags,
887 + token);
888 + DPMAC_CMD_MDIO_READ(cmd, cfg);
889 +
890 + /* send command to mc*/
891 + err = mc_send_command(mc_io, &cmd);
892 + if (err)
893 + return err;
894 +
895 + /* retrieve response parameters */
896 + DPMAC_RSP_MDIO_READ(cmd, cfg->data);
897 +
898 + return 0;
899 +}
900 +
901 +int dpmac_mdio_write(struct fsl_mc_io *mc_io,
902 + uint32_t cmd_flags,
903 + uint16_t token,
904 + struct dpmac_mdio_cfg *cfg)
905 +{
906 + struct mc_command cmd = { 0 };
907 +
908 + /* prepare command */
909 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_MDIO_WRITE,
910 + cmd_flags,
911 + token);
912 + DPMAC_CMD_MDIO_WRITE(cmd, cfg);
913 +
914 + /* send command to mc*/
915 + return mc_send_command(mc_io, &cmd);
916 +}
917 +
918 +int dpmac_get_link_cfg(struct fsl_mc_io *mc_io,
919 + uint32_t cmd_flags,
920 + uint16_t token,
921 + struct dpmac_link_cfg *cfg)
922 +{
923 + struct mc_command cmd = { 0 };
924 + int err = 0;
925 +
926 + /* prepare command */
927 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_LINK_CFG,
928 + cmd_flags,
929 + token);
930 +
931 + /* send command to mc*/
932 + err = mc_send_command(mc_io, &cmd);
933 + if (err)
934 + return err;
935 +
936 + DPMAC_RSP_GET_LINK_CFG(cmd, cfg);
937 +
938 + return 0;
939 +}
940 +
941 +int dpmac_set_link_state(struct fsl_mc_io *mc_io,
942 + uint32_t cmd_flags,
943 + uint16_t token,
944 + struct dpmac_link_state *link_state)
945 +{
946 + struct mc_command cmd = { 0 };
947 +
948 + /* prepare command */
949 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE,
950 + cmd_flags,
951 + token);
952 + DPMAC_CMD_SET_LINK_STATE(cmd, link_state);
953 +
954 + /* send command to mc*/
955 + return mc_send_command(mc_io, &cmd);
956 +}
957 +
958 +int dpmac_get_counter(struct fsl_mc_io *mc_io,
959 + uint32_t cmd_flags,
960 + uint16_t token,
961 + enum dpmac_counter type,
962 + uint64_t *counter)
963 +{
964 + struct mc_command cmd = { 0 };
965 + int err = 0;
966 +
967 + /* prepare command */
968 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_COUNTER,
969 + cmd_flags,
970 + token);
971 + DPMAC_CMD_GET_COUNTER(cmd, type);
972 +
973 + /* send command to mc*/
974 + err = mc_send_command(mc_io, &cmd);
975 + if (err)
976 + return err;
977 +
978 + DPMAC_RSP_GET_COUNTER(cmd, *counter);
979 +
980 + return 0;
981 +}
982 --- /dev/null
983 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac.h
984 @@ -0,0 +1,593 @@
985 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
986 + *
987 + * Redistribution and use in source and binary forms, with or without
988 + * modification, are permitted provided that the following conditions are met:
989 + * * Redistributions of source code must retain the above copyright
990 + * notice, this list of conditions and the following disclaimer.
991 + * * Redistributions in binary form must reproduce the above copyright
992 + * notice, this list of conditions and the following disclaimer in the
993 + * documentation and/or other materials provided with the distribution.
994 + * * Neither the name of the above-listed copyright holders nor the
995 + * names of any contributors may be used to endorse or promote products
996 + * derived from this software without specific prior written permission.
997 + *
998 + *
999 + * ALTERNATIVELY, this software may be distributed under the terms of the
1000 + * GNU General Public License ("GPL") as published by the Free Software
1001 + * Foundation, either version 2 of that License or (at your option) any
1002 + * later version.
1003 + *
1004 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1005 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1006 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1007 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1008 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1009 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1010 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1011 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1012 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1013 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1014 + * POSSIBILITY OF SUCH DAMAGE.
1015 + */
1016 +#ifndef __FSL_DPMAC_H
1017 +#define __FSL_DPMAC_H
1018 +
1019 +/* Data Path MAC API
1020 + * Contains initialization APIs and runtime control APIs for DPMAC
1021 + */
1022 +
1023 +struct fsl_mc_io;
1024 +
1025 +/**
1026 + * dpmac_open() - Open a control session for the specified object.
1027 + * @mc_io: Pointer to MC portal's I/O object
1028 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1029 + * @dpmac_id: DPMAC unique ID
1030 + * @token: Returned token; use in subsequent API calls
1031 + *
1032 + * This function can be used to open a control session for an
1033 + * already created object; an object may have been declared in
1034 + * the DPL or by calling the dpmac_create function.
1035 + * This function returns a unique authentication token,
1036 + * associated with the specific object ID and the specific MC
1037 + * portal; this token must be used in all subsequent commands for
1038 + * this specific object
1039 + *
1040 + * Return: '0' on Success; Error code otherwise.
1041 + */
1042 +int dpmac_open(struct fsl_mc_io *mc_io,
1043 + uint32_t cmd_flags,
1044 + int dpmac_id,
1045 + uint16_t *token);
1046 +
1047 +/**
1048 + * dpmac_close() - Close the control session of the object
1049 + * @mc_io: Pointer to MC portal's I/O object
1050 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1051 + * @token: Token of DPMAC object
1052 + *
1053 + * After this function is called, no further operations are
1054 + * allowed on the object without opening a new control session.
1055 + *
1056 + * Return: '0' on Success; Error code otherwise.
1057 + */
1058 +int dpmac_close(struct fsl_mc_io *mc_io,
1059 + uint32_t cmd_flags,
1060 + uint16_t token);
1061 +
1062 +/**
1063 + * enum dpmac_link_type - DPMAC link type
1064 + * @DPMAC_LINK_TYPE_NONE: No link
1065 + * @DPMAC_LINK_TYPE_FIXED: Link is fixed type
1066 + * @DPMAC_LINK_TYPE_PHY: Link by PHY ID
1067 + * @DPMAC_LINK_TYPE_BACKPLANE: Backplane link type
1068 + */
1069 +enum dpmac_link_type {
1070 + DPMAC_LINK_TYPE_NONE,
1071 + DPMAC_LINK_TYPE_FIXED,
1072 + DPMAC_LINK_TYPE_PHY,
1073 + DPMAC_LINK_TYPE_BACKPLANE
1074 +};
1075 +
1076 +/**
1077 + * enum dpmac_eth_if - DPMAC Ethrnet interface
1078 + * @DPMAC_ETH_IF_MII: MII interface
1079 + * @DPMAC_ETH_IF_RMII: RMII interface
1080 + * @DPMAC_ETH_IF_SMII: SMII interface
1081 + * @DPMAC_ETH_IF_GMII: GMII interface
1082 + * @DPMAC_ETH_IF_RGMII: RGMII interface
1083 + * @DPMAC_ETH_IF_SGMII: SGMII interface
1084 + * @DPMAC_ETH_IF_QSGMII: QSGMII interface
1085 + * @DPMAC_ETH_IF_XAUI: XAUI interface
1086 + * @DPMAC_ETH_IF_XFI: XFI interface
1087 + */
1088 +enum dpmac_eth_if {
1089 + DPMAC_ETH_IF_MII,
1090 + DPMAC_ETH_IF_RMII,
1091 + DPMAC_ETH_IF_SMII,
1092 + DPMAC_ETH_IF_GMII,
1093 + DPMAC_ETH_IF_RGMII,
1094 + DPMAC_ETH_IF_SGMII,
1095 + DPMAC_ETH_IF_QSGMII,
1096 + DPMAC_ETH_IF_XAUI,
1097 + DPMAC_ETH_IF_XFI
1098 +};
1099 +
1100 +/**
1101 + * struct dpmac_cfg - Structure representing DPMAC configuration
1102 + * @mac_id: Represents the Hardware MAC ID; in case of multiple WRIOP,
1103 + * the MAC IDs are continuous.
1104 + * For example: 2 WRIOPs, 16 MACs in each:
1105 + * MAC IDs for the 1st WRIOP: 1-16,
1106 + * MAC IDs for the 2nd WRIOP: 17-32.
1107 + */
1108 +struct dpmac_cfg {
1109 + int mac_id;
1110 +};
1111 +
1112 +/**
1113 + * dpmac_create() - Create the DPMAC object.
1114 + * @mc_io: Pointer to MC portal's I/O object
1115 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1116 + * @cfg: Configuration structure
1117 + * @token: Returned token; use in subsequent API calls
1118 + *
1119 + * Create the DPMAC object, allocate required resources and
1120 + * perform required initialization.
1121 + *
1122 + * The object can be created either by declaring it in the
1123 + * DPL file, or by calling this function.
1124 + * This function returns a unique authentication token,
1125 + * associated with the specific object ID and the specific MC
1126 + * portal; this token must be used in all subsequent calls to
1127 + * this specific object. For objects that are created using the
1128 + * DPL file, call dpmac_open function to get an authentication
1129 + * token first.
1130 + *
1131 + * Return: '0' on Success; Error code otherwise.
1132 + */
1133 +int dpmac_create(struct fsl_mc_io *mc_io,
1134 + uint32_t cmd_flags,
1135 + const struct dpmac_cfg *cfg,
1136 + uint16_t *token);
1137 +
1138 +/**
1139 + * dpmac_destroy() - Destroy the DPMAC object and release all its resources.
1140 + * @mc_io: Pointer to MC portal's I/O object
1141 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1142 + * @token: Token of DPMAC object
1143 + *
1144 + * Return: '0' on Success; error code otherwise.
1145 + */
1146 +int dpmac_destroy(struct fsl_mc_io *mc_io,
1147 + uint32_t cmd_flags,
1148 + uint16_t token);
1149 +
1150 +/**
1151 + * DPMAC IRQ Index and Events
1152 + */
1153 +
1154 +/**
1155 + * IRQ index
1156 + */
1157 +#define DPMAC_IRQ_INDEX 0
1158 +/**
1159 + * IRQ event - indicates a change in link state
1160 + */
1161 +#define DPMAC_IRQ_EVENT_LINK_CFG_REQ 0x00000001
1162 +/**
1163 + * IRQ event - Indicates that the link state changed
1164 + */
1165 +#define DPMAC_IRQ_EVENT_LINK_CHANGED 0x00000002
1166 +
1167 +/**
1168 + * struct dpmac_irq_cfg - IRQ configuration
1169 + * @addr: Address that must be written to signal a message-based interrupt
1170 + * @val: Value to write into irq_addr address
1171 + * @irq_num: A user defined number associated with this IRQ
1172 + */
1173 +struct dpmac_irq_cfg {
1174 + uint64_t addr;
1175 + uint32_t val;
1176 + int irq_num;
1177 +};
1178 +
1179 +/**
1180 + * dpmac_set_irq() - Set IRQ information for the DPMAC to trigger an interrupt.
1181 + * @mc_io: Pointer to MC portal's I/O object
1182 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1183 + * @token: Token of DPMAC object
1184 + * @irq_index: Identifies the interrupt index to configure
1185 + * @irq_cfg: IRQ configuration
1186 + *
1187 + * Return: '0' on Success; Error code otherwise.
1188 + */
1189 +int dpmac_set_irq(struct fsl_mc_io *mc_io,
1190 + uint32_t cmd_flags,
1191 + uint16_t token,
1192 + uint8_t irq_index,
1193 + struct dpmac_irq_cfg *irq_cfg);
1194 +
1195 +/**
1196 + * dpmac_get_irq() - Get IRQ information from the DPMAC.
1197 + * @mc_io: Pointer to MC portal's I/O object
1198 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1199 + * @token: Token of DPMAC object
1200 + * @irq_index: The interrupt index to configure
1201 + * @type: Interrupt type: 0 represents message interrupt
1202 + * type (both irq_addr and irq_val are valid)
1203 + * @irq_cfg: IRQ attributes
1204 + *
1205 + * Return: '0' on Success; Error code otherwise.
1206 + */
1207 +int dpmac_get_irq(struct fsl_mc_io *mc_io,
1208 + uint32_t cmd_flags,
1209 + uint16_t token,
1210 + uint8_t irq_index,
1211 + int *type,
1212 + struct dpmac_irq_cfg *irq_cfg);
1213 +
1214 +/**
1215 + * dpmac_set_irq_enable() - Set overall interrupt state.
1216 + * @mc_io: Pointer to MC portal's I/O object
1217 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1218 + * @token: Token of DPMAC object
1219 + * @irq_index: The interrupt index to configure
1220 + * @en: Interrupt state - enable = 1, disable = 0
1221 + *
1222 + * Allows GPP software to control when interrupts are generated.
1223 + * Each interrupt can have up to 32 causes. The enable/disable control's the
1224 + * overall interrupt state. if the interrupt is disabled no causes will cause
1225 + * an interrupt.
1226 + *
1227 + * Return: '0' on Success; Error code otherwise.
1228 + */
1229 +int dpmac_set_irq_enable(struct fsl_mc_io *mc_io,
1230 + uint32_t cmd_flags,
1231 + uint16_t token,
1232 + uint8_t irq_index,
1233 + uint8_t en);
1234 +
1235 +/**
1236 + * dpmac_get_irq_enable() - Get overall interrupt state
1237 + * @mc_io: Pointer to MC portal's I/O object
1238 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1239 + * @token: Token of DPMAC object
1240 + * @irq_index: The interrupt index to configure
1241 + * @en: Returned interrupt state - enable = 1, disable = 0
1242 + *
1243 + * Return: '0' on Success; Error code otherwise.
1244 + */
1245 +int dpmac_get_irq_enable(struct fsl_mc_io *mc_io,
1246 + uint32_t cmd_flags,
1247 + uint16_t token,
1248 + uint8_t irq_index,
1249 + uint8_t *en);
1250 +
1251 +/**
1252 + * dpmac_set_irq_mask() - Set interrupt mask.
1253 + * @mc_io: Pointer to MC portal's I/O object
1254 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1255 + * @token: Token of DPMAC object
1256 + * @irq_index: The interrupt index to configure
1257 + * @mask: Event mask to trigger interrupt;
1258 + * each bit:
1259 + * 0 = ignore event
1260 + * 1 = consider event for asserting IRQ
1261 + *
1262 + * Every interrupt can have up to 32 causes and the interrupt model supports
1263 + * masking/unmasking each cause independently
1264 + *
1265 + * Return: '0' on Success; Error code otherwise.
1266 + */
1267 +int dpmac_set_irq_mask(struct fsl_mc_io *mc_io,
1268 + uint32_t cmd_flags,
1269 + uint16_t token,
1270 + uint8_t irq_index,
1271 + uint32_t mask);
1272 +
1273 +/**
1274 + * dpmac_get_irq_mask() - Get interrupt mask.
1275 + * @mc_io: Pointer to MC portal's I/O object
1276 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1277 + * @token: Token of DPMAC object
1278 + * @irq_index: The interrupt index to configure
1279 + * @mask: Returned event mask to trigger interrupt
1280 + *
1281 + * Every interrupt can have up to 32 causes and the interrupt model supports
1282 + * masking/unmasking each cause independently
1283 + *
1284 + * Return: '0' on Success; Error code otherwise.
1285 + */
1286 +int dpmac_get_irq_mask(struct fsl_mc_io *mc_io,
1287 + uint32_t cmd_flags,
1288 + uint16_t token,
1289 + uint8_t irq_index,
1290 + uint32_t *mask);
1291 +
1292 +/**
1293 + * dpmac_get_irq_status() - Get the current status of any pending interrupts.
1294 + *
1295 + * @mc_io: Pointer to MC portal's I/O object
1296 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1297 + * @token: Token of DPMAC object
1298 + * @irq_index: The interrupt index to configure
1299 + * @status: Returned interrupts status - one bit per cause:
1300 + * 0 = no interrupt pending
1301 + * 1 = interrupt pending
1302 + *
1303 + * Return: '0' on Success; Error code otherwise.
1304 + */
1305 +int dpmac_get_irq_status(struct fsl_mc_io *mc_io,
1306 + uint32_t cmd_flags,
1307 + uint16_t token,
1308 + uint8_t irq_index,
1309 + uint32_t *status);
1310 +
1311 +/**
1312 + * dpmac_clear_irq_status() - Clear a pending interrupt's status
1313 + *
1314 + * @mc_io: Pointer to MC portal's I/O object
1315 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1316 + * @token: Token of DPMAC object
1317 + * @irq_index: The interrupt index to configure
1318 + * @status: Bits to clear (W1C) - one bit per cause:
1319 + * 0 = don't change
1320 + * 1 = clear status bit
1321 + *
1322 + * Return: '0' on Success; Error code otherwise.
1323 + */
1324 +int dpmac_clear_irq_status(struct fsl_mc_io *mc_io,
1325 + uint32_t cmd_flags,
1326 + uint16_t token,
1327 + uint8_t irq_index,
1328 + uint32_t status);
1329 +
1330 +/**
1331 + * struct dpmac_attr - Structure representing DPMAC attributes
1332 + * @id: DPMAC object ID
1333 + * @phy_id: PHY ID
1334 + * @link_type: link type
1335 + * @eth_if: Ethernet interface
1336 + * @max_rate: Maximum supported rate - in Mbps
1337 + * @version: DPMAC version
1338 + */
1339 +struct dpmac_attr {
1340 + int id;
1341 + int phy_id;
1342 + enum dpmac_link_type link_type;
1343 + enum dpmac_eth_if eth_if;
1344 + uint32_t max_rate;
1345 + /**
1346 + * struct version - Structure representing DPMAC version
1347 + * @major: DPMAC major version
1348 + * @minor: DPMAC minor version
1349 + */
1350 + struct {
1351 + uint16_t major;
1352 + uint16_t minor;
1353 + } version;
1354 +};
1355 +
1356 +/**
1357 + * dpmac_get_attributes - Retrieve DPMAC attributes.
1358 + *
1359 + * @mc_io: Pointer to MC portal's I/O object
1360 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1361 + * @token: Token of DPMAC object
1362 + * @attr: Returned object's attributes
1363 + *
1364 + * Return: '0' on Success; Error code otherwise.
1365 + */
1366 +int dpmac_get_attributes(struct fsl_mc_io *mc_io,
1367 + uint32_t cmd_flags,
1368 + uint16_t token,
1369 + struct dpmac_attr *attr);
1370 +
1371 +/**
1372 + * struct dpmac_mdio_cfg - DPMAC MDIO read/write parameters
1373 + * @phy_addr: MDIO device address
1374 + * @reg: Address of the register within the Clause 45 PHY device from which data
1375 + * is to be read
1376 + * @data: Data read/write from/to MDIO
1377 + */
1378 +struct dpmac_mdio_cfg {
1379 + uint8_t phy_addr;
1380 + uint8_t reg;
1381 + uint16_t data;
1382 +};
1383 +
1384 +/**
1385 + * dpmac_mdio_read() - Perform MDIO read transaction
1386 + * @mc_io: Pointer to opaque I/O object
1387 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1388 + * @token: Token of DPMAC object
1389 + * @cfg: Structure with MDIO transaction parameters
1390 + *
1391 + * Return: '0' on Success; Error code otherwise.
1392 + */
1393 +int dpmac_mdio_read(struct fsl_mc_io *mc_io,
1394 + uint32_t cmd_flags,
1395 + uint16_t token,
1396 + struct dpmac_mdio_cfg *cfg);
1397 +
1398 +/**
1399 + * dpmac_mdio_write() - Perform MDIO write transaction
1400 + * @mc_io: Pointer to opaque I/O object
1401 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1402 + * @token: Token of DPMAC object
1403 + * @cfg: Structure with MDIO transaction parameters
1404 + *
1405 + * Return: '0' on Success; Error code otherwise.
1406 + */
1407 +int dpmac_mdio_write(struct fsl_mc_io *mc_io,
1408 + uint32_t cmd_flags,
1409 + uint16_t token,
1410 + struct dpmac_mdio_cfg *cfg);
1411 +
1412 +/**
1413 + * DPMAC link configuration/state options
1414 + */
1415 +
1416 +/**
1417 + * Enable auto-negotiation
1418 + */
1419 +#define DPMAC_LINK_OPT_AUTONEG 0x0000000000000001ULL
1420 +/**
1421 + * Enable half-duplex mode
1422 + */
1423 +#define DPMAC_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
1424 +/**
1425 + * Enable pause frames
1426 + */
1427 +#define DPMAC_LINK_OPT_PAUSE 0x0000000000000004ULL
1428 +/**
1429 + * Enable a-symmetric pause frames
1430 + */
1431 +#define DPMAC_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
1432 +
1433 +/**
1434 + * struct dpmac_link_cfg - Structure representing DPMAC link configuration
1435 + * @rate: Link's rate - in Mbps
1436 + * @options: Enable/Disable DPMAC link cfg features (bitmap)
1437 + */
1438 +struct dpmac_link_cfg {
1439 + uint32_t rate;
1440 + uint64_t options;
1441 +};
1442 +
1443 +/**
1444 + * dpmac_get_link_cfg() - Get Ethernet link configuration
1445 + * @mc_io: Pointer to opaque I/O object
1446 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1447 + * @token: Token of DPMAC object
1448 + * @cfg: Returned structure with the link configuration
1449 + *
1450 + * Return: '0' on Success; Error code otherwise.
1451 + */
1452 +int dpmac_get_link_cfg(struct fsl_mc_io *mc_io,
1453 + uint32_t cmd_flags,
1454 + uint16_t token,
1455 + struct dpmac_link_cfg *cfg);
1456 +
1457 +/**
1458 + * struct dpmac_link_state - DPMAC link configuration request
1459 + * @rate: Rate in Mbps
1460 + * @options: Enable/Disable DPMAC link cfg features (bitmap)
1461 + * @up: Link state
1462 + */
1463 +struct dpmac_link_state {
1464 + uint32_t rate;
1465 + uint64_t options;
1466 + int up;
1467 +};
1468 +
1469 +/**
1470 + * dpmac_set_link_state() - Set the Ethernet link status
1471 + * @mc_io: Pointer to opaque I/O object
1472 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1473 + * @token: Token of DPMAC object
1474 + * @link_state: Link state configuration
1475 + *
1476 + * Return: '0' on Success; Error code otherwise.
1477 + */
1478 +int dpmac_set_link_state(struct fsl_mc_io *mc_io,
1479 + uint32_t cmd_flags,
1480 + uint16_t token,
1481 + struct dpmac_link_state *link_state);
1482 +
1483 +/**
1484 + * enum dpmac_counter - DPMAC counter types
1485 + * @DPMAC_CNT_ING_FRAME_64: counts 64-bytes frames, good or bad.
1486 + * @DPMAC_CNT_ING_FRAME_127: counts 65- to 127-bytes frames, good or bad.
1487 + * @DPMAC_CNT_ING_FRAME_255: counts 128- to 255-bytes frames, good or bad.
1488 + * @DPMAC_CNT_ING_FRAME_511: counts 256- to 511-bytes frames, good or bad.
1489 + * @DPMAC_CNT_ING_FRAME_1023: counts 512- to 1023-bytes frames, good or bad.
1490 + * @DPMAC_CNT_ING_FRAME_1518: counts 1024- to 1518-bytes frames, good or bad.
1491 + * @DPMAC_CNT_ING_FRAME_1519_MAX: counts 1519-bytes frames and larger
1492 + * (up to max frame length specified),
1493 + * good or bad.
1494 + * @DPMAC_CNT_ING_FRAG: counts frames which are shorter than 64 bytes received
1495 + * with a wrong CRC
1496 + * @DPMAC_CNT_ING_JABBER: counts frames longer than the maximum frame length
1497 + * specified, with a bad frame check sequence.
1498 + * @DPMAC_CNT_ING_FRAME_DISCARD: counts dropped frames due to internal errors.
1499 + * Occurs when a receive FIFO overflows.
1500 + * Includes also frames truncated as a result of
1501 + * the receive FIFO overflow.
1502 + * @DPMAC_CNT_ING_ALIGN_ERR: counts frames with an alignment error
1503 + * (optional used for wrong SFD).
1504 + * @DPMAC_CNT_EGR_UNDERSIZED: counts frames transmitted that was less than 64
1505 + * bytes long with a good CRC.
1506 + * @DPMAC_CNT_ING_OVERSIZED: counts frames longer than the maximum frame length
1507 + * specified, with a good frame check sequence.
1508 + * @DPMAC_CNT_ING_VALID_PAUSE_FRAME: counts valid pause frames (regular and PFC)
1509 + * @DPMAC_CNT_EGR_VALID_PAUSE_FRAME: counts valid pause frames transmitted
1510 + * (regular and PFC).
1511 + * @DPMAC_CNT_ING_BYTE: counts bytes received except preamble for all valid
1512 + * frames and valid pause frames.
1513 + * @DPMAC_CNT_ING_MCAST_FRAME: counts received multicast frames.
1514 + * @DPMAC_CNT_ING_BCAST_FRAME: counts received broadcast frames.
1515 + * @DPMAC_CNT_ING_ALL_FRAME: counts each good or bad frames received.
1516 + * @DPMAC_CNT_ING_UCAST_FRAME: counts received unicast frames.
1517 + * @DPMAC_CNT_ING_ERR_FRAME: counts frames received with an error
1518 + * (except for undersized/fragment frame).
1519 + * @DPMAC_CNT_EGR_BYTE: counts bytes transmitted except preamble for all valid
1520 + * frames and valid pause frames transmitted.
1521 + * @DPMAC_CNT_EGR_MCAST_FRAME: counts transmitted multicast frames.
1522 + * @DPMAC_CNT_EGR_BCAST_FRAME: counts transmitted broadcast frames.
1523 + * @DPMAC_CNT_EGR_UCAST_FRAME: counts transmitted unicast frames.
1524 + * @DPMAC_CNT_EGR_ERR_FRAME: counts frames transmitted with an error.
1525 + * @DPMAC_CNT_ING_GOOD_FRAME: counts frames received without error, including
1526 + * pause frames.
1527 + * @DPMAC_CNT_ENG_GOOD_FRAME: counts frames transmitted without error, including
1528 + * pause frames.
1529 + */
1530 +enum dpmac_counter {
1531 + DPMAC_CNT_ING_FRAME_64,
1532 + DPMAC_CNT_ING_FRAME_127,
1533 + DPMAC_CNT_ING_FRAME_255,
1534 + DPMAC_CNT_ING_FRAME_511,
1535 + DPMAC_CNT_ING_FRAME_1023,
1536 + DPMAC_CNT_ING_FRAME_1518,
1537 + DPMAC_CNT_ING_FRAME_1519_MAX,
1538 + DPMAC_CNT_ING_FRAG,
1539 + DPMAC_CNT_ING_JABBER,
1540 + DPMAC_CNT_ING_FRAME_DISCARD,
1541 + DPMAC_CNT_ING_ALIGN_ERR,
1542 + DPMAC_CNT_EGR_UNDERSIZED,
1543 + DPMAC_CNT_ING_OVERSIZED,
1544 + DPMAC_CNT_ING_VALID_PAUSE_FRAME,
1545 + DPMAC_CNT_EGR_VALID_PAUSE_FRAME,
1546 + DPMAC_CNT_ING_BYTE,
1547 + DPMAC_CNT_ING_MCAST_FRAME,
1548 + DPMAC_CNT_ING_BCAST_FRAME,
1549 + DPMAC_CNT_ING_ALL_FRAME,
1550 + DPMAC_CNT_ING_UCAST_FRAME,
1551 + DPMAC_CNT_ING_ERR_FRAME,
1552 + DPMAC_CNT_EGR_BYTE,
1553 + DPMAC_CNT_EGR_MCAST_FRAME,
1554 + DPMAC_CNT_EGR_BCAST_FRAME,
1555 + DPMAC_CNT_EGR_UCAST_FRAME,
1556 + DPMAC_CNT_EGR_ERR_FRAME,
1557 + DPMAC_CNT_ING_GOOD_FRAME,
1558 + DPMAC_CNT_ENG_GOOD_FRAME
1559 +};
1560 +
1561 +/**
1562 + * dpmac_get_counter() - Read a specific DPMAC counter
1563 + * @mc_io: Pointer to opaque I/O object
1564 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
1565 + * @token: Token of DPMAC object
1566 + * @type: The requested counter
1567 + * @counter: Returned counter value
1568 + *
1569 + * Return: The requested counter; '0' otherwise.
1570 + */
1571 +int dpmac_get_counter(struct fsl_mc_io *mc_io,
1572 + uint32_t cmd_flags,
1573 + uint16_t token,
1574 + enum dpmac_counter type,
1575 + uint64_t *counter);
1576 +
1577 +#endif /* __FSL_DPMAC_H */
1578 --- /dev/null
1579 +++ b/drivers/staging/fsl-dpaa2/mac/mac.c
1580 @@ -0,0 +1,767 @@
1581 +/* Copyright 2015 Freescale Semiconductor Inc.
1582 + *
1583 + * Redistribution and use in source and binary forms, with or without
1584 + * modification, are permitted provided that the following conditions are met:
1585 + * * Redistributions of source code must retain the above copyright
1586 + * notice, this list of conditions and the following disclaimer.
1587 + * * Redistributions in binary form must reproduce the above copyright
1588 + * notice, this list of conditions and the following disclaimer in the
1589 + * documentation and/or other materials provided with the distribution.
1590 + * * Neither the name of Freescale Semiconductor nor the
1591 + * names of its contributors may be used to endorse or promote products
1592 + * derived from this software without specific prior written permission.
1593 + *
1594 + *
1595 + * ALTERNATIVELY, this software may be distributed under the terms of the
1596 + * GNU General Public License ("GPL") as published by the Free Software
1597 + * Foundation, either version 2 of that License or (at your option) any
1598 + * later version.
1599 + *
1600 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1601 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1602 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1603 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1604 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1605 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1606 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1607 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1608 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1609 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1610 + */
1611 +
1612 +#include <linux/module.h>
1613 +
1614 +#include <linux/netdevice.h>
1615 +#include <linux/etherdevice.h>
1616 +#include <linux/rtnetlink.h>
1617 +#include <linux/if_vlan.h>
1618 +
1619 +#include <uapi/linux/if_bridge.h>
1620 +#include <net/netlink.h>
1621 +
1622 +#include <linux/of.h>
1623 +#include <linux/of_mdio.h>
1624 +#include <linux/of_net.h>
1625 +#include <linux/phy.h>
1626 +#include <linux/phy_fixed.h>
1627 +#include <linux/interrupt.h>
1628 +#include <linux/msi.h>
1629 +
1630 +#include "../../fsl-mc/include/mc.h"
1631 +#include "../../fsl-mc/include/mc-sys.h"
1632 +
1633 +#include "dpmac.h"
1634 +#include "dpmac-cmd.h"
1635 +
1636 +#define DPAA2_SUPPORTED_DPMAC_VERSION 3
1637 +
1638 +struct dpaa2_mac_priv {
1639 + struct net_device *netdev;
1640 + struct fsl_mc_device *mc_dev;
1641 + struct dpmac_attr attr;
1642 + struct dpmac_link_state old_state;
1643 +};
1644 +
1645 +/* TODO: fix the 10G modes, mapping can't be right:
1646 + * XGMII is paralel
1647 + * XAUI is serial, using 8b/10b encoding
1648 + * XFI is also serial but using 64b/66b encoding
1649 + * they can't all map to XGMII...
1650 + *
1651 + * This must be kept in sync with enum dpmac_eth_if.
1652 + */
1653 +static phy_interface_t dpaa2_mac_iface_mode[] = {
1654 + /* DPMAC_ETH_IF_MII */
1655 + PHY_INTERFACE_MODE_MII,
1656 + /* DPMAC_ETH_IF_RMII */
1657 + PHY_INTERFACE_MODE_RMII,
1658 + /* DPMAC_ETH_IF_SMII */
1659 + PHY_INTERFACE_MODE_SMII,
1660 + /* DPMAC_ETH_IF_GMII */
1661 + PHY_INTERFACE_MODE_GMII,
1662 + /* DPMAC_ETH_IF_RGMII */
1663 + PHY_INTERFACE_MODE_RGMII,
1664 + /* DPMAC_ETH_IF_SGMII */
1665 + PHY_INTERFACE_MODE_SGMII,
1666 + /* DPMAC_ETH_IF_QSGMII */
1667 + PHY_INTERFACE_MODE_QSGMII,
1668 + /* DPMAC_ETH_IF_XAUI */
1669 + PHY_INTERFACE_MODE_XGMII,
1670 + /* DPMAC_ETH_IF_XFI */
1671 + PHY_INTERFACE_MODE_XGMII,
1672 +};
1673 +
1674 +static void dpaa2_mac_link_changed(struct net_device *netdev)
1675 +{
1676 + struct phy_device *phydev;
1677 + struct dpmac_link_state state = { 0 };
1678 + struct dpaa2_mac_priv *priv = netdev_priv(netdev);
1679 + int err;
1680 +
1681 + /* the PHY just notified us of link state change */
1682 + phydev = netdev->phydev;
1683 +
1684 + state.up = !!phydev->link;
1685 + if (phydev->link) {
1686 + state.rate = phydev->speed;
1687 +
1688 + if (!phydev->duplex)
1689 + state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
1690 + if (phydev->autoneg)
1691 + state.options |= DPMAC_LINK_OPT_AUTONEG;
1692 +
1693 + netif_carrier_on(netdev);
1694 + } else {
1695 + netif_carrier_off(netdev);
1696 + }
1697 +
1698 + if (priv->old_state.up != state.up ||
1699 + priv->old_state.rate != state.rate ||
1700 + priv->old_state.options != state.options) {
1701 + priv->old_state = state;
1702 + phy_print_status(phydev);
1703 + }
1704 +
1705 + /* We must call into the MC firmware at all times, because we don't know
1706 + * when and whether a potential DPNI may have read the link state.
1707 + */
1708 + err = dpmac_set_link_state(priv->mc_dev->mc_io, 0,
1709 + priv->mc_dev->mc_handle, &state);
1710 + if (unlikely(err))
1711 + dev_err(&priv->mc_dev->dev, "dpmac_set_link_state: %d\n", err);
1712 +}
1713 +
1714 +/* IRQ bits that we handle */
1715 +static const u32 dpmac_irq_mask = DPMAC_IRQ_EVENT_LINK_CFG_REQ;
1716 +
1717 +#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
1718 +static netdev_tx_t dpaa2_mac_drop_frame(struct sk_buff *skb,
1719 + struct net_device *dev)
1720 +{
1721 + /* we don't support I/O for now, drop the frame */
1722 + dev_kfree_skb_any(skb);
1723 + return NETDEV_TX_OK;
1724 +}
1725 +
1726 +static int dpaa2_mac_open(struct net_device *netdev)
1727 +{
1728 + /* start PHY state machine */
1729 + phy_start(netdev->phydev);
1730 +
1731 + return 0;
1732 +}
1733 +
1734 +static int dpaa2_mac_stop(struct net_device *netdev)
1735 +{
1736 + if (!netdev->phydev)
1737 + goto done;
1738 +
1739 + /* stop PHY state machine */
1740 + phy_stop(netdev->phydev);
1741 +
1742 + /* signal link down to firmware */
1743 + netdev->phydev->link = 0;
1744 + dpaa2_mac_link_changed(netdev);
1745 +
1746 +done:
1747 + return 0;
1748 +}
1749 +
1750 +static int dpaa2_mac_get_settings(struct net_device *netdev,
1751 + struct ethtool_cmd *cmd)
1752 +{
1753 + return phy_ethtool_gset(netdev->phydev, cmd);
1754 +}
1755 +
1756 +static int dpaa2_mac_set_settings(struct net_device *netdev,
1757 + struct ethtool_cmd *cmd)
1758 +{
1759 + return phy_ethtool_sset(netdev->phydev, cmd);
1760 +}
1761 +
1762 +static struct rtnl_link_stats64
1763 +*dpaa2_mac_get_stats(struct net_device *netdev,
1764 + struct rtnl_link_stats64 *storage)
1765 +{
1766 + struct dpaa2_mac_priv *priv = netdev_priv(netdev);
1767 + u64 tmp;
1768 + int err;
1769 +
1770 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1771 + DPMAC_CNT_EGR_MCAST_FRAME,
1772 + &storage->tx_packets);
1773 + if (err)
1774 + goto error;
1775 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1776 + DPMAC_CNT_EGR_BCAST_FRAME, &tmp);
1777 + if (err)
1778 + goto error;
1779 + storage->tx_packets += tmp;
1780 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1781 + DPMAC_CNT_EGR_UCAST_FRAME, &tmp);
1782 + if (err)
1783 + goto error;
1784 + storage->tx_packets += tmp;
1785 +
1786 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1787 + DPMAC_CNT_EGR_UNDERSIZED, &storage->tx_dropped);
1788 + if (err)
1789 + goto error;
1790 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1791 + DPMAC_CNT_EGR_BYTE, &storage->tx_bytes);
1792 + if (err)
1793 + goto error;
1794 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1795 + DPMAC_CNT_EGR_ERR_FRAME, &storage->tx_errors);
1796 + if (err)
1797 + goto error;
1798 +
1799 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1800 + DPMAC_CNT_ING_ALL_FRAME, &storage->rx_packets);
1801 + if (err)
1802 + goto error;
1803 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1804 + DPMAC_CNT_ING_MCAST_FRAME, &storage->multicast);
1805 + if (err)
1806 + goto error;
1807 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1808 + DPMAC_CNT_ING_FRAME_DISCARD,
1809 + &storage->rx_dropped);
1810 + if (err)
1811 + goto error;
1812 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1813 + DPMAC_CNT_ING_ALIGN_ERR, &storage->rx_errors);
1814 + if (err)
1815 + goto error;
1816 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1817 + DPMAC_CNT_ING_OVERSIZED, &tmp);
1818 + if (err)
1819 + goto error;
1820 + storage->rx_errors += tmp;
1821 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1822 + DPMAC_CNT_ING_BYTE, &storage->rx_bytes);
1823 + if (err)
1824 + goto error;
1825 +
1826 + return storage;
1827 +
1828 +error:
1829 + netdev_err(netdev, "dpmac_get_counter err %d\n", err);
1830 + return storage;
1831 +}
1832 +
1833 +static struct {
1834 + enum dpmac_counter id;
1835 + char name[ETH_GSTRING_LEN];
1836 +} dpaa2_mac_counters[] = {
1837 + {DPMAC_CNT_ING_ALL_FRAME, "rx all frames"},
1838 + {DPMAC_CNT_ING_GOOD_FRAME, "rx frames ok"},
1839 + {DPMAC_CNT_ING_ERR_FRAME, "rx frame errors"},
1840 + {DPMAC_CNT_ING_FRAME_DISCARD, "rx frame discards"},
1841 + {DPMAC_CNT_ING_UCAST_FRAME, "rx u-cast"},
1842 + {DPMAC_CNT_ING_BCAST_FRAME, "rx b-cast"},
1843 + {DPMAC_CNT_ING_MCAST_FRAME, "rx m-cast"},
1844 + {DPMAC_CNT_ING_FRAME_64, "rx 64 bytes"},
1845 + {DPMAC_CNT_ING_FRAME_127, "rx 65-127 bytes"},
1846 + {DPMAC_CNT_ING_FRAME_255, "rx 128-255 bytes"},
1847 + {DPMAC_CNT_ING_FRAME_511, "rx 256-511 bytes"},
1848 + {DPMAC_CNT_ING_FRAME_1023, "rx 512-1023 bytes"},
1849 + {DPMAC_CNT_ING_FRAME_1518, "rx 1024-1518 bytes"},
1850 + {DPMAC_CNT_ING_FRAME_1519_MAX, "rx 1519-max bytes"},
1851 + {DPMAC_CNT_ING_FRAG, "rx frags"},
1852 + {DPMAC_CNT_ING_JABBER, "rx jabber"},
1853 + {DPMAC_CNT_ING_ALIGN_ERR, "rx align errors"},
1854 + {DPMAC_CNT_ING_OVERSIZED, "rx oversized"},
1855 + {DPMAC_CNT_ING_VALID_PAUSE_FRAME, "rx pause"},
1856 + {DPMAC_CNT_ING_BYTE, "rx bytes"},
1857 + {DPMAC_CNT_ENG_GOOD_FRAME, "tx frames ok"},
1858 + {DPMAC_CNT_EGR_UCAST_FRAME, "tx u-cast"},
1859 + {DPMAC_CNT_EGR_MCAST_FRAME, "tx m-cast"},
1860 + {DPMAC_CNT_EGR_BCAST_FRAME, "tx b-cast"},
1861 + {DPMAC_CNT_EGR_ERR_FRAME, "tx frame errors"},
1862 + {DPMAC_CNT_EGR_UNDERSIZED, "tx undersized"},
1863 + {DPMAC_CNT_EGR_VALID_PAUSE_FRAME, "tx b-pause"},
1864 + {DPMAC_CNT_EGR_BYTE, "tx bytes"},
1865 +
1866 +};
1867 +
1868 +static void dpaa2_mac_get_strings(struct net_device *netdev,
1869 + u32 stringset, u8 *data)
1870 +{
1871 + int i;
1872 +
1873 + switch (stringset) {
1874 + case ETH_SS_STATS:
1875 + for (i = 0; i < ARRAY_SIZE(dpaa2_mac_counters); i++)
1876 + memcpy(data + i * ETH_GSTRING_LEN,
1877 + dpaa2_mac_counters[i].name,
1878 + ETH_GSTRING_LEN);
1879 + break;
1880 + }
1881 +}
1882 +
1883 +static void dpaa2_mac_get_ethtool_stats(struct net_device *netdev,
1884 + struct ethtool_stats *stats,
1885 + u64 *data)
1886 +{
1887 + struct dpaa2_mac_priv *priv = netdev_priv(netdev);
1888 + int i;
1889 + int err;
1890 +
1891 + for (i = 0; i < ARRAY_SIZE(dpaa2_mac_counters); i++) {
1892 + err = dpmac_get_counter(priv->mc_dev->mc_io,
1893 + 0,
1894 + priv->mc_dev->mc_handle,
1895 + dpaa2_mac_counters[i].id, &data[i]);
1896 + if (err)
1897 + netdev_err(netdev, "dpmac_get_counter[%s] err %d\n",
1898 + dpaa2_mac_counters[i].name, err);
1899 + }
1900 +}
1901 +
1902 +static int dpaa2_mac_get_sset_count(struct net_device *dev, int sset)
1903 +{
1904 + switch (sset) {
1905 + case ETH_SS_STATS:
1906 + return ARRAY_SIZE(dpaa2_mac_counters);
1907 + default:
1908 + return -EOPNOTSUPP;
1909 + }
1910 +}
1911 +
1912 +static const struct net_device_ops dpaa2_mac_ndo_ops = {
1913 + .ndo_start_xmit = &dpaa2_mac_drop_frame,
1914 + .ndo_open = &dpaa2_mac_open,
1915 + .ndo_stop = &dpaa2_mac_stop,
1916 + .ndo_get_stats64 = &dpaa2_mac_get_stats,
1917 +};
1918 +
1919 +static const struct ethtool_ops dpaa2_mac_ethtool_ops = {
1920 + .get_settings = &dpaa2_mac_get_settings,
1921 + .set_settings = &dpaa2_mac_set_settings,
1922 + .get_strings = &dpaa2_mac_get_strings,
1923 + .get_ethtool_stats = &dpaa2_mac_get_ethtool_stats,
1924 + .get_sset_count = &dpaa2_mac_get_sset_count,
1925 +};
1926 +#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
1927 +
1928 +static int configure_link(struct dpaa2_mac_priv *priv,
1929 + struct dpmac_link_cfg *cfg)
1930 +{
1931 + struct phy_device *phydev = priv->netdev->phydev;
1932 +
1933 + if (!phydev) {
1934 + dev_warn(priv->netdev->dev.parent,
1935 + "asked to change PHY settings but PHY ref is NULL, ignoring\n");
1936 + return 0;
1937 + }
1938 +
1939 + phydev->speed = cfg->rate;
1940 + phydev->duplex = !!(cfg->options & DPMAC_LINK_OPT_HALF_DUPLEX);
1941 +
1942 + if (cfg->options & DPMAC_LINK_OPT_AUTONEG) {
1943 + phydev->autoneg = 1;
1944 + phydev->advertising |= ADVERTISED_Autoneg;
1945 + } else {
1946 + phydev->autoneg = 0;
1947 + phydev->advertising &= ~ADVERTISED_Autoneg;
1948 + }
1949 +
1950 + phy_start_aneg(phydev);
1951 +
1952 + return 0;
1953 +}
1954 +
1955 +static irqreturn_t dpaa2_mac_irq_handler(int irq_num, void *arg)
1956 +{
1957 + struct device *dev = (struct device *)arg;
1958 + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
1959 + struct dpaa2_mac_priv *priv = dev_get_drvdata(dev);
1960 + struct dpmac_link_cfg link_cfg;
1961 + u8 irq_index = DPMAC_IRQ_INDEX;
1962 + u32 status, clear = 0;
1963 + int err;
1964 +
1965 + if (mc_dev->irqs[0]->msi_desc->irq != irq_num) {
1966 + dev_err(dev, "received unexpected interrupt %d!\n", irq_num);
1967 + goto err;
1968 + }
1969 +
1970 + err = dpmac_get_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
1971 + irq_index, &status);
1972 + if (err) {
1973 + dev_err(dev, "dpmac_get_irq_status err %d\n", err);
1974 + clear = ~0x0u;
1975 + goto out;
1976 + }
1977 +
1978 + /* DPNI-initiated link configuration; 'ifconfig up' also calls this */
1979 + if (status & DPMAC_IRQ_EVENT_LINK_CFG_REQ) {
1980 + dev_dbg(dev, "DPMAC IRQ %d - LINK_CFG_REQ\n", irq_num);
1981 + clear |= DPMAC_IRQ_EVENT_LINK_CFG_REQ;
1982 +
1983 + err = dpmac_get_link_cfg(mc_dev->mc_io, 0, mc_dev->mc_handle,
1984 + &link_cfg);
1985 + if (err) {
1986 + dev_err(dev, "dpmac_get_link_cfg err %d\n", err);
1987 + goto out;
1988 + }
1989 +
1990 + err = configure_link(priv, &link_cfg);
1991 + if (err) {
1992 + dev_err(dev, "cannot configure link\n");
1993 + goto out;
1994 + }
1995 + }
1996 +
1997 +out:
1998 + err = dpmac_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
1999 + irq_index, clear);
2000 + if (err < 0)
2001 + dev_err(&mc_dev->dev, "dpmac_clear_irq_status() err %d\n", err);
2002 +
2003 + return IRQ_HANDLED;
2004 +
2005 +err:
2006 + dev_warn(dev, "DPMAC IRQ %d was not handled!\n", irq_num);
2007 + return IRQ_NONE;
2008 +}
2009 +
2010 +static int setup_irqs(struct fsl_mc_device *mc_dev)
2011 +{
2012 + int err;
2013 +
2014 + err = fsl_mc_allocate_irqs(mc_dev);
2015 + if (err) {
2016 + dev_err(&mc_dev->dev, "fsl_mc_allocate_irqs err %d\n", err);
2017 + return err;
2018 + }
2019 +
2020 + err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
2021 + DPMAC_IRQ_INDEX, dpmac_irq_mask);
2022 + if (err < 0) {
2023 + dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
2024 + goto free_irq;
2025 + }
2026 + err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
2027 + DPMAC_IRQ_INDEX, 0);
2028 + if (err) {
2029 + dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
2030 + goto free_irq;
2031 + }
2032 +
2033 + err = devm_request_threaded_irq(&mc_dev->dev,
2034 + mc_dev->irqs[0]->msi_desc->irq,
2035 + NULL, &dpaa2_mac_irq_handler,
2036 + IRQF_NO_SUSPEND | IRQF_ONESHOT,
2037 + dev_name(&mc_dev->dev), &mc_dev->dev);
2038 + if (err) {
2039 + dev_err(&mc_dev->dev, "devm_request_threaded_irq err %d\n",
2040 + err);
2041 + goto free_irq;
2042 + }
2043 +
2044 + err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
2045 + DPMAC_IRQ_INDEX, dpmac_irq_mask);
2046 + if (err < 0) {
2047 + dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
2048 + goto free_irq;
2049 + }
2050 + err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
2051 + DPMAC_IRQ_INDEX, 1);
2052 + if (err) {
2053 + dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
2054 + goto unregister_irq;
2055 + }
2056 +
2057 + return 0;
2058 +
2059 +unregister_irq:
2060 + devm_free_irq(&mc_dev->dev, mc_dev->irqs[0]->msi_desc->irq, &mc_dev->dev);
2061 +free_irq:
2062 + fsl_mc_free_irqs(mc_dev);
2063 +
2064 + return err;
2065 +}
2066 +
2067 +static void teardown_irqs(struct fsl_mc_device *mc_dev)
2068 +{
2069 + int err;
2070 +
2071 + err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
2072 + DPMAC_IRQ_INDEX, dpmac_irq_mask);
2073 + if (err < 0)
2074 + dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
2075 +
2076 + err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
2077 + DPMAC_IRQ_INDEX, 0);
2078 + if (err < 0)
2079 + dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
2080 +
2081 + devm_free_irq(&mc_dev->dev, mc_dev->irqs[0]->msi_desc->irq, &mc_dev->dev);
2082 + fsl_mc_free_irqs(mc_dev);
2083 +}
2084 +
2085 +static struct device_node *lookup_node(struct device *dev, int dpmac_id)
2086 +{
2087 + struct device_node *dpmacs, *dpmac = NULL;
2088 + struct device_node *mc_node = dev->of_node;
2089 + const void *id;
2090 + int lenp;
2091 + int dpmac_id_be32 = cpu_to_be32(dpmac_id);
2092 +
2093 + dpmacs = of_find_node_by_name(mc_node, "dpmacs");
2094 + if (!dpmacs) {
2095 + dev_err(dev, "No dpmacs subnode in device-tree\n");
2096 + return NULL;
2097 + }
2098 +
2099 + while ((dpmac = of_get_next_child(dpmacs, dpmac))) {
2100 + id = of_get_property(dpmac, "reg", &lenp);
2101 + if (!id || lenp != sizeof(int)) {
2102 + dev_warn(dev, "Unsuitable reg property in dpmac node\n");
2103 + continue;
2104 + }
2105 + if (*(int *)id == dpmac_id_be32)
2106 + return dpmac;
2107 + }
2108 +
2109 + return NULL;
2110 +}
2111 +
2112 +static int check_dpmac_version(struct dpaa2_mac_priv *priv)
2113 +{
2114 + struct device *dev = &priv->mc_dev->dev;
2115 + int mc_version = priv->attr.version.major;
2116 +
2117 + /* Check that the FLIB-defined version matches the one reported by MC */
2118 + if (mc_version != DPMAC_VER_MAJOR) {
2119 + dev_err(dev, "DPMAC FLIB version mismatch: MC says %d, we have %d\n",
2120 + mc_version, DPMAC_VER_MAJOR);
2121 + return -EINVAL;
2122 + }
2123 +
2124 + /* ... and that we actually support it */
2125 + if (mc_version < DPAA2_SUPPORTED_DPMAC_VERSION) {
2126 + dev_err(dev, "Unsupported DPMAC FLIB version (%d)\n",
2127 + mc_version);
2128 + return -EINVAL;
2129 + }
2130 +
2131 + dev_dbg(dev, "Using DPMAC FLIB version %d\n", mc_version);
2132 +
2133 + return 0;
2134 +}
2135 +
2136 +static int dpaa2_mac_probe(struct fsl_mc_device *mc_dev)
2137 +{
2138 + struct device *dev;
2139 + struct dpaa2_mac_priv *priv = NULL;
2140 + struct device_node *phy_node, *dpmac_node;
2141 + struct net_device *netdev;
2142 + phy_interface_t if_mode;
2143 + int err = 0;
2144 +
2145 + /* just being completely paranoid */
2146 + if (!mc_dev)
2147 + return -EFAULT;
2148 + dev = &mc_dev->dev;
2149 +
2150 + /* prepare a net_dev structure to make the phy lib API happy */
2151 + netdev = alloc_etherdev(sizeof(*priv));
2152 + if (!netdev) {
2153 + dev_err(dev, "alloc_etherdev error\n");
2154 + err = -ENOMEM;
2155 + goto err_exit;
2156 + }
2157 + priv = netdev_priv(netdev);
2158 + priv->mc_dev = mc_dev;
2159 + priv->netdev = netdev;
2160 +
2161 + SET_NETDEV_DEV(netdev, dev);
2162 + snprintf(netdev->name, IFNAMSIZ, "mac%d", mc_dev->obj_desc.id);
2163 +
2164 + dev_set_drvdata(dev, priv);
2165 +
2166 + err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io);
2167 + if (err || !mc_dev->mc_io) {
2168 + dev_err(dev, "fsl_mc_portal_allocate error: %d\n", err);
2169 + err = -ENODEV;
2170 + goto err_free_netdev;
2171 + }
2172 +
2173 + err = dpmac_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
2174 + &mc_dev->mc_handle);
2175 + if (err || !mc_dev->mc_handle) {
2176 + dev_err(dev, "dpmac_open error: %d\n", err);
2177 + err = -ENODEV;
2178 + goto err_free_mcp;
2179 + }
2180 +
2181 + err = dpmac_get_attributes(mc_dev->mc_io, 0,
2182 + mc_dev->mc_handle, &priv->attr);
2183 + if (err) {
2184 + dev_err(dev, "dpmac_get_attributes err %d\n", err);
2185 + err = -EINVAL;
2186 + goto err_close;
2187 + }
2188 +
2189 + err = check_dpmac_version(priv);
2190 + if (err)
2191 + goto err_close;
2192 +
2193 + /* Look up the DPMAC node in the device-tree. */
2194 + dpmac_node = lookup_node(dev, priv->attr.id);
2195 + if (!dpmac_node) {
2196 + dev_err(dev, "No dpmac@%d subnode found.\n", priv->attr.id);
2197 + err = -ENODEV;
2198 + goto err_close;
2199 + }
2200 +
2201 + err = setup_irqs(mc_dev);
2202 + if (err) {
2203 + err = -EFAULT;
2204 + goto err_close;
2205 + }
2206 +
2207 +#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
2208 + /* OPTIONAL, register netdev just to make it visible to the user */
2209 + netdev->netdev_ops = &dpaa2_mac_ndo_ops;
2210 + netdev->ethtool_ops = &dpaa2_mac_ethtool_ops;
2211 +
2212 + /* phy starts up enabled so netdev should be up too */
2213 + netdev->flags |= IFF_UP;
2214 +
2215 + err = register_netdev(priv->netdev);
2216 + if (err < 0) {
2217 + dev_err(dev, "register_netdev error %d\n", err);
2218 + err = -ENODEV;
2219 + goto err_free_irq;
2220 + }
2221 +#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
2222 +
2223 + /* probe the PHY as a fixed-link if the link type declared in DPC
2224 + * explicitly mandates this
2225 + */
2226 + if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED)
2227 + goto probe_fixed_link;
2228 +
2229 + if (priv->attr.eth_if < ARRAY_SIZE(dpaa2_mac_iface_mode)) {
2230 + if_mode = dpaa2_mac_iface_mode[priv->attr.eth_if];
2231 + dev_dbg(dev, "\tusing if mode %s for eth_if %d\n",
2232 + phy_modes(if_mode), priv->attr.eth_if);
2233 + } else {
2234 + dev_warn(dev, "Unexpected interface mode %d, will probe as fixed link\n",
2235 + priv->attr.eth_if);
2236 + goto probe_fixed_link;
2237 + }
2238 +
2239 + /* try to connect to the PHY */
2240 + phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0);
2241 + if (!phy_node) {
2242 + if (!phy_node) {
2243 + dev_err(dev, "dpmac node has no phy-handle property\n");
2244 + err = -ENODEV;
2245 + goto err_no_phy;
2246 + }
2247 + }
2248 + netdev->phydev = of_phy_connect(netdev, phy_node,
2249 + &dpaa2_mac_link_changed, 0, if_mode);
2250 + if (!netdev->phydev) {
2251 + /* No need for dev_err(); the kernel's loud enough as it is. */
2252 + dev_dbg(dev, "Can't of_phy_connect() now.\n");
2253 + /* We might be waiting for the MDIO MUX to probe, so defer
2254 + * our own probing.
2255 + */
2256 + err = -EPROBE_DEFER;
2257 + goto err_defer;
2258 + }
2259 + dev_info(dev, "Connected to %s PHY.\n", phy_modes(if_mode));
2260 +
2261 +probe_fixed_link:
2262 + if (!netdev->phydev) {
2263 + struct fixed_phy_status status = {
2264 + .link = 1,
2265 + /* fixed-phys don't support 10Gbps speed for now */
2266 + .speed = 1000,
2267 + .duplex = 1,
2268 + };
2269 +
2270 + /* try to register a fixed link phy */
2271 + netdev->phydev = fixed_phy_register(PHY_POLL, &status, -1, NULL);
2272 + if (!netdev->phydev || IS_ERR(netdev->phydev)) {
2273 + dev_err(dev, "error trying to register fixed PHY\n");
2274 + /* So we don't crash unregister_netdev() later on */
2275 + netdev->phydev = NULL;
2276 + err = -EFAULT;
2277 + goto err_no_phy;
2278 + }
2279 + dev_info(dev, "Registered fixed PHY.\n");
2280 + }
2281 +
2282 + /* start PHY state machine */
2283 +#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
2284 + dpaa2_mac_open(netdev);
2285 +#else /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
2286 + phy_start(netdev->phydev);
2287 +#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
2288 + return 0;
2289 +
2290 +err_defer:
2291 +err_no_phy:
2292 +#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
2293 + unregister_netdev(netdev);
2294 +err_free_irq:
2295 +#endif
2296 + teardown_irqs(mc_dev);
2297 +err_close:
2298 + dpmac_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
2299 +err_free_mcp:
2300 + fsl_mc_portal_free(mc_dev->mc_io);
2301 +err_free_netdev:
2302 + free_netdev(netdev);
2303 +err_exit:
2304 + return err;
2305 +}
2306 +
2307 +static int dpaa2_mac_remove(struct fsl_mc_device *mc_dev)
2308 +{
2309 + struct device *dev = &mc_dev->dev;
2310 + struct dpaa2_mac_priv *priv = dev_get_drvdata(dev);
2311 +
2312 + unregister_netdev(priv->netdev);
2313 + teardown_irqs(priv->mc_dev);
2314 + dpmac_close(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle);
2315 + fsl_mc_portal_free(priv->mc_dev->mc_io);
2316 + free_netdev(priv->netdev);
2317 +
2318 + dev_set_drvdata(dev, NULL);
2319 + kfree(priv);
2320 +
2321 + return 0;
2322 +}
2323 +
2324 +static const struct fsl_mc_device_match_id dpaa2_mac_match_id_table[] = {
2325 + {
2326 + .vendor = FSL_MC_VENDOR_FREESCALE,
2327 + .obj_type = "dpmac",
2328 + .ver_major = DPMAC_VER_MAJOR,
2329 + .ver_minor = DPMAC_VER_MINOR,
2330 + },
2331 + {}
2332 +};
2333 +
2334 +static struct fsl_mc_driver dpaa2_mac_drv = {
2335 + .driver = {
2336 + .name = KBUILD_MODNAME,
2337 + .owner = THIS_MODULE,
2338 + },
2339 + .probe = dpaa2_mac_probe,
2340 + .remove = dpaa2_mac_remove,
2341 + .match_id_table = dpaa2_mac_match_id_table,
2342 +};
2343 +
2344 +module_fsl_mc_driver(dpaa2_mac_drv);
2345 +
2346 +MODULE_LICENSE("GPL");
2347 +MODULE_DESCRIPTION("DPAA2 PHY proxy interface driver");