summaryrefslogtreecommitdiffstats
path: root/net/dsa/dsa_priv.h
blob: 8cf8608344f5cd24775f50d7816012cc7bc32d9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * net/dsa/dsa_priv.h - Hardware switch handling
 * Copyright (c) 2008-2009 Marvell Semiconductor
 */

#ifndef __DSA_PRIV_H
#define __DSA_PRIV_H

#include <linux/phy.h>
#include <linux/netdevice.h>
#include <net/dsa.h>

#define DSA_MAX_NUM_OFFLOADING_BRIDGES		BITS_PER_LONG

enum {
	DSA_NOTIFIER_AGEING_TIME,
	DSA_NOTIFIER_BRIDGE_JOIN,
	DSA_NOTIFIER_BRIDGE_LEAVE,
	DSA_NOTIFIER_FDB_ADD,
	DSA_NOTIFIER_FDB_DEL,
	DSA_NOTIFIER_HOST_FDB_ADD,
	DSA_NOTIFIER_HOST_FDB_DEL,
	DSA_NOTIFIER_LAG_FDB_ADD,
	DSA_NOTIFIER_LAG_FDB_DEL,
	DSA_NOTIFIER_LAG_CHANGE,
	DSA_NOTIFIER_LAG_JOIN,
	DSA_NOTIFIER_LAG_LEAVE,
	DSA_NOTIFIER_MDB_ADD,
	DSA_NOTIFIER_MDB_DEL,
	DSA_NOTIFIER_HOST_MDB_ADD,
	DSA_NOTIFIER_HOST_MDB_DEL,
	DSA_NOTIFIER_VLAN_ADD,
	DSA_NOTIFIER_VLAN_DEL,
	DSA_NOTIFIER_HOST_VLAN_ADD,
	DSA_NOTIFIER_HOST_VLAN_DEL,
	DSA_NOTIFIER_MTU,
	DSA_NOTIFIER_TAG_PROTO,
	DSA_NOTIFIER_TAG_PROTO_CONNECT,
	DSA_NOTIFIER_TAG_PROTO_DISCONNECT,
	DSA_NOTIFIER_TAG_8021Q_VLAN_ADD,
	DSA_NOTIFIER_TAG_8021Q_VLAN_DEL,
	DSA_NOTIFIER_MASTER_STATE_CHANGE,
};

/* DSA_NOTIFIER_AGEING_TIME */
struct dsa_notifier_ageing_time_info {
	unsigned int ageing_time;
};

/* DSA_NOTIFIER_BRIDGE_* */
struct dsa_notifier_bridge_info {
	const struct dsa_port *dp;
	struct dsa_bridge bridge;
	bool tx_fwd_offload;
	struct netlink_ext_ack *extack;
};

/* DSA_NOTIFIER_FDB_* */
struct dsa_notifier_fdb_info {
	const struct dsa_port *dp;
	const unsigned char *addr;
	u16 vid;
	struct dsa_db db;
};

/* DSA_NOTIFIER_LAG_FDB_* */
struct dsa_notifier_lag_fdb_info {
	struct dsa_lag *lag;
	const unsigned char *addr;
	u16 vid;
	struct dsa_db db;
};

/* DSA_NOTIFIER_MDB_* */
struct dsa_notifier_mdb_info {
	const struct dsa_port *dp;
	const struct switchdev_obj_port_mdb *mdb;
	struct dsa_db db;
};

/* DSA_NOTIFIER_LAG_* */
struct dsa_notifier_lag_info {
	const struct dsa_port *dp;
	struct dsa_lag lag;
	struct netdev_lag_upper_info *info;
	struct netlink_ext_ack *extack;
};

/* DSA_NOTIFIER_VLAN_* */
struct dsa_notifier_vlan_info {
	const struct dsa_port *dp;
	const struct switchdev_obj_port_vlan *vlan;
	struct netlink_ext_ack *extack;
};

/* DSA_NOTIFIER_MTU */
struct dsa_notifier_mtu_info {
	const struct dsa_port *dp;
	int mtu;
};

/* DSA_NOTIFIER_TAG_PROTO_* */
struct dsa_notifier_tag_proto_info {
	const struct dsa_device_ops *tag_ops;
};

/* DSA_NOTIFIER_TAG_8021Q_VLAN_* */
struct dsa_notifier_tag_8021q_vlan_info {
	const struct dsa_port *dp;
	u16 vid;
};

/* DSA_NOTIFIER_MASTER_STATE_CHANGE */
struct dsa_notifier_master_state_info {
	const struct net_device *master;
	bool operational;
};

struct dsa_switchdev_event_work {
	struct net_device *dev;
	struct net_device *orig_dev;
	struct work_struct work;
	unsigned long event;
	/* Specific for SWITCHDEV_FDB_ADD_TO_DEVICE and
	 * SWITCHDEV_FDB_DEL_TO_DEVICE
	 */
	unsigned char addr[ETH_ALEN];
	u16 vid;
	bool host_addr;
};

enum dsa_standalone_event {
	DSA_UC_ADD,
	DSA_UC_DEL,
	DSA_MC_ADD,
	DSA_MC_DEL,
};

struct dsa_standalone_event_work {
	struct work_struct work;
	struct net_device *dev;
	enum dsa_standalone_event event;
	unsigned char addr[ETH_ALEN];
	u16 vid;
};

/* dsa.c */
struct net_device *dsa_dev_to_net_device(struct device *dev);

bool dsa_db_equal(const struct dsa_db *a, const struct dsa_db *b);

bool dsa_schedule_work(struct work_struct *work);

/* netlink.c */
extern struct rtnl_link_ops dsa_link_ops __read_mostly;

static inline bool dsa_switch_supports_uc_filtering(struct dsa_switch *ds)
{
	return ds->ops->port_fdb_add && ds->ops->port_fdb_del &&
	       ds->fdb_isolation && !ds->vlan_filtering_is_global &&
	       !ds->needs_standalone_vlan_filtering;
}

static inline bool dsa_switch_supports_mc_filtering(struct dsa_switch *ds)
{
	return ds->ops->port_mdb_add && ds->ops->port_mdb_del &&
	       ds->fdb_isolation && !ds->vlan_filtering_is_global &&
	       !ds->needs_standalone_vlan_filtering;
}

/* dsa2.c */
void dsa_lag_map(struct dsa_switch_tree *dst, struct dsa_lag *lag);
void dsa_lag_unmap(struct dsa_switch_tree *dst, struct dsa_lag *lag);
struct dsa_lag *dsa_tree_lag_find(struct dsa_switch_tree *dst,
				  const struct net_device *lag_dev);
struct net_device *dsa_tree_find_first_master(struct dsa_switch_tree *dst);
int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,
			      const struct dsa_device_ops *tag_ops,
			      const struct dsa_device_ops *old_tag_ops);
void dsa_tree_master_admin_state_change(struct dsa_switch_tree *dst,
					struct net_device *master,
					bool up);
void dsa_tree_master_oper_state_change(struct dsa_switch_tree *dst,
				       struct net_device *master,
				       bool up);
unsigned int dsa_bridge_num_get(const struct net_device *bridge_dev, int max);
void dsa_bridge_num_put(const struct net_device *bridge_dev,
			unsigned int bridge_num);
struct dsa_bridge *dsa_tree_bridge_find(struct dsa_switch_tree *dst,
					const struct net_device *br);

/* tag_8021q.c */
int dsa_switch_tag_8021q_vlan_add(struct dsa_switch *ds,
				  struct dsa_notifier_tag_8021q_vlan_info *info);
int dsa_switch_tag_8021q_vlan_del(struct dsa_switch *ds,
				  struct dsa_notifier_tag_8021q_vlan_info *info);

extern struct list_head dsa_tree_list;

#endif