Commit e8bacf40 authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-microchip-ksz_switch-refactor'

Arun Ramadoss says:

====================
net: dsa: microchip: refactor the ksz switch init function

During the ksz_switch_register function, it calls the individual switches init
functions (ksz8795.c and ksz9477.c). Both these functions have few things in
common like, copying the chip specific data to struct ksz_dev, allocating
ksz_port memory and mib_names memory & cnt. And to add the new LAN937x series
switch, these allocations has to be replicated.
Based on the review feedback of LAN937x part support patch, refactored the
switch init function to move allocations to switch register.

Link:https://patchwork.kernel.org/project/netdevbpf/patch/20220504151755.11737-8-arun.ramadoss@microchip.com/
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6431ce6c 008db08b
This diff is collapsed.
...@@ -34,6 +34,7 @@ KSZ_REGMAP_TABLE(ksz8863, 16, KSZ8863_SPI_ADDR_SHIFT, ...@@ -34,6 +34,7 @@ KSZ_REGMAP_TABLE(ksz8863, 16, KSZ8863_SPI_ADDR_SHIFT,
static int ksz8795_spi_probe(struct spi_device *spi) static int ksz8795_spi_probe(struct spi_device *spi)
{ {
const struct regmap_config *regmap_config; const struct regmap_config *regmap_config;
const struct ksz_chip_data *chip;
struct device *ddev = &spi->dev; struct device *ddev = &spi->dev;
struct regmap_config rc; struct regmap_config rc;
struct ksz_device *dev; struct ksz_device *dev;
...@@ -50,10 +51,15 @@ static int ksz8795_spi_probe(struct spi_device *spi) ...@@ -50,10 +51,15 @@ static int ksz8795_spi_probe(struct spi_device *spi)
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
regmap_config = device_get_match_data(ddev); chip = device_get_match_data(ddev);
if (!regmap_config) if (!chip)
return -EINVAL; return -EINVAL;
if (chip->chip_id == KSZ8830_CHIP_ID)
regmap_config = ksz8863_regmap_config;
else
regmap_config = ksz8795_regmap_config;
for (i = 0; i < ARRAY_SIZE(ksz8795_regmap_config); i++) { for (i = 0; i < ARRAY_SIZE(ksz8795_regmap_config); i++) {
rc = regmap_config[i]; rc = regmap_config[i];
rc.lock_arg = &dev->regmap_mutex; rc.lock_arg = &dev->regmap_mutex;
...@@ -113,11 +119,26 @@ static void ksz8795_spi_shutdown(struct spi_device *spi) ...@@ -113,11 +119,26 @@ static void ksz8795_spi_shutdown(struct spi_device *spi)
} }
static const struct of_device_id ksz8795_dt_ids[] = { static const struct of_device_id ksz8795_dt_ids[] = {
{ .compatible = "microchip,ksz8765", .data = &ksz8795_regmap_config }, {
{ .compatible = "microchip,ksz8794", .data = &ksz8795_regmap_config }, .compatible = "microchip,ksz8765",
{ .compatible = "microchip,ksz8795", .data = &ksz8795_regmap_config }, .data = &ksz_switch_chips[KSZ8765]
{ .compatible = "microchip,ksz8863", .data = &ksz8863_regmap_config }, },
{ .compatible = "microchip,ksz8873", .data = &ksz8863_regmap_config }, {
.compatible = "microchip,ksz8794",
.data = &ksz_switch_chips[KSZ8794]
},
{
.compatible = "microchip,ksz8795",
.data = &ksz_switch_chips[KSZ8795]
},
{
.compatible = "microchip,ksz8863",
.data = &ksz_switch_chips[KSZ8830]
},
{
.compatible = "microchip,ksz8873",
.data = &ksz_switch_chips[KSZ8830]
},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, ksz8795_dt_ids); MODULE_DEVICE_TABLE(of, ksz8795_dt_ids);
......
...@@ -206,8 +206,14 @@ static void ksz8863_smi_shutdown(struct mdio_device *mdiodev) ...@@ -206,8 +206,14 @@ static void ksz8863_smi_shutdown(struct mdio_device *mdiodev)
} }
static const struct of_device_id ksz8863_dt_ids[] = { static const struct of_device_id ksz8863_dt_ids[] = {
{ .compatible = "microchip,ksz8863" }, {
{ .compatible = "microchip,ksz8873" }, .compatible = "microchip,ksz8863",
.data = &ksz_switch_chips[KSZ8830]
},
{
.compatible = "microchip,ksz8873",
.data = &ksz_switch_chips[KSZ8830]
},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, ksz8863_dt_ids); MODULE_DEVICE_TABLE(of, ksz8863_dt_ids);
......
...@@ -23,48 +23,6 @@ ...@@ -23,48 +23,6 @@
#define NEW_XMII BIT(1) #define NEW_XMII BIT(1)
#define IS_9893 BIT(2) #define IS_9893 BIT(2)
static const struct {
int index;
char string[ETH_GSTRING_LEN];
} ksz9477_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
{ 0x00, "rx_hi" },
{ 0x01, "rx_undersize" },
{ 0x02, "rx_fragments" },
{ 0x03, "rx_oversize" },
{ 0x04, "rx_jabbers" },
{ 0x05, "rx_symbol_err" },
{ 0x06, "rx_crc_err" },
{ 0x07, "rx_align_err" },
{ 0x08, "rx_mac_ctrl" },
{ 0x09, "rx_pause" },
{ 0x0A, "rx_bcast" },
{ 0x0B, "rx_mcast" },
{ 0x0C, "rx_ucast" },
{ 0x0D, "rx_64_or_less" },
{ 0x0E, "rx_65_127" },
{ 0x0F, "rx_128_255" },
{ 0x10, "rx_256_511" },
{ 0x11, "rx_512_1023" },
{ 0x12, "rx_1024_1522" },
{ 0x13, "rx_1523_2000" },
{ 0x14, "rx_2001" },
{ 0x15, "tx_hi" },
{ 0x16, "tx_late_col" },
{ 0x17, "tx_pause" },
{ 0x18, "tx_bcast" },
{ 0x19, "tx_mcast" },
{ 0x1A, "tx_ucast" },
{ 0x1B, "tx_deferred" },
{ 0x1C, "tx_total_col" },
{ 0x1D, "tx_exc_col" },
{ 0x1E, "tx_single_col" },
{ 0x1F, "tx_mult_col" },
{ 0x80, "rx_total" },
{ 0x81, "tx_total" },
{ 0x82, "rx_discards" },
{ 0x83, "tx_discards" },
};
static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set) static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
{ {
regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0); regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0);
...@@ -100,7 +58,7 @@ static int ksz9477_change_mtu(struct dsa_switch *ds, int port, int mtu) ...@@ -100,7 +58,7 @@ static int ksz9477_change_mtu(struct dsa_switch *ds, int port, int mtu)
/* Cache the per-port MTU setting */ /* Cache the per-port MTU setting */
dev->ports[port].max_frame = frame_size; dev->ports[port].max_frame = frame_size;
for (i = 0; i < dev->port_cnt; i++) for (i = 0; i < dev->info->port_cnt; i++)
max_frame = max(max_frame, dev->ports[i].max_frame); max_frame = max(max_frame, dev->ports[i].max_frame);
return regmap_update_bits(dev->regmap[1], REG_SW_MTU__2, return regmap_update_bits(dev->regmap[1], REG_SW_MTU__2,
...@@ -287,7 +245,7 @@ static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, ...@@ -287,7 +245,7 @@ static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
u64 *dropped, u64 *cnt) u64 *dropped, u64 *cnt)
{ {
addr = ksz9477_mib_names[addr].index; addr = dev->info->mib_names[addr].index;
ksz9477_r_mib_cnt(dev, port, addr, cnt); ksz9477_r_mib_cnt(dev, port, addr, cnt);
} }
...@@ -316,9 +274,6 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, int port) ...@@ -316,9 +274,6 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, int port)
ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH); ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH);
ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0); ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0);
mutex_unlock(&mib->cnt_mutex); mutex_unlock(&mib->cnt_mutex);
mib->cnt_ptr = 0;
memset(mib->counters, 0, dev->mib_cnt * sizeof(u64));
} }
static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds, static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
...@@ -400,20 +355,6 @@ static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg, ...@@ -400,20 +355,6 @@ static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg,
return 0; return 0;
} }
static void ksz9477_get_strings(struct dsa_switch *ds, int port,
u32 stringset, uint8_t *buf)
{
int i;
if (stringset != ETH_SS_STATS)
return;
for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
memcpy(buf + i * ETH_GSTRING_LEN, ksz9477_mib_names[i].string,
ETH_GSTRING_LEN);
}
}
static void ksz9477_cfg_port_member(struct ksz_device *dev, int port, static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
u8 member) u8 member)
{ {
...@@ -434,7 +375,7 @@ static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) ...@@ -434,7 +375,7 @@ static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
SW_FLUSH_OPTION_M << SW_FLUSH_OPTION_S, SW_FLUSH_OPTION_M << SW_FLUSH_OPTION_S,
SW_FLUSH_OPTION_DYN_MAC << SW_FLUSH_OPTION_S); SW_FLUSH_OPTION_DYN_MAC << SW_FLUSH_OPTION_S);
if (port < dev->port_cnt) { if (port < dev->info->port_cnt) {
/* flush individual port */ /* flush individual port */
ksz_pread8(dev, port, P_STP_CTRL, &data); ksz_pread8(dev, port, P_STP_CTRL, &data);
if (!(data & PORT_LEARN_DISABLE)) if (!(data & PORT_LEARN_DISABLE))
...@@ -756,7 +697,7 @@ static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port, ...@@ -756,7 +697,7 @@ static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
mutex_lock(&dev->alu_mutex); mutex_lock(&dev->alu_mutex);
for (index = 0; index < dev->num_statics; index++) { for (index = 0; index < dev->info->num_statics; index++) {
/* find empty slot first */ /* find empty slot first */
data = (index << ALU_STAT_INDEX_S) | data = (index << ALU_STAT_INDEX_S) |
ALU_STAT_READ | ALU_STAT_START; ALU_STAT_READ | ALU_STAT_START;
...@@ -787,7 +728,7 @@ static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port, ...@@ -787,7 +728,7 @@ static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
} }
/* no available entry */ /* no available entry */
if (index == dev->num_statics) { if (index == dev->info->num_statics) {
err = -ENOSPC; err = -ENOSPC;
goto exit; goto exit;
} }
...@@ -832,7 +773,7 @@ static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port, ...@@ -832,7 +773,7 @@ static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port,
mutex_lock(&dev->alu_mutex); mutex_lock(&dev->alu_mutex);
for (index = 0; index < dev->num_statics; index++) { for (index = 0; index < dev->info->num_statics; index++) {
/* find empty slot first */ /* find empty slot first */
data = (index << ALU_STAT_INDEX_S) | data = (index << ALU_STAT_INDEX_S) |
ALU_STAT_READ | ALU_STAT_START; ALU_STAT_READ | ALU_STAT_START;
...@@ -861,7 +802,7 @@ static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port, ...@@ -861,7 +802,7 @@ static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port,
} }
/* no available entry */ /* no available entry */
if (index == dev->num_statics) if (index == dev->info->num_statics)
goto exit; goto exit;
/* clear port */ /* clear port */
...@@ -903,7 +844,7 @@ static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port, ...@@ -903,7 +844,7 @@ static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port,
* Check if any of the port is already set for sniffing * Check if any of the port is already set for sniffing
* If yes, instruct the user to remove the previous entry & exit * If yes, instruct the user to remove the previous entry & exit
*/ */
for (p = 0; p < dev->port_cnt; p++) { for (p = 0; p < dev->info->port_cnt; p++) {
/* Skip the current sniffing port */ /* Skip the current sniffing port */
if (p == mirror->to_local_port) if (p == mirror->to_local_port)
continue; continue;
...@@ -946,7 +887,7 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port, ...@@ -946,7 +887,7 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port,
/* Check if any of the port is still referring to sniffer port */ /* Check if any of the port is still referring to sniffer port */
for (p = 0; p < dev->port_cnt; p++) { for (p = 0; p < dev->info->port_cnt; p++) {
ksz_pread8(dev, p, P_MIRROR_CTRL, &data); ksz_pread8(dev, p, P_MIRROR_CTRL, &data);
if ((data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) { if ((data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) {
...@@ -1156,6 +1097,15 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port) ...@@ -1156,6 +1097,15 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port)
ksz9477_port_mmd_write(dev, port, 0x1c, 0x20, 0xeeee); ksz9477_port_mmd_write(dev, port, 0x1c, 0x20, 0xeeee);
} }
static void ksz9477_get_caps(struct dsa_switch *ds, int port,
struct phylink_config *config)
{
ksz_phylink_get_caps(ds, port, config);
config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000FD |
MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
}
static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
{ {
struct ksz_port *p = &dev->ports[port]; struct ksz_port *p = &dev->ports[port];
...@@ -1194,7 +1144,7 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) ...@@ -1194,7 +1144,7 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL, PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL,
false); false);
if (dev->phy_errata_9477) if (dev->info->phy_errata_9477)
ksz9477_phy_errata_setup(dev, port); ksz9477_phy_errata_setup(dev, port);
} else { } else {
/* force flow control */ /* force flow control */
...@@ -1259,8 +1209,9 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds) ...@@ -1259,8 +1209,9 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
struct ksz_port *p; struct ksz_port *p;
int i; int i;
for (i = 0; i < dev->port_cnt; i++) { for (i = 0; i < dev->info->port_cnt; i++) {
if (dsa_is_cpu_port(ds, i) && (dev->cpu_ports & (1 << i))) { if (dsa_is_cpu_port(ds, i) &&
(dev->info->cpu_ports & (1 << i))) {
phy_interface_t interface; phy_interface_t interface;
const char *prev_msg; const char *prev_msg;
const char *prev_mode; const char *prev_mode;
...@@ -1304,7 +1255,7 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds) ...@@ -1304,7 +1255,7 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
} }
} }
for (i = 0; i < dev->port_cnt; i++) { for (i = 0; i < dev->info->port_cnt; i++) {
if (i == dev->cpu_port) if (i == dev->cpu_port)
continue; continue;
p = &dev->ports[i]; p = &dev->ports[i];
...@@ -1328,7 +1279,7 @@ static int ksz9477_setup(struct dsa_switch *ds) ...@@ -1328,7 +1279,7 @@ static int ksz9477_setup(struct dsa_switch *ds)
int ret = 0; int ret = 0;
dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table), dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table),
dev->num_vlans, GFP_KERNEL); dev->info->num_vlans, GFP_KERNEL);
if (!dev->vlan_cache) if (!dev->vlan_cache)
return -ENOMEM; return -ENOMEM;
...@@ -1380,8 +1331,9 @@ static const struct dsa_switch_ops ksz9477_switch_ops = { ...@@ -1380,8 +1331,9 @@ static const struct dsa_switch_ops ksz9477_switch_ops = {
.phy_read = ksz9477_phy_read16, .phy_read = ksz9477_phy_read16,
.phy_write = ksz9477_phy_write16, .phy_write = ksz9477_phy_write16,
.phylink_mac_link_down = ksz_mac_link_down, .phylink_mac_link_down = ksz_mac_link_down,
.phylink_get_caps = ksz9477_get_caps,
.port_enable = ksz_enable_port, .port_enable = ksz_enable_port,
.get_strings = ksz9477_get_strings, .get_strings = ksz_get_strings,
.get_ethtool_stats = ksz_get_ethtool_stats, .get_ethtool_stats = ksz_get_ethtool_stats,
.get_sset_count = ksz_sset_count, .get_sset_count = ksz_sset_count,
.port_bridge_join = ksz_port_bridge_join, .port_bridge_join = ksz_port_bridge_join,
...@@ -1470,109 +1422,11 @@ static int ksz9477_switch_detect(struct ksz_device *dev) ...@@ -1470,109 +1422,11 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
return 0; return 0;
} }
struct ksz_chip_data {
u32 chip_id;
const char *dev_name;
int num_vlans;
int num_alus;
int num_statics;
int cpu_ports;
int port_cnt;
bool phy_errata_9477;
};
static const struct ksz_chip_data ksz9477_switch_chips[] = {
{
.chip_id = 0x00947700,
.dev_name = "KSZ9477",
.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 */
.phy_errata_9477 = true,
},
{
.chip_id = 0x00989700,
.dev_name = "KSZ9897",
.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 */
.phy_errata_9477 = true,
},
{
.chip_id = 0x00989300,
.dev_name = "KSZ9893",
.num_vlans = 4096,
.num_alus = 4096,
.num_statics = 16,
.cpu_ports = 0x07, /* can be configured as cpu port */
.port_cnt = 3, /* total port count */
},
{
.chip_id = 0x00956700,
.dev_name = "KSZ9567",
.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 */
.phy_errata_9477 = true,
},
};
static int ksz9477_switch_init(struct ksz_device *dev) static int ksz9477_switch_init(struct ksz_device *dev)
{ {
int i;
dev->ds->ops = &ksz9477_switch_ops; dev->ds->ops = &ksz9477_switch_ops;
for (i = 0; i < ARRAY_SIZE(ksz9477_switch_chips); i++) { dev->port_mask = (1 << dev->info->port_cnt) - 1;
const struct ksz_chip_data *chip = &ksz9477_switch_chips[i];
if (dev->chip_id == chip->chip_id) {
dev->name = chip->dev_name;
dev->num_vlans = chip->num_vlans;
dev->num_alus = chip->num_alus;
dev->num_statics = chip->num_statics;
dev->port_cnt = chip->port_cnt;
dev->cpu_ports = chip->cpu_ports;
dev->phy_errata_9477 = chip->phy_errata_9477;
break;
}
}
/* no switch found */
if (!dev->port_cnt)
return -ENODEV;
dev->port_mask = (1 << dev->port_cnt) - 1;
dev->reg_mib_cnt = SWITCH_COUNTER_NUM;
dev->mib_cnt = TOTAL_SWITCH_COUNTER_NUM;
dev->ports = devm_kzalloc(dev->dev,
dev->port_cnt * sizeof(struct ksz_port),
GFP_KERNEL);
if (!dev->ports)
return -ENOMEM;
for (i = 0; i < dev->port_cnt; i++) {
spin_lock_init(&dev->ports[i].mib.stats64_lock);
mutex_init(&dev->ports[i].mib.cnt_mutex);
dev->ports[i].mib.counters =
devm_kzalloc(dev->dev,
sizeof(u64) *
(TOTAL_SWITCH_COUNTER_NUM + 1),
GFP_KERNEL);
if (!dev->ports[i].mib.counters)
return -ENOMEM;
}
/* set the real number of ports */
dev->ds->num_ports = dev->port_cnt;
return 0; return 0;
} }
......
...@@ -87,12 +87,30 @@ static const struct i2c_device_id ksz9477_i2c_id[] = { ...@@ -87,12 +87,30 @@ static const struct i2c_device_id ksz9477_i2c_id[] = {
MODULE_DEVICE_TABLE(i2c, ksz9477_i2c_id); MODULE_DEVICE_TABLE(i2c, ksz9477_i2c_id);
static const struct of_device_id ksz9477_dt_ids[] = { static const struct of_device_id ksz9477_dt_ids[] = {
{ .compatible = "microchip,ksz9477" }, {
{ .compatible = "microchip,ksz9897" }, .compatible = "microchip,ksz9477",
{ .compatible = "microchip,ksz9893" }, .data = &ksz_switch_chips[KSZ9477]
{ .compatible = "microchip,ksz9563" }, },
{ .compatible = "microchip,ksz9567" }, {
{ .compatible = "microchip,ksz8563" }, .compatible = "microchip,ksz9897",
.data = &ksz_switch_chips[KSZ9897]
},
{
.compatible = "microchip,ksz9893",
.data = &ksz_switch_chips[KSZ9893]
},
{
.compatible = "microchip,ksz9563",
.data = &ksz_switch_chips[KSZ9893]
},
{
.compatible = "microchip,ksz8563",
.data = &ksz_switch_chips[KSZ9893]
},
{
.compatible = "microchip,ksz9567",
.data = &ksz_switch_chips[KSZ9567]
},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, ksz9477_dt_ids); MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);
......
...@@ -86,12 +86,30 @@ static void ksz9477_spi_shutdown(struct spi_device *spi) ...@@ -86,12 +86,30 @@ static void ksz9477_spi_shutdown(struct spi_device *spi)
} }
static const struct of_device_id ksz9477_dt_ids[] = { static const struct of_device_id ksz9477_dt_ids[] = {
{ .compatible = "microchip,ksz9477" }, {
{ .compatible = "microchip,ksz9897" }, .compatible = "microchip,ksz9477",
{ .compatible = "microchip,ksz9893" }, .data = &ksz_switch_chips[KSZ9477]
{ .compatible = "microchip,ksz9563" }, },
{ .compatible = "microchip,ksz8563" }, {
{ .compatible = "microchip,ksz9567" }, .compatible = "microchip,ksz9897",
.data = &ksz_switch_chips[KSZ9897]
},
{
.compatible = "microchip,ksz9893",
.data = &ksz_switch_chips[KSZ9893]
},
{
.compatible = "microchip,ksz9563",
.data = &ksz_switch_chips[KSZ9893]
},
{
.compatible = "microchip,ksz8563",
.data = &ksz_switch_chips[KSZ9893]
},
{
.compatible = "microchip,ksz9567",
.data = &ksz_switch_chips[KSZ9567]
},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, ksz9477_dt_ids); MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);
......
This diff is collapsed.
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <net/dsa.h> #include <net/dsa.h>
#define KSZ_MAX_NUM_PORTS 8
struct vlan_table { struct vlan_table {
u32 table[3]; u32 table[3];
}; };
...@@ -26,6 +28,30 @@ struct ksz_port_mib { ...@@ -26,6 +28,30 @@ struct ksz_port_mib {
struct spinlock stats64_lock; struct spinlock stats64_lock;
}; };
struct ksz_mib_names {
int index;
char string[ETH_GSTRING_LEN];
};
struct ksz_chip_data {
u32 chip_id;
const char *dev_name;
int num_vlans;
int num_alus;
int num_statics;
int cpu_ports;
int port_cnt;
bool phy_errata_9477;
bool ksz87xx_eee_link_erratum;
const struct ksz_mib_names *mib_names;
int mib_cnt;
u8 reg_mib_cnt;
bool supports_mii[KSZ_MAX_NUM_PORTS];
bool supports_rmii[KSZ_MAX_NUM_PORTS];
bool supports_rgmii[KSZ_MAX_NUM_PORTS];
bool internal_phy[KSZ_MAX_NUM_PORTS];
};
struct ksz_port { struct ksz_port {
bool remove_tag; /* Remove Tag flag set, for ksz8795 only */ bool remove_tag; /* Remove Tag flag set, for ksz8795 only */
int stp_state; int stp_state;
...@@ -47,7 +73,7 @@ struct ksz_port { ...@@ -47,7 +73,7 @@ struct ksz_port {
struct ksz_device { struct ksz_device {
struct dsa_switch *ds; struct dsa_switch *ds;
struct ksz_platform_data *pdata; struct ksz_platform_data *pdata;
const char *name; const struct ksz_chip_data *info;
struct mutex dev_mutex; /* device access */ struct mutex dev_mutex; /* device access */
struct mutex regmap_mutex; /* regmap access */ struct mutex regmap_mutex; /* regmap access */
...@@ -64,20 +90,9 @@ struct ksz_device { ...@@ -64,20 +90,9 @@ struct ksz_device {
/* chip specific data */ /* chip specific data */
u32 chip_id; u32 chip_id;
int num_vlans;
int num_alus;
int num_statics;
int cpu_port; /* port connected to CPU */ int cpu_port; /* port connected to CPU */
int cpu_ports; /* port bitmap can be cpu port */
int phy_port_cnt; int phy_port_cnt;
int port_cnt;
u8 reg_mib_cnt;
int mib_cnt;
const struct mib_names *mib_names;
phy_interface_t compat_interface; phy_interface_t compat_interface;
u32 regs_size;
bool phy_errata_9477;
bool ksz87xx_eee_link_erratum;
bool synclko_125; bool synclko_125;
bool synclko_disable; bool synclko_disable;
...@@ -89,11 +104,42 @@ struct ksz_device { ...@@ -89,11 +104,42 @@ struct ksz_device {
u16 mirror_rx; u16 mirror_rx;
u16 mirror_tx; u16 mirror_tx;
u32 features; /* chip specific features */ u32 features; /* chip specific features */
u32 overrides; /* chip functions set by user */
u16 host_mask;
u16 port_mask; u16 port_mask;
}; };
/* List of supported models */
enum ksz_model {
KSZ8795,
KSZ8794,
KSZ8765,
KSZ8830,
KSZ9477,
KSZ9897,
KSZ9893,
KSZ9567,
LAN9370,
LAN9371,
LAN9372,
LAN9373,
LAN9374,
};
enum ksz_chip_id {
KSZ8795_CHIP_ID = 0x8795,
KSZ8794_CHIP_ID = 0x8794,
KSZ8765_CHIP_ID = 0x8765,
KSZ8830_CHIP_ID = 0x8830,
KSZ9477_CHIP_ID = 0x00947700,
KSZ9897_CHIP_ID = 0x00989700,
KSZ9893_CHIP_ID = 0x00989300,
KSZ9567_CHIP_ID = 0x00956700,
LAN9370_CHIP_ID = 0x00937000,
LAN9371_CHIP_ID = 0x00937100,
LAN9372_CHIP_ID = 0x00937200,
LAN9373_CHIP_ID = 0x00937300,
LAN9374_CHIP_ID = 0x00937400,
};
struct alu_struct { struct alu_struct {
/* entry 1 */ /* entry 1 */
u8 is_static:1; u8 is_static:1;
...@@ -154,6 +200,9 @@ void ksz_init_mib_timer(struct ksz_device *dev); ...@@ -154,6 +200,9 @@ void ksz_init_mib_timer(struct ksz_device *dev);
void ksz_r_mib_stats64(struct ksz_device *dev, int port); void ksz_r_mib_stats64(struct ksz_device *dev, int port);
void ksz_get_stats64(struct dsa_switch *ds, int port, void ksz_get_stats64(struct dsa_switch *ds, int port,
struct rtnl_link_stats64 *s); struct rtnl_link_stats64 *s);
void ksz_phylink_get_caps(struct dsa_switch *ds, int port,
struct phylink_config *config);
extern const struct ksz_chip_data ksz_switch_chips[];
/* Common DSA access functions */ /* Common DSA access functions */
...@@ -180,6 +229,8 @@ int ksz_port_mdb_del(struct dsa_switch *ds, int port, ...@@ -180,6 +229,8 @@ int ksz_port_mdb_del(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb, const struct switchdev_obj_port_mdb *mdb,
struct dsa_db db); struct dsa_db db);
int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy); int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
void ksz_get_strings(struct dsa_switch *ds, int port,
u32 stringset, uint8_t *buf);
/* Common register access functions */ /* Common register access functions */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment