mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 06:33:41 +00:00
7ace30aeb6
Backport upstream code split patch for qca8k needed for ipq40xx target to correctly implement a DSA driver. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
282 lines
7.4 KiB
Diff
282 lines
7.4 KiB
Diff
From 472fcea160f27a5d9b7526093d9d8d89ba0b6137 Mon Sep 17 00:00:00 2001
|
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
|
Date: Wed, 27 Jul 2022 13:35:16 +0200
|
|
Subject: [PATCH 07/14] net: dsa: qca8k: move port set status/eee/ethtool stats
|
|
function to common code
|
|
|
|
The same logic to disable/enable port, set eee and get ethtool stats is
|
|
used by drivers based on qca8k family switch.
|
|
Move it to common code to make it accessible also by other drivers.
|
|
While at it also drop unnecessary qca8k_priv cast for void pointers.
|
|
|
|
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
|
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
---
|
|
drivers/net/dsa/qca/qca8k-8xxx.c | 105 -----------------------------
|
|
drivers/net/dsa/qca/qca8k-common.c | 102 ++++++++++++++++++++++++++++
|
|
drivers/net/dsa/qca/qca8k.h | 11 +++
|
|
3 files changed, 113 insertions(+), 105 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
@@ -768,21 +768,6 @@ out:
|
|
return ret;
|
|
}
|
|
|
|
-static void
|
|
-qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
|
|
-{
|
|
- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
|
|
-
|
|
- /* Port 0 and 6 have no internal PHY */
|
|
- if (port > 0 && port < 6)
|
|
- mask |= QCA8K_PORT_STATUS_LINK_AUTO;
|
|
-
|
|
- if (enable)
|
|
- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
|
|
- else
|
|
- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
|
|
-}
|
|
-
|
|
static int
|
|
qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
|
|
struct sk_buff *read_skb, u32 *val)
|
|
@@ -1974,20 +1959,6 @@ qca8k_phylink_mac_link_up(struct dsa_swi
|
|
qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
|
|
}
|
|
|
|
-static void
|
|
-qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data)
|
|
-{
|
|
- struct qca8k_priv *priv = ds->priv;
|
|
- int i;
|
|
-
|
|
- if (stringset != ETH_SS_STATS)
|
|
- return;
|
|
-
|
|
- for (i = 0; i < priv->info->mib_count; i++)
|
|
- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
|
|
- ETH_GSTRING_LEN);
|
|
-}
|
|
-
|
|
static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
|
|
{
|
|
struct qca8k_mib_eth_data *mib_eth_data;
|
|
@@ -2078,82 +2049,6 @@ exit:
|
|
}
|
|
|
|
static void
|
|
-qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
|
|
- uint64_t *data)
|
|
-{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|
- const struct qca8k_mib_desc *mib;
|
|
- u32 reg, i, val;
|
|
- u32 hi = 0;
|
|
- int ret;
|
|
-
|
|
- if (priv->mgmt_master && priv->info->ops->autocast_mib &&
|
|
- priv->info->ops->autocast_mib(ds, port, data) > 0)
|
|
- return;
|
|
-
|
|
- for (i = 0; i < priv->info->mib_count; i++) {
|
|
- mib = &ar8327_mib[i];
|
|
- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
|
|
-
|
|
- ret = qca8k_read(priv, reg, &val);
|
|
- if (ret < 0)
|
|
- continue;
|
|
-
|
|
- if (mib->size == 2) {
|
|
- ret = qca8k_read(priv, reg + 4, &hi);
|
|
- if (ret < 0)
|
|
- continue;
|
|
- }
|
|
-
|
|
- data[i] = val;
|
|
- if (mib->size == 2)
|
|
- data[i] |= (u64)hi << 32;
|
|
- }
|
|
-}
|
|
-
|
|
-static int
|
|
-qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
|
-{
|
|
- struct qca8k_priv *priv = ds->priv;
|
|
-
|
|
- if (sset != ETH_SS_STATS)
|
|
- return 0;
|
|
-
|
|
- return priv->info->mib_count;
|
|
-}
|
|
-
|
|
-static int
|
|
-qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
|
|
-{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|
- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
|
|
- u32 reg;
|
|
- int ret;
|
|
-
|
|
- mutex_lock(&priv->reg_mutex);
|
|
- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®);
|
|
- if (ret < 0)
|
|
- goto exit;
|
|
-
|
|
- if (eee->eee_enabled)
|
|
- reg |= lpi_en;
|
|
- else
|
|
- reg &= ~lpi_en;
|
|
- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
|
|
-
|
|
-exit:
|
|
- mutex_unlock(&priv->reg_mutex);
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static int
|
|
-qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
|
|
-{
|
|
- /* Nothing to do on the port's MAC */
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static void
|
|
qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|
{
|
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|
--- a/drivers/net/dsa/qca/qca8k-common.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-common.c
|
|
@@ -174,3 +174,105 @@ exit:
|
|
mutex_unlock(&priv->reg_mutex);
|
|
return ret;
|
|
}
|
|
+
|
|
+void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
|
|
+{
|
|
+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
|
|
+
|
|
+ /* Port 0 and 6 have no internal PHY */
|
|
+ if (port > 0 && port < 6)
|
|
+ mask |= QCA8K_PORT_STATUS_LINK_AUTO;
|
|
+
|
|
+ if (enable)
|
|
+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
|
|
+ else
|
|
+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
|
|
+}
|
|
+
|
|
+void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset,
|
|
+ uint8_t *data)
|
|
+{
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+ int i;
|
|
+
|
|
+ if (stringset != ETH_SS_STATS)
|
|
+ return;
|
|
+
|
|
+ for (i = 0; i < priv->info->mib_count; i++)
|
|
+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
|
|
+ ETH_GSTRING_LEN);
|
|
+}
|
|
+
|
|
+void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
|
|
+ uint64_t *data)
|
|
+{
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+ const struct qca8k_mib_desc *mib;
|
|
+ u32 reg, i, val;
|
|
+ u32 hi = 0;
|
|
+ int ret;
|
|
+
|
|
+ if (priv->mgmt_master && priv->info->ops->autocast_mib &&
|
|
+ priv->info->ops->autocast_mib(ds, port, data) > 0)
|
|
+ return;
|
|
+
|
|
+ for (i = 0; i < priv->info->mib_count; i++) {
|
|
+ mib = &ar8327_mib[i];
|
|
+ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
|
|
+
|
|
+ ret = qca8k_read(priv, reg, &val);
|
|
+ if (ret < 0)
|
|
+ continue;
|
|
+
|
|
+ if (mib->size == 2) {
|
|
+ ret = qca8k_read(priv, reg + 4, &hi);
|
|
+ if (ret < 0)
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ data[i] = val;
|
|
+ if (mib->size == 2)
|
|
+ data[i] |= (u64)hi << 32;
|
|
+ }
|
|
+}
|
|
+
|
|
+int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
|
+{
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+
|
|
+ if (sset != ETH_SS_STATS)
|
|
+ return 0;
|
|
+
|
|
+ return priv->info->mib_count;
|
|
+}
|
|
+
|
|
+int qca8k_set_mac_eee(struct dsa_switch *ds, int port,
|
|
+ struct ethtool_eee *eee)
|
|
+{
|
|
+ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
+ u32 reg;
|
|
+ int ret;
|
|
+
|
|
+ mutex_lock(&priv->reg_mutex);
|
|
+ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®);
|
|
+ if (ret < 0)
|
|
+ goto exit;
|
|
+
|
|
+ if (eee->eee_enabled)
|
|
+ reg |= lpi_en;
|
|
+ else
|
|
+ reg &= ~lpi_en;
|
|
+ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
|
|
+
|
|
+exit:
|
|
+ mutex_unlock(&priv->reg_mutex);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
|
|
+ struct ethtool_eee *e)
|
|
+{
|
|
+ /* Nothing to do on the port's MAC */
|
|
+ return 0;
|
|
+}
|
|
--- a/drivers/net/dsa/qca/qca8k.h
|
|
+++ b/drivers/net/dsa/qca/qca8k.h
|
|
@@ -423,6 +423,7 @@ struct qca8k_fdb {
|
|
extern const struct qca8k_mib_desc ar8327_mib[];
|
|
extern const struct regmap_access_table qca8k_readable_table;
|
|
int qca8k_mib_init(struct qca8k_priv *priv);
|
|
+void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable);
|
|
|
|
/* Common read/write/rmw function */
|
|
int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val);
|
|
@@ -435,4 +436,14 @@ int qca8k_bulk_write(struct qca8k_priv *
|
|
/* Common ops function */
|
|
int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
|
|
|
|
+/* Common ethtool stats function */
|
|
+void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data);
|
|
+void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
|
|
+ uint64_t *data);
|
|
+int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset);
|
|
+
|
|
+/* Common eee function */
|
|
+int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee);
|
|
+int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
|
|
+
|
|
#endif /* __QCA8K_H */
|