@@ -1151,9 +1151,9 @@ static int prepare_vlan_ingress_filters_off(struct mxl862xx_priv *priv, uint8_t
11511151 if (port == priv -> cpu_port )
11521152 vlan_cfg .entry_index = priv -> port_info [port ].vlan .ingress_vlan_block_info .filters_max - 1 ;
11531153 else {
1154- vlan_cfg . entry_index =
1155- priv -> port_info [port ]
1156- .vlan .ingress_vlan_block_info .final_filters_idx -- ;
1154+ /* for vlan filter off, this entry is fixed and always put at the end of the block */
1155+ vlan_cfg . entry_index = priv -> port_info [port ]. vlan . ingress_vlan_block_info . filters_max - 1 ;
1156+ priv -> port_info [ port ] .vlan .ingress_vlan_block_info .final_filters_idx = vlan_cfg . entry_index ;
11571157 }
11581158 vlan_cfg .filter .outer_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
11591159 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
@@ -1242,7 +1242,7 @@ static int prepare_vlan_egress_filters(struct dsa_switch *ds, uint8_t port, uint
12421242 //Entry 4: no outer/inner tag, no PVID DISCARD
12431243 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
12441244 vlan_cfg .extended_vlan_block_id = block_info -> block_id ;
1245- vlan_cfg .entry_index = block_info -> final_filters_idx -- ;
1245+ vlan_cfg .entry_index = block_info -> filters_max - 1 ;
12461246 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
12471247 vlan_cfg .filter .outer_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
12481248 vlan_cfg .treatment .remove_tag =
@@ -1252,10 +1252,12 @@ static int prepare_vlan_egress_filters(struct dsa_switch *ds, uint8_t port, uint
12521252 if (ret )
12531253 return ret ;
12541254
1255+ block_info -> final_filters_idx = vlan_cfg .entry_index ;
1256+
12551257 //Entry 3: Only Outer tag present. Discard if VID is not matching the previous rules
12561258 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
12571259 vlan_cfg .extended_vlan_block_id = block_info -> block_id ;
1258- vlan_cfg .entry_index = block_info -> final_filters_idx -- ;
1260+ vlan_cfg .entry_index = block_info -> filters_max - 2 ;
12591261 vlan_cfg .filter .outer_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL ;
12601262 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
12611263 vlan_cfg .treatment .remove_tag =
@@ -1265,10 +1267,12 @@ static int prepare_vlan_egress_filters(struct dsa_switch *ds, uint8_t port, uint
12651267 if (ret )
12661268 return ret ;
12671269
1270+ block_info -> final_filters_idx = vlan_cfg .entry_index ;
1271+
12681272 //Entry 2: Outer and Inner tags are present. Discard if VID is not matching the previous rules
12691273 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
12701274 vlan_cfg .extended_vlan_block_id = block_info -> block_id ;
1271- vlan_cfg .entry_index = block_info -> final_filters_idx -- ;
1275+ vlan_cfg .entry_index = block_info -> filters_max - 3 ;
12721276 vlan_cfg .filter .outer_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL ;
12731277 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL ;
12741278 vlan_cfg .treatment .remove_tag =
@@ -1278,6 +1282,8 @@ static int prepare_vlan_egress_filters(struct dsa_switch *ds, uint8_t port, uint
12781282 if (ret )
12791283 return ret ;
12801284
1285+ block_info -> final_filters_idx = vlan_cfg .entry_index ;
1286+
12811287 /* VID specific entries must be processed before the final entries,
12821288 * so putting them at the beginnig of the block */
12831289 ret = get_vlan_vid_filters_idx (priv , port , false, vid , & filter_0 , & filter_1 , & idx );
@@ -1982,9 +1988,7 @@ static int prepare_vlan_ingress_filters(struct dsa_switch *ds, uint8_t port, uin
19821988 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
19831989 vlan_cfg .extended_vlan_block_id =
19841990 priv -> port_info [port ].vlan .ingress_vlan_block_info .block_id ;
1985- vlan_cfg .entry_index =
1986- priv -> port_info [port ]
1987- .vlan .ingress_vlan_block_info .final_filters_idx -- ;
1991+ vlan_cfg .entry_index = priv -> port_info [port ].vlan .ingress_vlan_block_info .filters_max - 1 ;
19881992 vlan_cfg .filter .outer_vlan .type =
19891993 MXL862XX_EXTENDEDVLAN_FILTER_TYPE_DEFAULT ;
19901994 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
@@ -2000,13 +2004,13 @@ static int prepare_vlan_ingress_filters(struct dsa_switch *ds, uint8_t port, uin
20002004 return ret ;
20012005 }
20022006
2007+ priv -> port_info [port ].vlan .ingress_vlan_block_info .final_filters_idx = vlan_cfg .entry_index ;
2008+
20032009 //Entry 5 no other rule applies Outer tag default Inner tag present DISCARD
20042010 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
20052011 vlan_cfg .extended_vlan_block_id =
20062012 priv -> port_info [port ].vlan .ingress_vlan_block_info .block_id ;
2007- vlan_cfg .entry_index =
2008- priv -> port_info [port ]
2009- .vlan .ingress_vlan_block_info .final_filters_idx -- ;
2013+ vlan_cfg .entry_index = priv -> port_info [port ].vlan .ingress_vlan_block_info .filters_max - 2 ;
20102014 vlan_cfg .filter .outer_vlan .type =
20112015 MXL862XX_EXTENDEDVLAN_FILTER_TYPE_DEFAULT ;
20122016 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL ;
@@ -2022,13 +2026,13 @@ static int prepare_vlan_ingress_filters(struct dsa_switch *ds, uint8_t port, uin
20222026 return ret ;
20232027 }
20242028
2029+ priv -> port_info [port ].vlan .ingress_vlan_block_info .final_filters_idx = vlan_cfg .entry_index ;
2030+
20252031 // Entry 4 untagged pkts. If there's PVID accept and add PVID tag, otherwise reject
20262032 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
20272033 vlan_cfg .extended_vlan_block_id =
20282034 priv -> port_info [port ].vlan .ingress_vlan_block_info .block_id ;
2029- vlan_cfg .entry_index =
2030- priv -> port_info [port ]
2031- .vlan .ingress_vlan_block_info .final_filters_idx -- ;
2035+ vlan_cfg .entry_index = priv -> port_info [port ].vlan .ingress_vlan_block_info .filters_max - 3 ;
20322036 vlan_cfg .filter .outer_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
20332037 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
20342038 if (!priv -> port_info [port ].vlan .pvid ) {
@@ -2053,13 +2057,13 @@ static int prepare_vlan_ingress_filters(struct dsa_switch *ds, uint8_t port, uin
20532057 if (ret )
20542058 return ret ;
20552059
2060+ priv -> port_info [port ].vlan .ingress_vlan_block_info .final_filters_idx = vlan_cfg .entry_index ;
2061+
20562062 // Entry 3 : Only Outer tag present : not matching DISCARD
20572063 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
20582064 vlan_cfg .extended_vlan_block_id =
20592065 priv -> port_info [port ].vlan .ingress_vlan_block_info .block_id ;
2060- vlan_cfg .entry_index =
2061- priv -> port_info [port ]
2062- .vlan .ingress_vlan_block_info .final_filters_idx -- ;
2066+ vlan_cfg .entry_index = priv -> port_info [port ].vlan .ingress_vlan_block_info .filters_max - 4 ;
20632067 vlan_cfg .filter .outer_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL ;
20642068 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NO_TAG ;
20652069 vlan_cfg .treatment .remove_tag =
@@ -2069,14 +2073,13 @@ static int prepare_vlan_ingress_filters(struct dsa_switch *ds, uint8_t port, uin
20692073 if (ret )
20702074 return ret ;
20712075
2076+ priv -> port_info [port ].vlan .ingress_vlan_block_info .final_filters_idx = vlan_cfg .entry_index ;
2077+
20722078 // Entry 2 : Outer and Inner VLAN tag present : not matching DISCARD
20732079 memset (& vlan_cfg , 0 , sizeof (vlan_cfg ));
20742080 vlan_cfg .extended_vlan_block_id =
20752081 priv -> port_info [port ].vlan .ingress_vlan_block_info .block_id ;
2076- vlan_cfg .entry_index =
2077- priv -> port_info [port ]
2078- .vlan .ingress_vlan_block_info .final_filters_idx -- ;
2079-
2082+ vlan_cfg .entry_index = priv -> port_info [port ].vlan .ingress_vlan_block_info .filters_max - 5 ;
20802083 vlan_cfg .filter .outer_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL ;
20812084 vlan_cfg .filter .inner_vlan .type = MXL862XX_EXTENDEDVLAN_FILTER_TYPE_NORMAL ;
20822085 vlan_cfg .treatment .remove_tag =
@@ -2086,6 +2089,8 @@ static int prepare_vlan_ingress_filters(struct dsa_switch *ds, uint8_t port, uin
20862089 if (ret )
20872090 return ret ;
20882091
2092+ priv -> port_info [port ].vlan .ingress_vlan_block_info .final_filters_idx = vlan_cfg .entry_index ;
2093+
20892094 /* VID specific filtering rules which should be executed first before final ones.
20902095 * Storing starts at the beginning of the block. */
20912096
@@ -3226,7 +3231,7 @@ static void mxl862xx_phylink_get_caps(struct dsa_switch *ds, int port,
32263231 __set_bit (PHY_INTERFACE_MODE_2500BASEX , config -> supported_interfaces );
32273232 __set_bit (PHY_INTERFACE_MODE_10GBASER , config -> supported_interfaces );
32283233 __set_bit (PHY_INTERFACE_MODE_USXGMII , config -> supported_interfaces );
3229- config -> mac_capabilities |= MAC_5000FD | MAC_10000FD ;
3234+ config -> mac_capabilities |= MAC_10000FD ;
32303235 } else {
32313236 __set_bit (PHY_INTERFACE_MODE_NA , config -> supported_interfaces );
32323237 }
@@ -3484,7 +3489,7 @@ static int mxl862xx_port_fdb_add(struct dsa_switch *ds, int port,
34843489{
34853490 struct mxl862xx_mac_table_add param = {
34863491 .port_id = DSA_MXL_PORT (port ),
3487- .tci = vid & 0xFFF ,
3492+ .tci = 0 ,
34883493 .static_entry = true,
34893494 };
34903495 struct mxl862xx_priv * priv = ds -> priv ;
@@ -3503,6 +3508,9 @@ static int mxl862xx_port_fdb_add(struct dsa_switch *ds, int port,
35033508 continue ;
35043509
35053510 param .fid = priv -> port_info [i ].bridge_id ;
3511+ if (priv -> port_info [priv -> cpu_port ].tag_protocol == DSA_TAG_PROTO_MXL862 ) {
3512+ param .tci = (vid & 0xFFF );
3513+ }
35063514 ret = MXL862XX_API_READ (ds -> priv , MXL862XX_MAC_TABLEENTRYADD , param );
35073515 if (ret ) {
35083516 dev_err (ds -> dev , "failed to add FDB entry on port %d / fid %d\n" ,
@@ -3518,12 +3526,15 @@ static int mxl862xx_port_fdb_del(struct dsa_switch *ds, int port,
35183526 const unsigned char * addr , u16 vid , struct dsa_db db )
35193527{
35203528 struct mxl862xx_mac_table_remove param = {
3521- .tci = vid & 0xFFF ,
3529+ .tci = 0 ,
35223530 };
35233531 struct mxl862xx_priv * priv = ds -> priv ;
35243532 int ret , i ;
35253533
35263534 memcpy (param .mac , addr , ETH_ALEN );
3535+ if (priv -> port_info [priv -> cpu_port ].tag_protocol == DSA_TAG_PROTO_MXL862 ) {
3536+ param .tci = (vid & 0xFFF );
3537+ }
35273538
35283539 for (i = 0 ; i < priv -> hw_info -> max_ports ; i ++ ) {
35293540 if (dsa_is_unused_port (ds , i ))
0 commit comments