diff mbox series

[net-next,4/7] net: pcs: xpcs: adapt Wangxun NICs for SGMII mode

Message ID 20230724102341.10401-5-jiawenwu@trustnetic.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series support more link mode for TXGBE | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1342 this patch: 1342
netdev/cc_maintainers warning 4 maintainers not CCed: kuba@kernel.org edumazet@google.com davem@davemloft.net pabeni@redhat.com
netdev/build_clang success Errors and warnings before: 1365 this patch: 1365
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1365 this patch: 1365
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 105 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jiawen Wu July 24, 2023, 10:23 a.m. UTC
Wangxun NICs support the connection with SFP to RJ45 module. In this case,
PCS need to be configured in SGMII mode.

Accroding to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores
Ethernet PCS (version 3.20a) and custom design manual, do the following
configuration when the interface mode is SGMII.

1. program VR_MII_AN_CTRL bit(3) [TX_CONFIG] = 1b (PHY side SGMII)
2. program VR_MII_AN_CTRL bit(8) [MII_CTRL] = 1b (8-bit MII)
3. program VR_MII_DIG_CTRL1 bit(0) [PHY_MODE_CTRL] = 1b

Also CL37 AN in backplane configurations need to be enabled because of the
special hardware design. Another thing to note is that PMA needs to be
reconfigured before each CL37 AN configuration for SGMII, otherwise AN will
fail, although we don't know why.

On this device, CL37_ANSGM_STS (bit[4:1] of VR_MII_AN_INTR_STS) indicates
the status received from remote link during the auto-negotiation, and
self-clear after the auto-negotiation is complete.
Meanwhile, CL37_ANCMPLT_INTR will be set to 1, to indicate CL37 AN is
complete. So add another way to get the state for CL37 SGMII.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 drivers/net/pcs/pcs-xpcs-wx.c |  5 ++--
 drivers/net/pcs/pcs-xpcs.c    | 46 ++++++++++++++++++++++++++++++++---
 drivers/net/pcs/pcs-xpcs.h    |  6 +++++
 3 files changed, 51 insertions(+), 6 deletions(-)

Comments

Russell King (Oracle) July 24, 2023, 10:34 a.m. UTC | #1
On Mon, Jul 24, 2023 at 06:23:38PM +0800, Jiawen Wu wrote:
> Wangxun NICs support the connection with SFP to RJ45 module. In this case,
> PCS need to be configured in SGMII mode.
> 
> Accroding to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores
> Ethernet PCS (version 3.20a) and custom design manual, do the following
> configuration when the interface mode is SGMII.
> 
> 1. program VR_MII_AN_CTRL bit(3) [TX_CONFIG] = 1b (PHY side SGMII)
> 2. program VR_MII_AN_CTRL bit(8) [MII_CTRL] = 1b (8-bit MII)
> 3. program VR_MII_DIG_CTRL1 bit(0) [PHY_MODE_CTRL] = 1b

I'm confused by "PHY side SGMII" - what does this mean for the
transmitted 16-bit configuration word? Does it mean that _this_ side
is acting as if it were a PHY?

Thanks.
Jiawen Wu July 25, 2023, 2:05 a.m. UTC | #2
On Monday, July 24, 2023 6:35 PM, Russell King (Oracle) wrote:
> On Mon, Jul 24, 2023 at 06:23:38PM +0800, Jiawen Wu wrote:
> > Wangxun NICs support the connection with SFP to RJ45 module. In this case,
> > PCS need to be configured in SGMII mode.
> >
> > Accroding to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores
> > Ethernet PCS (version 3.20a) and custom design manual, do the following
> > configuration when the interface mode is SGMII.
> >
> > 1. program VR_MII_AN_CTRL bit(3) [TX_CONFIG] = 1b (PHY side SGMII)
> > 2. program VR_MII_AN_CTRL bit(8) [MII_CTRL] = 1b (8-bit MII)
> > 3. program VR_MII_DIG_CTRL1 bit(0) [PHY_MODE_CTRL] = 1b
> 
> I'm confused by "PHY side SGMII" - what does this mean for the
> transmitted 16-bit configuration word? Does it mean that _this_ side
> is acting as if it were a PHY?

I'm not sure, because the datasheet doesn't explicitly describe it. In this
case, the PHY is integrated in the SFP to RJ45 module. From my point of
view, TX control occurs on the PHY side. So program it as PHY side SGMII.
Russell King (Oracle) July 25, 2023, 7:48 a.m. UTC | #3
On Tue, Jul 25, 2023 at 10:05:05AM +0800, Jiawen Wu wrote:
> On Monday, July 24, 2023 6:35 PM, Russell King (Oracle) wrote:
> > On Mon, Jul 24, 2023 at 06:23:38PM +0800, Jiawen Wu wrote:
> > > Wangxun NICs support the connection with SFP to RJ45 module. In this case,
> > > PCS need to be configured in SGMII mode.
> > >
> > > Accroding to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores
> > > Ethernet PCS (version 3.20a) and custom design manual, do the following
> > > configuration when the interface mode is SGMII.
> > >
> > > 1. program VR_MII_AN_CTRL bit(3) [TX_CONFIG] = 1b (PHY side SGMII)
> > > 2. program VR_MII_AN_CTRL bit(8) [MII_CTRL] = 1b (8-bit MII)
> > > 3. program VR_MII_DIG_CTRL1 bit(0) [PHY_MODE_CTRL] = 1b
> > 
> > I'm confused by "PHY side SGMII" - what does this mean for the
> > transmitted 16-bit configuration word? Does it mean that _this_ side
> > is acting as if it were a PHY?
> 
> I'm not sure, because the datasheet doesn't explicitly describe it. In this
> case, the PHY is integrated in the SFP to RJ45 module. From my point of
> view, TX control occurs on the PHY side. So program it as PHY side SGMII.

Let me ask the question a different way. Would you use "PHY side SGMII"
if the PHY was directly connected to the PCS with SGMII?
Jiawen Wu July 25, 2023, 9:50 a.m. UTC | #4
On Tuesday, July 25, 2023 3:49 PM, Russell King (Oracle) wrote:
> On Tue, Jul 25, 2023 at 10:05:05AM +0800, Jiawen Wu wrote:
> > On Monday, July 24, 2023 6:35 PM, Russell King (Oracle) wrote:
> > > On Mon, Jul 24, 2023 at 06:23:38PM +0800, Jiawen Wu wrote:
> > > > Wangxun NICs support the connection with SFP to RJ45 module. In this case,
> > > > PCS need to be configured in SGMII mode.
> > > >
> > > > Accroding to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores
> > > > Ethernet PCS (version 3.20a) and custom design manual, do the following
> > > > configuration when the interface mode is SGMII.
> > > >
> > > > 1. program VR_MII_AN_CTRL bit(3) [TX_CONFIG] = 1b (PHY side SGMII)
> > > > 2. program VR_MII_AN_CTRL bit(8) [MII_CTRL] = 1b (8-bit MII)
> > > > 3. program VR_MII_DIG_CTRL1 bit(0) [PHY_MODE_CTRL] = 1b
> > >
> > > I'm confused by "PHY side SGMII" - what does this mean for the
> > > transmitted 16-bit configuration word? Does it mean that _this_ side
> > > is acting as if it were a PHY?
> >
> > I'm not sure, because the datasheet doesn't explicitly describe it. In this
> > case, the PHY is integrated in the SFP to RJ45 module. From my point of
> > view, TX control occurs on the PHY side. So program it as PHY side SGMII.
> 
> Let me ask the question a different way. Would you use "PHY side SGMII"
> if the PHY was directly connected to the PCS with SGMII?

The information obtained from the IC designer is that "PHY/MAC side SGMII"
is configured by experimentation. For these different kinds of NICs:
1) fiber + SFP-RJ45 module: PHY side SGMII
2) copper (pcs + external PHY): MAC side SGMII
3) backplane: PHY side SGMII

Backplane is not supported in the driver yet. If consider the "side" as "acting"
point, case 1 (this patch implement) seems more like "MAC side SGMII". But
in practice, it won't work.
Russell King (Oracle) July 25, 2023, 9:58 a.m. UTC | #5
On Tue, Jul 25, 2023 at 05:50:36PM +0800, Jiawen Wu wrote:
> On Tuesday, July 25, 2023 3:49 PM, Russell King (Oracle) wrote:
> > On Tue, Jul 25, 2023 at 10:05:05AM +0800, Jiawen Wu wrote:
> > > On Monday, July 24, 2023 6:35 PM, Russell King (Oracle) wrote:
> > > > On Mon, Jul 24, 2023 at 06:23:38PM +0800, Jiawen Wu wrote:
> > > > > Wangxun NICs support the connection with SFP to RJ45 module. In this case,
> > > > > PCS need to be configured in SGMII mode.
> > > > >
> > > > > Accroding to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores
> > > > > Ethernet PCS (version 3.20a) and custom design manual, do the following
> > > > > configuration when the interface mode is SGMII.
> > > > >
> > > > > 1. program VR_MII_AN_CTRL bit(3) [TX_CONFIG] = 1b (PHY side SGMII)
> > > > > 2. program VR_MII_AN_CTRL bit(8) [MII_CTRL] = 1b (8-bit MII)
> > > > > 3. program VR_MII_DIG_CTRL1 bit(0) [PHY_MODE_CTRL] = 1b
> > > >
> > > > I'm confused by "PHY side SGMII" - what does this mean for the
> > > > transmitted 16-bit configuration word? Does it mean that _this_ side
> > > > is acting as if it were a PHY?
> > >
> > > I'm not sure, because the datasheet doesn't explicitly describe it. In this
> > > case, the PHY is integrated in the SFP to RJ45 module. From my point of
> > > view, TX control occurs on the PHY side. So program it as PHY side SGMII.
> > 
> > Let me ask the question a different way. Would you use "PHY side SGMII"
> > if the PHY was directly connected to the PCS with SGMII?
> 
> The information obtained from the IC designer is that "PHY/MAC side SGMII"
> is configured by experimentation. For these different kinds of NICs:
> 1) fiber + SFP-RJ45 module: PHY side SGMII
> 2) copper (pcs + external PHY): MAC side SGMII

This makes no sense. a PHY on a RJ45 SFP module is just the same as a
PHY integrated into a board with the MAC.
Russell King (Oracle) July 25, 2023, 10:08 a.m. UTC | #6
On Tue, Jul 25, 2023 at 10:58:25AM +0100, Russell King (Oracle) wrote:
> > The information obtained from the IC designer is that "PHY/MAC side SGMII"
> > is configured by experimentation. For these different kinds of NICs:
> > 1) fiber + SFP-RJ45 module: PHY side SGMII
> > 2) copper (pcs + external PHY): MAC side SGMII
> 
> This makes no sense. a PHY on a RJ45 SFP module is just the same as a
> PHY integrated into a board with the MAC.


MAC ---- PCS <----- sgmii -----> PHY (whether on a board or SFP)

Control word flow:
             <------------------ link, speed, duplex
	     ------------------> acknowledge (value = 0x4001)

Sometimes, it's possible to connect two MACs/PCSs together:

MAC ---- PCS <----- sgmii -----> PCS ---- MAC

and in this case, one PCS would need to be configured in "MAC" mode
and the other would need to be configured in "PHY" mode because SGMII
is fundamentally asymmetric.

Here is the definition of the control word sent by either end:

Bit	MAC->PHY	PHY->MAC
15	0: Reserved	Link status, 1 = link up
14	1: Acknowledge	Reserved for AN acknowledge
13	0: Reserved	0: Reserved
12	0: Reserved	Duplex mode 1 = full, 0 = half
11:10	0: Reserved	Speed 11 = Reserved 10=1G, 01=100M, 00=10M
9:1	0: Reserved	0: Reserved
0	1		1

So my guess would be that "PHY side SGMII" means the device generates
the "PHY->MAC" format word whereas "MAC side SGMII" generates the
"MAC->PHY" format word - and it's the latter that you want to be using
both for Copper SFPs, which are no different from PHYs integrated onto
the board connected with SGMII.
Jiawen Wu July 25, 2023, 10:45 a.m. UTC | #7
On Tuesday, July 25, 2023 6:08 PM, Russell King (Oracle) wrote:
> On Tue, Jul 25, 2023 at 10:58:25AM +0100, Russell King (Oracle) wrote:
> > > The information obtained from the IC designer is that "PHY/MAC side SGMII"
> > > is configured by experimentation. For these different kinds of NICs:
> > > 1) fiber + SFP-RJ45 module: PHY side SGMII
> > > 2) copper (pcs + external PHY): MAC side SGMII
> >
> > This makes no sense. a PHY on a RJ45 SFP module is just the same as a
> > PHY integrated into a board with the MAC.
> 
> 
> MAC ---- PCS <----- sgmii -----> PHY (whether on a board or SFP)
> 
> Control word flow:
>              <------------------ link, speed, duplex
> 	     ------------------> acknowledge (value = 0x4001)
> 
> Sometimes, it's possible to connect two MACs/PCSs together:
> 
> MAC ---- PCS <----- sgmii -----> PCS ---- MAC
> 
> and in this case, one PCS would need to be configured in "MAC" mode
> and the other would need to be configured in "PHY" mode because SGMII
> is fundamentally asymmetric.
> 
> Here is the definition of the control word sent by either end:
> 
> Bit	MAC->PHY	PHY->MAC
> 15	0: Reserved	Link status, 1 = link up
> 14	1: Acknowledge	Reserved for AN acknowledge
> 13	0: Reserved	0: Reserved
> 12	0: Reserved	Duplex mode 1 = full, 0 = half
> 11:10	0: Reserved	Speed 11 = Reserved 10=1G, 01=100M, 00=10M
> 9:1	0: Reserved	0: Reserved
> 0	1		1
> 
> So my guess would be that "PHY side SGMII" means the device generates
> the "PHY->MAC" format word whereas "MAC side SGMII" generates the
> "MAC->PHY" format word - and it's the latter that you want to be using
> both for Copper SFPs, which are no different from PHYs integrated onto
> the board connected with SGMII.

Thanks for the detailed explanation, I can understand it.

So I need to find out why config it in MAC mode doesn't work. When I config
it in MAC mode, PHY would not change state to callback the xpcs_get_state().
I dump the PCS register through the tool at this time, VR_MII_AN_INTR_STS
is not always the same value, sometimes AN complete, sometimes not.

I'm not sure if this is related to the anomaly, log often shows:
"i2c_designware i2c_designware.1024: timeout in disabling adapter"
Andrew Lunn July 25, 2023, 5:37 p.m. UTC | #8
> +	if (xpcs_dev_is_txgbe(xpcs))
> +		xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP);

xpcs_dev_is_txgbe(xpcs) is being used quite a bit, and its not cheep
since it is a memcmp(). So suggest you do it once and add a quirk flag
to the xpcs structure.

	Andrew
Simon Horman July 26, 2023, 12:14 p.m. UTC | #9
On Mon, Jul 24, 2023 at 06:23:38PM +0800, Jiawen Wu wrote:
> Wangxun NICs support the connection with SFP to RJ45 module. In this case,
> PCS need to be configured in SGMII mode.
> 
> Accroding to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores

nit: Accroding -> According

...
Jiawen Wu July 28, 2023, 10:11 a.m. UTC | #10
On Tuesday, July 25, 2023 6:08 PM, Russell King (Oracle) wrote:
> On Tue, Jul 25, 2023 at 10:58:25AM +0100, Russell King (Oracle) wrote:
> > > The information obtained from the IC designer is that "PHY/MAC side SGMII"
> > > is configured by experimentation. For these different kinds of NICs:
> > > 1) fiber + SFP-RJ45 module: PHY side SGMII
> > > 2) copper (pcs + external PHY): MAC side SGMII
> >
> > This makes no sense. a PHY on a RJ45 SFP module is just the same as a
> > PHY integrated into a board with the MAC.
> 
> 
> MAC ---- PCS <----- sgmii -----> PHY (whether on a board or SFP)
> 
> Control word flow:
>              <------------------ link, speed, duplex
> 	     ------------------> acknowledge (value = 0x4001)
> 
> Sometimes, it's possible to connect two MACs/PCSs together:
> 
> MAC ---- PCS <----- sgmii -----> PCS ---- MAC
> 
> and in this case, one PCS would need to be configured in "MAC" mode
> and the other would need to be configured in "PHY" mode because SGMII
> is fundamentally asymmetric.
> 
> Here is the definition of the control word sent by either end:
> 
> Bit	MAC->PHY	PHY->MAC
> 15	0: Reserved	Link status, 1 = link up
> 14	1: Acknowledge	Reserved for AN acknowledge
> 13	0: Reserved	0: Reserved
> 12	0: Reserved	Duplex mode 1 = full, 0 = half
> 11:10	0: Reserved	Speed 11 = Reserved 10=1G, 01=100M, 00=10M
> 9:1	0: Reserved	0: Reserved
> 0	1		1
> 
> So my guess would be that "PHY side SGMII" means the device generates
> the "PHY->MAC" format word whereas "MAC side SGMII" generates the
> "MAC->PHY" format word - and it's the latter that you want to be using
> both for Copper SFPs, which are no different from PHYs integrated onto
> the board connected with SGMII.

There is a question about I2C MII read ops. I see that PHY in SFP-RJ45 module
is read by i2c_mii_read_default_c22(), but it limits the msgs[0].len=1.

A description in  the SFP-RJ45 datasheet shows:
The registers are accessible through the 2-wire serial CMOS EEPROM protocol
of the ATMEL AT24C01A or equivalent. The address of the PHY is 1010110x,
where x is the R/W bit. Each register's address is 000yyyyy, where yyyyy is the
binary equivalent of the register number. Write and read operations must send
or receive 16 bits of data, so the "multi-page" access protocol must be used.

So the PHY register address should be written twice: first high 8 bits, second low
8 bits. to read the register value.

Is there a problem with which driver?
Andrew Lunn July 28, 2023, 10:24 a.m. UTC | #11
> There is a question about I2C MII read ops. I see that PHY in SFP-RJ45 module
> is read by i2c_mii_read_default_c22(), but it limits the msgs[0].len=1.
> 
> A description in  the SFP-RJ45 datasheet shows:

Please give a link to this document.

The problem with copper PHYs embedded inside SFPs is that there is no
standardised protocol to talk to them. Each PHY vendor does their own
thing. At the moment, two different protocols are supported, ROLLBALL
and the default protocol. It might be another protocol needs to be
added to support the SFP you are testing with. So we need to see the
protocol specification.

      Andrew
Russell King (Oracle) July 28, 2023, 10:33 a.m. UTC | #12
On Fri, Jul 28, 2023 at 06:11:51PM +0800, Jiawen Wu wrote:
> On Tuesday, July 25, 2023 6:08 PM, Russell King (Oracle) wrote:
> > On Tue, Jul 25, 2023 at 10:58:25AM +0100, Russell King (Oracle) wrote:
> > > > The information obtained from the IC designer is that "PHY/MAC side SGMII"
> > > > is configured by experimentation. For these different kinds of NICs:
> > > > 1) fiber + SFP-RJ45 module: PHY side SGMII
> > > > 2) copper (pcs + external PHY): MAC side SGMII
> > >
> > > This makes no sense. a PHY on a RJ45 SFP module is just the same as a
> > > PHY integrated into a board with the MAC.
> > 
> > 
> > MAC ---- PCS <----- sgmii -----> PHY (whether on a board or SFP)
> > 
> > Control word flow:
> >              <------------------ link, speed, duplex
> > 	     ------------------> acknowledge (value = 0x4001)
> > 
> > Sometimes, it's possible to connect two MACs/PCSs together:
> > 
> > MAC ---- PCS <----- sgmii -----> PCS ---- MAC
> > 
> > and in this case, one PCS would need to be configured in "MAC" mode
> > and the other would need to be configured in "PHY" mode because SGMII
> > is fundamentally asymmetric.
> > 
> > Here is the definition of the control word sent by either end:
> > 
> > Bit	MAC->PHY	PHY->MAC
> > 15	0: Reserved	Link status, 1 = link up
> > 14	1: Acknowledge	Reserved for AN acknowledge
> > 13	0: Reserved	0: Reserved
> > 12	0: Reserved	Duplex mode 1 = full, 0 = half
> > 11:10	0: Reserved	Speed 11 = Reserved 10=1G, 01=100M, 00=10M
> > 9:1	0: Reserved	0: Reserved
> > 0	1		1
> > 
> > So my guess would be that "PHY side SGMII" means the device generates
> > the "PHY->MAC" format word whereas "MAC side SGMII" generates the
> > "MAC->PHY" format word - and it's the latter that you want to be using
> > both for Copper SFPs, which are no different from PHYs integrated onto
> > the board connected with SGMII.
> 
> There is a question about I2C MII read ops. I see that PHY in SFP-RJ45 module
> is read by i2c_mii_read_default_c22(), but it limits the msgs[0].len=1.
> 
> A description in  the SFP-RJ45 datasheet shows:
> The registers are accessible through the 2-wire serial CMOS EEPROM protocol
> of the ATMEL AT24C01A or equivalent. The address of the PHY is 1010110x,
> where x is the R/W bit. Each register's address is 000yyyyy, where yyyyy is the
> binary equivalent of the register number. Write and read operations must send
> or receive 16 bits of data, so the "multi-page" access protocol must be used.
> 
> So the PHY register address should be written twice: first high 8 bits, second low
> 8 bits. to read the register value.
> 
> Is there a problem with which driver?

No there isn't, and it conforms with the above.

A read looks like this:

      Address  Data                   Address  Data     Data
Start 10101100 000yyyyy RepeatedStart 10101101 DDDDDDDD DDDDDDDD Stop
                      or Stop followed
		          by Start

The terms "Address" and "Data" here are as per the I²C specification.
You will notice that the first part has one byte of address and *one*
byte of data to convey the register address. This is what the "1" you
are referring to above is for.

For completness, a write looks like this:

      Address  Data     Data     Data
Start 10101100 000yyyyy DDDDDDDD DDDDDDDD Stop

Essentially, in all cases, when 0x56 is addressed with the data
direction in write mode, the very first byte is _always_ the register
address and the remainder contain the data. When the data direction is
in read mode, the bytes are always data.

The description you quote above is poor because it doesn't make it
clear whether "read" and "write" apply to the bus transactions or to
the device operations. However, I can assure you that what is
implemented is correct, since this is the standard small 24xx memory
device protocol, and I've been programming that on various
microcontrollers and such like for the last 30 years.

Are you seeing a problem with the data read or written to the PHY?
Jiawen Wu July 31, 2023, 1:47 a.m. UTC | #13
On Friday, July 28, 2023 6:24 PM, : Andrew Lunn wrote:
> > There is a question about I2C MII read ops. I see that PHY in SFP-RJ45 module
> > is read by i2c_mii_read_default_c22(), but it limits the msgs[0].len=1.
> >
> > A description in  the SFP-RJ45 datasheet shows:
> 
> Please give a link to this document.

https://www.alldatasheet.com/datasheet-pdf/pdf/465165/AVAGO/ABCU-5710RZ.html

> 
> The problem with copper PHYs embedded inside SFPs is that there is no
> standardised protocol to talk to them. Each PHY vendor does their own
> thing. At the moment, two different protocols are supported, ROLLBALL
> and the default protocol. It might be another protocol needs to be
> added to support the SFP you are testing with. So we need to see the
> protocol specification.
> 
>       Andrew
>
Jiawen Wu July 31, 2023, 1:58 a.m. UTC | #14
> No there isn't, and it conforms with the above.
> 
> A read looks like this:
> 
>       Address  Data                   Address  Data     Data
> Start 10101100 000yyyyy RepeatedStart 10101101 DDDDDDDD DDDDDDDD Stop
>                       or Stop followed
> 		          by Start
> 
> The terms "Address" and "Data" here are as per the I²C specification.
> You will notice that the first part has one byte of address and *one*
> byte of data to convey the register address. This is what the "1" you
> are referring to above is for.
> 
> For completness, a write looks like this:
> 
>       Address  Data     Data     Data
> Start 10101100 000yyyyy DDDDDDDD DDDDDDDD Stop
> 
> Essentially, in all cases, when 0x56 is addressed with the data
> direction in write mode, the very first byte is _always_ the register
> address and the remainder contain the data. When the data direction is
> in read mode, the bytes are always data.
> 
> The description you quote above is poor because it doesn't make it
> clear whether "read" and "write" apply to the bus transactions or to
> the device operations. However, I can assure you that what is
> implemented is correct, since this is the standard small 24xx memory
> device protocol, and I've been programming that on various
> microcontrollers and such like for the last 30 years.
> 
> Are you seeing a problem with the data read or written to the PHY?

You are right, I misunderstood it. :(
Jiawen Wu Aug. 3, 2023, 2:20 a.m. UTC | #15
> No there isn't, and it conforms with the above.
> 
> A read looks like this:
> 
>       Address  Data                   Address  Data     Data
> Start 10101100 000yyyyy RepeatedStart 10101101 DDDDDDDD DDDDDDDD Stop
>                       or Stop followed
> 		          by Start
> 
> The terms "Address" and "Data" here are as per the I²C specification.
> You will notice that the first part has one byte of address and *one*
> byte of data to convey the register address. This is what the "1" you
> are referring to above is for.
> 
> For completness, a write looks like this:
> 
>       Address  Data     Data     Data
> Start 10101100 000yyyyy DDDDDDDD DDDDDDDD Stop
> 
> Essentially, in all cases, when 0x56 is addressed with the data
> direction in write mode, the very first byte is _always_ the register
> address and the remainder contain the data. When the data direction is
> in read mode, the bytes are always data.
> 
> The description you quote above is poor because it doesn't make it
> clear whether "read" and "write" apply to the bus transactions or to
> the device operations. However, I can assure you that what is
> implemented is correct, since this is the standard small 24xx memory
> device protocol, and I've been programming that on various
> microcontrollers and such like for the last 30 years.
> 
> Are you seeing a problem with the data read or written to the PHY?

Hi Russell,

I really don't know how to deal with "MAC side SGMII", could you please
help me?

From the test results, when I config PCS in "PHY side SGMII", the link status
of PHY in copper SFP is read by I2C after AN complete. Then PHY's link up
status is informed to PHYLINK, then PCS will check its status. But when I just
change PCS to "MAC side SGMII", I2C will keep reading timeouts since AN
complete. I checked the register of PCS to confirm AN complete, but PHY's
link status would never be updated in PHYLINK.

It's kind of weird to me, how does the configuration of PCS relate to I2C?

Thanks!
Russell King (Oracle) Aug. 3, 2023, 11:10 a.m. UTC | #16
On Thu, Aug 03, 2023 at 10:20:22AM +0800, Jiawen Wu wrote:
> > No there isn't, and it conforms with the above.
> > 
> > A read looks like this:
> > 
> >       Address  Data                   Address  Data     Data
> > Start 10101100 000yyyyy RepeatedStart 10101101 DDDDDDDD DDDDDDDD Stop
> >                       or Stop followed
> > 		          by Start
> > 
> > The terms "Address" and "Data" here are as per the I²C specification.
> > You will notice that the first part has one byte of address and *one*
> > byte of data to convey the register address. This is what the "1" you
> > are referring to above is for.
> > 
> > For completness, a write looks like this:
> > 
> >       Address  Data     Data     Data
> > Start 10101100 000yyyyy DDDDDDDD DDDDDDDD Stop
> > 
> > Essentially, in all cases, when 0x56 is addressed with the data
> > direction in write mode, the very first byte is _always_ the register
> > address and the remainder contain the data. When the data direction is
> > in read mode, the bytes are always data.
> > 
> > The description you quote above is poor because it doesn't make it
> > clear whether "read" and "write" apply to the bus transactions or to
> > the device operations. However, I can assure you that what is
> > implemented is correct, since this is the standard small 24xx memory
> > device protocol, and I've been programming that on various
> > microcontrollers and such like for the last 30 years.
> > 
> > Are you seeing a problem with the data read or written to the PHY?
> 
> Hi Russell,
> 
> I really don't know how to deal with "MAC side SGMII", could you please
> help me?
> 
> From the test results, when I config PCS in "PHY side SGMII", the link status
> of PHY in copper SFP is read by I2C after AN complete. Then PHY's link up
> status is informed to PHYLINK, then PCS will check its status. But when I just
> change PCS to "MAC side SGMII", I2C will keep reading timeouts since AN
> complete. I checked the register of PCS to confirm AN complete, but PHY's
> link status would never be updated in PHYLINK.

I don't understand what is going on here either - but what I do know
is that there is _zero_ difference as far as the network link is
concerned between an on-board PHY using SGMII to the MAC/PCS and a SFP
with a PHY using SGMII.

In both situations the PHY behaves the same - it presents a PHY-side
SGMII interface, so it sends to the MAC/PCS the speed and duplex
settings, and expects the MAC/PCS to acknowledge them.

The name "MAC side SGMII" suggests that this mode provides the
acknowledgement, whereas "PHY side SGMII" suggests that this mode
provides a speed and duplex.

Given all this, using "PHY side SGMII" with a SFP, and "MAC side
SGMII" for an on-board PHY just seems utterly wrong - and I can't
make head nor tail of it.

> It's kind of weird to me, how does the configuration of PCS relate to I2C?

I2C is just the access method for PHYs on SFPs - because there are
no MDIO bus pins on SFP modules, only I2C pins mainly for accessing
the identification EEPROM and diagnostics, but many copper SFPs have
a way to access the PHY.

I2C is transparent as far as phylib is concerned - the mdio-i2c
driver makes the PHY "appear" as if it is on a conventional MDIO
bus.
Jiawen Wu Aug. 4, 2023, 5:56 a.m. UTC | #17
On Thursday, August 3, 2023 7:11 PM, Russell King (Oracle) wrote:
> On Thu, Aug 03, 2023 at 10:20:22AM +0800, Jiawen Wu wrote:
> > > No there isn't, and it conforms with the above.
> > >
> > > A read looks like this:
> > >
> > >       Address  Data                   Address  Data     Data
> > > Start 10101100 000yyyyy RepeatedStart 10101101 DDDDDDDD DDDDDDDD Stop
> > >                       or Stop followed
> > > 		          by Start
> > >
> > > The terms "Address" and "Data" here are as per the I²C specification.
> > > You will notice that the first part has one byte of address and *one*
> > > byte of data to convey the register address. This is what the "1" you
> > > are referring to above is for.
> > >
> > > For completness, a write looks like this:
> > >
> > >       Address  Data     Data     Data
> > > Start 10101100 000yyyyy DDDDDDDD DDDDDDDD Stop
> > >
> > > Essentially, in all cases, when 0x56 is addressed with the data
> > > direction in write mode, the very first byte is _always_ the register
> > > address and the remainder contain the data. When the data direction is
> > > in read mode, the bytes are always data.
> > >
> > > The description you quote above is poor because it doesn't make it
> > > clear whether "read" and "write" apply to the bus transactions or to
> > > the device operations. However, I can assure you that what is
> > > implemented is correct, since this is the standard small 24xx memory
> > > device protocol, and I've been programming that on various
> > > microcontrollers and such like for the last 30 years.
> > >
> > > Are you seeing a problem with the data read or written to the PHY?
> >
> > Hi Russell,
> >
> > I really don't know how to deal with "MAC side SGMII", could you please
> > help me?
> >
> > From the test results, when I config PCS in "PHY side SGMII", the link status
> > of PHY in copper SFP is read by I2C after AN complete. Then PHY's link up
> > status is informed to PHYLINK, then PCS will check its status. But when I just
> > change PCS to "MAC side SGMII", I2C will keep reading timeouts since AN
> > complete. I checked the register of PCS to confirm AN complete, but PHY's
> > link status would never be updated in PHYLINK.
> 
> I don't understand what is going on here either - but what I do know
> is that there is _zero_ difference as far as the network link is
> concerned between an on-board PHY using SGMII to the MAC/PCS and a SFP
> with a PHY using SGMII.
> 
> In both situations the PHY behaves the same - it presents a PHY-side
> SGMII interface, so it sends to the MAC/PCS the speed and duplex
> settings, and expects the MAC/PCS to acknowledge them.
> 
> The name "MAC side SGMII" suggests that this mode provides the
> acknowledgement, whereas "PHY side SGMII" suggests that this mode
> provides a speed and duplex.
> 
> Given all this, using "PHY side SGMII" with a SFP, and "MAC side
> SGMII" for an on-board PHY just seems utterly wrong - and I can't
> make head nor tail of it.

Since no reasonable explanation can be given, can we assume that there is a
design flaw in the hardware? Although it's not clear to the designers...

> 
> > It's kind of weird to me, how does the configuration of PCS relate to I2C?
> 
> I2C is just the access method for PHYs on SFPs - because there are
> no MDIO bus pins on SFP modules, only I2C pins mainly for accessing
> the identification EEPROM and diagnostics, but many copper SFPs have
> a way to access the PHY.
> 
> I2C is transparent as far as phylib is concerned - the mdio-i2c
> driver makes the PHY "appear" as if it is on a conventional MDIO
> bus.
diff mbox series

Patch

diff --git a/drivers/net/pcs/pcs-xpcs-wx.c b/drivers/net/pcs/pcs-xpcs-wx.c
index 6d1df34958bd..7667924623fa 100644
--- a/drivers/net/pcs/pcs-xpcs-wx.c
+++ b/drivers/net/pcs/pcs-xpcs-wx.c
@@ -143,8 +143,9 @@  static bool txgbe_xpcs_mode_quirk(struct dw_xpcs *xpcs)
 	/* When txgbe do LAN reset, PCS will change to default 10GBASE-R mode */
 	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_CTRL2);
 	ret &= MDIO_PCS_CTRL2_TYPE;
-	if (ret == MDIO_PCS_CTRL2_10GBR &&
-	    xpcs->interface != PHY_INTERFACE_MODE_10GBASER)
+	if ((ret == MDIO_PCS_CTRL2_10GBR &&
+	     xpcs->interface != PHY_INTERFACE_MODE_10GBASER) ||
+	    xpcs->interface == PHY_INTERFACE_MODE_SGMII)
 		return true;
 
 	return false;
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index f38b9241a942..9f7406b6dd38 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -668,7 +668,10 @@  EXPORT_SYMBOL_GPL(xpcs_config_eee);
 static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
 				      unsigned int neg_mode)
 {
-	int ret, mdio_ctrl;
+	int ret, mdio_ctrl, tx_conf;
+
+	if (xpcs_dev_is_txgbe(xpcs))
+		xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP);
 
 	/* For AN for C37 SGMII mode, the settings are :-
 	 * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
@@ -705,9 +708,14 @@  static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
 	ret |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
 		DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
 		DW_VR_MII_PCS_MODE_MASK);
-	ret |= (DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII <<
-		DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
-		DW_VR_MII_TX_CONFIG_MASK);
+	if (xpcs_dev_is_txgbe(xpcs)) {
+		ret |= DW_VR_MII_AN_CTRL_8BIT;
+		tx_conf = DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII;
+	} else {
+		tx_conf = DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII;
+	}
+	ret |= tx_conf << DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
+		DW_VR_MII_TX_CONFIG_MASK;
 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
 	if (ret < 0)
 		return ret;
@@ -721,6 +729,9 @@  static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
 	else
 		ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
 
+	if (xpcs_dev_is_txgbe(xpcs))
+		ret |= DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL;
+
 	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
 	if (ret < 0)
 		return ret;
@@ -996,6 +1007,33 @@  static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,
 			state->duplex = DUPLEX_FULL;
 		else
 			state->duplex = DUPLEX_HALF;
+	} else if (ret == DW_VR_MII_AN_STS_C37_ANCMPLT_INTR) {
+		int speed, duplex;
+
+		state->link = true;
+
+		speed = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
+		if (speed < 0)
+			return speed;
+
+		speed &= SGMII_SPEED_SS13 | SGMII_SPEED_SS6;
+		if (speed == SGMII_SPEED_SS6)
+			state->speed = SPEED_1000;
+		else if (speed == SGMII_SPEED_SS13)
+			state->speed = SPEED_100;
+		else if (speed == 0)
+			state->speed = SPEED_10;
+
+		duplex = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
+		if (duplex < 0)
+			return duplex;
+
+		if (duplex & DW_FULL_DUPLEX)
+			state->duplex = DUPLEX_FULL;
+		else if (duplex & DW_HALF_DUPLEX)
+			state->duplex = DUPLEX_HALF;
+
+		xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
 	}
 
 	return 0;
diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h
index 08a8881614de..36a1786a2853 100644
--- a/drivers/net/pcs/pcs-xpcs.h
+++ b/drivers/net/pcs/pcs-xpcs.h
@@ -66,12 +66,14 @@ 
 
 /* VR_MII_DIG_CTRL1 */
 #define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW		BIT(9)
+#define DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL	BIT(0)
 
 /* VR_MII_DIG_CTRL2 */
 #define DW_VR_MII_DIG_CTRL2_TX_POL_INV		BIT(4)
 #define DW_VR_MII_DIG_CTRL2_RX_POL_INV		BIT(0)
 
 /* VR_MII_AN_CTRL */
+#define DW_VR_MII_AN_CTRL_8BIT			BIT(8)
 #define DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT	3
 #define DW_VR_MII_TX_CONFIG_MASK		BIT(3)
 #define DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII	0x1
@@ -97,6 +99,10 @@ 
 #define SGMII_SPEED_SS13		BIT(13)	/* SGMII speed along with SS6 */
 #define SGMII_SPEED_SS6			BIT(6)	/* SGMII speed along with SS13 */
 
+/* SR MII MMD AN Advertisement defines */
+#define DW_HALF_DUPLEX			BIT(6)
+#define DW_FULL_DUPLEX			BIT(5)
+
 /* VR MII EEE Control 0 defines */
 #define DW_VR_MII_EEE_LTX_EN			BIT(0)  /* LPI Tx Enable */
 #define DW_VR_MII_EEE_LRX_EN			BIT(1)  /* LPI Rx Enable */