Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1395440 > unrolled thread
| Started by | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| First post | 2016-05-06 00:50 +0200 |
| Last post | 2016-05-06 03:20 +0200 |
| Articles | 10 — 2 participants |
Back to article view | Back to linux.kernel
[RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
[RFC PATCH net-next 08/20] net: dsa: mv88e6xxx: factorize bridge support Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
[RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
Re: [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup Andrew Lunn <andrew@lunn.ch> - 2016-05-06 03:00 +0200
[RFC PATCH net-next 05/20] net: dsa: mv88e6xxx: factorize MAC address setting Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
[RFC PATCH net-next 10/20] net: dsa: mv88e6xxx: factorize ATU access Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
[RFC PATCH net-next 07/20] net: dsa: mv88e6xxx: factorize registers access Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
[RFC PATCH net-next 02/20] net: dsa: mv88e6xxx: factorize PHY indirect access Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
[RFC PATCH net-next 03/20] net: dsa: mv88e6xxx: factorize EEPROM access Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-05-06 00:50 +0200
Re: [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver Andrew Lunn <andrew@lunn.ch> - 2016-05-06 03:20 +0200
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver |
| Message-ID | <rvAfL-Dg-3@gated-at.bofh.it> |
This patchset merges all mv88e6* drivers supported by the shared mv88e6xxx code into a single mv88e6xxx DSA switch driver. Some flags are added to describe the capabilities of a switch model, such as the presence of a PPU, EEPROM, some old or new registers, etc. First these flags are used to conditionally support the same set of functions in every driver, then specific driver files are removed in favor of the common mv88e6xxx driver. Only the merge of driver specific setup code assumes a few differences. If these differences such as frames priorities are really needed for some models, they can easily be brought back in a future patch. Some inconsistencies might show up, such as the need for MV88E6XXX_FLAG_PPU and MV88E6XXX_FLAG_PPU_ACTIVE flags. But this patchset does not aim to fix them yet. A future patch can do that if they end up being inconsistencies. Vivien Didelot (20): net: dsa: mv88e6xxx: factorize PHY access with PPU net: dsa: mv88e6xxx: factorize PHY indirect access net: dsa: mv88e6xxx: factorize EEPROM access net: dsa: mv88e6xxx: factorize temperature access net: dsa: mv88e6xxx: factorize MAC address setting net: dsa: mv88e6xxx: factorize EEE access net: dsa: mv88e6xxx: factorize registers access net: dsa: mv88e6xxx: factorize bridge support net: dsa: mv88e6xxx: factorize VTU access net: dsa: mv88e6xxx: factorize ATU access net: dsa: mv88e6xxx: factorize switch reset net: dsa: mv88e6xxx: factorize global setup net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup net: dsa: mv88e6xxx: factorize VLAN Ethertype net: dsa: mv88e6xxx: factorize GLOBAL_MONITOR_CONTROL setup net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup net: dsa: mv88e6xxx: factorize frames priorities net: dsa: mv88e6xxx: factorize switch setup net: dsa: mv88e6xxx: factorize tag protocol net: dsa: mv88e6xxx: factorize the switch driver arch/arm/configs/multi_v5_defconfig | 5 +- arch/arm/configs/mvebu_v7_defconfig | 2 +- arch/arm/configs/orion5x_defconfig | 3 +- arch/tile/configs/tilegx_defconfig | 3 +- arch/tile/configs/tilepro_defconfig | 3 +- drivers/net/dsa/Kconfig | 41 +- drivers/net/dsa/Makefile | 15 +- drivers/net/dsa/mv88e6123.c | 130 ---- drivers/net/dsa/mv88e6131.c | 204 ------ drivers/net/dsa/mv88e6171.c | 151 ---- drivers/net/dsa/mv88e6352.c | 377 ---------- drivers/net/dsa/mv88e6xxx.c | 1348 +++++++++++++++++++++++++---------- drivers/net/dsa/mv88e6xxx.h | 190 ++--- 13 files changed, 1084 insertions(+), 1388 deletions(-) delete mode 100644 drivers/net/dsa/mv88e6123.c delete mode 100644 drivers/net/dsa/mv88e6131.c delete mode 100644 drivers/net/dsa/mv88e6171.c delete mode 100644 drivers/net/dsa/mv88e6352.c -- 2.8.2
[toc] | [next] | [standalone]
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 08/20] net: dsa: mv88e6xxx: factorize bridge support |
| Message-ID | <rvAfN-Dg-39@gated-at.bofh.it> |
| In reply to | #1395440 |
Add MV88E6XXX_FLAG_PORTSTATE and MV88E6XXX_FLAG_VLANTABLE flags to
identify switch models with required 802.1D operations.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 3 +++
drivers/net/dsa/mv88e6131.c | 13 +++++++++----
drivers/net/dsa/mv88e6171.c | 24 ++++++++++++++++--------
drivers/net/dsa/mv88e6352.c | 24 ++++++++++++++++++------
drivers/net/dsa/mv88e6xxx.c | 9 +++++++++
drivers/net/dsa/mv88e6xxx.h | 13 +++++++++++++
6 files changed, 68 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index e5335c2..05d5196 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -136,6 +136,9 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
.set_eeprom = mv88e6xxx_set_eeprom,
.get_regs_len = mv88e6xxx_get_regs_len,
.get_regs = mv88e6xxx_get_regs,
+ .port_bridge_join = mv88e6xxx_port_bridge_join,
+ .port_bridge_leave = mv88e6xxx_port_bridge_leave,
+ .port_stp_state_set = mv88e6xxx_port_stp_state_set,
};
MODULE_ALIAS("platform:mv88e6123");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 89cabbf..125fbbb 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -24,28 +24,32 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
.name = "Marvell 88E6095/88E6095F",
.num_databases = 256,
.num_ports = 11,
- .flags = MV88E6XXX_FLAG_PPU,
+ .flags = MV88E6XXX_FLAG_PPU |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
.family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6085",
.num_databases = 4096,
.num_ports = 10,
- .flags = MV88E6XXX_FLAG_PPU,
+ .flags = MV88E6XXX_FLAG_PPU |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6131",
.num_databases = 256,
.num_ports = 8,
- .flags = MV88E6XXX_FLAG_PPU,
+ .flags = MV88E6XXX_FLAG_PPU |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6185",
.num_databases = 256,
.num_ports = 10,
- .flags = MV88E6XXX_FLAG_PPU,
+ .flags = MV88E6XXX_FLAG_PPU |
+ MV88E6XXX_FLAG_VLANTABLE,
}
};
@@ -168,6 +172,7 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
.adjust_link = mv88e6xxx_adjust_link,
.port_bridge_join = mv88e6xxx_port_bridge_join,
.port_bridge_leave = mv88e6xxx_port_bridge_leave,
+ .port_stp_state_set = mv88e6xxx_port_stp_state_set,
.port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
.port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
.port_vlan_add = mv88e6xxx_port_vlan_add,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 6953d12..8ba338d 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,36 +24,44 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.name = "Marvell 88E6171",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY |
+ .flags = MV88E6XXX_FLAG_PORTSTATE |
+ MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
- MV88E6XXX_FLAG_TEMP,
+ MV88E6XXX_FLAG_TEMP |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6175",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY |
+ .flags = MV88E6XXX_FLAG_PORTSTATE |
+ MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
- MV88E6XXX_FLAG_TEMP,
+ MV88E6XXX_FLAG_TEMP |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6350",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY |
+ .flags = MV88E6XXX_FLAG_PORTSTATE |
+ MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
- MV88E6XXX_FLAG_TEMP,
+ MV88E6XXX_FLAG_TEMP |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6351",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY |
+ .flags = MV88E6XXX_FLAG_PORTSTATE |
+ MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
- MV88E6XXX_FLAG_TEMP,
+ MV88E6XXX_FLAG_TEMP |
+ MV88E6XXX_FLAG_VLANTABLE,
}
};
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index d4ebfb3..a67dcf9 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -31,10 +31,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
- MV88E6XXX_FLAG_TEMP_LIMIT,
+ MV88E6XXX_FLAG_TEMP_LIMIT |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
.family = MV88E6XXX_FAMILY_6320,
@@ -43,10 +45,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
- MV88E6XXX_FLAG_TEMP_LIMIT,
+ MV88E6XXX_FLAG_TEMP_LIMIT |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
.family = MV88E6XXX_FAMILY_6352,
@@ -55,10 +59,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
- MV88E6XXX_FLAG_TEMP_LIMIT,
+ MV88E6XXX_FLAG_TEMP_LIMIT |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
.family = MV88E6XXX_FAMILY_6352,
@@ -67,10 +73,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
- MV88E6XXX_FLAG_TEMP_LIMIT,
+ MV88E6XXX_FLAG_TEMP_LIMIT |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
.family = MV88E6XXX_FAMILY_6352,
@@ -79,10 +87,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
- MV88E6XXX_FLAG_TEMP_LIMIT,
+ MV88E6XXX_FLAG_TEMP_LIMIT |
+ MV88E6XXX_FLAG_VLANTABLE,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
.family = MV88E6XXX_FAMILY_6352,
@@ -91,10 +101,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
- MV88E6XXX_FLAG_TEMP_LIMIT,
+ MV88E6XXX_FLAG_TEMP_LIMIT |
+ MV88E6XXX_FLAG_VLANTABLE,
}
};
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 4ed6379..c6e4254e 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1359,6 +1359,9 @@ void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int stp_state;
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_PORTSTATE))
+ return;
+
switch (state) {
case BR_STATE_DISABLED:
stp_state = PORT_CONTROL_STATE_DISABLED;
@@ -2420,6 +2423,9 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int i, err = 0;
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE))
+ return -EOPNOTSUPP;
+
mutex_lock(&ps->smi_mutex);
/* Assign the bridge and remap each port's VLANTable */
@@ -2444,6 +2450,9 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
struct net_device *bridge = ps->ports[port].bridge_dev;
int i;
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE))
+ return;
+
mutex_lock(&ps->smi_mutex);
/* Unassign the bridge and remap each port's VLANTable */
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 305bccf..bf8475b 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -360,6 +360,11 @@ enum mv88e6xxx_cap {
*/
MV88E6XXX_CAP_EEPROM,
+ /* Port State Filtering for 802.1D Spanning Tree.
+ * See PORT_CONTROL_STATE_* values in the PORT_CONTROL register.
+ */
+ MV88E6XXX_CAP_PORTSTATE,
+
/* PHY Polling Unit.
* See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
*/
@@ -383,16 +388,24 @@ enum mv88e6xxx_cap {
*/
MV88E6XXX_CAP_TEMP,
MV88E6XXX_CAP_TEMP_LIMIT,
+
+ /* In-chip Port Based VLANs.
+ * Each port VLANTable register (see PORT_BASE_VLAN) is used to restrict
+ * the output (or egress) ports to which it is allowed to send frames.
+ */
+ MV88E6XXX_CAP_VLANTABLE,
};
/* Bitmask of capabilities */
#define MV88E6XXX_FLAG_EEE BIT(MV88E6XXX_CAP_EEE)
#define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM)
+#define MV88E6XXX_FLAG_PORTSTATE BIT(MV88E6XXX_CAP_PORTSTATE)
#define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU)
#define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY)
#define MV88E6XXX_FLAG_SWITCH_MAC BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF)
#define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP)
#define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT)
+#define MV88E6XXX_FLAG_VLANTABLE BIT(MV88E6XXX_CAP_VLANTABLE)
struct mv88e6xxx_info {
enum mv88e6xxx_family family;
--
2.8.2
[toc] | [prev] | [next] | [standalone]
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup |
| Message-ID | <rvAfN-Dg-41@gated-at.bofh.it> |
| In reply to | #1395440 |
All switch models configure the GLOBAL_CONTROL register with slightly
differences.
Assume a common setup to enable the PHY Polling Unit if present, discard
packets with excessive collisions, set the maximum frame size to 1632,
and mask all interrupt sources.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 8 --------
drivers/net/dsa/mv88e6131.c | 11 -----------
drivers/net/dsa/mv88e6171.c | 9 ---------
drivers/net/dsa/mv88e6352.c | 9 ---------
drivers/net/dsa/mv88e6xxx.c | 14 ++++++++++++++
5 files changed, 14 insertions(+), 37 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 938d5ca..077fe30 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -61,14 +61,6 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
int ret;
u32 reg;
- /* Disable the PHY polling unit (since there won't be any
- * external PHYs to poll), don't discard packets with
- * excessive collisions, and mask all interrupt sources.
- */
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 0x0000);
- if (ret)
- return ret;
-
/* Configure the upstream port, and configure the upstream
* port as the port to which ingress and egress monitor frames
* are to be sent.
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 2c43348..013668c 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -77,17 +77,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
int ret;
u32 reg;
- /* Enable the PHY polling unit, don't discard packets with
- * excessive collisions, use a weighted fair queueing scheme
- * to arbitrate between packet queues, set the maximum frame
- * size to 1632, and mask all interrupt sources.
- */
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
- GLOBAL_CONTROL_PPU_ENABLE |
- GLOBAL_CONTROL_MAX_FRAME_1632);
- if (ret)
- return ret;
-
/* Set the VLAN ethertype to 0x8100. */
ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100);
if (ret)
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index fcdb5a7..f7dbf78 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -93,15 +93,6 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
int ret;
u32 reg;
- /* Discard packets with excessive collisions, mask all
- * interrupt sources, enable PPU.
- */
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
- GLOBAL_CONTROL_PPU_ENABLE |
- GLOBAL_CONTROL_DISCARD_EXCESS);
- if (ret)
- return ret;
-
/* Configure the upstream port, and configure the upstream
* port as the port to which ingress and egress monitor frames
* are to be sent.
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 94a2698..54849f5 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -144,15 +144,6 @@ static int mv88e6352_setup_global(struct dsa_switch *ds)
int ret;
u32 reg;
- /* Discard packets with excessive collisions,
- * mask all interrupt sources, enable PPU (bit 14, undocumented).
- */
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
- GLOBAL_CONTROL_PPU_ENABLE |
- GLOBAL_CONTROL_DISCARD_EXCESS);
- if (ret)
- return ret;
-
/* Configure the upstream port, and configure the upstream
* port as the port to which ingress and egress monitor frames
* are to be sent.
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 7ec532d..1cba078 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2912,9 +2912,23 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
{
+ u16 reg;
int err;
int i;
+ /* Enable the PHY Polling Unit if present, discard packets with
+ * excessive collisions, set the maximum frame size to 1632, and mask
+ * all interrupt sources.
+ */
+ reg = GLOBAL_CONTROL_DISCARD_EXCESS | GLOBAL_CONTROL_MAX_FRAME_1632;
+ if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU) ||
+ mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE))
+ reg |= GLOBAL_CONTROL_PPU_ENABLE;
+
+ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, reg);
+ if (err)
+ return err;
+
/* Set the default address aging time to 5 minutes, and
* enable address learn messages to be sent to all message
* ports.
--
2.8.2
[toc] | [prev] | [next] | [standalone]
| From | Andrew Lunn <andrew@lunn.ch> |
|---|---|
| Date | 2016-05-06 03:00 +0200 |
| Subject | Re: [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup |
| Message-ID | <rvChA-2DB-9@gated-at.bofh.it> |
| In reply to | #1395442 |
On Thu, May 05, 2016 at 06:40:57PM -0400, Vivien Didelot wrote:
> All switch models configure the GLOBAL_CONTROL register with slightly
> differences.
And as far as i know, we have no idea why.
> Assume a common setup to enable the PHY Polling Unit if present, discard
> packets with excessive collisions, set the maximum frame size to 1632,
> and mask all interrupt sources.
This is a behaviour change, not just a refactor. It would be good to
say on which families it has been tested, and which have not.
Andrew
[toc] | [prev] | [next] | [standalone]
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 05/20] net: dsa: mv88e6xxx: factorize MAC address setting |
| Message-ID | <rvAfM-Dg-29@gated-at.bofh.it> |
| In reply to | #1395440 |
Some switch models have a dedicated register for Switch MAC/WoF/WoL.
This register, when present, is used to indirectly set the switch MAC
address, instead of a direct write to 3 global registers.
Identify this feature and share a common mv88e6xxx_set_addr function.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 11 +++--
drivers/net/dsa/mv88e6131.c | 2 +-
drivers/net/dsa/mv88e6171.c | 6 ++-
drivers/net/dsa/mv88e6352.c | 8 ++-
drivers/net/dsa/mv88e6xxx.c | 115 ++++++++++++++++++++++++--------------------
drivers/net/dsa/mv88e6xxx.h | 11 ++++-
6 files changed, 92 insertions(+), 61 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 6f4f719..57a6d76 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -24,21 +24,24 @@ static const struct mv88e6xxx_info mv88e6123_table[] = {
.name = "Marvell 88E6123",
.num_databases = 4096,
.num_ports = 3,
- .flags = MV88E6XXX_FLAG_TEMP,
+ .flags = MV88E6XXX_FLAG_SWITCH_MAC |
+ MV88E6XXX_FLAG_TEMP,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6161",
.num_databases = 4096,
.num_ports = 6,
- .flags = MV88E6XXX_FLAG_TEMP,
+ .flags = MV88E6XXX_FLAG_SWITCH_MAC |
+ MV88E6XXX_FLAG_TEMP,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6165",
.num_databases = 4096,
.num_ports = 6,
- .flags = MV88E6XXX_FLAG_TEMP,
+ .flags = MV88E6XXX_FLAG_SWITCH_MAC |
+ MV88E6XXX_FLAG_TEMP,
}
};
@@ -114,7 +117,7 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
.tag_protocol = DSA_TAG_PROTO_EDSA,
.probe = mv88e6123_drv_probe,
.setup = mv88e6123_setup,
- .set_addr = mv88e6xxx_set_addr_indirect,
+ .set_addr = mv88e6xxx_set_addr,
.phy_read = mv88e6xxx_phy_read,
.phy_write = mv88e6xxx_phy_write,
.get_strings = mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index e8eb9a6..519d1eb 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -147,7 +147,7 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
.tag_protocol = DSA_TAG_PROTO_DSA,
.probe = mv88e6131_drv_probe,
.setup = mv88e6131_setup,
- .set_addr = mv88e6xxx_set_addr_direct,
+ .set_addr = mv88e6xxx_set_addr,
.phy_read = mv88e6xxx_phy_read,
.phy_write = mv88e6xxx_phy_write,
.get_strings = mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index bd2082e..f947950 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -25,6 +25,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.num_databases = 4096,
.num_ports = 7,
.flags = MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
@@ -33,6 +34,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.num_databases = 4096,
.num_ports = 7,
.flags = MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
@@ -41,6 +43,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.num_databases = 4096,
.num_ports = 7,
.flags = MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
@@ -49,6 +52,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.num_databases = 4096,
.num_ports = 7,
.flags = MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP,
}
};
@@ -127,7 +131,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
.tag_protocol = DSA_TAG_PROTO_EDSA,
.probe = mv88e6171_drv_probe,
.setup = mv88e6171_setup,
- .set_addr = mv88e6xxx_set_addr_indirect,
+ .set_addr = mv88e6xxx_set_addr,
.phy_read = mv88e6xxx_phy_read,
.phy_write = mv88e6xxx_phy_write,
.get_strings = mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index f588e2f..90732da 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -31,6 +31,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
MV88E6XXX_FLAG_TEMP_LIMIT,
}, {
@@ -41,6 +42,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
MV88E6XXX_FLAG_TEMP_LIMIT,
}, {
@@ -51,6 +53,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
MV88E6XXX_FLAG_TEMP_LIMIT,
}, {
@@ -61,6 +64,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
MV88E6XXX_FLAG_TEMP_LIMIT,
}, {
@@ -71,6 +75,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
MV88E6XXX_FLAG_TEMP_LIMIT,
}, {
@@ -81,6 +86,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.num_ports = 7,
.flags = MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_SMI_PHY |
+ MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
MV88E6XXX_FLAG_TEMP_LIMIT,
}
@@ -158,7 +164,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.tag_protocol = DSA_TAG_PROTO_EDSA,
.probe = mv88e6352_drv_probe,
.setup = mv88e6352_setup,
- .set_addr = mv88e6xxx_set_addr_indirect,
+ .set_addr = mv88e6xxx_set_addr,
.phy_read = mv88e6xxx_phy_read,
.phy_write = mv88e6xxx_phy_write,
.get_strings = mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 5f7851e..5483e69 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -173,58 +173,6 @@ int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
return ret;
}
-int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int err;
-
- err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_01,
- (addr[0] << 8) | addr[1]);
- if (err)
- return err;
-
- err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_23,
- (addr[2] << 8) | addr[3]);
- if (err)
- return err;
-
- return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_45,
- (addr[4] << 8) | addr[5]);
-}
-
-int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int ret;
- int i;
-
- for (i = 0; i < 6; i++) {
- int j;
-
- /* Write the MAC address byte. */
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
- GLOBAL2_SWITCH_MAC_BUSY |
- (i << 8) | addr[i]);
- if (ret)
- return ret;
-
- /* Wait for the write to complete. */
- for (j = 0; j < 16; j++) {
- ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2,
- GLOBAL2_SWITCH_MAC);
- if (ret < 0)
- return ret;
-
- if ((ret & GLOBAL2_SWITCH_MAC_BUSY) == 0)
- break;
- }
- if (j == 16)
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
static int _mv88e6xxx_phy_read(struct mv88e6xxx_priv_state *ps, int addr,
int regnum)
{
@@ -1131,6 +1079,69 @@ out:
return ret;
}
+static int _mv88e6xxx_set_addr_direct(struct mv88e6xxx_priv_state *ps, u8 *addr)
+{
+ int err;
+
+ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_01,
+ (addr[0] << 8) | addr[1]);
+ if (err)
+ return err;
+
+ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_23,
+ (addr[2] << 8) | addr[3]);
+ if (err)
+ return err;
+
+ return _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_45,
+ (addr[4] << 8) | addr[5]);
+}
+
+static int _mv88e6xxx_switch_mac_wait(struct mv88e6xxx_priv_state *ps)
+{
+ return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
+ GLOBAL2_SWITCH_MAC_BUSY);
+}
+
+static int _mv88e6xxx_set_addr_indirect(struct mv88e6xxx_priv_state *ps,
+ u8 *addr)
+{
+ int i, err;
+
+ for (i = 0; i < 6; i++) {
+ /* Write the MAC address byte. */
+ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
+ GLOBAL2_SWITCH_MAC_BUSY |
+ (i << 8) | addr[i]);
+ if (err)
+ break;
+
+ /* Wait for the write to complete. */
+ err = _mv88e6xxx_switch_mac_wait(ps);
+ if (err)
+ break;
+ }
+
+ return err;
+}
+
+int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int err;
+
+ mutex_lock(&ps->smi_mutex);
+
+ if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SWITCH_MAC))
+ err = _mv88e6xxx_set_addr_indirect(ps, addr);
+ else
+ err = _mv88e6xxx_set_addr_direct(ps, addr);
+
+ mutex_unlock(&ps->smi_mutex);
+
+ return err;
+}
+
static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_priv_state *ps, u16 fid, u16 cmd)
{
int ret;
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index e7c2e45..72b563e 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -367,6 +367,13 @@ enum mv88e6xxx_cap {
*/
MV88E6XXX_CAP_SMI_PHY,
+ /* Switch MAC/WoL/WoF register.
+ * This requires an indirect access to set the switch MAC address
+ * through GLOBAL2_SWITCH_MAC, otherwise GLOBAL_MAC_01, GLOBAL_MAC_23,
+ * and GLOBAL_MAC_45 are used with a direct access.
+ */
+ MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF,
+
/* Internal temperature sensor.
* Available from any enabled port's PHY register 26, page 6.
*/
@@ -378,6 +385,7 @@ enum mv88e6xxx_cap {
#define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM)
#define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU)
#define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY)
+#define MV88E6XXX_FLAG_SWITCH_MAC BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF)
#define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP)
#define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT)
@@ -497,8 +505,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds);
int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg);
int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
int reg, u16 val);
-int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
-int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
+int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr);
int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
--
2.8.2
[toc] | [prev] | [next] | [standalone]
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 10/20] net: dsa: mv88e6xxx: factorize ATU access |
| Message-ID | <rvAfN-Dg-43@gated-at.bofh.it> |
| In reply to | #1395440 |
Add a MV88E6XXX_FLAG_ATU flag to identify switch models with an Address
Translation Unit.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 4 ++++
drivers/net/dsa/mv88e6131.c | 12 ++++++++----
drivers/net/dsa/mv88e6171.c | 12 ++++++++----
drivers/net/dsa/mv88e6352.c | 18 ++++++++++++------
drivers/net/dsa/mv88e6xxx.c | 14 ++++++++++++++
drivers/net/dsa/mv88e6xxx.h | 6 ++++++
6 files changed, 52 insertions(+), 14 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 3992f4f..c562c4a 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -144,6 +144,10 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
.port_vlan_add = mv88e6xxx_port_vlan_add,
.port_vlan_del = mv88e6xxx_port_vlan_del,
.port_vlan_dump = mv88e6xxx_port_vlan_dump,
+ .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
+ .port_fdb_add = mv88e6xxx_port_fdb_add,
+ .port_fdb_del = mv88e6xxx_port_fdb_del,
+ .port_fdb_dump = mv88e6xxx_port_fdb_dump,
};
MODULE_ALIAS("platform:mv88e6123");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index d99ebad..655781f 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -24,7 +24,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
.name = "Marvell 88E6095/88E6095F",
.num_databases = 256,
.num_ports = 11,
- .flags = MV88E6XXX_FLAG_PPU |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PPU |
MV88E6XXX_FLAG_VLANTABLE |
MV88E6XXX_FLAG_VTU,
}, {
@@ -33,7 +34,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
.name = "Marvell 88E6085",
.num_databases = 4096,
.num_ports = 10,
- .flags = MV88E6XXX_FLAG_PPU |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PPU |
MV88E6XXX_FLAG_VLANTABLE |
MV88E6XXX_FLAG_VTU,
}, {
@@ -42,7 +44,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
.name = "Marvell 88E6131",
.num_databases = 256,
.num_ports = 8,
- .flags = MV88E6XXX_FLAG_PPU |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PPU |
MV88E6XXX_FLAG_VLANTABLE |
MV88E6XXX_FLAG_VTU,
}, {
@@ -51,7 +54,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
.name = "Marvell 88E6185",
.num_databases = 256,
.num_ports = 10,
- .flags = MV88E6XXX_FLAG_PPU |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PPU |
MV88E6XXX_FLAG_VLANTABLE |
MV88E6XXX_FLAG_VTU,
}
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index bbea365..66e581f 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,7 +24,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.name = "Marvell 88E6171",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_PORTSTATE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
@@ -36,7 +37,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.name = "Marvell 88E6175",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_PORTSTATE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
@@ -48,7 +50,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.name = "Marvell 88E6350",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_PORTSTATE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
@@ -60,7 +63,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.name = "Marvell 88E6351",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_PORTSTATE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
MV88E6XXX_FLAG_SWITCH_MAC |
MV88E6XXX_FLAG_TEMP |
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 0ed4172..f10aaee 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -29,7 +29,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6320",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_EEE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
@@ -44,7 +45,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6321",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_EEE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
@@ -59,7 +61,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6172",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_EEE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
@@ -74,7 +77,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6176",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_EEE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
@@ -89,7 +93,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6240",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_EEE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
@@ -104,7 +109,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6352",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_EEE |
+ .flags = MV88E6XXX_FLAG_ATU |
+ MV88E6XXX_FLAG_EEE |
MV88E6XXX_FLAG_EEPROM |
MV88E6XXX_FLAG_PORTSTATE |
MV88E6XXX_FLAG_SMI_PHY |
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 805bd0f..810226d 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2265,6 +2265,11 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans)
{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+ return -EOPNOTSUPP;
+
/* We don't need any dynamic resource from the kernel (yet),
* so skip the prepare phase.
*/
@@ -2280,6 +2285,9 @@ void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
GLOBAL_ATU_DATA_STATE_UC_STATIC;
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+ return;
+
mutex_lock(&ps->smi_mutex);
if (_mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, state))
netdev_err(ds->ports[port], "failed to load MAC address\n");
@@ -2292,6 +2300,9 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+ return -EOPNOTSUPP;
+
mutex_lock(&ps->smi_mutex);
ret = _mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid,
GLOBAL_ATU_DATA_STATE_UNUSED);
@@ -2397,6 +2408,9 @@ int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
u16 fid;
int err;
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+ return -EOPNOTSUPP;
+
mutex_lock(&ps->smi_mutex);
/* Dump port's default Filtering Information Database (VLAN ID 0) */
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 9de6ae9..e639de7 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -351,6 +351,11 @@ enum mv88e6xxx_family {
};
enum mv88e6xxx_cap {
+ /* Address Translation Unit.
+ * The ATU is used to lookup and learn MAC addresses. See GLOBAL_ATU_OP.
+ */
+ MV88E6XXX_CAP_ATU,
+
/* Energy Efficient Ethernet.
*/
MV88E6XXX_CAP_EEE,
@@ -402,6 +407,7 @@ enum mv88e6xxx_cap {
};
/* Bitmask of capabilities */
+#define MV88E6XXX_FLAG_ATU BIT(MV88E6XXX_CAP_ATU)
#define MV88E6XXX_FLAG_EEE BIT(MV88E6XXX_CAP_EEE)
#define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM)
#define MV88E6XXX_FLAG_PORTSTATE BIT(MV88E6XXX_CAP_PORTSTATE)
--
2.8.2
[toc] | [prev] | [next] | [standalone]
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 07/20] net: dsa: mv88e6xxx: factorize registers access |
| Message-ID | <rvAfN-Dg-47@gated-at.bofh.it> |
| In reply to | #1395440 |
Only 6131 was not supporting the port registers access yet. Assume such
support and use the unlock access routines in the meantime.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6131.c | 2 ++
drivers/net/dsa/mv88e6xxx.c | 6 +++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 73cf879..89cabbf 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -157,6 +157,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
.get_sset_count = mv88e6xxx_get_sset_count,
.get_eeprom = mv88e6xxx_get_eeprom,
.set_eeprom = mv88e6xxx_set_eeprom,
+ .get_regs_len = mv88e6xxx_get_regs_len,
+ .get_regs = mv88e6xxx_get_regs,
#ifdef CONFIG_NET_DSA_HWMON
.get_temp = mv88e6xxx_get_temp,
.get_temp_limit = mv88e6xxx_get_temp_limit,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 1fbd6d2..4ed6379 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -706,13 +706,17 @@ void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
memset(p, 0xff, 32 * sizeof(u16));
+ mutex_lock(&ps->smi_mutex);
+
for (i = 0; i < 32; i++) {
int ret;
- ret = mv88e6xxx_reg_read(ps, REG_PORT(port), i);
+ ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), i);
if (ret >= 0)
p[i] = ret;
}
+
+ mutex_unlock(&ps->smi_mutex);
}
static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset,
--
2.8.2
[toc] | [prev] | [next] | [standalone]
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 02/20] net: dsa: mv88e6xxx: factorize PHY indirect access |
| Message-ID | <rvAfN-Dg-49@gated-at.bofh.it> |
| In reply to | #1395440 |
Some switch has dedicated SMI PHY Command and Data registers, used to
indirectly access the PHYs, instead of direct access.
Identify these switch models and make mv88e6xxx_phy_{read,write} generic
enough to support every models.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6171.c | 8 ++++++--
drivers/net/dsa/mv88e6352.c | 10 ++++++++--
drivers/net/dsa/mv88e6xxx.c | 37 ++++---------------------------------
drivers/net/dsa/mv88e6xxx.h | 10 +++++++---
4 files changed, 25 insertions(+), 40 deletions(-)
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index f75164d..304e25e 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,24 +24,28 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.name = "Marvell 88E6171",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6175",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6350",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6351",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}
};
@@ -120,8 +124,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
.probe = mv88e6171_drv_probe,
.setup = mv88e6171_setup,
.set_addr = mv88e6xxx_set_addr_indirect,
- .phy_read = mv88e6xxx_phy_read_indirect,
- .phy_write = mv88e6xxx_phy_write_indirect,
+ .phy_read = mv88e6xxx_phy_read,
+ .phy_write = mv88e6xxx_phy_write,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index c622a1d..df9f944 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -29,36 +29,42 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6320",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6321",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6172",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6176",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6240",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6352",
.num_databases = 4096,
.num_ports = 7,
+ .flags = MV88E6XXX_FLAG_SMI_PHY,
}
};
@@ -338,8 +344,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.probe = mv88e6352_drv_probe,
.setup = mv88e6352_setup,
.set_addr = mv88e6xxx_set_addr_indirect,
- .phy_read = mv88e6xxx_phy_read_indirect,
- .phy_write = mv88e6xxx_phy_write_indirect,
+ .phy_read = mv88e6xxx_phy_read,
+ .phy_write = mv88e6xxx_phy_write,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 4e031aa..e48271c 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2868,6 +2868,8 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
ret = _mv88e6xxx_phy_read_ppu(ps, addr, regnum);
+ else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
+ ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
else
ret = _mv88e6xxx_phy_read(ps, addr, regnum);
@@ -2891,6 +2893,8 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
err = _mv88e6xxx_phy_write_ppu(ps, addr, regnum, val);
+ else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
+ err = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
else
err = _mv88e6xxx_phy_write(ps, addr, regnum, val);
@@ -2899,39 +2903,6 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
return err;
}
-int
-mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int addr = mv88e6xxx_port_to_phy_addr(ps, port);
- int ret;
-
- if (addr < 0)
- return 0xffff;
-
- mutex_lock(&ps->smi_mutex);
- ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
- mutex_unlock(&ps->smi_mutex);
- return ret;
-}
-
-int
-mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
- u16 val)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int addr = mv88e6xxx_port_to_phy_addr(ps, port);
- int ret;
-
- if (addr < 0)
- return addr;
-
- mutex_lock(&ps->smi_mutex);
- ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
- mutex_unlock(&ps->smi_mutex);
- return ret;
-}
-
#ifdef CONFIG_NET_DSA_HWMON
static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 3e77985..95cbb8b 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -355,10 +355,17 @@ enum mv88e6xxx_cap {
* See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
*/
MV88E6XXX_CAP_PPU,
+
+ /* SMI PHY Command and Data registers.
+ * This requires an indirect access to PHY registers through
+ * GLOBAL2_SMI_OP, otherwise direct access to PHY registers is done.
+ */
+ MV88E6XXX_CAP_SMI_PHY,
};
/* Bitmask of capabilities */
#define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU)
+#define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY)
struct mv88e6xxx_info {
enum mv88e6xxx_family family;
@@ -480,9 +487,6 @@ int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
-int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum);
-int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
- u16 val);
void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
uint64_t *data);
--
2.8.2
[toc] | [prev] | [next] | [standalone]
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-05-06 00:50 +0200 |
| Subject | [RFC PATCH net-next 03/20] net: dsa: mv88e6xxx: factorize EEPROM access |
| Message-ID | <rvAfN-Dg-45@gated-at.bofh.it> |
| In reply to | #1395440 |
Add a MV88E6XXX_FLAG_EEPROM flag to describe switch models featuring an
EEPROM and distribute the EEPROM access routines to all models.
In the meantime, change the static functions to use a
mv88e6xxx_priv_state instead of a dsa_switch.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 2 +
drivers/net/dsa/mv88e6131.c | 2 +
drivers/net/dsa/mv88e6171.c | 2 +
drivers/net/dsa/mv88e6352.c | 225 +++-------------------------------------
drivers/net/dsa/mv88e6xxx.c | 248 +++++++++++++++++++++++++++++++++++++++++---
drivers/net/dsa/mv88e6xxx.h | 12 ++-
6 files changed, 264 insertions(+), 227 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 5535a42..1fc8f0d 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -121,6 +121,8 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
#ifdef CONFIG_NET_DSA_HWMON
.get_temp = mv88e6xxx_get_temp,
#endif
+ .get_eeprom = mv88e6xxx_get_eeprom,
+ .set_eeprom = mv88e6xxx_set_eeprom,
.get_regs_len = mv88e6xxx_get_regs_len,
.get_regs = mv88e6xxx_get_regs,
};
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 437faf8..3796f6d 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -153,6 +153,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
+ .get_eeprom = mv88e6xxx_get_eeprom,
+ .set_eeprom = mv88e6xxx_set_eeprom,
.adjust_link = mv88e6xxx_adjust_link,
.port_bridge_join = mv88e6xxx_port_bridge_join,
.port_bridge_leave = mv88e6xxx_port_bridge_leave,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 304e25e..b8b6902 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -133,6 +133,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
#ifdef CONFIG_NET_DSA_HWMON
.get_temp = mv88e6xxx_get_temp,
#endif
+ .get_eeprom = mv88e6xxx_get_eeprom,
+ .set_eeprom = mv88e6xxx_set_eeprom,
.get_regs_len = mv88e6xxx_get_regs_len,
.get_regs = mv88e6xxx_get_regs,
.port_bridge_join = mv88e6xxx_port_bridge_join,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index df9f944..e6437de 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -29,42 +29,48 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.name = "Marvell 88E6320",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY,
+ .flags = MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6321",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY,
+ .flags = MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6172",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY,
+ .flags = MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6176",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY,
+ .flags = MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6240",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY,
+ .flags = MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_SMI_PHY,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6352",
.num_databases = 4096,
.num_ports = 7,
- .flags = MV88E6XXX_FLAG_SMI_PHY,
+ .flags = MV88E6XXX_FLAG_EEPROM |
+ MV88E6XXX_FLAG_SMI_PHY,
}
};
@@ -125,8 +131,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
if (ret < 0)
return ret;
- mutex_init(&ps->eeprom_mutex);
-
ret = mv88e6xxx_switch_reset(ps, true);
if (ret < 0)
return ret;
@@ -138,207 +142,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
return mv88e6xxx_setup_ports(ds);
}
-static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int ret;
-
- mutex_lock(&ps->eeprom_mutex);
-
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
- GLOBAL2_EEPROM_OP_READ |
- (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
- if (ret < 0)
- goto error;
-
- ret = mv88e6xxx_eeprom_busy_wait(ds);
- if (ret < 0)
- goto error;
-
- ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA);
-error:
- mutex_unlock(&ps->eeprom_mutex);
- return ret;
-}
-
-static int mv88e6352_get_eeprom(struct dsa_switch *ds,
- struct ethtool_eeprom *eeprom, u8 *data)
-{
- int offset;
- int len;
- int ret;
-
- offset = eeprom->offset;
- len = eeprom->len;
- eeprom->len = 0;
-
- eeprom->magic = 0xc3ec4951;
-
- ret = mv88e6xxx_eeprom_load_wait(ds);
- if (ret < 0)
- return ret;
-
- if (offset & 1) {
- int word;
-
- word = mv88e6352_read_eeprom_word(ds, offset >> 1);
- if (word < 0)
- return word;
-
- *data++ = (word >> 8) & 0xff;
-
- offset++;
- len--;
- eeprom->len++;
- }
-
- while (len >= 2) {
- int word;
-
- word = mv88e6352_read_eeprom_word(ds, offset >> 1);
- if (word < 0)
- return word;
-
- *data++ = word & 0xff;
- *data++ = (word >> 8) & 0xff;
-
- offset += 2;
- len -= 2;
- eeprom->len += 2;
- }
-
- if (len) {
- int word;
-
- word = mv88e6352_read_eeprom_word(ds, offset >> 1);
- if (word < 0)
- return word;
-
- *data++ = word & 0xff;
-
- offset++;
- len--;
- eeprom->len++;
- }
-
- return 0;
-}
-
-static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int ret;
-
- ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP);
- if (ret < 0)
- return ret;
-
- if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN))
- return -EROFS;
-
- return 0;
-}
-
-static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr,
- u16 data)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int ret;
-
- mutex_lock(&ps->eeprom_mutex);
-
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
- if (ret < 0)
- goto error;
-
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
- GLOBAL2_EEPROM_OP_WRITE |
- (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
- if (ret < 0)
- goto error;
-
- ret = mv88e6xxx_eeprom_busy_wait(ds);
-error:
- mutex_unlock(&ps->eeprom_mutex);
- return ret;
-}
-
-static int mv88e6352_set_eeprom(struct dsa_switch *ds,
- struct ethtool_eeprom *eeprom, u8 *data)
-{
- int offset;
- int ret;
- int len;
-
- if (eeprom->magic != 0xc3ec4951)
- return -EINVAL;
-
- ret = mv88e6352_eeprom_is_readonly(ds);
- if (ret)
- return ret;
-
- offset = eeprom->offset;
- len = eeprom->len;
- eeprom->len = 0;
-
- ret = mv88e6xxx_eeprom_load_wait(ds);
- if (ret < 0)
- return ret;
-
- if (offset & 1) {
- int word;
-
- word = mv88e6352_read_eeprom_word(ds, offset >> 1);
- if (word < 0)
- return word;
-
- word = (*data++ << 8) | (word & 0xff);
-
- ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
- if (ret < 0)
- return ret;
-
- offset++;
- len--;
- eeprom->len++;
- }
-
- while (len >= 2) {
- int word;
-
- word = *data++;
- word |= *data++ << 8;
-
- ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
- if (ret < 0)
- return ret;
-
- offset += 2;
- len -= 2;
- eeprom->len += 2;
- }
-
- if (len) {
- int word;
-
- word = mv88e6352_read_eeprom_word(ds, offset >> 1);
- if (word < 0)
- return word;
-
- word = (word & 0xff00) | *data++;
-
- ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
- if (ret < 0)
- return ret;
-
- offset++;
- len--;
- eeprom->len++;
- }
-
- return 0;
-}
-
struct dsa_switch_driver mv88e6352_switch_driver = {
.tag_protocol = DSA_TAG_PROTO_EDSA,
.probe = mv88e6352_drv_probe,
@@ -358,8 +161,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.set_temp_limit = mv88e6xxx_set_temp_limit,
.get_temp_alarm = mv88e6xxx_get_temp_alarm,
#endif
- .get_eeprom = mv88e6352_get_eeprom,
- .set_eeprom = mv88e6352_set_eeprom,
+ .get_eeprom = mv88e6xxx_get_eeprom,
+ .set_eeprom = mv88e6xxx_set_eeprom,
.get_regs_len = mv88e6xxx_get_regs_len,
.get_regs = mv88e6xxx_get_regs,
.port_bridge_join = mv88e6xxx_port_bridge_join,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index e48271c..233c265 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -786,38 +786,255 @@ static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset,
return -ETIMEDOUT;
}
-static int mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg,
- int offset, u16 mask)
+static int _mv88e6xxx_phy_wait(struct mv88e6xxx_priv_state *ps)
+{
+ return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SMI_OP,
+ GLOBAL2_SMI_OP_BUSY);
+}
+
+static int _mv88e6xxx_eeprom_load_wait(struct mv88e6xxx_priv_state *ps)
+{
+ return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+ GLOBAL2_EEPROM_OP_LOAD);
+}
+
+static int _mv88e6xxx_eeprom_busy_wait(struct mv88e6xxx_priv_state *ps)
+{
+ return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+ GLOBAL2_EEPROM_OP_BUSY);
+}
+
+static int _mv88e6xxx_read_eeprom_word(struct mv88e6xxx_priv_state *ps,
+ int addr)
{
int ret;
- mutex_lock(&ps->smi_mutex);
- ret = _mv88e6xxx_wait(ps, reg, offset, mask);
- mutex_unlock(&ps->smi_mutex);
+ mutex_lock(&ps->eeprom_mutex);
+
+ ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+ GLOBAL2_EEPROM_OP_READ |
+ (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
+ if (ret)
+ goto unlock;
+
+ ret = _mv88e6xxx_eeprom_busy_wait(ps);
+ if (ret)
+ goto unlock;
+
+ ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA);
+unlock:
+ mutex_unlock(&ps->eeprom_mutex);
return ret;
}
-static int _mv88e6xxx_phy_wait(struct mv88e6xxx_priv_state *ps)
+static int _mv88e6xxx_get_eeprom(struct mv88e6xxx_priv_state *ps,
+ struct ethtool_eeprom *eeprom, u8 *data)
{
- return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SMI_OP,
- GLOBAL2_SMI_OP_BUSY);
+ int offset;
+ int len;
+ int ret;
+
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+ return -EOPNOTSUPP;
+
+ offset = eeprom->offset;
+ len = eeprom->len;
+ eeprom->len = 0;
+
+ eeprom->magic = 0xc3ec4951;
+
+ ret = _mv88e6xxx_eeprom_load_wait(ps);
+ if (ret < 0)
+ return ret;
+
+ if (offset & 1) {
+ int word;
+
+ word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+ if (word < 0)
+ return word;
+
+ *data++ = (word >> 8) & 0xff;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ while (len >= 2) {
+ int word;
+
+ word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+ if (word < 0)
+ return word;
+
+ *data++ = word & 0xff;
+ *data++ = (word >> 8) & 0xff;
+
+ offset += 2;
+ len -= 2;
+ eeprom->len += 2;
+ }
+
+ if (len) {
+ int word;
+
+ word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+ if (word < 0)
+ return word;
+
+ *data++ = word & 0xff;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ return 0;
}
-int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
+int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+ u8 *data)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int err;
+
+ mutex_lock(&ps->smi_mutex);
+ err = _mv88e6xxx_get_eeprom(ps, eeprom, data);
+ mutex_unlock(&ps->smi_mutex);
+
+ return err;
+}
+
+static int _mv88e6xxx_eeprom_is_readonly(struct mv88e6xxx_priv_state *ps)
+{
+ int ret;
+
+ ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP);
+ if (ret < 0)
+ return ret;
- return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
- GLOBAL2_EEPROM_OP_LOAD);
+ if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN))
+ return -EROFS;
+
+ return 0;
+}
+
+static int _mv88e6xxx_write_eeprom_word(struct mv88e6xxx_priv_state *ps,
+ int addr, u16 data)
+{
+ int err;
+
+ mutex_lock(&ps->eeprom_mutex);
+
+ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
+ if (err)
+ goto unlock;
+
+ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+ GLOBAL2_EEPROM_OP_WRITE |
+ (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
+ if (err)
+ goto unlock;
+
+ err = _mv88e6xxx_eeprom_busy_wait(ps);
+unlock:
+ mutex_unlock(&ps->eeprom_mutex);
+
+ return err;
}
-int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
+static int _mv88e6xxx_set_eeprom(struct mv88e6xxx_priv_state *ps,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int offset;
+ int ret;
+ int len;
+
+ if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+ return -EOPNOTSUPP;
+
+ if (eeprom->magic != 0xc3ec4951)
+ return -EINVAL;
+
+ ret = _mv88e6xxx_eeprom_is_readonly(ps);
+ if (ret)
+ return ret;
+
+ offset = eeprom->offset;
+ len = eeprom->len;
+ eeprom->len = 0;
+
+ ret = _mv88e6xxx_eeprom_load_wait(ps);
+ if (ret < 0)
+ return ret;
+
+ if (offset & 1) {
+ int word;
+
+ word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+ if (word < 0)
+ return word;
+
+ word = (*data++ << 8) | (word & 0xff);
+
+ ret = _mv88e6xxx_write_eeprom_word(ps, offset >> 1, word);
+ if (ret < 0)
+ return ret;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ while (len >= 2) {
+ int word;
+
+ word = *data++;
+ word |= *data++ << 8;
+
+ ret = _mv88e6xxx_write_eeprom_word(ps, offset >> 1, word);
+ if (ret < 0)
+ return ret;
+
+ offset += 2;
+ len -= 2;
+ eeprom->len += 2;
+ }
+
+ if (len) {
+ int word;
+
+ word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+ if (word < 0)
+ return word;
+
+ word = (word & 0xff00) | *data++;
+
+ ret = _mv88e6xxx_write_eeprom_word(ps, offset >> 1, word);
+ if (ret < 0)
+ return ret;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ return 0;
+}
+
+int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+ u8 *data)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int err;
- return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
- GLOBAL2_EEPROM_OP_BUSY);
+ mutex_lock(&ps->smi_mutex);
+ err = _mv88e6xxx_set_eeprom(ps, eeprom, data);
+ mutex_unlock(&ps->smi_mutex);
+
+ return err;
}
static int _mv88e6xxx_atu_wait(struct mv88e6xxx_priv_state *ps)
@@ -2577,6 +2794,9 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
+ if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+ mutex_init(&ps->eeprom_mutex);
+
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
mv88e6xxx_ppu_state_init(ps);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 95cbb8b..08cb5c4 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -351,6 +351,11 @@ enum mv88e6xxx_family {
};
enum mv88e6xxx_cap {
+ /* EEPROM Command and Data registers.
+ * See GLOBAL2_EEPROM_OP and GLOBAL2_EEPROM_DATA.
+ */
+ MV88E6XXX_CAP_EEPROM,
+
/* PHY Polling Unit.
* See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
*/
@@ -364,6 +369,7 @@ enum mv88e6xxx_cap {
};
/* Bitmask of capabilities */
+#define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM)
#define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU)
#define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY)
@@ -501,8 +507,10 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp);
int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp);
int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp);
int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm);
-int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds);
-int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds);
+int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+ u8 *data);
+int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+ u8 *data);
int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum);
int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
u16 val);
--
2.8.2
[toc] | [prev] | [next] | [standalone]
| From | Andrew Lunn <andrew@lunn.ch> |
|---|---|
| Date | 2016-05-06 03:20 +0200 |
| Subject | Re: [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver |
| Message-ID | <rvCAW-3eB-1@gated-at.bofh.it> |
| In reply to | #1395440 |
> +config NET_DSA_MV88E6XXX
> tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
> depends on NET_DSA
> - select NET_DSA_MV88E6XXX
> select NET_DSA_TAG_EDSA
> ---help---
> This enables support for the Marvell 88E6085/6095/6095F/6131
> ethernet switch chips.
Hi Vivien
You should update the list of devices. We need some text in the
tristate and help which suggests this driver supports everything
except mv88e6060.
Andrew
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web