--- v2
+++ v4
@@ -1,157 +1,68 @@
-Add the qca8081 phy driver config_init function, which includes:
-1. Enable fast restrain.
-2. Add 802.3az configurations.
-3. initialize ADC threshold as 100mv.
+Add generic fast retrain auto-negotiation function for C45 PHYs.
Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
- drivers/net/phy/at803x.c | 119 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 119 insertions(+)
+ drivers/net/phy/phy-c45.c | 34 ++++++++++++++++++++++++++++++++++
+ include/linux/phy.h | 1 +
+ 2 files changed, 35 insertions(+)
-diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
-index b12cad633b98..d838a21017f6 100644
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -169,6 +169,51 @@
- #define AT803X_KEEP_PLL_ENABLED BIT(0)
- #define AT803X_DISABLE_SMARTEEE BIT(1)
+diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
+index c617dbcad6ea..b01180e1f578 100644
+--- a/drivers/net/phy/phy-c45.c
++++ b/drivers/net/phy/phy-c45.c
+@@ -611,6 +611,40 @@ int genphy_c45_loopback(struct phy_device *phydev, bool enable)
+ }
+ EXPORT_SYMBOL_GPL(genphy_c45_loopback);
-+/* ADC threshold */
-+#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80
-+#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0)
-+#define QCA808X_ADC_THRESHOLD_80MV 0
-+#define QCA808X_ADC_THRESHOLD_100MV 0xf0
-+#define QCA808X_ADC_THRESHOLD_200MV 0x0f
-+#define QCA808X_ADC_THRESHOLD_300MV 0xff
-+
-+/* CLD control */
-+#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007
-+#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4)
-+#define QCA808X_8023AZ_AFE_EN 0x90
-+
-+/* AZ control */
-+#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008
-+#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014
-+#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E
-+#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E
-+#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419
-+
-+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020
-+#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341
-+
-+#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c
-+#define QCA808X_TOP_OPTION1_DATA 0x0
-+
-+#define QCA808X_PHY_MMD3_DEBUG_1 0xa100
-+#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203
-+#define QCA808X_PHY_MMD3_DEBUG_2 0xa101
-+#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad
-+#define QCA808X_PHY_MMD3_DEBUG_3 0xa103
-+#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698
-+#define QCA808X_PHY_MMD3_DEBUG_4 0xa105
-+#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001
-+#define QCA808X_PHY_MMD3_DEBUG_5 0xa106
-+#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111
-+#define QCA808X_PHY_MMD3_DEBUG_6 0xa011
-+#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85
-+
- MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-@@ -1379,6 +1424,79 @@ static int qca83xx_config_init(struct phy_device *phydev)
- return 0;
- }
-
-+static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
++/**
++ * genphy_c45_fast_retrain - configure fast retrain registers
++ * @phydev: target phy_device struct
++ *
++ * Description: If fast-retrain is enabled, we configure PHY as
++ * advertising fast retrain capable and THP Bypass Request, then
++ * enable fast retrain. If it is not enabled, we configure fast
++ * retrain disabled.
++ */
++int genphy_c45_fast_retrain(struct phy_device *phydev, bool enable)
+{
+ int ret;
+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-+ MDIO_AN_10GBT_CTRL_ADV2_5G |
-+ MDIO_AN_10GBT_CTRL_ADVFSRT2_5G |
-+ MDIO_AN_10GBT_CTRL_ADVLPTIMING);
-+ if (ret)
-+ return ret;
++ if (!enable)
++ return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
++ MDIO_PMA_10GBR_FSRT_ENABLE);
+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
++ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported)) {
++ ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
++ MDIO_AN_10GBT_CTRL_ADVFSRT2_5G);
++ if (ret)
++ return ret;
++
++ ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_AN_CTRL2,
++ MDIO_AN_THP_BP2_5GT);
++ if (ret)
++ return ret;
++ }
++
++ return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
+ MDIO_PMA_10GBR_FSRT_ENABLE);
-+ if (ret)
-+ return ret;
++}
++EXPORT_SYMBOL_GPL(genphy_c45_fast_retrain);
+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_CTRL2, MDIO_AN_THP_BP2_5GT);
-+ if (ret)
-+ return ret;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
-+ QCA808X_TOP_OPTION1_DATA);
-+
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
-+ QCA808X_MSE_THRESHOLD_20DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
-+ QCA808X_MSE_THRESHOLD_17DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
-+ QCA808X_MSE_THRESHOLD_27DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
-+ QCA808X_MSE_THRESHOLD_28DB_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
-+ QCA808X_MMD3_DEBUG_1_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
-+ QCA808X_MMD3_DEBUG_4_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
-+ QCA808X_MMD3_DEBUG_5_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
-+ QCA808X_MMD3_DEBUG_3_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
-+ QCA808X_MMD3_DEBUG_6_VALUE);
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
-+ QCA808X_MMD3_DEBUG_2_VALUE);
-+
-+ return 0;
-+}
-+
-+static int qca808x_config_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Active adc&vga on 802.3az for the link 1000M and 100M */
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
-+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
-+ if (ret)
-+ return ret;
-+
-+ /* Adjust the threshold on 802.3az for the link 1000M */
-+ ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
-+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, QCA808X_MMD3_AZ_TRAINING_VAL);
-+ if (ret)
-+ return ret;
-+
-+ /* Config the fast retrain for the link 2500M */
-+ ret = qca808x_phy_fast_retrain_config(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* Configure adc threshold as 100mv for the link 10M */
-+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
-+ QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
-+}
-+
- static int qca808x_read_status(struct phy_device *phydev)
- {
- int ret;
-@@ -1530,6 +1648,7 @@ static struct phy_driver at803x_driver[] = {
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .read_status = qca808x_read_status,
-+ .config_init = qca808x_config_init,
- }, };
+ struct phy_driver genphy_c45_driver = {
+ .phy_id = 0xffffffff,
+ .phy_id_mask = 0xffffffff,
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 736e1d1a47c4..04e90423fa88 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -1584,6 +1584,7 @@ int genphy_c45_config_aneg(struct phy_device *phydev);
+ int genphy_c45_loopback(struct phy_device *phydev, bool enable);
+ int genphy_c45_pma_resume(struct phy_device *phydev);
+ int genphy_c45_pma_suspend(struct phy_device *phydev);
++int genphy_c45_fast_retrain(struct phy_device *phydev, bool enable);
- module_phy_driver(at803x_driver);
+ /* Generic C45 PHY driver */
+ extern struct phy_driver genphy_c45_driver;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project