return err;
}
-static bool mv88e6xxx_6097_family(struct mv88e6xxx_chip *chip)
-{
- return chip->info->family == MV88E6XXX_FAMILY_6097;
-}
-
-static bool mv88e6xxx_6165_family(struct mv88e6xxx_chip *chip)
-{
- return chip->info->family == MV88E6XXX_FAMILY_6165;
-}
-
-static bool mv88e6xxx_6341_family(struct mv88e6xxx_chip *chip)
-{
- return chip->info->family == MV88E6XXX_FAMILY_6341;
-}
-
-static bool mv88e6xxx_6351_family(struct mv88e6xxx_chip *chip)
-{
- return chip->info->family == MV88E6XXX_FAMILY_6351;
-}
-
-static bool mv88e6xxx_6352_family(struct mv88e6xxx_chip *chip)
-{
- return chip->info->family == MV88E6XXX_FAMILY_6352;
-}
-
static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
int link, int speed, int duplex,
phy_interface_t mode)
netdev_err(ds->ports[port].netdev, "failed to flush ATU\n");
}
-static int _mv88e6xxx_vtu_stu_flush(struct mv88e6xxx_chip *chip)
+static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
{
- int ret;
-
- ret = mv88e6xxx_g1_vtu_op_wait(chip);
- if (ret < 0)
- return ret;
+ if (!chip->info->max_vid)
+ return 0;
- return mv88e6xxx_g1_vtu_op(chip, GLOBAL_VTU_OP_FLUSH_ALL);
+ return mv88e6xxx_g1_vtu_flush(chip);
}
-static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry,
- unsigned int nibble_offset)
+static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
+ struct mv88e6xxx_vtu_entry *entry)
{
- u16 regs[3];
- int i, err;
-
- for (i = 0; i < 3; ++i) {
- u16 *reg = ®s[i];
-
- err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
- if (err)
- return err;
- }
-
- for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
- unsigned int shift = (i % 4) * 4 + nibble_offset;
- u16 reg = regs[i / 4];
-
- entry->state[i] = (reg >> shift) & GLOBAL_VTU_STU_DATA_MASK;
- }
-
- return 0;
-}
+ if (!chip->info->ops->vtu_getnext)
+ return -EOPNOTSUPP;
-static int mv88e6xxx_vtu_data_read(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry)
-{
- return _mv88e6xxx_vtu_stu_data_read(chip, entry, 0);
+ return chip->info->ops->vtu_getnext(chip, entry);
}
-static int mv88e6xxx_stu_data_read(struct mv88e6xxx_chip *chip,
+static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
struct mv88e6xxx_vtu_entry *entry)
{
- return _mv88e6xxx_vtu_stu_data_read(chip, entry, 2);
-}
-
-static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry,
- unsigned int nibble_offset)
-{
- u16 regs[3] = { 0 };
- int i, err;
-
- for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
- unsigned int shift = (i % 4) * 4 + nibble_offset;
- u8 data = entry->state[i];
-
- regs[i / 4] |= (data & GLOBAL_VTU_STU_DATA_MASK) << shift;
- }
-
- for (i = 0; i < 3; ++i) {
- u16 reg = regs[i];
-
- err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
- if (err)
- return err;
- }
-
- return 0;
-}
-
-static int mv88e6xxx_vtu_data_write(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry)
-{
- return _mv88e6xxx_vtu_stu_data_write(chip, entry, 0);
-}
-
-static int mv88e6xxx_stu_data_write(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry)
-{
- return _mv88e6xxx_vtu_stu_data_write(chip, entry, 2);
-}
-
-static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_chip *chip, u16 vid)
-{
- return mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID,
- vid & GLOBAL_VTU_VID_MASK);
-}
-
-static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry)
-{
- struct mv88e6xxx_vtu_entry next = { 0 };
- u16 val;
- int err;
-
- err = mv88e6xxx_g1_vtu_op_wait(chip);
- if (err)
- return err;
-
- err = mv88e6xxx_g1_vtu_op(chip, GLOBAL_VTU_OP_VTU_GET_NEXT);
- if (err)
- return err;
-
- err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
- if (err)
- return err;
-
- next.vid = val & GLOBAL_VTU_VID_MASK;
- next.valid = !!(val & GLOBAL_VTU_VID_VALID);
-
- if (next.valid) {
- err = mv88e6xxx_vtu_data_read(chip, &next);
- if (err)
- return err;
-
- if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
- err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_FID, &val);
- if (err)
- return err;
-
- next.fid = val & GLOBAL_VTU_FID_MASK;
- } else if (mv88e6xxx_num_databases(chip) == 256) {
- /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
- * VTU DBNum[3:0] are located in VTU Operation 3:0
- */
- err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_OP, &val);
- if (err)
- return err;
-
- next.fid = (val & 0xf00) >> 4;
- next.fid |= val & 0xf;
- }
-
- if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
- err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
- if (err)
- return err;
-
- next.sid = val & GLOBAL_VTU_SID_MASK;
- }
- }
+ if (!chip->info->ops->vtu_loadpurge)
+ return -EOPNOTSUPP;
- *entry = next;
- return 0;
+ return chip->info->ops->vtu_loadpurge(chip, entry);
}
static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
int (*cb)(struct switchdev_obj *obj))
{
struct mv88e6xxx_chip *chip = ds->priv;
- struct mv88e6xxx_vtu_entry next;
+ struct mv88e6xxx_vtu_entry next = {
+ .vid = chip->info->max_vid,
+ };
u16 pvid;
int err;
if (err)
goto unlock;
- err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
- if (err)
- goto unlock;
-
do {
- err = _mv88e6xxx_vtu_getnext(chip, &next);
+ err = mv88e6xxx_vtu_getnext(chip, &next);
if (err)
break;
return err;
}
-static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry)
-{
- u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE;
- u16 reg = 0;
- int err;
-
- err = mv88e6xxx_g1_vtu_op_wait(chip);
- if (err)
- return err;
-
- if (!entry->valid)
- goto loadpurge;
-
- /* Write port member tags */
- err = mv88e6xxx_vtu_data_write(chip, entry);
- if (err)
- return err;
-
- if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
- reg = entry->sid & GLOBAL_VTU_SID_MASK;
- err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
- if (err)
- return err;
- }
-
- if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
- reg = entry->fid & GLOBAL_VTU_FID_MASK;
- err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_FID, reg);
- if (err)
- return err;
- } else if (mv88e6xxx_num_databases(chip) == 256) {
- /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
- * VTU DBNum[3:0] are located in VTU Operation 3:0
- */
- op |= (entry->fid & 0xf0) << 8;
- op |= entry->fid & 0xf;
- }
-
- reg = GLOBAL_VTU_VID_VALID;
-loadpurge:
- reg |= entry->vid & GLOBAL_VTU_VID_MASK;
- err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
- if (err)
- return err;
-
- return mv88e6xxx_g1_vtu_op(chip, op);
-}
-
-static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_chip *chip, u8 sid,
- struct mv88e6xxx_vtu_entry *entry)
-{
- struct mv88e6xxx_vtu_entry next = { 0 };
- u16 val;
- int err;
-
- err = mv88e6xxx_g1_vtu_op_wait(chip);
- if (err)
- return err;
-
- err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID,
- sid & GLOBAL_VTU_SID_MASK);
- if (err)
- return err;
-
- err = mv88e6xxx_g1_vtu_op(chip, GLOBAL_VTU_OP_STU_GET_NEXT);
- if (err)
- return err;
-
- err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
- if (err)
- return err;
-
- next.sid = val & GLOBAL_VTU_SID_MASK;
-
- err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
- if (err)
- return err;
-
- next.valid = !!(val & GLOBAL_VTU_VID_VALID);
-
- if (next.valid) {
- err = mv88e6xxx_stu_data_read(chip, &next);
- if (err)
- return err;
- }
-
- *entry = next;
- return 0;
-}
-
-static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_vtu_entry *entry)
-{
- u16 reg = 0;
- int err;
-
- err = mv88e6xxx_g1_vtu_op_wait(chip);
- if (err)
- return err;
-
- if (!entry->valid)
- goto loadpurge;
-
- /* Write port states */
- err = mv88e6xxx_stu_data_write(chip, entry);
- if (err)
- return err;
-
- reg = GLOBAL_VTU_VID_VALID;
-loadpurge:
- err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
- if (err)
- return err;
-
- reg = entry->sid & GLOBAL_VTU_SID_MASK;
- err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
- if (err)
- return err;
-
- return mv88e6xxx_g1_vtu_op(chip, GLOBAL_VTU_OP_STU_LOAD_PURGE);
-}
-
static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
{
DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
- struct mv88e6xxx_vtu_entry vlan;
+ struct mv88e6xxx_vtu_entry vlan = {
+ .vid = chip->info->max_vid,
+ };
int i, err;
bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
}
/* Set every FID bit used by the VLAN entries */
- err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
- if (err)
- return err;
-
do {
- err = _mv88e6xxx_vtu_getnext(chip, &vlan);
+ err = mv88e6xxx_vtu_getnext(chip, &vlan);
if (err)
return err;
return mv88e6xxx_g1_atu_flush(chip, *fid, true);
}
-static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid,
- struct mv88e6xxx_vtu_entry *entry)
-{
- struct dsa_switch *ds = chip->ds;
- struct mv88e6xxx_vtu_entry vlan = {
- .valid = true,
- .vid = vid,
- };
- int i, err;
-
- err = mv88e6xxx_atu_new(chip, &vlan.fid);
- if (err)
- return err;
-
- /* exclude all ports except the CPU and DSA ports */
- for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
- vlan.member[i] = dsa_is_cpu_port(ds, i) ||
- dsa_is_dsa_port(ds, i)
- ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
- : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
-
- if (mv88e6xxx_6097_family(chip) || mv88e6xxx_6165_family(chip) ||
- mv88e6xxx_6351_family(chip) || mv88e6xxx_6352_family(chip) ||
- mv88e6xxx_6341_family(chip)) {
- struct mv88e6xxx_vtu_entry vstp;
-
- /* Adding a VTU entry requires a valid STU entry. As VSTP is not
- * implemented, only one STU entry is needed to cover all VTU
- * entries. Thus, validate the SID 0.
- */
- vlan.sid = 0;
- err = _mv88e6xxx_stu_getnext(chip, GLOBAL_VTU_SID_MASK, &vstp);
- if (err)
- return err;
-
- if (vstp.sid != vlan.sid || !vstp.valid) {
- memset(&vstp, 0, sizeof(vstp));
- vstp.valid = true;
- vstp.sid = vlan.sid;
-
- err = _mv88e6xxx_stu_loadpurge(chip, &vstp);
- if (err)
- return err;
- }
- }
-
- *entry = vlan;
- return 0;
-}
-
-static int _mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
- struct mv88e6xxx_vtu_entry *entry, bool creat)
+static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
+ struct mv88e6xxx_vtu_entry *entry, bool new)
{
int err;
if (!vid)
return -EINVAL;
- err = _mv88e6xxx_vtu_vid_write(chip, vid - 1);
- if (err)
- return err;
+ entry->vid = vid - 1;
+ entry->valid = false;
- err = _mv88e6xxx_vtu_getnext(chip, entry);
+ err = mv88e6xxx_vtu_getnext(chip, entry);
if (err)
return err;
- if (entry->vid != vid || !entry->valid) {
- if (!creat)
- return -EOPNOTSUPP;
- /* -ENOENT would've been more appropriate, but switchdev expects
- * -EOPNOTSUPP to inform bridge about an eventual software VLAN.
- */
+ if (entry->vid == vid && entry->valid)
+ return 0;
+
+ if (new) {
+ int i;
- err = _mv88e6xxx_vtu_new(chip, vid, entry);
+ /* Initialize a fresh VLAN entry */
+ memset(entry, 0, sizeof(*entry));
+ entry->valid = true;
+ entry->vid = vid;
+
+ /* Include only CPU and DSA ports */
+ for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
+ entry->member[i] = dsa_is_normal_port(chip->ds, i) ?
+ GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER :
+ GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED;
+
+ return mv88e6xxx_atu_new(chip, &entry->fid);
}
- return err;
+ /* switchdev expects -EOPNOTSUPP to honor software VLANs */
+ return -EOPNOTSUPP;
}
static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
u16 vid_begin, u16 vid_end)
{
struct mv88e6xxx_chip *chip = ds->priv;
- struct mv88e6xxx_vtu_entry vlan;
+ struct mv88e6xxx_vtu_entry vlan = {
+ .vid = vid_begin - 1,
+ };
int i, err;
if (!vid_begin)
mutex_lock(&chip->reg_lock);
- err = _mv88e6xxx_vtu_vid_write(chip, vid_begin - 1);
- if (err)
- goto unlock;
-
do {
- err = _mv88e6xxx_vtu_getnext(chip, &vlan);
+ err = mv88e6xxx_vtu_getnext(chip, &vlan);
if (err)
goto unlock;
struct mv88e6xxx_vtu_entry vlan;
int err;
- err = _mv88e6xxx_vtu_get(chip, vid, &vlan, true);
+ err = mv88e6xxx_vtu_get(chip, vid, &vlan, true);
if (err)
return err;
GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;
- return _mv88e6xxx_vtu_loadpurge(chip, &vlan);
+ return mv88e6xxx_vtu_loadpurge(chip, &vlan);
}
static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
struct mv88e6xxx_vtu_entry vlan;
int i, err;
- err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
+ err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
if (err)
return err;
}
}
- err = _mv88e6xxx_vtu_loadpurge(chip, &vlan);
+ err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
if (err)
return err;
if (vid == 0)
err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid);
else
- err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
+ err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
if (err)
return err;
return err;
/* Dump VLANs' Filtering Information Databases */
- err = _mv88e6xxx_vtu_vid_write(chip, vlan.vid);
- if (err)
- return err;
-
do {
- err = _mv88e6xxx_vtu_getnext(chip, &vlan);
+ err = mv88e6xxx_vtu_getnext(chip, &vlan);
if (err)
return err;
if (err)
return err;
- /* Clear all the VTU and STU entries */
- err = _mv88e6xxx_vtu_stu_flush(chip);
- if (err < 0)
- return err;
-
/* Configure the IP ToS mapping registers. */
err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_0, 0x0000);
if (err)
goto unlock;
}
+ err = mv88e6xxx_vtu_setup(chip);
+ if (err)
+ goto unlock;
+
err = mv88e6xxx_pvt_setup(chip);
if (err)
goto unlock;
.ppu_enable = mv88e6185_g1_ppu_enable,
.ppu_disable = mv88e6185_g1_ppu_disable,
.reset = mv88e6185_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6095_ops = {
.ppu_enable = mv88e6185_g1_ppu_enable,
.ppu_disable = mv88e6185_g1_ppu_disable,
.reset = mv88e6185_g1_reset,
+ .vtu_getnext = mv88e6185_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6097_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6123_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6131_ops = {
.ppu_enable = mv88e6185_g1_ppu_enable,
.ppu_disable = mv88e6185_g1_ppu_disable,
.reset = mv88e6185_g1_reset,
+ .vtu_getnext = mv88e6185_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6141_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6161_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6165_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6171_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6172_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6175_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6176_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6185_ops = {
.ppu_enable = mv88e6185_g1_ppu_enable,
.ppu_disable = mv88e6185_g1_ppu_disable,
.reset = mv88e6185_g1_reset,
+ .vtu_getnext = mv88e6185_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6190_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6390_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6190x_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6390_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6191_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6390_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6240_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6290_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6390_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6320_ops = {
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6185_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6185_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6341_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6350_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6351_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6352_ops = {
.watchdog_ops = &mv88e6097_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6390_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6390_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_ops mv88e6390x_ops = {
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
+ .vtu_getnext = mv88e6390_g1_vtu_getnext,
+ .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
};
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.name = "Marvell 88E6190",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
+ .max_vid = 8191,
.port_base_addr = 0x0,
.global1_addr = 0x1b,
.tag_protocol = DSA_TAG_PROTO_DSA,
.name = "Marvell 88E6190X",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
+ .max_vid = 8191,
.port_base_addr = 0x0,
.global1_addr = 0x1b,
.age_time_coeff = 3750,
.name = "Marvell 88E6191",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
+ .max_vid = 8191,
.port_base_addr = 0x0,
.global1_addr = 0x1b,
.age_time_coeff = 3750,
.name = "Marvell 88E6290",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
+ .max_vid = 8191,
.port_base_addr = 0x0,
.global1_addr = 0x1b,
.age_time_coeff = 3750,
.name = "Marvell 88E6390",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
+ .max_vid = 8191,
.port_base_addr = 0x0,
.global1_addr = 0x1b,
.age_time_coeff = 3750,
.name = "Marvell 88E6390X",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
+ .max_vid = 8191,
.port_base_addr = 0x0,
.global1_addr = 0x1b,
.age_time_coeff = 3750,