diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c index bed9198603..d34dd3b03b 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c @@ -1163,6 +1163,40 @@ static void rtldsa_update_port_counters(struct rtl838x_switch_priv *priv, int po spin_unlock(&counters->link_stat_lock); } +void rtldsa_counters_lock_register(struct rtl838x_switch_priv *priv, int port) + __acquires(&priv->ports[port].counters.lock) +{ + spin_lock(&priv->ports[port].counters.lock); +} + +void rtldsa_counters_unlock_register(struct rtl838x_switch_priv *priv, int port) + __releases(&priv->ports[port].counters.lock) +{ + spin_unlock(&priv->ports[port].counters.lock); +} + +void rtldsa_counters_lock_table(struct rtl838x_switch_priv *priv, int port __maybe_unused) + __acquires(&priv->counters_lock) +{ + mutex_lock(&priv->counters_lock); +} + +void rtldsa_counters_unlock_table(struct rtl838x_switch_priv *priv, int port __maybe_unused) + __releases(&priv->ports[port].counters.lock) +{ + mutex_unlock(&priv->counters_lock); +} + +static void rtldsa_counters_lock(struct rtl838x_switch_priv *priv, int port) +{ + priv->r->stat_counters_lock(priv, port); +} + +static void rtldsa_counters_unlock(struct rtl838x_switch_priv *priv, int port) +{ + priv->r->stat_counters_unlock(priv, port); +} + static void rtldsa_poll_counters(struct work_struct *work) { struct rtl838x_switch_priv *priv = container_of(to_delayed_work(work), @@ -1173,9 +1207,9 @@ static void rtldsa_poll_counters(struct work_struct *work) if (!priv->ports[i].phy && !priv->pcs[i]) continue; - mutex_lock(&priv->counters_lock); + rtldsa_counters_lock(priv, i); rtldsa_update_port_counters(priv, i); - mutex_unlock(&priv->counters_lock); + rtldsa_counters_unlock(priv, i); } queue_delayed_work(priv->wq, &priv->counters_work, @@ -1193,6 +1227,7 @@ static void rtldsa_init_counters(struct rtl838x_switch_priv *priv) counters = &priv->ports[i].counters; memset(counters, 0, sizeof(*counters)); + spin_lock_init(&counters->lock); spin_lock_init(&counters->link_stat_lock); } @@ -1272,13 +1307,13 @@ static void rtldsa_get_eth_phy_stats(struct dsa_switch *ds, int port, if (!rtldsa_get_mib_desc(priv)) return; - mutex_lock(&priv->counters_lock); + rtldsa_counters_lock(priv, port); rtldsa_update_port_counters(priv, port); phy_stats->SymbolErrorDuringCarrier = counters->symbol_errors.val; - mutex_unlock(&priv->counters_lock); + rtldsa_counters_unlock(priv, port); } static void rtldsa_get_eth_mac_stats(struct dsa_switch *ds, int port, @@ -1293,7 +1328,7 @@ static void rtldsa_get_eth_mac_stats(struct dsa_switch *ds, int port, if (!rtldsa_get_mib_desc(priv)) return; - mutex_lock(&priv->counters_lock); + rtldsa_counters_lock(priv, port); rtldsa_update_port_counters(priv, port); @@ -1327,7 +1362,7 @@ static void rtldsa_get_eth_mac_stats(struct dsa_switch *ds, int port, mac_stats->FrameCheckSequenceErrors = counters->crc_align_errors.val; - mutex_unlock(&priv->counters_lock); + rtldsa_counters_unlock(priv, port); } static void rtldsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port, @@ -1342,13 +1377,13 @@ static void rtldsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port, if (!rtldsa_get_mib_desc(priv)) return; - mutex_lock(&priv->counters_lock); + rtldsa_counters_lock(priv, port); rtldsa_update_port_counters(priv, port); ctrl_stats->UnsupportedOpcodesReceived = counters->unsupported_opcodes.val; - mutex_unlock(&priv->counters_lock); + rtldsa_counters_unlock(priv, port); } static void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port, @@ -1366,7 +1401,7 @@ static void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port, if (!mib_desc) return; - mutex_lock(&priv->counters_lock); + rtldsa_counters_lock(priv, port); rtldsa_update_port_counters(priv, port); @@ -1392,7 +1427,7 @@ static void rtldsa_get_rmon_stats(struct dsa_switch *ds, int port, *ranges = mib_desc->rmon_ranges; - mutex_unlock(&priv->counters_lock); + rtldsa_counters_unlock(priv, port); } static void rtldsa_get_stats64(struct dsa_switch *ds, int port, @@ -1427,14 +1462,14 @@ static void rtldsa_get_pause_stats(struct dsa_switch *ds, int port, if (!rtldsa_get_mib_desc(priv)) return; - mutex_lock(&priv->counters_lock); + rtldsa_counters_lock(priv, port); rtldsa_update_port_counters(priv, port); pause_stats->tx_pause_frames = counters->tx_pause_frames.val; pause_stats->rx_pause_frames = counters->rx_pause_frames.val; - mutex_unlock(&priv->counters_lock); + rtldsa_counters_unlock(priv, port); } static int rtl83xx_mc_group_alloc(struct rtl838x_switch_priv *priv, int port) diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c index 4cecf181bb..c57027ed1d 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c @@ -1673,6 +1673,8 @@ const struct rtl838x_reg rtl838x_reg = { .stat_port_rst = RTL838X_STAT_PORT_RST, .stat_rst = RTL838X_STAT_RST, .stat_port_std_mib = RTL838X_STAT_PORT_STD_MIB, + .stat_counters_lock = rtldsa_counters_lock_register, + .stat_counters_unlock = rtldsa_counters_unlock_register, .port_iso_ctrl = rtl838x_port_iso_ctrl, .traffic_enable = rtl838x_traffic_enable, .traffic_disable = rtl838x_traffic_disable, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h index e3f894ad6d..bca2d8a1f7 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h @@ -710,6 +710,11 @@ struct rtldsa_counter { }; struct rtldsa_counter_state { + /** + * @lock: protect updates to members of the structure when the + * priv->counters_lock is not used. + */ + spinlock_t lock; ktime_t last_update; struct rtldsa_counter symbol_errors; @@ -1122,6 +1127,8 @@ struct rtl838x_reg { int stat_port_std_mib; int stat_port_prv_mib; u64 (*stat_port_table_read)(int port, unsigned int mib_size, unsigned int offset, bool is_pvt); + void (*stat_counters_lock)(struct rtl838x_switch_priv *priv, int port); + void (*stat_counters_unlock)(struct rtl838x_switch_priv *priv, int port); int (*port_iso_ctrl)(int p); void (*traffic_enable)(int source, int dest); void (*traffic_disable)(int source, int dest); @@ -1284,6 +1291,15 @@ struct rtl838x_switch_priv { void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv); void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv); +void rtldsa_counters_lock_register(struct rtl838x_switch_priv *priv, int port) + __acquires(&priv->ports[port].counters.lock); +void rtldsa_counters_unlock_register(struct rtl838x_switch_priv *priv, int port) + __releases(&priv->ports[port].counters.lock); +void rtldsa_counters_lock_table(struct rtl838x_switch_priv *priv, int port) + __acquires(&priv->counters_lock); +void rtldsa_counters_unlock_table(struct rtl838x_switch_priv *priv, int port) + __releases(&priv->ports[port].counters.lock); + extern int rtldsa_max_available_queue[]; extern int rtldsa_default_queue_weights[]; diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c index c98a8c90d4..e3adefcd10 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c @@ -1647,6 +1647,8 @@ const struct rtl838x_reg rtl839x_reg = { .stat_port_rst = RTL839X_STAT_PORT_RST, .stat_rst = RTL839X_STAT_RST, .stat_port_std_mib = RTL839X_STAT_PORT_STD_MIB, + .stat_counters_lock = rtldsa_counters_lock_register, + .stat_counters_unlock = rtldsa_counters_unlock_register, .traffic_enable = rtl839x_traffic_enable, .traffic_disable = rtl839x_traffic_disable, .traffic_set = rtl839x_traffic_set, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c index babb014a90..f835681541 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c @@ -2616,6 +2616,8 @@ const struct rtl838x_reg rtl930x_reg = { .stat_rst = RTL930X_STAT_RST, .stat_port_std_mib = RTL930X_STAT_PORT_MIB_CNTR, .stat_port_prv_mib = RTL930X_STAT_PORT_PRVTE_CNTR, + .stat_counters_lock = rtldsa_counters_lock_register, + .stat_counters_unlock = rtldsa_counters_unlock_register, .traffic_enable = rtl930x_traffic_enable, .traffic_disable = rtl930x_traffic_disable, .traffic_set = rtl930x_traffic_set, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c index 45daf6b0f0..f0817e7f45 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c @@ -1775,6 +1775,8 @@ const struct rtl838x_reg rtl931x_reg = { .stat_rst = RTL931X_STAT_RST, .stat_port_std_mib = 0, /* Not defined */ .stat_port_table_read = rtldsa_931x_stat_port_table_read, + .stat_counters_lock = rtldsa_counters_lock_table, + .stat_counters_unlock = rtldsa_counters_unlock_table, .traffic_enable = rtl931x_traffic_enable, .traffic_disable = rtl931x_traffic_disable, .traffic_set = rtl931x_traffic_set,