From: Vivien Didelot <hidden> Date: 2016-06-14 18:36:51
Some switch models have different way to access their internal registers
through SMI, and different places where to find the switch ID register.
This patchset abstracts these differences with a new SMI ops structure
and new data in the info structure: the port_base_addr member indicates
where start the ports registers and the MV88E6XXX_FLAG_MULTI_CHIP flag
indicates the need for an indirect SMI access.
The new MDIO probe code uses the compatible info data to detect the
device, and the legacy probe code iterate on compatible info table
(which currently only contains the 88E6085 info) to detect devices.
With these changes, the driver can easily support other switch models
with different register access. For instance, the 88E6060 uses a direct
SMI access even if the chip SMI address is non-zero and port registers
(where the switch ID registers is located) start at 0x8. The port
registers of the 88E6390X start at 0x10. Adding support to probe these
two models would basically look like this:
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+ [MV88E6060] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6060,
+ .family = MV88E6XXX_FAMILY_6060,
+ .name = "Marvell 88E6060",
+ .num_databases = 16,
+ .num_ports = 6,
+ .port_base_addr = 0x8,
+ .flags = ...,
+ },
+
[MV88E6085] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
.family = MV88E6XXX_FAMILY_6097,
...
.port_base_addr = 0x10,
.flags = MV88E6XXX_FLAGS_FAMILY_6352,
},
+
+ [MV88E6390] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6390,
+ .family = MV88E6XXX_FAMILY_6390,
+ .name = "Marvell 88E6390X",
+ .num_databases = 4096,
+ .num_ports = 11,
+ .port_base_addr = 0x0,
+ .flags = ... | MV88E6XXX_FLAG_MULTI_CHIP,
+ },
};
static const struct of_device_id mv88e6xxx_of_id_table[] = {
{
+ .compatible = "marvell,mv88e6060",
+ .data = &mv88e6xxx_table[MV88E6060],
+ }, {
.compatible = "marvell,mv88e6085",
.data = &mv88e6xxx_table[MV88E6085],
+ }, {
+ .compatible = "marvell,mv88e6390",
+ .data = &mv88e6xxx_table[MV88E6390],
},
{ /* sentinel */ },
};
This patchset also adds helpers to abstract common code of probe
functions and make them more readable before adding the changes
described above.
Changes since v1 [1]:
- merge style fix from Ben Dooks
- add Acked-by/Reviewed-by tags
- drop one compatible string per model
- detect the SMI device based on the compatible info
- add an SMI ops structure
[1] https://lkml.org/lkml/2016/6/8/1201
Vivien Didelot (12):
net: dsa: mv88e6xxx: fix style issues
net: dsa: mv88e6xxx: remove redundant assignments
net: dsa: mv88e6xxx: use already declared variables
net: dsa: mv88e6xxx: do not increment bus refcount
net: dsa: mv88e6xxx: add switch register helpers
net: dsa: mv88e6xxx: add port base address to info
net: dsa: mv88e6xxx: put chip info in ID table
net: dsa: mv88e6xxx: read switch ID from info
net: dsa: mv88e6xxx: add SMI detection helper
net: dsa: mv88e6xxx: iterate on compatible info
net: dsa: mv88e6xxx: add an SMI ops structure
net: dsa: mv88e6xxx: add addressing mode to info
drivers/net/dsa/mv88e6xxx.c | 342 ++++++++++++++++++++++++++++----------------
drivers/net/dsa/mv88e6xxx.h | 26 +++-
2 files changed, 244 insertions(+), 124 deletions(-)
--
2.8.3
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:15
The chip->ds and ds->slave_mii_bus assignments are common to both legacy
and new MDIO probing and are already done in the later setup code.
Remove the duplicated assignments from the MDIO probing code.
Signed-off-by: Vivien Didelot <redacted>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx.c | 3 ---
1 file changed, 3 deletions(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:20
Not all Marvell switches have their Port Registers SMI Addresses
starting at 0x10. Add this data in the info structure.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 17 +++++++++++++++++
drivers/net/dsa/mv88e6xxx.h | 1 +
2 files changed, 18 insertions(+)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:22
The MDIO device probe and remove functions are respectively incrementing
and decrementing the bus refcount themselves. Since these bus level
actions are out of the device scope, remove them.
Signed-off-by: Vivien Didelot <redacted>
Acked-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx.c | 3 ---
1 file changed, 3 deletions(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:24
In the MDIO probing function, dev is already assigned to &mdiodev->dev
and np is already assigned to mdiodev->dev.of_node, so use them.
Signed-off-by: Vivien Didelot <redacted>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:26
The mixed assignments, allocations and registrations in the probe code
make it hard to follow the logic and figure out what is DSA or chip
specific.
Extract the struct dsa_switch related code in a simple
mv88e6xxx_register_switch helper function.
For symmetry in the code, add a mv88e6xxx_unregister_switch function.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 41 ++++++++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 13 deletions(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:30
Extract the allocation and switch ID reading code used by both legacy
and new probing into an helper function which uses a info structure to
describe how to access the switch ID register.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 74 ++++++++++++++++++++-------------------------
1 file changed, 32 insertions(+), 42 deletions(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:33
Add the chip info structure as the data of the compatible of device,
which will be used later by probe code.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:34
Retrieve the info structure of the compatible of device in the new probe
function, in order to know how to access the switch ID register.
That way, a compatible info can be used to describe how to access the
switch registers on models with different registers layout or addressing
modes.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:32:58
The Marvell switch models have different mode the access the internal
SMI registers. When the chip address on the SMI master bus is 0, the
chips respond to all SMI devices addresses known to them. When the chip
address is not zero, most chips use an indirect access to registers
using two SMI Command and Data registers.
Add a pointer to a new SMI ops structure in the chip to explicit the
addressing mode and simplify the probing code.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 133 +++++++++++++++++++++++++++++---------------
drivers/net/dsa/mv88e6xxx.h | 9 +++
2 files changed, 98 insertions(+), 44 deletions(-)
@@ -63,14 +95,11 @@ static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)return-ETIMEDOUT;}-staticint__mv88e6xxx_reg_read(structmii_bus*bus,intsw_addr,intaddr,-intreg)+staticintmv88e6xxx_smi_indirect_read(structmii_bus*bus,intsw_addr,+intaddr,intreg,u16*val){intret;-if(sw_addr==0)-returnmdiobus_read_nested(bus,addr,reg);-/* Wait for the bus to become free. */ret=mv88e6xxx_reg_wait_ready(bus,sw_addr);if(ret<0)
@@ -92,46 +121,16 @@ static int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr,if(ret<0)returnret;-returnret&0xffff;-}--staticint_mv88e6xxx_reg_read(structmv88e6xxx_priv_state*ps,-intaddr,intreg)-{-intret;--assert_smi_lock(ps);--ret=__mv88e6xxx_reg_read(ps->bus,ps->sw_addr,addr,reg);-if(ret<0)-returnret;--dev_dbg(ps->dev,"<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",-addr,reg,ret);--returnret;-}--staticintmv88e6xxx_reg_read(structmv88e6xxx_priv_state*ps,intaddr,-intreg)-{-intret;+*val=ret&0xffff;-mutex_lock(&ps->smi_mutex);-ret=_mv88e6xxx_reg_read(ps,addr,reg);-mutex_unlock(&ps->smi_mutex);--returnret;+return0;}-staticint__mv88e6xxx_reg_write(structmii_bus*bus,intsw_addr,intaddr,-intreg,u16val)+staticintmv88e6xxx_smi_indirect_write(structmii_bus*bus,intsw_addr,+intaddr,intreg,u16val){intret;-if(sw_addr==0)-returnmdiobus_write_nested(bus,addr,reg,val);-/* Wait for the bus to become free. */ret=mv88e6xxx_reg_wait_ready(bus,sw_addr);if(ret<0)
@@ -156,15 +155,56 @@ static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,return0;}+staticconststructmv88e6xxx_smi_opsmv88e6xxx_smi_indirect_ops={+.read=mv88e6xxx_smi_indirect_read,+.write=mv88e6xxx_smi_indirect_write,+};++staticint_mv88e6xxx_reg_read(structmv88e6xxx_priv_state*ps,+intaddr,intreg)+{+u16val;+interr;++assert_smi_lock(ps);++err=ps->smi_ops->read(ps->bus,ps->sw_addr,addr,reg,&val);+if(err)+returnerr;++dev_dbg(ps->dev,"<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",+addr,reg,val);++returnval;+}++staticintmv88e6xxx_reg_read(structmv88e6xxx_priv_state*ps,intaddr,+intreg)+{+intret;++mutex_lock(&ps->smi_mutex);+ret=_mv88e6xxx_reg_read(ps,addr,reg);+mutex_unlock(&ps->smi_mutex);++returnret;+}+staticint_mv88e6xxx_reg_write(structmv88e6xxx_priv_state*ps,intaddr,intreg,u16val){+interr;+assert_smi_lock(ps);+err=ps->smi_ops->write(ps->bus,ps->sw_addr,addr,reg,val);+if(err)+returnerr;+dev_dbg(ps->dev,"-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",addr,reg,val);-return__mv88e6xxx_reg_write(ps->bus,ps->sw_addr,addr,reg,val);+return0;}staticintmv88e6xxx_reg_write(structmv88e6xxx_priv_state*ps,intaddr,
@@ -555,6 +562,8 @@ struct mv88e6xxx_priv_state {/* The device this structure is associated to */structdevice*dev;+conststructmv88e6xxx_smi_ops*smi_ops;+/* When using multi-chip addressing, this mutex protects*accesstotheindirectaccessregisters.(Insingle-chip*mode,thismutexiseffectivelyuseless.)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:33:19
When the SMI address of the switch chip on the SMI master bus is not
zero, some chips (e.g. 88E6352) use an indirect access through two SMI
Command and Data registers, while others (e.g. 88E6060) still use a
direct access.
Add a capability flag to describe chips supporting the Multi-chip
Addressing Mode.
Use the SMI indirect access ops only for switches with this flag and
change the direct SMI direct access ops to support non-zero chip
address.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 6 +++---
drivers/net/dsa/mv88e6xxx.h | 16 +++++++++++++++-
2 files changed, 18 insertions(+), 4 deletions(-)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:34:36
With legacy probing, we cannot have a compatible info structure. We have
to guess it. Instead of using only the first info structure of the info
table, iterate over the compatible data.
That way, the legacy code will support new compatible chips with
different register access without requiring any code change.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
@@ -3668,6 +3668,25 @@ mv88e6xxx_smi_detect(struct device *dev, struct mii_bus *bus, int sw_addr,returnps;}+staticstructmv88e6xxx_priv_state*+mv88e6xxx_drv_detect(structdevice*dev,structmii_bus*bus,intsw_addr)+{+structmv88e6xxx_priv_state*ps=NULL;+conststructmv88e6xxx_info*info;+conststructof_device_id*id;++/* Iterate over compatible info to detect the chip */+for(id=&mv88e6xxx_of_id_table[0];id&&id->data;++id){+info=(conststructmv88e6xxx_info*)id->data;++ps=mv88e6xxx_smi_detect(dev,bus,sw_addr,info);+if(ps)+break;+}++returnps;+}+staticconstchar*mv88e6xxx_drv_probe(structdevice*dsa_dev,structdevice*host_dev,intsw_addr,void**priv)
From: Vivien Didelot <hidden> Date: 2016-06-14 18:37:43
This patch fixes 5 style problems reported by checkpatch:
WARNING: suspect code indent for conditional statements (8, 24)
#492: FILE: drivers/net/dsa/mv88e6xxx.c:492:
+ if (phydev->link)
+ reg |= PORT_PCS_CTRL_LINK_UP;
CHECK: Logical continuations should be on the previous line
#1318: FILE: drivers/net/dsa/mv88e6xxx.c:1318:
+ oldstate == PORT_CONTROL_STATE_FORWARDING)
+ && (state == PORT_CONTROL_STATE_DISABLED ||
CHECK: multiple assignments should be avoided
#1662: FILE: drivers/net/dsa/mv88e6xxx.c:1662:
+ vlan->vid_begin = vlan->vid_end = next.vid;
WARNING: line over 80 characters
#2097: FILE: drivers/net/dsa/mv88e6xxx.c:2097:
+ const struct switchdev_obj_port_vlan *vlan,
WARNING: suspect code indent for conditional statements (16, 32)
#2734: FILE: drivers/net/dsa/mv88e6xxx.c:2734:
+ if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
[...]
+ reg |= PORT_CONTROL_EGRESS_ADD_TAG;
total: 0 errors, 3 warnings, 2 checks, 3805 lines checked
It also rebases and integrates changes sent by Ben Dooks [1]:
The driver has a number of functions that are not exported or
declared elsewhere, so make them static to avoid the following
warnings from sparse:
drivers/net/dsa/mv88e6xxx.c:113:5: warning: symbol 'mv88e6xxx_reg_read' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:167:5: warning: symbol 'mv88e6xxx_reg_write' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:231:5: warning: symbol 'mv88e6xxx_set_addr' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:367:6: warning: symbol 'mv88e6xxx_ppu_state_init' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3157:5: warning: symbol 'mv88e6xxx_phy_page_read' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3169:5: warning: symbol 'mv88e6xxx_phy_page_write' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3583:26: warning: symbol 'mv88e6xxx_switch_driver' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3621:5: warning: symbol 'mv88e6xxx_probe' was not declared. Should it be static?
[1] http://patchwork.ozlabs.org/patch/632708/
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 42 +++++++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 19 deletions(-)
@@ -1314,9 +1315,9 @@ static int _mv88e6xxx_port_state(struct mv88e6xxx_priv_state *ps, int port,*BlockingorListeningstate.*/if((oldstate==PORT_CONTROL_STATE_LEARNING||-oldstate==PORT_CONTROL_STATE_FORWARDING)-&&(state==PORT_CONTROL_STATE_DISABLED||-state==PORT_CONTROL_STATE_BLOCKING)){+oldstate==PORT_CONTROL_STATE_FORWARDING)&&+(state==PORT_CONTROL_STATE_DISABLED||+state==PORT_CONTROL_STATE_BLOCKING)){ret=_mv88e6xxx_atu_remove(ps,0,port,false);if(ret)returnret;
@@ -1659,7 +1660,8 @@ static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,continue;/* reinit and dump this VLAN obj */-vlan->vid_begin=vlan->vid_end=next.vid;+vlan->vid_begin=next.vid;+vlan->vid_end=next.vid;vlan->flags=0;if(next.data[port]==GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED)
@@ -3170,8 +3174,8 @@ int mv88e6xxx_mdio_page_read(struct dsa_switch *ds, int port, int page, int reg)returnret;}-intmv88e6xxx_mdio_page_write(structdsa_switch*ds,intport,intpage,-intreg,intval)+staticintmv88e6xxx_mdio_page_write(structdsa_switch*ds,intport,intpage,+intreg,intval){structmv88e6xxx_priv_state*ps=ds_to_priv(ds);intret;
From: Sergei Shtylyov <hidden> Date: 2016-06-14 18:50:34
Hello.
On 06/14/2016 09:31 PM, Vivien Didelot wrote:
quoted hunk
Retrieve the info structure of the compatible of device in the new probe
function, in order to know how to access the switch ID register.
That way, a compatible info can be used to describe how to access the
switch registers on models with different registers layout or addressing
modes.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
From: Sergei Shtylyov <hidden> Date: 2016-06-14 19:38:50
On 06/14/2016 09:31 PM, Vivien Didelot wrote:
quoted hunk
With legacy probing, we cannot have a compatible info structure. We have
to guess it. Instead of using only the first info structure of the info
table, iterate over the compatible data.
That way, the legacy code will support new compatible chips with
different register access without requiring any code change.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
@@ -3668,6 +3668,25 @@ mv88e6xxx_smi_detect(struct device *dev, struct mii_bus *bus, int sw_addr,returnps;}+staticstructmv88e6xxx_priv_state*+mv88e6xxx_drv_detect(structdevice*dev,structmii_bus*bus,intsw_addr)+{+structmv88e6xxx_priv_state*ps=NULL;+conststructmv88e6xxx_info*info;+conststructof_device_id*id;++/* Iterate over compatible info to detect the chip */+for(id=&mv88e6xxx_of_id_table[0];id&&id->data;++id){+info=(conststructmv88e6xxx_info*)id->data;
The explicit cast shouldn't be needed...
[...]
MBR, Sergei
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-06-14 21:14:37
On Tue, Jun 14, 2016 at 02:31:42PM -0400, Vivien Didelot wrote:
This patch fixes 5 style problems reported by checkpatch:
WARNING: suspect code indent for conditional statements (8, 24)
#492: FILE: drivers/net/dsa/mv88e6xxx.c:492:
+ if (phydev->link)
+ reg |= PORT_PCS_CTRL_LINK_UP;
CHECK: Logical continuations should be on the previous line
#1318: FILE: drivers/net/dsa/mv88e6xxx.c:1318:
+ oldstate == PORT_CONTROL_STATE_FORWARDING)
+ && (state == PORT_CONTROL_STATE_DISABLED ||
CHECK: multiple assignments should be avoided
#1662: FILE: drivers/net/dsa/mv88e6xxx.c:1662:
+ vlan->vid_begin = vlan->vid_end = next.vid;
WARNING: line over 80 characters
#2097: FILE: drivers/net/dsa/mv88e6xxx.c:2097:
+ const struct switchdev_obj_port_vlan *vlan,
WARNING: suspect code indent for conditional statements (16, 32)
#2734: FILE: drivers/net/dsa/mv88e6xxx.c:2734:
+ if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
[...]
+ reg |= PORT_CONTROL_EGRESS_ADD_TAG;
total: 0 errors, 3 warnings, 2 checks, 3805 lines checked
It also rebases and integrates changes sent by Ben Dooks [1]:
The driver has a number of functions that are not exported or
declared elsewhere, so make them static to avoid the following
warnings from sparse:
drivers/net/dsa/mv88e6xxx.c:113:5: warning: symbol 'mv88e6xxx_reg_read' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:167:5: warning: symbol 'mv88e6xxx_reg_write' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:231:5: warning: symbol 'mv88e6xxx_set_addr' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:367:6: warning: symbol 'mv88e6xxx_ppu_state_init' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3157:5: warning: symbol 'mv88e6xxx_phy_page_read' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3169:5: warning: symbol 'mv88e6xxx_phy_page_write' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3583:26: warning: symbol 'mv88e6xxx_switch_driver' was not declared. Should it be static?
drivers/net/dsa/mv88e6xxx.c:3621:5: warning: symbol 'mv88e6xxx_probe' was not declared. Should it be static?
[1] http://patchwork.ozlabs.org/patch/632708/
Signed-off-by: Vivien Didelot <redacted>
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-06-14 21:17:26
On Tue, Jun 14, 2016 at 02:31:46PM -0400, Vivien Didelot wrote:
The mixed assignments, allocations and registrations in the probe code
make it hard to follow the logic and figure out what is DSA or chip
specific.
Extract the struct dsa_switch related code in a simple
mv88e6xxx_register_switch helper function.
For symmetry in the code, add a mv88e6xxx_unregister_switch function.
Signed-off-by: Vivien Didelot <redacted>
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-06-14 21:47:03
On Tue, Jun 14, 2016 at 02:31:51PM -0400, Vivien Didelot wrote:
With legacy probing, we cannot have a compatible info structure. We have
to guess it. Instead of using only the first info structure of the info
table, iterate over the compatible data.
That way, the legacy code will support new compatible chips with
different register access without requiring any code change.
I don't think this is safe when used in combination with multi-chip
addresses. This code will perform writes on various addresses,
addresses which could be real registers on a device.
I don't see a need to support guessing. The new binding will work,
without any guessing. So use that.
Andrew
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-06-14 21:50:38
On Tue, Jun 14, 2016 at 02:31:50PM -0400, Vivien Didelot wrote:
quoted hunk
Extract the allocation and switch ID reading code used by both legacy
and new probing into an helper function which uses a info structure to
describe how to access the switch ID register.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 74 ++++++++++++++++++++-------------------------
1 file changed, 32 insertions(+), 42 deletions(-)
I don't like the way this detect function goes a lot further than
detection. I would say detection finished when you have the info
structure. Return at that point, and let the probe do the rest.
Andrew
Is sw_addr is > 0 and MV88E6XXX_FLAG_MULTI_CHIP is not set, you should
return -EINVAL. The device tree is invalid.
OK, I'll change this snippet for the following until we explicitly add
support for such device with non-zero address and direct SMI access:
if (sw_addr == 0)
ops = &mv88e6xxx_smi_direct_ops;
else if (info->flags & MV88E6XXX_FLAG_MULTI_CHIP)
ops = &mv88e6xxx_smi_indirect_ops;
else
return NULL;
Thanks,
Vivien
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-06-14 22:04:39
+struct mv88e6xxx_smi_ops {
+ int (*read)(struct mii_bus *bus, int sw_addr,
+ int addr, int reg, u16 *val);
+ int (*write)(struct mii_bus *bus, int sw_addr,
+ int addr, int reg, u16 val);
+};
+
I think this API would be better if it used ps, not bus and sw_addr.
The only problem is the very first read to get the switch ID. I would
add one more layer in between, so that you can call the lowest level
functions without having a ps structure.
Andrew
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-06-14 22:09:45
On Tue, Jun 14, 2016 at 02:31:53PM -0400, Vivien Didelot wrote:
quoted hunk
When the SMI address of the switch chip on the SMI master bus is not
zero, some chips (e.g. 88E6352) use an indirect access through two SMI
Command and Data registers, while others (e.g. 88E6060) still use a
direct access.
Add a capability flag to describe chips supporting the Multi-chip
Addressing Mode.
Use the SMI indirect access ops only for switches with this flag and
change the direct SMI direct access ops to support non-zero chip
address.
Signed-off-by: Vivien Didelot <redacted>
---
drivers/net/dsa/mv88e6xxx.c | 6 +++---
drivers/net/dsa/mv88e6xxx.h | 16 +++++++++++++++-
2 files changed, 18 insertions(+), 4 deletions(-)
I don't like the way this detect function goes a lot further than
detection. I would say detection finished when you have the info
structure. Return at that point, and let the probe do the rest.
OK, I split detection and allocation.
Thanks,
Vivien
From: Vivien Didelot <hidden> Date: 2016-06-14 22:13:23
Hi Andrew,
Andrew Lunn [off-list ref] writes:
On Tue, Jun 14, 2016 at 02:31:51PM -0400, Vivien Didelot wrote:
quoted
With legacy probing, we cannot have a compatible info structure. We have
to guess it. Instead of using only the first info structure of the info
table, iterate over the compatible data.
That way, the legacy code will support new compatible chips with
different register access without requiring any code change.
I don't think this is safe when used in combination with multi-chip
addresses. This code will perform writes on various addresses,
addresses which could be real registers on a device.
I don't see a need to support guessing. The new binding will work,
without any guessing. So use that.
OK, I drop this patch and limit the detection in the legacy probing
against the 6085 chip info.
Thanks,
Vivien
From: Vivien Didelot <hidden> Date: 2016-06-14 22:24:21
Hi Andrew,
Andrew Lunn [off-list ref] writes:
quoted
- ret = mdiobus_read_nested(bus, addr, reg);
+ ret = mdiobus_read_nested(bus, sw_addr + addr, reg);
if (ret < 0)
return ret;
If we are doing direct access, doesn't it means sw_addr is 0?
So isn't this pointless?
6060 has no indirect access and directly responds to 16 SMI addresses,
regardless its chip address which can be strapped to either 0 or 16.
If we want to add support for it in mv88e6xxx someday (which is likely),
the code is ready for that.
Question 1) given this, should I still consider your first comment on
this patch about the mv88e6xxx_smi_ops assignment?
Question 2) is MV88E6XXX_FLAG_MULTI_CHIP confusing? I took a short name
for style but maybe a longer MV88E6XXX_FLAG_MULTI_CHIP_ADDRESSING or
MV88E6XXX_FLAG_MULTI_CHIP_MODE would be clearer to make to distinction
between "Single-chip Addressing Mode" and "Multi-chip Addressing Mode".
Thanks,
Vivien
From: Vivien Didelot <hidden> Date: 2016-06-14 22:26:50
Hi Andrew,
Andrew Lunn [off-list ref] writes:
quoted
+struct mv88e6xxx_smi_ops {
+ int (*read)(struct mii_bus *bus, int sw_addr,
+ int addr, int reg, u16 *val);
+ int (*write)(struct mii_bus *bus, int sw_addr,
+ int addr, int reg, u16 val);
+};
+
I think this API would be better if it used ps, not bus and sw_addr.
The only problem is the very first read to get the switch ID. I would
add one more layer in between, so that you can call the lowest level
functions without having a ps structure.
That's why I keep it simple for the moment.
The low-level API using ps is now _mv88e6xxx_reg_{read,write}. I can
rename them to mv88e6xxx_smi_{read,write} in v3 or later.
Thanks,
Vivien
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-06-14 22:44:30
On Tue, Jun 14, 2016 at 06:24:17PM -0400, Vivien Didelot wrote:
Hi Andrew,
Andrew Lunn [off-list ref] writes:
quoted
quoted
- ret = mdiobus_read_nested(bus, addr, reg);
+ ret = mdiobus_read_nested(bus, sw_addr + addr, reg);
if (ret < 0)
return ret;
If we are doing direct access, doesn't it means sw_addr is 0?
So isn't this pointless?
6060 has no indirect access and directly responds to 16 SMI addresses,
regardless its chip address which can be strapped to either 0 or 16.
Ah! O.K.
wnr854t-setup.c uses 0.
rd88f6183ap-ge-setup.c uses 0.
wrt350n-v2-setup.c uses 0.
rd88f5181l-fxo-setup.c uses 0.
rd88f5181l-ge-setup.c uses 0.
mach-bf518/boards/ezbrd.c uses 0.
The 6060 is a very old device. I doubt we will get any new boards
contributed using it. We are also going to have trouble actually
finding a device with one in order to test a merged mv88e6xxx and
mv88e6060 driver.
So i say we ignore the possibility of an 6060 on 16, until one really
comes along.
Question 2) is MV88E6XXX_FLAG_MULTI_CHIP confusing?
From: Vivien Didelot <hidden> Date: 2016-06-14 23:11:34
Hi,
Andrew Lunn [off-list ref] writes:
On Tue, Jun 14, 2016 at 06:24:17PM -0400, Vivien Didelot wrote:
quoted
Hi Andrew,
Andrew Lunn [off-list ref] writes:
quoted
quoted
- ret = mdiobus_read_nested(bus, addr, reg);
+ ret = mdiobus_read_nested(bus, sw_addr + addr, reg);
if (ret < 0)
return ret;
If we are doing direct access, doesn't it means sw_addr is 0?
So isn't this pointless?
6060 has no indirect access and directly responds to 16 SMI addresses,
regardless its chip address which can be strapped to either 0 or 16.
Ah! O.K.
wnr854t-setup.c uses 0.
rd88f6183ap-ge-setup.c uses 0.
wrt350n-v2-setup.c uses 0.
rd88f5181l-fxo-setup.c uses 0.
rd88f5181l-ge-setup.c uses 0.
mach-bf518/boards/ezbrd.c uses 0.
The 6060 is a very old device. I doubt we will get any new boards
contributed using it. We are also going to have trouble actually
finding a device with one in order to test a merged mv88e6xxx and
mv88e6060 driver.
So i say we ignore the possibility of an 6060 on 16, until one really
comes along.