rtldsa_counters_unlock(priv, port);
}
+void rtldsa_update_counters_atomically(struct rtl838x_switch_priv *priv, int port)
+{
+ rtldsa_counters_lock(priv, port);
+ rtldsa_update_port_counters(priv, port);
+ rtldsa_counters_unlock(priv, port);
+}
+
static void rtldsa_get_stats64(struct dsa_switch *ds, int port,
struct rtnl_link_stats64 *s)
{
return;
}
+ if (priv->r->stat_update_counters_atomically)
+ priv->r->stat_update_counters_atomically(priv, port);
+
/* retrieve prepared return data without potentially sleeping via mutex */
spin_lock(&counters->link_stat_lock);
memcpy(s, &counters->link_stat, sizeof(*s));
.stat_port_std_mib = RTL838X_STAT_PORT_STD_MIB,
.stat_counters_lock = rtldsa_counters_lock_register,
.stat_counters_unlock = rtldsa_counters_unlock_register,
+ .stat_update_counters_atomically = rtldsa_update_counters_atomically,
.port_iso_ctrl = rtl838x_port_iso_ctrl,
.traffic_enable = rtl838x_traffic_enable,
.traffic_disable = rtl838x_traffic_disable,
struct rtldsa_counter_state {
/**
* @lock: protect updates to members of the structure when the
- * priv->counters_lock is not used.
+ * priv->counters_lock is not used. (see rtl931x_reg->stat_update_counters_atomically)
*/
spinlock_t lock;
ktime_t last_update;
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);
+
+ /**
+ * @stat_update_counters_atomically: When set, the SoC family allows atomically retrieving
+ * of statistic counters using this function. This function must not require "might_sleep"
+ * code.
+ *
+ * Any SoC family which requires stat_port_table_read must use the table
+ * rtldsa_counters_(un)lock_table helpers. They are using a mutex for locking. The counters
+ * update is therefore not atomic.
+ */
+ void (*stat_update_counters_atomically)(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);
void rtldsa_counters_unlock_table(struct rtl838x_switch_priv *priv, int port)
__releases(&priv->ports[port].counters.lock);
+void rtldsa_update_counters_atomically(struct rtl838x_switch_priv *priv, int port);
+
extern int rtldsa_max_available_queue[];
extern int rtldsa_default_queue_weights[];
.stat_port_std_mib = RTL839X_STAT_PORT_STD_MIB,
.stat_counters_lock = rtldsa_counters_lock_register,
.stat_counters_unlock = rtldsa_counters_unlock_register,
+ .stat_update_counters_atomically = rtldsa_update_counters_atomically,
.traffic_enable = rtl839x_traffic_enable,
.traffic_disable = rtl839x_traffic_disable,
.traffic_set = rtl839x_traffic_set,
.stat_port_prv_mib = RTL930X_STAT_PORT_PRVTE_CNTR,
.stat_counters_lock = rtldsa_counters_lock_register,
.stat_counters_unlock = rtldsa_counters_unlock_register,
+ .stat_update_counters_atomically = rtldsa_update_counters_atomically,
.traffic_enable = rtl930x_traffic_enable,
.traffic_disable = rtl930x_traffic_disable,
.traffic_set = rtl930x_traffic_set,