2016-06-23 14:57:38

by Martin Blumenstingl

[permalink] [raw]
Subject: ath9k: extend and improve handling of ath9k_platform_data

This series improves handling of ath9k_platform_data inside ath9k. A
quick summary of the changes is:
- led_active_high can now be configured via ath9k_platform_data:
This change is based on a patch originally written by Vittorio
Gambaletta which is part of OpenWrt's ath9k patches.
- small code cleanups which include removal of unused variables,
return values duplicate code (no functional changes)
- ath9k_hw_init_macaddr will not change common->macaddr anymore
to make it independent of whether it's called before or after
ath9k_platform_data initialization in init.c
- initialization based on ath9k_platform_data in init.c is now
easier to understand (no functional changes)

Patch 6 from this series supersedes the following patch by Eduardo
Abinader: "ath9k: return false when reading wrong eeprom offset" [0]


[0] https://patchwork.kernel.org/patch/9181371/




2016-06-23 14:57:41

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH 3/6] ath9k: ath9k_hw_init_macaddr should not overwrite valid MAC addresses

Currently setting the MAC address via ath9k_platform_data works only due
to the order in which init.c sets common->macaddr, which is done after
ath9k_hw_init_macaddr was executed. It would be better if the latter
was independent of the order in which it's being called.

Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4f98ca0..4dd3aca 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -478,21 +478,25 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
u16 eeval;
static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };

+ /* MAC address may already be loaded via ath9k_platform_data */
+ if (is_valid_ether_addr(common->macaddr))
+ return 0;
+
for (i = 0; i < 3; i++) {
eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
common->macaddr[2 * i] = eeval >> 8;
common->macaddr[2 * i + 1] = eeval & 0xff;
}
- if (!is_valid_ether_addr(common->macaddr)) {
- ath_err(common,
- "eeprom contains invalid mac address: %pM\n",
- common->macaddr);

- random_ether_addr(common->macaddr);
- ath_err(common,
- "random mac address will be used: %pM\n",
- common->macaddr);
- }
+ if (is_valid_ether_addr(common->macaddr))
+ return 0;
+
+ ath_err(common, "eeprom contains invalid mac address: %pM\n",
+ common->macaddr);
+
+ random_ether_addr(common->macaddr);
+ ath_err(common, "random mac address will be used: %pM\n",
+ common->macaddr);

return 0;
}
--
2.9.0


2016-06-23 14:57:44

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH 5/6] ath9k: move all ath9k_platform_data initialization into one function

No functional changes, this simply makes the code easier to understand
because all initialization based on ath9k_platform_data is now within
one function.

Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/net/wireless/ath/ath9k/init.c | 49 ++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 384929d..a0f4a52 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -512,15 +512,31 @@ static void ath9k_eeprom_release(struct ath_softc *sc)
release_firmware(sc->sc_ah->eeprom_blob);
}

-static int ath9k_init_soc_platform(struct ath_softc *sc)
+static int ath9k_init_platform(struct ath_softc *sc)
{
struct ath9k_platform_data *pdata = sc->dev->platform_data;
struct ath_hw *ah = sc->sc_ah;
- int ret = 0;
+ struct ath_common *common = ath9k_hw_common(ah);
+ int ret;

if (!pdata)
return 0;

+ if (!pdata->use_eeprom) {
+ ah->ah_flags &= ~AH_USE_EEPROM;
+ ah->gpio_mask = pdata->gpio_mask;
+ ah->gpio_val = pdata->gpio_val;
+ ah->led_pin = pdata->led_pin;
+ ah->is_clk_25mhz = pdata->is_clk_25mhz;
+ ah->get_mac_revision = pdata->get_mac_revision;
+ ah->external_reset = pdata->external_reset;
+ ah->disable_2ghz = pdata->disable_2ghz;
+ ah->disable_5ghz = pdata->disable_5ghz;
+
+ if (!pdata->endian_check)
+ ah->ah_flags |= AH_NO_EEP_SWAP;
+ }
+
if (pdata->eeprom_name) {
ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
if (ret)
@@ -533,13 +549,15 @@ static int ath9k_init_soc_platform(struct ath_softc *sc)
if (pdata->tx_gain_buffalo)
ah->config.tx_gain_buffalo = true;

- return ret;
+ if (pdata->macaddr)
+ ether_addr_copy(common->macaddr, pdata->macaddr);
+
+ return 0;
}

static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
const struct ath_bus_ops *bus_ops)
{
- struct ath9k_platform_data *pdata = sc->dev->platform_data;
struct ath_hw *ah = NULL;
struct ath9k_hw_capabilities *pCap;
struct ath_common *common;
@@ -553,6 +571,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
ah->dev = sc->dev;
ah->hw = sc->hw;
ah->hw_version.devid = devid;
+ ah->ah_flags |= AH_USE_EEPROM;
+ ah->led_pin = -1;
ah->reg_ops.read = ath9k_ioread32;
ah->reg_ops.multi_read = ath9k_multi_ioread32;
ah->reg_ops.write = ath9k_iowrite32;
@@ -572,22 +592,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
if (!ath9k_is_chanctx_enabled())
sc->cur_chan->hw_queue_base = 0;

- if (!pdata || pdata->use_eeprom) {
- ah->ah_flags |= AH_USE_EEPROM;
- sc->sc_ah->led_pin = -1;
- } else {
- sc->sc_ah->gpio_mask = pdata->gpio_mask;
- sc->sc_ah->gpio_val = pdata->gpio_val;
- sc->sc_ah->led_pin = pdata->led_pin;
- ah->is_clk_25mhz = pdata->is_clk_25mhz;
- ah->get_mac_revision = pdata->get_mac_revision;
- ah->external_reset = pdata->external_reset;
- ah->disable_2ghz = pdata->disable_2ghz;
- ah->disable_5ghz = pdata->disable_5ghz;
- if (!pdata->endian_check)
- ah->ah_flags |= AH_NO_EEP_SWAP;
- }
-
common->ops = &ah->reg_ops;
common->bus_ops = bus_ops;
common->ps_ops = &ath9k_ps_ops;
@@ -603,7 +607,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
*/
ath9k_init_pcoem_platform(sc);

- ret = ath9k_init_soc_platform(sc);
+ ret = ath9k_init_platform(sc);
if (ret)
return ret;

@@ -649,9 +653,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
if (ret)
goto err_hw;

- if (pdata && pdata->macaddr)
- memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
-
ret = ath9k_init_queues(sc);
if (ret)
goto err_queues;
--
2.9.0


2016-06-23 14:57:42

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH 4/6] ath9k: remove return value from ath9k_hw_init_macaddr

ath9k_hw_init_macaddr unconditionally returns 0 in all cases, making the
return value unnecessary.

Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4dd3aca..fa59117 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -471,7 +471,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
}

-static int ath9k_hw_init_macaddr(struct ath_hw *ah)
+static void ath9k_hw_init_macaddr(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
int i;
@@ -480,7 +480,7 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)

/* MAC address may already be loaded via ath9k_platform_data */
if (is_valid_ether_addr(common->macaddr))
- return 0;
+ return;

for (i = 0; i < 3; i++) {
eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
@@ -489,7 +489,7 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
}

if (is_valid_ether_addr(common->macaddr))
- return 0;
+ return;

ath_err(common, "eeprom contains invalid mac address: %pM\n",
common->macaddr);
@@ -498,7 +498,7 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
ath_err(common, "random mac address will be used: %pM\n",
common->macaddr);

- return 0;
+ return;
}

static int ath9k_hw_post_init(struct ath_hw *ah)
@@ -637,12 +637,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
if (r)
return r;

- r = ath9k_hw_init_macaddr(ah);
- if (r) {
- ath_err(common, "Failed to initialize MAC address\n");
- return r;
- }
-
+ ath9k_hw_init_macaddr(ah);
ath9k_hw_init_hang_checks(ah);

common->state = ATH_HW_INITIALIZED;
--
2.9.0


2016-06-23 14:57:41

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH 2/6] ath9k: remove variable which is set but never read

No functional changes - this only removes a variable which is set but
never read.

Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8b2895f..4f98ca0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -474,15 +474,12 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
static int ath9k_hw_init_macaddr(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- u32 sum;
int i;
u16 eeval;
static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };

- sum = 0;
for (i = 0; i < 3; i++) {
eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
- sum += eeval;
common->macaddr[2 * i] = eeval >> 8;
common->macaddr[2 * i + 1] = eeval & 0xff;
}
--
2.9.0


2016-06-23 14:57:45

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH 6/6] ath9k: simplify the code-paths when not using the built-in EEPROM

There were two paths in the code for "external" eeprom sources. The code
in eeprom.c only handled the cases where the eeprom data was loaded via
request_firmware. ahb.c and pci.c on the other hand had some duplicate
code which was only used when the eeprom data was passed via
ath9k_platform_data.
With this change all eeprom data handling is now unified in eeprom.c.

Signed-off-by: Martin Blumenstingl <[email protected]>
---
This supersedes the following patch by Eduardo Abinader
<[email protected]>:
"ath9k: return false when reading wrong eeprom offset"
https://patchwork.kernel.org/patch/9181371/

drivers/net/wireless/ath/ath9k/ahb.c | 18 +++------------
drivers/net/wireless/ath/ath9k/eeprom.c | 19 +++++++++------
drivers/net/wireless/ath/ath9k/pci.c | 41 +++++++++++----------------------
3 files changed, 28 insertions(+), 50 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index bd4a1a6..bea6186 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -18,7 +18,6 @@

#include <linux/nl80211.h>
#include <linux/platform_device.h>
-#include <linux/ath9k_platform.h>
#include <linux/module.h>
#include "ath9k.h"

@@ -58,20 +57,9 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)

static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_softc *sc = (struct ath_softc *)common->priv;
- struct platform_device *pdev = to_platform_device(sc->dev);
- struct ath9k_platform_data *pdata;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
- ath_err(common,
- "%s: flash read failed, offset %08x is out of range\n",
- __func__, off);
- return false;
- }
-
- *data = pdata->eeprom_data[off];
- return true;
+ ath_err(common, "%s: eeprom data has to be provided externally\n",
+ __func__);
+ return false;
}

static struct ath_bus_ops ath_ahb_bus_ops = {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index a794157..ba1c8ba 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -15,6 +15,7 @@
*/

#include "hw.h"
+#include <linux/ath9k_platform.h>

void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
{
@@ -108,26 +109,30 @@ void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
}
}

-static bool ath9k_hw_nvram_read_blob(struct ath_hw *ah, u32 off,
+static bool ath9k_hw_nvram_read_blob(u16 *blob, size_t blob_size, u32 offset,
u16 *data)
{
- u16 *blob_data;
-
- if (off * sizeof(u16) > ah->eeprom_blob->size)
+ if (offset * sizeof(u16) > blob_size)
return false;

- blob_data = (u16 *)ah->eeprom_blob->data;
- *data = blob_data[off];
+ *data = blob[offset];
return true;
}

bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
{
struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_platform_data *pdata = ah->dev->platform_data;
bool ret;

if (ah->eeprom_blob)
- ret = ath9k_hw_nvram_read_blob(ah, off, data);
+ ret = ath9k_hw_nvram_read_blob((u16 *) ah->eeprom_blob->data,
+ ah->eeprom_blob->size, off,
+ data);
+ else if (pdata && !pdata->use_eeprom && pdata->eeprom_data)
+ ret = ath9k_hw_nvram_read_blob(pdata->eeprom_data,
+ ARRAY_SIZE(pdata->eeprom_data),
+ off, data);
else
ret = common->bus_ops->eeprom_read(common, off, data);

diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 7cdaf40..0dd454a 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -19,7 +19,6 @@
#include <linux/nl80211.h>
#include <linux/pci.h>
#include <linux/pci-aspm.h>
-#include <linux/ath9k_platform.h>
#include <linux/module.h>
#include "ath9k.h"

@@ -786,35 +785,21 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)

static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_softc *sc = (struct ath_softc *) common->priv;
- struct ath9k_platform_data *pdata = sc->dev->platform_data;
-
- if (pdata && !pdata->use_eeprom) {
- if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
- ath_err(common,
- "%s: eeprom read failed, offset %08x is out of range\n",
- __func__, off);
- }
-
- *data = pdata->eeprom_data[off];
- } else {
- struct ath_hw *ah = (struct ath_hw *) common->ah;
-
- common->ops->read(ah, AR5416_EEPROM_OFFSET +
- (off << AR5416_EEPROM_S));
-
- if (!ath9k_hw_wait(ah,
- AR_EEPROM_STATUS_DATA,
- AR_EEPROM_STATUS_DATA_BUSY |
- AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
- AH_WAIT_TIMEOUT)) {
- return false;
- }
-
- *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
- AR_EEPROM_STATUS_DATA_VAL);
+ struct ath_hw *ah = (struct ath_hw *) common->ah;
+
+ common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+ if (!ath9k_hw_wait(ah,
+ AR_EEPROM_STATUS_DATA,
+ AR_EEPROM_STATUS_DATA_BUSY |
+ AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+ AH_WAIT_TIMEOUT)) {
+ return false;
}

+ *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
+ AR_EEPROM_STATUS_DATA_VAL);
+
return true;
}

--
2.9.0


2016-06-23 14:57:39

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH 1/6] ath9k: Allow configuration of LED polarity in platform data.

Some devices running OpenWrt need this and it makes sense to add this
to ath9k_platform_data as the next patches will add a devicetree
(boolean) property for it as well.

Suggested-by: Vittorio Gambaletta <[email protected]>
Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/net/wireless/ath/ath9k/init.c | 3 +++
include/linux/ath9k_platform.h | 1 +
2 files changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 2ee8624..384929d 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -527,6 +527,9 @@ static int ath9k_init_soc_platform(struct ath_softc *sc)
return ret;
}

+ if (pdata->led_active_high)
+ ah->config.led_active_high = true;
+
if (pdata->tx_gain_buffalo)
ah->config.tx_gain_buffalo = true;

diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index e66153d..76860a4 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -40,6 +40,7 @@ struct ath9k_platform_data {
bool tx_gain_buffalo;
bool disable_2ghz;
bool disable_5ghz;
+ bool led_active_high;

int (*get_mac_revision)(void);
int (*external_reset)(void);
--
2.9.0


2016-06-24 04:22:48

by Julian Calaby

[permalink] [raw]
Subject: Re: [PATCH 4/6] ath9k: remove return value from ath9k_hw_init_macaddr

Hi All,

On Fri, Jun 24, 2016 at 12:57 AM, Martin Blumenstingl
<[email protected]> wrote:
> ath9k_hw_init_macaddr unconditionally returns 0 in all cases, making the
> return value unnecessary.
>
> Signed-off-by: Martin Blumenstingl <[email protected]>

Looks right to me.

Reviewed-by: Julian Calaby <[email protected]>

Thanks,

--
Julian Calaby

Email: [email protected]
Profile: http://www.google.com/profiles/julian.calaby/

2016-06-24 04:20:51

by Julian Calaby

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath9k: remove variable which is set but never read

Hi All,

On Fri, Jun 24, 2016 at 12:57 AM, Martin Blumenstingl
<[email protected]> wrote:
> No functional changes - this only removes a variable which is set but
> never read.
>
> Signed-off-by: Martin Blumenstingl <[email protected]>

Looks right to me.

Reviewed-by: Julian Calaby <[email protected]>

Thanks,

--
Julian Calaby

Email: [email protected]
Profile: http://www.google.com/profiles/julian.calaby/

2016-07-19 17:58:54

by Kalle Valo

[permalink] [raw]
Subject: Re: [v2] ath9k: simplify the code-paths when not using the built-in EEPROM

Martin Blumenstingl <[email protected]> wrote:
> There were two paths in the code for "external" eeprom sources. The code
> in eeprom.c only handled the cases where the eeprom data was loaded via
> request_firmware. ahb.c and pci.c on the other hand had some duplicate
> code which was only used when the eeprom data was passed via
> ath9k_platform_data.
> With this change all eeprom data handling is now unified in eeprom.c.
>
> Signed-off-by: Martin Blumenstingl <[email protected]>

Thanks, 1 patch applied to ath-next branch of ath.git:

563985199693 ath9k: simplify the code-paths when not using the built-in EEPROM

--
Sent by pwcli
https://patchwork.kernel.org/patch/9222187/


2016-07-08 14:02:12

by Kalle Valo

[permalink] [raw]
Subject: Re: [1/6] ath9k: Allow configuration of LED polarity in platform data.

Martin Blumenstingl <[email protected]> wrote:
> Some devices running OpenWrt need this and it makes sense to add this
> to ath9k_platform_data as the next patches will add a devicetree
> (boolean) property for it as well.
>
> Suggested-by: Vittorio Gambaletta <[email protected]>
> Signed-off-by: Martin Blumenstingl <[email protected]>

Thanks, 5 patches applied to ath-next branch of ath.git:

3467f0d43301 ath9k: Allow configuration of LED polarity in platform data.
b27301f86cc7 ath9k: remove variable which is set but never read
0cefa9749883 ath9k: ath9k_hw_init_macaddr should not overwrite valid MAC addresses
d323cb71abef ath9k: remove return value from ath9k_hw_init_macaddr
28755b8f6d94 ath9k: move all ath9k_platform_data initialization into one function

--
Sent by pwcli
https://patchwork.kernel.org/patch/9195397/


2016-07-09 23:10:21

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH v2] ath9k: simplify the code-paths when not using the built-in EEPROM

There were two paths in the code for "external" eeprom sources. The code
in eeprom.c only handled the cases where the eeprom data was loaded via
request_firmware. ahb.c and pci.c on the other hand had some duplicate
code which was only used when the eeprom data was passed via
ath9k_platform_data.
With this change all eeprom data handling is now unified in eeprom.c.

Signed-off-by: Martin Blumenstingl <[email protected]>
---
Changes since v1:
- rebased to currrent ath.git/ath-next to resolve a small merge
conflict with commit
"0f27ac40fb64 ath9k: return false when reading wrong eeprom offset"
- renamed ath9k_hw_nvram_read_blob to ath9k_hw_nvram_read_array since
that name fit the function's purpose better
- fixed a bug in v1 which caused ARRAY_SIZE(pdata->eeprom_blob) to be
interpreted as "count of u8", while it is actually "count of u16"
(this led to some small code changes, such as introduction of the
_read_pdata and _read_firmware functions to make the code easier to
read)

drivers/net/wireless/ath/ath9k/ahb.c | 18 +++-----------
drivers/net/wireless/ath/ath9k/eeprom.c | 33 +++++++++++++++++++------
drivers/net/wireless/ath/ath9k/pci.c | 43 ++++++++++-----------------------
3 files changed, 41 insertions(+), 53 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index bd4a1a6..bea6186 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -18,7 +18,6 @@

#include <linux/nl80211.h>
#include <linux/platform_device.h>
-#include <linux/ath9k_platform.h>
#include <linux/module.h>
#include "ath9k.h"

@@ -58,20 +57,9 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)

static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_softc *sc = (struct ath_softc *)common->priv;
- struct platform_device *pdev = to_platform_device(sc->dev);
- struct ath9k_platform_data *pdata;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
- ath_err(common,
- "%s: flash read failed, offset %08x is out of range\n",
- __func__, off);
- return false;
- }
-
- *data = pdata->eeprom_data[off];
- return true;
+ ath_err(common, "%s: eeprom data has to be provided externally\n",
+ __func__);
+ return false;
}

static struct ath_bus_ops ath_ahb_bus_ops = {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index a794157..a449588 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -15,6 +15,7 @@
*/

#include "hw.h"
+#include <linux/ath9k_platform.h>

void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
{
@@ -108,26 +109,42 @@ void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
}
}

-static bool ath9k_hw_nvram_read_blob(struct ath_hw *ah, u32 off,
- u16 *data)
+static bool ath9k_hw_nvram_read_array(u16 *blob, size_t blob_size,
+ off_t offset, u16 *data)
{
- u16 *blob_data;
-
- if (off * sizeof(u16) > ah->eeprom_blob->size)
+ if (offset > blob_size)
return false;

- blob_data = (u16 *)ah->eeprom_blob->data;
- *data = blob_data[off];
+ *data = blob[offset];
return true;
}

+static bool ath9k_hw_nvram_read_pdata(struct ath9k_platform_data *pdata,
+ off_t offset, u16 *data)
+{
+ return ath9k_hw_nvram_read_array(pdata->eeprom_data,
+ ARRAY_SIZE(pdata->eeprom_data),
+ offset, data);
+}
+
+static bool ath9k_hw_nvram_read_firmware(const struct firmware *eeprom_blob,
+ off_t offset, u16 *data)
+{
+ return ath9k_hw_nvram_read_array((u16 *) eeprom_blob->data,
+ eeprom_blob->size / sizeof(u16),
+ offset, data);
+}
+
bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
{
struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_platform_data *pdata = ah->dev->platform_data;
bool ret;

if (ah->eeprom_blob)
- ret = ath9k_hw_nvram_read_blob(ah, off, data);
+ ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data);
+ else if (pdata && !pdata->use_eeprom && pdata->eeprom_data)
+ ret = ath9k_hw_nvram_read_pdata(pdata, off, data);
else
ret = common->bus_ops->eeprom_read(common, off, data);

diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index aa04b13..0dd454a 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -19,7 +19,6 @@
#include <linux/nl80211.h>
#include <linux/pci.h>
#include <linux/pci-aspm.h>
-#include <linux/ath9k_platform.h>
#include <linux/module.h>
#include "ath9k.h"

@@ -786,37 +785,21 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)

static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_softc *sc = (struct ath_softc *) common->priv;
- struct ath9k_platform_data *pdata = sc->dev->platform_data;
-
- if (pdata && !pdata->use_eeprom) {
- if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
- ath_err(common,
- "%s: eeprom read failed, offset %08x is out of range\n",
- __func__, off);
-
- return false;
- }
-
- *data = pdata->eeprom_data[off];
- } else {
- struct ath_hw *ah = (struct ath_hw *) common->ah;
-
- common->ops->read(ah, AR5416_EEPROM_OFFSET +
- (off << AR5416_EEPROM_S));
-
- if (!ath9k_hw_wait(ah,
- AR_EEPROM_STATUS_DATA,
- AR_EEPROM_STATUS_DATA_BUSY |
- AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
- AH_WAIT_TIMEOUT)) {
- return false;
- }
-
- *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
- AR_EEPROM_STATUS_DATA_VAL);
+ struct ath_hw *ah = (struct ath_hw *) common->ah;
+
+ common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+ if (!ath9k_hw_wait(ah,
+ AR_EEPROM_STATUS_DATA,
+ AR_EEPROM_STATUS_DATA_BUSY |
+ AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+ AH_WAIT_TIMEOUT)) {
+ return false;
}

+ *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
+ AR_EEPROM_STATUS_DATA_VAL);
+
return true;
}

--
2.9.0