ath9k: Check for errors when reading SREV register [Linux 4.9.187]

This Linux kernel change "ath9k: Check for errors when reading SREV register" is included in the Linux 4.9.187 release. This change is authored by Tim Schumacher <timschumi [at] gmx.de> on Mon Mar 18 20:05:57 2019 +0100. The commit for this change in Linux stable tree is 2c1907e (patch) which is from upstream commit 2f90c7e. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 2f90c7e.

ath9k: Check for errors when reading SREV register

[ Upstream commit 2f90c7e5d09437a4d8d5546feaae9f1cf48cfbe1 ]

Right now, if an error is encountered during the SREV register
read (i.e. an EIO in ath9k_regread()), that error code gets
passed all the way to __ath9k_hw_init(), where it is visible
during the "Chip rev not supported" message.

    ath9k_htc 1-1.4:1.0: ath9k_htc: HTC initialized with 33 credits
    ath: phy2: Mac Chip Rev 0x0f.3 is not supported by this driver
    ath: phy2: Unable to initialize hardware; initialization status: -95
    ath: phy2: Unable to initialize hardware; initialization status: -95
    ath9k_htc: Failed to initialize the device

Check for -EIO explicitly in ath9k_hw_read_revisions() and return
a boolean based on the success of the operation. Check for that in
__ath9k_hw_init() and abort with a more debugging-friendly message
if reading the revisions wasn't successful.

    ath9k_htc 1-1.4:1.0: ath9k_htc: HTC initialized with 33 credits
    ath: phy2: Failed to read SREV register
    ath: phy2: Could not read hardware revision
    ath: phy2: Unable to initialize hardware; initialization status: -95
    ath: phy2: Unable to initialize hardware; initialization status: -95
    ath9k_htc: Failed to initialize the device

This helps when debugging by directly showing the first point of
failure and it could prevent possible errors if a 0x0f.3 revision
is ever supported.

Signed-off-by: Tim Schumacher <timschumi@gmx.de>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 32 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/wireless/ath/ath9k/hw.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 951bac2..e7fca78 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -250,8 +250,9 @@ void ath9k_hw_get_channel_centers(struct ath_hw *ah,
 /* Chip Revisions */
 /******************/

-static void ath9k_hw_read_revisions(struct ath_hw *ah)
+static bool ath9k_hw_read_revisions(struct ath_hw *ah)
 {
+   u32 srev;
    u32 val;

    if (ah->get_mac_revision)
@@ -267,25 +268,33 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
            val = REG_READ(ah, AR_SREV);
            ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
        }
-       return;
+       return true;
    case AR9300_DEVID_AR9340:
        ah->hw_version.macVersion = AR_SREV_VERSION_9340;
-       return;
+       return true;
    case AR9300_DEVID_QCA955X:
        ah->hw_version.macVersion = AR_SREV_VERSION_9550;
-       return;
+       return true;
    case AR9300_DEVID_AR953X:
        ah->hw_version.macVersion = AR_SREV_VERSION_9531;
-       return;
+       return true;
    case AR9300_DEVID_QCA956X:
        ah->hw_version.macVersion = AR_SREV_VERSION_9561;
-       return;
+       return true;
    }

-   val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
+   srev = REG_READ(ah, AR_SREV);
+
+   if (srev == -EIO) {
+       ath_err(ath9k_hw_common(ah),
+           "Failed to read SREV register");
+       return false;
+   }
+
+   val = srev & AR_SREV_ID;

    if (val == 0xFF) {
-       val = REG_READ(ah, AR_SREV);
+       val = srev;
        ah->hw_version.macVersion =
            (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
        ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
@@ -304,6 +313,8 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
        if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
            ah->is_pciexpress = true;
    }
+
+   return true;
 }

 /************************************/
@@ -557,7 +568,10 @@ static int __ath9k_hw_init(struct ath_hw *ah)
    struct ath_common *common = ath9k_hw_common(ah);
    int r = 0;

-   ath9k_hw_read_revisions(ah);
+   if (!ath9k_hw_read_revisions(ah)) {
+       ath_err(common, "Could not read hardware revisions");
+       return -EOPNOTSUPP;
+   }

    switch (ah->hw_version.macVersion) {
    case AR_SREV_VERSION_5416_PCI:

Leave a Reply

Your email address will not be published. Required fields are marked *