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
7 This is a commit of the cummulative, squashed dpmac patches.
8 All the commit logs are preserved below.
10 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
12 --------------------------------------------------------------
14 flib,dpmac: add dpmac files (Rebasing onto kernel 3.19, MC 0.6)
16 patches moved from 4.0 kernel
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>
22 staging: fsl-dpaa2: mac: Added MAC / PHY interface driver.
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.
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>
35 fsl-dpaa2: mac: Change IRQ flags
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>
43 fsl-dpaa2: mac: Check for actual link state change
45 Do not invoke the MC firmware if the link state hasn't changed.
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>
54 fsl-dpaa2: mac: Fix "dpmac netdevs" probing
56 Fixup code under DPAA2_MAC_NETDEVS to probe again. In particular, remove
57 the temporary addition of "fixed.c" in the mac/ folder.
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>
66 flib: Remove duplicate header files
68 These files are included by the DPAA2 mac driver files.
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>
77 fsl-dpaa2: mac: Add dependency on CONFIG_FIXED_PHY
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.
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>
88 fsl-dpaa2: mac: Fix macro
90 Remove macro ending backslash.
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>
99 fsl-dpaa2: mac: migrated remaining flibs for MC fw 8.0.0
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>
105 staging: fsl-dpaa2: mac: Port to MC-0.7 Flibs
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>
113 staging: fsl-dpaa2: mac: Do programing of MSIs in devm_request_threaded_irq()
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
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>
126 fsl-dpaa2: mac: Fix driver probing
128 The DPMAC probing function was broken in many ways. This patch adds
130 - Look up PHY nodes based on the phy-handle property of the respective
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
135 - Add Kconfig dependencies on XGMAC_MDIO and MDIO_BUS_MUX_MMIOREG.
137 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
139 fsl-dpaa2: mac: Fix interrupt handling
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.
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.
149 Finally, DPMAC interrupt mask has to be explicitly specified before calling
150 dpmac_set_irq_enabled().
152 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
154 fsl-dpaa2: mac: Fix print in case device is not initialized
156 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
158 fsl-dpaa2: mac: Fix error paths at probe
160 Merge error condition checks. Add error codes to the early exit paths.
161 Fix swapped goto labels.
163 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
165 fsl-dpaa2: mac: Remove unused function prototype
167 fixed_phy_register_2() was a leftover since we had to backport fixed PHY
168 implementation on kernel v3.10.
170 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
172 fsl-dpaa2/mac: Update dpmac binary interface to v3.2
174 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
176 fsl-dpaa2: mac: Update Flib to MC 0.8.1
178 In practice, this adds a counter for "good" egress frames.
180 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
182 fsl-dpaa2: mac: Add counter for "good" egress frames
184 Now available with the 0.8.1 Flibs.
186 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
188 fsl-dpaa2: mac: Update dpmac_set_link_state() error checking
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
194 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
196 fsl-dpaa2: mac: Remove __cold attribute
198 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
200 fsl-dpaa2: mac: Check DPMAC FLIB version
202 Make sure we support the DPMAC version, otherwise abort probing
203 early on and provide an error message.
205 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
207 fsl-dpaa2: mac: Replace uintX_t with uX
209 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
211 fsl-dpaa2: mac: Fix crash on error path
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.
217 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
219 fsl-dpaa2: mac: Remove TODOs comments from the code
221 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
223 fsl-dpaa2: mac: Fix ppx_eth_iface_mode order
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.
228 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
230 fsl-dpaa2: mac: Remove forward declarations of functions
232 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
234 fsl-dpaa2: mac: Remove ppx_{err,warn,info} macros
236 Replace with their straighforward equivalents, their contexts being
239 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
241 fsl-dpaa2: mac: Use non-atomic MC portal
243 The DPMAC driver does not make MC calls from atomic contexts, so it is
244 safe to request non-atomic MC portals.
246 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
248 fsl-dpaa2: mac: Replace "ppx" prefix with "dpaa2_mac"
250 Use a similar naming convention as for the Ethernet driver,
251 replacing "ppx" with "dpaa2_mac" as prefix for functions and
254 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
256 fsl-dpaa2: mac: Remove unnecessary blank line
258 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
260 fsl-dpaa2: mac: Do not handle link change confirmation interrupt
262 The need for that interrupt is more about debugging.
264 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
266 fsl-dpaa2: mac: resolve compile issues on uprev to 4.5
268 -interrupt info in mc struct changed upstream
269 -fixed_phy_register() had new argument
271 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
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
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
296 +FREESCALE DPAA2 MAC/PHY INTERFACE DRIVER
297 +M: Alex Marginean <Alexandru.Marginean@freescale.com>
298 +L: linux-kernel@vger.kernel.org
300 +F: drivers/staging/fsl-dpaa2/mac/
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
317 obj-$(CONFIG_FSL_DPAA2_ETH) += ethernet/
318 +obj-$(CONFIG_FSL_DPAA2_MAC) += mac/
320 +++ b/drivers/staging/fsl-dpaa2/mac/Kconfig
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
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.
336 +config FSL_DPAA2_MAC_NETDEVS
337 + bool "Expose net interfaces for PHYs"
339 + depends on FSL_DPAA2_MAC
341 + Exposes macX net interfaces which allow direct control over MACs and
344 + Leave disabled if unsure.
347 +++ b/drivers/staging/fsl-dpaa2/mac/Makefile
350 +obj-$(CONFIG_FSL_DPAA2_MAC) += dpaa2-mac.o
352 +dpaa2-mac-objs := mac.o dpmac.o
355 + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
358 + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
360 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h
362 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
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.
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
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.
393 +#ifndef _FSL_DPMAC_CMD_H
394 +#define _FSL_DPMAC_CMD_H
397 +#define DPMAC_VER_MAJOR 3
398 +#define DPMAC_VER_MINOR 2
401 +#define DPMAC_CMDID_CLOSE 0x800
402 +#define DPMAC_CMDID_OPEN 0x80c
403 +#define DPMAC_CMDID_CREATE 0x90c
404 +#define DPMAC_CMDID_DESTROY 0x900
406 +#define DPMAC_CMDID_GET_ATTR 0x004
407 +#define DPMAC_CMDID_RESET 0x005
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
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
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)
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)
432 +/* cmd, param, offset, width, type, arg_name */
433 +#define DPMAC_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
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); \
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)
445 +/* cmd, param, offset, width, type, arg_name */
446 +#define DPMAC_RSP_GET_IRQ(cmd, type, irq_cfg) \
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); \
454 +/* cmd, param, offset, width, type, arg_name */
455 +#define DPMAC_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \
457 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, en); \
458 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
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)
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)
469 +/* cmd, param, offset, width, type, arg_name */
470 +#define DPMAC_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
472 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask);\
473 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
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)
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)
484 +/* cmd, param, offset, width, type, arg_name */
485 +#define DPMAC_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
487 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
488 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
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)
495 +/* cmd, param, offset, width, type, arg_name */
496 +#define DPMAC_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
498 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
499 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
502 +/* cmd, param, offset, width, type, arg_name */
503 +#define DPMAC_RSP_GET_ATTRIBUTES(cmd, attr) \
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);\
514 +/* cmd, param, offset, width, type, arg_name */
515 +#define DPMAC_CMD_MDIO_READ(cmd, cfg) \
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); \
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)
525 +/* cmd, param, offset, width, type, arg_name */
526 +#define DPMAC_CMD_MDIO_WRITE(cmd, cfg) \
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); \
533 +/* cmd, param, offset, width, type, arg_name */
534 +#define DPMAC_RSP_GET_LINK_CFG(cmd, cfg) \
536 + MC_RSP_OP(cmd, 0, 0, 64, uint64_t, cfg->options); \
537 + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, cfg->rate); \
540 +/* cmd, param, offset, width, type, arg_name */
541 +#define DPMAC_CMD_SET_LINK_STATE(cmd, cfg) \
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); \
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)
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)
556 +#endif /* _FSL_DPMAC_CMD_H */
558 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c
560 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
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.
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
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.
591 +#include "../../fsl-mc/include/mc-sys.h"
592 +#include "../../fsl-mc/include/mc-cmd.h"
594 +#include "dpmac-cmd.h"
596 +int dpmac_open(struct fsl_mc_io *mc_io,
597 + uint32_t cmd_flags,
601 + struct mc_command cmd = { 0 };
604 + /* prepare command */
605 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_OPEN,
608 + DPMAC_CMD_OPEN(cmd, dpmac_id);
610 + /* send command to mc*/
611 + err = mc_send_command(mc_io, &cmd);
615 + /* retrieve response parameters */
616 + *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
621 +int dpmac_close(struct fsl_mc_io *mc_io,
622 + uint32_t cmd_flags,
625 + struct mc_command cmd = { 0 };
627 + /* prepare command */
628 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags,
631 + /* send command to mc*/
632 + return mc_send_command(mc_io, &cmd);
635 +int dpmac_create(struct fsl_mc_io *mc_io,
636 + uint32_t cmd_flags,
637 + const struct dpmac_cfg *cfg,
640 + struct mc_command cmd = { 0 };
643 + /* prepare command */
644 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CREATE,
647 + DPMAC_CMD_CREATE(cmd, cfg);
649 + /* send command to mc*/
650 + err = mc_send_command(mc_io, &cmd);
654 + /* retrieve response parameters */
655 + *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
660 +int dpmac_destroy(struct fsl_mc_io *mc_io,
661 + uint32_t cmd_flags,
664 + struct mc_command cmd = { 0 };
666 + /* prepare command */
667 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_DESTROY,
671 + /* send command to mc*/
672 + return mc_send_command(mc_io, &cmd);
675 +int dpmac_set_irq(struct fsl_mc_io *mc_io,
676 + uint32_t cmd_flags,
679 + struct dpmac_irq_cfg *irq_cfg)
681 + struct mc_command cmd = { 0 };
683 + /* prepare command */
684 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ,
687 + DPMAC_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
689 + /* send command to mc*/
690 + return mc_send_command(mc_io, &cmd);
693 +int dpmac_get_irq(struct fsl_mc_io *mc_io,
694 + uint32_t cmd_flags,
698 + struct dpmac_irq_cfg *irq_cfg)
700 + struct mc_command cmd = { 0 };
703 + /* prepare command */
704 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ,
707 + DPMAC_CMD_GET_IRQ(cmd, irq_index);
709 + /* send command to mc*/
710 + err = mc_send_command(mc_io, &cmd);
714 + /* retrieve response parameters */
715 + DPMAC_RSP_GET_IRQ(cmd, *type, irq_cfg);
720 +int dpmac_set_irq_enable(struct fsl_mc_io *mc_io,
721 + uint32_t cmd_flags,
726 + struct mc_command cmd = { 0 };
728 + /* prepare command */
729 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_ENABLE,
732 + DPMAC_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
734 + /* send command to mc*/
735 + return mc_send_command(mc_io, &cmd);
738 +int dpmac_get_irq_enable(struct fsl_mc_io *mc_io,
739 + uint32_t cmd_flags,
744 + struct mc_command cmd = { 0 };
747 + /* prepare command */
748 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_ENABLE,
751 + DPMAC_CMD_GET_IRQ_ENABLE(cmd, irq_index);
753 + /* send command to mc*/
754 + err = mc_send_command(mc_io, &cmd);
758 + /* retrieve response parameters */
759 + DPMAC_RSP_GET_IRQ_ENABLE(cmd, *en);
764 +int dpmac_set_irq_mask(struct fsl_mc_io *mc_io,
765 + uint32_t cmd_flags,
770 + struct mc_command cmd = { 0 };
772 + /* prepare command */
773 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_MASK,
776 + DPMAC_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
778 + /* send command to mc*/
779 + return mc_send_command(mc_io, &cmd);
782 +int dpmac_get_irq_mask(struct fsl_mc_io *mc_io,
783 + uint32_t cmd_flags,
788 + struct mc_command cmd = { 0 };
791 + /* prepare command */
792 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_MASK,
795 + DPMAC_CMD_GET_IRQ_MASK(cmd, irq_index);
797 + /* send command to mc*/
798 + err = mc_send_command(mc_io, &cmd);
802 + /* retrieve response parameters */
803 + DPMAC_RSP_GET_IRQ_MASK(cmd, *mask);
808 +int dpmac_get_irq_status(struct fsl_mc_io *mc_io,
809 + uint32_t cmd_flags,
814 + struct mc_command cmd = { 0 };
817 + /* prepare command */
818 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_STATUS,
821 + DPMAC_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
823 + /* send command to mc*/
824 + err = mc_send_command(mc_io, &cmd);
828 + /* retrieve response parameters */
829 + DPMAC_RSP_GET_IRQ_STATUS(cmd, *status);
834 +int dpmac_clear_irq_status(struct fsl_mc_io *mc_io,
835 + uint32_t cmd_flags,
840 + struct mc_command cmd = { 0 };
842 + /* prepare command */
843 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLEAR_IRQ_STATUS,
846 + DPMAC_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
848 + /* send command to mc*/
849 + return mc_send_command(mc_io, &cmd);
852 +int dpmac_get_attributes(struct fsl_mc_io *mc_io,
853 + uint32_t cmd_flags,
855 + struct dpmac_attr *attr)
857 + struct mc_command cmd = { 0 };
860 + /* prepare command */
861 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_ATTR,
865 + /* send command to mc*/
866 + err = mc_send_command(mc_io, &cmd);
870 + /* retrieve response parameters */
871 + DPMAC_RSP_GET_ATTRIBUTES(cmd, attr);
876 +int dpmac_mdio_read(struct fsl_mc_io *mc_io,
877 + uint32_t cmd_flags,
879 + struct dpmac_mdio_cfg *cfg)
881 + struct mc_command cmd = { 0 };
884 + /* prepare command */
885 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_MDIO_READ,
888 + DPMAC_CMD_MDIO_READ(cmd, cfg);
890 + /* send command to mc*/
891 + err = mc_send_command(mc_io, &cmd);
895 + /* retrieve response parameters */
896 + DPMAC_RSP_MDIO_READ(cmd, cfg->data);
901 +int dpmac_mdio_write(struct fsl_mc_io *mc_io,
902 + uint32_t cmd_flags,
904 + struct dpmac_mdio_cfg *cfg)
906 + struct mc_command cmd = { 0 };
908 + /* prepare command */
909 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_MDIO_WRITE,
912 + DPMAC_CMD_MDIO_WRITE(cmd, cfg);
914 + /* send command to mc*/
915 + return mc_send_command(mc_io, &cmd);
918 +int dpmac_get_link_cfg(struct fsl_mc_io *mc_io,
919 + uint32_t cmd_flags,
921 + struct dpmac_link_cfg *cfg)
923 + struct mc_command cmd = { 0 };
926 + /* prepare command */
927 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_LINK_CFG,
931 + /* send command to mc*/
932 + err = mc_send_command(mc_io, &cmd);
936 + DPMAC_RSP_GET_LINK_CFG(cmd, cfg);
941 +int dpmac_set_link_state(struct fsl_mc_io *mc_io,
942 + uint32_t cmd_flags,
944 + struct dpmac_link_state *link_state)
946 + struct mc_command cmd = { 0 };
948 + /* prepare command */
949 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE,
952 + DPMAC_CMD_SET_LINK_STATE(cmd, link_state);
954 + /* send command to mc*/
955 + return mc_send_command(mc_io, &cmd);
958 +int dpmac_get_counter(struct fsl_mc_io *mc_io,
959 + uint32_t cmd_flags,
961 + enum dpmac_counter type,
964 + struct mc_command cmd = { 0 };
967 + /* prepare command */
968 + cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_COUNTER,
971 + DPMAC_CMD_GET_COUNTER(cmd, type);
973 + /* send command to mc*/
974 + err = mc_send_command(mc_io, &cmd);
978 + DPMAC_RSP_GET_COUNTER(cmd, *counter);
983 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac.h
985 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
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.
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
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.
1016 +#ifndef __FSL_DPMAC_H
1017 +#define __FSL_DPMAC_H
1019 +/* Data Path MAC API
1020 + * Contains initialization APIs and runtime control APIs for DPMAC
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
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
1040 + * Return: '0' on Success; Error code otherwise.
1042 +int dpmac_open(struct fsl_mc_io *mc_io,
1043 + uint32_t cmd_flags,
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
1053 + * After this function is called, no further operations are
1054 + * allowed on the object without opening a new control session.
1056 + * Return: '0' on Success; Error code otherwise.
1058 +int dpmac_close(struct fsl_mc_io *mc_io,
1059 + uint32_t cmd_flags,
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
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
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
1088 +enum dpmac_eth_if {
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,
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.
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
1119 + * Create the DPMAC object, allocate required resources and
1120 + * perform required initialization.
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
1131 + * Return: '0' on Success; Error code otherwise.
1133 +int dpmac_create(struct fsl_mc_io *mc_io,
1134 + uint32_t cmd_flags,
1135 + const struct dpmac_cfg *cfg,
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
1144 + * Return: '0' on Success; error code otherwise.
1146 +int dpmac_destroy(struct fsl_mc_io *mc_io,
1147 + uint32_t cmd_flags,
1151 + * DPMAC IRQ Index and Events
1157 +#define DPMAC_IRQ_INDEX 0
1159 + * IRQ event - indicates a change in link state
1161 +#define DPMAC_IRQ_EVENT_LINK_CFG_REQ 0x00000001
1163 + * IRQ event - Indicates that the link state changed
1165 +#define DPMAC_IRQ_EVENT_LINK_CHANGED 0x00000002
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
1173 +struct dpmac_irq_cfg {
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
1187 + * Return: '0' on Success; Error code otherwise.
1189 +int dpmac_set_irq(struct fsl_mc_io *mc_io,
1190 + uint32_t cmd_flags,
1192 + uint8_t irq_index,
1193 + struct dpmac_irq_cfg *irq_cfg);
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
1205 + * Return: '0' on Success; Error code otherwise.
1207 +int dpmac_get_irq(struct fsl_mc_io *mc_io,
1208 + uint32_t cmd_flags,
1210 + uint8_t irq_index,
1212 + struct dpmac_irq_cfg *irq_cfg);
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
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
1227 + * Return: '0' on Success; Error code otherwise.
1229 +int dpmac_set_irq_enable(struct fsl_mc_io *mc_io,
1230 + uint32_t cmd_flags,
1232 + uint8_t irq_index,
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
1243 + * Return: '0' on Success; Error code otherwise.
1245 +int dpmac_get_irq_enable(struct fsl_mc_io *mc_io,
1246 + uint32_t cmd_flags,
1248 + uint8_t irq_index,
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;
1259 + * 0 = ignore event
1260 + * 1 = consider event for asserting IRQ
1262 + * Every interrupt can have up to 32 causes and the interrupt model supports
1263 + * masking/unmasking each cause independently
1265 + * Return: '0' on Success; Error code otherwise.
1267 +int dpmac_set_irq_mask(struct fsl_mc_io *mc_io,
1268 + uint32_t cmd_flags,
1270 + uint8_t irq_index,
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
1281 + * Every interrupt can have up to 32 causes and the interrupt model supports
1282 + * masking/unmasking each cause independently
1284 + * Return: '0' on Success; Error code otherwise.
1286 +int dpmac_get_irq_mask(struct fsl_mc_io *mc_io,
1287 + uint32_t cmd_flags,
1289 + uint8_t irq_index,
1293 + * dpmac_get_irq_status() - Get the current status of any pending interrupts.
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
1303 + * Return: '0' on Success; Error code otherwise.
1305 +int dpmac_get_irq_status(struct fsl_mc_io *mc_io,
1306 + uint32_t cmd_flags,
1308 + uint8_t irq_index,
1309 + uint32_t *status);
1312 + * dpmac_clear_irq_status() - Clear a pending interrupt's status
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
1322 + * Return: '0' on Success; Error code otherwise.
1324 +int dpmac_clear_irq_status(struct fsl_mc_io *mc_io,
1325 + uint32_t cmd_flags,
1327 + uint8_t irq_index,
1331 + * struct dpmac_attr - Structure representing DPMAC attributes
1332 + * @id: DPMAC object ID
1334 + * @link_type: link type
1335 + * @eth_if: Ethernet interface
1336 + * @max_rate: Maximum supported rate - in Mbps
1337 + * @version: DPMAC version
1339 +struct dpmac_attr {
1342 + enum dpmac_link_type link_type;
1343 + enum dpmac_eth_if eth_if;
1344 + uint32_t max_rate;
1346 + * struct version - Structure representing DPMAC version
1347 + * @major: DPMAC major version
1348 + * @minor: DPMAC minor version
1357 + * dpmac_get_attributes - Retrieve DPMAC attributes.
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
1364 + * Return: '0' on Success; Error code otherwise.
1366 +int dpmac_get_attributes(struct fsl_mc_io *mc_io,
1367 + uint32_t cmd_flags,
1369 + struct dpmac_attr *attr);
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
1376 + * @data: Data read/write from/to MDIO
1378 +struct dpmac_mdio_cfg {
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
1391 + * Return: '0' on Success; Error code otherwise.
1393 +int dpmac_mdio_read(struct fsl_mc_io *mc_io,
1394 + uint32_t cmd_flags,
1396 + struct dpmac_mdio_cfg *cfg);
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
1405 + * Return: '0' on Success; Error code otherwise.
1407 +int dpmac_mdio_write(struct fsl_mc_io *mc_io,
1408 + uint32_t cmd_flags,
1410 + struct dpmac_mdio_cfg *cfg);
1413 + * DPMAC link configuration/state options
1417 + * Enable auto-negotiation
1419 +#define DPMAC_LINK_OPT_AUTONEG 0x0000000000000001ULL
1421 + * Enable half-duplex mode
1423 +#define DPMAC_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
1425 + * Enable pause frames
1427 +#define DPMAC_LINK_OPT_PAUSE 0x0000000000000004ULL
1429 + * Enable a-symmetric pause frames
1431 +#define DPMAC_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
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)
1438 +struct dpmac_link_cfg {
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
1450 + * Return: '0' on Success; Error code otherwise.
1452 +int dpmac_get_link_cfg(struct fsl_mc_io *mc_io,
1453 + uint32_t cmd_flags,
1455 + struct dpmac_link_cfg *cfg);
1458 + * struct dpmac_link_state - DPMAC link configuration request
1459 + * @rate: Rate in Mbps
1460 + * @options: Enable/Disable DPMAC link cfg features (bitmap)
1463 +struct dpmac_link_state {
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
1476 + * Return: '0' on Success; Error code otherwise.
1478 +int dpmac_set_link_state(struct fsl_mc_io *mc_io,
1479 + uint32_t cmd_flags,
1481 + struct dpmac_link_state *link_state);
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),
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
1527 + * @DPMAC_CNT_ENG_GOOD_FRAME: counts frames transmitted without error, including
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
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
1569 + * Return: The requested counter; '0' otherwise.
1571 +int dpmac_get_counter(struct fsl_mc_io *mc_io,
1572 + uint32_t cmd_flags,
1574 + enum dpmac_counter type,
1575 + uint64_t *counter);
1577 +#endif /* __FSL_DPMAC_H */
1579 +++ b/drivers/staging/fsl-dpaa2/mac/mac.c
1581 +/* Copyright 2015 Freescale Semiconductor Inc.
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.
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
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.
1612 +#include <linux/module.h>
1614 +#include <linux/netdevice.h>
1615 +#include <linux/etherdevice.h>
1616 +#include <linux/rtnetlink.h>
1617 +#include <linux/if_vlan.h>
1619 +#include <uapi/linux/if_bridge.h>
1620 +#include <net/netlink.h>
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>
1630 +#include "../../fsl-mc/include/mc.h"
1631 +#include "../../fsl-mc/include/mc-sys.h"
1634 +#include "dpmac-cmd.h"
1636 +#define DPAA2_SUPPORTED_DPMAC_VERSION 3
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;
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...
1651 + * This must be kept in sync with enum dpmac_eth_if.
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,
1674 +static void dpaa2_mac_link_changed(struct net_device *netdev)
1676 + struct phy_device *phydev;
1677 + struct dpmac_link_state state = { 0 };
1678 + struct dpaa2_mac_priv *priv = netdev_priv(netdev);
1681 + /* the PHY just notified us of link state change */
1682 + phydev = netdev->phydev;
1684 + state.up = !!phydev->link;
1685 + if (phydev->link) {
1686 + state.rate = phydev->speed;
1688 + if (!phydev->duplex)
1689 + state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
1690 + if (phydev->autoneg)
1691 + state.options |= DPMAC_LINK_OPT_AUTONEG;
1693 + netif_carrier_on(netdev);
1695 + netif_carrier_off(netdev);
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);
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.
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);
1714 +/* IRQ bits that we handle */
1715 +static const u32 dpmac_irq_mask = DPMAC_IRQ_EVENT_LINK_CFG_REQ;
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)
1721 + /* we don't support I/O for now, drop the frame */
1722 + dev_kfree_skb_any(skb);
1723 + return NETDEV_TX_OK;
1726 +static int dpaa2_mac_open(struct net_device *netdev)
1728 + /* start PHY state machine */
1729 + phy_start(netdev->phydev);
1734 +static int dpaa2_mac_stop(struct net_device *netdev)
1736 + if (!netdev->phydev)
1739 + /* stop PHY state machine */
1740 + phy_stop(netdev->phydev);
1742 + /* signal link down to firmware */
1743 + netdev->phydev->link = 0;
1744 + dpaa2_mac_link_changed(netdev);
1750 +static int dpaa2_mac_get_settings(struct net_device *netdev,
1751 + struct ethtool_cmd *cmd)
1753 + return phy_ethtool_gset(netdev->phydev, cmd);
1756 +static int dpaa2_mac_set_settings(struct net_device *netdev,
1757 + struct ethtool_cmd *cmd)
1759 + return phy_ethtool_sset(netdev->phydev, cmd);
1762 +static struct rtnl_link_stats64
1763 +*dpaa2_mac_get_stats(struct net_device *netdev,
1764 + struct rtnl_link_stats64 *storage)
1766 + struct dpaa2_mac_priv *priv = netdev_priv(netdev);
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);
1775 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1776 + DPMAC_CNT_EGR_BCAST_FRAME, &tmp);
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);
1784 + storage->tx_packets += tmp;
1786 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1787 + DPMAC_CNT_EGR_UNDERSIZED, &storage->tx_dropped);
1790 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1791 + DPMAC_CNT_EGR_BYTE, &storage->tx_bytes);
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);
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);
1803 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1804 + DPMAC_CNT_ING_MCAST_FRAME, &storage->multicast);
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);
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);
1816 + err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle,
1817 + DPMAC_CNT_ING_OVERSIZED, &tmp);
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);
1829 + netdev_err(netdev, "dpmac_get_counter err %d\n", err);
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"},
1868 +static void dpaa2_mac_get_strings(struct net_device *netdev,
1869 + u32 stringset, u8 *data)
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,
1883 +static void dpaa2_mac_get_ethtool_stats(struct net_device *netdev,
1884 + struct ethtool_stats *stats,
1887 + struct dpaa2_mac_priv *priv = netdev_priv(netdev);
1891 + for (i = 0; i < ARRAY_SIZE(dpaa2_mac_counters); i++) {
1892 + err = dpmac_get_counter(priv->mc_dev->mc_io,
1894 + priv->mc_dev->mc_handle,
1895 + dpaa2_mac_counters[i].id, &data[i]);
1897 + netdev_err(netdev, "dpmac_get_counter[%s] err %d\n",
1898 + dpaa2_mac_counters[i].name, err);
1902 +static int dpaa2_mac_get_sset_count(struct net_device *dev, int sset)
1905 + case ETH_SS_STATS:
1906 + return ARRAY_SIZE(dpaa2_mac_counters);
1908 + return -EOPNOTSUPP;
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,
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,
1926 +#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
1928 +static int configure_link(struct dpaa2_mac_priv *priv,
1929 + struct dpmac_link_cfg *cfg)
1931 + struct phy_device *phydev = priv->netdev->phydev;
1934 + dev_warn(priv->netdev->dev.parent,
1935 + "asked to change PHY settings but PHY ref is NULL, ignoring\n");
1939 + phydev->speed = cfg->rate;
1940 + phydev->duplex = !!(cfg->options & DPMAC_LINK_OPT_HALF_DUPLEX);
1942 + if (cfg->options & DPMAC_LINK_OPT_AUTONEG) {
1943 + phydev->autoneg = 1;
1944 + phydev->advertising |= ADVERTISED_Autoneg;
1946 + phydev->autoneg = 0;
1947 + phydev->advertising &= ~ADVERTISED_Autoneg;
1950 + phy_start_aneg(phydev);
1955 +static irqreturn_t dpaa2_mac_irq_handler(int irq_num, void *arg)
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;
1965 + if (mc_dev->irqs[0]->msi_desc->irq != irq_num) {
1966 + dev_err(dev, "received unexpected interrupt %d!\n", irq_num);
1970 + err = dpmac_get_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
1971 + irq_index, &status);
1973 + dev_err(dev, "dpmac_get_irq_status err %d\n", err);
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;
1983 + err = dpmac_get_link_cfg(mc_dev->mc_io, 0, mc_dev->mc_handle,
1986 + dev_err(dev, "dpmac_get_link_cfg err %d\n", err);
1990 + err = configure_link(priv, &link_cfg);
1992 + dev_err(dev, "cannot configure link\n");
1998 + err = dpmac_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
1999 + irq_index, clear);
2001 + dev_err(&mc_dev->dev, "dpmac_clear_irq_status() err %d\n", err);
2003 + return IRQ_HANDLED;
2006 + dev_warn(dev, "DPMAC IRQ %d was not handled!\n", irq_num);
2010 +static int setup_irqs(struct fsl_mc_device *mc_dev)
2014 + err = fsl_mc_allocate_irqs(mc_dev);
2016 + dev_err(&mc_dev->dev, "fsl_mc_allocate_irqs err %d\n", err);
2020 + err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
2021 + DPMAC_IRQ_INDEX, dpmac_irq_mask);
2023 + dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
2026 + err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
2027 + DPMAC_IRQ_INDEX, 0);
2029 + dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
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);
2039 + dev_err(&mc_dev->dev, "devm_request_threaded_irq err %d\n",
2044 + err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
2045 + DPMAC_IRQ_INDEX, dpmac_irq_mask);
2047 + dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
2050 + err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
2051 + DPMAC_IRQ_INDEX, 1);
2053 + dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
2054 + goto unregister_irq;
2060 + devm_free_irq(&mc_dev->dev, mc_dev->irqs[0]->msi_desc->irq, &mc_dev->dev);
2062 + fsl_mc_free_irqs(mc_dev);
2067 +static void teardown_irqs(struct fsl_mc_device *mc_dev)
2071 + err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
2072 + DPMAC_IRQ_INDEX, dpmac_irq_mask);
2074 + dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
2076 + err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
2077 + DPMAC_IRQ_INDEX, 0);
2079 + dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
2081 + devm_free_irq(&mc_dev->dev, mc_dev->irqs[0]->msi_desc->irq, &mc_dev->dev);
2082 + fsl_mc_free_irqs(mc_dev);
2085 +static struct device_node *lookup_node(struct device *dev, int dpmac_id)
2087 + struct device_node *dpmacs, *dpmac = NULL;
2088 + struct device_node *mc_node = dev->of_node;
2091 + int dpmac_id_be32 = cpu_to_be32(dpmac_id);
2093 + dpmacs = of_find_node_by_name(mc_node, "dpmacs");
2095 + dev_err(dev, "No dpmacs subnode in device-tree\n");
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");
2105 + if (*(int *)id == dpmac_id_be32)
2112 +static int check_dpmac_version(struct dpaa2_mac_priv *priv)
2114 + struct device *dev = &priv->mc_dev->dev;
2115 + int mc_version = priv->attr.version.major;
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);
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",
2131 + dev_dbg(dev, "Using DPMAC FLIB version %d\n", mc_version);
2136 +static int dpaa2_mac_probe(struct fsl_mc_device *mc_dev)
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;
2145 + /* just being completely paranoid */
2148 + dev = &mc_dev->dev;
2150 + /* prepare a net_dev structure to make the phy lib API happy */
2151 + netdev = alloc_etherdev(sizeof(*priv));
2153 + dev_err(dev, "alloc_etherdev error\n");
2157 + priv = netdev_priv(netdev);
2158 + priv->mc_dev = mc_dev;
2159 + priv->netdev = netdev;
2161 + SET_NETDEV_DEV(netdev, dev);
2162 + snprintf(netdev->name, IFNAMSIZ, "mac%d", mc_dev->obj_desc.id);
2164 + dev_set_drvdata(dev, priv);
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);
2170 + goto err_free_netdev;
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);
2178 + goto err_free_mcp;
2181 + err = dpmac_get_attributes(mc_dev->mc_io, 0,
2182 + mc_dev->mc_handle, &priv->attr);
2184 + dev_err(dev, "dpmac_get_attributes err %d\n", err);
2189 + err = check_dpmac_version(priv);
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);
2201 + err = setup_irqs(mc_dev);
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;
2212 + /* phy starts up enabled so netdev should be up too */
2213 + netdev->flags |= IFF_UP;
2215 + err = register_netdev(priv->netdev);
2217 + dev_err(dev, "register_netdev error %d\n", err);
2219 + goto err_free_irq;
2221 +#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
2223 + /* probe the PHY as a fixed-link if the link type declared in DPC
2224 + * explicitly mandates this
2226 + if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED)
2227 + goto probe_fixed_link;
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);
2234 + dev_warn(dev, "Unexpected interface mode %d, will probe as fixed link\n",
2235 + priv->attr.eth_if);
2236 + goto probe_fixed_link;
2239 + /* try to connect to the PHY */
2240 + phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0);
2243 + dev_err(dev, "dpmac node has no phy-handle property\n");
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.
2256 + err = -EPROBE_DEFER;
2259 + dev_info(dev, "Connected to %s PHY.\n", phy_modes(if_mode));
2262 + if (!netdev->phydev) {
2263 + struct fixed_phy_status status = {
2265 + /* fixed-phys don't support 10Gbps speed for now */
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;
2279 + dev_info(dev, "Registered fixed PHY.\n");
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 */
2292 +#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
2293 + unregister_netdev(netdev);
2296 + teardown_irqs(mc_dev);
2298 + dpmac_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
2300 + fsl_mc_portal_free(mc_dev->mc_io);
2302 + free_netdev(netdev);
2307 +static int dpaa2_mac_remove(struct fsl_mc_device *mc_dev)
2309 + struct device *dev = &mc_dev->dev;
2310 + struct dpaa2_mac_priv *priv = dev_get_drvdata(dev);
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);
2318 + dev_set_drvdata(dev, NULL);
2324 +static const struct fsl_mc_device_match_id dpaa2_mac_match_id_table[] = {
2326 + .vendor = FSL_MC_VENDOR_FREESCALE,
2327 + .obj_type = "dpmac",
2328 + .ver_major = DPMAC_VER_MAJOR,
2329 + .ver_minor = DPMAC_VER_MINOR,
2334 +static struct fsl_mc_driver dpaa2_mac_drv = {
2336 + .name = KBUILD_MODNAME,
2337 + .owner = THIS_MODULE,
2339 + .probe = dpaa2_mac_probe,
2340 + .remove = dpaa2_mac_remove,
2341 + .match_id_table = dpaa2_mac_match_id_table,
2344 +module_fsl_mc_driver(dpaa2_mac_drv);
2346 +MODULE_LICENSE("GPL");
2347 +MODULE_DESCRIPTION("DPAA2 PHY proxy interface driver");