diff options
Diffstat (limited to 'drivers/net/dsa/microchip')
-rw-r--r-- | drivers/net/dsa/microchip/ksz8795.c | 29 | ||||
-rw-r--r-- | drivers/net/dsa/microchip/ksz8795_reg.h | 3 | ||||
-rw-r--r-- | drivers/net/dsa/microchip/ksz_common.c | 39 | ||||
-rw-r--r-- | drivers/net/dsa/microchip/ksz_common.h | 20 |
4 files changed, 53 insertions, 38 deletions
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index ec1ddfcf7473..61b71bcfe396 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -1358,6 +1358,9 @@ static void ksz8795_cpu_interface_select(struct ksz_device *dev, int port) { struct ksz_port *p = &dev->ports[port]; + if (!ksz_is_ksz87xx(dev)) + return; + if (!p->interface && dev->compat_interface) { dev_warn(dev->dev, "Using legacy switch \"phy-mode\" property, because it is missing on port %d node. " @@ -1391,18 +1394,29 @@ void ksz8_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_ENABLE, true); - if (cpu_port) { - if (!ksz_is_ksz88x3(dev)) - ksz8795_cpu_interface_select(dev, port); - + if (cpu_port) member = dsa_user_ports(ds); - } else { + else member = BIT(dsa_upstream_port(ds, port)); - } ksz8_cfg_port_member(dev, port, member); } +static void ksz88x3_config_rmii_clk(struct ksz_device *dev) +{ + struct dsa_port *cpu_dp = dsa_to_port(dev->ds, dev->cpu_port); + bool rmii_clk_internal; + + if (!ksz_is_ksz88x3(dev)) + return; + + rmii_clk_internal = of_property_read_bool(cpu_dp->dn, + "microchip,rmii-clk-internal"); + + ksz_cfg(dev, KSZ88X3_REG_FVID_AND_HOST_MODE, + KSZ88X3_PORT3_RMII_CLK_INTERNAL, rmii_clk_internal); +} + void ksz8_config_cpu_port(struct dsa_switch *ds) { struct ksz_device *dev = ds->priv; @@ -1419,6 +1433,9 @@ void ksz8_config_cpu_port(struct dsa_switch *ds) ksz8_port_setup(dev, dev->cpu_port, true); + ksz8795_cpu_interface_select(dev, dev->cpu_port); + ksz88x3_config_rmii_clk(dev); + for (i = 0; i < dev->phy_port_cnt; i++) { ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED); } diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h b/drivers/net/dsa/microchip/ksz8795_reg.h index 3c9dae53e4d8..beca974e0171 100644 --- a/drivers/net/dsa/microchip/ksz8795_reg.h +++ b/drivers/net/dsa/microchip/ksz8795_reg.h @@ -22,6 +22,9 @@ #define KSZ8863_GLOBAL_SOFTWARE_RESET BIT(4) #define KSZ8863_PCS_RESET BIT(0) +#define KSZ88X3_REG_FVID_AND_HOST_MODE 0xC6 +#define KSZ88X3_PORT3_RMII_CLK_INTERNAL BIT(3) + #define REG_SW_CTRL_0 0x02 #define SW_NEW_BACKOFF BIT(7) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 9545aed905f5..245dfb7a7a31 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -1673,15 +1673,23 @@ static const struct ksz_chip_data *ksz_lookup_info(unsigned int prod_num) static int ksz_check_device_id(struct ksz_device *dev) { - const struct ksz_chip_data *dt_chip_data; + const struct ksz_chip_data *expected_chip_data; + u32 expected_chip_id; - dt_chip_data = of_device_get_match_data(dev->dev); + if (dev->pdata) { + expected_chip_id = dev->pdata->chip_id; + expected_chip_data = ksz_lookup_info(expected_chip_id); + if (WARN_ON(!expected_chip_data)) + return -ENODEV; + } else { + expected_chip_data = of_device_get_match_data(dev->dev); + expected_chip_id = expected_chip_data->chip_id; + } - /* Check for Device Tree and Chip ID */ - if (dt_chip_data->chip_id != dev->chip_id) { + if (expected_chip_id != dev->chip_id) { dev_err(dev->dev, "Device tree specifies chip %s but found %s, please fix it!\n", - dt_chip_data->dev_name, dev->info->dev_name); + expected_chip_data->dev_name, dev->info->dev_name); return -ENODEV; } @@ -2704,7 +2712,7 @@ static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, proto = DSA_TAG_PROTO_KSZ9477; if (is_lan937x(dev)) - proto = DSA_TAG_PROTO_LAN937X_VALUE; + proto = DSA_TAG_PROTO_LAN937X; return proto; } @@ -2714,10 +2722,18 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds, { struct ksz_tagger_data *tagger_data; - tagger_data = ksz_tagger_data(ds); - tagger_data->xmit_work_fn = ksz_port_deferred_xmit; - - return 0; + switch (proto) { + case DSA_TAG_PROTO_KSZ8795: + return 0; + case DSA_TAG_PROTO_KSZ9893: + case DSA_TAG_PROTO_KSZ9477: + case DSA_TAG_PROTO_LAN937X: + tagger_data = ksz_tagger_data(ds); + tagger_data->xmit_work_fn = ksz_port_deferred_xmit; + return 0; + default: + return -EPROTONOSUPPORT; + } } static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, @@ -4156,9 +4172,6 @@ int ksz_switch_register(struct ksz_device *dev) int ret; int i; - if (dev->pdata) - dev->chip_id = dev->pdata->chip_id; - dev->reset_gpio = devm_gpiod_get_optional(dev->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(dev->reset_gpio)) diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index d1a1c876ba0d..15612101a155 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -14,6 +14,7 @@ #include <linux/regmap.h> #include <net/dsa.h> #include <linux/irq.h> +#include <linux/platform_data/microchip-ksz.h> #include "ksz_ptp.h" @@ -203,25 +204,6 @@ enum ksz_model { LAN9374, }; -enum ksz_chip_id { - KSZ8563_CHIP_ID = 0x8563, - KSZ8795_CHIP_ID = 0x8795, - KSZ8794_CHIP_ID = 0x8794, - KSZ8765_CHIP_ID = 0x8765, - KSZ8830_CHIP_ID = 0x8830, - KSZ9477_CHIP_ID = 0x00947700, - KSZ9896_CHIP_ID = 0x00989600, - KSZ9897_CHIP_ID = 0x00989700, - KSZ9893_CHIP_ID = 0x00989300, - KSZ9563_CHIP_ID = 0x00956300, - KSZ9567_CHIP_ID = 0x00956700, - LAN9370_CHIP_ID = 0x00937000, - LAN9371_CHIP_ID = 0x00937100, - LAN9372_CHIP_ID = 0x00937200, - LAN9373_CHIP_ID = 0x00937300, - LAN9374_CHIP_ID = 0x00937400, -}; - enum ksz_regs { REG_SW_MAC_ADDR, REG_IND_CTRL_0, |