@@ -73,6 +73,10 @@ static int lan966x_port_attr_set(struct net_device *dev, const void *ctx,
7373 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME :
7474 lan966x_port_ageing_set (port , attr -> u .ageing_time );
7575 break ;
76+ case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING :
77+ lan966x_vlan_port_set_vlan_aware (port , attr -> u .vlan_filtering );
78+ lan966x_vlan_port_apply (port );
79+ break ;
7680 default :
7781 err = - EOPNOTSUPP ;
7882 break ;
@@ -120,7 +124,10 @@ static void lan966x_port_bridge_leave(struct lan966x_port *port,
120124 if (!lan966x -> bridge_mask )
121125 lan966x -> bridge = NULL ;
122126
123- lan966x_mac_cpu_learn (lan966x , port -> dev -> dev_addr , PORT_PVID );
127+ /* Set the port back to host mode */
128+ lan966x_vlan_port_set_vlan_aware (port , false);
129+ lan966x_vlan_port_set_vid (port , HOST_PVID , false, false);
130+ lan966x_vlan_port_apply (port );
124131}
125132
126133static int lan966x_port_changeupper (struct net_device * dev ,
@@ -264,6 +271,91 @@ static int lan966x_switchdev_event(struct notifier_block *nb,
264271 return NOTIFY_DONE ;
265272}
266273
274+ static int lan966x_handle_port_vlan_add (struct lan966x_port * port ,
275+ const struct switchdev_obj * obj )
276+ {
277+ const struct switchdev_obj_port_vlan * v = SWITCHDEV_OBJ_PORT_VLAN (obj );
278+ struct lan966x * lan966x = port -> lan966x ;
279+
280+ /* When adding a port to a vlan, we get a callback for the port but
281+ * also for the bridge. When get the callback for the bridge just bail
282+ * out. Then when the bridge is added to the vlan, then we get a
283+ * callback here but in this case the flags has set:
284+ * BRIDGE_VLAN_INFO_BRENTRY. In this case it means that the CPU
285+ * port is added to the vlan, so the broadcast frames and unicast frames
286+ * with dmac of the bridge should be foward to CPU.
287+ */
288+ if (netif_is_bridge_master (obj -> orig_dev ) &&
289+ !(v -> flags & BRIDGE_VLAN_INFO_BRENTRY ))
290+ return 0 ;
291+
292+ if (!netif_is_bridge_master (obj -> orig_dev ))
293+ lan966x_vlan_port_add_vlan (port , v -> vid ,
294+ v -> flags & BRIDGE_VLAN_INFO_PVID ,
295+ v -> flags & BRIDGE_VLAN_INFO_UNTAGGED );
296+ else
297+ lan966x_vlan_cpu_add_vlan (lan966x , v -> vid );
298+
299+ return 0 ;
300+ }
301+
302+ static int lan966x_handle_port_obj_add (struct net_device * dev , const void * ctx ,
303+ const struct switchdev_obj * obj ,
304+ struct netlink_ext_ack * extack )
305+ {
306+ struct lan966x_port * port = netdev_priv (dev );
307+ int err ;
308+
309+ if (ctx && ctx != port )
310+ return 0 ;
311+
312+ switch (obj -> id ) {
313+ case SWITCHDEV_OBJ_ID_PORT_VLAN :
314+ err = lan966x_handle_port_vlan_add (port , obj );
315+ break ;
316+ default :
317+ err = - EOPNOTSUPP ;
318+ break ;
319+ }
320+
321+ return err ;
322+ }
323+
324+ static int lan966x_handle_port_vlan_del (struct lan966x_port * port ,
325+ const struct switchdev_obj * obj )
326+ {
327+ const struct switchdev_obj_port_vlan * v = SWITCHDEV_OBJ_PORT_VLAN (obj );
328+ struct lan966x * lan966x = port -> lan966x ;
329+
330+ if (!netif_is_bridge_master (obj -> orig_dev ))
331+ lan966x_vlan_port_del_vlan (port , v -> vid );
332+ else
333+ lan966x_vlan_cpu_del_vlan (lan966x , v -> vid );
334+
335+ return 0 ;
336+ }
337+
338+ static int lan966x_handle_port_obj_del (struct net_device * dev , const void * ctx ,
339+ const struct switchdev_obj * obj )
340+ {
341+ struct lan966x_port * port = netdev_priv (dev );
342+ int err ;
343+
344+ if (ctx && ctx != port )
345+ return 0 ;
346+
347+ switch (obj -> id ) {
348+ case SWITCHDEV_OBJ_ID_PORT_VLAN :
349+ err = lan966x_handle_port_vlan_del (port , obj );
350+ break ;
351+ default :
352+ err = - EOPNOTSUPP ;
353+ break ;
354+ }
355+
356+ return err ;
357+ }
358+
267359static int lan966x_switchdev_blocking_event (struct notifier_block * nb ,
268360 unsigned long event ,
269361 void * ptr )
@@ -272,6 +364,16 @@ static int lan966x_switchdev_blocking_event(struct notifier_block *nb,
272364 int err ;
273365
274366 switch (event ) {
367+ case SWITCHDEV_PORT_OBJ_ADD :
368+ err = switchdev_handle_port_obj_add (dev , ptr ,
369+ lan966x_netdevice_check ,
370+ lan966x_handle_port_obj_add );
371+ return notifier_from_errno (err );
372+ case SWITCHDEV_PORT_OBJ_DEL :
373+ err = switchdev_handle_port_obj_del (dev , ptr ,
374+ lan966x_netdevice_check ,
375+ lan966x_handle_port_obj_del );
376+ return notifier_from_errno (err );
275377 case SWITCHDEV_PORT_ATTR_SET :
276378 err = switchdev_handle_port_attr_set (dev , ptr ,
277379 lan966x_netdevice_check ,
0 commit comments