[3/3] net: phy: at803x: add qca8081 fifo reset on the link down

Message ID 20230629034846.30600-4-quic_luoj@quicinc.com
State New
Headers
Series net: phy: at803x: support qca8081 1G version chip |

Commit Message

Jie Luo June 29, 2023, 3:48 a.m. UTC
  The qca8081 fifo needs to be reset on link down and released
on the link up in case of any abnormal issue such as the
packet blocked on the PHY.

Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
 drivers/net/phy/at803x.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
  

Comments

Andrew Lunn June 29, 2023, 1:23 p.m. UTC | #1
> +static int qca808x_fifo_reset(struct phy_device *phydev)
> +{
> +	/* Reset serdes fifo on link down, Release serdes fifo on link up,
> +	 * the serdes address is phy address added by 1.
> +	 */
> +	return mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
> +			MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
> +			QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);

In polling mode, this is going to be called once per second. Do you
really want to be setting that register all the time? Consider using
the link_change_notify callback.

Also, can you tell us more about this SERDES device on the bus. I just
want to make sure this is not a PCS and should have its own driver.

     Andrew
  
Jie Luo June 30, 2023, 6:54 a.m. UTC | #2
On 6/29/2023 9:23 PM, Andrew Lunn wrote:
>> +static int qca808x_fifo_reset(struct phy_device *phydev)
>> +{
>> +	/* Reset serdes fifo on link down, Release serdes fifo on link up,
>> +	 * the serdes address is phy address added by 1.
>> +	 */
>> +	return mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
>> +			MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
>> +			QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
> 
> In polling mode, this is going to be called once per second. Do you
> really want to be setting that register all the time? Consider using
> the link_change_notify callback.
> 
> Also, can you tell us more about this SERDES device on the bus. I just
> want to make sure this is not a PCS and should have its own driver.
> 
>       Andrew
Hi Andrew,
Thanks for the review.
yes, we can use the link_change_notify, since the fifo reset is needed 
on the link changed, i will update the patch to use link_change_notify.

SERDES device is the block converts data between serial data and 
parallel interfaces in each direction, which is the SGMII interface in 
qca8081 PHY, it's address is always the PHY address added by 1 in 
qca8081 PHY.
  
Andrew Lunn June 30, 2023, 1:21 p.m. UTC | #3
> SERDES device is the block converts data between serial data and parallel
> interfaces in each direction, which is the SGMII interface in qca8081 PHY,
> it's address is always the PHY address added by 1 in qca8081 PHY.

What other registers does this block have? What behaviour can be
configured? Does it have any support for Clause 73? Is there an open
datasheet for it?

	    Andrew
  
Jie Luo July 1, 2023, 8:04 a.m. UTC | #4
On 6/30/2023 9:21 PM, Andrew Lunn wrote:
>> SERDES device is the block converts data between serial data and parallel
>> interfaces in each direction, which is the SGMII interface in qca8081 PHY,
>> it's address is always the PHY address added by 1 in qca8081 PHY.
> 
> What other registers does this block have? What behaviour can be
> configured? Does it have any support for Clause 73? Is there an open
> datasheet for it?
> 
> 	    Andrew

Hi Andrew,
This block includes MII and MMD1 registers, which mainly configure the 
PLL clocks, reset and calibration of the interface sgmii, there is no 
related Clause 73 control register in this block.

Normally it is the hardware behavior, driver do not need to configure 
these registers, adding this interface fifo reset is for avoiding the 
packet block issue in some corner case.

it seems there is no open datasheet after searching the internet, but 
you can get the basic information of qca8081 from the following link.
https://www.qualcomm.com/products/internet-of-things/networking/wi-fi-networks/qca8081

Thanks,
Jie
  
Andrew Lunn July 1, 2023, 2:34 p.m. UTC | #5
> Hi Andrew,
> This block includes MII and MMD1 registers, which mainly configure the PLL
> clocks, reset and calibration of the interface sgmii, there is no related
> Clause 73 control register in this block.

O.K. What does it have in the MII ID registers? Does Linux think it is
a PHY and instantiating an generic PHY driver for it?

	Andrew
  
Jie Luo July 1, 2023, 3:44 p.m. UTC | #6
On 7/1/2023 10:34 PM, Andrew Lunn wrote:
>> Hi Andrew,
>> This block includes MII and MMD1 registers, which mainly configure the PLL
>> clocks, reset and calibration of the interface sgmii, there is no related
>> Clause 73 control register in this block.
> 
> O.K. What does it have in the MII ID registers? Does Linux think it is
> a PHY and instantiating an generic PHY driver for it?
> 
> 	Andrew
Hi Andrew,
it is the PLL related registers, there is no PHY ID existed in MII 
register 2, 3 of this block, so it can't be instantiated as the generic 
PHY device.
  
Andrew Lunn July 1, 2023, 4:21 p.m. UTC | #7
> Hi Andrew,
> it is the PLL related registers, there is no PHY ID existed in MII register
> 2, 3 of this block, so it can't be instantiated as the generic PHY device.

Well, phylib is going to scan those ID registers, and if it finds
something other than 0xffff 0xffff in those two ID registers it is
going to think a PHY is there. And then if there is no driver using
that ID, it will instantiate a generic PHY.

You might be able to see this in /sys/bus/mdio_bus, especially if you
don't have a DT node representing the MDIO bus.

      Andrew
  
Jie Luo July 2, 2023, 10 a.m. UTC | #8
On 7/2/2023 12:21 AM, Andrew Lunn wrote:
>> Hi Andrew,
>> it is the PLL related registers, there is no PHY ID existed in MII register
>> 2, 3 of this block, so it can't be instantiated as the generic PHY device.
> 
> Well, phylib is going to scan those ID registers, and if it finds
> something other than 0xffff 0xffff in those two ID registers it is
> going to think a PHY is there. And then if there is no driver using
> that ID, it will instantiate a generic PHY.
> 
> You might be able to see this in /sys/bus/mdio_bus, especially if you
> don't have a DT node representing the MDIO bus.
> 
>        Andrew
Okay, understand it. thanks Andrew for pointing this.
i will check it.
  

Patch

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 29aab7eaaa90..5dc707eaf18c 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -276,6 +276,9 @@ 
 #define QCA808X_PHY_MMD7_CHIP_TYPE		0x901d
 #define QCA808X_PHY_CHIP_TYPE_1G		BIT(0)
 
+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL	0x9072
+#define QCA8081_PHY_FIFO_RSTN			BIT(11)
+
 MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
@@ -1808,6 +1811,16 @@  static int qca808x_config_init(struct phy_device *phydev)
 			QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
 }
 
+static int qca808x_fifo_reset(struct phy_device *phydev)
+{
+	/* Reset serdes fifo on link down, Release serdes fifo on link up,
+	 * the serdes address is phy address added by 1.
+	 */
+	return mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
+			MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
+			QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
+}
+
 static int qca808x_read_status(struct phy_device *phydev)
 {
 	int ret;
@@ -1827,6 +1840,10 @@  static int qca808x_read_status(struct phy_device *phydev)
 	if (ret < 0)
 		return ret;
 
+	ret = qca808x_fifo_reset(phydev);
+	if (ret < 0)
+		return ret;
+
 	if (phydev->link) {
 		if (phydev->speed == SPEED_2500)
 			phydev->interface = PHY_INTERFACE_MODE_2500BASEX;