Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
v6.8
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * DPAA2 Ethernet Switch declarations
  4 *
  5 * Copyright 2014-2016 Freescale Semiconductor Inc.
  6 * Copyright 2017-2021 NXP
  7 *
  8 */
  9
 10#ifndef __ETHSW_H
 11#define __ETHSW_H
 12
 13#include <linux/netdevice.h>
 14#include <linux/etherdevice.h>
 15#include <linux/rtnetlink.h>
 16#include <linux/if_vlan.h>
 17#include <uapi/linux/if_bridge.h>
 18#include <net/switchdev.h>
 19#include <linux/if_bridge.h>
 20#include <linux/fsl/mc.h>
 21#include <net/pkt_cls.h>
 22#include <soc/fsl/dpaa2-io.h>
 23
 24#include "dpaa2-mac.h"
 25#include "dpsw.h"
 26
 27/* Number of IRQs supported */
 28#define DPSW_IRQ_NUM	2
 29
 30/* Port is member of VLAN */
 31#define ETHSW_VLAN_MEMBER	1
 32/* VLAN to be treated as untagged on egress */
 33#define ETHSW_VLAN_UNTAGGED	2
 34/* Untagged frames will be assigned to this VLAN */
 35#define ETHSW_VLAN_PVID		4
 36/* VLAN configured on the switch */
 37#define ETHSW_VLAN_GLOBAL	8
 38
 39/* Maximum Frame Length supported by HW (currently 10k) */
 40#define DPAA2_MFL		(10 * 1024)
 41#define ETHSW_MAX_FRAME_LENGTH	(DPAA2_MFL - VLAN_ETH_HLEN - ETH_FCS_LEN)
 42#define ETHSW_L2_MAX_FRM(mtu)	((mtu) + VLAN_ETH_HLEN + ETH_FCS_LEN)
 43
 44#define ETHSW_FEATURE_MAC_ADDR	BIT(0)
 45
 46/* Number of receive queues (one RX and one TX_CONF) */
 47#define DPAA2_SWITCH_RX_NUM_FQS	2
 48
 49/* Hardware requires alignment for ingress/egress buffer addresses */
 50#define DPAA2_SWITCH_RX_BUF_RAW_SIZE	PAGE_SIZE
 51#define DPAA2_SWITCH_RX_BUF_TAILROOM \
 52	SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
 53#define DPAA2_SWITCH_RX_BUF_SIZE \
 54	(DPAA2_SWITCH_RX_BUF_RAW_SIZE - DPAA2_SWITCH_RX_BUF_TAILROOM)
 55
 56#define DPAA2_SWITCH_STORE_SIZE 16
 57
 58/* Buffer management */
 59#define BUFS_PER_CMD			7
 60#define DPAA2_ETHSW_NUM_BUFS		(1024 * BUFS_PER_CMD)
 61#define DPAA2_ETHSW_REFILL_THRESH	(DPAA2_ETHSW_NUM_BUFS * 5 / 6)
 62
 63/* Number of times to retry DPIO portal operations while waiting
 64 * for portal to finish executing current command and become
 65 * available. We want to avoid being stuck in a while loop in case
 66 * hardware becomes unresponsive, but not give up too easily if
 67 * the portal really is busy for valid reasons
 68 */
 69#define DPAA2_SWITCH_SWP_BUSY_RETRIES		1000
 70
 71/* Hardware annotation buffer size */
 72#define DPAA2_SWITCH_HWA_SIZE			64
 73/* Software annotation buffer size */
 74#define DPAA2_SWITCH_SWA_SIZE			64
 75
 76#define DPAA2_SWITCH_TX_BUF_ALIGN		64
 77
 78#define DPAA2_SWITCH_TX_DATA_OFFSET \
 79	(DPAA2_SWITCH_HWA_SIZE + DPAA2_SWITCH_SWA_SIZE)
 80
 81#define DPAA2_SWITCH_NEEDED_HEADROOM \
 82	(DPAA2_SWITCH_TX_DATA_OFFSET + DPAA2_SWITCH_TX_BUF_ALIGN)
 83
 84#define DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES	16
 85#define DPAA2_ETHSW_PORT_DEFAULT_TRAPS		1
 86
 87#define DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE	256
 88
 89extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops;
 90
 91struct ethsw_core;
 92
 93struct dpaa2_switch_fq {
 94	struct ethsw_core *ethsw;
 95	enum dpsw_queue_type type;
 96	struct dpaa2_io_store *store;
 97	struct dpaa2_io_notification_ctx nctx;
 98	struct napi_struct napi;
 99	u32 fqid;
100};
101
102struct dpaa2_switch_fdb {
103	struct net_device	*bridge_dev;
104	u16			fdb_id;
105	bool			in_use;
106};
107
108struct dpaa2_switch_acl_entry {
109	struct list_head	list;
110	u16			prio;
111	unsigned long		cookie;
112
113	struct dpsw_acl_entry_cfg cfg;
114	struct dpsw_acl_key	key;
115};
116
117struct dpaa2_switch_mirror_entry {
118	struct list_head	list;
119	struct dpsw_reflection_cfg cfg;
120	unsigned long		cookie;
121	u16 if_id;
122};
123
124struct dpaa2_switch_filter_block {
125	struct ethsw_core	*ethsw;
126	u64			ports;
127	bool			in_use;
128
129	struct list_head	acl_entries;
130	u16			acl_id;
131	u8			num_acl_rules;
132
133	struct list_head	mirror_entries;
134};
135
136static inline bool
137dpaa2_switch_acl_tbl_is_full(struct dpaa2_switch_filter_block *filter_block)
138{
139	if ((filter_block->num_acl_rules + DPAA2_ETHSW_PORT_DEFAULT_TRAPS) >=
140	    DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES)
141		return true;
142	return false;
143}
144
145/* Per port private data */
146struct ethsw_port_priv {
147	struct net_device	*netdev;
148	u16			idx;
149	struct ethsw_core	*ethsw_data;
150	u8			link_state;
151	u8			stp_state;
152
153	u8			vlans[VLAN_VID_MASK + 1];
154	u16			pvid;
155	u16			tx_qdid;
156
157	struct dpaa2_switch_fdb	*fdb;
158	bool			bcast_flood;
159	bool			ucast_flood;
160	bool			learn_ena;
161
162	struct dpaa2_switch_filter_block *filter_block;
163	struct dpaa2_mac	*mac;
164	/* Protects against changes to port_priv->mac */
165	struct mutex		mac_lock;
166};
167
168/* Switch data */
169struct ethsw_core {
170	struct device			*dev;
171	struct fsl_mc_io		*mc_io;
172	u16				dpsw_handle;
173	struct dpsw_attr		sw_attr;
174	u16				major, minor;
175	unsigned long			features;
176	int				dev_id;
177	struct ethsw_port_priv		**ports;
178	struct iommu_domain		*iommu_domain;
179
180	u8				vlans[VLAN_VID_MASK + 1];
181
182	struct workqueue_struct		*workqueue;
183
184	struct dpaa2_switch_fq		fq[DPAA2_SWITCH_RX_NUM_FQS];
185	struct fsl_mc_device		*dpbp_dev;
186	int				buf_count;
187	u16				bpid;
188	int				napi_users;
189
190	struct dpaa2_switch_fdb		*fdbs;
191	struct dpaa2_switch_filter_block *filter_blocks;
192	u16				mirror_port;
193};
194
195static inline int dpaa2_switch_get_index(struct ethsw_core *ethsw,
196					 struct net_device *netdev)
197{
198	int i;
199
200	for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
201		if (ethsw->ports[i]->netdev == netdev)
202			return ethsw->ports[i]->idx;
203
204	return -EINVAL;
205}
206
207static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw)
208{
209	if (ethsw->sw_attr.options & DPSW_OPT_CTRL_IF_DIS) {
210		dev_err(ethsw->dev, "Control Interface is disabled, cannot probe\n");
211		return false;
212	}
213
214	if (ethsw->sw_attr.flooding_cfg != DPSW_FLOODING_PER_FDB) {
215		dev_err(ethsw->dev, "Flooding domain is not per FDB, cannot probe\n");
216		return false;
217	}
218
219	if (ethsw->sw_attr.broadcast_cfg != DPSW_BROADCAST_PER_FDB) {
220		dev_err(ethsw->dev, "Broadcast domain is not per FDB, cannot probe\n");
221		return false;
222	}
223
224	if (ethsw->sw_attr.max_fdbs < ethsw->sw_attr.num_ifs) {
225		dev_err(ethsw->dev, "The number of FDBs is lower than the number of ports, cannot probe\n");
226		return false;
227	}
228
229	return true;
230}
231
232static inline bool
233dpaa2_switch_port_is_type_phy(struct ethsw_port_priv *port_priv)
234{
235	return dpaa2_mac_is_type_phy(port_priv->mac);
236}
237
238static inline bool dpaa2_switch_port_has_mac(struct ethsw_port_priv *port_priv)
239{
240	return port_priv->mac ? true : false;
241}
242
243bool dpaa2_switch_port_dev_check(const struct net_device *netdev);
244
245int dpaa2_switch_port_vlans_add(struct net_device *netdev,
246				const struct switchdev_obj_port_vlan *vlan);
247
248int dpaa2_switch_port_vlans_del(struct net_device *netdev,
249				const struct switchdev_obj_port_vlan *vlan);
250
251typedef int dpaa2_switch_fdb_cb_t(struct ethsw_port_priv *port_priv,
252				  struct fdb_dump_entry *fdb_entry,
253				  void *data);
254
255/* TC offload */
256
257int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_filter_block *block,
258				    struct flow_cls_offload *cls);
259
260int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_filter_block *block,
261				    struct flow_cls_offload *cls);
262
263int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_filter_block *block,
264				      struct tc_cls_matchall_offload *cls);
265
266int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_filter_block *block,
267				      struct tc_cls_matchall_offload *cls);
268
269int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *block,
270			       struct dpaa2_switch_acl_entry *entry);
271
272int dpaa2_switch_block_offload_mirror(struct dpaa2_switch_filter_block *block,
273				      struct ethsw_port_priv *port_priv);
274
275int dpaa2_switch_block_unoffload_mirror(struct dpaa2_switch_filter_block *block,
276					struct ethsw_port_priv *port_priv);
277#endif	/* __ETHSW_H */
v6.13.7
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * DPAA2 Ethernet Switch declarations
  4 *
  5 * Copyright 2014-2016 Freescale Semiconductor Inc.
  6 * Copyright 2017-2021 NXP
  7 *
  8 */
  9
 10#ifndef __ETHSW_H
 11#define __ETHSW_H
 12
 13#include <linux/netdevice.h>
 14#include <linux/etherdevice.h>
 15#include <linux/rtnetlink.h>
 16#include <linux/if_vlan.h>
 17#include <uapi/linux/if_bridge.h>
 18#include <net/switchdev.h>
 19#include <linux/if_bridge.h>
 20#include <linux/fsl/mc.h>
 21#include <net/pkt_cls.h>
 22#include <soc/fsl/dpaa2-io.h>
 23
 24#include "dpaa2-mac.h"
 25#include "dpsw.h"
 26
 27/* Number of IRQs supported */
 28#define DPSW_IRQ_NUM	2
 29
 30/* Port is member of VLAN */
 31#define ETHSW_VLAN_MEMBER	1
 32/* VLAN to be treated as untagged on egress */
 33#define ETHSW_VLAN_UNTAGGED	2
 34/* Untagged frames will be assigned to this VLAN */
 35#define ETHSW_VLAN_PVID		4
 36/* VLAN configured on the switch */
 37#define ETHSW_VLAN_GLOBAL	8
 38
 39/* Maximum Frame Length supported by HW (currently 10k) */
 40#define DPAA2_MFL		(10 * 1024)
 41#define ETHSW_MAX_FRAME_LENGTH	(DPAA2_MFL - VLAN_ETH_HLEN - ETH_FCS_LEN)
 42#define ETHSW_L2_MAX_FRM(mtu)	((mtu) + VLAN_ETH_HLEN + ETH_FCS_LEN)
 43
 44#define ETHSW_FEATURE_MAC_ADDR	BIT(0)
 45
 46/* Number of receive queues (one RX and one TX_CONF) */
 47#define DPAA2_SWITCH_RX_NUM_FQS	2
 48
 49/* Hardware requires alignment for ingress/egress buffer addresses */
 50#define DPAA2_SWITCH_RX_BUF_RAW_SIZE	PAGE_SIZE
 51#define DPAA2_SWITCH_RX_BUF_TAILROOM \
 52	SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
 53#define DPAA2_SWITCH_RX_BUF_SIZE \
 54	(DPAA2_SWITCH_RX_BUF_RAW_SIZE - DPAA2_SWITCH_RX_BUF_TAILROOM)
 55
 56#define DPAA2_SWITCH_STORE_SIZE 16
 57
 58/* Buffer management */
 59#define BUFS_PER_CMD			7
 60#define DPAA2_ETHSW_NUM_BUFS		(1024 * BUFS_PER_CMD)
 61#define DPAA2_ETHSW_REFILL_THRESH	(DPAA2_ETHSW_NUM_BUFS * 5 / 6)
 62
 63/* Number of times to retry DPIO portal operations while waiting
 64 * for portal to finish executing current command and become
 65 * available. We want to avoid being stuck in a while loop in case
 66 * hardware becomes unresponsive, but not give up too easily if
 67 * the portal really is busy for valid reasons
 68 */
 69#define DPAA2_SWITCH_SWP_BUSY_RETRIES		1000
 70
 71/* Hardware annotation buffer size */
 72#define DPAA2_SWITCH_HWA_SIZE			64
 73/* Software annotation buffer size */
 74#define DPAA2_SWITCH_SWA_SIZE			64
 75
 76#define DPAA2_SWITCH_TX_BUF_ALIGN		64
 77
 78#define DPAA2_SWITCH_TX_DATA_OFFSET \
 79	(DPAA2_SWITCH_HWA_SIZE + DPAA2_SWITCH_SWA_SIZE)
 80
 81#define DPAA2_SWITCH_NEEDED_HEADROOM \
 82	(DPAA2_SWITCH_TX_DATA_OFFSET + DPAA2_SWITCH_TX_BUF_ALIGN)
 83
 84#define DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES	16
 85#define DPAA2_ETHSW_PORT_DEFAULT_TRAPS		1
 86
 87#define DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE	256
 88
 89extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops;
 90
 91struct ethsw_core;
 92
 93struct dpaa2_switch_fq {
 94	struct ethsw_core *ethsw;
 95	enum dpsw_queue_type type;
 96	struct dpaa2_io_store *store;
 97	struct dpaa2_io_notification_ctx nctx;
 98	struct napi_struct napi;
 99	u32 fqid;
100};
101
102struct dpaa2_switch_fdb {
103	struct net_device	*bridge_dev;
104	u16			fdb_id;
105	bool			in_use;
106};
107
108struct dpaa2_switch_acl_entry {
109	struct list_head	list;
110	u16			prio;
111	unsigned long		cookie;
112
113	struct dpsw_acl_entry_cfg cfg;
114	struct dpsw_acl_key	key;
115};
116
117struct dpaa2_switch_mirror_entry {
118	struct list_head	list;
119	struct dpsw_reflection_cfg cfg;
120	unsigned long		cookie;
121	u16 if_id;
122};
123
124struct dpaa2_switch_filter_block {
125	struct ethsw_core	*ethsw;
126	u64			ports;
127	bool			in_use;
128
129	struct list_head	acl_entries;
130	u16			acl_id;
131	u8			num_acl_rules;
132
133	struct list_head	mirror_entries;
134};
135
136static inline bool
137dpaa2_switch_acl_tbl_is_full(struct dpaa2_switch_filter_block *filter_block)
138{
139	if ((filter_block->num_acl_rules + DPAA2_ETHSW_PORT_DEFAULT_TRAPS) >=
140	    DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES)
141		return true;
142	return false;
143}
144
145/* Per port private data */
146struct ethsw_port_priv {
147	struct net_device	*netdev;
148	u16			idx;
149	struct ethsw_core	*ethsw_data;
150	u8			link_state;
151	u8			stp_state;
152
153	u8			vlans[VLAN_VID_MASK + 1];
154	u16			pvid;
155	u16			tx_qdid;
156
157	struct dpaa2_switch_fdb	*fdb;
158	bool			bcast_flood;
159	bool			ucast_flood;
160	bool			learn_ena;
161
162	struct dpaa2_switch_filter_block *filter_block;
163	struct dpaa2_mac	*mac;
164	/* Protects against changes to port_priv->mac */
165	struct mutex		mac_lock;
166};
167
168/* Switch data */
169struct ethsw_core {
170	struct device			*dev;
171	struct fsl_mc_io		*mc_io;
172	u16				dpsw_handle;
173	struct dpsw_attr		sw_attr;
174	u16				major, minor;
175	unsigned long			features;
176	int				dev_id;
177	struct ethsw_port_priv		**ports;
178	struct iommu_domain		*iommu_domain;
179
180	u8				vlans[VLAN_VID_MASK + 1];
181
182	struct workqueue_struct		*workqueue;
183
184	struct dpaa2_switch_fq		fq[DPAA2_SWITCH_RX_NUM_FQS];
185	struct fsl_mc_device		*dpbp_dev;
186	int				buf_count;
187	u16				bpid;
188	int				napi_users;
189
190	struct dpaa2_switch_fdb		*fdbs;
191	struct dpaa2_switch_filter_block *filter_blocks;
192	u16				mirror_port;
193};
194
195static inline int dpaa2_switch_get_index(struct ethsw_core *ethsw,
196					 struct net_device *netdev)
197{
198	int i;
199
200	for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
201		if (ethsw->ports[i]->netdev == netdev)
202			return ethsw->ports[i]->idx;
203
204	return -EINVAL;
205}
206
207static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw)
208{
209	if (ethsw->sw_attr.options & DPSW_OPT_CTRL_IF_DIS) {
210		dev_err(ethsw->dev, "Control Interface is disabled, cannot probe\n");
211		return false;
212	}
213
214	if (ethsw->sw_attr.flooding_cfg != DPSW_FLOODING_PER_FDB) {
215		dev_err(ethsw->dev, "Flooding domain is not per FDB, cannot probe\n");
216		return false;
217	}
218
219	if (ethsw->sw_attr.broadcast_cfg != DPSW_BROADCAST_PER_FDB) {
220		dev_err(ethsw->dev, "Broadcast domain is not per FDB, cannot probe\n");
221		return false;
222	}
223
224	if (ethsw->sw_attr.max_fdbs < ethsw->sw_attr.num_ifs) {
225		dev_err(ethsw->dev, "The number of FDBs is lower than the number of ports, cannot probe\n");
226		return false;
227	}
228
229	return true;
230}
231
232static inline bool
233dpaa2_switch_port_is_type_phy(struct ethsw_port_priv *port_priv)
234{
235	return dpaa2_mac_is_type_phy(port_priv->mac);
236}
237
238static inline bool dpaa2_switch_port_has_mac(struct ethsw_port_priv *port_priv)
239{
240	return port_priv->mac ? true : false;
241}
242
243bool dpaa2_switch_port_dev_check(const struct net_device *netdev);
244
245int dpaa2_switch_port_vlans_add(struct net_device *netdev,
246				const struct switchdev_obj_port_vlan *vlan);
247
248int dpaa2_switch_port_vlans_del(struct net_device *netdev,
249				const struct switchdev_obj_port_vlan *vlan);
250
251typedef int dpaa2_switch_fdb_cb_t(struct ethsw_port_priv *port_priv,
252				  struct fdb_dump_entry *fdb_entry,
253				  void *data);
254
255/* TC offload */
256
257int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_filter_block *block,
258				    struct flow_cls_offload *cls);
259
260int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_filter_block *block,
261				    struct flow_cls_offload *cls);
262
263int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_filter_block *block,
264				      struct tc_cls_matchall_offload *cls);
265
266int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_filter_block *block,
267				      struct tc_cls_matchall_offload *cls);
268
269int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *block,
270			       struct dpaa2_switch_acl_entry *entry);
271
272int dpaa2_switch_block_offload_mirror(struct dpaa2_switch_filter_block *block,
273				      struct ethsw_port_priv *port_priv);
274
275int dpaa2_switch_block_unoffload_mirror(struct dpaa2_switch_filter_block *block,
276					struct ethsw_port_priv *port_priv);
277#endif	/* __ETHSW_H */