ramips: mt7530 use lock to protect registers access

This commit is contained in:
lean 2021-09-24 22:12:29 +08:00
parent 6628f88d75
commit cf8d3b6b33

View File

@ -225,6 +225,9 @@ struct mt7530_priv {
struct mii_bus *bus;
struct switch_dev swdev;
/* protect among processes for registers access*/
struct mutex reg_mutex;
u8 mirror_dest_port;
bool global_vlan_enable;
struct mt7530_vlan_entry vlan_entries[MT7530_NUM_VLANS];
@ -399,9 +402,13 @@ mt7530_get_port_pvid(struct switch_dev *dev, int port, int *val)
if (port >= MT7530_NUM_PORTS)
return -EINVAL;
mutex_lock(&priv->reg_mutex);
*val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(port));
*val &= 0xfff;
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -434,6 +441,8 @@ mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS)
return -EINVAL;
mutex_lock(&priv->reg_mutex);
mt7530_vtcr(priv, 0, val->port_vlan);
member = mt7530_r32(priv, REG_ESW_VLAN_VAWD1);
@ -461,6 +470,8 @@ mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
val->port_vlan, i, etag);
}
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -530,6 +541,8 @@ mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
u32 vid;
int vlan;
mutex_lock(&priv->reg_mutex);
vlan = val->port_vlan;
vid = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
@ -538,6 +551,9 @@ mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
vid &= 0xfff;
val->value.i = vid;
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -662,6 +678,8 @@ mt7530_apply_config(struct switch_dev *dev)
u8 untag_ports;
bool is_mirror = false;
mutex_lock(&priv->reg_mutex);
if (!priv->global_vlan_enable) {
for (i = 0; i < MT7530_NUM_PORTS; i++)
mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00400000);
@ -671,6 +689,7 @@ mt7530_apply_config(struct switch_dev *dev)
for (i = 0; i < MT7530_NUM_PORTS; i++)
mt7530_w32(priv, REG_ESW_PORT_PVC(i), 0x810000c0);
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -765,6 +784,8 @@ mt7530_apply_config(struct switch_dev *dev)
mt7530_w32(priv, REG_ESW_WT_MAC_MFC, val);
}
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -778,6 +799,8 @@ mt7530_get_port_link(struct switch_dev *dev, int port,
if (port < 0 || port >= MT7530_NUM_PORTS)
return -EINVAL;
mutex_lock(&priv->reg_mutex);
pmsr = mt7530_r32(priv, 0x3008 + (0x100 * port));
link->link = pmsr & 1;
@ -800,6 +823,8 @@ mt7530_get_port_link(struct switch_dev *dev, int port,
break;
}
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -833,6 +858,8 @@ static int mt7621_sw_get_port_mib(struct switch_dev *dev,
if (val->port_vlan >= MT7530_NUM_PORTS)
return -EINVAL;
mutex_lock(&priv->reg_mutex);
len += snprintf(buf + len, sizeof(buf) - len,
"Port %d MIB counters\n", val->port_vlan);
@ -847,6 +874,9 @@ static int mt7621_sw_get_port_mib(struct switch_dev *dev,
val->value.s = buf;
val->len = len;
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -871,6 +901,8 @@ static int mt7530_sw_get_mib(struct switch_dev *dev,
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
int i, len = 0;
mutex_lock(&priv->reg_mutex);
len += snprintf(buf + len, sizeof(buf) - len, "Switch MIB counters\n");
for (i = 0; i < ARRAY_SIZE(mt7620_mibs); ++i) {
@ -884,6 +916,9 @@ static int mt7530_sw_get_mib(struct switch_dev *dev,
val->value.s = buf;
val->len = len;
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -932,6 +967,8 @@ static int mt7530_get_arl_table(struct switch_dev *dev,
int ret;
u32 atc;
mutex_lock(&priv->reg_mutex);
ret = snprintf(buf, size, "address resolution table\n");
if (ret >= size || ret <= 0) {
priv->arl_buf[0] = 0;
@ -978,6 +1015,8 @@ out:
val->value.s = priv->arl_buf;
val->len = strlen(priv->arl_buf);
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -992,6 +1031,8 @@ static int mt7530_sw_get_port_mib(struct switch_dev *dev,
if (val->port_vlan >= MT7530_NUM_PORTS)
return -EINVAL;
mutex_lock(&priv->reg_mutex);
len += snprintf(buf + len, sizeof(buf) - len,
"Port %d MIB counters\n", val->port_vlan);
@ -1006,6 +1047,9 @@ static int mt7530_sw_get_port_mib(struct switch_dev *dev,
val->value.s = buf;
val->len = len;
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -1017,9 +1061,13 @@ static int mt7530_get_port_stats(struct switch_dev *dev, int port,
if (port < 0 || port >= MT7530_NUM_PORTS)
return -EINVAL;
mutex_lock(&priv->reg_mutex);
stats->tx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_TXB_ID, port);
stats->rx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_RXB_ID, port);
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -1031,9 +1079,13 @@ static int mt7621_get_port_stats(struct switch_dev *dev, int port,
if (port < 0 || port >= MT7530_NUM_PORTS)
return -EINVAL;
mutex_lock(&priv->reg_mutex);
stats->tx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_TXB_ID, port);
stats->rx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_RXB_ID, port);
mutex_unlock(&priv->reg_mutex);
return 0;
}
@ -1201,6 +1253,8 @@ mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vl
mt7530->bus = bus;
mt7530->global_vlan_enable = vlan;
mutex_init(&mt7530->reg_mutex);
swdev = &mt7530->swdev;
if (bus) {
swdev->alias = "mt7530";
@ -1223,10 +1277,10 @@ mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vl
ret = register_switch(swdev, NULL);
if (ret) {
dev_err(dev, "failed to register mt7530\n");
mutex_destroy(&mt7530->reg_mutex);
return ret;
}
map = mt7530_find_mapping(dev->of_node);
if (map)
mt7530_apply_mapping(mt7530, map);