From 3177d7bbe0f256d6f6841c54fb65eaea2f3e26c1 Mon Sep 17 00:00:00 2001 From: Xin Gao Date: Wed, 17 Aug 2022 09:35:29 +0800 Subject: [PATCH 01/18] core: Variable type completion 'unsigned int' is better than 'unsigned'. Signed-off-by: Xin Gao Signed-off-by: David S. Miller --- net/core/netclassid_cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c index 1a6a86693b745..d6a70aeaa5037 100644 --- a/net/core/netclassid_cgroup.c +++ b/net/core/netclassid_cgroup.c @@ -66,7 +66,7 @@ struct update_classid_context { #define UPDATE_CLASSID_BATCH 1000 -static int update_classid_sock(const void *v, struct file *file, unsigned n) +static int update_classid_sock(const void *v, struct file *file, unsigned int n) { struct update_classid_context *ctx = (void *)v; struct socket *sock = sock_from_file(file); From b449080956127410dbc94ba7497de066d68c7573 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:18 +0200 Subject: [PATCH 02/18] net: dsa: microchip: add separate struct ksz_chip_data for KSZ8563 chip Add separate entry for the KSZ8563 chip. According to the documentation it can support Gbit only on RGMII port. So, we will need to be able to describe in the followup patch. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz_common.c | 39 ++++++++++++++++++++++++-- drivers/net/dsa/microchip/ksz_common.h | 6 ++++ drivers/net/dsa/microchip/ksz_spi.c | 2 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 6bd69a7e6809d..5cadc831c75d5 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -413,6 +413,29 @@ static const u8 lan937x_shifts[] = { }; const struct ksz_chip_data ksz_switch_chips[] = { + [KSZ8563] = { + .chip_id = KSZ8563_CHIP_ID, + .dev_name = "KSZ8563", + .num_vlans = 4096, + .num_alus = 4096, + .num_statics = 16, + .cpu_ports = 0x07, /* can be configured as cpu port */ + .port_cnt = 3, /* total port count */ + .ops = &ksz9477_dev_ops, + .mib_names = ksz9477_mib_names, + .mib_cnt = ARRAY_SIZE(ksz9477_mib_names), + .reg_mib_cnt = MIB_COUNTER_NUM, + .regs = ksz9477_regs, + .masks = ksz9477_masks, + .shifts = ksz9477_shifts, + .xmii_ctrl0 = ksz9477_xmii_ctrl0, + .xmii_ctrl1 = ksz8795_xmii_ctrl1, /* Same as ksz8795 */ + .supports_mii = {false, false, true}, + .supports_rmii = {false, false, true}, + .supports_rgmii = {false, false, true}, + .internal_phy = {true, true, false}, + }, + [KSZ8795] = { .chip_id = KSZ8795_CHIP_ID, .dev_name = "KSZ8795", @@ -1366,6 +1389,7 @@ static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, proto = DSA_TAG_PROTO_KSZ8795; if (dev->chip_id == KSZ8830_CHIP_ID || + dev->chip_id == KSZ8563_CHIP_ID || dev->chip_id == KSZ9893_CHIP_ID) proto = DSA_TAG_PROTO_KSZ9893; @@ -1685,7 +1709,7 @@ static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port, static int ksz_switch_detect(struct ksz_device *dev) { - u8 id1, id2; + u8 id1, id2, id4; u16 id16; u32 id32; int ret; @@ -1731,7 +1755,6 @@ static int ksz_switch_detect(struct ksz_device *dev) switch (id32) { case KSZ9477_CHIP_ID: case KSZ9897_CHIP_ID: - case KSZ9893_CHIP_ID: case KSZ9567_CHIP_ID: case LAN9370_CHIP_ID: case LAN9371_CHIP_ID: @@ -1739,6 +1762,18 @@ static int ksz_switch_detect(struct ksz_device *dev) case LAN9373_CHIP_ID: case LAN9374_CHIP_ID: dev->chip_id = id32; + break; + case KSZ9893_CHIP_ID: + ret = ksz_read8(dev, REG_CHIP_ID4, + &id4); + if (ret) + return ret; + + if (id4 == SKU_ID_KSZ8563) + dev->chip_id = KSZ8563_CHIP_ID; + else + dev->chip_id = KSZ9893_CHIP_ID; + break; default: dev_err(dev->dev, diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 0d9520dc6d2db..eedcbcddd000c 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -124,6 +124,7 @@ struct ksz_device { /* List of supported models */ enum ksz_model { + KSZ8563, KSZ8795, KSZ8794, KSZ8765, @@ -140,6 +141,7 @@ enum ksz_model { }; enum ksz_chip_id { + KSZ8563_CHIP_ID = 0x8563, KSZ8795_CHIP_ID = 0x8795, KSZ8794_CHIP_ID = 0x8794, KSZ8765_CHIP_ID = 0x8765, @@ -483,6 +485,10 @@ static inline int is_lan937x(struct ksz_device *dev) #define SW_REV_ID_M GENMASK(7, 4) +/* KSZ9893, KSZ9563, KSZ8563 specific register */ +#define REG_CHIP_ID4 0x0f +#define SKU_ID_KSZ8563 0x3c + /* Driver set switch broadcast storm protection at 10% rate. */ #define BROADCAST_STORM_PROT_RATE 10 diff --git a/drivers/net/dsa/microchip/ksz_spi.c b/drivers/net/dsa/microchip/ksz_spi.c index 05bd089795f83..746b725b09ec4 100644 --- a/drivers/net/dsa/microchip/ksz_spi.c +++ b/drivers/net/dsa/microchip/ksz_spi.c @@ -160,7 +160,7 @@ static const struct of_device_id ksz_dt_ids[] = { }, { .compatible = "microchip,ksz8563", - .data = &ksz_switch_chips[KSZ9893] + .data = &ksz_switch_chips[KSZ8563] }, { .compatible = "microchip,ksz9567", From 505bf3205aaa3d736aa432ff62bd532882cec32e Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:19 +0200 Subject: [PATCH 03/18] net: dsa: microchip: do per-port Gbit detection instead of per-chip KSZ8563 has two 100Mbit PHYs and CPU port with RGMII support. Since 1000Mbit configuration for the RGMII capable MAC is present, we should use per port validation. As main part of migration to per-port validation we need to rework ksz9477_switch_init() function. Which is using undocumented REG_GLOBAL_OPTIONS register to detect per-chip Gbit support. So, it is related to some sort of risk for regressions. To reduce this risk I compared the code with publicly available documentations. This function will executed on following currently supported chips: struct ksz_chip_data OF compatible KSZ9477 KSZ9477 KSZ9897 KSZ9897 KSZ9893 KSZ9893, KSZ9563 KSZ8563 KSZ8563 KSZ9567 KSZ9567 Only KSZ9893, KSZ9563, KSZ8563 document existence of 0xf == REG_GLOBAL_OPTIONS register with bit field description "SKU ID": KSZ9893 0x0C KSZ9563 0x1C KSZ8563 0x3C The existence of hidden flags is not documented. KSZ9477, KSZ9897, KSZ9567 do not document this register at all. Only KSZ8563 is documented as non Gbit chip: 100Mbit PHYs and RGMII CPU port. So, this change should not introduce a regression for configurations with properly used OF compatibles. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 20 +++----------------- drivers/net/dsa/microchip/ksz_common.c | 5 +++++ drivers/net/dsa/microchip/ksz_common.h | 2 +- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index e4f446db0ca18..0f7f44358d7b3 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -320,7 +320,7 @@ void ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) return; /* No gigabit support. Do not write to this register. */ - if (!(dev->features & GBIT_SUPPORT) && reg == MII_CTRL1000) + if (!dev->info->gbit_capable[addr] && reg == MII_CTRL1000) return; ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); @@ -914,7 +914,7 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port) /* Energy Efficient Ethernet (EEE) feature select must * be manually disabled (except on KSZ8565 which is 100Mbit) */ - if (dev->features & GBIT_SUPPORT) + if (dev->info->gbit_capable[port]) ksz9477_port_mmd_write(dev, port, 0x07, 0x3c, 0x0000); /* Register settings are required to meet data sheet @@ -941,7 +941,7 @@ void ksz9477_get_caps(struct ksz_device *dev, int port, config->mac_capabilities = MAC_10 | MAC_100 | MAC_ASYM_PAUSE | MAC_SYM_PAUSE; - if (dev->features & GBIT_SUPPORT) + if (dev->info->gbit_capable[port]) config->mac_capabilities |= MAC_1000FD; } @@ -1158,27 +1158,13 @@ int ksz9477_switch_init(struct ksz_device *dev) if (ret) return ret; - ret = ksz_read8(dev, REG_GLOBAL_OPTIONS, &data8); - if (ret) - return ret; - /* Number of ports can be reduced depending on chip. */ dev->phy_port_cnt = 5; - /* Default capability is gigabit capable. */ - dev->features = GBIT_SUPPORT; - if (dev->chip_id == KSZ9893_CHIP_ID) { dev->features |= IS_9893; - /* Chip does not support gigabit. */ - if (data8 & SW_QW_ABLE) - dev->features &= ~GBIT_SUPPORT; dev->phy_port_cnt = 2; - } else { - /* Chip does not support gigabit. */ - if (!(data8 & SW_GIGABIT_ABLE)) - dev->features &= ~GBIT_SUPPORT; } return 0; diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 5cadc831c75d5..7b6d7efc0a002 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -434,6 +434,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .supports_rmii = {false, false, true}, .supports_rgmii = {false, false, true}, .internal_phy = {true, true, false}, + .gbit_capable = {false, false, true}, }, [KSZ8795] = { @@ -568,6 +569,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { false, true, false}, .internal_phy = {true, true, true, true, true, false, false}, + .gbit_capable = {true, true, true, true, true, true, true}, }, [KSZ9897] = { @@ -596,6 +598,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { false, true, true}, .internal_phy = {true, true, true, true, true, false, false}, + .gbit_capable = {true, true, true, true, true, true, true}, }, [KSZ9893] = { @@ -619,6 +622,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .supports_rmii = {false, false, true}, .supports_rgmii = {false, false, true}, .internal_phy = {true, true, false}, + .gbit_capable = {true, true, true}, }, [KSZ9567] = { @@ -647,6 +651,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { false, true, true}, .internal_phy = {true, true, true, true, true, false, false}, + .gbit_capable = {true, true, true, true, true, true, true}, }, [LAN9370] = { diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index eedcbcddd000c..e3e120d659410 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -61,6 +61,7 @@ struct ksz_chip_data { bool supports_rmii[KSZ_MAX_NUM_PORTS]; bool supports_rgmii[KSZ_MAX_NUM_PORTS]; bool internal_phy[KSZ_MAX_NUM_PORTS]; + bool gbit_capable[KSZ_MAX_NUM_PORTS]; }; struct ksz_port { @@ -504,7 +505,6 @@ static inline int is_lan937x(struct ksz_device *dev) #define SW_START 0x01 /* Used with variable features to indicate capabilities. */ -#define GBIT_SUPPORT BIT(0) #define IS_9893 BIT(2) /* xMII configuration */ From d7539fc2b41a126d596d1e5777e0697a4acc692c Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:20 +0200 Subject: [PATCH 04/18] net: dsa: microchip: don't announce extended register support on non Gbit chips This issue was detected after adding support of regmap_ranges for KSZ8563R chip. This chip is reporting extended registers support without having actual extended registers. This made PHYlib request not existing registers. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 0f7f44358d7b3..2b3bf1d3950c2 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -264,6 +264,16 @@ void ksz9477_port_init_cnt(struct ksz_device *dev, int port) mutex_unlock(&mib->cnt_mutex); } +static void ksz9477_r_phy_quirks(struct ksz_device *dev, u16 addr, u16 reg, + u16 *data) +{ + /* KSZ8563R do not have extended registers but BMSR_ESTATEN and + * BMSR_ERCAP bits are set. + */ + if (dev->chip_id == KSZ8563_CHIP_ID && reg == MII_BMSR) + *data &= ~(BMSR_ESTATEN | BMSR_ERCAP); +} + void ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) { u16 val = 0xffff; @@ -308,6 +318,7 @@ void ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) } } else { ksz_pread16(dev, addr, 0x100 + (reg << 1), &val); + ksz9477_r_phy_quirks(dev, addr, reg, &val); } *data = val; From 8f420456792308639fcbc15462050c521fbd127d Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:21 +0200 Subject: [PATCH 05/18] net: dsa: microchip: allow to pass return values for PHY read/write accesses PHY access may end with errors on different levels. So, allow to forward return values where possible. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz8.h | 4 ++-- drivers/net/dsa/microchip/ksz8795.c | 8 ++++++-- drivers/net/dsa/microchip/ksz9477.c | 12 ++++++++---- drivers/net/dsa/microchip/ksz9477.h | 4 ++-- drivers/net/dsa/microchip/ksz_common.c | 10 ++++++++-- drivers/net/dsa/microchip/ksz_common.h | 4 ++-- drivers/net/dsa/microchip/lan937x.h | 4 ++-- drivers/net/dsa/microchip/lan937x_main.c | 8 ++++---- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h index 42c50cc4d8536..8582b4b67d989 100644 --- a/drivers/net/dsa/microchip/ksz8.h +++ b/drivers/net/dsa/microchip/ksz8.h @@ -17,8 +17,8 @@ u32 ksz8_get_port_addr(int port, int offset); void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member); void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port); void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port); -void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); -void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val); +int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); +int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val); int ksz8_r_dyn_mac_table(struct ksz_device *dev, u16 addr, u8 *mac_addr, u8 *fid, u8 *src_port, u8 *timestamp, u16 *entries); int ksz8_r_sta_mac_table(struct ksz_device *dev, u16 addr, diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index c79a5128235f9..f2dd75ee0e075 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -552,7 +552,7 @@ static void ksz8_w_vlan_table(struct ksz_device *dev, u16 vid, u16 vlan) ksz8_w_table(dev, TABLE_VLAN, addr, buf); } -void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) +int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) { u8 restart, speed, ctrl, link; int processed = true; @@ -674,9 +674,11 @@ void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) } if (processed) *val = data; + + return 0; } -void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) +int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) { u8 restart, speed, ctrl, data; const u16 *regs; @@ -787,6 +789,8 @@ void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) default: break; } + + return 0; } void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 2b3bf1d3950c2..a4f682d3e1fe6 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -274,7 +274,7 @@ static void ksz9477_r_phy_quirks(struct ksz_device *dev, u16 addr, u16 reg, *data &= ~(BMSR_ESTATEN | BMSR_ERCAP); } -void ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) +int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) { u16 val = 0xffff; @@ -322,19 +322,23 @@ void ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) } *data = val; + + return 0; } -void ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) +int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) { /* No real PHY after this. */ if (addr >= dev->phy_port_cnt) - return; + return 0; /* No gigabit support. Do not write to this register. */ if (!dev->info->gbit_capable[addr] && reg == MII_CTRL1000) - return; + return 0; ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); + + return 0; } void ksz9477_cfg_port_member(struct ksz_device *dev, int port, u8 member) diff --git a/drivers/net/dsa/microchip/ksz9477.h b/drivers/net/dsa/microchip/ksz9477.h index cd278b307b3c7..ce87e4e09ada8 100644 --- a/drivers/net/dsa/microchip/ksz9477.h +++ b/drivers/net/dsa/microchip/ksz9477.h @@ -16,8 +16,8 @@ u32 ksz9477_get_port_addr(int port, int offset); void ksz9477_cfg_port_member(struct ksz_device *dev, int port, u8 member); void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port); void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port); -void ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data); -void ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val); +int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data); +int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val); void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt); void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, u64 *dropped, u64 *cnt); diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 7b6d7efc0a002..099c7bf699406 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -1132,8 +1132,11 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg) { struct ksz_device *dev = ds->priv; u16 val = 0xffff; + int ret; - dev->dev_ops->r_phy(dev, addr, reg, &val); + ret = dev->dev_ops->r_phy(dev, addr, reg, &val); + if (ret) + return ret; return val; } @@ -1141,8 +1144,11 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg) static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val) { struct ksz_device *dev = ds->priv; + int ret; - dev->dev_ops->w_phy(dev, addr, reg, val); + ret = dev->dev_ops->w_phy(dev, addr, reg, val); + if (ret) + return ret; return 0; } diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index e3e120d659410..584850672b9a6 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -262,8 +262,8 @@ struct ksz_dev_ops { void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); void (*port_cleanup)(struct ksz_device *dev, int port); void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); - void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); - void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val); + int (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); + int (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val); void (*r_mib_cnt)(struct ksz_device *dev, int port, u16 addr, u64 *cnt); void (*r_mib_pkt)(struct ksz_device *dev, int port, u16 addr, diff --git a/drivers/net/dsa/microchip/lan937x.h b/drivers/net/dsa/microchip/lan937x.h index 4e0b1dccec270..5d78d034a62f1 100644 --- a/drivers/net/dsa/microchip/lan937x.h +++ b/drivers/net/dsa/microchip/lan937x.h @@ -12,8 +12,8 @@ void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port); void lan937x_config_cpu_port(struct dsa_switch *ds); int lan937x_switch_init(struct ksz_device *dev); void lan937x_switch_exit(struct ksz_device *dev); -void lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data); -void lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val); +int lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data); +int lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val); int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu); void lan937x_phylink_get_caps(struct ksz_device *dev, int port, struct phylink_config *config); diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index daedd2bf20c1b..7b464f1fb5d88 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -128,14 +128,14 @@ static int lan937x_internal_phy_read(struct ksz_device *dev, int addr, int reg, return ksz_read16(dev, REG_VPHY_IND_DATA__2, val); } -void lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) +int lan937x_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) { - lan937x_internal_phy_read(dev, addr, reg, data); + return lan937x_internal_phy_read(dev, addr, reg, data); } -void lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) +int lan937x_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) { - lan937x_internal_phy_write(dev, addr, reg, val); + return lan937x_internal_phy_write(dev, addr, reg, val); } static int lan937x_sw_mdio_read(struct mii_bus *bus, int addr, int regnum) From d38bc3b4b8a6a01170d7f79f2c48ca678d135bbb Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:22 +0200 Subject: [PATCH 06/18] net: dsa: microchip: forward error value on all ksz_pread/ksz_pwrite functions ksz_read*/ksz_write* are able to return errors, so forward it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz_common.h | 38 ++++++++++++++------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 584850672b9a6..62b9499afca58 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -394,40 +394,42 @@ static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value) return regmap_bulk_write(dev->regmap[2], reg, val, 2); } -static inline void ksz_pread8(struct ksz_device *dev, int port, int offset, - u8 *data) +static inline int ksz_pread8(struct ksz_device *dev, int port, int offset, + u8 *data) { - ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data); + return ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data); } -static inline void ksz_pread16(struct ksz_device *dev, int port, int offset, - u16 *data) +static inline int ksz_pread16(struct ksz_device *dev, int port, int offset, + u16 *data) { - ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data); + return ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data); } -static inline void ksz_pread32(struct ksz_device *dev, int port, int offset, - u32 *data) +static inline int ksz_pread32(struct ksz_device *dev, int port, int offset, + u32 *data) { - ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data); + return ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data); } -static inline void ksz_pwrite8(struct ksz_device *dev, int port, int offset, - u8 data) +static inline int ksz_pwrite8(struct ksz_device *dev, int port, int offset, + u8 data) { - ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data); + return ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data); } -static inline void ksz_pwrite16(struct ksz_device *dev, int port, int offset, - u16 data) +static inline int ksz_pwrite16(struct ksz_device *dev, int port, int offset, + u16 data) { - ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), data); + return ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), + data); } -static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset, - u32 data) +static inline int ksz_pwrite32(struct ksz_device *dev, int port, int offset, + u32 data) { - ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data); + return ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), + data); } static inline void ksz_prmw8(struct ksz_device *dev, int port, int offset, From 9da975e1bbef6804145743a6ec0cae0f2f3f4c09 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:23 +0200 Subject: [PATCH 07/18] net: dsa: microchip: ksz9477: add error handling to ksz9477_r/w_phy Now ksz_pread/ksz_pwrite can return error value. So, make use of it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index a4f682d3e1fe6..f60ceaf25a66c 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -277,6 +277,7 @@ static void ksz9477_r_phy_quirks(struct ksz_device *dev, u16 addr, u16 reg, int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) { u16 val = 0xffff; + int ret; /* No real PHY after this. Simulate the PHY. * A fixed PHY can be setup in the device tree, but this function is @@ -317,7 +318,10 @@ int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) break; } } else { - ksz_pread16(dev, addr, 0x100 + (reg << 1), &val); + ret = ksz_pread16(dev, addr, 0x100 + (reg << 1), &val); + if (ret) + return ret; + ksz9477_r_phy_quirks(dev, addr, reg, &val); } @@ -334,11 +338,9 @@ int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) /* No gigabit support. Do not write to this register. */ if (!dev->info->gbit_capable[addr] && reg == MII_CTRL1000) - return 0; + return -ENXIO; - ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); - - return 0; + return ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); } void ksz9477_cfg_port_member(struct ksz_device *dev, int port, u8 member) From 9590fc4a2af55f92142ecbb724d999adf77a07c0 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:24 +0200 Subject: [PATCH 08/18] net: dsa: microchip: ksz8795: add error handling to ksz8_r/w_phy Now ksz_pread/ksz_pwrite can return error value. So, make use of it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz8795.c | 102 ++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 21 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index f2dd75ee0e075..f020d9f402845 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -560,14 +560,24 @@ int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) u8 val1, val2; u16 data = 0; u8 p = phy; + int ret; regs = dev->info->regs; switch (reg) { case MII_BMCR: - ksz_pread8(dev, p, regs[P_NEG_RESTART_CTRL], &restart); - ksz_pread8(dev, p, regs[P_SPEED_STATUS], &speed); - ksz_pread8(dev, p, regs[P_FORCE_CTRL], &ctrl); + ret = ksz_pread8(dev, p, regs[P_NEG_RESTART_CTRL], &restart); + if (ret) + return ret; + + ret = ksz_pread8(dev, p, regs[P_SPEED_STATUS], &speed); + if (ret) + return ret; + + ret = ksz_pread8(dev, p, regs[P_FORCE_CTRL], &ctrl); + if (ret) + return ret; + if (restart & PORT_PHY_LOOPBACK) data |= BMCR_LOOPBACK; if (ctrl & PORT_FORCE_100_MBIT) @@ -597,7 +607,10 @@ int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) data |= KSZ886X_BMCR_DISABLE_LED; break; case MII_BMSR: - ksz_pread8(dev, p, regs[P_LINK_STATUS], &link); + ret = ksz_pread8(dev, p, regs[P_LINK_STATUS], &link); + if (ret) + return ret; + data = BMSR_100FULL | BMSR_100HALF | BMSR_10FULL | @@ -618,7 +631,10 @@ int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) data = KSZ8795_ID_LO; break; case MII_ADVERTISE: - ksz_pread8(dev, p, regs[P_LOCAL_CTRL], &ctrl); + ret = ksz_pread8(dev, p, regs[P_LOCAL_CTRL], &ctrl); + if (ret) + return ret; + data = ADVERTISE_CSMA; if (ctrl & PORT_AUTO_NEG_SYM_PAUSE) data |= ADVERTISE_PAUSE_CAP; @@ -632,7 +648,10 @@ int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) data |= ADVERTISE_10HALF; break; case MII_LPA: - ksz_pread8(dev, p, regs[P_REMOTE_STATUS], &link); + ret = ksz_pread8(dev, p, regs[P_REMOTE_STATUS], &link); + if (ret) + return ret; + data = LPA_SLCT; if (link & PORT_REMOTE_SYM_PAUSE) data |= LPA_PAUSE_CAP; @@ -648,8 +667,14 @@ int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) data |= LPA_LPACK; break; case PHY_REG_LINK_MD: - ksz_pread8(dev, p, REG_PORT_LINK_MD_CTRL, &val1); - ksz_pread8(dev, p, REG_PORT_LINK_MD_RESULT, &val2); + ret = ksz_pread8(dev, p, REG_PORT_LINK_MD_CTRL, &val1); + if (ret) + return ret; + + ret = ksz_pread8(dev, p, REG_PORT_LINK_MD_RESULT, &val2); + if (ret) + return ret; + if (val1 & PORT_START_CABLE_DIAG) data |= PHY_START_CABLE_DIAG; @@ -664,7 +689,10 @@ int ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val) FIELD_GET(PORT_CABLE_FAULT_COUNTER_L, val2)); break; case PHY_REG_PHY_CTRL: - ksz_pread8(dev, p, regs[P_LINK_STATUS], &link); + ret = ksz_pread8(dev, p, regs[P_LINK_STATUS], &link); + if (ret) + return ret; + if (link & PORT_MDIX_STATUS) data |= KSZ886X_CTRL_MDIX_STAT; break; @@ -683,6 +711,7 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) u8 restart, speed, ctrl, data; const u16 *regs; u8 p = phy; + int ret; regs = dev->info->regs; @@ -692,15 +721,26 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) /* Do not support PHY reset function. */ if (val & BMCR_RESET) break; - ksz_pread8(dev, p, regs[P_SPEED_STATUS], &speed); + ret = ksz_pread8(dev, p, regs[P_SPEED_STATUS], &speed); + if (ret) + return ret; + data = speed; if (val & KSZ886X_BMCR_HP_MDIX) data |= PORT_HP_MDIX; else data &= ~PORT_HP_MDIX; - if (data != speed) - ksz_pwrite8(dev, p, regs[P_SPEED_STATUS], data); - ksz_pread8(dev, p, regs[P_FORCE_CTRL], &ctrl); + + if (data != speed) { + ret = ksz_pwrite8(dev, p, regs[P_SPEED_STATUS], data); + if (ret) + return ret; + } + + ret = ksz_pread8(dev, p, regs[P_FORCE_CTRL], &ctrl); + if (ret) + return ret; + data = ctrl; if (ksz_is_ksz88x3(dev)) { if ((val & BMCR_ANENABLE)) @@ -726,9 +766,17 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) data |= PORT_FORCE_FULL_DUPLEX; else data &= ~PORT_FORCE_FULL_DUPLEX; - if (data != ctrl) - ksz_pwrite8(dev, p, regs[P_FORCE_CTRL], data); - ksz_pread8(dev, p, regs[P_NEG_RESTART_CTRL], &restart); + + if (data != ctrl) { + ret = ksz_pwrite8(dev, p, regs[P_FORCE_CTRL], data); + if (ret) + return ret; + } + + ret = ksz_pread8(dev, p, regs[P_NEG_RESTART_CTRL], &restart); + if (ret) + return ret; + data = restart; if (val & KSZ886X_BMCR_DISABLE_LED) data |= PORT_LED_OFF; @@ -758,11 +806,19 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) data |= PORT_PHY_LOOPBACK; else data &= ~PORT_PHY_LOOPBACK; - if (data != restart) - ksz_pwrite8(dev, p, regs[P_NEG_RESTART_CTRL], data); + + if (data != restart) { + ret = ksz_pwrite8(dev, p, regs[P_NEG_RESTART_CTRL], + data); + if (ret) + return ret; + } break; case MII_ADVERTISE: - ksz_pread8(dev, p, regs[P_LOCAL_CTRL], &ctrl); + ret = ksz_pread8(dev, p, regs[P_LOCAL_CTRL], &ctrl); + if (ret) + return ret; + data = ctrl; data &= ~(PORT_AUTO_NEG_SYM_PAUSE | PORT_AUTO_NEG_100BTX_FD | @@ -779,8 +835,12 @@ int ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val) data |= PORT_AUTO_NEG_10BT_FD; if (val & ADVERTISE_10HALF) data |= PORT_AUTO_NEG_10BT; - if (data != ctrl) - ksz_pwrite8(dev, p, regs[P_LOCAL_CTRL], data); + + if (data != ctrl) { + ret = ksz_pwrite8(dev, p, regs[P_LOCAL_CTRL], data); + if (ret) + return ret; + } break; case PHY_REG_LINK_MD: if (val & PHY_START_CABLE_DIAG) From b5708dc6539d7630b4ddbd9f72a74280630770b8 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:25 +0200 Subject: [PATCH 09/18] net: dsa: microchip: KSZ9893: do not write to not supported Output Clock Control Register This issue was detected after adding regmap register access validation. KSZ9893 compatible chips do not have "Output Clock Control Register 0x0103". So, avoid writing to it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index f60ceaf25a66c..fb9de6b447b12 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -193,6 +193,11 @@ int ksz9477_reset_switch(struct ksz_device *dev) ksz_write32(dev, REG_SW_PORT_INT_MASK__4, 0x7F); ksz_read32(dev, REG_SW_PORT_INT_STATUS__4, &data32); + /* KSZ9893 compatible chips do not support refclk configuration */ + if (dev->chip_id == KSZ9893_CHIP_ID || + dev->chip_id == KSZ8563_CHIP_ID) + return 0; + data8 = SW_ENABLE_REFCLKO; if (dev->synclko_disable) data8 = 0; From ec6ba50c65c1e30218f69055a556bdd133af6da5 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:26 +0200 Subject: [PATCH 10/18] net: dsa: microchip: add support for regmap_access_tables This is complex driver with support for different chips with different layouts. To detect at least some bugs earlier, we should validate register accesses by using regmap_access_table support. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz_common.h | 46 +++++++++++++++++++++++--- drivers/net/dsa/microchip/ksz_spi.c | 3 ++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 62b9499afca58..4491cedd32c32 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -62,6 +62,8 @@ struct ksz_chip_data { bool supports_rgmii[KSZ_MAX_NUM_PORTS]; bool internal_phy[KSZ_MAX_NUM_PORTS]; bool gbit_capable[KSZ_MAX_NUM_PORTS]; + const struct regmap_access_table *wr_table; + const struct regmap_access_table *rd_table; }; struct ksz_port { @@ -333,6 +335,10 @@ static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) unsigned int value; int ret = regmap_read(dev->regmap[0], reg, &value); + if (ret) + dev_err(dev->dev, "can't read 8bit reg: 0x%x %pe\n", reg, + ERR_PTR(ret)); + *val = value; return ret; } @@ -342,6 +348,10 @@ static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) unsigned int value; int ret = regmap_read(dev->regmap[1], reg, &value); + if (ret) + dev_err(dev->dev, "can't read 16bit reg: 0x%x %pe\n", reg, + ERR_PTR(ret)); + *val = value; return ret; } @@ -351,6 +361,10 @@ static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val) unsigned int value; int ret = regmap_read(dev->regmap[2], reg, &value); + if (ret) + dev_err(dev->dev, "can't read 32bit reg: 0x%x %pe\n", reg, + ERR_PTR(ret)); + *val = value; return ret; } @@ -361,7 +375,10 @@ static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) int ret; ret = regmap_bulk_read(dev->regmap[2], reg, value, 2); - if (!ret) + if (ret) + dev_err(dev->dev, "can't read 64bit reg: 0x%x %pe\n", reg, + ERR_PTR(ret)); + else *val = (u64)value[0] << 32 | value[1]; return ret; @@ -369,17 +386,38 @@ static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value) { - return regmap_write(dev->regmap[0], reg, value); + int ret; + + ret = regmap_write(dev->regmap[0], reg, value); + if (ret) + dev_err(dev->dev, "can't write 8bit reg: 0x%x %pe\n", reg, + ERR_PTR(ret)); + + return ret; } static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value) { - return regmap_write(dev->regmap[1], reg, value); + int ret; + + ret = regmap_write(dev->regmap[1], reg, value); + if (ret) + dev_err(dev->dev, "can't write 16bit reg: 0x%x %pe\n", reg, + ERR_PTR(ret)); + + return ret; } static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value) { - return regmap_write(dev->regmap[2], reg, value); + int ret; + + ret = regmap_write(dev->regmap[2], reg, value); + if (ret) + dev_err(dev->dev, "can't write 32bit reg: 0x%x %pe\n", reg, + ERR_PTR(ret)); + + return ret; } static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value) diff --git a/drivers/net/dsa/microchip/ksz_spi.c b/drivers/net/dsa/microchip/ksz_spi.c index 746b725b09ec4..44c2d99124066 100644 --- a/drivers/net/dsa/microchip/ksz_spi.c +++ b/drivers/net/dsa/microchip/ksz_spi.c @@ -66,7 +66,10 @@ static int ksz_spi_probe(struct spi_device *spi) for (i = 0; i < ARRAY_SIZE(ksz8795_regmap_config); i++) { rc = regmap_config[i]; rc.lock_arg = &dev->regmap_mutex; + rc.wr_table = chip->wr_table; + rc.rd_table = chip->rd_table; dev->regmap[i] = devm_regmap_init_spi(spi, &rc); + if (IS_ERR(dev->regmap[i])) { ret = PTR_ERR(dev->regmap[i]); dev_err(&spi->dev, From 41131bac9a9adf98024d129d676c09cdf72b7de7 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:27 +0200 Subject: [PATCH 11/18] net: dsa: microchip: add regmap_range for KSZ8563 chip Add register validation for KSZ8563. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz_common.c | 121 +++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 099c7bf699406..b63d4ca608553 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -412,6 +412,125 @@ static const u8 lan937x_shifts[] = { [ALU_STAT_INDEX] = 8, }; +static const struct regmap_range ksz8563_valid_regs[] = { + regmap_reg_range(0x0000, 0x0003), + regmap_reg_range(0x0006, 0x0006), + regmap_reg_range(0x000f, 0x001f), + regmap_reg_range(0x0100, 0x0100), + regmap_reg_range(0x0104, 0x0107), + regmap_reg_range(0x010d, 0x010d), + regmap_reg_range(0x0110, 0x0113), + regmap_reg_range(0x0120, 0x012b), + regmap_reg_range(0x0201, 0x0201), + regmap_reg_range(0x0210, 0x0213), + regmap_reg_range(0x0300, 0x0300), + regmap_reg_range(0x0302, 0x031b), + regmap_reg_range(0x0320, 0x032b), + regmap_reg_range(0x0330, 0x0336), + regmap_reg_range(0x0338, 0x033e), + regmap_reg_range(0x0340, 0x035f), + regmap_reg_range(0x0370, 0x0370), + regmap_reg_range(0x0378, 0x0378), + regmap_reg_range(0x037c, 0x037d), + regmap_reg_range(0x0390, 0x0393), + regmap_reg_range(0x0400, 0x040e), + regmap_reg_range(0x0410, 0x042f), + regmap_reg_range(0x0500, 0x0519), + regmap_reg_range(0x0520, 0x054b), + regmap_reg_range(0x0550, 0x05b3), + + /* port 1 */ + regmap_reg_range(0x1000, 0x1001), + regmap_reg_range(0x1004, 0x100b), + regmap_reg_range(0x1013, 0x1013), + regmap_reg_range(0x1017, 0x1017), + regmap_reg_range(0x101b, 0x101b), + regmap_reg_range(0x101f, 0x1021), + regmap_reg_range(0x1030, 0x1030), + regmap_reg_range(0x1100, 0x1111), + regmap_reg_range(0x111a, 0x111d), + regmap_reg_range(0x1122, 0x1127), + regmap_reg_range(0x112a, 0x112b), + regmap_reg_range(0x1136, 0x1139), + regmap_reg_range(0x113e, 0x113f), + regmap_reg_range(0x1400, 0x1401), + regmap_reg_range(0x1403, 0x1403), + regmap_reg_range(0x1410, 0x1417), + regmap_reg_range(0x1420, 0x1423), + regmap_reg_range(0x1500, 0x1507), + regmap_reg_range(0x1600, 0x1612), + regmap_reg_range(0x1800, 0x180f), + regmap_reg_range(0x1900, 0x1907), + regmap_reg_range(0x1914, 0x191b), + regmap_reg_range(0x1a00, 0x1a03), + regmap_reg_range(0x1a04, 0x1a08), + regmap_reg_range(0x1b00, 0x1b01), + regmap_reg_range(0x1b04, 0x1b04), + regmap_reg_range(0x1c00, 0x1c05), + regmap_reg_range(0x1c08, 0x1c1b), + + /* port 2 */ + regmap_reg_range(0x2000, 0x2001), + regmap_reg_range(0x2004, 0x200b), + regmap_reg_range(0x2013, 0x2013), + regmap_reg_range(0x2017, 0x2017), + regmap_reg_range(0x201b, 0x201b), + regmap_reg_range(0x201f, 0x2021), + regmap_reg_range(0x2030, 0x2030), + regmap_reg_range(0x2100, 0x2111), + regmap_reg_range(0x211a, 0x211d), + regmap_reg_range(0x2122, 0x2127), + regmap_reg_range(0x212a, 0x212b), + regmap_reg_range(0x2136, 0x2139), + regmap_reg_range(0x213e, 0x213f), + regmap_reg_range(0x2400, 0x2401), + regmap_reg_range(0x2403, 0x2403), + regmap_reg_range(0x2410, 0x2417), + regmap_reg_range(0x2420, 0x2423), + regmap_reg_range(0x2500, 0x2507), + regmap_reg_range(0x2600, 0x2612), + regmap_reg_range(0x2800, 0x280f), + regmap_reg_range(0x2900, 0x2907), + regmap_reg_range(0x2914, 0x291b), + regmap_reg_range(0x2a00, 0x2a03), + regmap_reg_range(0x2a04, 0x2a08), + regmap_reg_range(0x2b00, 0x2b01), + regmap_reg_range(0x2b04, 0x2b04), + regmap_reg_range(0x2c00, 0x2c05), + regmap_reg_range(0x2c08, 0x2c1b), + + /* port 3 */ + regmap_reg_range(0x3000, 0x3001), + regmap_reg_range(0x3004, 0x300b), + regmap_reg_range(0x3013, 0x3013), + regmap_reg_range(0x3017, 0x3017), + regmap_reg_range(0x301b, 0x301b), + regmap_reg_range(0x301f, 0x3021), + regmap_reg_range(0x3030, 0x3030), + regmap_reg_range(0x3300, 0x3301), + regmap_reg_range(0x3303, 0x3303), + regmap_reg_range(0x3400, 0x3401), + regmap_reg_range(0x3403, 0x3403), + regmap_reg_range(0x3410, 0x3417), + regmap_reg_range(0x3420, 0x3423), + regmap_reg_range(0x3500, 0x3507), + regmap_reg_range(0x3600, 0x3612), + regmap_reg_range(0x3800, 0x380f), + regmap_reg_range(0x3900, 0x3907), + regmap_reg_range(0x3914, 0x391b), + regmap_reg_range(0x3a00, 0x3a03), + regmap_reg_range(0x3a04, 0x3a08), + regmap_reg_range(0x3b00, 0x3b01), + regmap_reg_range(0x3b04, 0x3b04), + regmap_reg_range(0x3c00, 0x3c05), + regmap_reg_range(0x3c08, 0x3c1b), +}; + +static const struct regmap_access_table ksz8563_register_set = { + .yes_ranges = ksz8563_valid_regs, + .n_yes_ranges = ARRAY_SIZE(ksz8563_valid_regs), +}; + const struct ksz_chip_data ksz_switch_chips[] = { [KSZ8563] = { .chip_id = KSZ8563_CHIP_ID, @@ -435,6 +554,8 @@ const struct ksz_chip_data ksz_switch_chips[] = { .supports_rgmii = {false, false, true}, .internal_phy = {true, true, false}, .gbit_capable = {false, false, true}, + .wr_table = &ksz8563_register_set, + .rd_table = &ksz8563_register_set, }, [KSZ8795] = { From 5bd3ecd121e34370b4d5a02de925335655bbaa9a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:28 +0200 Subject: [PATCH 12/18] net: dsa: microchip: ksz9477: remove MII_CTRL1000 check from ksz9477_w_phy() The reason why PHYlib may access MII_CTRL1000 on the chip without GBit support is only if chip provides wrong information about extended caps register. This issue is now handled by ksz9477_r_phy_quirks() With proper regmap_ranges provided for all chips we will be able to catch this kind of bugs any way. So, remove this sanity check. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index fb9de6b447b12..f0c81d90c99f4 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -341,10 +341,6 @@ int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) if (addr >= dev->phy_port_cnt) return 0; - /* No gigabit support. Do not write to this register. */ - if (!dev->info->gbit_capable[addr] && reg == MII_CTRL1000) - return -ENXIO; - return ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); } From 74e792b5f2dd518983f401aa130094f1dbd0d74f Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:29 +0200 Subject: [PATCH 13/18] net: dsa: microchip: add regmap_range for KSZ9477 chip Add register validation for KSZ9477 Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz_common.c | 272 +++++++++++++++++++++++++ 1 file changed, 272 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index b63d4ca608553..7eb74ab049336 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -531,6 +531,276 @@ static const struct regmap_access_table ksz8563_register_set = { .n_yes_ranges = ARRAY_SIZE(ksz8563_valid_regs), }; +static const struct regmap_range ksz9477_valid_regs[] = { + regmap_reg_range(0x0000, 0x0003), + regmap_reg_range(0x0006, 0x0006), + regmap_reg_range(0x0010, 0x001f), + regmap_reg_range(0x0100, 0x0100), + regmap_reg_range(0x0103, 0x0107), + regmap_reg_range(0x010d, 0x010d), + regmap_reg_range(0x0110, 0x0113), + regmap_reg_range(0x0120, 0x012b), + regmap_reg_range(0x0201, 0x0201), + regmap_reg_range(0x0210, 0x0213), + regmap_reg_range(0x0300, 0x0300), + regmap_reg_range(0x0302, 0x031b), + regmap_reg_range(0x0320, 0x032b), + regmap_reg_range(0x0330, 0x0336), + regmap_reg_range(0x0338, 0x033e), + regmap_reg_range(0x0340, 0x035f), + regmap_reg_range(0x0370, 0x0370), + regmap_reg_range(0x0378, 0x0378), + regmap_reg_range(0x037c, 0x037d), + regmap_reg_range(0x0390, 0x0393), + regmap_reg_range(0x0400, 0x040e), + regmap_reg_range(0x0410, 0x042f), + regmap_reg_range(0x0444, 0x044b), + regmap_reg_range(0x0450, 0x046f), + regmap_reg_range(0x0500, 0x0519), + regmap_reg_range(0x0520, 0x054b), + regmap_reg_range(0x0550, 0x05b3), + regmap_reg_range(0x0604, 0x060b), + regmap_reg_range(0x0610, 0x0612), + regmap_reg_range(0x0614, 0x062c), + regmap_reg_range(0x0640, 0x0645), + regmap_reg_range(0x0648, 0x064d), + + /* port 1 */ + regmap_reg_range(0x1000, 0x1001), + regmap_reg_range(0x1013, 0x1013), + regmap_reg_range(0x1017, 0x1017), + regmap_reg_range(0x101b, 0x101b), + regmap_reg_range(0x101f, 0x1020), + regmap_reg_range(0x1030, 0x1030), + regmap_reg_range(0x1100, 0x1115), + regmap_reg_range(0x111a, 0x111f), + regmap_reg_range(0x1122, 0x1127), + regmap_reg_range(0x112a, 0x112b), + regmap_reg_range(0x1136, 0x1139), + regmap_reg_range(0x113e, 0x113f), + regmap_reg_range(0x1400, 0x1401), + regmap_reg_range(0x1403, 0x1403), + regmap_reg_range(0x1410, 0x1417), + regmap_reg_range(0x1420, 0x1423), + regmap_reg_range(0x1500, 0x1507), + regmap_reg_range(0x1600, 0x1613), + regmap_reg_range(0x1800, 0x180f), + regmap_reg_range(0x1820, 0x1827), + regmap_reg_range(0x1830, 0x1837), + regmap_reg_range(0x1840, 0x184b), + regmap_reg_range(0x1900, 0x1907), + regmap_reg_range(0x1914, 0x191b), + regmap_reg_range(0x1920, 0x1920), + regmap_reg_range(0x1923, 0x1927), + regmap_reg_range(0x1a00, 0x1a03), + regmap_reg_range(0x1a04, 0x1a07), + regmap_reg_range(0x1b00, 0x1b01), + regmap_reg_range(0x1b04, 0x1b04), + regmap_reg_range(0x1c00, 0x1c05), + regmap_reg_range(0x1c08, 0x1c1b), + + /* port 2 */ + regmap_reg_range(0x2000, 0x2001), + regmap_reg_range(0x2013, 0x2013), + regmap_reg_range(0x2017, 0x2017), + regmap_reg_range(0x201b, 0x201b), + regmap_reg_range(0x201f, 0x2020), + regmap_reg_range(0x2030, 0x2030), + regmap_reg_range(0x2100, 0x2115), + regmap_reg_range(0x211a, 0x211f), + regmap_reg_range(0x2122, 0x2127), + regmap_reg_range(0x212a, 0x212b), + regmap_reg_range(0x2136, 0x2139), + regmap_reg_range(0x213e, 0x213f), + regmap_reg_range(0x2400, 0x2401), + regmap_reg_range(0x2403, 0x2403), + regmap_reg_range(0x2410, 0x2417), + regmap_reg_range(0x2420, 0x2423), + regmap_reg_range(0x2500, 0x2507), + regmap_reg_range(0x2600, 0x2613), + regmap_reg_range(0x2800, 0x280f), + regmap_reg_range(0x2820, 0x2827), + regmap_reg_range(0x2830, 0x2837), + regmap_reg_range(0x2840, 0x284b), + regmap_reg_range(0x2900, 0x2907), + regmap_reg_range(0x2914, 0x291b), + regmap_reg_range(0x2920, 0x2920), + regmap_reg_range(0x2923, 0x2927), + regmap_reg_range(0x2a00, 0x2a03), + regmap_reg_range(0x2a04, 0x2a07), + regmap_reg_range(0x2b00, 0x2b01), + regmap_reg_range(0x2b04, 0x2b04), + regmap_reg_range(0x2c00, 0x2c05), + regmap_reg_range(0x2c08, 0x2c1b), + + /* port 3 */ + regmap_reg_range(0x3000, 0x3001), + regmap_reg_range(0x3013, 0x3013), + regmap_reg_range(0x3017, 0x3017), + regmap_reg_range(0x301b, 0x301b), + regmap_reg_range(0x301f, 0x3020), + regmap_reg_range(0x3030, 0x3030), + regmap_reg_range(0x3100, 0x3115), + regmap_reg_range(0x311a, 0x311f), + regmap_reg_range(0x3122, 0x3127), + regmap_reg_range(0x312a, 0x312b), + regmap_reg_range(0x3136, 0x3139), + regmap_reg_range(0x313e, 0x313f), + regmap_reg_range(0x3400, 0x3401), + regmap_reg_range(0x3403, 0x3403), + regmap_reg_range(0x3410, 0x3417), + regmap_reg_range(0x3420, 0x3423), + regmap_reg_range(0x3500, 0x3507), + regmap_reg_range(0x3600, 0x3613), + regmap_reg_range(0x3800, 0x380f), + regmap_reg_range(0x3820, 0x3827), + regmap_reg_range(0x3830, 0x3837), + regmap_reg_range(0x3840, 0x384b), + regmap_reg_range(0x3900, 0x3907), + regmap_reg_range(0x3914, 0x391b), + regmap_reg_range(0x3920, 0x3920), + regmap_reg_range(0x3923, 0x3927), + regmap_reg_range(0x3a00, 0x3a03), + regmap_reg_range(0x3a04, 0x3a07), + regmap_reg_range(0x3b00, 0x3b01), + regmap_reg_range(0x3b04, 0x3b04), + regmap_reg_range(0x3c00, 0x3c05), + regmap_reg_range(0x3c08, 0x3c1b), + + /* port 4 */ + regmap_reg_range(0x4000, 0x4001), + regmap_reg_range(0x4013, 0x4013), + regmap_reg_range(0x4017, 0x4017), + regmap_reg_range(0x401b, 0x401b), + regmap_reg_range(0x401f, 0x4020), + regmap_reg_range(0x4030, 0x4030), + regmap_reg_range(0x4100, 0x4115), + regmap_reg_range(0x411a, 0x411f), + regmap_reg_range(0x4122, 0x4127), + regmap_reg_range(0x412a, 0x412b), + regmap_reg_range(0x4136, 0x4139), + regmap_reg_range(0x413e, 0x413f), + regmap_reg_range(0x4400, 0x4401), + regmap_reg_range(0x4403, 0x4403), + regmap_reg_range(0x4410, 0x4417), + regmap_reg_range(0x4420, 0x4423), + regmap_reg_range(0x4500, 0x4507), + regmap_reg_range(0x4600, 0x4613), + regmap_reg_range(0x4800, 0x480f), + regmap_reg_range(0x4820, 0x4827), + regmap_reg_range(0x4830, 0x4837), + regmap_reg_range(0x4840, 0x484b), + regmap_reg_range(0x4900, 0x4907), + regmap_reg_range(0x4914, 0x491b), + regmap_reg_range(0x4920, 0x4920), + regmap_reg_range(0x4923, 0x4927), + regmap_reg_range(0x4a00, 0x4a03), + regmap_reg_range(0x4a04, 0x4a07), + regmap_reg_range(0x4b00, 0x4b01), + regmap_reg_range(0x4b04, 0x4b04), + regmap_reg_range(0x4c00, 0x4c05), + regmap_reg_range(0x4c08, 0x4c1b), + + /* port 5 */ + regmap_reg_range(0x5000, 0x5001), + regmap_reg_range(0x5013, 0x5013), + regmap_reg_range(0x5017, 0x5017), + regmap_reg_range(0x501b, 0x501b), + regmap_reg_range(0x501f, 0x5020), + regmap_reg_range(0x5030, 0x5030), + regmap_reg_range(0x5100, 0x5115), + regmap_reg_range(0x511a, 0x511f), + regmap_reg_range(0x5122, 0x5127), + regmap_reg_range(0x512a, 0x512b), + regmap_reg_range(0x5136, 0x5139), + regmap_reg_range(0x513e, 0x513f), + regmap_reg_range(0x5400, 0x5401), + regmap_reg_range(0x5403, 0x5403), + regmap_reg_range(0x5410, 0x5417), + regmap_reg_range(0x5420, 0x5423), + regmap_reg_range(0x5500, 0x5507), + regmap_reg_range(0x5600, 0x5613), + regmap_reg_range(0x5800, 0x580f), + regmap_reg_range(0x5820, 0x5827), + regmap_reg_range(0x5830, 0x5837), + regmap_reg_range(0x5840, 0x584b), + regmap_reg_range(0x5900, 0x5907), + regmap_reg_range(0x5914, 0x591b), + regmap_reg_range(0x5920, 0x5920), + regmap_reg_range(0x5923, 0x5927), + regmap_reg_range(0x5a00, 0x5a03), + regmap_reg_range(0x5a04, 0x5a07), + regmap_reg_range(0x5b00, 0x5b01), + regmap_reg_range(0x5b04, 0x5b04), + regmap_reg_range(0x5c00, 0x5c05), + regmap_reg_range(0x5c08, 0x5c1b), + + /* port 6 */ + regmap_reg_range(0x6000, 0x6001), + regmap_reg_range(0x6013, 0x6013), + regmap_reg_range(0x6017, 0x6017), + regmap_reg_range(0x601b, 0x601b), + regmap_reg_range(0x601f, 0x6020), + regmap_reg_range(0x6030, 0x6030), + regmap_reg_range(0x6300, 0x6301), + regmap_reg_range(0x6400, 0x6401), + regmap_reg_range(0x6403, 0x6403), + regmap_reg_range(0x6410, 0x6417), + regmap_reg_range(0x6420, 0x6423), + regmap_reg_range(0x6500, 0x6507), + regmap_reg_range(0x6600, 0x6613), + regmap_reg_range(0x6800, 0x680f), + regmap_reg_range(0x6820, 0x6827), + regmap_reg_range(0x6830, 0x6837), + regmap_reg_range(0x6840, 0x684b), + regmap_reg_range(0x6900, 0x6907), + regmap_reg_range(0x6914, 0x691b), + regmap_reg_range(0x6920, 0x6920), + regmap_reg_range(0x6923, 0x6927), + regmap_reg_range(0x6a00, 0x6a03), + regmap_reg_range(0x6a04, 0x6a07), + regmap_reg_range(0x6b00, 0x6b01), + regmap_reg_range(0x6b04, 0x6b04), + regmap_reg_range(0x6c00, 0x6c05), + regmap_reg_range(0x6c08, 0x6c1b), + + /* port 7 */ + regmap_reg_range(0x7000, 0x7001), + regmap_reg_range(0x7013, 0x7013), + regmap_reg_range(0x7017, 0x7017), + regmap_reg_range(0x701b, 0x701b), + regmap_reg_range(0x701f, 0x7020), + regmap_reg_range(0x7030, 0x7030), + regmap_reg_range(0x7200, 0x7203), + regmap_reg_range(0x7206, 0x7207), + regmap_reg_range(0x7300, 0x7301), + regmap_reg_range(0x7400, 0x7401), + regmap_reg_range(0x7403, 0x7403), + regmap_reg_range(0x7410, 0x7417), + regmap_reg_range(0x7420, 0x7423), + regmap_reg_range(0x7500, 0x7507), + regmap_reg_range(0x7600, 0x7613), + regmap_reg_range(0x7800, 0x780f), + regmap_reg_range(0x7820, 0x7827), + regmap_reg_range(0x7830, 0x7837), + regmap_reg_range(0x7840, 0x784b), + regmap_reg_range(0x7900, 0x7907), + regmap_reg_range(0x7914, 0x791b), + regmap_reg_range(0x7920, 0x7920), + regmap_reg_range(0x7923, 0x7927), + regmap_reg_range(0x7a00, 0x7a03), + regmap_reg_range(0x7a04, 0x7a07), + regmap_reg_range(0x7b00, 0x7b01), + regmap_reg_range(0x7b04, 0x7b04), + regmap_reg_range(0x7c00, 0x7c05), + regmap_reg_range(0x7c08, 0x7c1b), +}; + +static const struct regmap_access_table ksz9477_register_set = { + .yes_ranges = ksz9477_valid_regs, + .n_yes_ranges = ARRAY_SIZE(ksz9477_valid_regs), +}; + const struct ksz_chip_data ksz_switch_chips[] = { [KSZ8563] = { .chip_id = KSZ8563_CHIP_ID, @@ -691,6 +961,8 @@ const struct ksz_chip_data ksz_switch_chips[] = { .internal_phy = {true, true, true, true, true, false, false}, .gbit_capable = {true, true, true, true, true, true, true}, + .wr_table = &ksz9477_register_set, + .rd_table = &ksz9477_register_set, }, [KSZ9897] = { From 0a7fbd514edfcf1e67f9737f35c0a12b3ff1b438 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:30 +0200 Subject: [PATCH 14/18] net: dsa: microchip: ksz9477: use internal_phy instead of phy_port_cnt With code refactoring was introduced new variable internal_phy. Let's use it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index f0c81d90c99f4..d1ee6b4b49542 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -290,7 +290,7 @@ int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) * For RGMII PHY there is no way to access it so the fixed PHY should * be used. For SGMII PHY the supporting code will be added later. */ - if (addr >= dev->phy_port_cnt) { + if (!dev->info->internal_phy[addr]) { struct ksz_port *p = &dev->ports[addr]; switch (reg) { @@ -338,7 +338,7 @@ int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data) int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) { /* No real PHY after this. */ - if (addr >= dev->phy_port_cnt) + if (!dev->info->internal_phy[addr]) return 0; return ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); @@ -887,7 +887,7 @@ static phy_interface_t ksz9477_get_interface(struct ksz_device *dev, int port) phy_interface_t interface; bool gbit; - if (port < dev->phy_port_cnt) + if (dev->info->internal_phy[port]) return PHY_INTERFACE_MODE_NA; gbit = ksz_get_gbit(dev, port); @@ -994,7 +994,7 @@ void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) /* enable 802.1p priority */ ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true); - if (port < dev->phy_port_cnt) { + if (dev->info->internal_phy[port]) { /* do not force flow control */ ksz_port_cfg(dev, port, REG_PORT_CTRL_0, PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL, @@ -1017,7 +1017,7 @@ void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) ksz9477_cfg_port_member(dev, port, member); /* clear pending interrupts */ - if (port < dev->phy_port_cnt) + if (dev->info->internal_phy[port]) ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, &data16); } @@ -1080,7 +1080,7 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED); p->on = 1; - if (i < dev->phy_port_cnt) + if (dev->info->internal_phy[i]) p->phy = 1; if (dev->chip_id == 0x00947700 && i == 6) { p->sgmii = 1; @@ -1176,15 +1176,9 @@ int ksz9477_switch_init(struct ksz_device *dev) if (ret) return ret; - /* Number of ports can be reduced depending on chip. */ - dev->phy_port_cnt = 5; - - if (dev->chip_id == KSZ9893_CHIP_ID) { + if (dev->chip_id == KSZ9893_CHIP_ID) dev->features |= IS_9893; - dev->phy_port_cnt = 2; - } - return 0; } From 6aaa8e7d20026652ede69ce3ff4772859752da15 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:31 +0200 Subject: [PATCH 15/18] net: dsa: microchip: remove unused port phy variable This variable is unused. So, drop it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz8795.c | 1 - drivers/net/dsa/microchip/ksz9477.c | 5 ----- drivers/net/dsa/microchip/ksz_common.h | 1 - 3 files changed, 7 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index f020d9f402845..bd3b133e7085b 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -1251,7 +1251,6 @@ void ksz8_config_cpu_port(struct dsa_switch *ds) if (i == dev->phy_port_cnt) break; p->on = 1; - p->phy = 1; } for (i = 0; i < dev->phy_port_cnt; i++) { p = &dev->ports[i]; diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index d1ee6b4b49542..4a2074a12b3f7 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1080,13 +1080,8 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED); p->on = 1; - if (dev->info->internal_phy[i]) - p->phy = 1; if (dev->chip_id == 0x00947700 && i == 6) { p->sgmii = 1; - - /* SGMII PHY detection code is not implemented yet. */ - p->phy = 0; } } } diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 4491cedd32c32..99da2092d0d7d 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -73,7 +73,6 @@ struct ksz_port { struct phy_device phydev; u32 on:1; /* port is not disabled by hardware */ - u32 phy:1; /* port has a PHY */ u32 fiber:1; /* port is fiber */ u32 sgmii:1; /* port is SGMII */ u32 force:1; From 7d39143449ea3308ed116a7cc71bc870a2d25151 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:32 +0200 Subject: [PATCH 16/18] net: dsa: microchip: ksz9477: remove unused "on" variable This variable is not used on ksz9477 side. Remove it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 4a2074a12b3f7..18375309233ad 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1069,7 +1069,6 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) /* enable cpu port */ ksz9477_port_setup(dev, i, true); - p->on = 1; } } @@ -1079,7 +1078,6 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) p = &dev->ports[i]; ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED); - p->on = 1; if (dev->chip_id == 0x00947700 && i == 6) { p->sgmii = 1; } From e7f695210140ea67dd81f7c9d95c3a685966e1de Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:33 +0200 Subject: [PATCH 17/18] net: dsa: microchip: remove unused sgmii variable This variable is not used. So, remove it. Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 5 ----- drivers/net/dsa/microchip/ksz_common.h | 1 - 2 files changed, 6 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 18375309233ad..077b4e5c29c7c 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1075,12 +1075,7 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) for (i = 0; i < dev->info->port_cnt; i++) { if (i == dev->cpu_port) continue; - p = &dev->ports[i]; - ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED); - if (dev->chip_id == 0x00947700 && i == 6) { - p->sgmii = 1; - } } } diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 99da2092d0d7d..4914cc1c803a4 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -74,7 +74,6 @@ struct ksz_port { u32 on:1; /* port is not disabled by hardware */ u32 fiber:1; /* port is fiber */ - u32 sgmii:1; /* port is SGMII */ u32 force:1; u32 read:1; /* read MIB counters in background */ u32 freeze:1; /* MIB counter freeze is enabled */ From 32cbac21b9f47c00b72d40a46d87039270daff7a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 26 Aug 2022 12:56:34 +0200 Subject: [PATCH 18/18] net: dsa: microchip: remove IS_9893 flag Use chip_id as other places of this code do it Signed-off-by: Oleksij Rempel Reviewed-by: Vladimir Oltean Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477.c | 3 --- drivers/net/dsa/microchip/ksz_common.c | 3 ++- drivers/net/dsa/microchip/ksz_common.h | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 077b4e5c29c7c..42d7e4c124594 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1164,9 +1164,6 @@ int ksz9477_switch_init(struct ksz_device *dev) if (ret) return ret; - if (dev->chip_id == KSZ9893_CHIP_ID) - dev->features |= IS_9893; - return 0; } diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 7eb74ab049336..37fb5ba2cd7ad 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -1912,7 +1912,8 @@ static void ksz_set_xmii(struct ksz_device *dev, int port, case PHY_INTERFACE_MODE_RGMII_RXID: data8 |= bitval[P_RGMII_SEL]; /* On KSZ9893, disable RGMII in-band status support */ - if (dev->features & IS_9893) + if (dev->chip_id == KSZ9893_CHIP_ID || + dev->chip_id == KSZ8563_CHIP_ID) data8 &= ~P_MII_MAC_MODE; break; default: diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 4914cc1c803a4..c01989c04d4e3 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -119,7 +119,6 @@ struct ksz_device { unsigned long mib_read_interval; u16 mirror_rx; u16 mirror_tx; - u32 features; /* chip specific features */ u16 port_mask; }; @@ -542,9 +541,6 @@ static inline int is_lan937x(struct ksz_device *dev) #define SW_START 0x01 -/* Used with variable features to indicate capabilities. */ -#define IS_9893 BIT(2) - /* xMII configuration */ #define P_MII_DUPLEX_M BIT(6) #define P_MII_100MBIT_M BIT(4)