Commit 331d64f7 authored by Arun Ramadoss's avatar Arun Ramadoss Committed by David S. Miller

net: dsa: microchip: add the enable_stp_addr pointer in ksz_dev_ops

In order to transmit the STP BPDU packet to the CPU port, the STP
address 01-80-c2-00-00-00 has to be added to static alu table for
ksz8795 series switch. For the ksz9477 switch, there is reserved
multicast table which handles forwarding the particular set of
multicast address to cpu port. So enabling the multicast reserved table
and updated the cpu port index. The stp addr is enabled during the setup
phase using the enable_stp_addr pointer in struct ksz_dev_ops.
Signed-off-by: default avatarArun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fb9324be
...@@ -1368,10 +1368,25 @@ static int ksz8_handle_global_errata(struct dsa_switch *ds) ...@@ -1368,10 +1368,25 @@ static int ksz8_handle_global_errata(struct dsa_switch *ds)
return ret; return ret;
} }
static int ksz8_enable_stp_addr(struct ksz_device *dev)
{
struct alu_struct alu;
/* Setup STP address for STP operation. */
memset(&alu, 0, sizeof(alu));
ether_addr_copy(alu.mac, eth_stp_addr);
alu.is_static = true;
alu.is_override = true;
alu.port_forward = dev->info->cpu_ports;
ksz8_w_sta_mac_table(dev, 0, &alu);
return 0;
}
static int ksz8_setup(struct dsa_switch *ds) static int ksz8_setup(struct dsa_switch *ds)
{ {
struct ksz_device *dev = ds->priv; struct ksz_device *dev = ds->priv;
struct alu_struct alu;
int i, ret = 0; int i, ret = 0;
dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table), dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table),
...@@ -1422,14 +1437,7 @@ static int ksz8_setup(struct dsa_switch *ds) ...@@ -1422,14 +1437,7 @@ static int ksz8_setup(struct dsa_switch *ds)
for (i = 0; i < (dev->info->num_vlans / 4); i++) for (i = 0; i < (dev->info->num_vlans / 4); i++)
ksz8_r_vlan_entries(dev, i); ksz8_r_vlan_entries(dev, i);
/* Setup STP address for STP operation. */ dev->dev_ops->enable_stp_addr(dev);
memset(&alu, 0, sizeof(alu));
ether_addr_copy(alu.mac, eth_stp_addr);
alu.is_static = true;
alu.is_override = true;
alu.port_forward = dev->info->cpu_ports;
ksz8_w_sta_mac_table(dev, 0, &alu);
ksz_init_mib_timer(dev); ksz_init_mib_timer(dev);
...@@ -1546,6 +1554,7 @@ static const struct ksz_dev_ops ksz8_dev_ops = { ...@@ -1546,6 +1554,7 @@ static const struct ksz_dev_ops ksz8_dev_ops = {
.mirror_del = ksz8_port_mirror_del, .mirror_del = ksz8_port_mirror_del,
.get_caps = ksz8_get_caps, .get_caps = ksz8_get_caps,
.config_cpu_port = ksz8_config_cpu_port, .config_cpu_port = ksz8_config_cpu_port,
.enable_stp_addr = ksz8_enable_stp_addr,
.reset = ksz8_reset_switch, .reset = ksz8_reset_switch,
.init = ksz8_switch_init, .init = ksz8_switch_init,
.exit = ksz8_switch_exit, .exit = ksz8_switch_exit,
......
...@@ -1236,6 +1236,36 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds) ...@@ -1236,6 +1236,36 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
} }
} }
static int ksz9477_enable_stp_addr(struct ksz_device *dev)
{
u32 data;
int ret;
/* Enable Reserved multicast table */
ksz_cfg(dev, REG_SW_LUE_CTRL_0, SW_RESV_MCAST_ENABLE, true);
/* Set the Override bit for forwarding BPDU packet to CPU */
ret = ksz_write32(dev, REG_SW_ALU_VAL_B,
ALU_V_OVERRIDE | BIT(dev->cpu_port));
if (ret < 0)
return ret;
data = ALU_STAT_START | ALU_RESV_MCAST_ADDR;
ret = ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data);
if (ret < 0)
return ret;
/* wait to be finished */
ret = ksz9477_wait_alu_sta_ready(dev);
if (ret < 0) {
dev_err(dev->dev, "Failed to update Reserved Multicast table\n");
return ret;
}
return 0;
}
static int ksz9477_setup(struct dsa_switch *ds) static int ksz9477_setup(struct dsa_switch *ds)
{ {
struct ksz_device *dev = ds->priv; struct ksz_device *dev = ds->priv;
...@@ -1281,6 +1311,8 @@ static int ksz9477_setup(struct dsa_switch *ds) ...@@ -1281,6 +1311,8 @@ static int ksz9477_setup(struct dsa_switch *ds)
/* start switch */ /* start switch */
ksz_cfg(dev, REG_SW_OPERATION, SW_START, true); ksz_cfg(dev, REG_SW_OPERATION, SW_START, true);
dev->dev_ops->enable_stp_addr(dev);
ksz_init_mib_timer(dev); ksz_init_mib_timer(dev);
ds->configure_vlan_while_not_filtering = false; ds->configure_vlan_while_not_filtering = false;
...@@ -1401,6 +1433,7 @@ static const struct ksz_dev_ops ksz9477_dev_ops = { ...@@ -1401,6 +1433,7 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
.change_mtu = ksz9477_change_mtu, .change_mtu = ksz9477_change_mtu,
.max_mtu = ksz9477_max_mtu, .max_mtu = ksz9477_max_mtu,
.config_cpu_port = ksz9477_config_cpu_port, .config_cpu_port = ksz9477_config_cpu_port,
.enable_stp_addr = ksz9477_enable_stp_addr,
.reset = ksz9477_reset_switch, .reset = ksz9477_reset_switch,
.init = ksz9477_switch_init, .init = ksz9477_switch_init,
.exit = ksz9477_switch_exit, .exit = ksz9477_switch_exit,
......
...@@ -205,6 +205,7 @@ struct ksz_dev_ops { ...@@ -205,6 +205,7 @@ struct ksz_dev_ops {
void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze); void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze);
void (*port_init_cnt)(struct ksz_device *dev, int port); void (*port_init_cnt)(struct ksz_device *dev, int port);
void (*config_cpu_port)(struct dsa_switch *ds); void (*config_cpu_port)(struct dsa_switch *ds);
int (*enable_stp_addr)(struct ksz_device *dev);
int (*reset)(struct ksz_device *dev); int (*reset)(struct ksz_device *dev);
int (*init)(struct ksz_device *dev); int (*init)(struct ksz_device *dev);
void (*exit)(struct ksz_device *dev); void (*exit)(struct ksz_device *dev);
......
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