123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583 |
- From 737eb75a815f9c08dcbb6631db57f4f4b0540a5b Mon Sep 17 00:00:00 2001
- From: Christian Marangi <[email protected]>
- Date: Tue, 6 Feb 2024 18:31:07 +0100
- Subject: [PATCH 04/10] net: phy: qcom: move more function to shared library
- Move more function to shared library in preparation for introduction of
- new PHY Family qca807x that will make use of both functions from at803x
- and qca808x as it's a transition PHY with some implementation of at803x
- and some from the new qca808x.
- Signed-off-by: Christian Marangi <[email protected]>
- Reviewed-by: Andrew Lunn <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- drivers/net/phy/qcom/at803x.c | 35 -----
- drivers/net/phy/qcom/qca808x.c | 205 ----------------------------
- drivers/net/phy/qcom/qcom-phy-lib.c | 193 ++++++++++++++++++++++++++
- drivers/net/phy/qcom/qcom.h | 51 +++++++
- 4 files changed, 244 insertions(+), 240 deletions(-)
- --- a/drivers/net/phy/qcom/at803x.c
- +++ b/drivers/net/phy/qcom/at803x.c
- @@ -504,41 +504,6 @@ static void at803x_link_change_notify(st
- }
- }
-
- -static int at803x_read_status(struct phy_device *phydev)
- -{
- - struct at803x_ss_mask ss_mask = { 0 };
- - int err, old_link = phydev->link;
- -
- - /* Update the link, but return if there was an error */
- - err = genphy_update_link(phydev);
- - if (err)
- - return err;
- -
- - /* why bother the PHY if nothing can have changed */
- - if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
- - return 0;
- -
- - phydev->speed = SPEED_UNKNOWN;
- - phydev->duplex = DUPLEX_UNKNOWN;
- - phydev->pause = 0;
- - phydev->asym_pause = 0;
- -
- - err = genphy_read_lpa(phydev);
- - if (err < 0)
- - return err;
- -
- - ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
- - ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
- - err = at803x_read_specific_status(phydev, ss_mask);
- - if (err < 0)
- - return err;
- -
- - if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
- - phy_resolve_aneg_pause(phydev);
- -
- - return 0;
- -}
- -
- static int at803x_config_aneg(struct phy_device *phydev)
- {
- struct at803x_priv *priv = phydev->priv;
- --- a/drivers/net/phy/qcom/qca808x.c
- +++ b/drivers/net/phy/qcom/qca808x.c
- @@ -2,7 +2,6 @@
-
- #include <linux/phy.h>
- #include <linux/module.h>
- -#include <linux/ethtool_netlink.h>
-
- #include "qcom.h"
-
- @@ -63,55 +62,6 @@
- #define QCA808X_DBG_AN_TEST 0xb
- #define QCA808X_HIBERNATION_EN BIT(15)
-
- -#define QCA808X_CDT_ENABLE_TEST BIT(15)
- -#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
- -#define QCA808X_CDT_STATUS BIT(11)
- -#define QCA808X_CDT_LENGTH_UNIT BIT(10)
- -
- -#define QCA808X_MMD3_CDT_STATUS 0x8064
- -#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
- -#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
- -#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
- -#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
- -#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
- -#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
- -
- -#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
- -#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
- -#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
- -#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
- -
- -#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
- -#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
- -#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
- -#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
- -#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
- -
- -#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
- -#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
- -#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
- -#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
- -
- -/* NORMAL are MDI with type set to 0 */
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
- - QCA808X_CDT_STATUS_STAT_MDI1)
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
- - QCA808X_CDT_STATUS_STAT_MDI1)
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
- - QCA808X_CDT_STATUS_STAT_MDI2)
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
- - QCA808X_CDT_STATUS_STAT_MDI2)
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
- - QCA808X_CDT_STATUS_STAT_MDI3)
- -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
- - QCA808X_CDT_STATUS_STAT_MDI3)
- -
- -/* Added for reference of existence but should be handled by wait_for_completion already */
- -#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
- -
- #define QCA808X_MMD7_LED_GLOBAL 0x8073
- #define QCA808X_LED_BLINK_1 GENMASK(11, 6)
- #define QCA808X_LED_BLINK_2 GENMASK(5, 0)
- @@ -406,86 +356,6 @@ static int qca808x_soft_reset(struct phy
- return ret;
- }
-
- -static bool qca808x_cdt_fault_length_valid(int cdt_code)
- -{
- - switch (cdt_code) {
- - case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
- - case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
- - return true;
- - default:
- - return false;
- - }
- -}
- -
- -static int qca808x_cable_test_result_trans(int cdt_code)
- -{
- - switch (cdt_code) {
- - case QCA808X_CDT_STATUS_STAT_NORMAL:
- - return ETHTOOL_A_CABLE_RESULT_CODE_OK;
- - case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
- - return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
- - case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
- - return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
- - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
- - return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
- - case QCA808X_CDT_STATUS_STAT_FAIL:
- - default:
- - return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
- - }
- -}
- -
- -static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
- - int result)
- -{
- - int val;
- - u32 cdt_length_reg = 0;
- -
- - switch (pair) {
- - case ETHTOOL_A_CABLE_PAIR_A:
- - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
- - break;
- - case ETHTOOL_A_CABLE_PAIR_B:
- - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
- - break;
- - case ETHTOOL_A_CABLE_PAIR_C:
- - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
- - break;
- - case ETHTOOL_A_CABLE_PAIR_D:
- - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
- - break;
- - default:
- - return -EINVAL;
- - }
- -
- - val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
- - if (val < 0)
- - return val;
- -
- - if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
- - val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
- - else
- - val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
- -
- - return at803x_cdt_fault_length(val);
- -}
- -
- static int qca808x_cable_test_start(struct phy_device *phydev)
- {
- int ret;
- @@ -526,81 +396,6 @@ static int qca808x_cable_test_start(stru
-
- return 0;
- }
- -
- -static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
- - u16 status)
- -{
- - int length, result;
- - u16 pair_code;
- -
- - switch (pair) {
- - case ETHTOOL_A_CABLE_PAIR_A:
- - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
- - break;
- - case ETHTOOL_A_CABLE_PAIR_B:
- - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
- - break;
- - case ETHTOOL_A_CABLE_PAIR_C:
- - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
- - break;
- - case ETHTOOL_A_CABLE_PAIR_D:
- - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
- - break;
- - default:
- - return -EINVAL;
- - }
- -
- - result = qca808x_cable_test_result_trans(pair_code);
- - ethnl_cable_test_result(phydev, pair, result);
- -
- - if (qca808x_cdt_fault_length_valid(pair_code)) {
- - length = qca808x_cdt_fault_length(phydev, pair, result);
- - ethnl_cable_test_fault_length(phydev, pair, length);
- - }
- -
- - return 0;
- -}
- -
- -static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
- -{
- - int ret, val;
- -
- - *finished = false;
- -
- - val = QCA808X_CDT_ENABLE_TEST |
- - QCA808X_CDT_LENGTH_UNIT;
- - ret = at803x_cdt_start(phydev, val);
- - if (ret)
- - return ret;
- -
- - ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
- - if (ret)
- - return ret;
- -
- - val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
- - if (val < 0)
- - return val;
- -
- - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
- - if (ret)
- - return ret;
- -
- - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
- - if (ret)
- - return ret;
- -
- - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
- - if (ret)
- - return ret;
- -
- - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
- - if (ret)
- - return ret;
- -
- - *finished = true;
- -
- - return 0;
- -}
-
- static int qca808x_get_features(struct phy_device *phydev)
- {
- --- a/drivers/net/phy/qcom/qcom-phy-lib.c
- +++ b/drivers/net/phy/qcom/qcom-phy-lib.c
- @@ -5,6 +5,7 @@
-
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
- +#include <linux/ethtool_netlink.h>
-
- #include "qcom.h"
-
- @@ -311,6 +312,42 @@ int at803x_prepare_config_aneg(struct ph
- }
- EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg);
-
- +int at803x_read_status(struct phy_device *phydev)
- +{
- + struct at803x_ss_mask ss_mask = { 0 };
- + int err, old_link = phydev->link;
- +
- + /* Update the link, but return if there was an error */
- + err = genphy_update_link(phydev);
- + if (err)
- + return err;
- +
- + /* why bother the PHY if nothing can have changed */
- + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
- + return 0;
- +
- + phydev->speed = SPEED_UNKNOWN;
- + phydev->duplex = DUPLEX_UNKNOWN;
- + phydev->pause = 0;
- + phydev->asym_pause = 0;
- +
- + err = genphy_read_lpa(phydev);
- + if (err < 0)
- + return err;
- +
- + ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
- + ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
- + err = at803x_read_specific_status(phydev, ss_mask);
- + if (err < 0)
- + return err;
- +
- + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
- + phy_resolve_aneg_pause(phydev);
- +
- + return 0;
- +}
- +EXPORT_SYMBOL_GPL(at803x_read_status);
- +
- static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
- {
- int val;
- @@ -427,3 +464,159 @@ int at803x_cdt_wait_for_completion(struc
- return ret < 0 ? ret : 0;
- }
- EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion);
- +
- +static bool qca808x_cdt_fault_length_valid(int cdt_code)
- +{
- + switch (cdt_code) {
- + case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
- + case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
- + return true;
- + default:
- + return false;
- + }
- +}
- +
- +static int qca808x_cable_test_result_trans(int cdt_code)
- +{
- + switch (cdt_code) {
- + case QCA808X_CDT_STATUS_STAT_NORMAL:
- + return ETHTOOL_A_CABLE_RESULT_CODE_OK;
- + case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
- + return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
- + case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
- + return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
- + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
- + return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
- + case QCA808X_CDT_STATUS_STAT_FAIL:
- + default:
- + return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
- + }
- +}
- +
- +static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
- + int result)
- +{
- + int val;
- + u32 cdt_length_reg = 0;
- +
- + switch (pair) {
- + case ETHTOOL_A_CABLE_PAIR_A:
- + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
- + break;
- + case ETHTOOL_A_CABLE_PAIR_B:
- + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
- + break;
- + case ETHTOOL_A_CABLE_PAIR_C:
- + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
- + break;
- + case ETHTOOL_A_CABLE_PAIR_D:
- + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
- + if (val < 0)
- + return val;
- +
- + if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
- + val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
- + else
- + val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
- +
- + return at803x_cdt_fault_length(val);
- +}
- +
- +static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
- + u16 status)
- +{
- + int length, result;
- + u16 pair_code;
- +
- + switch (pair) {
- + case ETHTOOL_A_CABLE_PAIR_A:
- + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
- + break;
- + case ETHTOOL_A_CABLE_PAIR_B:
- + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
- + break;
- + case ETHTOOL_A_CABLE_PAIR_C:
- + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
- + break;
- + case ETHTOOL_A_CABLE_PAIR_D:
- + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + result = qca808x_cable_test_result_trans(pair_code);
- + ethnl_cable_test_result(phydev, pair, result);
- +
- + if (qca808x_cdt_fault_length_valid(pair_code)) {
- + length = qca808x_cdt_fault_length(phydev, pair, result);
- + ethnl_cable_test_fault_length(phydev, pair, length);
- + }
- +
- + return 0;
- +}
- +
- +int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
- +{
- + int ret, val;
- +
- + *finished = false;
- +
- + val = QCA808X_CDT_ENABLE_TEST |
- + QCA808X_CDT_LENGTH_UNIT;
- + ret = at803x_cdt_start(phydev, val);
- + if (ret)
- + return ret;
- +
- + ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
- + if (ret)
- + return ret;
- +
- + val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
- + if (val < 0)
- + return val;
- +
- + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
- + if (ret)
- + return ret;
- +
- + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
- + if (ret)
- + return ret;
- +
- + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
- + if (ret)
- + return ret;
- +
- + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
- + if (ret)
- + return ret;
- +
- + *finished = true;
- +
- + return 0;
- +}
- +EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status);
- --- a/drivers/net/phy/qcom/qcom.h
- +++ b/drivers/net/phy/qcom/qcom.h
- @@ -54,6 +54,55 @@
- #define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8)
- #define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0)
-
- +#define QCA808X_CDT_ENABLE_TEST BIT(15)
- +#define QCA808X_CDT_INTER_CHECK_DIS BIT(13)
- +#define QCA808X_CDT_STATUS BIT(11)
- +#define QCA808X_CDT_LENGTH_UNIT BIT(10)
- +
- +#define QCA808X_MMD3_CDT_STATUS 0x8064
- +#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065
- +#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066
- +#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067
- +#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068
- +#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8)
- +#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0)
- +
- +#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12)
- +#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8)
- +#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4)
- +#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0)
- +
- +#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0)
- +#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
- +#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
- +#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
- +#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
- +
- +#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2)
- +#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
- +#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
- +#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
- +
- +/* NORMAL are MDI with type set to 0 */
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
- + QCA808X_CDT_STATUS_STAT_MDI1)
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
- + QCA808X_CDT_STATUS_STAT_MDI1)
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
- + QCA808X_CDT_STATUS_STAT_MDI2)
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
- + QCA808X_CDT_STATUS_STAT_MDI2)
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
- + QCA808X_CDT_STATUS_STAT_MDI3)
- +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
- + QCA808X_CDT_STATUS_STAT_MDI3)
- +
- +/* Added for reference of existence but should be handled by wait_for_completion already */
- +#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3))
- +
- #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
- #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
- #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
- @@ -110,6 +159,7 @@ int at803x_read_specific_status(struct p
- struct at803x_ss_mask ss_mask);
- int at803x_config_mdix(struct phy_device *phydev, u8 ctrl);
- int at803x_prepare_config_aneg(struct phy_device *phydev);
- +int at803x_read_status(struct phy_device *phydev);
- int at803x_get_tunable(struct phy_device *phydev,
- struct ethtool_tunable *tuna, void *data);
- int at803x_set_tunable(struct phy_device *phydev,
- @@ -118,3 +168,4 @@ int at803x_cdt_fault_length(int dt);
- int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start);
- int at803x_cdt_wait_for_completion(struct phy_device *phydev,
- u32 cdt_en);
- +int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished);
|