net: dsa: mv88e6xxx: add cap for IRL
Add capability flags to describe the presence of Ingress Rate Limit unit registers and an helper function to clear it. In the meantime, fix a few harmless issues: - 6185 and 6095 don't have such registers (reserved) - the previous code didn't wait for the IRL operation to complete Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9bda889fae
commit
8ec61c7f7c
|
@ -3150,6 +3150,29 @@ static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mv88e6xxx_g2_clear_irl(struct mv88e6xxx_chip *chip)
|
||||||
|
{
|
||||||
|
int port, err;
|
||||||
|
|
||||||
|
/* Init all Ingress Rate Limit resources of all ports */
|
||||||
|
for (port = 0; port < chip->info->num_ports; ++port) {
|
||||||
|
/* XXX newer chips (like 88E6390) have different 2-bit ops */
|
||||||
|
err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_IRL_CMD,
|
||||||
|
GLOBAL2_IRL_CMD_OP_INIT_ALL |
|
||||||
|
(port << 8));
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Wait for the operation to complete */
|
||||||
|
err = _mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_IRL_CMD,
|
||||||
|
GLOBAL2_IRL_CMD_BUSY);
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Indirect write to the Switch MAC/WoL/WoF register */
|
/* Indirect write to the Switch MAC/WoL/WoF register */
|
||||||
static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
|
static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
|
||||||
unsigned int pointer, u8 data)
|
unsigned int pointer, u8 data)
|
||||||
|
@ -3198,7 +3221,6 @@ static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
|
||||||
{
|
{
|
||||||
u16 reg;
|
u16 reg;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
|
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
|
||||||
/* Consider the frames with reserved multicast destination
|
/* Consider the frames with reserved multicast destination
|
||||||
|
@ -3243,6 +3265,15 @@ static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_IRL)) {
|
||||||
|
/* Disable ingress rate limiting by resetting all per port
|
||||||
|
* ingress rate limit resources to their initial state.
|
||||||
|
*/
|
||||||
|
err = mv88e6xxx_g2_clear_irl(chip);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_PVT)) {
|
if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_PVT)) {
|
||||||
/* Initialize Cross-chip Port VLAN Table to reset defaults */
|
/* Initialize Cross-chip Port VLAN Table to reset defaults */
|
||||||
err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_PVT_ADDR,
|
err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_PVT_ADDR,
|
||||||
|
@ -3258,23 +3289,6 @@ static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
|
|
||||||
mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
|
|
||||||
mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip) ||
|
|
||||||
mv88e6xxx_6320_family(chip)) {
|
|
||||||
/* Disable ingress rate limiting by resetting all
|
|
||||||
* ingress rate limit registers to their initial
|
|
||||||
* state.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < chip->info->num_ports; i++) {
|
|
||||||
err = _mv88e6xxx_reg_write(chip, REG_GLOBAL2,
|
|
||||||
GLOBAL2_INGRESS_OP,
|
|
||||||
0x9000 | (i << 8));
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,8 +298,13 @@
|
||||||
#define GLOBAL2_TRUNK_MAPPING 0x08
|
#define GLOBAL2_TRUNK_MAPPING 0x08
|
||||||
#define GLOBAL2_TRUNK_MAPPING_UPDATE BIT(15)
|
#define GLOBAL2_TRUNK_MAPPING_UPDATE BIT(15)
|
||||||
#define GLOBAL2_TRUNK_MAPPING_ID_SHIFT 11
|
#define GLOBAL2_TRUNK_MAPPING_ID_SHIFT 11
|
||||||
#define GLOBAL2_INGRESS_OP 0x09
|
#define GLOBAL2_IRL_CMD 0x09
|
||||||
#define GLOBAL2_INGRESS_DATA 0x0a
|
#define GLOBAL2_IRL_CMD_BUSY BIT(15)
|
||||||
|
#define GLOBAL2_IRL_CMD_OP_INIT_ALL ((0x001 << 12) | GLOBAL2_IRL_CMD_BUSY)
|
||||||
|
#define GLOBAL2_IRL_CMD_OP_INIT_SEL ((0x010 << 12) | GLOBAL2_IRL_CMD_BUSY)
|
||||||
|
#define GLOBAL2_IRL_CMD_OP_WRITE_SEL ((0x011 << 12) | GLOBAL2_IRL_CMD_BUSY)
|
||||||
|
#define GLOBAL2_IRL_CMD_OP_READ_SEL ((0x100 << 12) | GLOBAL2_IRL_CMD_BUSY)
|
||||||
|
#define GLOBAL2_IRL_DATA 0x0a
|
||||||
#define GLOBAL2_PVT_ADDR 0x0b
|
#define GLOBAL2_PVT_ADDR 0x0b
|
||||||
#define GLOBAL2_PVT_ADDR_BUSY BIT(15)
|
#define GLOBAL2_PVT_ADDR_BUSY BIT(15)
|
||||||
#define GLOBAL2_PVT_ADDR_OP_INIT_ONES ((0x01 << 12) | GLOBAL2_PVT_ADDR_BUSY)
|
#define GLOBAL2_PVT_ADDR_OP_INIT_ONES ((0x01 << 12) | GLOBAL2_PVT_ADDR_BUSY)
|
||||||
|
@ -393,6 +398,8 @@ enum mv88e6xxx_cap {
|
||||||
MV88E6XXX_CAP_GLOBAL2,
|
MV88E6XXX_CAP_GLOBAL2,
|
||||||
MV88E6XXX_CAP_G2_MGMT_EN_2X, /* (0x02) MGMT Enable Register 2x */
|
MV88E6XXX_CAP_G2_MGMT_EN_2X, /* (0x02) MGMT Enable Register 2x */
|
||||||
MV88E6XXX_CAP_G2_MGMT_EN_0X, /* (0x03) MGMT Enable Register 0x */
|
MV88E6XXX_CAP_G2_MGMT_EN_0X, /* (0x03) MGMT Enable Register 0x */
|
||||||
|
MV88E6XXX_CAP_G2_IRL_CMD, /* (0x09) Ingress Rate Command */
|
||||||
|
MV88E6XXX_CAP_G2_IRL_DATA, /* (0x0a) Ingress Rate Data */
|
||||||
MV88E6XXX_CAP_G2_PVT_ADDR, /* (0x0b) Cross Chip Port VLAN Addr */
|
MV88E6XXX_CAP_G2_PVT_ADDR, /* (0x0b) Cross Chip Port VLAN Addr */
|
||||||
MV88E6XXX_CAP_G2_PVT_DATA, /* (0x0c) Cross Chip Port VLAN Data */
|
MV88E6XXX_CAP_G2_PVT_DATA, /* (0x0c) Cross Chip Port VLAN Data */
|
||||||
MV88E6XXX_CAP_G2_SWITCH_MAC, /* (0x0d) Switch MAC/WoL/WoF */
|
MV88E6XXX_CAP_G2_SWITCH_MAC, /* (0x0d) Switch MAC/WoL/WoF */
|
||||||
|
@ -440,6 +447,8 @@ enum mv88e6xxx_cap {
|
||||||
#define MV88E6XXX_FLAG_GLOBAL2 BIT(MV88E6XXX_CAP_GLOBAL2)
|
#define MV88E6XXX_FLAG_GLOBAL2 BIT(MV88E6XXX_CAP_GLOBAL2)
|
||||||
#define MV88E6XXX_FLAG_G2_MGMT_EN_2X BIT(MV88E6XXX_CAP_G2_MGMT_EN_2X)
|
#define MV88E6XXX_FLAG_G2_MGMT_EN_2X BIT(MV88E6XXX_CAP_G2_MGMT_EN_2X)
|
||||||
#define MV88E6XXX_FLAG_G2_MGMT_EN_0X BIT(MV88E6XXX_CAP_G2_MGMT_EN_0X)
|
#define MV88E6XXX_FLAG_G2_MGMT_EN_0X BIT(MV88E6XXX_CAP_G2_MGMT_EN_0X)
|
||||||
|
#define MV88E6XXX_FLAG_G2_IRL_CMD BIT(MV88E6XXX_CAP_G2_IRL_CMD)
|
||||||
|
#define MV88E6XXX_FLAG_G2_IRL_DATA BIT(MV88E6XXX_CAP_G2_IRL_DATA)
|
||||||
#define MV88E6XXX_FLAG_G2_PVT_ADDR BIT(MV88E6XXX_CAP_G2_PVT_ADDR)
|
#define MV88E6XXX_FLAG_G2_PVT_ADDR BIT(MV88E6XXX_CAP_G2_PVT_ADDR)
|
||||||
#define MV88E6XXX_FLAG_G2_PVT_DATA BIT(MV88E6XXX_CAP_G2_PVT_DATA)
|
#define MV88E6XXX_FLAG_G2_PVT_DATA BIT(MV88E6XXX_CAP_G2_PVT_DATA)
|
||||||
#define MV88E6XXX_FLAG_G2_SWITCH_MAC BIT(MV88E6XXX_CAP_G2_SWITCH_MAC)
|
#define MV88E6XXX_FLAG_G2_SWITCH_MAC BIT(MV88E6XXX_CAP_G2_SWITCH_MAC)
|
||||||
|
@ -453,6 +462,11 @@ enum mv88e6xxx_cap {
|
||||||
#define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT)
|
#define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT)
|
||||||
#define MV88E6XXX_FLAG_VTU BIT(MV88E6XXX_CAP_VTU)
|
#define MV88E6XXX_FLAG_VTU BIT(MV88E6XXX_CAP_VTU)
|
||||||
|
|
||||||
|
/* Ingress Rate Limit unit */
|
||||||
|
#define MV88E6XXX_FLAGS_IRL \
|
||||||
|
(MV88E6XXX_FLAG_G2_IRL_CMD | \
|
||||||
|
MV88E6XXX_FLAG_G2_IRL_DATA)
|
||||||
|
|
||||||
/* Cross-chip Port VLAN Table */
|
/* Cross-chip Port VLAN Table */
|
||||||
#define MV88E6XXX_FLAGS_PVT \
|
#define MV88E6XXX_FLAGS_PVT \
|
||||||
(MV88E6XXX_FLAG_G2_PVT_ADDR | \
|
(MV88E6XXX_FLAG_G2_PVT_ADDR | \
|
||||||
|
@ -474,6 +488,7 @@ enum mv88e6xxx_cap {
|
||||||
MV88E6XXX_FLAG_PPU | \
|
MV88E6XXX_FLAG_PPU | \
|
||||||
MV88E6XXX_FLAG_STU | \
|
MV88E6XXX_FLAG_STU | \
|
||||||
MV88E6XXX_FLAG_VTU | \
|
MV88E6XXX_FLAG_VTU | \
|
||||||
|
MV88E6XXX_FLAGS_IRL | \
|
||||||
MV88E6XXX_FLAGS_PVT)
|
MV88E6XXX_FLAGS_PVT)
|
||||||
|
|
||||||
#define MV88E6XXX_FLAGS_FAMILY_6165 \
|
#define MV88E6XXX_FLAGS_FAMILY_6165 \
|
||||||
|
@ -486,6 +501,7 @@ enum mv88e6xxx_cap {
|
||||||
MV88E6XXX_FLAG_STU | \
|
MV88E6XXX_FLAG_STU | \
|
||||||
MV88E6XXX_FLAG_TEMP | \
|
MV88E6XXX_FLAG_TEMP | \
|
||||||
MV88E6XXX_FLAG_VTU | \
|
MV88E6XXX_FLAG_VTU | \
|
||||||
|
MV88E6XXX_FLAGS_IRL | \
|
||||||
MV88E6XXX_FLAGS_PVT)
|
MV88E6XXX_FLAGS_PVT)
|
||||||
|
|
||||||
#define MV88E6XXX_FLAGS_FAMILY_6185 \
|
#define MV88E6XXX_FLAGS_FAMILY_6185 \
|
||||||
|
@ -509,6 +525,7 @@ enum mv88e6xxx_cap {
|
||||||
MV88E6XXX_FLAG_TEMP | \
|
MV88E6XXX_FLAG_TEMP | \
|
||||||
MV88E6XXX_FLAG_TEMP_LIMIT | \
|
MV88E6XXX_FLAG_TEMP_LIMIT | \
|
||||||
MV88E6XXX_FLAG_VTU | \
|
MV88E6XXX_FLAG_VTU | \
|
||||||
|
MV88E6XXX_FLAGS_IRL | \
|
||||||
MV88E6XXX_FLAGS_PVT)
|
MV88E6XXX_FLAGS_PVT)
|
||||||
|
|
||||||
#define MV88E6XXX_FLAGS_FAMILY_6351 \
|
#define MV88E6XXX_FLAGS_FAMILY_6351 \
|
||||||
|
@ -523,6 +540,7 @@ enum mv88e6xxx_cap {
|
||||||
MV88E6XXX_FLAG_STU | \
|
MV88E6XXX_FLAG_STU | \
|
||||||
MV88E6XXX_FLAG_TEMP | \
|
MV88E6XXX_FLAG_TEMP | \
|
||||||
MV88E6XXX_FLAG_VTU | \
|
MV88E6XXX_FLAG_VTU | \
|
||||||
|
MV88E6XXX_FLAGS_IRL | \
|
||||||
MV88E6XXX_FLAGS_PVT)
|
MV88E6XXX_FLAGS_PVT)
|
||||||
|
|
||||||
#define MV88E6XXX_FLAGS_FAMILY_6352 \
|
#define MV88E6XXX_FLAGS_FAMILY_6352 \
|
||||||
|
@ -540,6 +558,7 @@ enum mv88e6xxx_cap {
|
||||||
MV88E6XXX_FLAG_TEMP | \
|
MV88E6XXX_FLAG_TEMP | \
|
||||||
MV88E6XXX_FLAG_TEMP_LIMIT | \
|
MV88E6XXX_FLAG_TEMP_LIMIT | \
|
||||||
MV88E6XXX_FLAG_VTU | \
|
MV88E6XXX_FLAG_VTU | \
|
||||||
|
MV88E6XXX_FLAGS_IRL | \
|
||||||
MV88E6XXX_FLAGS_PVT)
|
MV88E6XXX_FLAGS_PVT)
|
||||||
|
|
||||||
struct mv88e6xxx_info {
|
struct mv88e6xxx_info {
|
||||||
|
|
Loading…
Reference in New Issue