From 891daf49b0f6e900af6bde51e2dc2cbc72b83f4e Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Mon, 30 Jan 2017 20:29:33 +0100 Subject: [PATCH 1/3] net: dsa: mv88e6xxx: Don't forbid MDIO I/Os for PHY addr >= num_of_ports Some Marvell ethernet switches have internal ethernet transceivers with hardcoded phy addresses. These addresses can be greater than the number of ports or its value might be different than the associated port number. This is for example the case for MV88E6341 that has 6 ports and internal Port 1 to Port4 PHYs mapped at SMI addresses from 0x11 to 0x14. This commits fixes the issue by removing the condition in MDIO callbacks. Signed-off-by: Romain Perier Reviewed-by: Andrew Lunn Reviewed-by: Vivien Didelot Signed-off-by: Gregory CLEMENT Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 84cba32443de..1344dad21f46 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2917,9 +2917,6 @@ static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg) u16 val; int err; - if (phy >= mv88e6xxx_num_ports(chip)) - return 0xffff; - if (!chip->info->ops->phy_read) return -EOPNOTSUPP; @@ -2936,9 +2933,6 @@ static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) struct mv88e6xxx_chip *chip = mdio_bus->chip; int err; - if (phy >= mv88e6xxx_num_ports(chip)) - return 0xffff; - if (!chip->info->ops->phy_write) return -EOPNOTSUPP; From a75961d0ebfd8866e03855bfdbb5733a268b0a44 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 30 Jan 2017 20:29:34 +0100 Subject: [PATCH 2/3] net: dsa: mv88e6xxx: Add support for ethernet switch 88E6341 The Marvell 88E6341 device is single-chip, 6-port Ethernet switch with four integrated 10/100/1000Mbps Ethernet transceivers and one high speed SerDes interfaces. It is partially compatible with switches of family 88E6352 and switches of family 88E6390. This commit adds an initial support for this switch by describing its capabilities to the driver and introducing a new family. Signed-off-by: Gregory CLEMENT Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 54 +++++++++++++++++++++++++-- drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 19 +++++++++- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 1344dad21f46..6a583527917d 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -702,6 +702,11 @@ static bool mv88e6xxx_6320_family(struct mv88e6xxx_chip *chip) return chip->info->family == MV88E6XXX_FAMILY_6320; } +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; @@ -1726,7 +1731,8 @@ static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid, : 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_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 @@ -2577,7 +2583,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) || mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) || mv88e6xxx_6095_family(chip) || mv88e6xxx_6320_family(chip) || - mv88e6xxx_6185_family(chip)) + mv88e6xxx_6185_family(chip) || mv88e6xxx_6341_family(chip)) reg = PORT_CONTROL_2_MAP_DA; if (mv88e6xxx_6095_family(chip) || mv88e6xxx_6185_family(chip)) { @@ -2631,7 +2637,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) || mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) || - mv88e6xxx_6320_family(chip)) { + mv88e6xxx_6320_family(chip) || mv88e6xxx_6341_family(chip)) { /* Port ATU control: disable limiting the number of * address database entries that this port is allowed * to use. @@ -3650,6 +3656,34 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .reset = mv88e6352_g1_reset, }; +static const struct mv88e6xxx_ops mv88e6341_ops = { + /* MV88E6XXX_FAMILY_6341 */ + .get_eeprom = mv88e6xxx_g2_get_eeprom8, + .set_eeprom = mv88e6xxx_g2_set_eeprom8, + .set_switch_mac = mv88e6xxx_g2_set_switch_mac, + .phy_read = mv88e6xxx_g2_smi_phy_read, + .phy_write = mv88e6xxx_g2_smi_phy_write, + .port_set_link = mv88e6xxx_port_set_link, + .port_set_duplex = mv88e6xxx_port_set_duplex, + .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, + .port_set_speed = mv88e6390_port_set_speed, + .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_frame_mode = mv88e6351_port_set_frame_mode, + .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns, + .port_set_ether_type = mv88e6351_port_set_ether_type, + .port_jumbo_config = mv88e6165_port_jumbo_config, + .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, + .port_pause_config = mv88e6097_port_pause_config, + .stats_snapshot = mv88e6390_g1_stats_snapshot, + .stats_get_sset_count = mv88e6320_stats_get_sset_count, + .stats_get_strings = mv88e6320_stats_get_strings, + .stats_get_stats = mv88e6390_stats_get_stats, + .g1_set_cpu_port = mv88e6390_g1_set_cpu_port, + .g1_set_egress_port = mv88e6390_g1_set_egress_port, + .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, + .reset = mv88e6352_g1_reset, +}; + static const struct mv88e6xxx_ops mv88e6390_ops = { /* MV88E6XXX_FAMILY_6390 */ .get_eeprom = mv88e6xxx_g2_get_eeprom8, @@ -4037,6 +4071,20 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .ops = &mv88e6321_ops, }, + [MV88E6341] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6341, + .family = MV88E6XXX_FAMILY_6341, + .name = "Marvell 88E6341", + .num_databases = 4096, + .num_ports = 6, + .port_base_addr = 0x10, + .global1_addr = 0x1b, + .age_time_coeff = 3750, + .tag_protocol = DSA_TAG_PROTO_EDSA, + .flags = MV88E6XXX_FLAGS_FAMILY_6341, + .ops = &mv88e6341_ops, + }, + [MV88E6350] = { .prod_num = PORT_SWITCH_ID_PROD_NUM_6350, .family = MV88E6XXX_FAMILY_6351, diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h index e126ed00937b..76837d2022bb 100644 --- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h @@ -100,6 +100,7 @@ #define PORT_SWITCH_ID_PROD_NUM_6240 0x240 #define PORT_SWITCH_ID_PROD_NUM_6290 0x290 #define PORT_SWITCH_ID_PROD_NUM_6321 0x310 +#define PORT_SWITCH_ID_PROD_NUM_6341 0x341 #define PORT_SWITCH_ID_PROD_NUM_6352 0x352 #define PORT_SWITCH_ID_PROD_NUM_6350 0x371 #define PORT_SWITCH_ID_PROD_NUM_6351 0x375 @@ -382,7 +383,7 @@ #define GLOBAL2_EEPROM_CMD_WRITE_EN BIT(10) #define GLOBAL2_EEPROM_CMD_ADDR_MASK 0xff #define GLOBAL2_EEPROM_DATA 0x15 -#define GLOBAL2_EEPROM_ADDR 0x15 /* 6390 */ +#define GLOBAL2_EEPROM_ADDR 0x15 /* 6390, 6341 */ #define GLOBAL2_PTP_AVB_OP 0x16 #define GLOBAL2_PTP_AVB_DATA 0x17 #define GLOBAL2_SMI_PHY_CMD 0x18 @@ -434,6 +435,7 @@ enum mv88e6xxx_model { MV88E6290, MV88E6320, MV88E6321, + MV88E6341, MV88E6350, MV88E6351, MV88E6352, @@ -449,6 +451,7 @@ enum mv88e6xxx_family { MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */ MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */ MV88E6XXX_FAMILY_6320, /* 6320 6321 */ + MV88E6XXX_FAMILY_6341, /* 6141 6341 */ MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */ MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */ @@ -602,6 +605,20 @@ enum mv88e6xxx_cap { MV88E6XXX_FLAGS_MULTI_CHIP | \ MV88E6XXX_FLAGS_PVT) +#define MV88E6XXX_FLAGS_FAMILY_6341 \ + (MV88E6XXX_FLAG_EEE | \ + MV88E6XXX_FLAG_G1_ATU_FID | \ + MV88E6XXX_FLAG_G1_VTU_FID | \ + MV88E6XXX_FLAG_GLOBAL2 | \ + MV88E6XXX_FLAG_G2_INT | \ + MV88E6XXX_FLAG_G2_POT | \ + MV88E6XXX_FLAG_STU | \ + MV88E6XXX_FLAG_VTU | \ + MV88E6XXX_FLAGS_IRL | \ + MV88E6XXX_FLAGS_MULTI_CHIP | \ + MV88E6XXX_FLAGS_PVT | \ + MV88E6XXX_FLAGS_SERDES) + #define MV88E6XXX_FLAGS_FAMILY_6351 \ (MV88E6XXX_FLAG_G1_ATU_FID | \ MV88E6XXX_FLAG_G1_VTU_FID | \ From 1558727a1c1b65459cb9ae31f36ace45d56c6767 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 30 Jan 2017 20:29:35 +0100 Subject: [PATCH 3/3] net: dsa: mv88e6xxx: Add support for ethernet switch 88E6141 The Marvell 88E6341 device is single-chip, 6-port Ethernet switch with four integrated 10/100/1000Mbps Ethernet transceivers and one high speed SerDes interfaces. It belongs to the Topaz family and unlike the 88E6341 it does not have a TCAM. Signed-off-by: Gregory CLEMENT Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 42 +++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 2 ++ 2 files changed, 44 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 6a583527917d..bf385377a461 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3656,6 +3656,34 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .reset = mv88e6352_g1_reset, }; +static const struct mv88e6xxx_ops mv88e6141_ops = { + /* MV88E6XXX_FAMILY_6341 */ + .get_eeprom = mv88e6xxx_g2_get_eeprom8, + .set_eeprom = mv88e6xxx_g2_set_eeprom8, + .set_switch_mac = mv88e6xxx_g2_set_switch_mac, + .phy_read = mv88e6xxx_g2_smi_phy_read, + .phy_write = mv88e6xxx_g2_smi_phy_write, + .port_set_link = mv88e6xxx_port_set_link, + .port_set_duplex = mv88e6xxx_port_set_duplex, + .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, + .port_set_speed = mv88e6390_port_set_speed, + .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_frame_mode = mv88e6351_port_set_frame_mode, + .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns, + .port_set_ether_type = mv88e6351_port_set_ether_type, + .port_jumbo_config = mv88e6165_port_jumbo_config, + .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, + .port_pause_config = mv88e6097_port_pause_config, + .stats_snapshot = mv88e6390_g1_stats_snapshot, + .stats_get_sset_count = mv88e6320_stats_get_sset_count, + .stats_get_strings = mv88e6320_stats_get_strings, + .stats_get_stats = mv88e6390_stats_get_stats, + .g1_set_cpu_port = mv88e6390_g1_set_cpu_port, + .g1_set_egress_port = mv88e6390_g1_set_egress_port, + .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, + .reset = mv88e6352_g1_reset, +}; + static const struct mv88e6xxx_ops mv88e6341_ops = { /* MV88E6XXX_FAMILY_6341 */ .get_eeprom = mv88e6xxx_g2_get_eeprom8, @@ -4071,6 +4099,20 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .ops = &mv88e6321_ops, }, + [MV88E6141] = { + .prod_num = PORT_SWITCH_ID_PROD_NUM_6141, + .family = MV88E6XXX_FAMILY_6341, + .name = "Marvell 88E6341", + .num_databases = 4096, + .num_ports = 6, + .port_base_addr = 0x10, + .global1_addr = 0x1b, + .age_time_coeff = 3750, + .tag_protocol = DSA_TAG_PROTO_EDSA, + .flags = MV88E6XXX_FLAGS_FAMILY_6341, + .ops = &mv88e6141_ops, + }, + [MV88E6341] = { .prod_num = PORT_SWITCH_ID_PROD_NUM_6341, .family = MV88E6XXX_FAMILY_6341, diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h index 76837d2022bb..9c5c0472b211 100644 --- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h @@ -87,6 +87,7 @@ #define PORT_SWITCH_ID_PROD_NUM_6131 0x106 #define PORT_SWITCH_ID_PROD_NUM_6320 0x115 #define PORT_SWITCH_ID_PROD_NUM_6123 0x121 +#define PORT_SWITCH_ID_PROD_NUM_6141 0x340 #define PORT_SWITCH_ID_PROD_NUM_6161 0x161 #define PORT_SWITCH_ID_PROD_NUM_6165 0x165 #define PORT_SWITCH_ID_PROD_NUM_6171 0x171 @@ -421,6 +422,7 @@ enum mv88e6xxx_model { MV88E6097, MV88E6123, MV88E6131, + MV88E6141, MV88E6161, MV88E6165, MV88E6171,