1 From 8df017d70c54ceafc99b7904785603c678a2e5c1 Mon Sep 17 00:00:00 2001
2 From: Razvan Stefanescu <razvan.stefanescu@freescale.com>
3 Date: Tue, 22 Sep 2015 11:36:34 +0300
4 Subject: [PATCH 220/226] dpaa2-ethsw: Ethernet Switch driver
6 This is a commit of the cummulative, squashed dpaa2-l2switch patches.
7 All the commit logs are preserved below.
9 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
11 ---------------------------------------------------------------------
13 dpaa2-ethsw: Ethernet Switch driver
15 Initial support for DPAA2 L2 switch. The switch and all ports are
16 presented as network interfaces in linux (swX and swXpY). I/O
17 functionality is not available on these interfaces, they are exclusively
20 Configuration is done using bridge tool. Supported commands are:
21 - fdb operations with unicast/multicast addresses
23 - setting STP state of ports
24 - flooding, learning control
26 Offers support for retrieving port statistics via ethtool (or similar
29 This patch contains the following patches squashed together:
30 staging: fsl-dpaa2: ethsw: ethernet switch driver
31 dpaa2-ethsw: Include by default in configuration
32 staging: fsl-dpaa2: ethsw: Rebasing onto kernel 4.0
33 staging: fsl-mc: migrated remaining flibs for MC fw 8.0.0
34 dpaa2-ethsw: Prefix driver name with dpaa2-
35 dpaa2-ethsw: Set carrier state on probe
36 dpaa2-ethsw: Add support for link state update
38 These patches were initally submitted by:
39 Alex Marginean <alexandru.marginean@freescale.com>
40 J. German Rivera <German.Rivera@freescale.com>
41 Razvan Stefanescu <razvan.stefanescu@freescale.com>
43 and reviewed by Stuart Yoder <stuart.yoder@freescale.com>
45 Ported to linux-v4.1 by updating iflink usage and ndo_bridge_getlink()
46 parameters list update.
48 Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
49 [Stuart: resolved minor merge conflicts]
50 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
52 dpaa2-ethsw: Update dpsw binary interface to 7.0
54 This corresponds to MC release 0.8.0.
56 Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
58 dpaa2-ethsw: Add object version check
60 Abort probing if DPSW object version is smaller than required.
62 Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
64 dpaa2-ethsw: Fix interrupt handling
66 Mask only the events handled by the driver - DPSW_IRQ_EVENT_LINK_CHANGED.
68 Use clear-on-read mechanism for the interrupt status and avoid calling
69 dpsw_clear_irq_status(). Status contains the events handled (only link
70 state change for the moment) and masks the first 16-bits, as they are used
71 to store the interface ID that generated the event.
73 Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
75 dpaa2-ethsw: resolve compile issues on uprev to 4.5
77 -irq_number field no longer exists in fsl-mc interrupt
79 -netdev_master_upper_dev_link() has 2 new parameters, which
80 are set to NULL for now
82 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
85 drivers/staging/fsl-dpaa2/Kconfig | 1 +
86 drivers/staging/fsl-dpaa2/Makefile | 1 +
87 drivers/staging/fsl-dpaa2/ethsw/Kconfig | 7 +
88 drivers/staging/fsl-dpaa2/ethsw/Makefile | 10 +
89 drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h | 916 ++++++++++++
90 drivers/staging/fsl-dpaa2/ethsw/dpsw.c | 1639 +++++++++++++++++++++
91 drivers/staging/fsl-dpaa2/ethsw/dpsw.h | 2164 ++++++++++++++++++++++++++++
92 drivers/staging/fsl-dpaa2/ethsw/switch.c | 1711 ++++++++++++++++++++++
93 drivers/staging/fsl-mc/include/net.h | 1 -
94 10 files changed, 6455 insertions(+), 1 deletion(-)
95 create mode 100644 drivers/staging/fsl-dpaa2/ethsw/Kconfig
96 create mode 100644 drivers/staging/fsl-dpaa2/ethsw/Makefile
97 create mode 100644 drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h
98 create mode 100644 drivers/staging/fsl-dpaa2/ethsw/dpsw.c
99 create mode 100644 drivers/staging/fsl-dpaa2/ethsw/dpsw.h
100 create mode 100644 drivers/staging/fsl-dpaa2/ethsw/switch.c
104 @@ -4554,6 +4554,12 @@ S: Maintained
105 F: drivers/staging/fsl-mc/bus/mc-ioctl.h
106 F: drivers/staging/fsl-mc/bus/mc-restool.c
108 +FREESCALE DPAA2 ETHERNET SWITCH DRIVER
109 +M: Alex Marginean <Alexandru.Marginean@freescale.com>
110 +L: linux-kernel@vger.kernel.org
112 +F: drivers/staging/fsl-dpaa2/ethsw/
114 FREESCALE DPAA2 MAC/PHY INTERFACE DRIVER
115 M: Alex Marginean <Alexandru.Marginean@freescale.com>
116 L: linux-kernel@vger.kernel.org
117 --- a/drivers/staging/fsl-dpaa2/Kconfig
118 +++ b/drivers/staging/fsl-dpaa2/Kconfig
119 @@ -11,3 +11,4 @@ config FSL_DPAA2
120 source "drivers/staging/fsl-dpaa2/ethernet/Kconfig"
121 source "drivers/staging/fsl-dpaa2/mac/Kconfig"
122 source "drivers/staging/fsl-dpaa2/evb/Kconfig"
123 +source "drivers/staging/fsl-dpaa2/ethsw/Kconfig"
124 --- a/drivers/staging/fsl-dpaa2/Makefile
125 +++ b/drivers/staging/fsl-dpaa2/Makefile
127 obj-$(CONFIG_FSL_DPAA2_ETH) += ethernet/
128 obj-$(CONFIG_FSL_DPAA2_MAC) += mac/
129 obj-$(CONFIG_FSL_DPAA2_EVB) += evb/
130 +obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/
132 +++ b/drivers/staging/fsl-dpaa2/ethsw/Kconfig
134 +config FSL_DPAA2_ETHSW
135 + tristate "DPAA2 Ethernet Switch"
136 + depends on FSL_MC_BUS && FSL_DPAA2 && FSL_DPAA2_ETH
137 + select FSL_DPAA2_MAC
140 + Prototype driver for DPAA2 Ethernet Switch.
142 +++ b/drivers/staging/fsl-dpaa2/ethsw/Makefile
145 +obj-$(CONFIG_FSL_DPAA2_ETHSW) += dpaa2-ethsw.o
147 +dpaa2-ethsw-objs := switch.o dpsw.o
150 + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
153 + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
155 +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h
157 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
159 + * Redistribution and use in source and binary forms, with or without
160 + * modification, are permitted provided that the following conditions are met:
161 + * * Redistributions of source code must retain the above copyright
162 + * notice, this list of conditions and the following disclaimer.
163 + * * Redistributions in binary form must reproduce the above copyright
164 + * notice, this list of conditions and the following disclaimer in the
165 + * documentation and/or other materials provided with the distribution.
166 + * * Neither the name of the above-listed copyright holders nor the
167 + * names of any contributors may be used to endorse or promote products
168 + * derived from this software without specific prior written permission.
171 + * ALTERNATIVELY, this software may be distributed under the terms of the
172 + * GNU General Public License ("GPL") as published by the Free Software
173 + * Foundation, either version 2 of that License or (at your option) any
176 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
177 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
178 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
179 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
180 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
181 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
182 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
183 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
184 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
185 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
186 + * POSSIBILITY OF SUCH DAMAGE.
188 +#ifndef __FSL_DPSW_CMD_H
189 +#define __FSL_DPSW_CMD_H
192 +#define DPSW_VER_MAJOR 7
193 +#define DPSW_VER_MINOR 0
196 +#define DPSW_CMDID_CLOSE 0x800
197 +#define DPSW_CMDID_OPEN 0x802
198 +#define DPSW_CMDID_CREATE 0x902
199 +#define DPSW_CMDID_DESTROY 0x900
201 +#define DPSW_CMDID_ENABLE 0x002
202 +#define DPSW_CMDID_DISABLE 0x003
203 +#define DPSW_CMDID_GET_ATTR 0x004
204 +#define DPSW_CMDID_RESET 0x005
205 +#define DPSW_CMDID_IS_ENABLED 0x006
207 +#define DPSW_CMDID_SET_IRQ 0x010
208 +#define DPSW_CMDID_GET_IRQ 0x011
209 +#define DPSW_CMDID_SET_IRQ_ENABLE 0x012
210 +#define DPSW_CMDID_GET_IRQ_ENABLE 0x013
211 +#define DPSW_CMDID_SET_IRQ_MASK 0x014
212 +#define DPSW_CMDID_GET_IRQ_MASK 0x015
213 +#define DPSW_CMDID_GET_IRQ_STATUS 0x016
214 +#define DPSW_CMDID_CLEAR_IRQ_STATUS 0x017
216 +#define DPSW_CMDID_SET_REFLECTION_IF 0x022
218 +#define DPSW_CMDID_ADD_CUSTOM_TPID 0x024
220 +#define DPSW_CMDID_REMOVE_CUSTOM_TPID 0x026
222 +#define DPSW_CMDID_IF_SET_TCI 0x030
223 +#define DPSW_CMDID_IF_SET_STP 0x031
224 +#define DPSW_CMDID_IF_SET_ACCEPTED_FRAMES 0x032
225 +#define DPSW_CMDID_SET_IF_ACCEPT_ALL_VLAN 0x033
226 +#define DPSW_CMDID_IF_GET_COUNTER 0x034
227 +#define DPSW_CMDID_IF_SET_COUNTER 0x035
228 +#define DPSW_CMDID_IF_SET_TX_SELECTION 0x036
229 +#define DPSW_CMDID_IF_ADD_REFLECTION 0x037
230 +#define DPSW_CMDID_IF_REMOVE_REFLECTION 0x038
231 +#define DPSW_CMDID_IF_SET_FLOODING_METERING 0x039
232 +#define DPSW_CMDID_IF_SET_METERING 0x03A
233 +#define DPSW_CMDID_IF_SET_EARLY_DROP 0x03B
235 +#define DPSW_CMDID_IF_ENABLE 0x03D
236 +#define DPSW_CMDID_IF_DISABLE 0x03E
238 +#define DPSW_CMDID_IF_GET_ATTR 0x042
240 +#define DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH 0x044
241 +#define DPSW_CMDID_IF_GET_MAX_FRAME_LENGTH 0x045
242 +#define DPSW_CMDID_IF_GET_LINK_STATE 0x046
243 +#define DPSW_CMDID_IF_SET_FLOODING 0x047
244 +#define DPSW_CMDID_IF_SET_BROADCAST 0x048
245 +#define DPSW_CMDID_IF_SET_MULTICAST 0x049
246 +#define DPSW_CMDID_IF_GET_TCI 0x04A
248 +#define DPSW_CMDID_IF_SET_LINK_CFG 0x04C
250 +#define DPSW_CMDID_VLAN_ADD 0x060
251 +#define DPSW_CMDID_VLAN_ADD_IF 0x061
252 +#define DPSW_CMDID_VLAN_ADD_IF_UNTAGGED 0x062
253 +#define DPSW_CMDID_VLAN_ADD_IF_FLOODING 0x063
254 +#define DPSW_CMDID_VLAN_REMOVE_IF 0x064
255 +#define DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED 0x065
256 +#define DPSW_CMDID_VLAN_REMOVE_IF_FLOODING 0x066
257 +#define DPSW_CMDID_VLAN_REMOVE 0x067
258 +#define DPSW_CMDID_VLAN_GET_IF 0x068
259 +#define DPSW_CMDID_VLAN_GET_IF_FLOODING 0x069
260 +#define DPSW_CMDID_VLAN_GET_IF_UNTAGGED 0x06A
261 +#define DPSW_CMDID_VLAN_GET_ATTRIBUTES 0x06B
263 +#define DPSW_CMDID_FDB_GET_MULTICAST 0x080
264 +#define DPSW_CMDID_FDB_GET_UNICAST 0x081
265 +#define DPSW_CMDID_FDB_ADD 0x082
266 +#define DPSW_CMDID_FDB_REMOVE 0x083
267 +#define DPSW_CMDID_FDB_ADD_UNICAST 0x084
268 +#define DPSW_CMDID_FDB_REMOVE_UNICAST 0x085
269 +#define DPSW_CMDID_FDB_ADD_MULTICAST 0x086
270 +#define DPSW_CMDID_FDB_REMOVE_MULTICAST 0x087
271 +#define DPSW_CMDID_FDB_SET_LEARNING_MODE 0x088
272 +#define DPSW_CMDID_FDB_GET_ATTR 0x089
274 +#define DPSW_CMDID_ACL_ADD 0x090
275 +#define DPSW_CMDID_ACL_REMOVE 0x091
276 +#define DPSW_CMDID_ACL_ADD_ENTRY 0x092
277 +#define DPSW_CMDID_ACL_REMOVE_ENTRY 0x093
278 +#define DPSW_CMDID_ACL_ADD_IF 0x094
279 +#define DPSW_CMDID_ACL_REMOVE_IF 0x095
280 +#define DPSW_CMDID_ACL_GET_ATTR 0x096
282 +#define DPSW_CMDID_CTRL_IF_GET_ATTR 0x0A0
283 +#define DPSW_CMDID_CTRL_IF_SET_POOLS 0x0A1
284 +#define DPSW_CMDID_CTRL_IF_ENABLE 0x0A2
285 +#define DPSW_CMDID_CTRL_IF_DISABLE 0x0A3
287 +/* cmd, param, offset, width, type, arg_name */
288 +#define DPSW_CMD_OPEN(cmd, dpsw_id) \
289 + MC_CMD_OP(cmd, 0, 0, 32, int, dpsw_id)
291 +/* cmd, param, offset, width, type, arg_name */
292 +#define DPSW_CMD_CREATE(cmd, cfg) \
294 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->num_ifs);\
295 + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->adv.max_fdbs);\
296 + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->adv.max_meters_per_if);\
297 + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_component_type, \
298 + cfg->adv.component_type);\
299 + MC_CMD_OP(cmd, 1, 0, 16, uint16_t, cfg->adv.max_vlans);\
300 + MC_CMD_OP(cmd, 1, 16, 16, uint16_t, cfg->adv.max_fdb_entries);\
301 + MC_CMD_OP(cmd, 1, 32, 16, uint16_t, cfg->adv.fdb_aging_time);\
302 + MC_CMD_OP(cmd, 1, 48, 16, uint16_t, cfg->adv.max_fdb_mc_groups);\
303 + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->adv.options);\
306 +/* cmd, param, offset, width, type, arg_name */
307 +#define DPSW_RSP_IS_ENABLED(cmd, en) \
308 + MC_RSP_OP(cmd, 0, 0, 1, int, en)
310 +/* cmd, param, offset, width, type, arg_name */
311 +#define DPSW_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
313 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
314 + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
315 + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
316 + MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
319 +/* cmd, param, offset, width, type, arg_name */
320 +#define DPSW_CMD_GET_IRQ(cmd, irq_index) \
321 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
323 +/* cmd, param, offset, width, type, arg_name */
324 +#define DPSW_RSP_GET_IRQ(cmd, type, irq_cfg) \
326 + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \
327 + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
328 + MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
329 + MC_RSP_OP(cmd, 2, 32, 32, int, type); \
332 +/* cmd, param, offset, width, type, arg_name */
333 +#define DPSW_CMD_SET_IRQ_ENABLE(cmd, irq_index, enable_state) \
335 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, enable_state); \
336 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
339 +/* cmd, param, offset, width, type, arg_name */
340 +#define DPSW_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
341 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
343 +/* cmd, param, offset, width, type, arg_name */
344 +#define DPSW_RSP_GET_IRQ_ENABLE(cmd, enable_state) \
345 + MC_RSP_OP(cmd, 0, 0, 8, uint8_t, enable_state)
347 +/* cmd, param, offset, width, type, arg_name */
348 +#define DPSW_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
350 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask); \
351 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
354 +/* cmd, param, offset, width, type, arg_name */
355 +#define DPSW_CMD_GET_IRQ_MASK(cmd, irq_index) \
356 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
358 +/* cmd, param, offset, width, type, arg_name */
359 +#define DPSW_RSP_GET_IRQ_MASK(cmd, mask) \
360 + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
362 +/* cmd, param, offset, width, type, arg_name */
363 +#define DPSW_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
365 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
366 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
369 +/* cmd, param, offset, width, type, arg_name */
370 +#define DPSW_RSP_GET_IRQ_STATUS(cmd, status) \
371 + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
373 +/* cmd, param, offset, width, type, arg_name */
374 +#define DPSW_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
376 + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
377 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
380 +/* cmd, param, offset, width, type, arg_name */
381 +#define DPSW_RSP_GET_ATTR(cmd, attr) \
383 + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, attr->num_ifs);\
384 + MC_RSP_OP(cmd, 0, 16, 8, uint8_t, attr->max_fdbs);\
385 + MC_RSP_OP(cmd, 0, 24, 8, uint8_t, attr->num_fdbs);\
386 + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->max_vlans);\
387 + MC_RSP_OP(cmd, 0, 48, 16, uint16_t, attr->num_vlans);\
388 + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\
389 + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
390 + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, attr->max_fdb_entries);\
391 + MC_RSP_OP(cmd, 1, 48, 16, uint16_t, attr->fdb_aging_time);\
392 + MC_RSP_OP(cmd, 2, 0, 32, int, attr->id);\
393 + MC_RSP_OP(cmd, 2, 32, 16, uint16_t, attr->mem_size);\
394 + MC_RSP_OP(cmd, 2, 48, 16, uint16_t, attr->max_fdb_mc_groups);\
395 + MC_RSP_OP(cmd, 3, 0, 64, uint64_t, attr->options);\
396 + MC_RSP_OP(cmd, 4, 0, 8, uint8_t, attr->max_meters_per_if);\
397 + MC_RSP_OP(cmd, 4, 8, 4, enum dpsw_component_type, \
398 + attr->component_type);\
401 +/* cmd, param, offset, width, type, arg_name */
402 +#define DPSW_CMD_SET_REFLECTION_IF(cmd, if_id) \
403 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
405 +/* cmd, param, offset, width, type, arg_name */
406 +#define DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en) \
408 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
409 + MC_CMD_OP(cmd, 0, 16, 1, int, en);\
412 +/* cmd, param, offset, width, type, arg_name */
413 +#define DPSW_CMD_IF_SET_BROADCAST(cmd, if_id, en) \
415 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
416 + MC_CMD_OP(cmd, 0, 16, 1, int, en);\
419 +/* cmd, param, offset, width, type, arg_name */
420 +#define DPSW_CMD_IF_SET_MULTICAST(cmd, if_id, en) \
422 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
423 + MC_CMD_OP(cmd, 0, 16, 1, int, en);\
426 +/* cmd, param, offset, width, type, arg_name */
427 +#define DPSW_CMD_IF_SET_TCI(cmd, if_id, cfg) \
429 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
430 + MC_CMD_OP(cmd, 0, 16, 12, uint16_t, cfg->vlan_id);\
431 + MC_CMD_OP(cmd, 0, 28, 1, uint8_t, cfg->dei);\
432 + MC_CMD_OP(cmd, 0, 29, 3, uint8_t, cfg->pcp);\
435 +/* cmd, param, offset, width, type, arg_name */
436 +#define DPSW_CMD_IF_GET_TCI(cmd, if_id) \
437 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
439 +/* cmd, param, offset, width, type, arg_name */
440 +#define DPSW_RSP_IF_GET_TCI(cmd, cfg) \
442 + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
443 + MC_RSP_OP(cmd, 0, 32, 8, uint8_t, cfg->dei);\
444 + MC_RSP_OP(cmd, 0, 40, 8, uint8_t, cfg->pcp);\
447 +/* cmd, param, offset, width, type, arg_name */
448 +#define DPSW_CMD_IF_SET_STP(cmd, if_id, cfg) \
450 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
451 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
452 + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_stp_state, cfg->state);\
455 +/* cmd, param, offset, width, type, arg_name */
456 +#define DPSW_CMD_IF_SET_ACCEPTED_FRAMES(cmd, if_id, cfg) \
458 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
459 + MC_CMD_OP(cmd, 0, 16, 4, enum dpsw_accepted_frames, cfg->type);\
460 + MC_CMD_OP(cmd, 0, 20, 4, enum dpsw_action, cfg->unaccept_act);\
463 +/* cmd, param, offset, width, type, arg_name */
464 +#define DPSW_CMD_IF_SET_ACCEPT_ALL_VLAN(cmd, if_id, accept_all) \
466 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
467 + MC_CMD_OP(cmd, 0, 16, 1, int, accept_all);\
470 +/* cmd, param, offset, width, type, arg_name */
471 +#define DPSW_CMD_IF_GET_COUNTER(cmd, if_id, type) \
473 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
474 + MC_CMD_OP(cmd, 0, 16, 5, enum dpsw_counter, type);\
477 +/* cmd, param, offset, width, type, arg_name */
478 +#define DPSW_RSP_IF_GET_COUNTER(cmd, counter) \
479 + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, counter)
481 +/* cmd, param, offset, width, type, arg_name */
482 +#define DPSW_CMD_IF_SET_COUNTER(cmd, if_id, type, counter) \
484 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
485 + MC_CMD_OP(cmd, 0, 16, 5, enum dpsw_counter, type);\
486 + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, counter);\
489 +/* cmd, param, offset, width, type, arg_name */
490 +#define DPSW_CMD_IF_SET_TX_SELECTION(cmd, if_id, cfg) \
492 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
493 + MC_CMD_OP(cmd, 0, 16, 3, enum dpsw_priority_selector, \
494 + cfg->priority_selector);\
495 + MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->tc_id[0]);\
496 + MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->tc_id[1]);\
497 + MC_CMD_OP(cmd, 1, 16, 8, uint8_t, cfg->tc_id[2]);\
498 + MC_CMD_OP(cmd, 1, 24, 8, uint8_t, cfg->tc_id[3]);\
499 + MC_CMD_OP(cmd, 1, 32, 8, uint8_t, cfg->tc_id[4]);\
500 + MC_CMD_OP(cmd, 1, 40, 8, uint8_t, cfg->tc_id[5]);\
501 + MC_CMD_OP(cmd, 1, 48, 8, uint8_t, cfg->tc_id[6]);\
502 + MC_CMD_OP(cmd, 1, 56, 8, uint8_t, cfg->tc_id[7]);\
503 + MC_CMD_OP(cmd, 2, 0, 16, uint16_t, cfg->tc_sched[0].delta_bandwidth);\
504 + MC_CMD_OP(cmd, 2, 16, 4, enum dpsw_schedule_mode, \
505 + cfg->tc_sched[0].mode);\
506 + MC_CMD_OP(cmd, 2, 32, 16, uint16_t, cfg->tc_sched[1].delta_bandwidth);\
507 + MC_CMD_OP(cmd, 2, 48, 4, enum dpsw_schedule_mode, \
508 + cfg->tc_sched[1].mode);\
509 + MC_CMD_OP(cmd, 3, 0, 16, uint16_t, cfg->tc_sched[2].delta_bandwidth);\
510 + MC_CMD_OP(cmd, 3, 16, 4, enum dpsw_schedule_mode, \
511 + cfg->tc_sched[2].mode);\
512 + MC_CMD_OP(cmd, 3, 32, 16, uint16_t, cfg->tc_sched[3].delta_bandwidth);\
513 + MC_CMD_OP(cmd, 3, 48, 4, enum dpsw_schedule_mode, \
514 + cfg->tc_sched[3].mode);\
515 + MC_CMD_OP(cmd, 4, 0, 16, uint16_t, cfg->tc_sched[4].delta_bandwidth);\
516 + MC_CMD_OP(cmd, 4, 16, 4, enum dpsw_schedule_mode, \
517 + cfg->tc_sched[4].mode);\
518 + MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->tc_sched[5].delta_bandwidth);\
519 + MC_CMD_OP(cmd, 4, 48, 4, enum dpsw_schedule_mode, \
520 + cfg->tc_sched[5].mode);\
521 + MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->tc_sched[6].delta_bandwidth);\
522 + MC_CMD_OP(cmd, 5, 16, 4, enum dpsw_schedule_mode, \
523 + cfg->tc_sched[6].mode);\
524 + MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->tc_sched[7].delta_bandwidth);\
525 + MC_CMD_OP(cmd, 5, 48, 4, enum dpsw_schedule_mode, \
526 + cfg->tc_sched[7].mode);\
529 +/* cmd, param, offset, width, type, arg_name */
530 +#define DPSW_CMD_IF_ADD_REFLECTION(cmd, if_id, cfg) \
532 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
533 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
534 + MC_CMD_OP(cmd, 0, 32, 2, enum dpsw_reflection_filter, cfg->filter);\
537 +/* cmd, param, offset, width, type, arg_name */
538 +#define DPSW_CMD_IF_REMOVE_REFLECTION(cmd, if_id, cfg) \
540 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
541 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->vlan_id);\
542 + MC_CMD_OP(cmd, 0, 32, 2, enum dpsw_reflection_filter, cfg->filter);\
545 +/* cmd, param, offset, width, type, arg_name */
546 +#define DPSW_CMD_IF_SET_FLOODING_METERING(cmd, if_id, cfg) \
548 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
549 + MC_CMD_OP(cmd, 0, 24, 4, enum dpsw_metering_mode, cfg->mode);\
550 + MC_CMD_OP(cmd, 0, 28, 4, enum dpsw_metering_unit, cfg->units);\
551 + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, cfg->cir);\
552 + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->eir);\
553 + MC_CMD_OP(cmd, 1, 32, 32, uint32_t, cfg->cbs);\
554 + MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->ebs);\
557 +/* cmd, param, offset, width, type, arg_name */
558 +#define DPSW_CMD_IF_SET_METERING(cmd, if_id, tc_id, cfg) \
560 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
561 + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id);\
562 + MC_CMD_OP(cmd, 0, 24, 4, enum dpsw_metering_mode, cfg->mode);\
563 + MC_CMD_OP(cmd, 0, 28, 4, enum dpsw_metering_unit, cfg->units);\
564 + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, cfg->cir);\
565 + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->eir);\
566 + MC_CMD_OP(cmd, 1, 32, 32, uint32_t, cfg->cbs);\
567 + MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->ebs);\
570 +/* cmd, param, offset, width, type, arg_name */
571 +#define DPSW_PREP_EARLY_DROP(ext, cfg) \
573 + MC_PREP_OP(ext, 0, 0, 2, enum dpsw_early_drop_mode, cfg->drop_mode); \
574 + MC_PREP_OP(ext, 0, 2, 2, \
575 + enum dpsw_early_drop_unit, cfg->units); \
576 + MC_PREP_OP(ext, 0, 32, 32, uint32_t, cfg->tail_drop_threshold); \
577 + MC_PREP_OP(ext, 1, 0, 8, uint8_t, cfg->green.drop_probability); \
578 + MC_PREP_OP(ext, 2, 0, 64, uint64_t, cfg->green.max_threshold); \
579 + MC_PREP_OP(ext, 3, 0, 64, uint64_t, cfg->green.min_threshold); \
580 + MC_PREP_OP(ext, 5, 0, 8, uint8_t, cfg->yellow.drop_probability);\
581 + MC_PREP_OP(ext, 6, 0, 64, uint64_t, cfg->yellow.max_threshold); \
582 + MC_PREP_OP(ext, 7, 0, 64, uint64_t, cfg->yellow.min_threshold); \
585 +/* cmd, param, offset, width, type, arg_name */
586 +#define DPSW_EXT_EARLY_DROP(ext, cfg) \
588 + MC_EXT_OP(ext, 0, 0, 2, enum dpsw_early_drop_mode, cfg->drop_mode); \
589 + MC_EXT_OP(ext, 0, 2, 2, \
590 + enum dpsw_early_drop_unit, cfg->units); \
591 + MC_EXT_OP(ext, 0, 32, 32, uint32_t, cfg->tail_drop_threshold); \
592 + MC_EXT_OP(ext, 1, 0, 8, uint8_t, cfg->green.drop_probability); \
593 + MC_EXT_OP(ext, 2, 0, 64, uint64_t, cfg->green.max_threshold); \
594 + MC_EXT_OP(ext, 3, 0, 64, uint64_t, cfg->green.min_threshold); \
595 + MC_EXT_OP(ext, 5, 0, 8, uint8_t, cfg->yellow.drop_probability);\
596 + MC_EXT_OP(ext, 6, 0, 64, uint64_t, cfg->yellow.max_threshold); \
597 + MC_EXT_OP(ext, 7, 0, 64, uint64_t, cfg->yellow.min_threshold); \
600 +/* cmd, param, offset, width, type, arg_name */
601 +#define DPSW_CMD_IF_SET_EARLY_DROP(cmd, if_id, tc_id, early_drop_iova) \
603 + MC_CMD_OP(cmd, 0, 8, 8, uint8_t, tc_id); \
604 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, if_id); \
605 + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, early_drop_iova); \
608 +/* cmd, param, offset, width, type, arg_name */
609 +#define DPSW_CMD_ADD_CUSTOM_TPID(cmd, cfg) \
610 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->tpid)
612 +/* cmd, param, offset, width, type, arg_name */
613 +#define DPSW_CMD_REMOVE_CUSTOM_TPID(cmd, cfg) \
614 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->tpid)
616 +/* cmd, param, offset, width, type, arg_name */
617 +#define DPSW_CMD_IF_ENABLE(cmd, if_id) \
618 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
620 +/* cmd, param, offset, width, type, arg_name */
621 +#define DPSW_CMD_IF_DISABLE(cmd, if_id) \
622 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
624 +/* cmd, param, offset, width, type, arg_name */
625 +#define DPSW_CMD_IF_GET_ATTR(cmd, if_id) \
626 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
628 +/* cmd, param, offset, width, type, arg_name */
629 +#define DPSW_RSP_IF_GET_ATTR(cmd, attr) \
631 + MC_RSP_OP(cmd, 0, 0, 4, enum dpsw_accepted_frames, \
632 + attr->admit_untagged);\
633 + MC_RSP_OP(cmd, 0, 5, 1, int, attr->enabled);\
634 + MC_RSP_OP(cmd, 0, 6, 1, int, attr->accept_all_vlan);\
635 + MC_RSP_OP(cmd, 0, 16, 8, uint8_t, attr->num_tcs);\
636 + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qdid);\
637 + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options);\
638 + MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->rate);\
641 +/* cmd, param, offset, width, type, arg_name */
642 +#define DPSW_CMD_IF_SET_MAX_FRAME_LENGTH(cmd, if_id, frame_length) \
644 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
645 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, frame_length);\
648 +/* cmd, param, offset, width, type, arg_name */
649 +#define DPSW_CMD_IF_GET_MAX_FRAME_LENGTH(cmd, if_id) \
650 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
652 +/* cmd, param, offset, width, type, arg_name */
653 +#define DPSW_RSP_IF_GET_MAX_FRAME_LENGTH(cmd, frame_length) \
654 + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, frame_length)
656 +/* cmd, param, offset, width, type, arg_name */
657 +#define DPSW_CMD_IF_SET_LINK_CFG(cmd, if_id, cfg) \
659 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id);\
660 + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->rate);\
661 + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options);\
664 +/* cmd, param, offset, width, type, arg_name */
665 +#define DPSW_CMD_IF_GET_LINK_STATE(cmd, if_id) \
666 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, if_id)
668 +/* cmd, param, offset, width, type, arg_name */
669 +#define DPSW_RSP_IF_GET_LINK_STATE(cmd, state) \
671 + MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
672 + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
673 + MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
676 +/* cmd, param, offset, width, type, arg_name */
677 +#define DPSW_CMD_VLAN_ADD(cmd, vlan_id, cfg) \
679 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, cfg->fdb_id);\
680 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id);\
683 +/* cmd, param, offset, width, type, arg_name */
684 +#define DPSW_CMD_VLAN_ADD_IF(cmd, vlan_id) \
685 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
687 +/* cmd, param, offset, width, type, arg_name */
688 +#define DPSW_CMD_VLAN_ADD_IF_UNTAGGED(cmd, vlan_id) \
689 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
691 +/* cmd, param, offset, width, type, arg_name */
692 +#define DPSW_CMD_VLAN_ADD_IF_FLOODING(cmd, vlan_id) \
693 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
695 +#define DPSW_CMD_VLAN_REMOVE_IF(cmd, vlan_id) \
696 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
698 +/* cmd, param, offset, width, type, arg_name */
699 +#define DPSW_CMD_VLAN_REMOVE_IF_UNTAGGED(cmd, vlan_id) \
700 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
702 +/* cmd, param, offset, width, type, arg_name */
703 +#define DPSW_CMD_VLAN_REMOVE_IF_FLOODING(cmd, vlan_id) \
704 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
706 +/* cmd, param, offset, width, type, arg_name */
707 +#define DPSW_CMD_VLAN_REMOVE(cmd, vlan_id) \
708 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, vlan_id)
710 +/* cmd, param, offset, width, type, arg_name */
711 +#define DPSW_CMD_VLAN_GET_ATTR(cmd, vlan_id) \
712 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
714 +/* cmd, param, offset, width, type, arg_name */
715 +#define DPSW_RSP_VLAN_GET_ATTR(cmd, attr) \
717 + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->fdb_id); \
718 + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->num_ifs); \
719 + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, attr->num_untagged_ifs); \
720 + MC_RSP_OP(cmd, 1, 48, 16, uint16_t, attr->num_flooding_ifs); \
723 +/* cmd, param, offset, width, type, arg_name */
724 +#define DPSW_CMD_VLAN_GET_IF(cmd, vlan_id) \
725 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
727 +/* cmd, param, offset, width, type, arg_name */
728 +#define DPSW_RSP_VLAN_GET_IF(cmd, cfg) \
729 + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs)
731 +/* cmd, param, offset, width, type, arg_name */
732 +#define DPSW_CMD_VLAN_GET_IF_FLOODING(cmd, vlan_id) \
733 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
735 +/* cmd, param, offset, width, type, arg_name */
736 +#define DPSW_RSP_VLAN_GET_IF_FLOODING(cmd, cfg) \
737 + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs)
739 +/* cmd, param, offset, width, type, arg_name */
740 +#define DPSW_CMD_VLAN_GET_IF_UNTAGGED(cmd, vlan_id) \
741 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, vlan_id)
743 +/* cmd, param, offset, width, type, arg_name */
744 +#define DPSW_RSP_VLAN_GET_IF_UNTAGGED(cmd, cfg) \
745 + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs)
747 +/* param, offset, width, type, arg_name */
748 +#define DPSW_CMD_FDB_ADD(cmd, cfg) \
750 + MC_CMD_OP(cmd, 0, 32, 16, uint16_t, cfg->fdb_aging_time);\
751 + MC_CMD_OP(cmd, 0, 48, 16, uint16_t, cfg->num_fdb_entries);\
754 +/* cmd, param, offset, width, type, arg_name */
755 +#define DPSW_RSP_FDB_ADD(cmd, fdb_id) \
756 + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, fdb_id)
758 +/* cmd, param, offset, width, type, arg_name */
759 +#define DPSW_CMD_FDB_REMOVE(cmd, fdb_id) \
760 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id)
762 +/* cmd, param, offset, width, type, arg_name */
763 +#define DPSW_CMD_FDB_ADD_UNICAST(cmd, fdb_id, cfg) \
765 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
766 + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
767 + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
768 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
769 + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
770 + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
771 + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
772 + MC_CMD_OP(cmd, 1, 0, 8, uint16_t, cfg->if_egress);\
773 + MC_CMD_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
776 +/* cmd, param, offset, width, type, arg_name */
777 +#define DPSW_CMD_FDB_GET_UNICAST(cmd, fdb_id) \
779 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
780 + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
781 + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
782 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
783 + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
784 + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
785 + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
788 +/* cmd, param, offset, width, type, arg_name */
789 +#define DPSW_RSP_FDB_GET_UNICAST(cmd, cfg) \
791 + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, cfg->if_egress);\
792 + MC_RSP_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
795 +/* cmd, param, offset, width, type, arg_name */
796 +#define DPSW_CMD_FDB_REMOVE_UNICAST(cmd, fdb_id, cfg) \
798 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
799 + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
800 + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
801 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
802 + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
803 + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
804 + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
805 + MC_CMD_OP(cmd, 1, 0, 16, uint16_t, cfg->if_egress);\
806 + MC_CMD_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
809 +/* cmd, param, offset, width, type, arg_name */
810 +#define DPSW_CMD_FDB_ADD_MULTICAST(cmd, fdb_id, cfg) \
812 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
813 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs);\
814 + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_fdb_entry_type, cfg->type);\
815 + MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->mac_addr[5]);\
816 + MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->mac_addr[4]);\
817 + MC_CMD_OP(cmd, 1, 16, 8, uint8_t, cfg->mac_addr[3]);\
818 + MC_CMD_OP(cmd, 1, 24, 8, uint8_t, cfg->mac_addr[2]);\
819 + MC_CMD_OP(cmd, 1, 32, 8, uint8_t, cfg->mac_addr[1]);\
820 + MC_CMD_OP(cmd, 1, 40, 8, uint8_t, cfg->mac_addr[0]);\
823 +/* cmd, param, offset, width, type, arg_name */
824 +#define DPSW_CMD_FDB_GET_MULTICAST(cmd, fdb_id) \
826 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
827 + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, cfg->mac_addr[5]);\
828 + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, cfg->mac_addr[4]);\
829 + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->mac_addr[3]);\
830 + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, cfg->mac_addr[2]);\
831 + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, cfg->mac_addr[1]);\
832 + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, cfg->mac_addr[0]);\
835 +/* cmd, param, offset, width, type, arg_name */
836 +#define DPSW_RSP_FDB_GET_MULTICAST(cmd, cfg) \
838 + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, cfg->num_ifs);\
839 + MC_RSP_OP(cmd, 1, 16, 4, enum dpsw_fdb_entry_type, cfg->type);\
842 +/* cmd, param, offset, width, type, arg_name */
843 +#define DPSW_CMD_FDB_REMOVE_MULTICAST(cmd, fdb_id, cfg) \
845 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
846 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs);\
847 + MC_CMD_OP(cmd, 0, 32, 4, enum dpsw_fdb_entry_type, cfg->type);\
848 + MC_CMD_OP(cmd, 1, 0, 8, uint8_t, cfg->mac_addr[5]);\
849 + MC_CMD_OP(cmd, 1, 8, 8, uint8_t, cfg->mac_addr[4]);\
850 + MC_CMD_OP(cmd, 1, 16, 8, uint8_t, cfg->mac_addr[3]);\
851 + MC_CMD_OP(cmd, 1, 24, 8, uint8_t, cfg->mac_addr[2]);\
852 + MC_CMD_OP(cmd, 1, 32, 8, uint8_t, cfg->mac_addr[1]);\
853 + MC_CMD_OP(cmd, 1, 40, 8, uint8_t, cfg->mac_addr[0]);\
856 +/* cmd, param, offset, width, type, arg_name */
857 +#define DPSW_CMD_FDB_SET_LEARNING_MODE(cmd, fdb_id, mode) \
859 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id);\
860 + MC_CMD_OP(cmd, 0, 16, 4, enum dpsw_fdb_learning_mode, mode);\
863 +/* cmd, param, offset, width, type, arg_name */
864 +#define DPSW_CMD_FDB_GET_ATTR(cmd, fdb_id) \
865 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, fdb_id)
867 +/* cmd, param, offset, width, type, arg_name */
868 +#define DPSW_RSP_FDB_GET_ATTR(cmd, attr) \
870 + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->max_fdb_entries);\
871 + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->fdb_aging_time);\
872 + MC_RSP_OP(cmd, 0, 48, 16, uint16_t, attr->num_fdb_mc_groups);\
873 + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->max_fdb_mc_groups);\
874 + MC_RSP_OP(cmd, 1, 16, 4, enum dpsw_fdb_learning_mode, \
875 + attr->learning_mode);\
878 +/* cmd, param, offset, width, type, arg_name */
879 +#define DPSW_CMD_ACL_ADD(cmd, cfg) \
880 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->max_entries)
882 +/* cmd, param, offset, width, type, arg_name */
883 +#define DPSW_RSP_ACL_ADD(cmd, acl_id) \
884 + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, acl_id)
886 +/* cmd, param, offset, width, type, arg_name */
887 +#define DPSW_CMD_ACL_REMOVE(cmd, acl_id) \
888 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id)
890 +/* cmd, param, offset, width, type, arg_name */
891 +#define DPSW_PREP_ACL_ENTRY(ext, key) \
893 + MC_PREP_OP(ext, 0, 0, 8, uint8_t, key->match.l2_dest_mac[5]);\
894 + MC_PREP_OP(ext, 0, 8, 8, uint8_t, key->match.l2_dest_mac[4]);\
895 + MC_PREP_OP(ext, 0, 16, 8, uint8_t, key->match.l2_dest_mac[3]);\
896 + MC_PREP_OP(ext, 0, 24, 8, uint8_t, key->match.l2_dest_mac[2]);\
897 + MC_PREP_OP(ext, 0, 32, 8, uint8_t, key->match.l2_dest_mac[1]);\
898 + MC_PREP_OP(ext, 0, 40, 8, uint8_t, key->match.l2_dest_mac[0]);\
899 + MC_PREP_OP(ext, 0, 48, 16, uint16_t, key->match.l2_tpid);\
900 + MC_PREP_OP(ext, 1, 0, 8, uint8_t, key->match.l2_source_mac[5]);\
901 + MC_PREP_OP(ext, 1, 8, 8, uint8_t, key->match.l2_source_mac[4]);\
902 + MC_PREP_OP(ext, 1, 16, 8, uint8_t, key->match.l2_source_mac[3]);\
903 + MC_PREP_OP(ext, 1, 24, 8, uint8_t, key->match.l2_source_mac[2]);\
904 + MC_PREP_OP(ext, 1, 32, 8, uint8_t, key->match.l2_source_mac[1]);\
905 + MC_PREP_OP(ext, 1, 40, 8, uint8_t, key->match.l2_source_mac[0]);\
906 + MC_PREP_OP(ext, 1, 48, 16, uint16_t, key->match.l2_vlan_id);\
907 + MC_PREP_OP(ext, 2, 0, 32, uint32_t, key->match.l3_dest_ip);\
908 + MC_PREP_OP(ext, 2, 32, 32, uint32_t, key->match.l3_source_ip);\
909 + MC_PREP_OP(ext, 3, 0, 16, uint16_t, key->match.l4_dest_port);\
910 + MC_PREP_OP(ext, 3, 16, 16, uint16_t, key->match.l4_source_port);\
911 + MC_PREP_OP(ext, 3, 32, 16, uint16_t, key->match.l2_ether_type);\
912 + MC_PREP_OP(ext, 3, 48, 8, uint8_t, key->match.l2_pcp_dei);\
913 + MC_PREP_OP(ext, 3, 56, 8, uint8_t, key->match.l3_dscp);\
914 + MC_PREP_OP(ext, 4, 0, 8, uint8_t, key->mask.l2_dest_mac[5]);\
915 + MC_PREP_OP(ext, 4, 8, 8, uint8_t, key->mask.l2_dest_mac[4]);\
916 + MC_PREP_OP(ext, 4, 16, 8, uint8_t, key->mask.l2_dest_mac[3]);\
917 + MC_PREP_OP(ext, 4, 24, 8, uint8_t, key->mask.l2_dest_mac[2]);\
918 + MC_PREP_OP(ext, 4, 32, 8, uint8_t, key->mask.l2_dest_mac[1]);\
919 + MC_PREP_OP(ext, 4, 40, 8, uint8_t, key->mask.l2_dest_mac[0]);\
920 + MC_PREP_OP(ext, 4, 48, 16, uint16_t, key->mask.l2_tpid);\
921 + MC_PREP_OP(ext, 5, 0, 8, uint8_t, key->mask.l2_source_mac[5]);\
922 + MC_PREP_OP(ext, 5, 8, 8, uint8_t, key->mask.l2_source_mac[4]);\
923 + MC_PREP_OP(ext, 5, 16, 8, uint8_t, key->mask.l2_source_mac[3]);\
924 + MC_PREP_OP(ext, 5, 24, 8, uint8_t, key->mask.l2_source_mac[2]);\
925 + MC_PREP_OP(ext, 5, 32, 8, uint8_t, key->mask.l2_source_mac[1]);\
926 + MC_PREP_OP(ext, 5, 40, 8, uint8_t, key->mask.l2_source_mac[0]);\
927 + MC_PREP_OP(ext, 5, 48, 16, uint16_t, key->mask.l2_vlan_id);\
928 + MC_PREP_OP(ext, 6, 0, 32, uint32_t, key->mask.l3_dest_ip);\
929 + MC_PREP_OP(ext, 6, 32, 32, uint32_t, key->mask.l3_source_ip);\
930 + MC_PREP_OP(ext, 7, 0, 16, uint16_t, key->mask.l4_dest_port);\
931 + MC_PREP_OP(ext, 7, 16, 16, uint16_t, key->mask.l4_source_port);\
932 + MC_PREP_OP(ext, 7, 32, 16, uint16_t, key->mask.l2_ether_type);\
933 + MC_PREP_OP(ext, 7, 48, 8, uint8_t, key->mask.l2_pcp_dei);\
934 + MC_PREP_OP(ext, 7, 56, 8, uint8_t, key->mask.l3_dscp);\
935 + MC_PREP_OP(ext, 8, 0, 8, uint8_t, key->match.l3_protocol);\
936 + MC_PREP_OP(ext, 8, 8, 8, uint8_t, key->mask.l3_protocol);\
939 +/* cmd, param, offset, width, type, arg_name */
940 +#define DPSW_EXT_ACL_ENTRY(ext, key) \
942 + MC_EXT_OP(ext, 0, 0, 8, uint8_t, key->match.l2_dest_mac[5]);\
943 + MC_EXT_OP(ext, 0, 8, 8, uint8_t, key->match.l2_dest_mac[4]);\
944 + MC_EXT_OP(ext, 0, 16, 8, uint8_t, key->match.l2_dest_mac[3]);\
945 + MC_EXT_OP(ext, 0, 24, 8, uint8_t, key->match.l2_dest_mac[2]);\
946 + MC_EXT_OP(ext, 0, 32, 8, uint8_t, key->match.l2_dest_mac[1]);\
947 + MC_EXT_OP(ext, 0, 40, 8, uint8_t, key->match.l2_dest_mac[0]);\
948 + MC_EXT_OP(ext, 0, 48, 16, uint16_t, key->match.l2_tpid);\
949 + MC_EXT_OP(ext, 1, 0, 8, uint8_t, key->match.l2_source_mac[5]);\
950 + MC_EXT_OP(ext, 1, 8, 8, uint8_t, key->match.l2_source_mac[4]);\
951 + MC_EXT_OP(ext, 1, 16, 8, uint8_t, key->match.l2_source_mac[3]);\
952 + MC_EXT_OP(ext, 1, 24, 8, uint8_t, key->match.l2_source_mac[2]);\
953 + MC_EXT_OP(ext, 1, 32, 8, uint8_t, key->match.l2_source_mac[1]);\
954 + MC_EXT_OP(ext, 1, 40, 8, uint8_t, key->match.l2_source_mac[0]);\
955 + MC_EXT_OP(ext, 1, 48, 16, uint16_t, key->match.l2_vlan_id);\
956 + MC_EXT_OP(ext, 2, 0, 32, uint32_t, key->match.l3_dest_ip);\
957 + MC_EXT_OP(ext, 2, 32, 32, uint32_t, key->match.l3_source_ip);\
958 + MC_EXT_OP(ext, 3, 0, 16, uint16_t, key->match.l4_dest_port);\
959 + MC_EXT_OP(ext, 3, 16, 16, uint16_t, key->match.l4_source_port);\
960 + MC_EXT_OP(ext, 3, 32, 16, uint16_t, key->match.l2_ether_type);\
961 + MC_EXT_OP(ext, 3, 48, 8, uint8_t, key->match.l2_pcp_dei);\
962 + MC_EXT_OP(ext, 3, 56, 8, uint8_t, key->match.l3_dscp);\
963 + MC_EXT_OP(ext, 4, 0, 8, uint8_t, key->mask.l2_dest_mac[5]);\
964 + MC_EXT_OP(ext, 4, 8, 8, uint8_t, key->mask.l2_dest_mac[4]);\
965 + MC_EXT_OP(ext, 4, 16, 8, uint8_t, key->mask.l2_dest_mac[3]);\
966 + MC_EXT_OP(ext, 4, 24, 8, uint8_t, key->mask.l2_dest_mac[2]);\
967 + MC_EXT_OP(ext, 4, 32, 8, uint8_t, key->mask.l2_dest_mac[1]);\
968 + MC_EXT_OP(ext, 4, 40, 8, uint8_t, key->mask.l2_dest_mac[0]);\
969 + MC_EXT_OP(ext, 4, 48, 16, uint16_t, key->mask.l2_tpid);\
970 + MC_EXT_OP(ext, 5, 0, 8, uint8_t, key->mask.l2_source_mac[5]);\
971 + MC_EXT_OP(ext, 5, 8, 8, uint8_t, key->mask.l2_source_mac[4]);\
972 + MC_EXT_OP(ext, 5, 16, 8, uint8_t, key->mask.l2_source_mac[3]);\
973 + MC_EXT_OP(ext, 5, 24, 8, uint8_t, key->mask.l2_source_mac[2]);\
974 + MC_EXT_OP(ext, 5, 32, 8, uint8_t, key->mask.l2_source_mac[1]);\
975 + MC_EXT_OP(ext, 5, 40, 8, uint8_t, key->mask.l2_source_mac[0]);\
976 + MC_EXT_OP(ext, 5, 48, 16, uint16_t, key->mask.l2_vlan_id);\
977 + MC_EXT_OP(ext, 6, 0, 32, uint32_t, key->mask.l3_dest_ip);\
978 + MC_EXT_OP(ext, 6, 32, 32, uint32_t, key->mask.l3_source_ip);\
979 + MC_EXT_OP(ext, 7, 0, 16, uint16_t, key->mask.l4_dest_port);\
980 + MC_EXT_OP(ext, 7, 16, 16, uint16_t, key->mask.l4_source_port);\
981 + MC_EXT_OP(ext, 7, 32, 16, uint16_t, key->mask.l2_ether_type);\
982 + MC_EXT_OP(ext, 7, 48, 8, uint8_t, key->mask.l2_pcp_dei);\
983 + MC_EXT_OP(ext, 7, 56, 8, uint8_t, key->mask.l3_dscp);\
984 + MC_EXT_OP(ext, 8, 0, 8, uint8_t, key->match.l3_protocol);\
985 + MC_EXT_OP(ext, 8, 8, 8, uint8_t, key->mask.l3_protocol);\
988 +/* cmd, param, offset, width, type, arg_name */
989 +#define DPSW_CMD_ACL_ADD_ENTRY(cmd, acl_id, cfg) \
991 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
992 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->result.if_id);\
993 + MC_CMD_OP(cmd, 0, 32, 32, int, cfg->precedence);\
994 + MC_CMD_OP(cmd, 1, 0, 4, enum dpsw_acl_action, cfg->result.action);\
995 + MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_iova); \
998 +/* cmd, param, offset, width, type, arg_name */
999 +#define DPSW_CMD_ACL_REMOVE_ENTRY(cmd, acl_id, cfg) \
1001 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
1002 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->result.if_id);\
1003 + MC_CMD_OP(cmd, 0, 32, 32, int, cfg->precedence);\
1004 + MC_CMD_OP(cmd, 1, 0, 4, enum dpsw_acl_action, cfg->result.action);\
1005 + MC_CMD_OP(cmd, 6, 0, 64, uint64_t, cfg->key_iova); \
1008 +/* cmd, param, offset, width, type, arg_name */
1009 +#define DPSW_CMD_ACL_ADD_IF(cmd, acl_id, cfg) \
1011 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
1012 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs); \
1015 +/* cmd, param, offset, width, type, arg_name */
1016 +#define DPSW_CMD_ACL_REMOVE_IF(cmd, acl_id, cfg) \
1018 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id);\
1019 + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, cfg->num_ifs); \
1022 +/* cmd, param, offset, width, type, arg_name */
1023 +#define DPSW_CMD_ACL_GET_ATTR(cmd, acl_id) \
1024 + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, acl_id)
1026 +/* cmd, param, offset, width, type, arg_name */
1027 +#define DPSW_RSP_ACL_GET_ATTR(cmd, attr) \
1029 + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->max_entries);\
1030 + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->num_entries);\
1031 + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, attr->num_ifs);\
1034 +/* cmd, param, offset, width, type, arg_name */
1035 +#define DPSW_RSP_CTRL_IF_GET_ATTR(cmd, attr) \
1037 + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->rx_fqid);\
1038 + MC_RSP_OP(cmd, 1, 32, 32, uint32_t, attr->rx_err_fqid);\
1039 + MC_RSP_OP(cmd, 2, 0, 32, uint32_t, attr->tx_err_conf_fqid);\
1042 +/* cmd, param, offset, width, type, arg_name */
1043 +#define DPSW_CMD_CTRL_IF_SET_POOLS(cmd, cfg) \
1045 + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
1046 + MC_CMD_OP(cmd, 0, 8, 1, int, cfg->pools[0].backup_pool); \
1047 + MC_CMD_OP(cmd, 0, 9, 1, int, cfg->pools[1].backup_pool); \
1048 + MC_CMD_OP(cmd, 0, 10, 1, int, cfg->pools[2].backup_pool); \
1049 + MC_CMD_OP(cmd, 0, 11, 1, int, cfg->pools[3].backup_pool); \
1050 + MC_CMD_OP(cmd, 0, 12, 1, int, cfg->pools[4].backup_pool); \
1051 + MC_CMD_OP(cmd, 0, 13, 1, int, cfg->pools[5].backup_pool); \
1052 + MC_CMD_OP(cmd, 0, 14, 1, int, cfg->pools[6].backup_pool); \
1053 + MC_CMD_OP(cmd, 0, 15, 1, int, cfg->pools[7].backup_pool); \
1054 + MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
1055 + MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
1056 + MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
1057 + MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
1058 + MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
1059 + MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
1060 + MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
1061 + MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
1062 + MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
1063 + MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
1064 + MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
1065 + MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
1066 + MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
1067 + MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
1068 + MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
1069 + MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
1072 +#endif /* __FSL_DPSW_CMD_H */
1074 +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c
1076 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
1078 + * Redistribution and use in source and binary forms, with or without
1079 + * modification, are permitted provided that the following conditions are met:
1080 + * * Redistributions of source code must retain the above copyright
1081 + * notice, this list of conditions and the following disclaimer.
1082 + * * Redistributions in binary form must reproduce the above copyright
1083 + * notice, this list of conditions and the following disclaimer in the
1084 + * documentation and/or other materials provided with the distribution.
1085 + * * Neither the name of the above-listed copyright holders nor the
1086 + * names of any contributors may be used to endorse or promote products
1087 + * derived from this software without specific prior written permission.
1090 + * ALTERNATIVELY, this software may be distributed under the terms of the
1091 + * GNU General Public License ("GPL") as published by the Free Software
1092 + * Foundation, either version 2 of that License or (at your option) any
1095 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1096 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1097 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1098 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
1099 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1100 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1101 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1102 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1103 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1104 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1105 + * POSSIBILITY OF SUCH DAMAGE.
1107 +#include "../../fsl-mc/include/mc-sys.h"
1108 +#include "../../fsl-mc/include/mc-cmd.h"
1110 +#include "dpsw-cmd.h"
1112 +/* internal functions */
1113 +static void build_if_id_bitmap(const uint16_t *if_id,
1114 + const uint16_t num_ifs,
1115 + struct mc_command *cmd,
1120 + for (i = 0; (i < num_ifs) && (i < DPSW_MAX_IF); i++)
1121 + cmd->params[start_param + (if_id[i] / 64)] |= mc_enc(
1122 + (if_id[i] % 64), 1, 1);
1125 +static int read_if_id_bitmap(uint16_t *if_id,
1126 + uint16_t *num_ifs,
1127 + struct mc_command *cmd,
1130 + int bitmap[DPSW_MAX_IF] = { 0 };
1134 + for (i = 0; i < DPSW_MAX_IF; i++) {
1135 + bitmap[i] = (int)mc_dec(cmd->params[start_param + i / 64],
1137 + count += bitmap[i];
1140 + *num_ifs = (uint16_t)count;
1142 + for (i = 0; (i < DPSW_MAX_IF) && (j < count); i++) {
1144 + if_id[j] = (uint16_t)i;
1153 +int dpsw_open(struct fsl_mc_io *mc_io,
1154 + uint32_t cmd_flags,
1158 + struct mc_command cmd = { 0 };
1161 + /* prepare command */
1162 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN,
1165 + DPSW_CMD_OPEN(cmd, dpsw_id);
1167 + /* send command to mc*/
1168 + err = mc_send_command(mc_io, &cmd);
1172 + /* retrieve response parameters */
1173 + *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
1178 +int dpsw_close(struct fsl_mc_io *mc_io,
1179 + uint32_t cmd_flags,
1182 + struct mc_command cmd = { 0 };
1184 + /* prepare command */
1185 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE,
1189 + /* send command to mc*/
1190 + return mc_send_command(mc_io, &cmd);
1193 +int dpsw_create(struct fsl_mc_io *mc_io,
1194 + uint32_t cmd_flags,
1195 + const struct dpsw_cfg *cfg,
1198 + struct mc_command cmd = { 0 };
1201 + /* prepare command */
1202 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CREATE,
1205 + DPSW_CMD_CREATE(cmd, cfg);
1207 + /* send command to mc*/
1208 + err = mc_send_command(mc_io, &cmd);
1212 + /* retrieve response parameters */
1213 + *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
1218 +int dpsw_destroy(struct fsl_mc_io *mc_io,
1219 + uint32_t cmd_flags,
1222 + struct mc_command cmd = { 0 };
1224 + /* prepare command */
1225 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_DESTROY,
1229 + /* send command to mc*/
1230 + return mc_send_command(mc_io, &cmd);
1233 +int dpsw_enable(struct fsl_mc_io *mc_io,
1234 + uint32_t cmd_flags,
1237 + struct mc_command cmd = { 0 };
1239 + /* prepare command */
1240 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE,
1244 + /* send command to mc*/
1245 + return mc_send_command(mc_io, &cmd);
1248 +int dpsw_disable(struct fsl_mc_io *mc_io,
1249 + uint32_t cmd_flags,
1252 + struct mc_command cmd = { 0 };
1254 + /* prepare command */
1255 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE,
1259 + /* send command to mc*/
1260 + return mc_send_command(mc_io, &cmd);
1263 +int dpsw_is_enabled(struct fsl_mc_io *mc_io,
1264 + uint32_t cmd_flags,
1268 + struct mc_command cmd = { 0 };
1271 + /* prepare command */
1272 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IS_ENABLED, cmd_flags,
1275 + /* send command to mc*/
1276 + err = mc_send_command(mc_io, &cmd);
1280 + /* retrieve response parameters */
1281 + DPSW_RSP_IS_ENABLED(cmd, *en);
1286 +int dpsw_reset(struct fsl_mc_io *mc_io,
1287 + uint32_t cmd_flags,
1290 + struct mc_command cmd = { 0 };
1292 + /* prepare command */
1293 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET,
1297 + /* send command to mc*/
1298 + return mc_send_command(mc_io, &cmd);
1301 +int dpsw_set_irq(struct fsl_mc_io *mc_io,
1302 + uint32_t cmd_flags,
1304 + uint8_t irq_index,
1305 + struct dpsw_irq_cfg *irq_cfg)
1307 + struct mc_command cmd = { 0 };
1309 + /* prepare command */
1310 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ,
1313 + DPSW_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
1315 + /* send command to mc*/
1316 + return mc_send_command(mc_io, &cmd);
1319 +int dpsw_get_irq(struct fsl_mc_io *mc_io,
1320 + uint32_t cmd_flags,
1322 + uint8_t irq_index,
1324 + struct dpsw_irq_cfg *irq_cfg)
1326 + struct mc_command cmd = { 0 };
1329 + /* prepare command */
1330 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ,
1333 + DPSW_CMD_GET_IRQ(cmd, irq_index);
1335 + /* send command to mc*/
1336 + err = mc_send_command(mc_io, &cmd);
1340 + /* retrieve response parameters */
1341 + DPSW_RSP_GET_IRQ(cmd, *type, irq_cfg);
1346 +int dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
1347 + uint32_t cmd_flags,
1349 + uint8_t irq_index,
1352 + struct mc_command cmd = { 0 };
1354 + /* prepare command */
1355 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE,
1358 + DPSW_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
1360 + /* send command to mc*/
1361 + return mc_send_command(mc_io, &cmd);
1364 +int dpsw_get_irq_enable(struct fsl_mc_io *mc_io,
1365 + uint32_t cmd_flags,
1367 + uint8_t irq_index,
1370 + struct mc_command cmd = { 0 };
1373 + /* prepare command */
1374 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_ENABLE,
1377 + DPSW_CMD_GET_IRQ_ENABLE(cmd, irq_index);
1379 + /* send command to mc*/
1380 + err = mc_send_command(mc_io, &cmd);
1384 + /* retrieve response parameters */
1385 + DPSW_RSP_GET_IRQ_ENABLE(cmd, *en);
1390 +int dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
1391 + uint32_t cmd_flags,
1393 + uint8_t irq_index,
1396 + struct mc_command cmd = { 0 };
1398 + /* prepare command */
1399 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK,
1402 + DPSW_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
1404 + /* send command to mc*/
1405 + return mc_send_command(mc_io, &cmd);
1408 +int dpsw_get_irq_mask(struct fsl_mc_io *mc_io,
1409 + uint32_t cmd_flags,
1411 + uint8_t irq_index,
1414 + struct mc_command cmd = { 0 };
1417 + /* prepare command */
1418 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_MASK,
1421 + DPSW_CMD_GET_IRQ_MASK(cmd, irq_index);
1423 + /* send command to mc*/
1424 + err = mc_send_command(mc_io, &cmd);
1428 + /* retrieve response parameters */
1429 + DPSW_RSP_GET_IRQ_MASK(cmd, *mask);
1434 +int dpsw_get_irq_status(struct fsl_mc_io *mc_io,
1435 + uint32_t cmd_flags,
1437 + uint8_t irq_index,
1440 + struct mc_command cmd = { 0 };
1443 + /* prepare command */
1444 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS,
1447 + DPSW_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
1449 + /* send command to mc*/
1450 + err = mc_send_command(mc_io, &cmd);
1454 + /* retrieve response parameters */
1455 + DPSW_RSP_GET_IRQ_STATUS(cmd, *status);
1460 +int dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
1461 + uint32_t cmd_flags,
1463 + uint8_t irq_index,
1466 + struct mc_command cmd = { 0 };
1468 + /* prepare command */
1469 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS,
1472 + DPSW_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
1474 + /* send command to mc*/
1475 + return mc_send_command(mc_io, &cmd);
1478 +int dpsw_get_attributes(struct fsl_mc_io *mc_io,
1479 + uint32_t cmd_flags,
1481 + struct dpsw_attr *attr)
1483 + struct mc_command cmd = { 0 };
1486 + /* prepare command */
1487 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR,
1491 + /* send command to mc*/
1492 + err = mc_send_command(mc_io, &cmd);
1496 + /* retrieve response parameters */
1497 + DPSW_RSP_GET_ATTR(cmd, attr);
1502 +int dpsw_set_reflection_if(struct fsl_mc_io *mc_io,
1503 + uint32_t cmd_flags,
1507 + struct mc_command cmd = { 0 };
1509 + /* prepare command */
1510 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_REFLECTION_IF,
1513 + DPSW_CMD_SET_REFLECTION_IF(cmd, if_id);
1515 + /* send command to mc*/
1516 + return mc_send_command(mc_io, &cmd);
1519 +int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io,
1520 + uint32_t cmd_flags,
1523 + struct dpsw_link_cfg *cfg)
1525 + struct mc_command cmd = { 0 };
1527 + /* prepare command */
1528 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LINK_CFG,
1531 + DPSW_CMD_IF_SET_LINK_CFG(cmd, if_id, cfg);
1533 + /* send command to mc*/
1534 + return mc_send_command(mc_io, &cmd);
1537 +int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
1538 + uint32_t cmd_flags,
1541 + struct dpsw_link_state *state)
1543 + struct mc_command cmd = { 0 };
1546 + /* prepare command */
1547 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE,
1550 + DPSW_CMD_IF_GET_LINK_STATE(cmd, if_id);
1552 + /* send command to mc*/
1553 + err = mc_send_command(mc_io, &cmd);
1557 + /* retrieve response parameters */
1558 + DPSW_RSP_IF_GET_LINK_STATE(cmd, state);
1563 +int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
1564 + uint32_t cmd_flags,
1569 + struct mc_command cmd = { 0 };
1571 + /* prepare command */
1572 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_FLOODING,
1575 + DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en);
1577 + /* send command to mc*/
1578 + return mc_send_command(mc_io, &cmd);
1581 +int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
1582 + uint32_t cmd_flags,
1587 + struct mc_command cmd = { 0 };
1589 + /* prepare command */
1590 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_BROADCAST,
1593 + DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en);
1595 + /* send command to mc*/
1596 + return mc_send_command(mc_io, &cmd);
1599 +int dpsw_if_set_multicast(struct fsl_mc_io *mc_io,
1600 + uint32_t cmd_flags,
1605 + struct mc_command cmd = { 0 };
1607 + /* prepare command */
1608 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MULTICAST,
1611 + DPSW_CMD_IF_SET_FLOODING(cmd, if_id, en);
1613 + /* send command to mc*/
1614 + return mc_send_command(mc_io, &cmd);
1617 +int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
1618 + uint32_t cmd_flags,
1621 + const struct dpsw_tci_cfg *cfg)
1623 + struct mc_command cmd = { 0 };
1625 + /* prepare command */
1626 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI,
1629 + DPSW_CMD_IF_SET_TCI(cmd, if_id, cfg);
1631 + /* send command to mc*/
1632 + return mc_send_command(mc_io, &cmd);
1635 +int dpsw_if_get_tci(struct fsl_mc_io *mc_io,
1636 + uint32_t cmd_flags,
1639 + struct dpsw_tci_cfg *cfg)
1641 + struct mc_command cmd = { 0 };
1644 + /* prepare command */
1645 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_TCI,
1648 + DPSW_CMD_IF_GET_TCI(cmd, if_id);
1650 + /* send command to mc*/
1651 + err = mc_send_command(mc_io, &cmd);
1655 + /* retrieve response parameters */
1656 + DPSW_RSP_IF_GET_TCI(cmd, cfg);
1661 +int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
1662 + uint32_t cmd_flags,
1665 + const struct dpsw_stp_cfg *cfg)
1667 + struct mc_command cmd = { 0 };
1669 + /* prepare command */
1670 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP,
1673 + DPSW_CMD_IF_SET_STP(cmd, if_id, cfg);
1675 + /* send command to mc*/
1676 + return mc_send_command(mc_io, &cmd);
1679 +int dpsw_if_set_accepted_frames(struct fsl_mc_io *mc_io,
1680 + uint32_t cmd_flags,
1683 + const struct dpsw_accepted_frames_cfg *cfg)
1685 + struct mc_command cmd = { 0 };
1687 + /* prepare command */
1688 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_ACCEPTED_FRAMES,
1691 + DPSW_CMD_IF_SET_ACCEPTED_FRAMES(cmd, if_id, cfg);
1693 + /* send command to mc*/
1694 + return mc_send_command(mc_io, &cmd);
1697 +int dpsw_if_set_accept_all_vlan(struct fsl_mc_io *mc_io,
1698 + uint32_t cmd_flags,
1703 + struct mc_command cmd = { 0 };
1705 + /* prepare command */
1706 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IF_ACCEPT_ALL_VLAN,
1709 + DPSW_CMD_IF_SET_ACCEPT_ALL_VLAN(cmd, if_id, accept_all);
1711 + /* send command to mc*/
1712 + return mc_send_command(mc_io, &cmd);
1715 +int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
1716 + uint32_t cmd_flags,
1719 + enum dpsw_counter type,
1720 + uint64_t *counter)
1722 + struct mc_command cmd = { 0 };
1725 + /* prepare command */
1726 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER,
1729 + DPSW_CMD_IF_GET_COUNTER(cmd, if_id, type);
1731 + /* send command to mc*/
1732 + err = mc_send_command(mc_io, &cmd);
1736 + /* retrieve response parameters */
1737 + DPSW_RSP_IF_GET_COUNTER(cmd, *counter);
1742 +int dpsw_if_set_counter(struct fsl_mc_io *mc_io,
1743 + uint32_t cmd_flags,
1746 + enum dpsw_counter type,
1749 + struct mc_command cmd = { 0 };
1751 + /* prepare command */
1752 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_COUNTER,
1755 + DPSW_CMD_IF_SET_COUNTER(cmd, if_id, type, counter);
1757 + /* send command to mc*/
1758 + return mc_send_command(mc_io, &cmd);
1761 +int dpsw_if_set_tx_selection(struct fsl_mc_io *mc_io,
1762 + uint32_t cmd_flags,
1765 + const struct dpsw_tx_selection_cfg *cfg)
1767 + struct mc_command cmd = { 0 };
1769 + /* prepare command */
1770 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TX_SELECTION,
1773 + DPSW_CMD_IF_SET_TX_SELECTION(cmd, if_id, cfg);
1775 + /* send command to mc*/
1776 + return mc_send_command(mc_io, &cmd);
1779 +int dpsw_if_add_reflection(struct fsl_mc_io *mc_io,
1780 + uint32_t cmd_flags,
1783 + const struct dpsw_reflection_cfg *cfg)
1785 + struct mc_command cmd = { 0 };
1787 + /* prepare command */
1788 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ADD_REFLECTION,
1791 + DPSW_CMD_IF_ADD_REFLECTION(cmd, if_id, cfg);
1793 + /* send command to mc*/
1794 + return mc_send_command(mc_io, &cmd);
1797 +int dpsw_if_remove_reflection(struct fsl_mc_io *mc_io,
1798 + uint32_t cmd_flags,
1801 + const struct dpsw_reflection_cfg *cfg)
1803 + struct mc_command cmd = { 0 };
1805 + /* prepare command */
1806 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_REMOVE_REFLECTION,
1809 + DPSW_CMD_IF_REMOVE_REFLECTION(cmd, if_id, cfg);
1811 + /* send command to mc*/
1812 + return mc_send_command(mc_io, &cmd);
1815 +int dpsw_if_set_flooding_metering(struct fsl_mc_io *mc_io,
1816 + uint32_t cmd_flags,
1819 + const struct dpsw_metering_cfg *cfg)
1821 + struct mc_command cmd = { 0 };
1823 + /* prepare command */
1824 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_FLOODING_METERING,
1827 + DPSW_CMD_IF_SET_FLOODING_METERING(cmd, if_id, cfg);
1829 + /* send command to mc*/
1830 + return mc_send_command(mc_io, &cmd);
1833 +int dpsw_if_set_metering(struct fsl_mc_io *mc_io,
1834 + uint32_t cmd_flags,
1838 + const struct dpsw_metering_cfg *cfg)
1840 + struct mc_command cmd = { 0 };
1842 + /* prepare command */
1843 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_METERING,
1846 + DPSW_CMD_IF_SET_METERING(cmd, if_id, tc_id, cfg);
1848 + /* send command to mc*/
1849 + return mc_send_command(mc_io, &cmd);
1852 +void dpsw_prepare_early_drop(const struct dpsw_early_drop_cfg *cfg,
1853 + uint8_t *early_drop_buf)
1855 + uint64_t *ext_params = (uint64_t *)early_drop_buf;
1857 + DPSW_PREP_EARLY_DROP(ext_params, cfg);
1860 +int dpsw_if_set_early_drop(struct fsl_mc_io *mc_io,
1861 + uint32_t cmd_flags,
1865 + uint64_t early_drop_iova)
1867 + struct mc_command cmd = { 0 };
1869 + /* prepare command */
1870 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_EARLY_DROP,
1873 + DPSW_CMD_IF_SET_EARLY_DROP(cmd, if_id, tc_id, early_drop_iova);
1875 + /* send command to mc*/
1876 + return mc_send_command(mc_io, &cmd);
1879 +int dpsw_add_custom_tpid(struct fsl_mc_io *mc_io,
1880 + uint32_t cmd_flags,
1882 + const struct dpsw_custom_tpid_cfg *cfg)
1884 + struct mc_command cmd = { 0 };
1886 + /* prepare command */
1887 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ADD_CUSTOM_TPID,
1890 + DPSW_CMD_ADD_CUSTOM_TPID(cmd, cfg);
1892 + /* send command to mc*/
1893 + return mc_send_command(mc_io, &cmd);
1896 +int dpsw_remove_custom_tpid(struct fsl_mc_io *mc_io,
1897 + uint32_t cmd_flags,
1899 + const struct dpsw_custom_tpid_cfg *cfg)
1901 + struct mc_command cmd = { 0 };
1903 + /* prepare command */
1904 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_REMOVE_CUSTOM_TPID,
1907 + DPSW_CMD_REMOVE_CUSTOM_TPID(cmd, cfg);
1909 + /* send command to mc*/
1910 + return mc_send_command(mc_io, &cmd);
1913 +int dpsw_if_enable(struct fsl_mc_io *mc_io,
1914 + uint32_t cmd_flags,
1918 + struct mc_command cmd = { 0 };
1920 + /* prepare command */
1921 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE,
1924 + DPSW_CMD_IF_ENABLE(cmd, if_id);
1926 + /* send command to mc*/
1927 + return mc_send_command(mc_io, &cmd);
1930 +int dpsw_if_disable(struct fsl_mc_io *mc_io,
1931 + uint32_t cmd_flags,
1935 + struct mc_command cmd = { 0 };
1937 + /* prepare command */
1938 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE,
1941 + DPSW_CMD_IF_DISABLE(cmd, if_id);
1943 + /* send command to mc*/
1944 + return mc_send_command(mc_io, &cmd);
1947 +int dpsw_if_get_attributes(struct fsl_mc_io *mc_io,
1948 + uint32_t cmd_flags,
1951 + struct dpsw_if_attr *attr)
1953 + struct mc_command cmd = { 0 };
1956 + /* prepare command */
1957 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_ATTR,
1960 + DPSW_CMD_IF_GET_ATTR(cmd, if_id);
1962 + /* send command to mc*/
1963 + err = mc_send_command(mc_io, &cmd);
1967 + /* retrieve response parameters */
1968 + DPSW_RSP_IF_GET_ATTR(cmd, attr);
1973 +int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
1974 + uint32_t cmd_flags,
1977 + uint16_t frame_length)
1979 + struct mc_command cmd = { 0 };
1981 + /* prepare command */
1982 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH,
1985 + DPSW_CMD_IF_SET_MAX_FRAME_LENGTH(cmd, if_id, frame_length);
1987 + /* send command to mc*/
1988 + return mc_send_command(mc_io, &cmd);
1991 +int dpsw_if_get_max_frame_length(struct fsl_mc_io *mc_io,
1992 + uint32_t cmd_flags,
1995 + uint16_t *frame_length)
1997 + struct mc_command cmd = { 0 };
2000 + /* prepare command */
2001 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_MAX_FRAME_LENGTH,
2004 + DPSW_CMD_IF_GET_MAX_FRAME_LENGTH(cmd, if_id);
2006 + /* send command to mc*/
2007 + err = mc_send_command(mc_io, &cmd);
2011 + DPSW_RSP_IF_GET_MAX_FRAME_LENGTH(cmd, *frame_length);
2016 +int dpsw_vlan_add(struct fsl_mc_io *mc_io,
2017 + uint32_t cmd_flags,
2020 + const struct dpsw_vlan_cfg *cfg)
2022 + struct mc_command cmd = { 0 };
2024 + /* prepare command */
2025 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD,
2028 + DPSW_CMD_VLAN_ADD(cmd, vlan_id, cfg);
2030 + /* send command to mc*/
2031 + return mc_send_command(mc_io, &cmd);
2034 +int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
2035 + uint32_t cmd_flags,
2038 + const struct dpsw_vlan_if_cfg *cfg)
2040 + struct mc_command cmd = { 0 };
2042 + /* prepare command */
2043 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2044 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF,
2047 + DPSW_CMD_VLAN_ADD_IF(cmd, vlan_id);
2049 + /* send command to mc*/
2050 + return mc_send_command(mc_io, &cmd);
2053 +int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
2054 + uint32_t cmd_flags,
2057 + const struct dpsw_vlan_if_cfg *cfg)
2059 + struct mc_command cmd = { 0 };
2061 + /* prepare command */
2062 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2063 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED,
2066 + DPSW_CMD_VLAN_ADD_IF_UNTAGGED(cmd, vlan_id);
2068 + /* send command to mc*/
2069 + return mc_send_command(mc_io, &cmd);
2072 +int dpsw_vlan_add_if_flooding(struct fsl_mc_io *mc_io,
2073 + uint32_t cmd_flags,
2076 + const struct dpsw_vlan_if_cfg *cfg)
2078 + struct mc_command cmd = { 0 };
2080 + /* prepare command */
2081 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2082 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_FLOODING,
2085 + DPSW_CMD_VLAN_ADD_IF_FLOODING(cmd, vlan_id);
2087 + /* send command to mc*/
2088 + return mc_send_command(mc_io, &cmd);
2091 +int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
2092 + uint32_t cmd_flags,
2095 + const struct dpsw_vlan_if_cfg *cfg)
2097 + struct mc_command cmd = { 0 };
2099 + /* prepare command */
2100 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2101 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF,
2104 + DPSW_CMD_VLAN_REMOVE_IF(cmd, vlan_id);
2106 + /* send command to mc*/
2107 + return mc_send_command(mc_io, &cmd);
2110 +int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
2111 + uint32_t cmd_flags,
2114 + const struct dpsw_vlan_if_cfg *cfg)
2116 + struct mc_command cmd = { 0 };
2118 + /* prepare command */
2119 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2120 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED,
2123 + DPSW_CMD_VLAN_REMOVE_IF_UNTAGGED(cmd, vlan_id);
2125 + /* send command to mc*/
2126 + return mc_send_command(mc_io, &cmd);
2129 +int dpsw_vlan_remove_if_flooding(struct fsl_mc_io *mc_io,
2130 + uint32_t cmd_flags,
2133 + const struct dpsw_vlan_if_cfg *cfg)
2135 + struct mc_command cmd = { 0 };
2137 + /* prepare command */
2138 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2139 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_FLOODING,
2142 + DPSW_CMD_VLAN_REMOVE_IF_FLOODING(cmd, vlan_id);
2144 + /* send command to mc*/
2145 + return mc_send_command(mc_io, &cmd);
2148 +int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
2149 + uint32_t cmd_flags,
2153 + struct mc_command cmd = { 0 };
2155 + /* prepare command */
2156 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE,
2159 + DPSW_CMD_VLAN_REMOVE(cmd, vlan_id);
2161 + /* send command to mc*/
2162 + return mc_send_command(mc_io, &cmd);
2165 +int dpsw_vlan_get_attributes(struct fsl_mc_io *mc_io,
2166 + uint32_t cmd_flags,
2169 + struct dpsw_vlan_attr *attr)
2171 + struct mc_command cmd = { 0 };
2174 + /* prepare command */
2175 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_ATTRIBUTES,
2178 + DPSW_CMD_VLAN_GET_ATTR(cmd, vlan_id);
2180 + /* send command to mc*/
2181 + err = mc_send_command(mc_io, &cmd);
2185 + /* retrieve response parameters */
2186 + DPSW_RSP_VLAN_GET_ATTR(cmd, attr);
2191 +int dpsw_vlan_get_if(struct fsl_mc_io *mc_io,
2192 + uint32_t cmd_flags,
2195 + struct dpsw_vlan_if_cfg *cfg)
2197 + struct mc_command cmd = { 0 };
2200 + /* prepare command */
2201 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_IF,
2204 + DPSW_CMD_VLAN_GET_IF(cmd, vlan_id);
2206 + /* send command to mc*/
2207 + err = mc_send_command(mc_io, &cmd);
2211 + /* retrieve response parameters */
2212 + DPSW_RSP_VLAN_GET_IF(cmd, cfg);
2213 + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 1);
2218 +int dpsw_vlan_get_if_flooding(struct fsl_mc_io *mc_io,
2219 + uint32_t cmd_flags,
2222 + struct dpsw_vlan_if_cfg *cfg)
2224 + struct mc_command cmd = { 0 };
2227 + /* prepare command */
2228 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_IF_FLOODING,
2231 + DPSW_CMD_VLAN_GET_IF_FLOODING(cmd, vlan_id);
2233 + /* send command to mc*/
2234 + err = mc_send_command(mc_io, &cmd);
2238 + /* retrieve response parameters */
2239 + DPSW_RSP_VLAN_GET_IF_FLOODING(cmd, cfg);
2240 + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 1);
2245 +int dpsw_vlan_get_if_untagged(struct fsl_mc_io *mc_io,
2246 + uint32_t cmd_flags,
2249 + struct dpsw_vlan_if_cfg *cfg)
2251 + struct mc_command cmd = { 0 };
2254 + /* prepare command */
2255 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_GET_IF_UNTAGGED,
2258 + DPSW_CMD_VLAN_GET_IF_UNTAGGED(cmd, vlan_id);
2260 + /* send command to mc*/
2261 + err = mc_send_command(mc_io, &cmd);
2265 + /* retrieve response parameters */
2266 + DPSW_RSP_VLAN_GET_IF(cmd, cfg);
2267 + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 1);
2272 +int dpsw_fdb_add(struct fsl_mc_io *mc_io,
2273 + uint32_t cmd_flags,
2276 + const struct dpsw_fdb_cfg *cfg)
2278 + struct mc_command cmd = { 0 };
2281 + /* prepare command */
2282 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD,
2285 + DPSW_CMD_FDB_ADD(cmd, cfg);
2287 + /* send command to mc*/
2288 + err = mc_send_command(mc_io, &cmd);
2292 + /* retrieve response parameters */
2293 + DPSW_RSP_FDB_ADD(cmd, *fdb_id);
2298 +int dpsw_fdb_remove(struct fsl_mc_io *mc_io,
2299 + uint32_t cmd_flags,
2303 + struct mc_command cmd = { 0 };
2305 + /* prepare command */
2306 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE,
2309 + DPSW_CMD_FDB_REMOVE(cmd, fdb_id);
2311 + /* send command to mc*/
2312 + return mc_send_command(mc_io, &cmd);
2315 +int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
2316 + uint32_t cmd_flags,
2319 + const struct dpsw_fdb_unicast_cfg *cfg)
2321 + struct mc_command cmd = { 0 };
2323 + /* prepare command */
2324 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST,
2327 + DPSW_CMD_FDB_ADD_UNICAST(cmd, fdb_id, cfg);
2329 + /* send command to mc*/
2330 + return mc_send_command(mc_io, &cmd);
2333 +int dpsw_fdb_get_unicast(struct fsl_mc_io *mc_io,
2334 + uint32_t cmd_flags,
2337 + struct dpsw_fdb_unicast_cfg *cfg)
2339 + struct mc_command cmd = { 0 };
2342 + /* prepare command */
2343 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_GET_UNICAST,
2346 + DPSW_CMD_FDB_GET_UNICAST(cmd, fdb_id);
2348 + /* send command to mc*/
2349 + err = mc_send_command(mc_io, &cmd);
2353 + /* retrieve response parameters */
2354 + DPSW_RSP_FDB_GET_UNICAST(cmd, cfg);
2359 +int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
2360 + uint32_t cmd_flags,
2363 + const struct dpsw_fdb_unicast_cfg *cfg)
2365 + struct mc_command cmd = { 0 };
2367 + /* prepare command */
2368 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,
2371 + DPSW_CMD_FDB_REMOVE_UNICAST(cmd, fdb_id, cfg);
2373 + /* send command to mc*/
2374 + return mc_send_command(mc_io, &cmd);
2377 +int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
2378 + uint32_t cmd_flags,
2381 + const struct dpsw_fdb_multicast_cfg *cfg)
2383 + struct mc_command cmd = { 0 };
2385 + /* prepare command */
2386 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 2);
2387 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,
2390 + DPSW_CMD_FDB_ADD_MULTICAST(cmd, fdb_id, cfg);
2392 + /* send command to mc*/
2393 + return mc_send_command(mc_io, &cmd);
2396 +int dpsw_fdb_get_multicast(struct fsl_mc_io *mc_io,
2397 + uint32_t cmd_flags,
2400 + struct dpsw_fdb_multicast_cfg *cfg)
2402 + struct mc_command cmd = { 0 };
2405 + /* prepare command */
2406 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_GET_MULTICAST,
2409 + DPSW_CMD_FDB_GET_MULTICAST(cmd, fdb_id);
2411 + /* send command to mc*/
2412 + err = mc_send_command(mc_io, &cmd);
2416 + /* retrieve response parameters */
2417 + DPSW_RSP_FDB_GET_MULTICAST(cmd, cfg);
2418 + read_if_id_bitmap(cfg->if_id, &cfg->num_ifs, &cmd, 2);
2423 +int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
2424 + uint32_t cmd_flags,
2427 + const struct dpsw_fdb_multicast_cfg *cfg)
2429 + struct mc_command cmd = { 0 };
2431 + /* prepare command */
2432 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 2);
2433 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,
2436 + DPSW_CMD_FDB_REMOVE_MULTICAST(cmd, fdb_id, cfg);
2438 + /* send command to mc*/
2439 + return mc_send_command(mc_io, &cmd);
2442 +int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
2443 + uint32_t cmd_flags,
2446 + enum dpsw_fdb_learning_mode mode)
2448 + struct mc_command cmd = { 0 };
2450 + /* prepare command */
2451 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_SET_LEARNING_MODE,
2454 + DPSW_CMD_FDB_SET_LEARNING_MODE(cmd, fdb_id, mode);
2456 + /* send command to mc*/
2457 + return mc_send_command(mc_io, &cmd);
2460 +int dpsw_fdb_get_attributes(struct fsl_mc_io *mc_io,
2461 + uint32_t cmd_flags,
2464 + struct dpsw_fdb_attr *attr)
2466 + struct mc_command cmd = { 0 };
2469 + /* prepare command */
2470 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_GET_ATTR,
2473 + DPSW_CMD_FDB_GET_ATTR(cmd, fdb_id);
2475 + /* send command to mc*/
2476 + err = mc_send_command(mc_io, &cmd);
2480 + /* retrieve response parameters */
2481 + DPSW_RSP_FDB_GET_ATTR(cmd, attr);
2486 +int dpsw_acl_add(struct fsl_mc_io *mc_io,
2487 + uint32_t cmd_flags,
2490 + const struct dpsw_acl_cfg *cfg)
2492 + struct mc_command cmd = { 0 };
2495 + /* prepare command */
2496 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD,
2499 + DPSW_CMD_ACL_ADD(cmd, cfg);
2501 + /* send command to mc*/
2502 + err = mc_send_command(mc_io, &cmd);
2506 + /* retrieve response parameters */
2507 + DPSW_RSP_ACL_ADD(cmd, *acl_id);
2512 +int dpsw_acl_remove(struct fsl_mc_io *mc_io,
2513 + uint32_t cmd_flags,
2517 + struct mc_command cmd = { 0 };
2519 + /* prepare command */
2520 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE,
2523 + DPSW_CMD_ACL_REMOVE(cmd, acl_id);
2525 + /* send command to mc*/
2526 + return mc_send_command(mc_io, &cmd);
2529 +void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key,
2530 + uint8_t *entry_cfg_buf)
2532 + uint64_t *ext_params = (uint64_t *)entry_cfg_buf;
2534 + DPSW_PREP_ACL_ENTRY(ext_params, key);
2537 +int dpsw_acl_add_entry(struct fsl_mc_io *mc_io,
2538 + uint32_t cmd_flags,
2541 + const struct dpsw_acl_entry_cfg *cfg)
2543 + struct mc_command cmd = { 0 };
2545 + /* prepare command */
2546 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_ENTRY,
2549 + DPSW_CMD_ACL_ADD_ENTRY(cmd, acl_id, cfg);
2551 + /* send command to mc*/
2552 + return mc_send_command(mc_io, &cmd);
2555 +int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io,
2556 + uint32_t cmd_flags,
2559 + const struct dpsw_acl_entry_cfg *cfg)
2561 + struct mc_command cmd = { 0 };
2563 + /* prepare command */
2564 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_ENTRY,
2567 + DPSW_CMD_ACL_REMOVE_ENTRY(cmd, acl_id, cfg);
2569 + /* send command to mc*/
2570 + return mc_send_command(mc_io, &cmd);
2573 +int dpsw_acl_add_if(struct fsl_mc_io *mc_io,
2574 + uint32_t cmd_flags,
2577 + const struct dpsw_acl_if_cfg *cfg)
2579 + struct mc_command cmd = { 0 };
2581 + /* prepare command */
2582 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2583 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_IF,
2586 + DPSW_CMD_ACL_ADD_IF(cmd, acl_id, cfg);
2588 + /* send command to mc*/
2589 + return mc_send_command(mc_io, &cmd);
2592 +int dpsw_acl_remove_if(struct fsl_mc_io *mc_io,
2593 + uint32_t cmd_flags,
2596 + const struct dpsw_acl_if_cfg *cfg)
2598 + struct mc_command cmd = { 0 };
2600 + /* prepare command */
2601 + build_if_id_bitmap(cfg->if_id, cfg->num_ifs, &cmd, 1);
2602 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_IF,
2605 + DPSW_CMD_ACL_REMOVE_IF(cmd, acl_id, cfg);
2607 + /* send command to mc*/
2608 + return mc_send_command(mc_io, &cmd);
2611 +int dpsw_acl_get_attributes(struct fsl_mc_io *mc_io,
2612 + uint32_t cmd_flags,
2615 + struct dpsw_acl_attr *attr)
2617 + struct mc_command cmd = { 0 };
2620 + /* prepare command */
2621 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_GET_ATTR,
2624 + DPSW_CMD_ACL_GET_ATTR(cmd, acl_id);
2626 + /* send command to mc*/
2627 + err = mc_send_command(mc_io, &cmd);
2631 + /* retrieve response parameters */
2632 + DPSW_RSP_ACL_GET_ATTR(cmd, attr);
2637 +int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io,
2638 + uint32_t cmd_flags,
2640 + struct dpsw_ctrl_if_attr *attr)
2642 + struct mc_command cmd = { 0 };
2645 + /* prepare command */
2646 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_GET_ATTR,
2650 + /* send command to mc*/
2651 + err = mc_send_command(mc_io, &cmd);
2655 + /* retrieve response parameters */
2656 + DPSW_RSP_CTRL_IF_GET_ATTR(cmd, attr);
2661 +int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io,
2662 + uint32_t cmd_flags,
2664 + const struct dpsw_ctrl_if_pools_cfg *pools)
2666 + struct mc_command cmd = { 0 };
2668 + /* prepare command */
2669 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_POOLS,
2672 + DPSW_CMD_CTRL_IF_SET_POOLS(cmd, pools);
2674 + /* send command to mc*/
2675 + return mc_send_command(mc_io, &cmd);
2678 +int dpsw_ctrl_if_enable(struct fsl_mc_io *mc_io,
2679 + uint32_t cmd_flags,
2682 + struct mc_command cmd = { 0 };
2684 + /* prepare command */
2685 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_ENABLE,
2689 + /* send command to mc*/
2690 + return mc_send_command(mc_io, &cmd);
2694 +* @brief Function disables control interface
2695 +* @mc_io: Pointer to MC portal's I/O object
2696 +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2697 +* @token: Token of DPSW object
2699 +* Return: '0' on Success; Error code otherwise.
2701 +int dpsw_ctrl_if_disable(struct fsl_mc_io *mc_io,
2702 + uint32_t cmd_flags,
2705 + struct mc_command cmd = { 0 };
2707 + /* prepare command */
2708 + cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_DISABLE,
2712 + /* send command to mc*/
2713 + return mc_send_command(mc_io, &cmd);
2716 +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
2718 +/* Copyright 2013-2015 Freescale Semiconductor Inc.
2720 + * Redistribution and use in source and binary forms, with or without
2721 + * modification, are permitted provided that the following conditions are met:
2722 + * * Redistributions of source code must retain the above copyright
2723 + * notice, this list of conditions and the following disclaimer.
2724 + * * Redistributions in binary form must reproduce the above copyright
2725 + * notice, this list of conditions and the following disclaimer in the
2726 + * documentation and/or other materials provided with the distribution.
2727 + * * Neither the name of the above-listed copyright holders nor the
2728 + * names of any contributors may be used to endorse or promote products
2729 + * derived from this software without specific prior written permission.
2732 + * ALTERNATIVELY, this software may be distributed under the terms of the
2733 + * GNU General Public License ("GPL") as published by the Free Software
2734 + * Foundation, either version 2 of that License or (at your option) any
2737 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2738 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2739 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2740 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
2741 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2742 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2743 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2744 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2745 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2746 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2747 + * POSSIBILITY OF SUCH DAMAGE.
2749 +#ifndef __FSL_DPSW_H
2750 +#define __FSL_DPSW_H
2752 +#include "../../fsl-mc/include/net.h"
2754 +/* Data Path L2-Switch API
2755 + * Contains API for handling DPSW topology and functionality
2761 + * DPSW general definitions
2765 + * Maximum number of traffic class priorities
2767 +#define DPSW_MAX_PRIORITIES 8
2769 + * Maximum number of interfaces
2771 +#define DPSW_MAX_IF 64
2774 + * dpsw_open() - Open a control session for the specified object
2775 + * @mc_io: Pointer to MC portal's I/O object
2776 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2777 + * @dpsw_id: DPSW unique ID
2778 + * @token: Returned token; use in subsequent API calls
2780 + * This function can be used to open a control session for an
2781 + * already created object; an object may have been declared in
2782 + * the DPL or by calling the dpsw_create() function.
2783 + * This function returns a unique authentication token,
2784 + * associated with the specific object ID and the specific MC
2785 + * portal; this token must be used in all subsequent commands for
2786 + * this specific object
2788 + * Return: '0' on Success; Error code otherwise.
2790 +int dpsw_open(struct fsl_mc_io *mc_io,
2791 + uint32_t cmd_flags,
2796 + * dpsw_close() - Close the control session of the object
2797 + * @mc_io: Pointer to MC portal's I/O object
2798 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2799 + * @token: Token of DPSW object
2801 + * After this function is called, no further operations are
2802 + * allowed on the object without opening a new control session.
2804 + * Return: '0' on Success; Error code otherwise.
2806 +int dpsw_close(struct fsl_mc_io *mc_io,
2807 + uint32_t cmd_flags,
2815 + * Disable flooding
2817 +#define DPSW_OPT_FLOODING_DIS 0x0000000000000001ULL
2819 + * Disable Multicast
2821 +#define DPSW_OPT_MULTICAST_DIS 0x0000000000000004ULL
2823 + * Support control interface
2825 +#define DPSW_OPT_CTRL_IF_DIS 0x0000000000000010ULL
2827 + * Disable flooding metering
2829 +#define DPSW_OPT_FLOODING_METERING_DIS 0x0000000000000020ULL
2833 +#define DPSW_OPT_METERING_EN 0x0000000000000040ULL
2836 + * enum dpsw_component_type - component type of a bridge
2837 + * @DPSW_COMPONENT_TYPE_C_VLAN: A C-VLAN component of an
2838 + * enterprise VLAN bridge or of a Provider Bridge used
2839 + * to process C-tagged frames
2840 + * @DPSW_COMPONENT_TYPE_S_VLAN: An S-VLAN component of a
2844 +enum dpsw_component_type {
2845 + DPSW_COMPONENT_TYPE_C_VLAN = 0,
2846 + DPSW_COMPONENT_TYPE_S_VLAN
2850 + * struct dpsw_cfg - DPSW configuration
2851 + * @num_ifs: Number of external and internal interfaces
2852 + * @adv: Advanced parameters; default is all zeros;
2853 + * use this structure to change default settings
2858 + * struct adv - Advanced parameters
2859 + * @options: Enable/Disable DPSW features (bitmap)
2860 + * @max_vlans: Maximum Number of VLAN's; 0 - indicates default 16
2861 + * @max_meters_per_if: Number of meters per interface
2862 + * @max_fdbs: Maximum Number of FDB's; 0 - indicates default 16
2863 + * @max_fdb_entries: Number of FDB entries for default FDB table;
2864 + * 0 - indicates default 1024 entries.
2865 + * @fdb_aging_time: Default FDB aging time for default FDB table;
2866 + * 0 - indicates default 300 seconds
2867 + * @max_fdb_mc_groups: Number of multicast groups in each FDB table;
2868 + * 0 - indicates default 32
2869 + * @component_type: Indicates the component type of this bridge
2873 + uint16_t max_vlans;
2874 + uint8_t max_meters_per_if;
2876 + uint16_t max_fdb_entries;
2877 + uint16_t fdb_aging_time;
2878 + uint16_t max_fdb_mc_groups;
2879 + enum dpsw_component_type component_type;
2884 + * dpsw_create() - Create the DPSW object.
2885 + * @mc_io: Pointer to MC portal's I/O object
2886 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2887 + * @cfg: Configuration structure
2888 + * @token: Returned token; use in subsequent API calls
2890 + * Create the DPSW object, allocate required resources and
2891 + * perform required initialization.
2893 + * The object can be created either by declaring it in the
2894 + * DPL file, or by calling this function.
2896 + * This function returns a unique authentication token,
2897 + * associated with the specific object ID and the specific MC
2898 + * portal; this token must be used in all subsequent calls to
2899 + * this specific object. For objects that are created using the
2900 + * DPL file, call dpsw_open() function to get an authentication
2903 + * Return: '0' on Success; Error code otherwise.
2905 +int dpsw_create(struct fsl_mc_io *mc_io,
2906 + uint32_t cmd_flags,
2907 + const struct dpsw_cfg *cfg,
2911 + * dpsw_destroy() - Destroy the DPSW object and release all its resources.
2912 + * @mc_io: Pointer to MC portal's I/O object
2913 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2914 + * @token: Token of DPSW object
2916 + * Return: '0' on Success; error code otherwise.
2918 +int dpsw_destroy(struct fsl_mc_io *mc_io,
2919 + uint32_t cmd_flags,
2923 + * dpsw_enable() - Enable DPSW functionality
2924 + * @mc_io: Pointer to MC portal's I/O object
2925 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2926 + * @token: Token of DPSW object
2928 + * Return: Completion status. '0' on Success; Error code otherwise.
2930 +int dpsw_enable(struct fsl_mc_io *mc_io,
2931 + uint32_t cmd_flags,
2935 + * dpsw_disable() - Disable DPSW functionality
2936 + * @mc_io: Pointer to MC portal's I/O object
2937 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2938 + * @token: Token of DPSW object
2940 + * Return: Completion status. '0' on Success; Error code otherwise.
2942 +int dpsw_disable(struct fsl_mc_io *mc_io,
2943 + uint32_t cmd_flags,
2947 + * dpsw_is_enabled() - Check if the DPSW is enabled
2949 + * @mc_io: Pointer to MC portal's I/O object
2950 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2951 + * @token: Token of DPSW object
2952 + * @en: Returns '1' if object is enabled; '0' otherwise
2954 + * Return: '0' on Success; Error code otherwise
2956 +int dpsw_is_enabled(struct fsl_mc_io *mc_io,
2957 + uint32_t cmd_flags,
2962 + * dpsw_reset() - Reset the DPSW, returns the object to initial state.
2963 + * @mc_io: Pointer to MC portal's I/O object
2964 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
2965 + * @token: Token of DPSW object
2967 + * Return: '0' on Success; Error code otherwise.
2969 +int dpsw_reset(struct fsl_mc_io *mc_io,
2970 + uint32_t cmd_flags,
2974 + * DPSW IRQ Index and Events
2977 +#define DPSW_IRQ_INDEX_IF 0x0000
2978 +#define DPSW_IRQ_INDEX_L2SW 0x0001
2981 + * IRQ event - Indicates that the link state changed
2983 +#define DPSW_IRQ_EVENT_LINK_CHANGED 0x0001
2986 + * struct dpsw_irq_cfg - IRQ configuration
2987 + * @addr: Address that must be written to signal a message-based interrupt
2988 + * @val: Value to write into irq_addr address
2989 + * @irq_num: A user defined number associated with this IRQ
2991 +struct dpsw_irq_cfg {
2998 + * dpsw_set_irq() - Set IRQ information for the DPSW to trigger an interrupt.
2999 + * @mc_io: Pointer to MC portal's I/O object
3000 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3001 + * @token: Token of DPSW object
3002 + * @irq_index: Identifies the interrupt index to configure
3003 + * @irq_cfg: IRQ configuration
3005 + * Return: '0' on Success; Error code otherwise.
3007 +int dpsw_set_irq(struct fsl_mc_io *mc_io,
3008 + uint32_t cmd_flags,
3010 + uint8_t irq_index,
3011 + struct dpsw_irq_cfg *irq_cfg);
3014 + * dpsw_get_irq() - Get IRQ information from the DPSW
3016 + * @mc_io: Pointer to MC portal's I/O object
3017 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3018 + * @token: Token of DPSW object
3019 + * @irq_index: The interrupt index to configure
3020 + * @type: Interrupt type: 0 represents message interrupt
3021 + * type (both irq_addr and irq_val are valid)
3022 + * @irq_cfg: IRQ attributes
3024 + * Return: '0' on Success; Error code otherwise.
3026 +int dpsw_get_irq(struct fsl_mc_io *mc_io,
3027 + uint32_t cmd_flags,
3029 + uint8_t irq_index,
3031 + struct dpsw_irq_cfg *irq_cfg);
3034 + * dpsw_set_irq_enable() - Set overall interrupt state.
3035 + * @mc_io: Pointer to MC portal's I/O object
3036 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3037 + * @token: Token of DPCI object
3038 + * @irq_index: The interrupt index to configure
3039 + * @en: Interrupt state - enable = 1, disable = 0
3041 + * Allows GPP software to control when interrupts are generated.
3042 + * Each interrupt can have up to 32 causes. The enable/disable control's the
3043 + * overall interrupt state. if the interrupt is disabled no causes will cause
3046 + * Return: '0' on Success; Error code otherwise.
3048 +int dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
3049 + uint32_t cmd_flags,
3051 + uint8_t irq_index,
3055 + * dpsw_get_irq_enable() - Get overall interrupt state
3056 + * @mc_io: Pointer to MC portal's I/O object
3057 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3058 + * @token: Token of DPSW object
3059 + * @irq_index: The interrupt index to configure
3060 + * @en: Returned Interrupt state - enable = 1, disable = 0
3062 + * Return: '0' on Success; Error code otherwise.
3064 +int dpsw_get_irq_enable(struct fsl_mc_io *mc_io,
3065 + uint32_t cmd_flags,
3067 + uint8_t irq_index,
3071 + * dpsw_set_irq_mask() - Set interrupt mask.
3072 + * @mc_io: Pointer to MC portal's I/O object
3073 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3074 + * @token: Token of DPCI object
3075 + * @irq_index: The interrupt index to configure
3076 + * @mask: event mask to trigger interrupt;
3078 + * 0 = ignore event
3079 + * 1 = consider event for asserting IRQ
3081 + * Every interrupt can have up to 32 causes and the interrupt model supports
3082 + * masking/unmasking each cause independently
3084 + * Return: '0' on Success; Error code otherwise.
3086 +int dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
3087 + uint32_t cmd_flags,
3089 + uint8_t irq_index,
3093 + * dpsw_get_irq_mask() - Get interrupt mask.
3094 + * @mc_io: Pointer to MC portal's I/O object
3095 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3096 + * @token: Token of DPSW object
3097 + * @irq_index: The interrupt index to configure
3098 + * @mask: Returned event mask to trigger interrupt
3100 + * Every interrupt can have up to 32 causes and the interrupt model supports
3101 + * masking/unmasking each cause independently
3103 + * Return: '0' on Success; Error code otherwise.
3105 +int dpsw_get_irq_mask(struct fsl_mc_io *mc_io,
3106 + uint32_t cmd_flags,
3108 + uint8_t irq_index,
3112 + * dpsw_get_irq_status() - Get the current status of any pending interrupts
3113 + * @mc_io: Pointer to MC portal's I/O object
3114 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3115 + * @token: Token of DPSW object
3116 + * @irq_index: The interrupt index to configure
3117 + * @status: Returned interrupts status - one bit per cause:
3118 + * 0 = no interrupt pending
3119 + * 1 = interrupt pending
3121 + * Return: '0' on Success; Error code otherwise.
3123 +int dpsw_get_irq_status(struct fsl_mc_io *mc_io,
3124 + uint32_t cmd_flags,
3126 + uint8_t irq_index,
3127 + uint32_t *status);
3130 + * dpsw_clear_irq_status() - Clear a pending interrupt's status
3131 + * @mc_io: Pointer to MC portal's I/O object
3132 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3133 + * @token: Token of DPCI object
3134 + * @irq_index: The interrupt index to configure
3135 + * @status: bits to clear (W1C) - one bit per cause:
3136 + * 0 = don't change
3137 + * 1 = clear status bit
3139 + * Return: '0' on Success; Error code otherwise.
3141 +int dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
3142 + uint32_t cmd_flags,
3144 + uint8_t irq_index,
3147 + * struct dpsw_attr - Structure representing DPSW attributes
3148 + * @id: DPSW object ID
3149 + * @version: DPSW version
3150 + * @options: Enable/Disable DPSW features
3151 + * @max_vlans: Maximum Number of VLANs
3152 + * @max_meters_per_if: Number of meters per interface
3153 + * @max_fdbs: Maximum Number of FDBs
3154 + * @max_fdb_entries: Number of FDB entries for default FDB table;
3155 + * 0 - indicates default 1024 entries.
3156 + * @fdb_aging_time: Default FDB aging time for default FDB table;
3157 + * 0 - indicates default 300 seconds
3158 + * @max_fdb_mc_groups: Number of multicast groups in each FDB table;
3159 + * 0 - indicates default 32
3160 + * @mem_size: DPSW frame storage memory size
3161 + * @num_ifs: Number of interfaces
3162 + * @num_vlans: Current number of VLANs
3163 + * @num_fdbs: Current number of FDBs
3164 + * @component_type: Component type of this bridge
3169 + * struct version - DPSW version
3170 + * @major: DPSW major version
3171 + * @minor: DPSW minor version
3178 + uint16_t max_vlans;
3179 + uint8_t max_meters_per_if;
3181 + uint16_t max_fdb_entries;
3182 + uint16_t fdb_aging_time;
3183 + uint16_t max_fdb_mc_groups;
3185 + uint16_t mem_size;
3186 + uint16_t num_vlans;
3188 + enum dpsw_component_type component_type;
3192 + * dpsw_get_attributes() - Retrieve DPSW attributes
3193 + * @mc_io: Pointer to MC portal's I/O object
3194 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3195 + * @token: Token of DPSW object
3196 + * @attr: Returned DPSW attributes
3198 + * Return: Completion status. '0' on Success; Error code otherwise.
3200 +int dpsw_get_attributes(struct fsl_mc_io *mc_io,
3201 + uint32_t cmd_flags,
3203 + struct dpsw_attr *attr);
3206 + * dpsw_set_reflection_if() - Set target interface for reflected interfaces.
3207 + * @mc_io: Pointer to MC portal's I/O object
3208 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3209 + * @token: Token of DPSW object
3210 + * @if_id: Interface Id
3212 + * Only one reflection receive interface is allowed per switch
3214 + * Return: Completion status. '0' on Success; Error code otherwise.
3216 +int dpsw_set_reflection_if(struct fsl_mc_io *mc_io,
3217 + uint32_t cmd_flags,
3222 + * enum dpsw_action - Action selection for special/control frames
3223 + * @DPSW_ACTION_DROP: Drop frame
3224 + * @DPSW_ACTION_REDIRECT: Redirect frame to control port
3227 + DPSW_ACTION_DROP = 0,
3228 + DPSW_ACTION_REDIRECT = 1
3232 + * Enable auto-negotiation
3234 +#define DPSW_LINK_OPT_AUTONEG 0x0000000000000001ULL
3236 + * Enable half-duplex mode
3238 +#define DPSW_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
3240 + * Enable pause frames
3242 +#define DPSW_LINK_OPT_PAUSE 0x0000000000000004ULL
3244 + * Enable a-symmetric pause frames
3246 +#define DPSW_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
3249 + * struct dpsw_link_cfg - Structure representing DPSW link configuration
3251 + * @options: Mask of available options; use 'DPSW_LINK_OPT_<X>' values
3253 +struct dpsw_link_cfg {
3259 + * dpsw_if_set_link_cfg() - set the link configuration.
3260 + * @mc_io: Pointer to MC portal's I/O object
3261 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3262 + * @token: Token of DPSW object
3263 + * @if_id: interface id
3264 + * @cfg: Link configuration
3266 + * Return: '0' on Success; Error code otherwise.
3268 +int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io,
3269 + uint32_t cmd_flags,
3272 + struct dpsw_link_cfg *cfg);
3274 + * struct dpsw_link_state - Structure representing DPSW link state
3276 + * @options: Mask of available options; use 'DPSW_LINK_OPT_<X>' values
3277 + * @up: 0 - covers two cases: down and disconnected, 1 - up
3279 +struct dpsw_link_state {
3286 + * dpsw_if_get_link_state - Return the link state
3287 + * @mc_io: Pointer to MC portal's I/O object
3288 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3289 + * @token: Token of DPSW object
3290 + * @if_id: interface id
3291 + * @state: link state 1 - linkup, 0 - link down or disconnected
3293 + * @returns '0' on Success; Error code otherwise.
3295 +int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
3296 + uint32_t cmd_flags,
3299 + struct dpsw_link_state *state);
3302 + * dpsw_if_set_flooding() - Enable Disable flooding for particular interface
3303 + * @mc_io: Pointer to MC portal's I/O object
3304 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3305 + * @token: Token of DPSW object
3306 + * @if_id: Interface Identifier
3307 + * @en: 1 - enable, 0 - disable
3309 + * Return: Completion status. '0' on Success; Error code otherwise.
3311 +int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
3312 + uint32_t cmd_flags,
3318 + * dpsw_if_set_broadcast() - Enable/disable broadcast for particular interface
3319 + * @mc_io: Pointer to MC portal's I/O object
3320 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3321 + * @token: Token of DPSW object
3322 + * @if_id: Interface Identifier
3323 + * @en: 1 - enable, 0 - disable
3325 + * Return: Completion status. '0' on Success; Error code otherwise.
3327 +int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
3328 + uint32_t cmd_flags,
3334 + * dpsw_if_set_multicast() - Enable/disable multicast for particular interface
3335 + * @mc_io: Pointer to MC portal's I/O object
3336 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3337 + * @token: Token of DPSW object
3338 + * @if_id: Interface Identifier
3339 + * @en: 1 - enable, 0 - disable
3341 + * Return: Completion status. '0' on Success; Error code otherwise.
3343 +int dpsw_if_set_multicast(struct fsl_mc_io *mc_io,
3344 + uint32_t cmd_flags,
3350 + * struct dpsw_tci_cfg - Tag Contorl Information (TCI) configuration
3351 + * @pcp: Priority Code Point (PCP): a 3-bit field which refers
3352 + * to the IEEE 802.1p priority
3353 + * @dei: Drop Eligible Indicator (DEI): a 1-bit field. May be used
3354 + * separately or in conjunction with PCP to indicate frames
3355 + * eligible to be dropped in the presence of congestion
3356 + * @vlan_id: VLAN Identifier (VID): a 12-bit field specifying the VLAN
3357 + * to which the frame belongs. The hexadecimal values
3358 + * of 0x000 and 0xFFF are reserved;
3359 + * all other values may be used as VLAN identifiers,
3360 + * allowing up to 4,094 VLANs
3362 +struct dpsw_tci_cfg {
3369 + * dpsw_if_set_tci() - Set default VLAN Tag Control Information (TCI)
3370 + * @mc_io: Pointer to MC portal's I/O object
3371 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3372 + * @token: Token of DPSW object
3373 + * @if_id: Interface Identifier
3374 + * @cfg: Tag Control Information Configuration
3376 + * Return: Completion status. '0' on Success; Error code otherwise.
3378 +int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
3379 + uint32_t cmd_flags,
3382 + const struct dpsw_tci_cfg *cfg);
3385 + * dpsw_if_get_tci() - Get default VLAN Tag Control Information (TCI)
3386 + * @mc_io: Pointer to MC portal's I/O object
3387 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3388 + * @token: Token of DPSW object
3389 + * @if_id: Interface Identifier
3390 + * @cfg: Tag Control Information Configuration
3392 + * Return: Completion status. '0' on Success; Error code otherwise.
3394 +int dpsw_if_get_tci(struct fsl_mc_io *mc_io,
3395 + uint32_t cmd_flags,
3398 + struct dpsw_tci_cfg *cfg);
3401 + * enum dpsw_stp_state - Spanning Tree Protocol (STP) states
3402 + * @DPSW_STP_STATE_BLOCKING: Blocking state
3403 + * @DPSW_STP_STATE_LISTENING: Listening state
3404 + * @DPSW_STP_STATE_LEARNING: Learning state
3405 + * @DPSW_STP_STATE_FORWARDING: Forwarding state
3408 +enum dpsw_stp_state {
3409 + DPSW_STP_STATE_BLOCKING = 0,
3410 + DPSW_STP_STATE_LISTENING = 1,
3411 + DPSW_STP_STATE_LEARNING = 2,
3412 + DPSW_STP_STATE_FORWARDING = 3
3416 + * struct dpsw_stp_cfg - Spanning Tree Protocol (STP) Configuration
3417 + * @vlan_id: VLAN ID STP state
3418 + * @state: STP state
3420 +struct dpsw_stp_cfg {
3422 + enum dpsw_stp_state state;
3426 + * dpsw_if_set_stp() - Function sets Spanning Tree Protocol (STP) state.
3427 + * @mc_io: Pointer to MC portal's I/O object
3428 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3429 + * @token: Token of DPSW object
3430 + * @if_id: Interface Identifier
3431 + * @cfg: STP State configuration parameters
3433 + * The following STP states are supported -
3434 + * blocking, listening, learning, forwarding and disabled.
3436 + * Return: Completion status. '0' on Success; Error code otherwise.
3438 +int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
3439 + uint32_t cmd_flags,
3442 + const struct dpsw_stp_cfg *cfg);
3445 + * enum dpsw_accepted_frames - Types of frames to accept
3446 + * @DPSW_ADMIT_ALL: The device accepts VLAN tagged, untagged and
3447 + * priority tagged frames
3448 + * @DPSW_ADMIT_ONLY_VLAN_TAGGED: The device discards untagged frames or
3449 + * Priority-Tagged frames received on this interface.
3452 +enum dpsw_accepted_frames {
3453 + DPSW_ADMIT_ALL = 1,
3454 + DPSW_ADMIT_ONLY_VLAN_TAGGED = 3
3458 + * struct dpsw_accepted_frames_cfg - Types of frames to accept configuration
3459 + * @type: Defines ingress accepted frames
3460 + * @unaccept_act: When a frame is not accepted, it may be discarded or
3461 + * redirected to control interface depending on this mode
3463 +struct dpsw_accepted_frames_cfg {
3464 + enum dpsw_accepted_frames type;
3465 + enum dpsw_action unaccept_act;
3469 + * dpsw_if_set_accepted_frames()
3470 + * @mc_io: Pointer to MC portal's I/O object
3471 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3472 + * @token: Token of DPSW object
3473 + * @if_id: Interface Identifier
3474 + * @cfg: Frame types configuration
3476 + * When is admit_only_vlan_tagged- the device will discard untagged
3477 + * frames or Priority-Tagged frames received on this interface.
3478 + * When admit_only_untagged- untagged frames or Priority-Tagged
3479 + * frames received on this interface will be accepted and assigned
3480 + * to a VID based on the PVID and VID Set for this interface.
3481 + * When admit_all - the device will accept VLAN tagged, untagged
3482 + * and priority tagged frames.
3483 + * The default is admit_all
3485 + * Return: Completion status. '0' on Success; Error code otherwise.
3487 +int dpsw_if_set_accepted_frames(struct fsl_mc_io *mc_io,
3488 + uint32_t cmd_flags,
3491 + const struct dpsw_accepted_frames_cfg *cfg);
3494 + * dpsw_if_set_accept_all_vlan()
3495 + * @mc_io: Pointer to MC portal's I/O object
3496 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3497 + * @token: Token of DPSW object
3498 + * @if_id: Interface Identifier
3499 + * @accept_all: Accept or drop frames having different VLAN
3501 + * When this is accept (FALSE), the device will discard incoming
3502 + * frames for VLANs that do not include this interface in its
3503 + * Member set. When accept (TRUE), the interface will accept all incoming frames
3505 + * Return: Completion status. '0' on Success; Error code otherwise.
3507 +int dpsw_if_set_accept_all_vlan(struct fsl_mc_io *mc_io,
3508 + uint32_t cmd_flags,
3514 + * enum dpsw_counter - Counters types
3515 + * @DPSW_CNT_ING_FRAME: Counts ingress frames
3516 + * @DPSW_CNT_ING_BYTE: Counts ingress bytes
3517 + * @DPSW_CNT_ING_FLTR_FRAME: Counts filtered ingress frames
3518 + * @DPSW_CNT_ING_FRAME_DISCARD: Counts discarded ingress frame
3519 + * @DPSW_CNT_ING_MCAST_FRAME: Counts ingress multicast frames
3520 + * @DPSW_CNT_ING_MCAST_BYTE: Counts ingress multicast bytes
3521 + * @DPSW_CNT_ING_BCAST_FRAME: Counts ingress broadcast frames
3522 + * @DPSW_CNT_ING_BCAST_BYTES: Counts ingress broadcast bytes
3523 + * @DPSW_CNT_EGR_FRAME: Counts egress frames
3524 + * @DPSW_CNT_EGR_BYTE: Counts eEgress bytes
3525 + * @DPSW_CNT_EGR_FRAME_DISCARD: Counts discarded egress frames
3526 + * @DPSW_CNT_EGR_STP_FRAME_DISCARD: Counts egress STP discarded frames
3528 +enum dpsw_counter {
3529 + DPSW_CNT_ING_FRAME = 0x0,
3530 + DPSW_CNT_ING_BYTE = 0x1,
3531 + DPSW_CNT_ING_FLTR_FRAME = 0x2,
3532 + DPSW_CNT_ING_FRAME_DISCARD = 0x3,
3533 + DPSW_CNT_ING_MCAST_FRAME = 0x4,
3534 + DPSW_CNT_ING_MCAST_BYTE = 0x5,
3535 + DPSW_CNT_ING_BCAST_FRAME = 0x6,
3536 + DPSW_CNT_ING_BCAST_BYTES = 0x7,
3537 + DPSW_CNT_EGR_FRAME = 0x8,
3538 + DPSW_CNT_EGR_BYTE = 0x9,
3539 + DPSW_CNT_EGR_FRAME_DISCARD = 0xa,
3540 + DPSW_CNT_EGR_STP_FRAME_DISCARD = 0xb
3544 + * dpsw_if_get_counter() - Get specific counter of particular interface
3545 + * @mc_io: Pointer to MC portal's I/O object
3546 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3547 + * @token: Token of DPSW object
3548 + * @if_id: Interface Identifier
3549 + * @type: Counter type
3550 + * @counter: return value
3552 + * Return: Completion status. '0' on Success; Error code otherwise.
3554 +int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
3555 + uint32_t cmd_flags,
3558 + enum dpsw_counter type,
3559 + uint64_t *counter);
3562 + * dpsw_if_set_counter() - Set specific counter of particular interface
3563 + * @mc_io: Pointer to MC portal's I/O object
3564 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3565 + * @token: Token of DPSW object
3566 + * @if_id: Interface Identifier
3567 + * @type: Counter type
3568 + * @counter: New counter value
3570 + * Return: Completion status. '0' on Success; Error code otherwise.
3572 +int dpsw_if_set_counter(struct fsl_mc_io *mc_io,
3573 + uint32_t cmd_flags,
3576 + enum dpsw_counter type,
3577 + uint64_t counter);
3580 + * Maximum number of TC
3582 +#define DPSW_MAX_TC 8
3585 + * enum dpsw_priority_selector - User priority
3586 + * @DPSW_UP_PCP: Priority Code Point (PCP): a 3-bit field which
3587 + * refers to the IEEE 802.1p priority.
3588 + * @DPSW_UP_DSCP: Differentiated services Code Point (DSCP): 6 bit
3589 + * field from IP header
3592 +enum dpsw_priority_selector {
3598 + * enum dpsw_schedule_mode - Traffic classes scheduling
3599 + * @DPSW_SCHED_STRICT_PRIORITY: schedule strict priority
3600 + * @DPSW_SCHED_WEIGHTED: schedule based on token bucket created algorithm
3602 +enum dpsw_schedule_mode {
3603 + DPSW_SCHED_STRICT_PRIORITY,
3604 + DPSW_SCHED_WEIGHTED
3608 + * struct dpsw_tx_schedule_cfg - traffic class configuration
3609 + * @mode: Strict or weight-based scheduling
3610 + * @delta_bandwidth: weighted Bandwidth in range from 100 to 10000
3612 +struct dpsw_tx_schedule_cfg {
3613 + enum dpsw_schedule_mode mode;
3614 + uint16_t delta_bandwidth;
3618 + * struct dpsw_tx_selection_cfg - Mapping user priority into traffic
3619 + * class configuration
3620 + * @priority_selector: Source for user priority regeneration
3621 + * @tc_id: The Regenerated User priority that the incoming
3622 + * User Priority is mapped to for this interface
3623 + * @tc_sched: Traffic classes configuration
3625 +struct dpsw_tx_selection_cfg {
3626 + enum dpsw_priority_selector priority_selector;
3627 + uint8_t tc_id[DPSW_MAX_PRIORITIES];
3628 + struct dpsw_tx_schedule_cfg tc_sched[DPSW_MAX_TC];
3632 + * dpsw_if_set_tx_selection() - Function is used for mapping variety
3634 + * @mc_io: Pointer to MC portal's I/O object
3635 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3636 + * @token: Token of DPSW object
3637 + * @if_id: Interface Identifier
3638 + * @cfg: Traffic class mapping configuration
3640 + * Function is used for mapping variety of frame fields (DSCP, PCP)
3641 + * to Traffic Class. Traffic class is a number
3642 + * in the range from 0 to 7
3644 + * Return: Completion status. '0' on Success; Error code otherwise.
3646 +int dpsw_if_set_tx_selection(struct fsl_mc_io *mc_io,
3647 + uint32_t cmd_flags,
3650 + const struct dpsw_tx_selection_cfg *cfg);
3653 + * enum dpsw_reflection_filter - Filter type for frames to reflect
3654 + * @DPSW_REFLECTION_FILTER_INGRESS_ALL: Reflect all frames
3655 + * @DPSW_REFLECTION_FILTER_INGRESS_VLAN: Reflect only frames belong to
3656 + * particular VLAN defined by vid parameter
3659 +enum dpsw_reflection_filter {
3660 + DPSW_REFLECTION_FILTER_INGRESS_ALL = 0,
3661 + DPSW_REFLECTION_FILTER_INGRESS_VLAN = 1
3665 + * struct dpsw_reflection_cfg - Structure representing reflection information
3666 + * @filter: Filter type for frames to reflect
3667 + * @vlan_id: Vlan Id to reflect; valid only when filter type is
3668 + * DPSW_INGRESS_VLAN
3670 +struct dpsw_reflection_cfg {
3671 + enum dpsw_reflection_filter filter;
3676 + * dpsw_if_add_reflection() - Identify interface to be reflected or mirrored
3677 + * @mc_io: Pointer to MC portal's I/O object
3678 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3679 + * @token: Token of DPSW object
3680 + * @if_id: Interface Identifier
3681 + * @cfg: Reflection configuration
3683 + * Return: Completion status. '0' on Success; Error code otherwise.
3685 +int dpsw_if_add_reflection(struct fsl_mc_io *mc_io,
3686 + uint32_t cmd_flags,
3689 + const struct dpsw_reflection_cfg *cfg);
3692 + * dpsw_if_remove_reflection() - Remove interface to be reflected or mirrored
3693 + * @mc_io: Pointer to MC portal's I/O object
3694 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3695 + * @token: Token of DPSW object
3696 + * @if_id: Interface Identifier
3697 + * @cfg: Reflection configuration
3699 + * Return: Completion status. '0' on Success; Error code otherwise.
3701 +int dpsw_if_remove_reflection(struct fsl_mc_io *mc_io,
3702 + uint32_t cmd_flags,
3705 + const struct dpsw_reflection_cfg *cfg);
3708 + * enum dpsw_metering_mode - Metering modes
3709 + * @DPSW_METERING_MODE_NONE: metering disabled
3710 + * @DPSW_METERING_MODE_RFC2698: RFC 2698
3711 + * @DPSW_METERING_MODE_RFC4115: RFC 4115
3713 +enum dpsw_metering_mode {
3714 + DPSW_METERING_MODE_NONE = 0,
3715 + DPSW_METERING_MODE_RFC2698,
3716 + DPSW_METERING_MODE_RFC4115
3720 + * enum dpsw_metering_unit - Metering count
3721 + * @DPSW_METERING_UNIT_BYTES: count bytes
3722 + * @DPSW_METERING_UNIT_FRAMES: count frames
3724 +enum dpsw_metering_unit {
3725 + DPSW_METERING_UNIT_BYTES = 0,
3726 + DPSW_METERING_UNIT_FRAMES
3730 + * struct dpsw_metering_cfg - Metering configuration
3731 + * @mode: metering modes
3732 + * @units: Bytes or frame units
3733 + * @cir: Committed information rate (CIR) in Kbits/s
3734 + * @eir: Peak information rate (PIR) Kbit/s rfc2698
3735 + * Excess information rate (EIR) Kbit/s rfc4115
3736 + * @cbs: Committed burst size (CBS) in bytes
3737 + * @ebs: Peak burst size (PBS) in bytes for rfc2698
3738 + * Excess bust size (EBS) in bytes rfc4115
3741 +struct dpsw_metering_cfg {
3742 + enum dpsw_metering_mode mode;
3743 + enum dpsw_metering_unit units;
3751 + * dpsw_if_set_flooding_metering() - Set flooding metering
3752 + * @mc_io: Pointer to MC portal's I/O object
3753 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3754 + * @token: Token of DPSW object
3755 + * @if_id: Interface Identifier
3756 + * @cfg: Metering parameters
3758 + * Return: Completion status. '0' on Success; Error code otherwise.
3760 +int dpsw_if_set_flooding_metering(struct fsl_mc_io *mc_io,
3761 + uint32_t cmd_flags,
3764 + const struct dpsw_metering_cfg *cfg);
3767 + * dpsw_if_set_metering() - Set interface metering for flooding
3768 + * @mc_io: Pointer to MC portal's I/O object
3769 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3770 + * @token: Token of DPSW object
3771 + * @if_id: Interface Identifier
3772 + * @tc_id: Traffic class ID
3773 + * @cfg: Metering parameters
3775 + * Return: Completion status. '0' on Success; Error code otherwise.
3777 +int dpsw_if_set_metering(struct fsl_mc_io *mc_io,
3778 + uint32_t cmd_flags,
3782 + const struct dpsw_metering_cfg *cfg);
3785 + * enum dpsw_early_drop_unit - DPSW early drop unit
3786 + * @DPSW_EARLY_DROP_UNIT_BYTE: count bytes
3787 + * @DPSW_EARLY_DROP_UNIT_FRAMES: count frames
3789 +enum dpsw_early_drop_unit {
3790 + DPSW_EARLY_DROP_UNIT_BYTE = 0,
3791 + DPSW_EARLY_DROP_UNIT_FRAMES
3795 + * enum dpsw_early_drop_mode - DPSW early drop mode
3796 + * @DPSW_EARLY_DROP_MODE_NONE: early drop is disabled
3797 + * @DPSW_EARLY_DROP_MODE_TAIL: early drop in taildrop mode
3798 + * @DPSW_EARLY_DROP_MODE_WRED: early drop in WRED mode
3800 +enum dpsw_early_drop_mode {
3801 + DPSW_EARLY_DROP_MODE_NONE = 0,
3802 + DPSW_EARLY_DROP_MODE_TAIL,
3803 + DPSW_EARLY_DROP_MODE_WRED
3807 + * struct dpsw_wred_cfg - WRED configuration
3808 + * @max_threshold: maximum threshold that packets may be discarded. Above this
3809 + * threshold all packets are discarded; must be less than 2^39;
3810 + * approximated to be expressed as (x+256)*2^(y-1) due to HW
3812 + * @min_threshold: minimum threshold that packets may be discarded at
3813 + * @drop_probability: probability that a packet will be discarded (1-100,
3814 + * associated with the maximum threshold)
3816 +struct dpsw_wred_cfg {
3817 + uint64_t min_threshold;
3818 + uint64_t max_threshold;
3819 + uint8_t drop_probability;
3823 + * struct dpsw_early_drop_cfg - early-drop configuration
3824 + * @drop_mode: drop mode
3825 + * @units: count units
3826 + * @yellow: WRED - 'yellow' configuration
3827 + * @green: WRED - 'green' configuration
3828 + * @tail_drop_threshold: tail drop threshold
3830 +struct dpsw_early_drop_cfg {
3831 + enum dpsw_early_drop_mode drop_mode;
3832 + enum dpsw_early_drop_unit units;
3833 + struct dpsw_wred_cfg yellow;
3834 + struct dpsw_wred_cfg green;
3835 + uint32_t tail_drop_threshold;
3839 + * dpsw_prepare_early_drop() - Prepare an early drop for setting in to interface
3840 + * @cfg: Early-drop configuration
3841 + * @early_drop_buf: Zeroed 256 bytes of memory before mapping it to DMA
3843 + * This function has to be called before dpsw_if_tc_set_early_drop
3846 +void dpsw_prepare_early_drop(const struct dpsw_early_drop_cfg *cfg,
3847 + uint8_t *early_drop_buf);
3850 + * dpsw_if_set_early_drop() - Set interface traffic class early-drop
3852 + * @mc_io: Pointer to MC portal's I/O object
3853 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3854 + * @token: Token of DPSW object
3855 + * @if_id: Interface Identifier
3856 + * @tc_id: Traffic class selection (0-7)
3857 + * @early_drop_iova: I/O virtual address of 64 bytes;
3858 + * Must be cacheline-aligned and DMA-able memory
3860 + * warning: Before calling this function, call dpsw_prepare_if_tc_early_drop()
3861 + * to prepare the early_drop_iova parameter
3863 + * Return: '0' on Success; error code otherwise.
3865 +int dpsw_if_set_early_drop(struct fsl_mc_io *mc_io,
3866 + uint32_t cmd_flags,
3870 + uint64_t early_drop_iova);
3873 + * struct dpsw_custom_tpid_cfg - Structure representing tag Protocol identifier
3874 + * @tpid: An additional tag protocol identifier
3876 +struct dpsw_custom_tpid_cfg {
3881 + * dpsw_add_custom_tpid() - API Configures a distinct Ethernet type value
3882 + * @mc_io: Pointer to MC portal's I/O object
3883 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3884 + * @token: Token of DPSW object
3885 + * @cfg: Tag Protocol identifier
3887 + * API Configures a distinct Ethernet type value (or TPID value)
3888 + * to indicate a VLAN tag in addition to the common
3889 + * TPID values 0x8100 and 0x88A8.
3890 + * Two additional TPID's are supported
3892 + * Return: Completion status. '0' on Success; Error code otherwise.
3894 +int dpsw_add_custom_tpid(struct fsl_mc_io *mc_io,
3895 + uint32_t cmd_flags,
3897 + const struct dpsw_custom_tpid_cfg *cfg);
3900 + * dpsw_remove_custom_tpid - API removes a distinct Ethernet type value
3901 + * @mc_io: Pointer to MC portal's I/O object
3902 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3903 + * @token: Token of DPSW object
3904 + * @cfg: Tag Protocol identifier
3906 + * Return: Completion status. '0' on Success; Error code otherwise.
3908 +int dpsw_remove_custom_tpid(struct fsl_mc_io *mc_io,
3909 + uint32_t cmd_flags,
3911 + const struct dpsw_custom_tpid_cfg *cfg);
3914 + * dpsw_if_enable() - Enable Interface
3915 + * @mc_io: Pointer to MC portal's I/O object
3916 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3917 + * @token: Token of DPSW object
3918 + * @if_id: Interface Identifier
3920 + * Return: Completion status. '0' on Success; Error code otherwise.
3922 +int dpsw_if_enable(struct fsl_mc_io *mc_io,
3923 + uint32_t cmd_flags,
3928 + * dpsw_if_disable() - Disable Interface
3929 + * @mc_io: Pointer to MC portal's I/O object
3930 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3931 + * @token: Token of DPSW object
3932 + * @if_id: Interface Identifier
3934 + * Return: Completion status. '0' on Success; Error code otherwise.
3936 +int dpsw_if_disable(struct fsl_mc_io *mc_io,
3937 + uint32_t cmd_flags,
3942 + * struct dpsw_if_attr - Structure representing DPSW interface attributes
3943 + * @num_tcs: Number of traffic classes
3944 + * @rate: Transmit rate in bits per second
3945 + * @options: Interface configuration options (bitmap)
3946 + * @enabled: Indicates if interface is enabled
3947 + * @accept_all_vlan: The device discards/accepts incoming frames
3948 + * for VLANs that do not include this interface
3949 + * @admit_untagged: When set to 'DPSW_ADMIT_ONLY_VLAN_TAGGED', the device
3950 + * discards untagged frames or priority-tagged frames received on
3952 + * When set to 'DPSW_ADMIT_ALL', untagged frames or priority-
3953 + * tagged frames received on this interface are accepted
3954 + * @qdid: control frames transmit qdid
3956 +struct dpsw_if_attr {
3961 + int accept_all_vlan;
3962 + enum dpsw_accepted_frames admit_untagged;
3967 + * dpsw_if_get_attributes() - Function obtains attributes of interface
3968 + * @mc_io: Pointer to MC portal's I/O object
3969 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3970 + * @token: Token of DPSW object
3971 + * @if_id: Interface Identifier
3972 + * @attr: Returned interface attributes
3974 + * Return: Completion status. '0' on Success; Error code otherwise.
3976 +int dpsw_if_get_attributes(struct fsl_mc_io *mc_io,
3977 + uint32_t cmd_flags,
3980 + struct dpsw_if_attr *attr);
3983 + * dpsw_if_set_max_frame_length() - Set Maximum Receive frame length.
3984 + * @mc_io: Pointer to MC portal's I/O object
3985 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
3986 + * @token: Token of DPSW object
3987 + * @if_id: Interface Identifier
3988 + * @frame_length: Maximum Frame Length
3990 + * Return: Completion status. '0' on Success; Error code otherwise.
3992 +int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
3993 + uint32_t cmd_flags,
3996 + uint16_t frame_length);
3999 + * dpsw_if_get_max_frame_length() - Get Maximum Receive frame length.
4000 + * @mc_io: Pointer to MC portal's I/O object
4001 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4002 + * @token: Token of DPSW object
4003 + * @if_id: Interface Identifier
4004 + * @frame_length: Returned maximum Frame Length
4006 + * Return: Completion status. '0' on Success; Error code otherwise.
4008 +int dpsw_if_get_max_frame_length(struct fsl_mc_io *mc_io,
4009 + uint32_t cmd_flags,
4012 + uint16_t *frame_length);
4015 + * struct dpsw_vlan_cfg - VLAN Configuration
4016 + * @fdb_id: Forwarding Data Base
4018 +struct dpsw_vlan_cfg {
4023 + * dpsw_vlan_add() - Adding new VLAN to DPSW.
4024 + * @mc_io: Pointer to MC portal's I/O object
4025 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4026 + * @token: Token of DPSW object
4027 + * @vlan_id: VLAN Identifier
4028 + * @cfg: VLAN configuration
4030 + * Only VLAN ID and FDB ID are required parameters here.
4031 + * 12 bit VLAN ID is defined in IEEE802.1Q.
4032 + * Adding a duplicate VLAN ID is not allowed.
4033 + * FDB ID can be shared across multiple VLANs. Shared learning
4034 + * is obtained by calling dpsw_vlan_add for multiple VLAN IDs
4035 + * with same fdb_id
4037 + * Return: Completion status. '0' on Success; Error code otherwise.
4039 +int dpsw_vlan_add(struct fsl_mc_io *mc_io,
4040 + uint32_t cmd_flags,
4043 + const struct dpsw_vlan_cfg *cfg);
4046 + * struct dpsw_vlan_if_cfg - Set of VLAN Interfaces
4047 + * @num_ifs: The number of interfaces that are assigned to the egress
4048 + * list for this VLAN
4049 + * @if_id: The set of interfaces that are
4050 + * assigned to the egress list for this VLAN
4052 +struct dpsw_vlan_if_cfg {
4054 + uint16_t if_id[DPSW_MAX_IF];
4058 + * dpsw_vlan_add_if() - Adding a set of interfaces to an existing VLAN.
4059 + * @mc_io: Pointer to MC portal's I/O object
4060 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4061 + * @token: Token of DPSW object
4062 + * @vlan_id: VLAN Identifier
4063 + * @cfg: Set of interfaces to add
4065 + * It adds only interfaces not belonging to this VLAN yet,
4066 + * otherwise an error is generated and an entire command is
4067 + * ignored. This function can be called numerous times always
4068 + * providing required interfaces delta.
4070 + * Return: Completion status. '0' on Success; Error code otherwise.
4072 +int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
4073 + uint32_t cmd_flags,
4076 + const struct dpsw_vlan_if_cfg *cfg);
4079 + * dpsw_vlan_add_if_untagged() - Defining a set of interfaces that should be
4080 + * transmitted as untagged.
4081 + * @mc_io: Pointer to MC portal's I/O object
4082 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4083 + * @token: Token of DPSW object
4084 + * @vlan_id: VLAN Identifier
4085 + * @cfg: set of interfaces that should be transmitted as untagged
4087 + * These interfaces should already belong to this VLAN.
4088 + * By default all interfaces are transmitted as tagged.
4089 + * Providing un-existing interface or untagged interface that is
4090 + * configured untagged already generates an error and the entire
4091 + * command is ignored.
4093 + * Return: Completion status. '0' on Success; Error code otherwise.
4095 +int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
4096 + uint32_t cmd_flags,
4099 + const struct dpsw_vlan_if_cfg *cfg);
4102 + * dpsw_vlan_add_if_flooding() - Define a set of interfaces that should be
4103 + * included in flooding when frame with unknown destination
4104 + * unicast MAC arrived.
4105 + * @mc_io: Pointer to MC portal's I/O object
4106 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4107 + * @token: Token of DPSW object
4108 + * @vlan_id: VLAN Identifier
4109 + * @cfg: Set of interfaces that should be used for flooding
4111 + * These interfaces should belong to this VLAN. By default all
4112 + * interfaces are included into flooding list. Providing
4113 + * un-existing interface or an interface that already in the
4114 + * flooding list generates an error and the entire command is
4117 + * Return: Completion status. '0' on Success; Error code otherwise.
4119 +int dpsw_vlan_add_if_flooding(struct fsl_mc_io *mc_io,
4120 + uint32_t cmd_flags,
4123 + const struct dpsw_vlan_if_cfg *cfg);
4126 + * dpsw_vlan_remove_if() - Remove interfaces from an existing VLAN.
4127 + * @mc_io: Pointer to MC portal's I/O object
4128 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4129 + * @token: Token of DPSW object
4130 + * @vlan_id: VLAN Identifier
4131 + * @cfg: Set of interfaces that should be removed
4133 + * Interfaces must belong to this VLAN, otherwise an error
4134 + * is returned and an the command is ignored
4136 + * Return: Completion status. '0' on Success; Error code otherwise.
4138 +int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
4139 + uint32_t cmd_flags,
4142 + const struct dpsw_vlan_if_cfg *cfg);
4145 + * dpsw_vlan_remove_if_untagged() - Define a set of interfaces that should be
4146 + * converted from transmitted as untagged to transmit as tagged.
4147 + * @mc_io: Pointer to MC portal's I/O object
4148 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4149 + * @token: Token of DPSW object
4150 + * @vlan_id: VLAN Identifier
4151 + * @cfg: set of interfaces that should be removed
4153 + * Interfaces provided by API have to belong to this VLAN and
4154 + * configured untagged, otherwise an error is returned and the
4155 + * command is ignored
4157 + * Return: Completion status. '0' on Success; Error code otherwise.
4159 +int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
4160 + uint32_t cmd_flags,
4163 + const struct dpsw_vlan_if_cfg *cfg);
4166 + * dpsw_vlan_remove_if_flooding() - Define a set of interfaces that should be
4167 + * removed from the flooding list.
4168 + * @mc_io: Pointer to MC portal's I/O object
4169 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4170 + * @token: Token of DPSW object
4171 + * @vlan_id: VLAN Identifier
4172 + * @cfg: set of interfaces used for flooding
4174 + * Return: Completion status. '0' on Success; Error code otherwise.
4176 +int dpsw_vlan_remove_if_flooding(struct fsl_mc_io *mc_io,
4177 + uint32_t cmd_flags,
4180 + const struct dpsw_vlan_if_cfg *cfg);
4183 + * dpsw_vlan_remove() - Remove an entire VLAN
4184 + * @mc_io: Pointer to MC portal's I/O object
4185 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4186 + * @token: Token of DPSW object
4187 + * @vlan_id: VLAN Identifier
4189 + * Return: Completion status. '0' on Success; Error code otherwise.
4191 +int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
4192 + uint32_t cmd_flags,
4194 + uint16_t vlan_id);
4197 + * struct dpsw_vlan_attr - VLAN attributes
4198 + * @fdb_id: Associated FDB ID
4199 + * @num_ifs: Number of interfaces
4200 + * @num_untagged_ifs: Number of untagged interfaces
4201 + * @num_flooding_ifs: Number of flooding interfaces
4203 +struct dpsw_vlan_attr {
4206 + uint16_t num_untagged_ifs;
4207 + uint16_t num_flooding_ifs;
4211 + * dpsw_vlan_get_attributes() - Get VLAN attributes
4212 + * @mc_io: Pointer to MC portal's I/O object
4213 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4214 + * @token: Token of DPSW object
4215 + * @vlan_id: VLAN Identifier
4216 + * @attr: Returned DPSW attributes
4218 + * Return: Completion status. '0' on Success; Error code otherwise.
4220 +int dpsw_vlan_get_attributes(struct fsl_mc_io *mc_io,
4221 + uint32_t cmd_flags,
4224 + struct dpsw_vlan_attr *attr);
4227 + * dpsw_vlan_get_if() - Get interfaces belong to this VLAN
4228 + * @mc_io: Pointer to MC portal's I/O object
4229 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4230 + * @token: Token of DPSW object
4231 + * @vlan_id: VLAN Identifier
4232 + * @cfg: Returned set of interfaces belong to this VLAN
4234 + * Return: Completion status. '0' on Success; Error code otherwise.
4236 +int dpsw_vlan_get_if(struct fsl_mc_io *mc_io,
4237 + uint32_t cmd_flags,
4240 + struct dpsw_vlan_if_cfg *cfg);
4243 + * dpsw_vlan_get_if_flooding() - Get interfaces used in flooding for this VLAN
4244 + * @mc_io: Pointer to MC portal's I/O object
4245 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4246 + * @token: Token of DPSW object
4247 + * @vlan_id: VLAN Identifier
4248 + * @cfg: Returned set of flooding interfaces
4250 + * Return: Completion status. '0' on Success; Error code otherwise.
4252 +int dpsw_vlan_get_if_flooding(struct fsl_mc_io *mc_io,
4253 + uint32_t cmd_flags,
4256 + struct dpsw_vlan_if_cfg *cfg);
4259 + * dpsw_vlan_get_if_untagged() - Get interfaces that should be transmitted as
4261 + * @mc_io: Pointer to MC portal's I/O object
4262 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4263 + * @token: Token of DPSW object
4264 + * @vlan_id: VLAN Identifier
4265 + * @cfg: Returned set of untagged interfaces
4267 + * Return: Completion status. '0' on Success; Error code otherwise.
4269 +int dpsw_vlan_get_if_untagged(struct fsl_mc_io *mc_io,
4270 + uint32_t cmd_flags,
4273 + struct dpsw_vlan_if_cfg *cfg);
4276 + * struct dpsw_fdb_cfg - FDB Configuration
4277 + * @num_fdb_entries: Number of FDB entries
4278 + * @fdb_aging_time: Aging time in seconds
4280 +struct dpsw_fdb_cfg {
4281 + uint16_t num_fdb_entries;
4282 + uint16_t fdb_aging_time;
4286 + * dpsw_fdb_add() - Add FDB to switch and Returns handle to FDB table for
4288 + * @mc_io: Pointer to MC portal's I/O object
4289 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4290 + * @token: Token of DPSW object
4291 + * @fdb_id: Returned Forwarding Database Identifier
4292 + * @cfg: FDB Configuration
4294 + * Return: Completion status. '0' on Success; Error code otherwise.
4296 +int dpsw_fdb_add(struct fsl_mc_io *mc_io,
4297 + uint32_t cmd_flags,
4300 + const struct dpsw_fdb_cfg *cfg);
4303 + * dpsw_fdb_remove() - Remove FDB from switch
4304 + * @mc_io: Pointer to MC portal's I/O object
4305 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4306 + * @token: Token of DPSW object
4307 + * @fdb_id: Forwarding Database Identifier
4309 + * Return: Completion status. '0' on Success; Error code otherwise.
4311 +int dpsw_fdb_remove(struct fsl_mc_io *mc_io,
4312 + uint32_t cmd_flags,
4317 + * enum dpsw_fdb_entry_type - FDB Entry type - Static/Dynamic
4318 + * @DPSW_FDB_ENTRY_STATIC: Static entry
4319 + * @DPSW_FDB_ENTRY_DINAMIC: Dynamic entry
4321 +enum dpsw_fdb_entry_type {
4322 + DPSW_FDB_ENTRY_STATIC = 0,
4323 + DPSW_FDB_ENTRY_DINAMIC = 1
4327 + * struct dpsw_fdb_unicast_cfg - Unicast entry configuration
4328 + * @type: Select static or dynamic entry
4329 + * @mac_addr: MAC address
4330 + * @if_egress: Egress interface ID
4332 +struct dpsw_fdb_unicast_cfg {
4333 + enum dpsw_fdb_entry_type type;
4334 + uint8_t mac_addr[6];
4335 + uint16_t if_egress;
4339 + * dpsw_fdb_add_unicast() - Function adds an unicast entry into MAC lookup table
4340 + * @mc_io: Pointer to MC portal's I/O object
4341 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4342 + * @token: Token of DPSW object
4343 + * @fdb_id: Forwarding Database Identifier
4344 + * @cfg: Unicast entry configuration
4346 + * Return: Completion status. '0' on Success; Error code otherwise.
4348 +int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
4349 + uint32_t cmd_flags,
4352 + const struct dpsw_fdb_unicast_cfg *cfg);
4355 + * dpsw_fdb_get_unicast() - Get unicast entry from MAC lookup table by
4356 + * unicast Ethernet address
4357 + * @mc_io: Pointer to MC portal's I/O object
4358 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4359 + * @token: Token of DPSW object
4360 + * @fdb_id: Forwarding Database Identifier
4361 + * @cfg: Returned unicast entry configuration
4363 + * Return: Completion status. '0' on Success; Error code otherwise.
4365 +int dpsw_fdb_get_unicast(struct fsl_mc_io *mc_io,
4366 + uint32_t cmd_flags,
4369 + struct dpsw_fdb_unicast_cfg *cfg);
4372 + * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table
4373 + * @mc_io: Pointer to MC portal's I/O object
4374 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4375 + * @token: Token of DPSW object
4376 + * @fdb_id: Forwarding Database Identifier
4377 + * @cfg: Unicast entry configuration
4379 + * Return: Completion status. '0' on Success; Error code otherwise.
4381 +int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
4382 + uint32_t cmd_flags,
4385 + const struct dpsw_fdb_unicast_cfg *cfg);
4388 + * struct dpsw_fdb_multicast_cfg - Multi-cast entry configuration
4389 + * @type: Select static or dynamic entry
4390 + * @mac_addr: MAC address
4391 + * @num_ifs: Number of external and internal interfaces
4392 + * @if_id: Egress interface IDs
4394 +struct dpsw_fdb_multicast_cfg {
4395 + enum dpsw_fdb_entry_type type;
4396 + uint8_t mac_addr[6];
4398 + uint16_t if_id[DPSW_MAX_IF];
4402 + * dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group
4403 + * @mc_io: Pointer to MC portal's I/O object
4404 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4405 + * @token: Token of DPSW object
4406 + * @fdb_id: Forwarding Database Identifier
4407 + * @cfg: Multicast entry configuration
4409 + * If group doesn't exist, it will be created.
4410 + * It adds only interfaces not belonging to this multicast group
4411 + * yet, otherwise error will be generated and the command is
4413 + * This function may be called numerous times always providing
4414 + * required interfaces delta.
4416 + * Return: Completion status. '0' on Success; Error code otherwise.
4418 +int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
4419 + uint32_t cmd_flags,
4422 + const struct dpsw_fdb_multicast_cfg *cfg);
4425 + * dpsw_fdb_get_multicast() - Reading multi-cast group by multi-cast Ethernet
4427 + * @mc_io: Pointer to MC portal's I/O object
4428 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4429 + * @token: Token of DPSW object
4430 + * @fdb_id: Forwarding Database Identifier
4431 + * @cfg: Returned multicast entry configuration
4433 + * Return: Completion status. '0' on Success; Error code otherwise.
4435 +int dpsw_fdb_get_multicast(struct fsl_mc_io *mc_io,
4436 + uint32_t cmd_flags,
4439 + struct dpsw_fdb_multicast_cfg *cfg);
4442 + * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast
4444 + * @mc_io: Pointer to MC portal's I/O object
4445 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4446 + * @token: Token of DPSW object
4447 + * @fdb_id: Forwarding Database Identifier
4448 + * @cfg: Multicast entry configuration
4450 + * Interfaces provided by this API have to exist in the group,
4451 + * otherwise an error will be returned and an entire command
4452 + * ignored. If there is no interface left in the group,
4453 + * an entire group is deleted
4455 + * Return: Completion status. '0' on Success; Error code otherwise.
4457 +int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
4458 + uint32_t cmd_flags,
4461 + const struct dpsw_fdb_multicast_cfg *cfg);
4464 + * enum dpsw_fdb_learning_mode - Auto-learning modes
4465 + * @DPSW_FDB_LEARNING_MODE_DIS: Disable Auto-learning
4466 + * @DPSW_FDB_LEARNING_MODE_HW: Enable HW auto-Learning
4467 + * @DPSW_FDB_LEARNING_MODE_NON_SECURE: Enable None secure learning by CPU
4468 + * @DPSW_FDB_LEARNING_MODE_SECURE: Enable secure learning by CPU
4470 + * NONE - SECURE LEARNING
4471 + * SMAC found DMAC found CTLU Action
4472 + * v v Forward frame to
4473 + * 1. DMAC destination
4474 + * - v Forward frame to
4475 + * 1. DMAC destination
4476 + * 2. Control interface
4477 + * v - Forward frame to
4478 + * 1. Flooding list of interfaces
4479 + * - - Forward frame to
4480 + * 1. Flooding list of interfaces
4481 + * 2. Control interface
4483 + * SMAC found DMAC found CTLU Action
4484 + * v v Forward frame to
4485 + * 1. DMAC destination
4486 + * - v Forward frame to
4487 + * 1. Control interface
4488 + * v - Forward frame to
4489 + * 1. Flooding list of interfaces
4490 + * - - Forward frame to
4491 + * 1. Control interface
4493 +enum dpsw_fdb_learning_mode {
4494 + DPSW_FDB_LEARNING_MODE_DIS = 0,
4495 + DPSW_FDB_LEARNING_MODE_HW = 1,
4496 + DPSW_FDB_LEARNING_MODE_NON_SECURE = 2,
4497 + DPSW_FDB_LEARNING_MODE_SECURE = 3
4501 + * dpsw_fdb_set_learning_mode() - Define FDB learning mode
4502 + * @mc_io: Pointer to MC portal's I/O object
4503 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4504 + * @token: Token of DPSW object
4505 + * @fdb_id: Forwarding Database Identifier
4506 + * @mode: learning mode
4508 + * Return: Completion status. '0' on Success; Error code otherwise.
4510 +int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
4511 + uint32_t cmd_flags,
4514 + enum dpsw_fdb_learning_mode mode);
4517 + * struct dpsw_fdb_attr - FDB Attributes
4518 + * @max_fdb_entries: Number of FDB entries
4519 + * @fdb_aging_time: Aging time in seconds
4520 + * @learning_mode: Learning mode
4521 + * @num_fdb_mc_groups: Current number of multicast groups
4522 + * @max_fdb_mc_groups: Maximum number of multicast groups
4524 +struct dpsw_fdb_attr {
4525 + uint16_t max_fdb_entries;
4526 + uint16_t fdb_aging_time;
4527 + enum dpsw_fdb_learning_mode learning_mode;
4528 + uint16_t num_fdb_mc_groups;
4529 + uint16_t max_fdb_mc_groups;
4533 + * dpsw_fdb_get_attributes() - Get FDB attributes
4534 + * @mc_io: Pointer to MC portal's I/O object
4535 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4536 + * @token: Token of DPSW object
4537 + * @fdb_id: Forwarding Database Identifier
4538 + * @attr: Returned FDB attributes
4540 + * Return: Completion status. '0' on Success; Error code otherwise.
4542 +int dpsw_fdb_get_attributes(struct fsl_mc_io *mc_io,
4543 + uint32_t cmd_flags,
4546 + struct dpsw_fdb_attr *attr);
4549 + * struct dpsw_acl_cfg - ACL Configuration
4550 + * @max_entries: Number of FDB entries
4552 +struct dpsw_acl_cfg {
4553 + uint16_t max_entries;
4557 + * struct dpsw_acl_fields - ACL fields.
4558 + * @l2_dest_mac: Destination MAC address: BPDU, Multicast, Broadcast, Unicast,
4559 + * slow protocols, MVRP, STP
4560 + * @l2_source_mac: Source MAC address
4561 + * @l2_tpid: Layer 2 (Ethernet) protocol type, used to identify the following
4562 + * protocols: MPLS, PTP, PFC, ARP, Jumbo frames, LLDP, IEEE802.1ae,
4563 + * Q-in-Q, IPv4, IPv6, PPPoE
4564 + * @l2_pcp_dei: indicate which protocol is encapsulated in the payload
4565 + * @l2_vlan_id: layer 2 VLAN ID
4566 + * @l2_ether_type: layer 2 Ethernet type
4567 + * @l3_dscp: Layer 3 differentiated services code point
4568 + * @l3_protocol: Tells the Network layer at the destination host, to which
4569 + * Protocol this packet belongs to. The following protocol are
4570 + * supported: ICMP, IGMP, IPv4 (encapsulation), TCP, IPv6
4571 + * (encapsulation), GRE, PTP
4572 + * @l3_source_ip: Source IPv4 IP
4573 + * @l3_dest_ip: Destination IPv4 IP
4574 + * @l4_source_port: Source TCP/UDP Port
4575 + * @l4_dest_port: Destination TCP/UDP Port
4577 +struct dpsw_acl_fields {
4578 + uint8_t l2_dest_mac[6];
4579 + uint8_t l2_source_mac[6];
4581 + uint8_t l2_pcp_dei;
4582 + uint16_t l2_vlan_id;
4583 + uint16_t l2_ether_type;
4585 + uint8_t l3_protocol;
4586 + uint32_t l3_source_ip;
4587 + uint32_t l3_dest_ip;
4588 + uint16_t l4_source_port;
4589 + uint16_t l4_dest_port;
4593 + * struct dpsw_acl_key - ACL key
4594 + * @match: Match fields
4595 + * @mask: Mask: b'1 - valid, b'0 don't care
4597 +struct dpsw_acl_key {
4598 + struct dpsw_acl_fields match;
4599 + struct dpsw_acl_fields mask;
4603 + * enum dpsw_acl_action
4604 + * @DPSW_ACL_ACTION_DROP: Drop frame
4605 + * @DPSW_ACL_ACTION_REDIRECT: Redirect to certain port
4606 + * @DPSW_ACL_ACTION_ACCEPT: Accept frame
4607 + * @DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF: Redirect to control interface
4609 +enum dpsw_acl_action {
4610 + DPSW_ACL_ACTION_DROP,
4611 + DPSW_ACL_ACTION_REDIRECT,
4612 + DPSW_ACL_ACTION_ACCEPT,
4613 + DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF
4617 + * struct dpsw_acl_result - ACL action
4618 + * @action: Action should be taken when ACL entry hit
4619 + * @if_id: Interface IDs to redirect frame. Valid only if redirect selected for
4622 +struct dpsw_acl_result {
4623 + enum dpsw_acl_action action;
4628 + * struct dpsw_acl_entry_cfg - ACL entry
4629 + * @key_iova: I/O virtual address of DMA-able memory filled with key after call
4630 + * to dpsw_acl_prepare_entry_cfg()
4631 + * @result: Required action when entry hit occurs
4632 + * @precedence: Precedence inside ACL 0 is lowest; This priority can not change
4633 + * during the lifetime of a Policy. It is user responsibility to
4634 + * space the priorities according to consequent rule additions.
4636 +struct dpsw_acl_entry_cfg {
4637 + uint64_t key_iova;
4638 + struct dpsw_acl_result result;
4643 + * dpsw_acl_add() - Adds ACL to L2 switch.
4644 + * @mc_io: Pointer to MC portal's I/O object
4645 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4646 + * @token: Token of DPSW object
4647 + * @acl_id: Returned ACL ID, for the future reference
4648 + * @cfg: ACL configuration
4650 + * Create Access Control List. Multiple ACLs can be created and
4651 + * co-exist in L2 switch
4653 + * Return: '0' on Success; Error code otherwise.
4655 +int dpsw_acl_add(struct fsl_mc_io *mc_io,
4656 + uint32_t cmd_flags,
4659 + const struct dpsw_acl_cfg *cfg);
4662 + * dpsw_acl_remove() - Removes ACL from L2 switch.
4663 + * @mc_io: Pointer to MC portal's I/O object
4664 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4665 + * @token: Token of DPSW object
4668 + * Return: '0' on Success; Error code otherwise.
4670 +int dpsw_acl_remove(struct fsl_mc_io *mc_io,
4671 + uint32_t cmd_flags,
4676 + * dpsw_acl_prepare_entry_cfg() - Set an entry to ACL.
4678 + * @entry_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
4680 + * This function has to be called before adding or removing acl_entry
4683 +void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key,
4684 + uint8_t *entry_cfg_buf);
4687 + * dpsw_acl_add_entry() - Adds an entry to ACL.
4688 + * @mc_io: Pointer to MC portal's I/O object
4689 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4690 + * @token: Token of DPSW object
4692 + * @cfg: entry configuration
4694 + * warning: This function has to be called after dpsw_acl_set_entry_cfg()
4696 + * Return: '0' on Success; Error code otherwise.
4698 +int dpsw_acl_add_entry(struct fsl_mc_io *mc_io,
4699 + uint32_t cmd_flags,
4702 + const struct dpsw_acl_entry_cfg *cfg);
4705 + * dpsw_acl_remove_entry() - Removes an entry from ACL.
4706 + * @mc_io: Pointer to MC portal's I/O object
4707 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4708 + * @token: Token of DPSW object
4710 + * @cfg: entry configuration
4712 + * warning: This function has to be called after dpsw_acl_set_entry_cfg()
4714 + * Return: '0' on Success; Error code otherwise.
4716 +int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io,
4717 + uint32_t cmd_flags,
4720 + const struct dpsw_acl_entry_cfg *cfg);
4723 + * struct dpsw_acl_if_cfg - List of interfaces to Associate with ACL
4724 + * @num_ifs: Number of interfaces
4725 + * @if_id: List of interfaces
4727 +struct dpsw_acl_if_cfg {
4729 + uint16_t if_id[DPSW_MAX_IF];
4733 + * dpsw_acl_add_if() - Associate interface/interfaces with ACL.
4734 + * @mc_io: Pointer to MC portal's I/O object
4735 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4736 + * @token: Token of DPSW object
4738 + * @cfg: interfaces list
4740 + * Return: '0' on Success; Error code otherwise.
4742 +int dpsw_acl_add_if(struct fsl_mc_io *mc_io,
4743 + uint32_t cmd_flags,
4746 + const struct dpsw_acl_if_cfg *cfg);
4749 + * dpsw_acl_remove_if() - De-associate interface/interfaces from ACL.
4750 + * @mc_io: Pointer to MC portal's I/O object
4751 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4752 + * @token: Token of DPSW object
4754 + * @cfg: interfaces list
4756 + * Return: '0' on Success; Error code otherwise.
4758 +int dpsw_acl_remove_if(struct fsl_mc_io *mc_io,
4759 + uint32_t cmd_flags,
4762 + const struct dpsw_acl_if_cfg *cfg);
4765 + * struct dpsw_acl_attr - ACL Attributes
4766 + * @max_entries: Max number of ACL entries
4767 + * @num_entries: Number of used ACL entries
4768 + * @num_ifs: Number of interfaces associated with ACL
4770 +struct dpsw_acl_attr {
4771 + uint16_t max_entries;
4772 + uint16_t num_entries;
4777 +* dpsw_acl_get_attributes() - Get specific counter of particular interface
4778 +* @mc_io: Pointer to MC portal's I/O object
4779 +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4780 +* @token: Token of DPSW object
4781 +* @acl_id: ACL Identifier
4782 +* @attr: Returned ACL attributes
4784 +* Return: '0' on Success; Error code otherwise.
4786 +int dpsw_acl_get_attributes(struct fsl_mc_io *mc_io,
4787 + uint32_t cmd_flags,
4790 + struct dpsw_acl_attr *attr);
4792 +* struct dpsw_ctrl_if_attr - Control interface attributes
4793 +* @rx_fqid: Receive FQID
4794 +* @rx_err_fqid: Receive error FQID
4795 +* @tx_err_conf_fqid: Transmit error and confirmation FQID
4797 +struct dpsw_ctrl_if_attr {
4799 + uint32_t rx_err_fqid;
4800 + uint32_t tx_err_conf_fqid;
4804 +* dpsw_ctrl_if_get_attributes() - Obtain control interface attributes
4805 +* @mc_io: Pointer to MC portal's I/O object
4806 +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4807 +* @token: Token of DPSW object
4808 +* @attr: Returned control interface attributes
4810 +* Return: '0' on Success; Error code otherwise.
4812 +int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io,
4813 + uint32_t cmd_flags,
4815 + struct dpsw_ctrl_if_attr *attr);
4818 + * Maximum number of DPBP
4820 +#define DPSW_MAX_DPBP 8
4823 + * struct dpsw_ctrl_if_pools_cfg - Control interface buffer pools configuration
4824 + * @num_dpbp: Number of DPBPs
4825 + * @pools: Array of buffer pools parameters; The number of valid entries
4826 + * must match 'num_dpbp' value
4828 +struct dpsw_ctrl_if_pools_cfg {
4831 + * struct pools - Buffer pools parameters
4832 + * @dpbp_id: DPBP object ID
4833 + * @buffer_size: Buffer size
4834 + * @backup_pool: Backup pool
4838 + uint16_t buffer_size;
4840 + } pools[DPSW_MAX_DPBP];
4844 +* dpsw_ctrl_if_set_pools() - Set control interface buffer pools
4845 +* @mc_io: Pointer to MC portal's I/O object
4846 +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4847 +* @token: Token of DPSW object
4848 +* @cfg: buffer pools configuration
4850 +* Return: '0' on Success; Error code otherwise.
4852 +int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io,
4853 + uint32_t cmd_flags,
4855 + const struct dpsw_ctrl_if_pools_cfg *cfg);
4858 +* dpsw_ctrl_if_enable() - Enable control interface
4859 +* @mc_io: Pointer to MC portal's I/O object
4860 +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4861 +* @token: Token of DPSW object
4863 +* Return: '0' on Success; Error code otherwise.
4865 +int dpsw_ctrl_if_enable(struct fsl_mc_io *mc_io,
4866 + uint32_t cmd_flags,
4870 +* dpsw_ctrl_if_disable() - Function disables control interface
4871 +* @mc_io: Pointer to MC portal's I/O object
4872 +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
4873 +* @token: Token of DPSW object
4875 +* Return: '0' on Success; Error code otherwise.
4877 +int dpsw_ctrl_if_disable(struct fsl_mc_io *mc_io,
4878 + uint32_t cmd_flags,
4881 +#endif /* __FSL_DPSW_H */
4883 +++ b/drivers/staging/fsl-dpaa2/ethsw/switch.c
4885 +/* Copyright 2014-2015 Freescale Semiconductor Inc.
4887 + * Redistribution and use in source and binary forms, with or without
4888 + * modification, are permitted provided that the following conditions are met:
4889 + * * Redistributions of source code must retain the above copyright
4890 + * notice, this list of conditions and the following disclaimer.
4891 + * * Redistributions in binary form must reproduce the above copyright
4892 + * notice, this list of conditions and the following disclaimer in the
4893 + * documentation and/or other materials provided with the distribution.
4894 + * * Neither the name of Freescale Semiconductor nor the
4895 + * names of its contributors may be used to endorse or promote products
4896 + * derived from this software without specific prior written permission.
4899 + * ALTERNATIVELY, this software may be distributed under the terms of the
4900 + * GNU General Public License ("GPL") as published by the Free Software
4901 + * Foundation, either version 2 of that License or (at your option) any
4904 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
4905 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4906 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
4907 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
4908 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4909 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4910 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4911 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4912 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4913 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4916 +#include <linux/module.h>
4918 +#include <linux/netdevice.h>
4919 +#include <linux/etherdevice.h>
4920 +#include <linux/rtnetlink.h>
4921 +#include <linux/if_vlan.h>
4922 +#include <linux/interrupt.h>
4923 +#include <linux/msi.h>
4925 +#include <uapi/linux/if_bridge.h>
4926 +#include <net/netlink.h>
4928 +#include "../../fsl-mc/include/mc.h"
4930 +#include "dpsw-cmd.h"
4932 +/* Minimal supported DPSE version */
4933 +#define DPSW_MIN_VER_MAJOR 7
4934 +#define DPSW_MIN_VER_MINOR 0
4937 +#define DPSW_MAX_IRQ_NUM 2
4939 +#define ETHSW_VLAN_MEMBER 1
4940 +#define ETHSW_VLAN_UNTAGGED 2
4941 +#define ETHSW_VLAN_PVID 4
4942 +#define ETHSW_VLAN_GLOBAL 8
4944 +struct ethsw_port_priv {
4945 + struct net_device *netdev;
4946 + struct list_head list;
4948 + struct ethsw_dev_priv *ethsw_priv;
4951 + char vlans[VLAN_VID_MASK+1];
4955 +struct ethsw_dev_priv {
4956 + struct net_device *netdev;
4957 + struct fsl_mc_io *mc_io;
4958 + uint16_t dpsw_handle;
4959 + struct dpsw_attr sw_attr;
4961 + /*TODO: redundant, we can use the slave dev list */
4962 + struct list_head port_list;
4967 + char vlans[VLAN_VID_MASK+1];
4970 +static int ethsw_port_stop(struct net_device *netdev);
4971 +static int ethsw_port_open(struct net_device *netdev);
4973 +static inline void __get_priv(struct net_device *netdev,
4974 + struct ethsw_dev_priv **priv,
4975 + struct ethsw_port_priv **port_priv)
4977 + struct ethsw_dev_priv *_priv = NULL;
4978 + struct ethsw_port_priv *_port_priv = NULL;
4980 + if (netdev->flags & IFF_MASTER) {
4981 + _priv = netdev_priv(netdev);
4983 + _port_priv = netdev_priv(netdev);
4984 + _priv = _port_priv->ethsw_priv;
4990 + *port_priv = _port_priv;
4993 +/* -------------------------------------------------------------------------- */
4994 +/* ethsw netdevice ops */
4996 +static netdev_tx_t ethsw_dropframe(struct sk_buff *skb, struct net_device *dev)
4998 + /* we don't support I/O for now, drop the frame */
4999 + dev_kfree_skb_any(skb);
5000 + return NETDEV_TX_OK;
5003 +static int ethsw_open(struct net_device *netdev)
5005 + struct ethsw_dev_priv *priv = netdev_priv(netdev);
5006 + struct list_head *pos;
5007 + struct ethsw_port_priv *port_priv = NULL;
5010 + err = dpsw_enable(priv->mc_io, 0, priv->dpsw_handle);
5012 + netdev_err(netdev, "dpsw_enable err %d\n", err);
5016 + list_for_each(pos, &priv->port_list) {
5017 + port_priv = list_entry(pos, struct ethsw_port_priv, list);
5018 + err = dev_open(port_priv->netdev);
5020 + netdev_err(port_priv->netdev, "dev_open err %d\n", err);
5026 +static int ethsw_stop(struct net_device *netdev)
5028 + struct ethsw_dev_priv *priv = netdev_priv(netdev);
5029 + struct list_head *pos;
5030 + struct ethsw_port_priv *port_priv = NULL;
5033 + err = dpsw_disable(priv->mc_io, 0, priv->dpsw_handle);
5035 + netdev_err(netdev, "dpsw_disable err %d\n", err);
5039 + list_for_each(pos, &priv->port_list) {
5040 + port_priv = list_entry(pos, struct ethsw_port_priv, list);
5041 + err = dev_close(port_priv->netdev);
5043 + netdev_err(port_priv->netdev,
5044 + "dev_close err %d\n", err);
5050 +static int ethsw_add_vlan(struct net_device *netdev, u16 vid)
5052 + struct ethsw_dev_priv *priv = netdev_priv(netdev);
5055 + struct dpsw_vlan_cfg vcfg = {
5056 + /* TODO: add support for VLAN private FDBs */
5059 + if (priv->vlans[vid]) {
5060 + netdev_err(netdev, "VLAN already configured\n");
5064 + err = dpsw_vlan_add(priv->mc_io, 0, priv->dpsw_handle, vid, &vcfg);
5066 + netdev_err(netdev, "dpsw_vlan_add err %d\n", err);
5069 + priv->vlans[vid] = ETHSW_VLAN_MEMBER;
5074 +static int ethsw_port_add_vlan(struct net_device *netdev, u16 vid, u16 flags)
5076 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5077 + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
5080 + struct dpsw_vlan_if_cfg vcfg = {
5082 + .if_id[0] = port_priv->port_index,
5085 + if (port_priv->vlans[vid]) {
5086 + netdev_err(netdev, "VLAN already configured\n");
5090 + if (flags & BRIDGE_VLAN_INFO_PVID && netif_oper_up(netdev)) {
5091 + netdev_err(netdev, "interface must be down to change PVID!\n");
5095 + err = dpsw_vlan_add_if(priv->mc_io, 0, priv->dpsw_handle, vid, &vcfg);
5097 + netdev_err(netdev, "dpsw_vlan_add_if err %d\n", err);
5100 + port_priv->vlans[vid] = ETHSW_VLAN_MEMBER;
5102 + if (flags & BRIDGE_VLAN_INFO_UNTAGGED) {
5103 + err = dpsw_vlan_add_if_untagged(priv->mc_io, 0,
5104 + priv->dpsw_handle, vid, &vcfg);
5106 + netdev_err(netdev, "dpsw_vlan_add_if_untagged err %d\n",
5110 + port_priv->vlans[vid] |= ETHSW_VLAN_UNTAGGED;
5113 + if (flags & BRIDGE_VLAN_INFO_PVID) {
5114 + struct dpsw_tci_cfg tci_cfg = {
5115 + /* TODO: at least add better defaults if these cannot
5123 + err = dpsw_if_set_tci(priv->mc_io, 0, priv->dpsw_handle,
5124 + port_priv->port_index, &tci_cfg);
5126 + netdev_err(netdev, "dpsw_if_set_tci err %d\n", err);
5129 + port_priv->vlans[vid] |= ETHSW_VLAN_PVID;
5135 +static const struct nla_policy ifla_br_policy[IFLA_MAX+1] = {
5136 + [IFLA_BRIDGE_FLAGS] = { .type = NLA_U16 },
5137 + [IFLA_BRIDGE_MODE] = { .type = NLA_U16 },
5138 + [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY,
5139 + .len = sizeof(struct bridge_vlan_info), },
5142 +static int ethsw_setlink_af_spec(struct net_device *netdev,
5143 + struct nlattr **tb)
5145 + struct bridge_vlan_info *vinfo;
5146 + struct ethsw_dev_priv *priv = NULL;
5147 + struct ethsw_port_priv *port_priv = NULL;
5150 + if (!tb[IFLA_BRIDGE_VLAN_INFO]) {
5151 + netdev_err(netdev, "no VLAN INFO in nlmsg\n");
5152 + return -EOPNOTSUPP;
5155 + vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]);
5157 + if (!vinfo->vid || vinfo->vid > VLAN_VID_MASK)
5160 + __get_priv(netdev, &priv, &port_priv);
5162 + if (!port_priv || !priv->vlans[vinfo->vid]) {
5163 + /* command targets switch device or this is a new VLAN */
5164 + err = ethsw_add_vlan(priv->netdev, vinfo->vid);
5168 + /* command targets switch device; mark it*/
5170 + priv->vlans[vinfo->vid] |= ETHSW_VLAN_GLOBAL;
5174 + /* command targets switch port */
5175 + err = ethsw_port_add_vlan(netdev, vinfo->vid, vinfo->flags);
5183 +static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
5184 + [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
5185 + [IFLA_BRPORT_COST] = { .type = NLA_U32 },
5186 + [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
5187 + [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
5188 + [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
5189 + [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
5190 + [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
5191 + [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
5194 +static int ethsw_set_learning(struct net_device *netdev, u8 flag)
5196 + struct ethsw_dev_priv *priv = netdev_priv(netdev);
5197 + enum dpsw_fdb_learning_mode learn_mode;
5201 + learn_mode = DPSW_FDB_LEARNING_MODE_HW;
5203 + learn_mode = DPSW_FDB_LEARNING_MODE_DIS;
5205 + err = dpsw_fdb_set_learning_mode(priv->mc_io, 0, priv->dpsw_handle,
5208 + netdev_err(netdev, "dpsw_fdb_set_learning_mode err %d\n", err);
5211 + priv->learning = !!flag;
5216 +static int ethsw_port_set_flood(struct net_device *netdev, u8 flag)
5218 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5219 + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
5222 + err = dpsw_if_set_flooding(priv->mc_io, 0, priv->dpsw_handle,
5223 + port_priv->port_index, (int)flag);
5225 + netdev_err(netdev, "dpsw_fdb_set_learning_mode err %d\n", err);
5228 + priv->flood = !!flag;
5233 +static int ethsw_port_set_state(struct net_device *netdev, u8 state)
5235 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5236 + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
5237 + u8 old_state = port_priv->stp_state;
5240 + struct dpsw_stp_cfg stp_cfg = {
5244 + /* TODO: check port state, interface may be down */
5246 + if (state > BR_STATE_BLOCKING)
5249 + if (state == port_priv->stp_state)
5252 + if (state == BR_STATE_DISABLED) {
5253 + port_priv->stp_state = state;
5255 + err = ethsw_port_stop(netdev);
5259 + err = dpsw_if_set_stp(priv->mc_io, 0, priv->dpsw_handle,
5260 + port_priv->port_index, &stp_cfg);
5262 + netdev_err(netdev, "dpsw_if_set_stp err %d\n", err);
5266 + port_priv->stp_state = state;
5268 + if (old_state == BR_STATE_DISABLED) {
5269 + err = ethsw_port_open(netdev);
5277 + port_priv->stp_state = old_state;
5281 +static int ethsw_setlink_protinfo(struct net_device *netdev,
5282 + struct nlattr **tb)
5284 + struct ethsw_dev_priv *priv;
5285 + struct ethsw_port_priv *port_priv = NULL;
5288 + __get_priv(netdev, &priv, &port_priv);
5290 + if (tb[IFLA_BRPORT_LEARNING]) {
5291 + u8 flag = nla_get_u8(tb[IFLA_BRPORT_LEARNING]);
5294 + netdev_warn(netdev,
5295 + "learning set on whole switch dev\n");
5297 + err = ethsw_set_learning(priv->netdev, flag);
5301 + } else if (tb[IFLA_BRPORT_UNICAST_FLOOD] && port_priv) {
5302 + u8 flag = nla_get_u8(tb[IFLA_BRPORT_UNICAST_FLOOD]);
5304 + err = ethsw_port_set_flood(port_priv->netdev, flag);
5308 + } else if (tb[IFLA_BRPORT_STATE] && port_priv) {
5309 + u8 state = nla_get_u8(tb[IFLA_BRPORT_STATE]);
5311 + err = ethsw_port_set_state(port_priv->netdev, state);
5316 + return -EOPNOTSUPP;
5322 +static int ethsw_setlink(struct net_device *netdev,
5323 + struct nlmsghdr *nlh,
5326 + struct nlattr *attr;
5327 + struct nlattr *tb[(IFLA_BRIDGE_MAX > IFLA_BRPORT_MAX) ?
5328 + IFLA_BRIDGE_MAX : IFLA_BRPORT_MAX+1];
5331 + attr = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
5333 + err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, attr,
5336 + netdev_err(netdev,
5337 + "nla_parse_nested for br_policy err %d\n",
5342 + err = ethsw_setlink_af_spec(netdev, tb);
5346 + attr = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_PROTINFO);
5348 + err = nla_parse_nested(tb, IFLA_BRPORT_MAX, attr,
5349 + ifla_brport_policy);
5351 + netdev_err(netdev,
5352 + "nla_parse_nested for brport_policy err %d\n",
5357 + err = ethsw_setlink_protinfo(netdev, tb);
5361 + netdev_err(netdev, "nlmsg_find_attr found no AF_SPEC/PROTINFO\n");
5362 + return -EOPNOTSUPP;
5365 +static int __nla_put_netdev(struct sk_buff *skb, struct net_device *netdev,
5366 + struct ethsw_dev_priv *priv)
5368 + u8 operstate = netif_running(netdev) ? netdev->operstate : IF_OPER_DOWN;
5372 + err = nla_put_string(skb, IFLA_IFNAME, netdev->name);
5375 + err = nla_put_u32(skb, IFLA_MASTER, priv->netdev->ifindex);
5378 + err = nla_put_u32(skb, IFLA_MTU, netdev->mtu);
5381 + err = nla_put_u8(skb, IFLA_OPERSTATE, operstate);
5384 + if (netdev->addr_len) {
5385 + err = nla_put(skb, IFLA_ADDRESS, netdev->addr_len,
5386 + netdev->dev_addr);
5391 + iflink = dev_get_iflink(netdev);
5392 + if (netdev->ifindex != iflink) {
5393 + err = nla_put_u32(skb, IFLA_LINK, iflink);
5401 + netdev_err(netdev, "nla_put_ err %d\n", err);
5405 +static int __nla_put_port(struct sk_buff *skb, struct net_device *netdev,
5406 + struct ethsw_port_priv *port_priv)
5408 + struct nlattr *nest;
5411 + u8 stp_state = port_priv->stp_state;
5413 + if (port_priv->stp_state == DPSW_STP_STATE_BLOCKING)
5414 + stp_state = BR_STATE_BLOCKING;
5416 + nest = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);
5418 + netdev_err(netdev, "nla_nest_start failed\n");
5422 + err = nla_put_u8(skb, IFLA_BRPORT_STATE, stp_state);
5425 + err = nla_put_u16(skb, IFLA_BRPORT_PRIORITY, 0);
5428 + err = nla_put_u32(skb, IFLA_BRPORT_COST, 0);
5431 + err = nla_put_u8(skb, IFLA_BRPORT_MODE, 0);
5434 + err = nla_put_u8(skb, IFLA_BRPORT_GUARD, 0);
5437 + err = nla_put_u8(skb, IFLA_BRPORT_PROTECT, 0);
5440 + err = nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, 0);
5443 + err = nla_put_u8(skb, IFLA_BRPORT_LEARNING,
5444 + port_priv->ethsw_priv->learning);
5447 + err = nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD,
5448 + port_priv->ethsw_priv->flood);
5451 + nla_nest_end(skb, nest);
5456 + netdev_err(netdev, "nla_put_ err %d\n", err);
5457 + nla_nest_cancel(skb, nest);
5461 +static int __nla_put_vlan(struct sk_buff *skb, struct net_device *netdev,
5462 + struct ethsw_dev_priv *priv,
5463 + struct ethsw_port_priv *port_priv)
5465 + struct nlattr *nest;
5466 + struct bridge_vlan_info vinfo;
5467 + const char *vlans;
5471 + nest = nla_nest_start(skb, IFLA_AF_SPEC);
5473 + netdev_err(netdev, "nla_nest_start failed");
5478 + vlans = port_priv->vlans;
5480 + vlans = priv->vlans;
5482 + for (i = 0; i < VLAN_VID_MASK+1; i++) {
5486 + if (vlans[i] & ETHSW_VLAN_UNTAGGED)
5487 + vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
5489 + if (vlans[i] & ETHSW_VLAN_PVID)
5490 + vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
5492 + if (vlans[i] & ETHSW_VLAN_MEMBER) {
5493 + err = nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
5494 + sizeof(vinfo), &vinfo);
5500 + nla_nest_end(skb, nest);
5504 + netdev_err(netdev, "nla_put_ err %d\n", err);
5505 + nla_nest_cancel(skb, nest);
5509 +static int ethsw_getlink(struct sk_buff *skb, u32 pid, u32 seq,
5510 + struct net_device *netdev, u32 filter_mask,
5513 + struct ethsw_dev_priv *priv;
5514 + struct ethsw_port_priv *port_priv = NULL;
5515 + struct ifinfomsg *hdr;
5516 + struct nlmsghdr *nlh;
5519 + __get_priv(netdev, &priv, &port_priv);
5521 + nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*hdr), NLM_F_MULTI);
5525 + hdr = nlmsg_data(nlh);
5526 + memset(hdr, 0, sizeof(*hdr));
5527 + hdr->ifi_family = AF_BRIDGE;
5528 + hdr->ifi_type = netdev->type;
5529 + hdr->ifi_index = netdev->ifindex;
5530 + hdr->ifi_flags = dev_get_flags(netdev);
5532 + err = __nla_put_netdev(skb, netdev, priv);
5537 + err = __nla_put_port(skb, netdev, port_priv);
5542 + /* Check if the VID information is requested */
5543 + if (filter_mask & RTEXT_FILTER_BRVLAN) {
5544 + err = __nla_put_vlan(skb, netdev, priv, port_priv);
5549 + nlmsg_end(skb, nlh);
5553 + nlmsg_cancel(skb, nlh);
5557 +static int ethsw_dellink_switch(struct ethsw_dev_priv *priv, u16 vid)
5559 + struct list_head *pos;
5560 + struct ethsw_port_priv *ppriv_local = NULL;
5563 + if (!priv->vlans[vid])
5566 + err = dpsw_vlan_remove(priv->mc_io, 0, priv->dpsw_handle, vid);
5568 + netdev_err(priv->netdev, "dpsw_vlan_remove err %d\n", err);
5571 + priv->vlans[vid] = 0;
5573 + list_for_each(pos, &priv->port_list) {
5574 + ppriv_local = list_entry(pos, struct ethsw_port_priv,
5576 + ppriv_local->vlans[vid] = 0;
5582 +static int ethsw_dellink_port(struct ethsw_dev_priv *priv,
5583 + struct ethsw_port_priv *port_priv,
5586 + struct list_head *pos;
5587 + struct ethsw_port_priv *ppriv_local = NULL;
5588 + struct dpsw_vlan_if_cfg vcfg = {
5590 + .if_id[0] = port_priv->port_index,
5592 + unsigned int count = 0;
5595 + if (!port_priv->vlans[vid])
5598 + /* VLAN will be deleted from switch if global flag is not set
5599 + * and is configured on only one port
5601 + if (!(priv->vlans[vid] & ETHSW_VLAN_GLOBAL)) {
5602 + list_for_each(pos, &priv->port_list) {
5603 + ppriv_local = list_entry(pos, struct ethsw_port_priv,
5605 + if (ppriv_local->vlans[vid] & ETHSW_VLAN_MEMBER)
5610 + return ethsw_dellink_switch(priv, vid);
5613 + err = dpsw_vlan_remove_if(priv->mc_io, 0, priv->dpsw_handle,
5616 + netdev_err(priv->netdev, "dpsw_vlan_remove_if err %d\n", err);
5619 + port_priv->vlans[vid] = 0;
5623 +static int ethsw_dellink(struct net_device *netdev,
5624 + struct nlmsghdr *nlh,
5627 + struct nlattr *tb[IFLA_BRIDGE_MAX+1];
5628 + struct nlattr *spec;
5629 + struct bridge_vlan_info *vinfo;
5630 + struct ethsw_dev_priv *priv;
5631 + struct ethsw_port_priv *port_priv = NULL;
5634 + spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
5638 + err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, spec, ifla_br_policy);
5642 + if (!tb[IFLA_BRIDGE_VLAN_INFO])
5643 + return -EOPNOTSUPP;
5645 + vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]);
5647 + if (!vinfo->vid || vinfo->vid > VLAN_VID_MASK)
5650 + __get_priv(netdev, &priv, &port_priv);
5652 + /* decide if command targets switch device or port */
5654 + err = ethsw_dellink_switch(priv, vinfo->vid);
5656 + err = ethsw_dellink_port(priv, port_priv, vinfo->vid);
5661 +static const struct net_device_ops ethsw_ops = {
5662 + .ndo_open = ðsw_open,
5663 + .ndo_stop = ðsw_stop,
5665 + .ndo_bridge_setlink = ðsw_setlink,
5666 + .ndo_bridge_getlink = ðsw_getlink,
5667 + .ndo_bridge_dellink = ðsw_dellink,
5669 + .ndo_start_xmit = ðsw_dropframe,
5672 +/*--------------------------------------------------------------------------- */
5673 +/* switch port netdevice ops */
5675 +static int _ethsw_port_carrier_state_sync(struct net_device *netdev)
5677 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5678 + struct dpsw_link_state state;
5681 + err = dpsw_if_get_link_state(port_priv->ethsw_priv->mc_io, 0,
5682 + port_priv->ethsw_priv->dpsw_handle,
5683 + port_priv->port_index, &state);
5684 + if (unlikely(err)) {
5685 + netdev_err(netdev, "dpsw_if_get_link_state() err %d\n", err);
5689 + WARN_ONCE(state.up > 1, "Garbage read into link_state");
5692 + netif_carrier_on(port_priv->netdev);
5694 + netif_carrier_off(port_priv->netdev);
5699 +static int ethsw_port_open(struct net_device *netdev)
5701 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5704 + if (!netif_oper_up(netdev) ||
5705 + port_priv->stp_state == BR_STATE_DISABLED)
5708 + err = dpsw_if_enable(port_priv->ethsw_priv->mc_io, 0,
5709 + port_priv->ethsw_priv->dpsw_handle,
5710 + port_priv->port_index);
5712 + netdev_err(netdev, "dpsw_if_enable err %d\n", err);
5719 +static int ethsw_port_stop(struct net_device *netdev)
5721 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5724 + err = dpsw_if_disable(port_priv->ethsw_priv->mc_io, 0,
5725 + port_priv->ethsw_priv->dpsw_handle,
5726 + port_priv->port_index);
5728 + netdev_err(netdev, "dpsw_if_disable err %d\n", err);
5735 +static int ethsw_port_fdb_add_uc(struct net_device *netdev,
5736 + const unsigned char *addr)
5738 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5739 + struct dpsw_fdb_unicast_cfg entry = {0};
5742 + entry.if_egress = port_priv->port_index;
5743 + entry.type = DPSW_FDB_ENTRY_STATIC;
5744 + ether_addr_copy(entry.mac_addr, addr);
5746 + err = dpsw_fdb_add_unicast(port_priv->ethsw_priv->mc_io, 0,
5747 + port_priv->ethsw_priv->dpsw_handle,
5750 + netdev_err(netdev, "dpsw_fdb_add_unicast err %d\n", err);
5754 +static int ethsw_port_fdb_del_uc(struct net_device *netdev,
5755 + const unsigned char *addr)
5757 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5758 + struct dpsw_fdb_unicast_cfg entry = {0};
5761 + entry.if_egress = port_priv->port_index;
5762 + entry.type = DPSW_FDB_ENTRY_STATIC;
5763 + ether_addr_copy(entry.mac_addr, addr);
5765 + err = dpsw_fdb_remove_unicast(port_priv->ethsw_priv->mc_io, 0,
5766 + port_priv->ethsw_priv->dpsw_handle,
5769 + netdev_err(netdev, "dpsw_fdb_remove_unicast err %d\n", err);
5773 +static int ethsw_port_fdb_add_mc(struct net_device *netdev,
5774 + const unsigned char *addr)
5776 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5777 + struct dpsw_fdb_multicast_cfg entry = {0};
5780 + ether_addr_copy(entry.mac_addr, addr);
5781 + entry.type = DPSW_FDB_ENTRY_STATIC;
5782 + entry.num_ifs = 1;
5783 + entry.if_id[0] = port_priv->port_index;
5785 + err = dpsw_fdb_add_multicast(port_priv->ethsw_priv->mc_io, 0,
5786 + port_priv->ethsw_priv->dpsw_handle,
5789 + netdev_err(netdev, "dpsw_fdb_add_multicast err %d\n", err);
5793 +static int ethsw_port_fdb_del_mc(struct net_device *netdev,
5794 + const unsigned char *addr)
5796 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5797 + struct dpsw_fdb_multicast_cfg entry = {0};
5800 + ether_addr_copy(entry.mac_addr, addr);
5801 + entry.type = DPSW_FDB_ENTRY_STATIC;
5802 + entry.num_ifs = 1;
5803 + entry.if_id[0] = port_priv->port_index;
5805 + err = dpsw_fdb_remove_multicast(port_priv->ethsw_priv->mc_io, 0,
5806 + port_priv->ethsw_priv->dpsw_handle,
5809 + netdev_err(netdev, "dpsw_fdb_remove_multicast err %d\n", err);
5813 +static int _lookup_address(struct net_device *netdev, int is_uc,
5814 + const unsigned char *addr)
5816 + struct netdev_hw_addr *ha;
5817 + struct netdev_hw_addr_list *list = (is_uc) ? &netdev->uc : &netdev->mc;
5819 + netif_addr_lock_bh(netdev);
5820 + list_for_each_entry(ha, &list->list, list) {
5821 + if (ether_addr_equal(ha->addr, addr)) {
5822 + netif_addr_unlock_bh(netdev);
5826 + netif_addr_unlock_bh(netdev);
5830 +static int ethsw_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
5831 + struct net_device *netdev,
5832 + const unsigned char *addr, u16 vid,
5835 + struct list_head *pos;
5836 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5837 + struct ethsw_dev_priv *priv = port_priv->ethsw_priv;
5840 + /* TODO: add replace support when added to iproute bridge */
5841 + if (!(flags & NLM_F_REQUEST)) {
5842 + netdev_err(netdev,
5843 + "ethsw_port_fdb_add unexpected flags value %08x\n",
5848 + if (is_unicast_ether_addr(addr)) {
5849 + /* if entry cannot be replaced, return error if exists */
5850 + if (flags & NLM_F_EXCL || flags & NLM_F_APPEND) {
5851 + list_for_each(pos, &priv->port_list) {
5852 + port_priv = list_entry(pos,
5853 + struct ethsw_port_priv,
5855 + if (_lookup_address(port_priv->netdev,
5861 + err = ethsw_port_fdb_add_uc(netdev, addr);
5863 + netdev_err(netdev, "ethsw_port_fdb_add_uc err %d\n",
5868 + /* we might have replaced an existing entry for a different
5869 + * switch port, make sure the address doesn't linger in any
5870 + * port address list
5872 + list_for_each(pos, &priv->port_list) {
5873 + port_priv = list_entry(pos, struct ethsw_port_priv,
5875 + dev_uc_del(port_priv->netdev, addr);
5878 + err = dev_uc_add(netdev, addr);
5880 + netdev_err(netdev, "dev_uc_add err %d\n", err);
5884 + struct dpsw_fdb_multicast_cfg entry = {
5885 + .type = DPSW_FDB_ENTRY_STATIC,
5889 + /* check if address is already set on this port */
5890 + if (_lookup_address(netdev, 0, addr))
5893 + /* check if the address exists on other port */
5894 + ether_addr_copy(entry.mac_addr, addr);
5895 + err = dpsw_fdb_get_multicast(priv->mc_io, 0, priv->dpsw_handle,
5898 + /* entry exists, can we replace it? */
5899 + if (flags & NLM_F_EXCL)
5901 + } else if (err != -ENAVAIL) {
5902 + netdev_err(netdev, "dpsw_fdb_get_unicast err %d\n",
5907 + err = ethsw_port_fdb_add_mc(netdev, addr);
5909 + netdev_err(netdev, "ethsw_port_fdb_add_mc err %d\n",
5914 + err = dev_mc_add(netdev, addr);
5916 + netdev_err(netdev, "dev_mc_add err %d\n", err);
5924 +static int ethsw_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
5925 + struct net_device *netdev,
5926 + const unsigned char *addr, u16 vid)
5930 + if (is_unicast_ether_addr(addr)) {
5931 + err = ethsw_port_fdb_del_uc(netdev, addr);
5933 + netdev_err(netdev, "ethsw_port_fdb_del_uc err %d\n",
5938 + /* also delete if configured on port */
5939 + err = dev_uc_del(netdev, addr);
5940 + if (err && err != -ENOENT) {
5941 + netdev_err(netdev, "dev_uc_del err %d\n", err);
5945 + if (!_lookup_address(netdev, 0, addr))
5948 + err = dev_mc_del(netdev, addr);
5950 + netdev_err(netdev, "dev_mc_del err %d\n", err);
5954 + err = ethsw_port_fdb_del_mc(netdev, addr);
5956 + netdev_err(netdev, "ethsw_port_fdb_del_mc err %d\n",
5965 +static struct rtnl_link_stats64 *
5966 +ethsw_port_get_stats(struct net_device *netdev,
5967 + struct rtnl_link_stats64 *storage)
5969 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
5973 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
5974 + port_priv->ethsw_priv->dpsw_handle,
5975 + port_priv->port_index,
5976 + DPSW_CNT_ING_FRAME, &storage->rx_packets);
5980 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
5981 + port_priv->ethsw_priv->dpsw_handle,
5982 + port_priv->port_index,
5983 + DPSW_CNT_EGR_FRAME, &storage->tx_packets);
5987 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
5988 + port_priv->ethsw_priv->dpsw_handle,
5989 + port_priv->port_index,
5990 + DPSW_CNT_ING_BYTE, &storage->rx_bytes);
5994 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
5995 + port_priv->ethsw_priv->dpsw_handle,
5996 + port_priv->port_index,
5997 + DPSW_CNT_EGR_BYTE, &storage->tx_bytes);
6001 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
6002 + port_priv->ethsw_priv->dpsw_handle,
6003 + port_priv->port_index,
6004 + DPSW_CNT_ING_FRAME_DISCARD,
6005 + &storage->rx_dropped);
6009 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
6010 + port_priv->ethsw_priv->dpsw_handle,
6011 + port_priv->port_index,
6012 + DPSW_CNT_ING_FLTR_FRAME,
6016 + storage->rx_dropped += tmp;
6018 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
6019 + port_priv->ethsw_priv->dpsw_handle,
6020 + port_priv->port_index,
6021 + DPSW_CNT_EGR_FRAME_DISCARD,
6022 + &storage->tx_dropped);
6029 + netdev_err(netdev, "dpsw_if_get_counter err %d\n", err);
6033 +static const struct net_device_ops ethsw_port_ops = {
6034 + .ndo_open = ðsw_port_open,
6035 + .ndo_stop = ðsw_port_stop,
6037 + .ndo_fdb_add = ðsw_port_fdb_add,
6038 + .ndo_fdb_del = ðsw_port_fdb_del,
6039 + .ndo_fdb_dump = &ndo_dflt_fdb_dump,
6041 + .ndo_get_stats64 = ðsw_port_get_stats,
6043 + .ndo_start_xmit = ðsw_dropframe,
6047 + enum dpsw_counter id;
6048 + char name[ETH_GSTRING_LEN];
6049 +} ethsw_ethtool_counters[] = {
6050 + {DPSW_CNT_ING_FRAME, "rx frames"},
6051 + {DPSW_CNT_ING_BYTE, "rx bytes"},
6052 + {DPSW_CNT_ING_FLTR_FRAME, "rx filtered frames"},
6053 + {DPSW_CNT_ING_FRAME_DISCARD, "rx discarded frames"},
6054 + {DPSW_CNT_ING_BCAST_FRAME, "rx b-cast frames"},
6055 + {DPSW_CNT_ING_BCAST_BYTES, "rx b-cast bytes"},
6056 + {DPSW_CNT_ING_MCAST_FRAME, "rx m-cast frames"},
6057 + {DPSW_CNT_ING_MCAST_BYTE, "rx m-cast bytes"},
6058 + {DPSW_CNT_EGR_FRAME, "tx frames"},
6059 + {DPSW_CNT_EGR_BYTE, "tx bytes"},
6060 + {DPSW_CNT_EGR_FRAME_DISCARD, "tx discarded frames"},
6064 +static int ethsw_ethtool_get_sset_count(struct net_device *dev, int sset)
6067 + case ETH_SS_STATS:
6068 + return ARRAY_SIZE(ethsw_ethtool_counters);
6070 + return -EOPNOTSUPP;
6074 +static void ethsw_ethtool_get_strings(struct net_device *netdev,
6075 + u32 stringset, u8 *data)
6079 + switch (stringset) {
6080 + case ETH_SS_STATS:
6081 + for (i = 0; i < ARRAY_SIZE(ethsw_ethtool_counters); i++)
6082 + memcpy(data + i * ETH_GSTRING_LEN,
6083 + ethsw_ethtool_counters[i].name, ETH_GSTRING_LEN);
6088 +static void ethsw_ethtool_get_stats(struct net_device *netdev,
6089 + struct ethtool_stats *stats,
6092 + struct ethsw_port_priv *port_priv = netdev_priv(netdev);
6096 + for (i = 0; i < ARRAY_SIZE(ethsw_ethtool_counters); i++) {
6097 + err = dpsw_if_get_counter(port_priv->ethsw_priv->mc_io, 0,
6098 + port_priv->ethsw_priv->dpsw_handle,
6099 + port_priv->port_index,
6100 + ethsw_ethtool_counters[i].id,
6103 + netdev_err(netdev, "dpsw_if_get_counter[%s] err %d\n",
6104 + ethsw_ethtool_counters[i].name, err);
6108 +static const struct ethtool_ops ethsw_port_ethtool_ops = {
6109 + .get_strings = ðsw_ethtool_get_strings,
6110 + .get_ethtool_stats = ðsw_ethtool_get_stats,
6111 + .get_sset_count = ðsw_ethtool_get_sset_count,
6114 +/* -------------------------------------------------------------------------- */
6115 +/* ethsw driver functions */
6117 +static int ethsw_links_state_update(struct ethsw_dev_priv *priv)
6119 + struct list_head *pos;
6120 + struct ethsw_port_priv *port_priv;
6123 + list_for_each(pos, &priv->port_list) {
6124 + port_priv = list_entry(pos, struct ethsw_port_priv,
6127 + err = _ethsw_port_carrier_state_sync(port_priv->netdev);
6129 + netdev_err(port_priv->netdev,
6130 + "_ethsw_port_carrier_state_sync err %d\n",
6137 +static irqreturn_t ethsw_irq0_handler(int irq_num, void *arg)
6139 + return IRQ_WAKE_THREAD;
6142 +static irqreturn_t _ethsw_irq0_handler_thread(int irq_num, void *arg)
6144 + struct device *dev = (struct device *)arg;
6145 + struct fsl_mc_device *sw_dev = to_fsl_mc_device(dev);
6146 + struct net_device *netdev = dev_get_drvdata(dev);
6147 + struct ethsw_dev_priv *priv = netdev_priv(netdev);
6149 + struct fsl_mc_io *io = priv->mc_io;
6150 + uint16_t token = priv->dpsw_handle;
6151 + int irq_index = DPSW_IRQ_INDEX_IF;
6153 + /* Mask the events and the if_id reserved bits to be cleared on read */
6154 + uint32_t status = DPSW_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;
6157 + /* Sanity check */
6158 + if (WARN_ON(!sw_dev || !sw_dev->irqs || !sw_dev->irqs[irq_index]))
6160 + if (WARN_ON(sw_dev->irqs[irq_index]->msi_desc->irq != irq_num))
6163 + err = dpsw_get_irq_status(io, 0, token, irq_index, &status);
6164 + if (unlikely(err)) {
6165 + netdev_err(netdev, "Can't get irq status (err %d)", err);
6167 + err = dpsw_clear_irq_status(io, 0, token, irq_index,
6169 + if (unlikely(err))
6170 + netdev_err(netdev, "Can't clear irq status (err %d)",
6175 + if (status & DPSW_IRQ_EVENT_LINK_CHANGED) {
6176 + err = ethsw_links_state_update(priv);
6177 + if (unlikely(err))
6182 + return IRQ_HANDLED;
6185 +static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev)
6187 + struct device *dev = &sw_dev->dev;
6188 + struct net_device *netdev = dev_get_drvdata(dev);
6189 + struct ethsw_dev_priv *priv = netdev_priv(netdev);
6191 + struct fsl_mc_device_irq *irq;
6192 + const int irq_index = DPSW_IRQ_INDEX_IF;
6193 + uint32_t mask = DPSW_IRQ_EVENT_LINK_CHANGED;
6195 + err = fsl_mc_allocate_irqs(sw_dev);
6196 + if (unlikely(err)) {
6197 + dev_err(dev, "MC irqs allocation failed\n");
6201 + if (WARN_ON(sw_dev->obj_desc.irq_count != DPSW_MAX_IRQ_NUM)) {
6206 + err = dpsw_set_irq_enable(priv->mc_io, 0, priv->dpsw_handle,
6208 + if (unlikely(err)) {
6209 + dev_err(dev, "dpsw_set_irq_enable err %d\n", err);
6213 + irq = sw_dev->irqs[irq_index];
6215 + err = devm_request_threaded_irq(dev, irq->msi_desc->irq,
6216 + ethsw_irq0_handler,
6217 + _ethsw_irq0_handler_thread,
6218 + IRQF_NO_SUSPEND | IRQF_ONESHOT,
6219 + dev_name(dev), dev);
6220 + if (unlikely(err)) {
6221 + dev_err(dev, "devm_request_threaded_irq(): %d", err);
6225 + err = dpsw_set_irq_mask(priv->mc_io, 0, priv->dpsw_handle,
6227 + if (unlikely(err)) {
6228 + dev_err(dev, "dpsw_set_irq_mask(): %d", err);
6229 + goto free_devm_irq;
6232 + err = dpsw_set_irq_enable(priv->mc_io, 0, priv->dpsw_handle,
6234 + if (unlikely(err)) {
6235 + dev_err(dev, "dpsw_set_irq_enable(): %d", err);
6236 + goto free_devm_irq;
6242 + devm_free_irq(dev, irq->msi_desc->irq, dev);
6244 + fsl_mc_free_irqs(sw_dev);
6248 +static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev)
6250 + struct device *dev = &sw_dev->dev;
6251 + struct net_device *netdev = dev_get_drvdata(dev);
6252 + struct ethsw_dev_priv *priv = netdev_priv(netdev);
6254 + dpsw_set_irq_enable(priv->mc_io, 0, priv->dpsw_handle,
6255 + DPSW_IRQ_INDEX_IF, 0);
6256 + devm_free_irq(dev,
6257 + sw_dev->irqs[DPSW_IRQ_INDEX_IF]->msi_desc->irq,
6259 + fsl_mc_free_irqs(sw_dev);
6263 +ethsw_init(struct fsl_mc_device *sw_dev)
6265 + struct device *dev = &sw_dev->dev;
6266 + struct ethsw_dev_priv *priv;
6267 + struct net_device *netdev;
6270 + const struct dpsw_stp_cfg stp_cfg = {
6272 + .state = DPSW_STP_STATE_FORWARDING,
6275 + netdev = dev_get_drvdata(dev);
6276 + priv = netdev_priv(netdev);
6278 + priv->dev_id = sw_dev->obj_desc.id;
6280 + err = dpsw_open(priv->mc_io, 0, priv->dev_id, &priv->dpsw_handle);
6282 + dev_err(dev, "dpsw_open err %d\n", err);
6285 + if (!priv->dpsw_handle) {
6286 + dev_err(dev, "dpsw_open returned null handle but no error\n");
6291 + err = dpsw_get_attributes(priv->mc_io, 0, priv->dpsw_handle,
6294 + dev_err(dev, "dpsw_get_attributes err %d\n", err);
6298 + /* Minimum supported DPSW version check */
6299 + if (priv->sw_attr.version.major < DPSW_MIN_VER_MAJOR ||
6300 + (priv->sw_attr.version.major == DPSW_MIN_VER_MAJOR &&
6301 + priv->sw_attr.version.minor < DPSW_MIN_VER_MINOR)) {
6302 + dev_err(dev, "DPSW version %d:%d not supported. Use %d.%d or greater.\n",
6303 + priv->sw_attr.version.major,
6304 + priv->sw_attr.version.minor,
6305 + DPSW_MIN_VER_MAJOR, DPSW_MIN_VER_MINOR);
6310 + err = dpsw_reset(priv->mc_io, 0, priv->dpsw_handle);
6312 + dev_err(dev, "dpsw_reset err %d\n", err);
6316 + err = dpsw_fdb_set_learning_mode(priv->mc_io, 0, priv->dpsw_handle, 0,
6317 + DPSW_FDB_LEARNING_MODE_HW);
6319 + dev_err(dev, "dpsw_fdb_set_learning_mode err %d\n", err);
6323 + for (i = 0; i < priv->sw_attr.num_ifs; i++) {
6324 + err = dpsw_if_set_stp(priv->mc_io, 0, priv->dpsw_handle, i,
6327 + dev_err(dev, "dpsw_if_set_stp err %d for port %d\n",
6332 + err = dpsw_if_set_broadcast(priv->mc_io, 0,
6333 + priv->dpsw_handle, i, 1);
6336 + "dpsw_if_set_broadcast err %d for port %d\n",
6345 + dpsw_close(priv->mc_io, 0, priv->dpsw_handle);
6351 +ethsw_takedown(struct fsl_mc_device *sw_dev)
6353 + struct device *dev = &sw_dev->dev;
6354 + struct net_device *netdev;
6355 + struct ethsw_dev_priv *priv;
6358 + netdev = dev_get_drvdata(dev);
6359 + priv = netdev_priv(netdev);
6361 + err = dpsw_close(priv->mc_io, 0, priv->dpsw_handle);
6363 + dev_warn(dev, "dpsw_close err %d\n", err);
6369 +ethsw_remove(struct fsl_mc_device *sw_dev)
6371 + struct device *dev;
6372 + struct net_device *netdev;
6373 + struct ethsw_dev_priv *priv;
6374 + struct ethsw_port_priv *port_priv;
6375 + struct list_head *pos;
6377 + dev = &sw_dev->dev;
6378 + netdev = dev_get_drvdata(dev);
6379 + priv = netdev_priv(netdev);
6381 + list_for_each(pos, &priv->port_list) {
6382 + port_priv = list_entry(pos, struct ethsw_port_priv, list);
6385 + netdev_upper_dev_unlink(port_priv->netdev, netdev);
6388 + unregister_netdev(port_priv->netdev);
6389 + free_netdev(port_priv->netdev);
6392 + ethsw_teardown_irqs(sw_dev);
6394 + unregister_netdev(netdev);
6396 + ethsw_takedown(sw_dev);
6397 + fsl_mc_portal_free(priv->mc_io);
6399 + dev_set_drvdata(dev, NULL);
6400 + free_netdev(netdev);
6406 +ethsw_probe(struct fsl_mc_device *sw_dev)
6408 + struct device *dev;
6409 + struct net_device *netdev = NULL;
6410 + struct ethsw_dev_priv *priv = NULL;
6413 + const char def_mcast[ETH_ALEN] = {
6414 + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01,
6416 + char port_name[IFNAMSIZ];
6418 + dev = &sw_dev->dev;
6420 + /* register switch device, it's for management only - no I/O */
6421 + netdev = alloc_etherdev(sizeof(*priv));
6423 + dev_err(dev, "alloc_etherdev error\n");
6426 + netdev->netdev_ops = ðsw_ops;
6428 + SET_NETDEV_DEV(netdev, dev);
6429 + dev_set_drvdata(dev, netdev);
6431 + priv = netdev_priv(netdev);
6432 + priv->netdev = netdev;
6434 + err = fsl_mc_portal_allocate(sw_dev, 0, &priv->mc_io);
6436 + dev_err(dev, "fsl_mc_portal_allocate err %d\n", err);
6437 + goto err_free_netdev;
6439 + if (!priv->mc_io) {
6440 + dev_err(dev, "fsl_mc_portal_allocate returned null handle but no error\n");
6442 + goto err_free_netdev;
6445 + err = ethsw_init(sw_dev);
6447 + dev_err(dev, "switch init err %d\n", err);
6448 + goto err_free_cmdport;
6451 + netdev->flags = netdev->flags | IFF_PROMISC | IFF_MASTER;
6453 + /* TODO: should we hold rtnl_lock here? We can't register_netdev under
6456 + dev_alloc_name(netdev, "sw%d");
6457 + err = register_netdev(netdev);
6459 + dev_err(dev, "register_netdev error %d\n", err);
6460 + goto err_takedown;
6463 + dev_info(dev, "register_netdev res %d\n", err);
6465 + /* VLAN 1 is implicitly configured on the switch */
6466 + priv->vlans[1] = ETHSW_VLAN_MEMBER;
6467 + /* Flooding, learning are implicitly enabled */
6468 + priv->learning = true;
6469 + priv->flood = true;
6471 + /* register switch ports */
6472 + snprintf(port_name, IFNAMSIZ, "%sp%%d", netdev->name);
6474 + INIT_LIST_HEAD(&priv->port_list);
6475 + for (i = 0; i < priv->sw_attr.num_ifs; i++) {
6476 + struct net_device *port_netdev;
6477 + struct ethsw_port_priv *port_priv;
6479 + port_netdev = alloc_etherdev(sizeof(struct ethsw_port_priv));
6480 + if (!port_netdev) {
6481 + dev_err(dev, "alloc_etherdev error\n");
6482 + goto err_takedown;
6485 + port_priv = netdev_priv(port_netdev);
6486 + port_priv->netdev = port_netdev;
6487 + port_priv->ethsw_priv = priv;
6489 + port_priv->port_index = i;
6490 + port_priv->stp_state = BR_STATE_FORWARDING;
6491 + /* VLAN 1 is configured by default on all switch ports */
6492 + port_priv->vlans[1] = ETHSW_VLAN_MEMBER | ETHSW_VLAN_UNTAGGED |
6495 + SET_NETDEV_DEV(port_netdev, dev);
6496 + port_netdev->netdev_ops = ðsw_port_ops;
6497 + port_netdev->ethtool_ops = ðsw_port_ethtool_ops;
6499 + port_netdev->flags = port_netdev->flags |
6500 + IFF_PROMISC | IFF_SLAVE;
6502 + dev_alloc_name(port_netdev, port_name);
6503 + err = register_netdev(port_netdev);
6505 + dev_err(dev, "register_netdev error %d\n", err);
6506 + free_netdev(port_netdev);
6507 + goto err_takedown;
6512 + err = netdev_master_upper_dev_link(port_netdev, netdev, NULL, NULL);
6514 + dev_err(dev, "netdev_master_upper_dev_link error %d\n",
6516 + unregister_netdev(port_netdev);
6517 + free_netdev(port_netdev);
6519 + goto err_takedown;
6522 + rtmsg_ifinfo(RTM_NEWLINK, port_netdev, IFF_SLAVE, GFP_KERNEL);
6526 + list_add(&port_priv->list, &priv->port_list);
6528 + /* TODO: implmenet set_rm_mode instead of this */
6529 + err = ethsw_port_fdb_add_mc(port_netdev, def_mcast);
6531 + dev_warn(&netdev->dev,
6532 + "ethsw_port_fdb_add_mc err %d\n", err);
6535 + /* sync carrier state */
6536 + err = _ethsw_port_carrier_state_sync(port_netdev);
6538 + netdev_err(netdev,
6539 + "_ethsw_port_carrier_state_sync err %d\n",
6543 + /* the switch starts up enabled */
6545 + err = dev_open(netdev);
6548 + dev_warn(dev, "dev_open err %d\n", err);
6551 + err = ethsw_setup_irqs(sw_dev);
6552 + if (unlikely(err)) {
6553 + dev_warn(dev, "ethsw_setup_irqs err %d\n", err);
6554 + goto err_takedown;
6557 + dev_info(&netdev->dev,
6558 + "probed %d port switch\n", priv->sw_attr.num_ifs);
6562 + ethsw_remove(sw_dev);
6564 + fsl_mc_portal_free(priv->mc_io);
6566 + dev_set_drvdata(dev, NULL);
6567 + free_netdev(netdev);
6572 +static const struct fsl_mc_device_match_id ethsw_match_id_table[] = {
6574 + .vendor = FSL_MC_VENDOR_FREESCALE,
6575 + .obj_type = "dpsw",
6576 + .ver_major = DPSW_VER_MAJOR,
6577 + .ver_minor = DPSW_VER_MINOR,
6582 +static struct fsl_mc_driver eth_sw_drv = {
6584 + .name = KBUILD_MODNAME,
6585 + .owner = THIS_MODULE,
6587 + .probe = ethsw_probe,
6588 + .remove = ethsw_remove,
6589 + .match_id_table = ethsw_match_id_table,
6592 +module_fsl_mc_driver(eth_sw_drv);
6594 +MODULE_LICENSE("GPL");
6595 +MODULE_DESCRIPTION("DPAA2 Ethernet Switch Driver (prototype)");
6596 --- a/drivers/staging/fsl-mc/include/net.h
6597 +++ b/drivers/staging/fsl-mc/include/net.h
6599 /*************************** GTP fields ************************************/
6600 #define NH_FLD_GTP_TEID (1)
6603 /* Protocol options */
6605 /* Ethernet options */