/* Insert MemberTag and PortState data */ for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { unsignedint member_offset = (i % 4) * 4; unsignedint state_offset = member_offset + 2;
/* Insert data */ for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { unsignedint offset = (i % 8) * 2;
regs[i / 8] |= (data[i] & 0x3) << offset;
}
/* Write the 2 VTU/STU Data registers */ for (i = 0; i < 2; ++i) {
u16 reg = regs[i]; int err;
err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_VTU_DATA1 + i, reg); if (err) return err;
}
return 0;
}
/* VLAN Translation Unit Operations */
int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry)
{ int err;
err = mv88e6xxx_g1_vtu_op_wait(chip); if (err) return err;
/* To get the next higher active VID, the VTU GetNext operation can be * started again without setting the VID registers since it already * contains the last VID. * * To save a few hardware accesses and abstract this to the caller, * write the VID only once, when the entry is given as invalid.
*/ if (!entry->valid) {
err = mv88e6xxx_g1_vtu_vid_write(chip, false, entry->vid); if (err) return err;
}
err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT); if (err) return err;
int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry)
{
u16 val; int err;
err = mv88e6xxx_g1_vtu_getnext(chip, entry); if (err) return err;
if (entry->valid) {
err = mv88e6185_g1_vtu_data_read(chip, entry->member, entry->state); if (err) return err;
/* VTU DBNum[3:0] are located in VTU Operation 3:0 * VTU DBNum[7:4] ([5:4] for 6250) are located in VTU Operation 11:8 (9:8)
*/
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP, &val); if (err) return err;
int mv88e6352_g1_vtu_getnext(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry)
{ int err;
/* Fetch VLAN MemberTag data from the VTU */
err = mv88e6xxx_g1_vtu_getnext(chip, entry); if (err) return err;
if (entry->valid) {
err = mv88e6185_g1_vtu_data_read(chip, entry->member, NULL); if (err) return err;
err = mv88e6xxx_g1_vtu_fid_read(chip, entry); if (err) return err;
err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid); if (err) return err;
}
return 0;
}
int mv88e6390_g1_vtu_getnext(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry)
{ int err;
/* Fetch VLAN MemberTag data from the VTU */
err = mv88e6xxx_g1_vtu_getnext(chip, entry); if (err) return err;
if (entry->valid) {
err = mv88e6390_g1_vtu_data_read(chip, entry->member); if (err) return err;
err = mv88e6xxx_g1_vtu_fid_read(chip, entry); if (err) return err;
err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid); if (err) return err;
}
return 0;
}
int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry)
{
u16 op = MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE; int err;
err = mv88e6xxx_g1_vtu_op_wait(chip); if (err) return err;
err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid); if (err) return err;
if (entry->valid) {
err = mv88e6185_g1_vtu_data_write(chip, entry->member, entry->state); if (err) return err;
/* VTU DBNum[3:0] are located in VTU Operation 3:0 * VTU DBNum[7:4] are located in VTU Operation 11:8 * * For the 6250/6220, the latter are really [5:4] and * 9:8, but in those cases bits 7:6 of entry->fid are * 0 since they have num_databases = 64.
*/
op |= entry->fid & 0x000f;
op |= (entry->fid & 0x00f0) << 4;
}
return mv88e6xxx_g1_vtu_op(chip, op);
}
int mv88e6352_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry)
{ int err;
err = mv88e6xxx_g1_vtu_op_wait(chip); if (err) return err;
err = mv88e6xxx_g1_vtu_vid_write(chip, entry->valid, entry->vid); if (err) return err;
if (entry->valid) { /* Write MemberTag data */
err = mv88e6185_g1_vtu_data_write(chip, entry->member, NULL); if (err) return err;
err = mv88e6xxx_g1_vtu_fid_write(chip, entry); if (err) return err;
err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid); if (err) return err;
}
int mv88e6xxx_g1_stu_getnext(struct mv88e6xxx_chip *chip, struct mv88e6xxx_stu_entry *entry)
{ int err;
err = mv88e6xxx_g1_vtu_op_wait(chip); if (err) return err;
/* To get the next higher active SID, the STU GetNext operation can be * started again without setting the SID registers since it already * contains the last SID. * * To save a few hardware accesses and abstract this to the caller, * write the SID only once, when the entry is given as invalid.
*/ if (!entry->valid) {
err = mv88e6xxx_g1_vtu_sid_write(chip, entry->sid); if (err) return err;
}
err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_STU_GET_NEXT); if (err) return err;
err = mv88e6xxx_g1_vtu_vid_read(chip, &entry->valid, NULL); if (err) return err;
if (entry->valid) {
err = mv88e6xxx_g1_vtu_sid_read(chip, &entry->sid); if (err) return err;
}
return 0;
}
int mv88e6352_g1_stu_getnext(struct mv88e6xxx_chip *chip, struct mv88e6xxx_stu_entry *entry)
{ int err;
err = mv88e6xxx_g1_stu_getnext(chip, entry); if (err) return err;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.