@@ -18,44 +18,83 @@ struct mlx5_bridge_switchdev_fdb_work {
1818 bool add ;
1919};
2020
21+ static bool mlx5_esw_bridge_dev_same_esw (struct net_device * dev , struct mlx5_eswitch * esw )
22+ {
23+ struct mlx5e_priv * priv = netdev_priv (dev );
24+
25+ return esw == priv -> mdev -> priv .eswitch ;
26+ }
27+
28+ static int mlx5_esw_bridge_vport_num_vhca_id_get (struct net_device * dev , struct mlx5_eswitch * esw ,
29+ u16 * vport_num , u16 * esw_owner_vhca_id )
30+ {
31+ struct mlx5e_rep_priv * rpriv ;
32+ struct mlx5e_priv * priv ;
33+
34+ if (!mlx5e_eswitch_rep (dev ) || !mlx5_esw_bridge_dev_same_esw (dev , esw ))
35+ return - ENODEV ;
36+
37+ priv = netdev_priv (dev );
38+ rpriv = priv -> ppriv ;
39+ * vport_num = rpriv -> rep -> vport ;
40+ * esw_owner_vhca_id = MLX5_CAP_GEN (priv -> mdev , vhca_id );
41+ return 0 ;
42+ }
43+
44+ static int
45+ mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (struct net_device * dev , struct mlx5_eswitch * esw ,
46+ u16 * vport_num , u16 * esw_owner_vhca_id )
47+ {
48+ struct net_device * lower_dev ;
49+ struct list_head * iter ;
50+
51+ if (mlx5e_eswitch_rep (dev ) && mlx5_esw_bridge_dev_same_esw (dev , esw ))
52+ return mlx5_esw_bridge_vport_num_vhca_id_get (dev , esw , vport_num ,
53+ esw_owner_vhca_id );
54+
55+ netdev_for_each_lower_dev (dev , lower_dev , iter ) {
56+ int err ;
57+
58+ if (netif_is_bridge_master (lower_dev ))
59+ continue ;
60+
61+ err = mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (lower_dev , esw , vport_num ,
62+ esw_owner_vhca_id );
63+ if (!err )
64+ return 0 ;
65+ }
66+
67+ return - ENODEV ;
68+ }
69+
2170static int mlx5_esw_bridge_port_changeupper (struct notifier_block * nb , void * ptr )
2271{
2372 struct mlx5_esw_bridge_offloads * br_offloads = container_of (nb ,
2473 struct mlx5_esw_bridge_offloads ,
2574 netdev_nb );
2675 struct net_device * dev = netdev_notifier_info_to_dev (ptr );
2776 struct netdev_notifier_changeupper_info * info = ptr ;
77+ struct net_device * upper = info -> upper_dev ;
78+ u16 vport_num , esw_owner_vhca_id ;
2879 struct netlink_ext_ack * extack ;
29- struct mlx5e_rep_priv * rpriv ;
30- struct mlx5_eswitch * esw ;
31- struct mlx5_vport * vport ;
32- struct net_device * upper ;
33- struct mlx5e_priv * priv ;
34- u16 vport_num ;
35-
36- if (!mlx5e_eswitch_rep (dev ))
37- return 0 ;
80+ int ifindex = upper -> ifindex ;
81+ int err ;
3882
39- upper = info -> upper_dev ;
4083 if (!netif_is_bridge_master (upper ))
4184 return 0 ;
4285
43- esw = br_offloads -> esw ;
44- priv = netdev_priv ( dev );
45- if (esw != priv -> mdev -> priv . eswitch )
86+ err = mlx5_esw_bridge_vport_num_vhca_id_get ( dev , br_offloads -> esw , & vport_num ,
87+ & esw_owner_vhca_id );
88+ if (err )
4689 return 0 ;
4790
48- rpriv = priv -> ppriv ;
49- vport_num = rpriv -> rep -> vport ;
50- vport = mlx5_eswitch_get_vport (esw , vport_num );
51- if (IS_ERR (vport ))
52- return PTR_ERR (vport );
53-
5491 extack = netdev_notifier_info_to_extack (& info -> info );
5592
5693 return info -> linking ?
57- mlx5_esw_bridge_vport_link (upper -> ifindex , br_offloads , vport , extack ) :
58- mlx5_esw_bridge_vport_unlink (upper -> ifindex , br_offloads , vport , extack );
94+ mlx5_esw_bridge_vport_link (ifindex , vport_num , esw_owner_vhca_id , br_offloads ,
95+ extack ) :
96+ mlx5_esw_bridge_vport_unlink (ifindex , vport_num , esw_owner_vhca_id , br_offloads ,
97+ extack );
5998}
6099
61100static int mlx5_esw_bridge_switchdev_port_event (struct notifier_block * nb ,
@@ -75,87 +114,80 @@ static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
75114 return notifier_from_errno (err );
76115}
77116
78- static int mlx5_esw_bridge_port_obj_add ( struct net_device * dev ,
79- const void * ctx ,
80- const struct switchdev_obj * obj ,
81- struct netlink_ext_ack * extack )
117+ static int
118+ mlx5_esw_bridge_port_obj_add ( struct net_device * dev ,
119+ struct switchdev_notifier_port_obj_info * port_obj_info ,
120+ struct mlx5_esw_bridge_offloads * br_offloads )
82121{
122+ struct netlink_ext_ack * extack = switchdev_notifier_info_to_extack (& port_obj_info -> info );
123+ const struct switchdev_obj * obj = port_obj_info -> obj ;
83124 const struct switchdev_obj_port_vlan * vlan ;
84- struct mlx5e_rep_priv * rpriv ;
85- struct mlx5_eswitch * esw ;
86- struct mlx5_vport * vport ;
87- struct mlx5e_priv * priv ;
88- u16 vport_num ;
89- int err = 0 ;
125+ u16 vport_num , esw_owner_vhca_id ;
126+ int err ;
90127
91- priv = netdev_priv (dev );
92- rpriv = priv -> ppriv ;
93- vport_num = rpriv -> rep -> vport ;
94- esw = priv -> mdev -> priv .eswitch ;
95- vport = mlx5_eswitch_get_vport (esw , vport_num );
96- if (IS_ERR (vport ))
97- return PTR_ERR (vport );
128+ err = mlx5_esw_bridge_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
129+ & esw_owner_vhca_id );
130+ if (err )
131+ return 0 ;
132+
133+ port_obj_info -> handled = true;
98134
99135 switch (obj -> id ) {
100136 case SWITCHDEV_OBJ_ID_PORT_VLAN :
101137 vlan = SWITCHDEV_OBJ_PORT_VLAN (obj );
102- err = mlx5_esw_bridge_port_vlan_add (vlan -> vid , vlan -> flags , esw , vport , extack );
138+ err = mlx5_esw_bridge_port_vlan_add (vport_num , esw_owner_vhca_id , vlan -> vid ,
139+ vlan -> flags , br_offloads , extack );
103140 break ;
104141 default :
105142 return - EOPNOTSUPP ;
106143 }
107144 return err ;
108145}
109146
110- static int mlx5_esw_bridge_port_obj_del (struct net_device * dev ,
111- const void * ctx ,
112- const struct switchdev_obj * obj )
147+ static int
148+ mlx5_esw_bridge_port_obj_del (struct net_device * dev ,
149+ struct switchdev_notifier_port_obj_info * port_obj_info ,
150+ struct mlx5_esw_bridge_offloads * br_offloads )
113151{
152+ const struct switchdev_obj * obj = port_obj_info -> obj ;
114153 const struct switchdev_obj_port_vlan * vlan ;
115- struct mlx5e_rep_priv * rpriv ;
116- struct mlx5_eswitch * esw ;
117- struct mlx5_vport * vport ;
118- struct mlx5e_priv * priv ;
119- u16 vport_num ;
154+ u16 vport_num , esw_owner_vhca_id ;
155+ int err ;
120156
121- priv = netdev_priv (dev );
122- rpriv = priv -> ppriv ;
123- vport_num = rpriv -> rep -> vport ;
124- esw = priv -> mdev -> priv .eswitch ;
125- vport = mlx5_eswitch_get_vport (esw , vport_num );
126- if (IS_ERR (vport ))
127- return PTR_ERR (vport );
157+ err = mlx5_esw_bridge_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
158+ & esw_owner_vhca_id );
159+ if (err )
160+ return 0 ;
161+
162+ port_obj_info -> handled = true;
128163
129164 switch (obj -> id ) {
130165 case SWITCHDEV_OBJ_ID_PORT_VLAN :
131166 vlan = SWITCHDEV_OBJ_PORT_VLAN (obj );
132- mlx5_esw_bridge_port_vlan_del (vlan -> vid , esw , vport );
167+ mlx5_esw_bridge_port_vlan_del (vport_num , esw_owner_vhca_id , vlan -> vid , br_offloads );
133168 break ;
134169 default :
135170 return - EOPNOTSUPP ;
136171 }
137172 return 0 ;
138173}
139174
140- static int mlx5_esw_bridge_port_obj_attr_set ( struct net_device * dev ,
141- const void * ctx ,
142- const struct switchdev_attr * attr ,
143- struct netlink_ext_ack * extack )
175+ static int
176+ mlx5_esw_bridge_port_obj_attr_set ( struct net_device * dev ,
177+ struct switchdev_notifier_port_attr_info * port_attr_info ,
178+ struct mlx5_esw_bridge_offloads * br_offloads )
144179{
145- struct mlx5e_rep_priv * rpriv ;
146- struct mlx5_eswitch * esw ;
147- struct mlx5_vport * vport ;
148- struct mlx5e_priv * priv ;
149- u16 vport_num ;
150- int err = 0 ;
180+ struct netlink_ext_ack * extack = switchdev_notifier_info_to_extack (& port_attr_info -> info );
181+ const struct switchdev_attr * attr = port_attr_info -> attr ;
182+ u16 vport_num , esw_owner_vhca_id ;
183+ int err ;
151184
152- priv = netdev_priv (dev );
153- rpriv = priv -> ppriv ;
154- vport_num = rpriv -> rep -> vport ;
155- esw = priv -> mdev -> priv .eswitch ;
156- vport = mlx5_eswitch_get_vport (esw , vport_num );
157- if (IS_ERR (vport ))
158- return PTR_ERR (vport );
185+ err = mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
186+ & esw_owner_vhca_id );
187+ if (err )
188+ return 0 ;
189+
190+ port_attr_info -> handled = true;
159191
160192 switch (attr -> id ) {
161193 case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS :
@@ -167,10 +199,12 @@ static int mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
167199 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS :
168200 break ;
169201 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME :
170- err = mlx5_esw_bridge_ageing_time_set (attr -> u .ageing_time , esw , vport );
202+ err = mlx5_esw_bridge_ageing_time_set (vport_num , esw_owner_vhca_id ,
203+ attr -> u .ageing_time , br_offloads );
171204 break ;
172205 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING :
173- err = mlx5_esw_bridge_vlan_filtering_set (attr -> u .vlan_filtering , esw , vport );
206+ err = mlx5_esw_bridge_vlan_filtering_set (vport_num , esw_owner_vhca_id ,
207+ attr -> u .vlan_filtering , br_offloads );
174208 break ;
175209 default :
176210 err = - EOPNOTSUPP ;
@@ -179,27 +213,24 @@ static int mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
179213 return err ;
180214}
181215
182- static int mlx5_esw_bridge_event_blocking (struct notifier_block * unused ,
216+ static int mlx5_esw_bridge_event_blocking (struct notifier_block * nb ,
183217 unsigned long event , void * ptr )
184218{
219+ struct mlx5_esw_bridge_offloads * br_offloads = container_of (nb ,
220+ struct mlx5_esw_bridge_offloads ,
221+ nb_blk );
185222 struct net_device * dev = switchdev_notifier_info_to_dev (ptr );
186223 int err ;
187224
188225 switch (event ) {
189226 case SWITCHDEV_PORT_OBJ_ADD :
190- err = switchdev_handle_port_obj_add (dev , ptr ,
191- mlx5e_eswitch_rep ,
192- mlx5_esw_bridge_port_obj_add );
227+ err = mlx5_esw_bridge_port_obj_add (dev , ptr , br_offloads );
193228 break ;
194229 case SWITCHDEV_PORT_OBJ_DEL :
195- err = switchdev_handle_port_obj_del (dev , ptr ,
196- mlx5e_eswitch_rep ,
197- mlx5_esw_bridge_port_obj_del );
230+ err = mlx5_esw_bridge_port_obj_del (dev , ptr , br_offloads );
198231 break ;
199232 case SWITCHDEV_PORT_ATTR_SET :
200- err = switchdev_handle_port_attr_set (dev , ptr ,
201- mlx5e_eswitch_rep ,
202- mlx5_esw_bridge_port_obj_attr_set );
233+ err = mlx5_esw_bridge_port_obj_attr_set (dev , ptr , br_offloads );
203234 break ;
204235 default :
205236 err = 0 ;
@@ -222,27 +253,27 @@ static void mlx5_esw_bridge_switchdev_fdb_event_work(struct work_struct *work)
222253 container_of (work , struct mlx5_bridge_switchdev_fdb_work , work );
223254 struct switchdev_notifier_fdb_info * fdb_info =
224255 & fdb_work -> fdb_info ;
256+ struct mlx5_esw_bridge_offloads * br_offloads ;
225257 struct net_device * dev = fdb_work -> dev ;
226- struct mlx5e_rep_priv * rpriv ;
227- struct mlx5_eswitch * esw ;
228- struct mlx5_vport * vport ;
258+ u16 vport_num , esw_owner_vhca_id ;
229259 struct mlx5e_priv * priv ;
230- u16 vport_num ;
260+ int err ;
231261
232262 rtnl_lock ();
233263
234264 priv = netdev_priv (dev );
235- rpriv = priv -> ppriv ;
236- vport_num = rpriv -> rep -> vport ;
237- esw = priv -> mdev -> priv .eswitch ;
238- vport = mlx5_eswitch_get_vport (esw , vport_num );
239- if (IS_ERR (vport ))
265+ br_offloads = priv -> mdev -> priv .eswitch -> br_offloads ;
266+ err = mlx5_esw_bridge_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
267+ & esw_owner_vhca_id );
268+ if (err )
240269 goto out ;
241270
242271 if (fdb_work -> add )
243- mlx5_esw_bridge_fdb_create (dev , esw , vport , fdb_info );
272+ mlx5_esw_bridge_fdb_create (dev , vport_num , esw_owner_vhca_id , br_offloads ,
273+ fdb_info );
244274 else
245- mlx5_esw_bridge_fdb_remove (dev , esw , vport , fdb_info );
275+ mlx5_esw_bridge_fdb_remove (dev , vport_num , esw_owner_vhca_id , br_offloads ,
276+ fdb_info );
246277
247278out :
248279 rtnl_unlock ();
@@ -288,18 +319,10 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb,
288319 struct mlx5_bridge_switchdev_fdb_work * work ;
289320 struct switchdev_notifier_info * info = ptr ;
290321 struct net_device * upper ;
291- struct mlx5e_priv * priv ;
292-
293- if (!mlx5e_eswitch_rep (dev ))
294- return NOTIFY_DONE ;
295- priv = netdev_priv (dev );
296- if (priv -> mdev -> priv .eswitch != br_offloads -> esw )
297- return NOTIFY_DONE ;
298322
299323 if (event == SWITCHDEV_PORT_ATTR_SET ) {
300- int err = switchdev_handle_port_attr_set (dev , ptr ,
301- mlx5e_eswitch_rep ,
302- mlx5_esw_bridge_port_obj_attr_set );
324+ int err = mlx5_esw_bridge_port_obj_attr_set (dev , ptr , br_offloads );
325+
303326 return notifier_from_errno (err );
304327 }
305328
@@ -309,6 +332,11 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb,
309332 if (!netif_is_bridge_master (upper ))
310333 return NOTIFY_DONE ;
311334
335+ if (!mlx5e_eswitch_rep (dev ))
336+ return NOTIFY_DONE ;
337+ if (!mlx5_esw_bridge_dev_same_esw (dev , br_offloads -> esw ))
338+ return NOTIFY_DONE ;
339+
312340 switch (event ) {
313341 case SWITCHDEV_FDB_ADD_TO_DEVICE :
314342 case SWITCHDEV_FDB_DEL_TO_DEVICE :
0 commit comments