Commit 472fcea1 authored by Christian Marangi's avatar Christian Marangi Committed by Jakub Kicinski

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: default avatarChristian Marangi <ansuelsmth@gmail.com>
Reviewed-by: default avatarVladimir Oltean <olteanv@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent fce1ec0c
......@@ -768,21 +768,6 @@ qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
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)
......@@ -1824,20 +1809,6 @@ static void qca8k_setup_pcs(struct qca8k_priv *priv, struct qca8k_pcs *qpcs,
qpcs->port = port;
}
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;
......@@ -1927,82 +1898,6 @@ qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
return ret;
}
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, &reg);
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)
{
......
......@@ -173,3 +173,105 @@ int qca8k_mib_init(struct qca8k_priv *priv)
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, &reg);
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;
}
......@@ -431,6 +431,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);
......@@ -443,4 +444,14 @@ int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
/* 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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment