Commit 7fa28bc6 authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'microchip-dsa-driver-improvements'

Oleksij Rempel says:

====================
Microchip DSA Driver Improvements

changes v2:
- set .max_register = U8_MAX, it should be more readable
- clarify in the RMW error handling patch, logging behavior
  expectation.

I'd like to share a set of patches for the Microchip DSA driver. These
patches were chosen from a bigger set because they are simpler and
should be easier to review. The goal is to make the code easier to read,
get rid of unused code, and handle errors better.
====================

Link: https://lore.kernel.org/r/20230526073445.668430-1-o.rempel@pengutronix.deSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents eee2e03c d0dec333
...@@ -28,13 +28,13 @@ ...@@ -28,13 +28,13 @@
static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set) static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
{ {
regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0); regmap_update_bits(ksz_regmap_8(dev), addr, bits, set ? bits : 0);
} }
static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits, static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
bool set) bool set)
{ {
regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset), regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset),
bits, set ? bits : 0); bits, set ? bits : 0);
} }
...@@ -941,7 +941,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) ...@@ -941,7 +941,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
{ {
u8 learn[DSA_MAX_PORTS]; u8 learn[DSA_MAX_PORTS];
int first, index, cnt; int first, index, cnt;
struct ksz_port *p;
const u16 *regs; const u16 *regs;
regs = dev->info->regs; regs = dev->info->regs;
...@@ -955,9 +954,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) ...@@ -955,9 +954,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
cnt = dev->info->port_cnt; cnt = dev->info->port_cnt;
} }
for (index = first; index < cnt; index++) { for (index = first; index < cnt; index++) {
p = &dev->ports[index];
if (!p->on)
continue;
ksz_pread8(dev, index, regs[P_STP_CTRL], &learn[index]); ksz_pread8(dev, index, regs[P_STP_CTRL], &learn[index]);
if (!(learn[index] & PORT_LEARN_DISABLE)) if (!(learn[index] & PORT_LEARN_DISABLE))
ksz_pwrite8(dev, index, regs[P_STP_CTRL], ksz_pwrite8(dev, index, regs[P_STP_CTRL],
...@@ -965,9 +961,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) ...@@ -965,9 +961,6 @@ void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
} }
ksz_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_DYN_MAC_TABLE, true); ksz_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_DYN_MAC_TABLE, true);
for (index = first; index < cnt; index++) { for (index = first; index < cnt; index++) {
p = &dev->ports[index];
if (!p->on)
continue;
if (!(learn[index] & PORT_LEARN_DISABLE)) if (!(learn[index] & PORT_LEARN_DISABLE))
ksz_pwrite8(dev, index, regs[P_STP_CTRL], learn[index]); ksz_pwrite8(dev, index, regs[P_STP_CTRL], learn[index]);
} }
...@@ -1338,25 +1331,14 @@ void ksz8_config_cpu_port(struct dsa_switch *ds) ...@@ -1338,25 +1331,14 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)
ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true); ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true);
p = &dev->ports[dev->cpu_port];
p->on = 1;
ksz8_port_setup(dev, dev->cpu_port, true); ksz8_port_setup(dev, dev->cpu_port, true);
for (i = 0; i < dev->phy_port_cnt; i++) { for (i = 0; i < dev->phy_port_cnt; i++) {
p = &dev->ports[i];
ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED); ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED);
/* Last port may be disabled. */
if (i == dev->phy_port_cnt)
break;
p->on = 1;
} }
for (i = 0; i < dev->phy_port_cnt; i++) { for (i = 0; i < dev->phy_port_cnt; i++) {
p = &dev->ports[i]; p = &dev->ports[i];
if (!p->on)
continue;
if (!ksz_is_ksz88x3(dev)) { if (!ksz_is_ksz88x3(dev)) {
ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote); ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote);
if (remote & KSZ8_PORT_FIBER_MODE) if (remote & KSZ8_PORT_FIBER_MODE)
...@@ -1425,14 +1407,14 @@ int ksz8_setup(struct dsa_switch *ds) ...@@ -1425,14 +1407,14 @@ int ksz8_setup(struct dsa_switch *ds)
ksz_cfg(dev, S_LINK_AGING_CTRL, SW_LINK_AUTO_AGING, true); ksz_cfg(dev, S_LINK_AGING_CTRL, SW_LINK_AUTO_AGING, true);
/* Enable aggressive back off algorithm in half duplex mode. */ /* Enable aggressive back off algorithm in half duplex mode. */
regmap_update_bits(dev->regmap[0], REG_SW_CTRL_1, regmap_update_bits(ksz_regmap_8(dev), REG_SW_CTRL_1,
SW_AGGR_BACKOFF, SW_AGGR_BACKOFF); SW_AGGR_BACKOFF, SW_AGGR_BACKOFF);
/* /*
* Make sure unicast VLAN boundary is set as default and * Make sure unicast VLAN boundary is set as default and
* enable no excessive collision drop. * enable no excessive collision drop.
*/ */
regmap_update_bits(dev->regmap[0], REG_SW_CTRL_2, regmap_update_bits(ksz_regmap_8(dev), REG_SW_CTRL_2,
UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP, UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP,
UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP); UNICAST_VLAN_BOUNDARY | NO_EXC_COLLISION_DROP);
......
...@@ -104,6 +104,7 @@ static const struct regmap_config ksz8863_regmap_config[] = { ...@@ -104,6 +104,7 @@ static const struct regmap_config ksz8863_regmap_config[] = {
.cache_type = REGCACHE_NONE, .cache_type = REGCACHE_NONE,
.lock = ksz_regmap_lock, .lock = ksz_regmap_lock,
.unlock = ksz_regmap_unlock, .unlock = ksz_regmap_unlock,
.max_register = U8_MAX,
}, },
{ {
.name = "#16", .name = "#16",
...@@ -113,6 +114,7 @@ static const struct regmap_config ksz8863_regmap_config[] = { ...@@ -113,6 +114,7 @@ static const struct regmap_config ksz8863_regmap_config[] = {
.cache_type = REGCACHE_NONE, .cache_type = REGCACHE_NONE,
.lock = ksz_regmap_lock, .lock = ksz_regmap_lock,
.unlock = ksz_regmap_unlock, .unlock = ksz_regmap_unlock,
.max_register = U8_MAX,
}, },
{ {
.name = "#32", .name = "#32",
...@@ -122,11 +124,14 @@ static const struct regmap_config ksz8863_regmap_config[] = { ...@@ -122,11 +124,14 @@ static const struct regmap_config ksz8863_regmap_config[] = {
.cache_type = REGCACHE_NONE, .cache_type = REGCACHE_NONE,
.lock = ksz_regmap_lock, .lock = ksz_regmap_lock,
.unlock = ksz_regmap_unlock, .unlock = ksz_regmap_unlock,
.max_register = U8_MAX,
} }
}; };
static int ksz8863_smi_probe(struct mdio_device *mdiodev) static int ksz8863_smi_probe(struct mdio_device *mdiodev)
{ {
struct device *ddev = &mdiodev->dev;
const struct ksz_chip_data *chip;
struct regmap_config rc; struct regmap_config rc;
struct ksz_device *dev; struct ksz_device *dev;
int ret; int ret;
...@@ -136,9 +141,15 @@ static int ksz8863_smi_probe(struct mdio_device *mdiodev) ...@@ -136,9 +141,15 @@ static int ksz8863_smi_probe(struct mdio_device *mdiodev)
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(ksz8863_regmap_config); i++) { chip = device_get_match_data(ddev);
if (!chip)
return -EINVAL;
for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
rc = ksz8863_regmap_config[i]; rc = ksz8863_regmap_config[i];
rc.lock_arg = &dev->regmap_mutex; rc.lock_arg = &dev->regmap_mutex;
rc.wr_table = chip->wr_table;
rc.rd_table = chip->rd_table;
dev->regmap[i] = devm_regmap_init(&mdiodev->dev, dev->regmap[i] = devm_regmap_init(&mdiodev->dev,
&regmap_smi[i], dev, &regmap_smi[i], dev,
&rc); &rc);
......
...@@ -21,25 +21,25 @@ ...@@ -21,25 +21,25 @@
static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set) static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
{ {
regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0); regmap_update_bits(ksz_regmap_8(dev), addr, bits, set ? bits : 0);
} }
static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits, static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
bool set) bool set)
{ {
regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset), regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset),
bits, set ? bits : 0); bits, set ? bits : 0);
} }
static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set) static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
{ {
regmap_update_bits(dev->regmap[2], addr, bits, set ? bits : 0); regmap_update_bits(ksz_regmap_32(dev), addr, bits, set ? bits : 0);
} }
static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset, static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,
u32 bits, bool set) u32 bits, bool set)
{ {
regmap_update_bits(dev->regmap[2], PORT_CTRL_ADDR(port, offset), regmap_update_bits(ksz_regmap_32(dev), PORT_CTRL_ADDR(port, offset),
bits, set ? bits : 0); bits, set ? bits : 0);
} }
...@@ -52,7 +52,7 @@ int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu) ...@@ -52,7 +52,7 @@ int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu)
frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
return regmap_update_bits(dev->regmap[1], REG_SW_MTU__2, return regmap_update_bits(ksz_regmap_16(dev), REG_SW_MTU__2,
REG_SW_MTU_MASK, frame_size); REG_SW_MTU_MASK, frame_size);
} }
...@@ -60,7 +60,7 @@ static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev) ...@@ -60,7 +60,7 @@ static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev)
{ {
unsigned int val; unsigned int val;
return regmap_read_poll_timeout(dev->regmap[0], REG_SW_VLAN_CTRL, return regmap_read_poll_timeout(ksz_regmap_8(dev), REG_SW_VLAN_CTRL,
val, !(val & VLAN_START), 10, 1000); val, !(val & VLAN_START), 10, 1000);
} }
...@@ -147,7 +147,7 @@ static int ksz9477_wait_alu_ready(struct ksz_device *dev) ...@@ -147,7 +147,7 @@ static int ksz9477_wait_alu_ready(struct ksz_device *dev)
{ {
unsigned int val; unsigned int val;
return regmap_read_poll_timeout(dev->regmap[2], REG_SW_ALU_CTRL__4, return regmap_read_poll_timeout(ksz_regmap_32(dev), REG_SW_ALU_CTRL__4,
val, !(val & ALU_START), 10, 1000); val, !(val & ALU_START), 10, 1000);
} }
...@@ -155,7 +155,7 @@ static int ksz9477_wait_alu_sta_ready(struct ksz_device *dev) ...@@ -155,7 +155,7 @@ static int ksz9477_wait_alu_sta_ready(struct ksz_device *dev)
{ {
unsigned int val; unsigned int val;
return regmap_read_poll_timeout(dev->regmap[2], return regmap_read_poll_timeout(ksz_regmap_32(dev),
REG_SW_ALU_STAT_CTRL__4, REG_SW_ALU_STAT_CTRL__4,
val, !(val & ALU_STAT_START), val, !(val & ALU_STAT_START),
10, 1000); 10, 1000);
...@@ -170,7 +170,7 @@ int ksz9477_reset_switch(struct ksz_device *dev) ...@@ -170,7 +170,7 @@ int ksz9477_reset_switch(struct ksz_device *dev)
ksz_cfg(dev, REG_SW_OPERATION, SW_RESET, true); ksz_cfg(dev, REG_SW_OPERATION, SW_RESET, true);
/* turn off SPI DO Edge select */ /* turn off SPI DO Edge select */
regmap_update_bits(dev->regmap[0], REG_SW_GLOBAL_SERIAL_CTRL_0, regmap_update_bits(ksz_regmap_8(dev), REG_SW_GLOBAL_SERIAL_CTRL_0,
SPI_AUTO_EDGE_DETECTION, 0); SPI_AUTO_EDGE_DETECTION, 0);
/* default configuration */ /* default configuration */
...@@ -213,7 +213,7 @@ void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt) ...@@ -213,7 +213,7 @@ void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt)
data |= (addr << MIB_COUNTER_INDEX_S); data |= (addr << MIB_COUNTER_INDEX_S);
ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data); ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
ret = regmap_read_poll_timeout(dev->regmap[2], ret = regmap_read_poll_timeout(ksz_regmap_32(dev),
PORT_CTRL_ADDR(port, REG_PORT_MIB_CTRL_STAT__4), PORT_CTRL_ADDR(port, REG_PORT_MIB_CTRL_STAT__4),
val, !(val & MIB_COUNTER_READ), 10, 1000); val, !(val & MIB_COUNTER_READ), 10, 1000);
/* failed to read MIB. get out of loop */ /* failed to read MIB. get out of loop */
...@@ -346,7 +346,7 @@ void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) ...@@ -346,7 +346,7 @@ void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
const u16 *regs = dev->info->regs; const u16 *regs = dev->info->regs;
u8 data; u8 data;
regmap_update_bits(dev->regmap[0], REG_SW_LUE_CTRL_2, regmap_update_bits(ksz_regmap_8(dev), REG_SW_LUE_CTRL_2,
SW_FLUSH_OPTION_M << SW_FLUSH_OPTION_S, SW_FLUSH_OPTION_M << SW_FLUSH_OPTION_S,
SW_FLUSH_OPTION_DYN_MAC << SW_FLUSH_OPTION_S); SW_FLUSH_OPTION_DYN_MAC << SW_FLUSH_OPTION_S);
...@@ -1165,7 +1165,7 @@ int ksz9477_setup(struct dsa_switch *ds) ...@@ -1165,7 +1165,7 @@ int ksz9477_setup(struct dsa_switch *ds)
ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_JUMBO_PACKET, true); ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_JUMBO_PACKET, true);
/* Now we can configure default MTU value */ /* Now we can configure default MTU value */
ret = regmap_update_bits(dev->regmap[1], REG_SW_MTU__2, REG_SW_MTU_MASK, ret = regmap_update_bits(ksz_regmap_16(dev), REG_SW_MTU__2, REG_SW_MTU_MASK,
VLAN_ETH_FRAME_LEN + ETH_FCS_LEN); VLAN_ETH_FRAME_LEN + ETH_FCS_LEN);
if (ret) if (ret)
return ret; return ret;
......
...@@ -24,7 +24,7 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c) ...@@ -24,7 +24,7 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c)
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_config); i++) { for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
rc = ksz9477_regmap_config[i]; rc = ksz9477_regmap_config[i];
rc.lock_arg = &dev->regmap_mutex; rc.lock_arg = &dev->regmap_mutex;
dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc); dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc);
......
...@@ -1075,6 +1075,45 @@ static const struct regmap_access_table ksz9896_register_set = { ...@@ -1075,6 +1075,45 @@ static const struct regmap_access_table ksz9896_register_set = {
.n_yes_ranges = ARRAY_SIZE(ksz9896_valid_regs), .n_yes_ranges = ARRAY_SIZE(ksz9896_valid_regs),
}; };
static const struct regmap_range ksz8873_valid_regs[] = {
regmap_reg_range(0x00, 0x01),
/* global control register */
regmap_reg_range(0x02, 0x0f),
/* port registers */
regmap_reg_range(0x10, 0x1d),
regmap_reg_range(0x1e, 0x1f),
regmap_reg_range(0x20, 0x2d),
regmap_reg_range(0x2e, 0x2f),
regmap_reg_range(0x30, 0x39),
regmap_reg_range(0x3f, 0x3f),
/* advanced control registers */
regmap_reg_range(0x60, 0x6f),
regmap_reg_range(0x70, 0x75),
regmap_reg_range(0x76, 0x78),
regmap_reg_range(0x79, 0x7a),
regmap_reg_range(0x7b, 0x83),
regmap_reg_range(0x8e, 0x99),
regmap_reg_range(0x9a, 0xa5),
regmap_reg_range(0xa6, 0xa6),
regmap_reg_range(0xa7, 0xaa),
regmap_reg_range(0xab, 0xae),
regmap_reg_range(0xaf, 0xba),
regmap_reg_range(0xbb, 0xbc),
regmap_reg_range(0xbd, 0xbd),
regmap_reg_range(0xc0, 0xc0),
regmap_reg_range(0xc2, 0xc2),
regmap_reg_range(0xc3, 0xc3),
regmap_reg_range(0xc4, 0xc4),
regmap_reg_range(0xc6, 0xc6),
};
static const struct regmap_access_table ksz8873_register_set = {
.yes_ranges = ksz8873_valid_regs,
.n_yes_ranges = ARRAY_SIZE(ksz8873_valid_regs),
};
const struct ksz_chip_data ksz_switch_chips[] = { const struct ksz_chip_data ksz_switch_chips[] = {
[KSZ8563] = { [KSZ8563] = {
.chip_id = KSZ8563_CHIP_ID, .chip_id = KSZ8563_CHIP_ID,
...@@ -1214,6 +1253,8 @@ const struct ksz_chip_data ksz_switch_chips[] = { ...@@ -1214,6 +1253,8 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.supports_mii = {false, false, true}, .supports_mii = {false, false, true},
.supports_rmii = {false, false, true}, .supports_rmii = {false, false, true},
.internal_phy = {true, true, false}, .internal_phy = {true, true, false},
.wr_table = &ksz8873_register_set,
.rd_table = &ksz8873_register_set,
}, },
[KSZ9477] = { [KSZ9477] = {
...@@ -2095,7 +2136,7 @@ static int ksz_setup(struct dsa_switch *ds) ...@@ -2095,7 +2136,7 @@ static int ksz_setup(struct dsa_switch *ds)
} }
/* set broadcast storm protection 10% rate */ /* set broadcast storm protection 10% rate */
regmap_update_bits(dev->regmap[1], regs[S_BROADCAST_CTRL], regmap_update_bits(ksz_regmap_16(dev), regs[S_BROADCAST_CTRL],
BROADCAST_STORM_RATE, BROADCAST_STORM_RATE,
(BROADCAST_STORM_VALUE * (BROADCAST_STORM_VALUE *
BROADCAST_STORM_PROT_RATE) / 100); BROADCAST_STORM_PROT_RATE) / 100);
...@@ -2106,7 +2147,7 @@ static int ksz_setup(struct dsa_switch *ds) ...@@ -2106,7 +2147,7 @@ static int ksz_setup(struct dsa_switch *ds)
ds->num_tx_queues = dev->info->num_tx_queues; ds->num_tx_queues = dev->info->num_tx_queues;
regmap_update_bits(dev->regmap[0], regs[S_MULTICAST_CTRL], regmap_update_bits(ksz_regmap_8(dev), regs[S_MULTICAST_CTRL],
MULTICAST_STORM_DISABLE, MULTICAST_STORM_DISABLE); MULTICAST_STORM_DISABLE, MULTICAST_STORM_DISABLE);
ksz_init_mib_timer(dev); ksz_init_mib_timer(dev);
...@@ -2156,7 +2197,7 @@ static int ksz_setup(struct dsa_switch *ds) ...@@ -2156,7 +2197,7 @@ static int ksz_setup(struct dsa_switch *ds)
} }
/* start switch */ /* start switch */
regmap_update_bits(dev->regmap[0], regs[S_START_CTRL], regmap_update_bits(ksz_regmap_8(dev), regs[S_START_CTRL],
SW_START, SW_START); SW_START, SW_START);
return 0; return 0;
......
...@@ -22,6 +22,13 @@ ...@@ -22,6 +22,13 @@
struct ksz_device; struct ksz_device;
struct ksz_port; struct ksz_port;
enum ksz_regmap_width {
KSZ_REGMAP_8,
KSZ_REGMAP_16,
KSZ_REGMAP_32,
__KSZ_NUM_REGMAPS,
};
struct vlan_table { struct vlan_table {
u32 table[3]; u32 table[3];
}; };
...@@ -101,7 +108,6 @@ struct ksz_port { ...@@ -101,7 +108,6 @@ struct ksz_port {
int stp_state; int stp_state;
struct phy_device phydev; struct phy_device phydev;
u32 on:1; /* port is not disabled by hardware */
u32 fiber:1; /* port is fiber */ u32 fiber:1; /* port is fiber */
u32 force:1; u32 force:1;
u32 read:1; /* read MIB counters in background */ u32 read:1; /* read MIB counters in background */
...@@ -137,7 +143,7 @@ struct ksz_device { ...@@ -137,7 +143,7 @@ struct ksz_device {
const struct ksz_dev_ops *dev_ops; const struct ksz_dev_ops *dev_ops;
struct device *dev; struct device *dev;
struct regmap *regmap[3]; struct regmap *regmap[__KSZ_NUM_REGMAPS];
void *priv; void *priv;
int irq; int irq;
...@@ -377,11 +383,25 @@ phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit); ...@@ -377,11 +383,25 @@ phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit);
extern const struct ksz_chip_data ksz_switch_chips[]; extern const struct ksz_chip_data ksz_switch_chips[];
/* Common register access functions */ /* Common register access functions */
static inline struct regmap *ksz_regmap_8(struct ksz_device *dev)
{
return dev->regmap[KSZ_REGMAP_8];
}
static inline struct regmap *ksz_regmap_16(struct ksz_device *dev)
{
return dev->regmap[KSZ_REGMAP_16];
}
static inline struct regmap *ksz_regmap_32(struct ksz_device *dev)
{
return dev->regmap[KSZ_REGMAP_32];
}
static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val)
{ {
unsigned int value; unsigned int value;
int ret = regmap_read(dev->regmap[0], reg, &value); int ret = regmap_read(ksz_regmap_8(dev), reg, &value);
if (ret) if (ret)
dev_err(dev->dev, "can't read 8bit reg: 0x%x %pe\n", reg, dev_err(dev->dev, "can't read 8bit reg: 0x%x %pe\n", reg,
...@@ -394,7 +414,7 @@ static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) ...@@ -394,7 +414,7 @@ static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val)
static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val)
{ {
unsigned int value; unsigned int value;
int ret = regmap_read(dev->regmap[1], reg, &value); int ret = regmap_read(ksz_regmap_16(dev), reg, &value);
if (ret) if (ret)
dev_err(dev->dev, "can't read 16bit reg: 0x%x %pe\n", reg, dev_err(dev->dev, "can't read 16bit reg: 0x%x %pe\n", reg,
...@@ -407,7 +427,7 @@ static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) ...@@ -407,7 +427,7 @@ static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val)
static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val) static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val)
{ {
unsigned int value; unsigned int value;
int ret = regmap_read(dev->regmap[2], reg, &value); int ret = regmap_read(ksz_regmap_32(dev), reg, &value);
if (ret) if (ret)
dev_err(dev->dev, "can't read 32bit reg: 0x%x %pe\n", reg, dev_err(dev->dev, "can't read 32bit reg: 0x%x %pe\n", reg,
...@@ -422,7 +442,7 @@ static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) ...@@ -422,7 +442,7 @@ static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val)
u32 value[2]; u32 value[2];
int ret; int ret;
ret = regmap_bulk_read(dev->regmap[2], reg, value, 2); ret = regmap_bulk_read(ksz_regmap_32(dev), reg, value, 2);
if (ret) if (ret)
dev_err(dev->dev, "can't read 64bit reg: 0x%x %pe\n", reg, dev_err(dev->dev, "can't read 64bit reg: 0x%x %pe\n", reg,
ERR_PTR(ret)); ERR_PTR(ret));
...@@ -436,7 +456,7 @@ static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value) ...@@ -436,7 +456,7 @@ static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value)
{ {
int ret; int ret;
ret = regmap_write(dev->regmap[0], reg, value); ret = regmap_write(ksz_regmap_8(dev), reg, value);
if (ret) if (ret)
dev_err(dev->dev, "can't write 8bit reg: 0x%x %pe\n", reg, dev_err(dev->dev, "can't write 8bit reg: 0x%x %pe\n", reg,
ERR_PTR(ret)); ERR_PTR(ret));
...@@ -448,7 +468,7 @@ static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value) ...@@ -448,7 +468,7 @@ static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value)
{ {
int ret; int ret;
ret = regmap_write(dev->regmap[1], reg, value); ret = regmap_write(ksz_regmap_16(dev), reg, value);
if (ret) if (ret)
dev_err(dev->dev, "can't write 16bit reg: 0x%x %pe\n", reg, dev_err(dev->dev, "can't write 16bit reg: 0x%x %pe\n", reg,
ERR_PTR(ret)); ERR_PTR(ret));
...@@ -460,7 +480,7 @@ static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value) ...@@ -460,7 +480,7 @@ static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value)
{ {
int ret; int ret;
ret = regmap_write(dev->regmap[2], reg, value); ret = regmap_write(ksz_regmap_32(dev), reg, value);
if (ret) if (ret)
dev_err(dev->dev, "can't write 32bit reg: 0x%x %pe\n", reg, dev_err(dev->dev, "can't write 32bit reg: 0x%x %pe\n", reg,
ERR_PTR(ret)); ERR_PTR(ret));
...@@ -473,7 +493,7 @@ static inline int ksz_rmw16(struct ksz_device *dev, u32 reg, u16 mask, ...@@ -473,7 +493,7 @@ static inline int ksz_rmw16(struct ksz_device *dev, u32 reg, u16 mask,
{ {
int ret; int ret;
ret = regmap_update_bits(dev->regmap[1], reg, mask, value); ret = regmap_update_bits(ksz_regmap_16(dev), reg, mask, value);
if (ret) if (ret)
dev_err(dev->dev, "can't rmw 16bit reg 0x%x: %pe\n", reg, dev_err(dev->dev, "can't rmw 16bit reg 0x%x: %pe\n", reg,
ERR_PTR(ret)); ERR_PTR(ret));
...@@ -486,7 +506,7 @@ static inline int ksz_rmw32(struct ksz_device *dev, u32 reg, u32 mask, ...@@ -486,7 +506,7 @@ static inline int ksz_rmw32(struct ksz_device *dev, u32 reg, u32 mask,
{ {
int ret; int ret;
ret = regmap_update_bits(dev->regmap[2], reg, mask, value); ret = regmap_update_bits(ksz_regmap_32(dev), reg, mask, value);
if (ret) if (ret)
dev_err(dev->dev, "can't rmw 32bit reg 0x%x: %pe\n", reg, dev_err(dev->dev, "can't rmw 32bit reg 0x%x: %pe\n", reg,
ERR_PTR(ret)); ERR_PTR(ret));
...@@ -503,12 +523,19 @@ static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value) ...@@ -503,12 +523,19 @@ static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value)
val[0] = swab32(value & 0xffffffffULL); val[0] = swab32(value & 0xffffffffULL);
val[1] = swab32(value >> 32ULL); val[1] = swab32(value >> 32ULL);
return regmap_bulk_write(dev->regmap[2], reg, val, 2); return regmap_bulk_write(ksz_regmap_32(dev), reg, val, 2);
} }
static inline int ksz_rmw8(struct ksz_device *dev, int offset, u8 mask, u8 val) static inline int ksz_rmw8(struct ksz_device *dev, int offset, u8 mask, u8 val)
{ {
return regmap_update_bits(dev->regmap[0], offset, mask, val); int ret;
ret = regmap_update_bits(ksz_regmap_8(dev), offset, mask, val);
if (ret)
dev_err(dev->dev, "can't rmw 8bit reg 0x%x: %pe\n", offset,
ERR_PTR(ret));
return ret;
} }
static inline int ksz_pread8(struct ksz_device *dev, int port, int offset, static inline int ksz_pread8(struct ksz_device *dev, int port, int offset,
...@@ -549,12 +576,20 @@ static inline int ksz_pwrite32(struct ksz_device *dev, int port, int offset, ...@@ -549,12 +576,20 @@ static inline int ksz_pwrite32(struct ksz_device *dev, int port, int offset,
data); data);
} }
static inline void ksz_prmw8(struct ksz_device *dev, int port, int offset, static inline int ksz_prmw8(struct ksz_device *dev, int port, int offset,
u8 mask, u8 val) u8 mask, u8 val)
{ {
regmap_update_bits(dev->regmap[0], int ret;
dev->dev_ops->get_port_addr(port, offset),
mask, val); ret = regmap_update_bits(ksz_regmap_8(dev),
dev->dev_ops->get_port_addr(port, offset),
mask, val);
if (ret)
dev_err(dev->dev, "can't rmw 8bit reg 0x%x: %pe\n",
dev->dev_ops->get_port_addr(port, offset),
ERR_PTR(ret));
return ret;
} }
static inline void ksz_regmap_lock(void *__mtx) static inline void ksz_regmap_lock(void *__mtx)
...@@ -709,9 +744,9 @@ static inline int is_lan937x(struct ksz_device *dev) ...@@ -709,9 +744,9 @@ static inline int is_lan937x(struct ksz_device *dev)
#define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \ #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \
static const struct regmap_config ksz##_regmap_config[] = { \ static const struct regmap_config ksz##_regmap_config[] = { \
KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \ [KSZ_REGMAP_8] = KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \
KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \ [KSZ_REGMAP_16] = KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \
KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \ [KSZ_REGMAP_32] = KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \
} }
#endif #endif
...@@ -63,7 +63,7 @@ static int ksz_spi_probe(struct spi_device *spi) ...@@ -63,7 +63,7 @@ static int ksz_spi_probe(struct spi_device *spi)
else else
regmap_config = ksz9477_regmap_config; regmap_config = ksz9477_regmap_config;
for (i = 0; i < ARRAY_SIZE(ksz8795_regmap_config); i++) { for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
rc = regmap_config[i]; rc = regmap_config[i];
rc.lock_arg = &dev->regmap_mutex; rc.lock_arg = &dev->regmap_mutex;
rc.wr_table = chip->wr_table; rc.wr_table = chip->wr_table;
......
...@@ -20,13 +20,13 @@ ...@@ -20,13 +20,13 @@
static int lan937x_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set) static int lan937x_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set)
{ {
return regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0); return regmap_update_bits(ksz_regmap_8(dev), addr, bits, set ? bits : 0);
} }
static int lan937x_port_cfg(struct ksz_device *dev, int port, int offset, static int lan937x_port_cfg(struct ksz_device *dev, int port, int offset,
u8 bits, bool set) u8 bits, bool set)
{ {
return regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset), return regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset),
bits, set ? bits : 0); bits, set ? bits : 0);
} }
...@@ -86,7 +86,7 @@ static int lan937x_internal_phy_write(struct ksz_device *dev, int addr, int reg, ...@@ -86,7 +86,7 @@ static int lan937x_internal_phy_write(struct ksz_device *dev, int addr, int reg,
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = regmap_read_poll_timeout(dev->regmap[1], REG_VPHY_IND_CTRL__2, ret = regmap_read_poll_timeout(ksz_regmap_16(dev), REG_VPHY_IND_CTRL__2,
value, !(value & VPHY_IND_BUSY), 10, value, !(value & VPHY_IND_BUSY), 10,
1000); 1000);
if (ret < 0) { if (ret < 0) {
...@@ -116,7 +116,7 @@ static int lan937x_internal_phy_read(struct ksz_device *dev, int addr, int reg, ...@@ -116,7 +116,7 @@ static int lan937x_internal_phy_read(struct ksz_device *dev, int addr, int reg,
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = regmap_read_poll_timeout(dev->regmap[1], REG_VPHY_IND_CTRL__2, ret = regmap_read_poll_timeout(ksz_regmap_16(dev), REG_VPHY_IND_CTRL__2,
value, !(value & VPHY_IND_BUSY), 10, value, !(value & VPHY_IND_BUSY), 10,
1000); 1000);
if (ret < 0) { if (ret < 0) {
......
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