 7ace30aeb6
			
		
	
	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 */
 |