return 0;
}
+static int rtldsa_port_vlan_fast_age(struct dsa_switch *ds, int port, u16 vid)
+{
+ struct rtl838x_switch_priv *priv = ds->priv;
+ int ret;
+
+ if (!priv->r->vlan_port_fast_age)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&priv->reg_mutex);
+ ret = priv->r->vlan_port_fast_age(priv, port, vid);
+ mutex_unlock(&priv->reg_mutex);
+
+ return ret;
+}
+
static void rtl83xx_setup_l2_uc_entry(struct rtl838x_l2_entry *e, int port, int vid, u64 mac)
{
memset(e, 0, sizeof(*e));
.port_vlan_filtering = rtl83xx_vlan_filtering,
.port_vlan_add = rtl83xx_vlan_add,
.port_vlan_del = rtl83xx_vlan_del,
+ .port_vlan_fast_age = rtldsa_port_vlan_fast_age,
.port_fdb_add = rtl83xx_port_fdb_add,
.port_fdb_del = rtl83xx_port_fdb_del,
void (*vlan_port_pvidmode_set)(int port, enum pbvlan_type type, enum pbvlan_mode mode);
void (*vlan_port_pvid_set)(int port, enum pbvlan_type type, int pvid);
void (*vlan_port_keep_tag_set)(int port, bool keep_outer, bool keep_inner);
+ int (*vlan_port_fast_age)(struct rtl838x_switch_priv *priv, int port, u16 vid);
void (*set_vlan_igr_filter)(int port, enum igr_filter state);
void (*set_vlan_egr_filter)(int port, enum egr_filter state);
void (*enable_learning)(int port, bool enable);
sw_w32_mask(0xfff << 16, pvid << 16, RTL930X_VLAN_PORT_PB_VLAN + (port << 2));
}
+static int rtldsa_930x_vlan_port_fast_age(struct rtl838x_switch_priv *priv, int port, u16 vid)
+{
+ u32 val;
+
+ sw_w32(port << 11, RTL930X_L2_TBL_FLUSH_CTRL + 4);
+
+ val = 0;
+ val |= vid << 12;
+ val |= BIT(26); /* compare port id */
+ val |= BIT(28); /* compare VID */
+ val |= BIT(30); /* status - trigger flush */
+ sw_w32(val, RTL930X_L2_TBL_FLUSH_CTRL);
+
+ do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(30));
+
+ return 0;
+}
+
static int rtl930x_set_ageing_time(unsigned long msec)
{
int t = sw_r32(RTL930X_L2_AGE_CTRL);
.vlan_port_keep_tag_set = rtl930x_vlan_port_keep_tag_set,
.vlan_port_pvidmode_set = rtl930x_vlan_port_pvidmode_set,
.vlan_port_pvid_set = rtl930x_vlan_port_pvid_set,
+ .vlan_port_fast_age = rtldsa_930x_vlan_port_fast_age,
.trk_mbr_ctr = rtl930x_trk_mbr_ctr,
.rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK,
.init_eee = rtl930x_init_eee,
sw_w32_mask(0xfff << 14, pvid << 14, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2));
}
+static int rtldsa_931x_vlan_port_fast_age(struct rtl838x_switch_priv *priv, int port, u16 vid)
+{
+ u32 val;
+
+ sw_w32(vid << 20, RTL931X_L2_TBL_FLUSH_CTRL + 4);
+
+ val = 0;
+ val |= port << 11;
+ val |= BIT(24); /* compare port id */
+ val |= BIT(26); /* compare VID */
+ val |= BIT(28); /* status - trigger flush */
+ sw_w32(val, RTL931X_L2_TBL_FLUSH_CTRL);
+
+ do { } while (sw_r32(RTL931X_L2_TBL_FLUSH_CTRL) & BIT (28));
+
+ return 0;
+}
+
static void rtl931x_set_igr_filter(int port, enum igr_filter state)
{
sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1),
.vlan_port_keep_tag_set = rtl931x_vlan_port_keep_tag_set,
.vlan_port_pvidmode_set = rtl931x_vlan_port_pvidmode_set,
.vlan_port_pvid_set = rtl931x_vlan_port_pvid_set,
+ .vlan_port_fast_age = rtldsa_931x_vlan_port_fast_age,
.trk_mbr_ctr = rtldsa_931x_trk_mbr_ctr,
.rma_bpdu_fld_pmask = RTL931X_RMA_BPDU_FLD_PMSK,
.set_vlan_igr_filter = rtl931x_set_igr_filter,