Merge branch 'net-dsa-microchip-add-lan9646-switch-support'

Tristram Ha says:

====================
net: dsa: microchip: Add LAN9646 switch support

This series of patches is to add LAN9646 switch support to the KSZ DSA
driver.
====================

Link: https://patch.msgid.link/20241109015705.82685-1-Tristram.Ha@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-11-13 19:55:02 -08:00
commit a71c69f51d
7 changed files with 75 additions and 3 deletions

View File

@ -34,6 +34,7 @@ properties:
- microchip,ksz9563
- microchip,ksz8563
- microchip,ksz8567
- microchip,lan9646
reset-gpios:
description:

View File

@ -1131,6 +1131,10 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds)
if (i == dev->cpu_port)
continue;
ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED);
/* Power down the internal PHY if port is unused. */
if (dsa_is_unused_port(ds, i) && dev->info->internal_phy[i])
ksz_pwrite16(dev, i, 0x100, BMCR_PDOWN);
}
}

View File

@ -2,7 +2,7 @@
/*
* Microchip KSZ9477 series register access through I2C
*
* Copyright (C) 2018-2019 Microchip Technology Inc.
* Copyright (C) 2018-2024 Microchip Technology Inc.
*/
#include <linux/i2c.h>
@ -16,6 +16,8 @@ KSZ_REGMAP_TABLE(ksz9477, not_used, 16, 0, 0);
static int ksz9477_i2c_probe(struct i2c_client *i2c)
{
const struct ksz_chip_data *chip;
struct device *ddev = &i2c->dev;
struct regmap_config rc;
struct ksz_device *dev;
int i, ret;
@ -24,6 +26,12 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c)
if (!dev)
return -ENOMEM;
chip = device_get_match_data(ddev);
if (!chip)
return -EINVAL;
/* Save chip id to do special initialization when probing. */
dev->chip_id = chip->chip_id;
for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
rc = ksz9477_regmap_config[i];
rc.lock_arg = &dev->regmap_mutex;
@ -111,6 +119,10 @@ static const struct of_device_id ksz9477_dt_ids[] = {
.compatible = "microchip,ksz9567",
.data = &ksz_switch_chips[KSZ9567]
},
{
.compatible = "microchip,lan9646",
.data = &ksz_switch_chips[LAN9646]
},
{},
};
MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);

View File

@ -1908,6 +1908,41 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.internal_phy = {true, true, true, true,
false, false, true, true},
},
[LAN9646] = {
.chip_id = LAN9646_CHIP_ID,
.dev_name = "LAN9646",
.num_vlans = 4096,
.num_alus = 4096,
.num_statics = 16,
.cpu_ports = 0x7F, /* can be configured as cpu port */
.port_cnt = 7, /* total physical port count */
.port_nirqs = 4,
.num_tx_queues = 4,
.num_ipms = 8,
.ops = &ksz9477_dev_ops,
.phylink_mac_ops = &ksz9477_phylink_mac_ops,
.phy_errata_9477 = true,
.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 = ksz9477_xmii_ctrl1,
.supports_mii = {false, false, false, false,
false, true, true},
.supports_rmii = {false, false, false, false,
false, true, true},
.supports_rgmii = {false, false, false, false,
false, true, true},
.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,
},
};
EXPORT_SYMBOL_GPL(ksz_switch_chips);
@ -2970,6 +3005,7 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)
case KSZ9896_CHIP_ID:
/* KSZ9896C Errata DS80000757A Module 3 */
case KSZ9897_CHIP_ID:
case LAN9646_CHIP_ID:
/* KSZ9897R Errata DS80000758C Module 4 */
/* Energy Efficient Ethernet (EEE) feature select must be manually disabled
* The EEE feature is enabled by default, but it is not fully
@ -3230,6 +3266,7 @@ static void ksz_port_teardown(struct dsa_switch *ds, int port)
case KSZ9893_CHIP_ID:
case KSZ9896_CHIP_ID:
case KSZ9897_CHIP_ID:
case LAN9646_CHIP_ID:
if (dsa_is_user_port(ds, port))
ksz9477_port_acl_free(dev, port);
}
@ -3286,7 +3323,8 @@ static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
dev->chip_id == KSZ9477_CHIP_ID ||
dev->chip_id == KSZ9896_CHIP_ID ||
dev->chip_id == KSZ9897_CHIP_ID ||
dev->chip_id == KSZ9567_CHIP_ID)
dev->chip_id == KSZ9567_CHIP_ID ||
dev->chip_id == LAN9646_CHIP_ID)
proto = DSA_TAG_PROTO_KSZ9477;
if (is_lan937x(dev))
@ -3405,6 +3443,7 @@ static int ksz_max_mtu(struct dsa_switch *ds, int port)
case LAN9372_CHIP_ID:
case LAN9373_CHIP_ID:
case LAN9374_CHIP_ID:
case LAN9646_CHIP_ID:
return KSZ9477_MAX_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;
}
@ -3427,6 +3466,7 @@ static int ksz_validate_eee(struct dsa_switch *ds, int port)
case KSZ9893_CHIP_ID:
case KSZ9896_CHIP_ID:
case KSZ9897_CHIP_ID:
case LAN9646_CHIP_ID:
return 0;
}
@ -3779,7 +3819,10 @@ static int ksz_switch_detect(struct ksz_device *dev)
case LAN9372_CHIP_ID:
case LAN9373_CHIP_ID:
case LAN9374_CHIP_ID:
dev->chip_id = id32;
/* LAN9646 does not have its own chip id. */
if (dev->chip_id != LAN9646_CHIP_ID)
dev->chip_id = id32;
break;
case KSZ9893_CHIP_ID:
ret = ksz_read8(dev, REG_CHIP_ID4,
@ -3818,6 +3861,7 @@ static int ksz_cls_flower_add(struct dsa_switch *ds, int port,
case KSZ9893_CHIP_ID:
case KSZ9896_CHIP_ID:
case KSZ9897_CHIP_ID:
case LAN9646_CHIP_ID:
return ksz9477_cls_flower_add(ds, port, cls, ingress);
}
@ -3838,6 +3882,7 @@ static int ksz_cls_flower_del(struct dsa_switch *ds, int port,
case KSZ9893_CHIP_ID:
case KSZ9896_CHIP_ID:
case KSZ9897_CHIP_ID:
case LAN9646_CHIP_ID:
return ksz9477_cls_flower_del(ds, port, cls, ingress);
}
@ -4925,6 +4970,7 @@ static int ksz_parse_drive_strength(struct ksz_device *dev)
case KSZ9893_CHIP_ID:
case KSZ9896_CHIP_ID:
case KSZ9897_CHIP_ID:
case LAN9646_CHIP_ID:
return ksz9477_drive_strength_write(dev, of_props,
ARRAY_SIZE(of_props));
default:

View File

@ -236,6 +236,7 @@ enum ksz_model {
LAN9372,
LAN9373,
LAN9374,
LAN9646,
};
enum ksz_regs {

View File

@ -54,6 +54,8 @@ static int ksz_spi_probe(struct spi_device *spi)
if (!chip)
return -EINVAL;
/* Save chip id to do special initialization when probing. */
dev->chip_id = chip->chip_id;
if (chip->chip_id == KSZ88X3_CHIP_ID)
regmap_config = ksz8863_regmap_config;
else if (chip->chip_id == KSZ8795_CHIP_ID ||
@ -203,6 +205,10 @@ static const struct of_device_id ksz_dt_ids[] = {
.compatible = "microchip,lan9374",
.data = &ksz_switch_chips[LAN9374]
},
{
.compatible = "microchip,lan9646",
.data = &ksz_switch_chips[LAN9646]
},
{},
};
MODULE_DEVICE_TABLE(of, ksz_dt_ids);
@ -228,6 +234,7 @@ static const struct spi_device_id ksz_spi_ids[] = {
{ "lan9372" },
{ "lan9373" },
{ "lan9374" },
{ "lan9646" },
{ },
};
MODULE_DEVICE_TABLE(spi, ksz_spi_ids);

View File

@ -42,6 +42,7 @@ enum ksz_chip_id {
LAN9372_CHIP_ID = 0x00937200,
LAN9373_CHIP_ID = 0x00937300,
LAN9374_CHIP_ID = 0x00937400,
LAN9646_CHIP_ID = 0x00964600,
};
struct ksz_platform_data {