[net-next,2/2] net: dsa: mv88e6xxx: enable support for 88E6361 switch

Message ID 20230517203430.448705-3-alexis.lothore@bootlin.com
State New
Headers
Series net: dsa: mv88e6xxx: add 88E6361 support |

Commit Message

Alexis Lothoré May 17, 2023, 8:34 p.m. UTC
  From: Alexis Lothoré <alexis.lothore@bootlin.com>

Marvell 88E6361 is an 8-port switch derived from the
88E6393X/88E9193X/88E6191X switches family. It can benefit from the
existing mv88e6xxx driver by simply adding the proper switch description in
the driver. Main differences with other switches from this
family are:
- 8 ports exposed (instead of 11): ports 1, 2 and 8 not available
- No 5GBase-x nor SFI/USXGMII support

Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 25 +++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/chip.h |  3 ++-
 drivers/net/dsa/mv88e6xxx/port.h |  1 +
 3 files changed, 28 insertions(+), 1 deletion(-)
  

Comments

Andrew Lunn May 17, 2023, 8:51 p.m. UTC | #1
On Wed, May 17, 2023 at 10:34:30PM +0200, alexis.lothore@bootlin.com wrote:
> From: Alexis Lothoré <alexis.lothore@bootlin.com>
> 
> Marvell 88E6361 is an 8-port switch derived from the
> 88E6393X/88E9193X/88E6191X switches family. It can benefit from the
> existing mv88e6xxx driver by simply adding the proper switch description in
> the driver. Main differences with other switches from this
> family are:
> - 8 ports exposed (instead of 11): ports 1, 2 and 8 not available
> - No 5GBase-x nor SFI/USXGMII support

So what exactly is supported for link modes?

The way you reuse the 6393 ops, are these differences actually
enforced? It looks like mv88e6393x_phylink_get_caps() will allow
2500BaseX, 5GBaseX and 10GBaseR for port 10.

> +	[MV88E6361] = {
> +		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
> +		.family = MV88E6XXX_FAMILY_6393,
> +		.name = "Marvell 88E6361",
> +		.num_databases = 4096,
> +		.num_macs = 16384,
> +		.num_ports = 11,
> +		/* Ports 1, 2 and 8 are not routed */
> +		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
> +		.num_internal_phys = 5,

Which ports have internal PHYs? 2, 3, 4, 5, 6, 7 ?  What does
mv88e6xxx_phy_is_internal() return for these ports, and
mv88e6xxx_get_capsmv88e6xxx_get_caps()? I'm wondering if you actually
need to list 8 here?

     Andrew
  
Alexis Lothoré May 18, 2023, 9:11 a.m. UTC | #2
Hello Andrew, thanks for the prompt review !

On 5/17/23 22:51, Andrew Lunn wrote:
> On Wed, May 17, 2023 at 10:34:30PM +0200, alexis.lothore@bootlin.com wrote:
>> From: Alexis Lothoré <alexis.lothore@bootlin.com>
>>
>> Marvell 88E6361 is an 8-port switch derived from the
>> 88E6393X/88E9193X/88E6191X switches family. It can benefit from the
>> existing mv88e6xxx driver by simply adding the proper switch description in
>> the driver. Main differences with other switches from this
>> family are:
>> - 8 ports exposed (instead of 11): ports 1, 2 and 8 not available
>> - No 5GBase-x nor SFI/USXGMII support
> 
> So what exactly is supported for link modes?
> 
> The way you reuse the 6393 ops, are these differences actually
> enforced? It looks like mv88e6393x_phylink_get_caps() will allow
> 2500BaseX, 5GBaseX and 10GBaseR for port 10.

You are right, mv88e6393x_phylink_get_caps is currently too "generous" with
capabilities for 88E6361. With this chip, supported links modes are the following:
- port 0: MII, RMII, RGMII, 1000BaseX, 2500BaseX
- port 3 to 7: triple speed internal phys
- port 9 and 10: 1000BaseX, 25000BaseX
I'll add those specifications in cover letter for next revision for this series.
So indeed reported capabilities are wrong, I will update it. Taking a quick look
at other ops, I guess I'll have to fix some others too like
mv88e6393x_port_max_speed_mode
> 
>> +	[MV88E6361] = {
>> +		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
>> +		.family = MV88E6XXX_FAMILY_6393,
>> +		.name = "Marvell 88E6361",
>> +		.num_databases = 4096,
>> +		.num_macs = 16384,
>> +		.num_ports = 11,
>> +		/* Ports 1, 2 and 8 are not routed */
>> +		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
>> +		.num_internal_phys = 5,
> 
> Which ports have internal PHYs? 2, 3, 4, 5, 6, 7 ?  What does
> mv88e6xxx_phy_is_internal() return for these ports, and
> mv88e6xxx_get_capsmv88e6xxx_get_caps()? I'm wondering if you actually
> need to list 8 here?

Indeed there is something wrong here too. I need to tune
mv88e6393x_phylink_get_caps to reflect 88E6361 differences.

As stated above, port 3 to 7 are the ones with internal PHY.
For mv88e6xxx_phy_is_internal, I see that it is merely comparing the port index
to the number of internal phys, so in this case it would advertise (wrongly)
that ports 0 to 4 have internal phys. I also see that your suggestion (setting
num_interal_phys to max internal phy index + 1) is already in use for this
family (6393X has 8 internal phys but defines num_internal_phys to 9), so if
it's acceptable I will do as you suggest and set it to 8.

Thanks,
Alexis

> 
>      Andrew
  
Andrew Lunn May 18, 2023, 12:58 p.m. UTC | #3
> >> +	[MV88E6361] = {
> >> +		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
> >> +		.family = MV88E6XXX_FAMILY_6393,
> >> +		.name = "Marvell 88E6361",
> >> +		.num_databases = 4096,
> >> +		.num_macs = 16384,
> >> +		.num_ports = 11,
> >> +		/* Ports 1, 2 and 8 are not routed */
> >> +		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
> >> +		.num_internal_phys = 5,
> > 
> > Which ports have internal PHYs? 2, 3, 4, 5, 6, 7 ?  What does
> > mv88e6xxx_phy_is_internal() return for these ports, and
> > mv88e6xxx_get_capsmv88e6xxx_get_caps()? I'm wondering if you actually
> > need to list 8 here?
> 
> Indeed there is something wrong here too. I need to tune
> mv88e6393x_phylink_get_caps to reflect 88E6361 differences.
> 
> As stated above, port 3 to 7 are the ones with internal PHY.
> For mv88e6xxx_phy_is_internal, I see that it is merely comparing the port index
> to the number of internal phys, so in this case it would advertise (wrongly)
> that ports 0 to 4 have internal phys.

Ports 1 and 2 should hopefully be protected by the
invalid_port_mask. It should not even be possible to create those
ports. port 0 is interesting, and possibly currently broken on
6393. Please take a look at that.

    Andrew

---
pw-bot: cr
  
Marek Behún May 19, 2023, 12:38 p.m. UTC | #4
On Thu, 18 May 2023 14:58:00 +0200
Andrew Lunn <andrew@lunn.ch> wrote:

> > >> +	[MV88E6361] = {
> > >> +		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
> > >> +		.family = MV88E6XXX_FAMILY_6393,
> > >> +		.name = "Marvell 88E6361",
> > >> +		.num_databases = 4096,
> > >> +		.num_macs = 16384,
> > >> +		.num_ports = 11,
> > >> +		/* Ports 1, 2 and 8 are not routed */
> > >> +		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
> > >> +		.num_internal_phys = 5,  
> > > 
> > > Which ports have internal PHYs? 2, 3, 4, 5, 6, 7 ?  What does
> > > mv88e6xxx_phy_is_internal() return for these ports, and
> > > mv88e6xxx_get_capsmv88e6xxx_get_caps()? I'm wondering if you actually
> > > need to list 8 here?  
> > 
> > Indeed there is something wrong here too. I need to tune
> > mv88e6393x_phylink_get_caps to reflect 88E6361 differences.
> > 
> > As stated above, port 3 to 7 are the ones with internal PHY.
> > For mv88e6xxx_phy_is_internal, I see that it is merely comparing the port index
> > to the number of internal phys, so in this case it would advertise (wrongly)
> > that ports 0 to 4 have internal phys.  
> 
> Ports 1 and 2 should hopefully be protected by the
> invalid_port_mask. It should not even be possible to create those
> ports. port 0 is interesting, and possibly currently broken on
> 6393. Please take a look at that.

Why would port 0 be broken on 6393x ?

Marek
  
Alexis Lothoré May 19, 2023, 1:16 p.m. UTC | #5
On 5/19/23 14:38, Marek Behún wrote:
> On Thu, 18 May 2023 14:58:00 +0200
> Andrew Lunn <andrew@lunn.ch> wrote:
> 
>>>>> +	[MV88E6361] = {
>>>>> +		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
>>>>> +		.family = MV88E6XXX_FAMILY_6393,
>>>>> +		.name = "Marvell 88E6361",
>>>>> +		.num_databases = 4096,
>>>>> +		.num_macs = 16384,
>>>>> +		.num_ports = 11,
>>>>> +		/* Ports 1, 2 and 8 are not routed */
>>>>> +		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
>>>>> +		.num_internal_phys = 5,  
>>>>
>>>> Which ports have internal PHYs? 2, 3, 4, 5, 6, 7 ?  What does
>>>> mv88e6xxx_phy_is_internal() return for these ports, and
>>>> mv88e6xxx_get_capsmv88e6xxx_get_caps()? I'm wondering if you actually
>>>> need to list 8 here?  
>>>
>>> Indeed there is something wrong here too. I need to tune
>>> mv88e6393x_phylink_get_caps to reflect 88E6361 differences.
>>>
>>> As stated above, port 3 to 7 are the ones with internal PHY.
>>> For mv88e6xxx_phy_is_internal, I see that it is merely comparing the port index
>>> to the number of internal phys, so in this case it would advertise (wrongly)
>>> that ports 0 to 4 have internal phys.  
>>
>> Ports 1 and 2 should hopefully be protected by the
>> invalid_port_mask. It should not even be possible to create those
>> ports. port 0 is interesting, and possibly currently broken on
>> 6393. Please take a look at that.
> 
> Why would port 0 be broken on 6393x ?
By "broken", I guess Andrew means that if we feed port 0 to
mv88e6xxx_phy_is_internal, it will return true, which is wrong since there is no
internal phy for port 0 on 6393X ?
> 
> Marek
  
Andrew Lunn May 19, 2023, 1:30 p.m. UTC | #6
> >> Ports 1 and 2 should hopefully be protected by the
> >> invalid_port_mask. It should not even be possible to create those
> >> ports. port 0 is interesting, and possibly currently broken on
> >> 6393. Please take a look at that.
> > 
> > Why would port 0 be broken on 6393x ?
> By "broken", I guess Andrew means that if we feed port 0 to
> mv88e6xxx_phy_is_internal, it will return true, which is wrong since there is no
> internal phy for port 0 on 6393X ?

Yes, that is what i was thinking. But i did not spend the time to look
at the code see if this is actually true. There might be a special
case somewhere in the code.

But in general, we try to avoid special cases, and add device specific
ops.

	Andrew
  
Marek Behún May 19, 2023, 1:32 p.m. UTC | #7
On Fri, 19 May 2023 15:16:57 +0200
Alexis Lothoré <alexis.lothore@bootlin.com> wrote:

> On 5/19/23 14:38, Marek Behún wrote:
> > On Thu, 18 May 2023 14:58:00 +0200
> > Andrew Lunn <andrew@lunn.ch> wrote:
> >   
> >>>>> +	[MV88E6361] = {
> >>>>> +		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
> >>>>> +		.family = MV88E6XXX_FAMILY_6393,
> >>>>> +		.name = "Marvell 88E6361",
> >>>>> +		.num_databases = 4096,
> >>>>> +		.num_macs = 16384,
> >>>>> +		.num_ports = 11,
> >>>>> +		/* Ports 1, 2 and 8 are not routed */
> >>>>> +		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
> >>>>> +		.num_internal_phys = 5,    
> >>>>
> >>>> Which ports have internal PHYs? 2, 3, 4, 5, 6, 7 ?  What does
> >>>> mv88e6xxx_phy_is_internal() return for these ports, and
> >>>> mv88e6xxx_get_capsmv88e6xxx_get_caps()? I'm wondering if you actually
> >>>> need to list 8 here?    
> >>>
> >>> Indeed there is something wrong here too. I need to tune
> >>> mv88e6393x_phylink_get_caps to reflect 88E6361 differences.
> >>>
> >>> As stated above, port 3 to 7 are the ones with internal PHY.
> >>> For mv88e6xxx_phy_is_internal, I see that it is merely comparing the port index
> >>> to the number of internal phys, so in this case it would advertise (wrongly)
> >>> that ports 0 to 4 have internal phys.    
> >>
> >> Ports 1 and 2 should hopefully be protected by the
> >> invalid_port_mask. It should not even be possible to create those
> >> ports. port 0 is interesting, and possibly currently broken on
> >> 6393. Please take a look at that.  
> > 
> > Why would port 0 be broken on 6393x ?  
> By "broken", I guess Andrew means that if we feed port 0 to
> mv88e6xxx_phy_is_internal, it will return true, which is wrong since there is no
> internal phy for port 0 on 6393X ?

OK that's true :)
  

Patch

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 64a2f2f83735..0be7135fa39d 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -6309,6 +6309,31 @@  static const struct mv88e6xxx_info mv88e6xxx_table[] = {
 		.ptp_support = true,
 		.ops = &mv88e6352_ops,
 	},
+	[MV88E6361] = {
+		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
+		.family = MV88E6XXX_FAMILY_6393,
+		.name = "Marvell 88E6361",
+		.num_databases = 4096,
+		.num_macs = 16384,
+		.num_ports = 11,
+		/* Ports 1, 2 and 8 are not routed */
+		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
+		.num_internal_phys = 5,
+		.max_vid = 4095,
+		.max_sid = 63,
+		.port_base_addr = 0x0,
+		.phy_base_addr = 0x0,
+		.global1_addr = 0x1b,
+		.global2_addr = 0x1c,
+		.age_time_coeff = 3750,
+		.g1_irqs = 10,
+		.g2_irqs = 14,
+		.atu_move_port_mask = 0x1f,
+		.pvt = true,
+		.multi_chip = true,
+		.ptp_support = true,
+		.ops = &mv88e6393x_ops,
+	},
 	[MV88E6390] = {
 		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
 		.family = MV88E6XXX_FAMILY_6390,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index da6e1339f809..c88e52e355a5 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -82,6 +82,7 @@  enum mv88e6xxx_model {
 	MV88E6350,
 	MV88E6351,
 	MV88E6352,
+	MV88E6361,
 	MV88E6390,
 	MV88E6390X,
 	MV88E6393X,
@@ -100,7 +101,7 @@  enum mv88e6xxx_family {
 	MV88E6XXX_FAMILY_6351,	/* 6171 6175 6350 6351 */
 	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
 	MV88E6XXX_FAMILY_6390,  /* 6190 6190X 6191 6290 6390 6390X */
-	MV88E6XXX_FAMILY_6393,	/* 6191X 6193X 6393X */
+	MV88E6XXX_FAMILY_6393,	/* 6191X 6193X 6361 6393X */
 };
 
 /**
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index aec9d4fd20e3..22e2147c29a7 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -138,6 +138,7 @@ 
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6141	0x3400
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6341	0x3410
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6352	0x3520
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6361	0x2610
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6350	0x3710
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6351	0x3750
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6390	0x3900