mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
net: dsa: microchip: move the drive strength config out of the common section
The drive strength configuration is done during the setup of all switches through a common function that then has specific behavior depending on the switch identity. Split the common configuration in two functions: one is dedicated to the KSZ8 family, the other is dedicated to the KSZ9477 family. Remove the drive strength configuration from the lan937x_setup since the LAN937x family doesn't support it. Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com> Link: https://patch.msgid.link/20260702-clean-ksz-4th-v1-10-93441e695fa4@bootlin.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
da466bf62b
commit
90c676dd4b
|
|
@ -36,6 +36,15 @@
|
|||
#include "ksz8_reg.h"
|
||||
#include "ksz8.h"
|
||||
|
||||
/* ksz88x3_drive_strengths - Drive strength mapping for KSZ8863, KSZ8873, ..
|
||||
* variants.
|
||||
* This values are documented in KSZ8873 and KSZ8863 datasheets.
|
||||
*/
|
||||
static const struct ksz_drive_strength ksz88x3_drive_strengths[] = {
|
||||
{ 0, 8000 },
|
||||
{ KSZ8873_DRIVE_STRENGTH_16MA, 16000 },
|
||||
};
|
||||
|
||||
struct ksz88xx_stats_raw {
|
||||
u64 rx;
|
||||
u64 rx_hi;
|
||||
|
|
@ -2291,6 +2300,122 @@ static void ksz88xx_r_mib_stats64(struct ksz_device *dev, int port)
|
|||
spin_unlock(&mib->stats64_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* ksz88x3_drive_strength_write() - Set the drive strength configuration for
|
||||
* KSZ8863 compatible chip variants.
|
||||
* @dev: ksz device
|
||||
* @props: Array of drive strength properties to be set
|
||||
* @num_props: Number of properties in the array
|
||||
*
|
||||
* This function applies the specified drive strength settings to KSZ88X3 chip
|
||||
* variants (KSZ8873, KSZ8863).
|
||||
* It ensures the configurations align with what the chip variant supports and
|
||||
* warns or errors out on unsupported settings.
|
||||
*
|
||||
* Return: 0 on success, error code otherwise
|
||||
*/
|
||||
static int ksz88x3_drive_strength_write(struct ksz_device *dev,
|
||||
struct ksz_driver_strength_prop *props,
|
||||
int num_props)
|
||||
{
|
||||
size_t array_size = ARRAY_SIZE(ksz88x3_drive_strengths);
|
||||
int microamp;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < num_props; i++) {
|
||||
if (props[i].value == -1 || i == KSZ_DRIVER_STRENGTH_IO)
|
||||
continue;
|
||||
|
||||
dev_warn(dev->dev, "%s is not supported by this chip variant\n",
|
||||
props[i].name);
|
||||
}
|
||||
|
||||
microamp = props[KSZ_DRIVER_STRENGTH_IO].value;
|
||||
ret = ksz_drive_strength_to_reg(ksz88x3_drive_strengths, array_size,
|
||||
microamp);
|
||||
if (ret < 0) {
|
||||
ksz_drive_strength_error(dev, ksz88x3_drive_strengths,
|
||||
array_size, microamp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ksz_rmw8(dev, KSZ8873_REG_GLOBAL_CTRL_12,
|
||||
KSZ8873_DRIVE_STRENGTH_16MA, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* ksz8_parse_drive_strength() - Extract and apply drive strength configurations
|
||||
* from device tree properties.
|
||||
* @dev: ksz device
|
||||
*
|
||||
* This function reads the specified drive strength properties from the
|
||||
* device tree, validates against the supported chip variants, and sets
|
||||
* them accordingly. An error should be critical here, as the drive strength
|
||||
* settings are crucial for EMI compliance.
|
||||
*
|
||||
* Return: 0 on success, error code otherwise
|
||||
*/
|
||||
static int ksz8_parse_drive_strength(struct ksz_device *dev)
|
||||
{
|
||||
struct ksz_driver_strength_prop of_props[] = {
|
||||
[KSZ_DRIVER_STRENGTH_HI] = {
|
||||
.name = "microchip,hi-drive-strength-microamp",
|
||||
.offset = SW_HI_SPEED_DRIVE_STRENGTH_S,
|
||||
.value = -1,
|
||||
},
|
||||
[KSZ_DRIVER_STRENGTH_LO] = {
|
||||
.name = "microchip,lo-drive-strength-microamp",
|
||||
.offset = SW_LO_SPEED_DRIVE_STRENGTH_S,
|
||||
.value = -1,
|
||||
},
|
||||
[KSZ_DRIVER_STRENGTH_IO] = {
|
||||
.name = "microchip,io-drive-strength-microamp",
|
||||
.offset = 0, /* don't care */
|
||||
.value = -1,
|
||||
},
|
||||
};
|
||||
struct device_node *np = dev->dev->of_node;
|
||||
bool have_any_prop = false;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(of_props); i++) {
|
||||
ret = of_property_read_u32(np, of_props[i].name,
|
||||
&of_props[i].value);
|
||||
if (ret && ret != -EINVAL)
|
||||
dev_warn(dev->dev, "Failed to read %s\n",
|
||||
of_props[i].name);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
have_any_prop = true;
|
||||
}
|
||||
|
||||
if (!have_any_prop)
|
||||
return 0;
|
||||
|
||||
switch (dev->chip_id) {
|
||||
case KSZ88X3_CHIP_ID:
|
||||
return ksz88x3_drive_strength_write(dev, of_props,
|
||||
ARRAY_SIZE(of_props));
|
||||
case KSZ8795_CHIP_ID:
|
||||
case KSZ8794_CHIP_ID:
|
||||
case KSZ8765_CHIP_ID:
|
||||
return ksz_drive_strength_write(dev, of_props,
|
||||
ARRAY_SIZE(of_props));
|
||||
default:
|
||||
/* KSZ8864, KSZ8895 */
|
||||
for (i = 0; i < ARRAY_SIZE(of_props); i++) {
|
||||
if (of_props[i].value == -1)
|
||||
continue;
|
||||
|
||||
dev_warn(dev->dev, "%s is not supported by this chip variant\n",
|
||||
of_props[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksz8_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
|
|
@ -2313,7 +2438,7 @@ static int ksz8_setup(struct dsa_switch *ds)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = ksz_parse_drive_strength(dev);
|
||||
ret = ksz8_parse_drive_strength(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -1615,6 +1615,58 @@ int ksz9477_enable_stp_addr(struct ksz_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ksz9477_parse_drive_strength() - Extract and apply drive strength
|
||||
* configurations from device tree properties.
|
||||
* @dev: ksz device
|
||||
*
|
||||
* This function reads the specified drive strength properties from the
|
||||
* device tree, validates against the supported chip variants, and sets
|
||||
* them accordingly. An error should be critical here, as the drive strength
|
||||
* settings are crucial for EMI compliance.
|
||||
*
|
||||
* Return: 0 on success, error code otherwise
|
||||
*/
|
||||
static int ksz9477_parse_drive_strength(struct ksz_device *dev)
|
||||
{
|
||||
struct ksz_driver_strength_prop of_props[] = {
|
||||
[KSZ_DRIVER_STRENGTH_HI] = {
|
||||
.name = "microchip,hi-drive-strength-microamp",
|
||||
.offset = SW_HI_SPEED_DRIVE_STRENGTH_S,
|
||||
.value = -1,
|
||||
},
|
||||
[KSZ_DRIVER_STRENGTH_LO] = {
|
||||
.name = "microchip,lo-drive-strength-microamp",
|
||||
.offset = SW_LO_SPEED_DRIVE_STRENGTH_S,
|
||||
.value = -1,
|
||||
},
|
||||
[KSZ_DRIVER_STRENGTH_IO] = {
|
||||
.name = "microchip,io-drive-strength-microamp",
|
||||
.offset = 0, /* don't care */
|
||||
.value = -1,
|
||||
},
|
||||
};
|
||||
struct device_node *np = dev->dev->of_node;
|
||||
bool have_any_prop = false;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(of_props); i++) {
|
||||
ret = of_property_read_u32(np, of_props[i].name,
|
||||
&of_props[i].value);
|
||||
if (ret && ret != -EINVAL)
|
||||
dev_warn(dev->dev, "Failed to read %s\n",
|
||||
of_props[i].name);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
have_any_prop = true;
|
||||
}
|
||||
|
||||
if (!have_any_prop)
|
||||
return 0;
|
||||
|
||||
return ksz_drive_strength_write(dev, of_props, ARRAY_SIZE(of_props));
|
||||
}
|
||||
static int ksz9477_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
|
|
@ -1637,7 +1689,7 @@ static int ksz9477_setup(struct dsa_switch *ds)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = ksz_parse_drive_strength(dev);
|
||||
ret = ksz9477_parse_drive_strength(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -113,28 +113,6 @@ static const struct ksz_mib_names ksz9477_mib_names[] = {
|
|||
{ 0x83, "tx_discards" },
|
||||
};
|
||||
|
||||
struct ksz_driver_strength_prop {
|
||||
const char *name;
|
||||
int offset;
|
||||
int value;
|
||||
};
|
||||
|
||||
enum ksz_driver_strength_type {
|
||||
KSZ_DRIVER_STRENGTH_HI,
|
||||
KSZ_DRIVER_STRENGTH_LO,
|
||||
KSZ_DRIVER_STRENGTH_IO,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ksz_drive_strength - drive strength mapping
|
||||
* @reg_val: register value
|
||||
* @microamp: microamp value
|
||||
*/
|
||||
struct ksz_drive_strength {
|
||||
u32 reg_val;
|
||||
u32 microamp;
|
||||
};
|
||||
|
||||
/* ksz9477_drive_strengths - Drive strength mapping for KSZ9477 variants
|
||||
*
|
||||
* This values are not documented in KSZ9477 variants but confirmed by
|
||||
|
|
@ -170,15 +148,6 @@ static const struct ksz_drive_strength ksz9477_drive_strengths[] = {
|
|||
{ SW_DRIVE_STRENGTH_28MA, 28000 },
|
||||
};
|
||||
|
||||
/* ksz88x3_drive_strengths - Drive strength mapping for KSZ8863, KSZ8873, ..
|
||||
* variants.
|
||||
* This values are documented in KSZ8873 and KSZ8863 datasheets.
|
||||
*/
|
||||
static const struct ksz_drive_strength ksz88x3_drive_strengths[] = {
|
||||
{ 0, 8000 },
|
||||
{ KSZ8873_DRIVE_STRENGTH_16MA, 16000 },
|
||||
};
|
||||
|
||||
/**
|
||||
* ksz_phylink_mac_disable_tx_lpi() - Callback to signal LPI support (Dummy)
|
||||
* @config: phylink config structure
|
||||
|
|
@ -3785,8 +3754,8 @@ static void ksz_parse_rgmii_delay(struct ksz_device *dev, int port_num,
|
|||
* Returns: If found, the corresponding register value for that drive strength
|
||||
* is returned. Otherwise, -EINVAL is returned indicating an invalid value.
|
||||
*/
|
||||
static int ksz_drive_strength_to_reg(const struct ksz_drive_strength *array,
|
||||
size_t array_size, int microamp)
|
||||
int ksz_drive_strength_to_reg(const struct ksz_drive_strength *array,
|
||||
size_t array_size, int microamp)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -3809,9 +3778,9 @@ static int ksz_drive_strength_to_reg(const struct ksz_drive_strength *array,
|
|||
* is detected. It lists out all the supported drive strength values for
|
||||
* reference in the error message.
|
||||
*/
|
||||
static void ksz_drive_strength_error(struct ksz_device *dev,
|
||||
const struct ksz_drive_strength *array,
|
||||
size_t array_size, int microamp)
|
||||
void ksz_drive_strength_error(struct ksz_device *dev,
|
||||
const struct ksz_drive_strength *array,
|
||||
size_t array_size, int microamp)
|
||||
{
|
||||
char supported_values[100];
|
||||
size_t remaining_size;
|
||||
|
|
@ -3850,9 +3819,9 @@ static void ksz_drive_strength_error(struct ksz_device *dev,
|
|||
*
|
||||
* Return: 0 on successful configuration, a negative error code on failure.
|
||||
*/
|
||||
static int ksz_drive_strength_write(struct ksz_device *dev,
|
||||
struct ksz_driver_strength_prop *props,
|
||||
int num_props)
|
||||
int ksz_drive_strength_write(struct ksz_device *dev,
|
||||
struct ksz_driver_strength_prop *props,
|
||||
int num_props)
|
||||
{
|
||||
size_t array_size = ARRAY_SIZE(ksz9477_drive_strengths);
|
||||
int i, ret, reg;
|
||||
|
|
@ -3889,130 +3858,6 @@ static int ksz_drive_strength_write(struct ksz_device *dev,
|
|||
return ksz_rmw8(dev, reg, mask, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* ksz88x3_drive_strength_write() - Set the drive strength configuration for
|
||||
* KSZ8863 compatible chip variants.
|
||||
* @dev: ksz device
|
||||
* @props: Array of drive strength properties to be set
|
||||
* @num_props: Number of properties in the array
|
||||
*
|
||||
* This function applies the specified drive strength settings to KSZ88X3 chip
|
||||
* variants (KSZ8873, KSZ8863).
|
||||
* It ensures the configurations align with what the chip variant supports and
|
||||
* warns or errors out on unsupported settings.
|
||||
*
|
||||
* Return: 0 on success, error code otherwise
|
||||
*/
|
||||
static int ksz88x3_drive_strength_write(struct ksz_device *dev,
|
||||
struct ksz_driver_strength_prop *props,
|
||||
int num_props)
|
||||
{
|
||||
size_t array_size = ARRAY_SIZE(ksz88x3_drive_strengths);
|
||||
int microamp;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < num_props; i++) {
|
||||
if (props[i].value == -1 || i == KSZ_DRIVER_STRENGTH_IO)
|
||||
continue;
|
||||
|
||||
dev_warn(dev->dev, "%s is not supported by this chip variant\n",
|
||||
props[i].name);
|
||||
}
|
||||
|
||||
microamp = props[KSZ_DRIVER_STRENGTH_IO].value;
|
||||
ret = ksz_drive_strength_to_reg(ksz88x3_drive_strengths, array_size,
|
||||
microamp);
|
||||
if (ret < 0) {
|
||||
ksz_drive_strength_error(dev, ksz88x3_drive_strengths,
|
||||
array_size, microamp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ksz_rmw8(dev, KSZ8873_REG_GLOBAL_CTRL_12,
|
||||
KSZ8873_DRIVE_STRENGTH_16MA, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* ksz_parse_drive_strength() - Extract and apply drive strength configurations
|
||||
* from device tree properties.
|
||||
* @dev: ksz device
|
||||
*
|
||||
* This function reads the specified drive strength properties from the
|
||||
* device tree, validates against the supported chip variants, and sets
|
||||
* them accordingly. An error should be critical here, as the drive strength
|
||||
* settings are crucial for EMI compliance.
|
||||
*
|
||||
* Return: 0 on success, error code otherwise
|
||||
*/
|
||||
int ksz_parse_drive_strength(struct ksz_device *dev)
|
||||
{
|
||||
struct ksz_driver_strength_prop of_props[] = {
|
||||
[KSZ_DRIVER_STRENGTH_HI] = {
|
||||
.name = "microchip,hi-drive-strength-microamp",
|
||||
.offset = SW_HI_SPEED_DRIVE_STRENGTH_S,
|
||||
.value = -1,
|
||||
},
|
||||
[KSZ_DRIVER_STRENGTH_LO] = {
|
||||
.name = "microchip,lo-drive-strength-microamp",
|
||||
.offset = SW_LO_SPEED_DRIVE_STRENGTH_S,
|
||||
.value = -1,
|
||||
},
|
||||
[KSZ_DRIVER_STRENGTH_IO] = {
|
||||
.name = "microchip,io-drive-strength-microamp",
|
||||
.offset = 0, /* don't care */
|
||||
.value = -1,
|
||||
},
|
||||
};
|
||||
struct device_node *np = dev->dev->of_node;
|
||||
bool have_any_prop = false;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(of_props); i++) {
|
||||
ret = of_property_read_u32(np, of_props[i].name,
|
||||
&of_props[i].value);
|
||||
if (ret && ret != -EINVAL)
|
||||
dev_warn(dev->dev, "Failed to read %s\n",
|
||||
of_props[i].name);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
have_any_prop = true;
|
||||
}
|
||||
|
||||
if (!have_any_prop)
|
||||
return 0;
|
||||
|
||||
switch (dev->chip_id) {
|
||||
case KSZ88X3_CHIP_ID:
|
||||
return ksz88x3_drive_strength_write(dev, of_props,
|
||||
ARRAY_SIZE(of_props));
|
||||
case KSZ8795_CHIP_ID:
|
||||
case KSZ8794_CHIP_ID:
|
||||
case KSZ8765_CHIP_ID:
|
||||
case KSZ8563_CHIP_ID:
|
||||
case KSZ8567_CHIP_ID:
|
||||
case KSZ9477_CHIP_ID:
|
||||
case KSZ9563_CHIP_ID:
|
||||
case KSZ9567_CHIP_ID:
|
||||
case KSZ9893_CHIP_ID:
|
||||
case KSZ9896_CHIP_ID:
|
||||
case KSZ9897_CHIP_ID:
|
||||
case LAN9646_CHIP_ID:
|
||||
return ksz_drive_strength_write(dev, of_props,
|
||||
ARRAY_SIZE(of_props));
|
||||
default:
|
||||
for (i = 0; i < ARRAY_SIZE(of_props); i++) {
|
||||
if (of_props[i].value == -1)
|
||||
continue;
|
||||
|
||||
dev_warn(dev->dev, "%s is not supported by this chip variant\n",
|
||||
of_props[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksz8463_configure_straps_spi(struct ksz_device *dev)
|
||||
{
|
||||
struct pinctrl *pinctrl;
|
||||
|
|
|
|||
|
|
@ -511,7 +511,37 @@ int ksz_mdio_register(struct ksz_device *dev);
|
|||
int ksz_pirq_setup(struct ksz_device *dev, u8 p);
|
||||
int ksz_girq_setup(struct ksz_device *dev);
|
||||
void ksz_irq_free(struct ksz_irq *kirq);
|
||||
int ksz_parse_drive_strength(struct ksz_device *dev);
|
||||
|
||||
struct ksz_driver_strength_prop {
|
||||
const char *name;
|
||||
int offset;
|
||||
int value;
|
||||
};
|
||||
|
||||
enum ksz_driver_strength_type {
|
||||
KSZ_DRIVER_STRENGTH_HI,
|
||||
KSZ_DRIVER_STRENGTH_LO,
|
||||
KSZ_DRIVER_STRENGTH_IO,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ksz_drive_strength - drive strength mapping
|
||||
* @reg_val: register value
|
||||
* @microamp: microamp value
|
||||
*/
|
||||
struct ksz_drive_strength {
|
||||
u32 reg_val;
|
||||
u32 microamp;
|
||||
};
|
||||
|
||||
void ksz_drive_strength_error(struct ksz_device *dev,
|
||||
const struct ksz_drive_strength *array,
|
||||
size_t array_size, int microamp);
|
||||
int ksz_drive_strength_to_reg(const struct ksz_drive_strength *array,
|
||||
size_t array_size, int microamp);
|
||||
int ksz_drive_strength_write(struct ksz_device *dev,
|
||||
struct ksz_driver_strength_prop *props,
|
||||
int num_props);
|
||||
|
||||
/* Common register access functions */
|
||||
static inline struct regmap *ksz_regmap_8(struct ksz_device *dev)
|
||||
|
|
|
|||
|
|
@ -787,10 +787,6 @@ static int lan937x_setup(struct dsa_switch *ds)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = ksz_parse_drive_strength(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* set broadcast storm protection 10% rate */
|
||||
storm_mask = BROADCAST_STORM_RATE;
|
||||
storm_rate = (BROADCAST_STORM_VALUE * BROADCAST_STORM_PROT_RATE) / 100;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user