diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c index 0d9e63541..b33ab3b97 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c @@ -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);