diff mbox series

[2/2] net: dsa: mv88e6xxx: Support serdes ports on MV88E6097

Message ID 20201013021858.20530-3-chris.packham@alliedtelesis.co.nz (mailing list archive)
State Not Applicable
Headers show
Series net: dsa: mv88e6xxx: serdes link without phy | expand

Commit Message

Chris Packham Oct. 13, 2020, 2:18 a.m. UTC
Implement serdes_power, serdes_get_lane and serdes_pcs_get_state ops for
the MV88E6097 so that ports 8 & 9 can be supported as serdes ports and
directly connected to other network interfaces or to SFPs without a PHY.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---

This should be usable for all variants of the 88E6185 that have
tri-speed capable ports (which is why I used the mv88e6185 prefix
instead of mv88e6097). But my hardware only has a 88e6097 so I've only
connected up the ops for that chip.

 drivers/net/dsa/mv88e6xxx/chip.c | 61 ++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

Comments

Andrew Lunn Oct. 18, 2020, 4:16 p.m. UTC | #1
On Tue, Oct 13, 2020 at 03:18:58PM +1300, Chris Packham wrote:
> Implement serdes_power, serdes_get_lane and serdes_pcs_get_state ops for
> the MV88E6097 so that ports 8 & 9 can be supported as serdes ports and
> directly connected to other network interfaces or to SFPs without a PHY.
> 
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> ---
> 
> This should be usable for all variants of the 88E6185 that have
> tri-speed capable ports (which is why I used the mv88e6185 prefix
> instead of mv88e6097). But my hardware only has a 88e6097 so I've only
> connected up the ops for that chip.
> 
>  drivers/net/dsa/mv88e6xxx/chip.c | 61 ++++++++++++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
> index 1ef392ee52c5..1c6cd5c43eb1 100644
> --- a/drivers/net/dsa/mv88e6xxx/chip.c
> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
> @@ -3436,6 +3436,64 @@ static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
>  	return err;
>  }
>  
> +static int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
> +				  bool up)
> +{
> +	/* The serdes power can't be controlled on this switch chip but we need
> +	 * to supply this function to avoid returning -EOPNOTSUPP in
> +	 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
> +	 */

Hi Chris

How about bit 11 of the control register 0? This looks a lot like a
BMCR, and BMCR_PDOWN.

This is what mv88e6352_serdes_power() does. You might be able to even
re-use it, if you can make the lane numbers work.

      Andrew
Chris Packham Oct. 18, 2020, 8:09 p.m. UTC | #2
On 19/10/20 5:16 am, Andrew Lunn wrote:
> On Tue, Oct 13, 2020 at 03:18:58PM +1300, Chris Packham wrote:
>> Implement serdes_power, serdes_get_lane and serdes_pcs_get_state ops for
>> the MV88E6097 so that ports 8 & 9 can be supported as serdes ports and
>> directly connected to other network interfaces or to SFPs without a PHY.
>>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>> ---
>>
>> This should be usable for all variants of the 88E6185 that have
>> tri-speed capable ports (which is why I used the mv88e6185 prefix
>> instead of mv88e6097). But my hardware only has a 88e6097 so I've only
>> connected up the ops for that chip.
>>
>>   drivers/net/dsa/mv88e6xxx/chip.c | 61 ++++++++++++++++++++++++++++++++
>>   1 file changed, 61 insertions(+)
>>
>> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
>> index 1ef392ee52c5..1c6cd5c43eb1 100644
>> --- a/drivers/net/dsa/mv88e6xxx/chip.c
>> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
>> @@ -3436,6 +3436,64 @@ static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
>>   	return err;
>>   }
>>   
>> +static int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
>> +				  bool up)
>> +{
>> +	/* The serdes power can't be controlled on this switch chip but we need
>> +	 * to supply this function to avoid returning -EOPNOTSUPP in
>> +	 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
>> +	 */
> Hi Chris
>
> How about bit 11 of the control register 0? This looks a lot like a
> BMCR, and BMCR_PDOWN.
>
> This is what mv88e6352_serdes_power() does. You might be able to even
> re-use it, if you can make the lane numbers work.

I assume you're talking about the PHY Control Register 0 bit 11. If so 
that's for the internal PHYs on ports 0-7. Ports 8, 9 and 10 don't have 
PHYs.
Andrew Lunn Oct. 18, 2020, 8:25 p.m. UTC | #3
> I assume you're talking about the PHY Control Register 0 bit 11. If so 
> that's for the internal PHYs on ports 0-7. Ports 8, 9 and 10 don't have 
> PHYs.

Hi Chris

I have a datasheet for the 6122/6121, from some corner of the web,
Part 3 of 3, Gigabit PHYs and SERDES.

http://www.image.micros.com.pl/_dane_techniczne_auto/ui88e6122b2lkj1i0.pdf

Section 5 of this document talks
about the SERDES registers. Register 0 is Control, register 1 is
Status - Fiber, register 2 and 3 are the usual ID, 4 is auto-net
advertisement etc.

Where these registers appear in the address space is not clear from
this document. It is normally in document part 2 of 3, which my
searching of the web did not find.

	  Andrew
Chris Packham Oct. 18, 2020, 9:15 p.m. UTC | #4
On 19/10/20 9:25 am, Andrew Lunn wrote:
>> I assume you're talking about the PHY Control Register 0 bit 11. If so
>> that's for the internal PHYs on ports 0-7. Ports 8, 9 and 10 don't have
>> PHYs.
> Hi Chris
>
> I have a datasheet for the 6122/6121, from some corner of the web,
> Part 3 of 3, Gigabit PHYs and SERDES.
>
> http://www.image.micros.com.pl/_dane_techniczne_auto/ui88e6122b2lkj1i0.pdf
>
> Section 5 of this document talks
> about the SERDES registers. Register 0 is Control, register 1 is
> Status - Fiber, register 2 and 3 are the usual ID, 4 is auto-net
> advertisement etc.
>
> Where these registers appear in the address space is not clear from
> this document. It is normally in document part 2 of 3, which my
> searching of the web did not find.
>
> 	  Andrew

I have got the 88E6122 datasheet(s) and can see the SERDES registers 
you're talking about (I think they're in the same register space as the 
built-in PHYs). It looks like the 88E6097 is different in that there are 
no SERDES registers exposed (at least not in a documented way). Looking 
at the 88E6185 it's the same as the 88E6097.

So how do you want to move this series forward? I can test it on the 
88E6097 (and have restricted it to just that chip for now), I'm pretty 
sure it'll work on the 88E6185. I doubt it'll work on the 88E6122 but 
maybe it would with a different serdes_power function (or even the 
mv88e6352_serdes_power() as you suggested).
Andrew Lunn Oct. 18, 2020, 10:08 p.m. UTC | #5
On Sun, Oct 18, 2020 at 09:15:52PM +0000, Chris Packham wrote:
> 
> On 19/10/20 9:25 am, Andrew Lunn wrote:
> >> I assume you're talking about the PHY Control Register 0 bit 11. If so
> >> that's for the internal PHYs on ports 0-7. Ports 8, 9 and 10 don't have
> >> PHYs.
> > Hi Chris
> >
> > I have a datasheet for the 6122/6121, from some corner of the web,
> > Part 3 of 3, Gigabit PHYs and SERDES.
> >
> > http://www.image.micros.com.pl/_dane_techniczne_auto/ui88e6122b2lkj1i0.pdf
> >
> > Section 5 of this document talks
> > about the SERDES registers. Register 0 is Control, register 1 is
> > Status - Fiber, register 2 and 3 are the usual ID, 4 is auto-net
> > advertisement etc.
> >
> > Where these registers appear in the address space is not clear from
> > this document. It is normally in document part 2 of 3, which my
> > searching of the web did not find.
> >
> > 	  Andrew
> 
> I have got the 88E6122 datasheet(s) and can see the SERDES registers 
> you're talking about (I think they're in the same register space as the 
> built-in PHYs). It looks like the 88E6097 is different in that there are 
> no SERDES registers exposed (at least not in a documented way). Looking 
> at the 88E6185 it's the same as the 88E6097.

Hi Chris

I find it odd there are no SERDES registers.  Can you poke around the
register space and look for ID registers? See if there are any with
Marvells OUI, but different to the chip ID found in the port
registers?

> So how do you want to move this series forward? I can test it on the 
> 88E6097 (and have restricted it to just that chip for now), I'm pretty 
> sure it'll work on the 88E6185. I doubt it'll work on the 88E6122 but 
> maybe it would with a different serdes_power function (or even the 
> mv88e6352_serdes_power() as you suggested).

Make your best guess for what you cannot test.

     Andrew
Chris Packham Oct. 18, 2020, 10:31 p.m. UTC | #6
On 19/10/20 11:08 am, Andrew Lunn wrote:
> On Sun, Oct 18, 2020 at 09:15:52PM +0000, Chris Packham wrote:
>> On 19/10/20 9:25 am, Andrew Lunn wrote:
>>>> I assume you're talking about the PHY Control Register 0 bit 11. If so
>>>> that's for the internal PHYs on ports 0-7. Ports 8, 9 and 10 don't have
>>>> PHYs.
>>> Hi Chris
>>>
>>> I have a datasheet for the 6122/6121, from some corner of the web,
>>> Part 3 of 3, Gigabit PHYs and SERDES.
>>>
>>> http://www.image.micros.com.pl/_dane_techniczne_auto/ui88e6122b2lkj1i0.pdf
>>>
>>> Section 5 of this document talks
>>> about the SERDES registers. Register 0 is Control, register 1 is
>>> Status - Fiber, register 2 and 3 are the usual ID, 4 is auto-net
>>> advertisement etc.
>>>
>>> Where these registers appear in the address space is not clear from
>>> this document. It is normally in document part 2 of 3, which my
>>> searching of the web did not find.
>>>
>>> 	  Andrew
>> I have got the 88E6122 datasheet(s) and can see the SERDES registers
>> you're talking about (I think they're in the same register space as the
>> built-in PHYs). It looks like the 88E6097 is different in that there are
>> no SERDES registers exposed (at least not in a documented way). Looking
>> at the 88E6185 it's the same as the 88E6097.
> Hi Chris
>
> I find it odd there are no SERDES registers.  Can you poke around the
> register space and look for ID registers? See if there are any with
> Marvells OUI, but different to the chip ID found in the port
> registers?
 From my experience with Marvell I don't think it's that odd. 
Particularly for a 1G SERDES there's really not much that needs 
configuring (although power up/down would be nice). I'll poke around 
that register space to see if anything is there.
>> So how do you want to move this series forward? I can test it on the
>> 88E6097 (and have restricted it to just that chip for now), I'm pretty
>> sure it'll work on the 88E6185. I doubt it'll work on the 88E6122 but
>> maybe it would with a different serdes_power function (or even the
>> mv88e6352_serdes_power() as you suggested).
> Make your best guess for what you cannot test.
Will do. I'll expand out at least to cover the 88E6185 in v2. I can 
probably guess at the 88E6122 aside from the ability to power up/down 
the rest looks the same from glancing the datasheets.
Chris Packham Oct. 19, 2020, 2:45 a.m. UTC | #7
On 19/10/20 11:31 am, Chris Packham wrote:
>
> On 19/10/20 11:08 am, Andrew Lunn wrote:
>> On Sun, Oct 18, 2020 at 09:15:52PM +0000, Chris Packham wrote:
>>> On 19/10/20 9:25 am, Andrew Lunn wrote:
>>>>> I assume you're talking about the PHY Control Register 0 bit 11. 
>>>>> If so
>>>>> that's for the internal PHYs on ports 0-7. Ports 8, 9 and 10 don't 
>>>>> have
>>>>> PHYs.
>>>> Hi Chris
>>>>
>>>> I have a datasheet for the 6122/6121, from some corner of the web,
>>>> Part 3 of 3, Gigabit PHYs and SERDES.
>>>>
>>>> http://www.image.micros.com.pl/_dane_techniczne_auto/ui88e6122b2lkj1i0.pdf 
>>>>
>>>>
>>>> Section 5 of this document talks
>>>> about the SERDES registers. Register 0 is Control, register 1 is
>>>> Status - Fiber, register 2 and 3 are the usual ID, 4 is auto-net
>>>> advertisement etc.
>>>>
>>>> Where these registers appear in the address space is not clear from
>>>> this document. It is normally in document part 2 of 3, which my
>>>> searching of the web did not find.
>>>>
>>>>       Andrew
>>> I have got the 88E6122 datasheet(s) and can see the SERDES registers
>>> you're talking about (I think they're in the same register space as the
>>> built-in PHYs). It looks like the 88E6097 is different in that there 
>>> are
>>> no SERDES registers exposed (at least not in a documented way). Looking
>>> at the 88E6185 it's the same as the 88E6097.
>> Hi Chris
>>
>> I find it odd there are no SERDES registers.  Can you poke around the
>> register space and look for ID registers? See if there are any with
>> Marvells OUI, but different to the chip ID found in the port
>> registers?
> From my experience with Marvell I don't think it's that odd. 
> Particularly for a 1G SERDES there's really not much that needs 
> configuring (although power up/down would be nice). I'll poke around 
> that register space to see if anything is there.

I poked around what I thought would be the relevant register space and 
couldn't find anything responding to the reads.

>>> So how do you want to move this series forward? I can test it on the
>>> 88E6097 (and have restricted it to just that chip for now), I'm pretty
>>> sure it'll work on the 88E6185. I doubt it'll work on the 88E6122 but
>>> maybe it would with a different serdes_power function (or even the
>>> mv88e6352_serdes_power() as you suggested).
>> Make your best guess for what you cannot test.
> Will do. I'll expand out at least to cover the 88E6185 in v2. I can 
> probably guess at the 88E6122 aside from the ability to power up/down 
> the rest looks the same from glancing the datasheets.
diff mbox series

Patch

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 1ef392ee52c5..1c6cd5c43eb1 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3436,6 +3436,64 @@  static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
 	return err;
 }
 
+static int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
+				  bool up)
+{
+	/* The serdes power can't be controlled on this switch chip but we need
+	 * to supply this function to avoid returning -EOPNOTSUPP in
+	 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
+	 */
+	return 0;
+}
+
+static u8 mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
+{
+	switch (chip->ports[port].cmode) {
+	case MV88E6185_PORT_STS_CMODE_SERDES:
+	case MV88E6185_PORT_STS_CMODE_1000BASE_X:
+		return port;
+	default:
+		return 0;
+	}
+}
+
+static int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
+					  u8 lane, struct phylink_link_state *state)
+{
+	int err;
+	u16 status;
+
+	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
+	if (err)
+		return err;
+
+	state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
+
+	if (state->link) {
+		state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
+
+		switch (status &  MV88E6XXX_PORT_STS_SPEED_MASK) {
+		case MV88E6XXX_PORT_STS_SPEED_1000:
+			state->speed = SPEED_1000;
+			break;
+		case MV88E6XXX_PORT_STS_SPEED_100:
+			state->speed = SPEED_100;
+			break;
+		case MV88E6XXX_PORT_STS_SPEED_10:
+			state->speed = SPEED_10;
+			break;
+		default:
+			dev_err(chip->dev, "invalid PHY speed\n");
+			return -EINVAL;
+		}
+	} else {
+		state->duplex = DUPLEX_UNKNOWN;
+		state->speed = SPEED_UNKNOWN;
+	}
+
+	return 0;
+}
+
 static const struct mv88e6xxx_ops mv88e6085_ops = {
 	/* MV88E6XXX_FAMILY_6097 */
 	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
@@ -3534,6 +3592,9 @@  static const struct mv88e6xxx_ops mv88e6097_ops = {
 	.set_egress_port = mv88e6095_g1_set_egress_port,
 	.watchdog_ops = &mv88e6097_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
+	.serdes_power = mv88e6185_serdes_power,
+	.serdes_get_lane = mv88e6185_serdes_get_lane,
+	.serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6085_g1_rmu_disable,