4141#define MXL862XX_FDMA_PCTRLP (p ) (0xA80 + ((p) * 0x6))
4242#define MXL862XX_FDMA_PCTRL_EN BIT(0) /* FDMA Port Enable */
4343
44- #define MAX_VLAN_ENTRIES (1024 - 160 )
44+ #define MAX_VLAN_ENTRIES (1024)
4545#define IDX_INVAL (-1)
4646
4747#define INGRESS_FINAL_RULES 5
@@ -266,20 +266,24 @@ static int mxl862xx_update_bridge_conf_port(struct dsa_switch *ds, u8 port,
266266 br_port_cfg .mask |=
267267 MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP |
268268 MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID |
269- MXL862XX_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING ;
269+ MXL862XX_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING |
270+ MXL862XX_BRIDGE_PORT_CONFIG_MASK_VLAN_BASED_MAC_LEARNING ;
270271
271272 /* Skip the port itself in it's own portmap */
272273 br_port_cfg .bridge_port_map [0 ] =
273274 priv -> bridge_portmap [bridge_id ] & ~(BIT (DSA_MXL_PORT (i )));
274275
275276 if (action ) {
276277 br_port_cfg .src_mac_learning_disable = !bridge ;
278+ br_port_cfg .vlan_src_mac_vid_enable = br_port_cfg .vlan_dst_mac_vid_enable =
279+ (vlan_sp_tag ) ? false : (bridge != NULL );
277280 br_port_cfg .bridge_id = bridge_id ;
278281 } else {
279282 /* When port is removed from the bridge, assign it back to the default
280283 * bridge 0
281284 */
282285 br_port_cfg .src_mac_learning_disable = true;
286+ br_port_cfg .vlan_src_mac_vid_enable = br_port_cfg .vlan_dst_mac_vid_enable = false;
283287 /* Cleanup the port own map leaving only the CPU port mapping. */
284288 if (i == port ) {
285289 br_port_cfg .bridge_port_map [0 ] = BIT (DSA_MXL_PORT (cpu_port ));
@@ -2257,7 +2261,7 @@ static int mxl862xx_port_vlan_add(struct dsa_switch *ds, int port,
22572261 /* vlan_filtering disabled */
22582262 /* skiping this configuration for vlan_sp_tag/cpu port as it requires special rules defined above */
22592263 if (!priv -> port_info [port ].vlan .filtering ) {
2260- dev_info (ds -> dev ,
2264+ dev_dbg (ds -> dev ,
22612265 "%s: port:%d setting VLAN:%d with vlan_filtering disabled\n" ,
22622266 __func__ , port , vid );
22632267 ret = prepare_vlan_ingress_filters_off_sp_tag (ds , port , vid );
@@ -2412,8 +2416,9 @@ static int mxl862xx_port_vlan_add(struct dsa_switch *ds, int port,
24122416 /* Update bridge port */
24132417 br_port_cfg .bridge_port_id = DSA_MXL_PORT (port );
24142418 br_port_cfg .mask |= MXL862XX_BRIDGE_PORT_CONFIG_MASK_EGRESS_VLAN |
2415- MXL862XX_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN |
2416- MXL862XX_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING ;
2419+ MXL862XX_BRIDGE_PORT_CONFIG_MASK_INGRESS_VLAN |
2420+ MXL862XX_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING |
2421+ MXL862XX_BRIDGE_PORT_CONFIG_MASK_VLAN_BASED_MAC_LEARNING ;
24172422 br_port_cfg .egress_extended_vlan_enable = true;
24182423 br_port_cfg .egress_extended_vlan_block_id =
24192424 priv -> port_info [port ].vlan .egress_vlan_block_info .block_id ;
@@ -2422,8 +2427,9 @@ static int mxl862xx_port_vlan_add(struct dsa_switch *ds, int port,
24222427 priv -> port_info [port ].vlan .ingress_vlan_block_info .block_id ;
24232428
24242429 /* Disable MAC learning for standalone ports. */
2425- br_port_cfg .src_mac_learning_disable =
2426- (standalone_port ) ? true : false;
2430+ br_port_cfg .src_mac_learning_disable = (standalone_port ) ? true : false;
2431+ br_port_cfg .vlan_src_mac_vid_enable = br_port_cfg .vlan_dst_mac_vid_enable =
2432+ (vlan_sp_tag ) ? false : !standalone_port ;
24272433
24282434 ret = MXL862XX_API_WRITE (priv , MXL862XX_BRIDGEPORT_CONFIGSET , br_port_cfg );
24292435 if (ret ) {
@@ -2514,7 +2520,7 @@ static int mxl862xx_port_vlan_del(struct dsa_switch *ds, int port,
25142520static_rules_cleanup :
25152521 /* If this is the last vlan entry or no entries left,
25162522 * remove static entries (placed at the end of the block) */
2517- if (last_vlan && block_id ) {
2523+ if (last_vlan && block_id != 0xffff ) {
25182524 for (entry_idx = block_info -> final_filters_idx ; entry_idx < block_info -> filters_max ; entry_idx ++ ) {
25192525 ret = deactivate_vlan_filter_entry (ds , block_id , entry_idx );
25202526 if (ret )
@@ -2666,12 +2672,18 @@ static int mxl862xx_find_bridge_id(struct dsa_switch *ds, struct net_device *bri
26662672static int mxl862xx_mac_learning (struct dsa_switch * ds , int port , bool enable )
26672673{
26682674 struct mxl862xx_bridge_port_config param = {
2669- .mask = MXL862XX_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING ,
2675+ .mask = MXL862XX_BRIDGE_PORT_CONFIG_MASK_MC_SRC_MAC_LEARNING |
2676+ MXL862XX_BRIDGE_PORT_CONFIG_MASK_VLAN_BASED_MAC_LEARNING ,
26702677 .bridge_port_id = DSA_MXL_PORT (port ),
26712678 .src_mac_learning_disable = !enable ,
26722679 };
26732680 int ret ;
2681+ struct mxl862xx_priv * priv = ds -> priv ;
2682+ u8 cpu_port = priv -> cpu_port ;
2683+ bool vlan_sp_tag = (priv -> port_info [cpu_port ].tag_protocol == DSA_TAG_PROTO_MXL862_8021Q );
26742684
2685+ param .vlan_src_mac_vid_enable = param .vlan_dst_mac_vid_enable =
2686+ (vlan_sp_tag ) ? false : enable ;
26752687 ret = MXL862XX_API_WRITE (ds -> priv , MXL862XX_BRIDGEPORT_CONFIGSET , param );
26762688 if (ret )
26772689 dev_err (ds -> dev , "failed to %s MAC learning on port %d\n" ,
@@ -2739,6 +2751,10 @@ static void mxl862xx_set_vlan_filter_limits(struct dsa_switch *ds)
27392751 vlan -> egress_vlan_block_info .final_filters_idx =
27402752 vlan -> egress_vlan_block_info .filters_max - 1 ;
27412753
2754+ /* block_id uninitialized */
2755+ vlan -> ingress_vlan_block_info .block_id = 0xffff ;
2756+ vlan -> egress_vlan_block_info .block_id = 0xffff ;
2757+
27422758 /* Set limits and indexes required for processing VLAN rules for user ports */
27432759 for (i = 0 ; i < priv -> hw_info -> max_ports ; i ++ ) {
27442760 if (dsa_is_unused_port (ds , i ))
0 commit comments