Skip to content

Commit ed1decf

Browse files
fchanfrank-w
authored andcommitted
net: dsa: mxl862xx: Fix issues
1. Packets fail to hit the FDB table when adding an FDB entry in mxl862_8021q mode. 2. VLAN add-delete operations cause the exVlan entries too low problem in mxl862 mode.
1 parent 7ec3281 commit ed1decf

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

drivers/net/dsa/mxl862xx/mxl862xx.c

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)