From: Gabor Juhos <juhosg@openwrt.org>
Date: Mon, 10 Dec 2012 15:46:15 +0000 (+0000)
Subject: mac80211: ath9k: allow to load EEPROM data via firmware API
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=dfd718d13d5351916325ff7464af88e617804cd4;p=openwrt%2Fstaging%2Fwigyori.git

mac80211: ath9k: allow to load EEPROM data via firmware API

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>

SVN-Revision: 34606
---

diff --git a/package/mac80211/patches/302-pending-ath9k-move-duplicated-debug-message-to-ath9k_hw_nvra.patch b/package/mac80211/patches/302-pending-ath9k-move-duplicated-debug-message-to-ath9k_hw_nvra.patch
new file mode 100644
index 0000000000..8f3e04eddd
--- /dev/null
+++ b/package/mac80211/patches/302-pending-ath9k-move-duplicated-debug-message-to-ath9k_hw_nvra.patch
@@ -0,0 +1,83 @@
+From cd3d888d569f5908c4345f7c99018f574c80a32b Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 9 Dec 2012 14:58:56 +0100
+Subject: [PATCH 1/4] ath9k: move duplicated debug message to
+ 'ath9k_hw_nvram_read'
+
+The fill_eeprom functions are printing the same
+debug message in case the 'ath9k_hw_nvram_read'
+function fails. Remove the duplicated code from
+fill_eeprom functions and add the ath_dbg call
+directly into 'ath9k_hw_nvram_read'.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/ath/ath9k/eeprom.c      |    8 +++++++-
+ drivers/net/wireless/ath/ath9k/eeprom_4k.c   |    6 ++----
+ drivers/net/wireless/ath/ath9k/eeprom_9287.c |    5 +----
+ drivers/net/wireless/ath/ath9k/eeprom_def.c  |    5 +----
+ 4 files changed, 11 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom.c
+@@ -115,7 +115,13 @@ void ath9k_hw_usb_gen_fill_eeprom(struct
+ 
+ bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data)
+ {
+-	return common->bus_ops->eeprom_read(common, off, data);
++	bool ret;
++
++	ret = common->bus_ops->eeprom_read(common, off, data);
++	if (!ret)
++		ath_dbg(common, EEPROM, "Unable to read eeprom region\n");
++
++	return ret;
+ }
+ 
+ void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+@@ -37,11 +37,9 @@ static bool __ath9k_hw_4k_fill_eeprom(st
+ 	int addr, eep_start_loc = 64;
+ 
+ 	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+-		if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
+-			ath_dbg(common, EEPROM,
+-				"Unable to read eeprom region\n");
++		if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
++					 eep_data))
+ 			return false;
+-		}
+ 		eep_data++;
+ 	}
+ 
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+@@ -40,11 +40,8 @@ static bool __ath9k_hw_ar9287_fill_eepro
+ 
+ 	for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) {
+ 		if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
+-					 eep_data)) {
+-			ath_dbg(common, EEPROM,
+-				"Unable to read eeprom region\n");
++					 eep_data))
+ 			return false;
+-		}
+ 		eep_data++;
+ 	}
+ 
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
+@@ -97,11 +97,8 @@ static bool __ath9k_hw_def_fill_eeprom(s
+ 
+ 	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+ 		if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc,
+-					 eep_data)) {
+-			ath_err(ath9k_hw_common(ah),
+-				"Unable to read eeprom region\n");
++					 eep_data))
+ 			return false;
+-		}
+ 		eep_data++;
+ 	}
+ 	return true;
diff --git a/package/mac80211/patches/303-pending-ath9k-add-EEPROM-offset-to-debug-message.patch b/package/mac80211/patches/303-pending-ath9k-add-EEPROM-offset-to-debug-message.patch
new file mode 100644
index 0000000000..d0561938e8
--- /dev/null
+++ b/package/mac80211/patches/303-pending-ath9k-add-EEPROM-offset-to-debug-message.patch
@@ -0,0 +1,26 @@
+From 910b74fb0e0369b18aa689ab02c9413235c18f98 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 9 Dec 2012 16:47:35 +0100
+Subject: [PATCH 2/4] ath9k: add EEPROM offset to debug message
+
+Show the EEPROM offset of the failed read operation
+in 'ath9k_hw_nvram_read'. The debug message is more
+informative this way.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/ath/ath9k/eeprom.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom.c
+@@ -119,7 +119,8 @@ bool ath9k_hw_nvram_read(struct ath_comm
+ 
+ 	ret = common->bus_ops->eeprom_read(common, off, data);
+ 	if (!ret)
+-		ath_dbg(common, EEPROM, "Unable to read eeprom region\n");
++		ath_dbg(common, EEPROM,
++			"unable to read eeprom region at offset %u\n", off);
+ 
+ 	return ret;
+ }
diff --git a/package/mac80211/patches/304-pending-ath9k-use-struct-ath_hw-as-the-first-argument-for-at.patch b/package/mac80211/patches/304-pending-ath9k-use-struct-ath_hw-as-the-first-argument-for-at.patch
new file mode 100644
index 0000000000..9076522a8b
--- /dev/null
+++ b/package/mac80211/patches/304-pending-ath9k-use-struct-ath_hw-as-the-first-argument-for-at.patch
@@ -0,0 +1,203 @@
+From 26c22324cca2db37fa294156fd875100d95438f4 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 9 Dec 2012 15:19:01 +0100
+Subject: [PATCH 3/4] ath9k: use 'struct ath_hw *' as the first argument for
+ 'ath9k_hw_nvram_read'
+
+The 'ath9k_hw_nvram_read' function takes a
+'struct ath_common *' as its first argument.
+Almost each of its caller has a 'struct ath_hw *'
+parameter in their argument list, and that is
+dereferenced in order to get the 'struct ath_common'
+pointer.
+
+Change the first argument of 'ath9k_hw_nvram_read'
+to be a 'struct ath_hw *', and remove the dereference
+calls from the callers.
+
+Also change the type of the first argument of the
+ar9300_eeprom_read_{byte,word} functions.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |   17 ++++++++---------
+ drivers/net/wireless/ath/ath9k/eeprom.c        |    3 ++-
+ drivers/net/wireless/ath/ath9k/eeprom.h        |    2 +-
+ drivers/net/wireless/ath/ath9k/eeprom_4k.c     |    6 ++----
+ drivers/net/wireless/ath/ath9k/eeprom_9287.c   |    6 ++----
+ drivers/net/wireless/ath/ath9k/eeprom_def.c    |    5 ++---
+ 6 files changed, 17 insertions(+), 22 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+@@ -3005,24 +3005,24 @@ static u32 ath9k_hw_ar9300_get_eeprom(st
+ 	}
+ }
+ 
+-static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
++static bool ar9300_eeprom_read_byte(struct ath_hw *ah, int address,
+ 				    u8 *buffer)
+ {
+ 	u16 val;
+ 
+-	if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
++	if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
+ 		return false;
+ 
+ 	*buffer = (val >> (8 * (address % 2))) & 0xff;
+ 	return true;
+ }
+ 
+-static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
++static bool ar9300_eeprom_read_word(struct ath_hw *ah, int address,
+ 				    u8 *buffer)
+ {
+ 	u16 val;
+ 
+-	if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
++	if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
+ 		return false;
+ 
+ 	buffer[0] = val >> 8;
+@@ -3048,14 +3048,14 @@ static bool ar9300_read_eeprom(struct at
+ 	 * the 16-bit word at that address
+ 	 */
+ 	if (address % 2 == 0) {
+-		if (!ar9300_eeprom_read_byte(common, address--, buffer++))
++		if (!ar9300_eeprom_read_byte(ah, address--, buffer++))
+ 			goto error;
+ 
+ 		count--;
+ 	}
+ 
+ 	for (i = 0; i < count / 2; i++) {
+-		if (!ar9300_eeprom_read_word(common, address, buffer))
++		if (!ar9300_eeprom_read_word(ah, address, buffer))
+ 			goto error;
+ 
+ 		address -= 2;
+@@ -3063,7 +3063,7 @@ static bool ar9300_read_eeprom(struct at
+ 	}
+ 
+ 	if (count % 2)
+-		if (!ar9300_eeprom_read_byte(common, address, buffer))
++		if (!ar9300_eeprom_read_byte(ah, address, buffer))
+ 			goto error;
+ 
+ 	return true;
+@@ -3240,12 +3240,11 @@ static bool ar9300_check_eeprom_header(s
+ static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
+ 				       int mdata_size)
+ {
+-	struct ath_common *common = ath9k_hw_common(ah);
+ 	u16 *data = (u16 *) mptr;
+ 	int i;
+ 
+ 	for (i = 0; i < mdata_size / 2; i++, data++)
+-		ath9k_hw_nvram_read(common, i, data);
++		ath9k_hw_nvram_read(ah, i, data);
+ 
+ 	return 0;
+ }
+--- a/drivers/net/wireless/ath/ath9k/eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom.c
+@@ -113,8 +113,9 @@ void ath9k_hw_usb_gen_fill_eeprom(struct
+ 	}
+ }
+ 
+-bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data)
++bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
+ {
++	struct ath_common *common = ath9k_hw_common(ah);
+ 	bool ret;
+ 
+ 	ret = common->bus_ops->eeprom_read(common, off, data);
+--- a/drivers/net/wireless/ath/ath9k/eeprom.h
++++ b/drivers/net/wireless/ath/ath9k/eeprom.h
+@@ -663,7 +663,7 @@ int16_t ath9k_hw_interpolate(u16 target,
+ 			     int16_t targetRight);
+ bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
+ 				    u16 *indexL, u16 *indexR);
+-bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data);
++bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data);
+ void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
+ 				  int eep_start_loc, int size);
+ void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+@@ -32,13 +32,11 @@ static int ath9k_hw_4k_get_eeprom_rev(st
+ 
+ static bool __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+ {
+-	struct ath_common *common = ath9k_hw_common(ah);
+ 	u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+ 	int addr, eep_start_loc = 64;
+ 
+ 	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+-		if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
+-					 eep_data))
++		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data))
+ 			return false;
+ 		eep_data++;
+ 	}
+@@ -194,7 +192,7 @@ static int ath9k_hw_4k_check_eeprom(stru
+ 
+ 
+ 	if (!ath9k_hw_use_flash(ah)) {
+-		if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
++		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+ 					 &magic)) {
+ 			ath_err(common, "Reading Magic # failed\n");
+ 			return false;
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+@@ -33,14 +33,12 @@ static int ath9k_hw_ar9287_get_eeprom_re
+ static bool __ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
+ {
+ 	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+-	struct ath_common *common = ath9k_hw_common(ah);
+ 	u16 *eep_data;
+ 	int addr, eep_start_loc = AR9287_EEP_START_LOC;
+ 	eep_data = (u16 *)eep;
+ 
+ 	for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) {
+-		if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
+-					 eep_data))
++		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data))
+ 			return false;
+ 		eep_data++;
+ 	}
+@@ -187,7 +185,7 @@ static int ath9k_hw_ar9287_check_eeprom(
+ 	struct ath_common *common = ath9k_hw_common(ah);
+ 
+ 	if (!ath9k_hw_use_flash(ah)) {
+-		if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
++		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+ 					 &magic)) {
+ 			ath_err(common, "Reading Magic # failed\n");
+ 			return false;
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
+@@ -91,12 +91,11 @@ static int ath9k_hw_def_get_eeprom_rev(s
+ 
+ static bool __ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+ {
+-	struct ath_common *common = ath9k_hw_common(ah);
+ 	u16 *eep_data = (u16 *)&ah->eeprom.def;
+ 	int addr, ar5416_eep_start_loc = 0x100;
+ 
+ 	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+-		if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc,
++		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+ 					 eep_data))
+ 			return false;
+ 		eep_data++;
+@@ -268,7 +267,7 @@ static int ath9k_hw_def_check_eeprom(str
+ 	bool need_swap = false;
+ 	int i, addr, size;
+ 
+-	if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
++	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+ 		ath_err(common, "Reading Magic # failed\n");
+ 		return false;
+ 	}
diff --git a/package/mac80211/patches/305-pending-ath9k-allow-to-load-EEPROM-content-via-firmware-API.patch b/package/mac80211/patches/305-pending-ath9k-allow-to-load-EEPROM-content-via-firmware-API.patch
new file mode 100644
index 0000000000..78efdc4e37
--- /dev/null
+++ b/package/mac80211/patches/305-pending-ath9k-allow-to-load-EEPROM-content-via-firmware-API.patch
@@ -0,0 +1,184 @@
+From ee4581f2f024c601a5e247ec6acab3e7df538f88 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 9 Dec 2012 17:31:54 +0100
+Subject: [PATCH 4/4] ath9k: allow to load EEPROM content via firmware API
+
+The calibration data for devices w/o a separate
+EEPROM chip can be specified via the 'eeprom_data'
+field of 'ath9k_platform_data'. The 'eeprom_data'
+is usually filled from board specific setup
+functions. It is easy if the EEPROM data is mapped
+to the memory, but it can be complicated if it is
+stored elsewhere.
+
+The patch adds support for loading of the EEPROM
+data via the firmware API to avoid this limitation.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/ath/ath9k/eeprom.c |   19 +++++++++-
+ drivers/net/wireless/ath/ath9k/hw.h     |    3 ++
+ drivers/net/wireless/ath/ath9k/init.c   |   60 ++++++++++++++++++++++++++++++-
+ include/linux/ath9k_platform.h          |    2 ++
+ 4 files changed, 82 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom.c
+@@ -113,12 +113,29 @@ void ath9k_hw_usb_gen_fill_eeprom(struct
+ 	}
+ }
+ 
++static bool ath9k_hw_nvram_read_blob(struct ath_hw *ah, u32 off,
++				     u16 *data)
++{
++	u16 *blob_data;
++
++	if (off * sizeof(u16) > ah->eeprom_blob->size)
++		return false;
++
++	blob_data = (u16 *)ah->eeprom_blob->data;
++	*data =  blob_data[off];
++	return true;
++}
++
+ bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
+ {
+ 	struct ath_common *common = ath9k_hw_common(ah);
+ 	bool ret;
+ 
+-	ret = common->bus_ops->eeprom_read(common, off, data);
++	if (ah->eeprom_blob)
++		ret = ath9k_hw_nvram_read_blob(ah, off, data);
++	else
++		ret = common->bus_ops->eeprom_read(common, off, data);
++
+ 	if (!ret)
+ 		ath_dbg(common, EEPROM,
+ 			"unable to read eeprom region at offset %u\n", off);
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -20,6 +20,7 @@
+ #include <linux/if_ether.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
++#include <linux/firmware.h>
+ 
+ #include "mac.h"
+ #include "ani.h"
+@@ -920,6 +921,8 @@ struct ath_hw {
+ 	bool is_clk_25mhz;
+ 	int (*get_mac_revision)(void);
+ 	int (*external_reset)(void);
++
++	const struct firmware *eeprom_blob;
+ };
+ 
+ struct ath_bus_ops {
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -25,6 +25,11 @@
+ 
+ #include "ath9k.h"
+ 
++struct ath9k_eeprom_ctx {
++	struct completion complete;
++	struct ath_hw *ah;
++};
++
+ static char *dev_info = "ath9k";
+ 
+ MODULE_AUTHOR("Atheros Communications");
+@@ -508,6 +513,51 @@ static void ath9k_init_misc(struct ath_s
+ 		sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
+ }
+ 
++static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
++				    void *ctx)
++{
++	struct ath9k_eeprom_ctx *ec = ctx;
++
++	if (eeprom_blob)
++		ec->ah->eeprom_blob = eeprom_blob;
++
++	complete(&ec->complete);
++}
++
++static int ath9k_eeprom_request(struct ath_softc *sc, const char *name)
++{
++	struct ath9k_eeprom_ctx ec;
++	struct ath_hw *ah = ah = sc->sc_ah;
++	int err;
++
++	/* try to load the EEPROM content asynchronously */
++	init_completion(&ec.complete);
++	ec.ah = sc->sc_ah;
++
++	err = request_firmware_nowait(THIS_MODULE, 1, name, sc->dev, GFP_KERNEL,
++				      &ec, ath9k_eeprom_request_cb);
++	if (err < 0) {
++		ath_err(ath9k_hw_common(ah),
++			"EEPROM request failed\n");
++		return err;
++	}
++
++	wait_for_completion(&ec.complete);
++
++	if (!ah->eeprom_blob) {
++		ath_err(ath9k_hw_common(ah),
++			"Unable to load EEPROM file %s\n", name);
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static void ath9k_eeprom_release(struct ath_softc *sc)
++{
++	release_firmware(sc->sc_ah->eeprom_blob);
++}
++
+ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
+ 			    const struct ath_bus_ops *bus_ops)
+ {
+@@ -585,6 +635,12 @@ static int ath9k_init_softc(u16 devid, s
+ 	ath_read_cachesize(common, &csz);
+ 	common->cachelsz = csz << 2; /* convert to bytes */
+ 
++	if (pdata->eeprom_name) {
++		ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
++		if (ret)
++			goto err_eeprom;
++	}
++
+ 	/* Initializes the hardware for all supported chipsets */
+ 	ret = ath9k_hw_init(ah);
+ 	if (ret)
+@@ -621,7 +677,8 @@ err_btcoex:
+ err_queues:
+ 	ath9k_hw_deinit(ah);
+ err_hw:
+-
++	ath9k_eeprom_release(sc);
++err_eeprom:
+ 	kfree(ah);
+ 	sc->sc_ah = NULL;
+ 
+@@ -884,6 +941,7 @@ static void ath9k_deinit_softc(struct at
+ 	if (sc->dfs_detector != NULL)
+ 		sc->dfs_detector->exit(sc->dfs_detector);
+ 
++	ath9k_eeprom_release(sc);
+ 	kfree(sc->sc_ah);
+ 	sc->sc_ah = NULL;
+ }
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -22,6 +22,8 @@
+ #define ATH9K_PLAT_EEP_MAX_WORDS	2048
+ 
+ struct ath9k_platform_data {
++	const char *eeprom_name;
++
+ 	u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
+ 	u8 *macaddr;
+ 
diff --git a/package/mac80211/patches/401-ath9k_blink_default.patch b/package/mac80211/patches/401-ath9k_blink_default.patch
index 10c7636963..b0cef87762 100644
--- a/package/mac80211/patches/401-ath9k_blink_default.patch
+++ b/package/mac80211/patches/401-ath9k_blink_default.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -40,7 +40,7 @@ int ath9k_modparam_nohwcrypt;
+@@ -45,7 +45,7 @@ int ath9k_modparam_nohwcrypt;
  module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
  MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
  
diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
index e8c7e952a9..8f82da5e3e 100644
--- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
+++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -678,6 +678,7 @@ static const struct ieee80211_iface_limi
+@@ -735,6 +735,7 @@ static const struct ieee80211_iface_limi
  #endif
  				 BIT(NL80211_IFTYPE_AP) |
  				 BIT(NL80211_IFTYPE_P2P_GO) },
diff --git a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
index 9d7385de7a..20282573f8 100644
--- a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
+++ b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
 +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
-@@ -266,7 +266,7 @@ static int ath9k_hw_def_check_eeprom(str
+@@ -262,7 +262,7 @@ static int ath9k_hw_def_check_eeprom(str
  {
  	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
  	struct ath_common *common = ath9k_hw_common(ah);
@@ -9,7 +9,7 @@
  	u32 sum = 0, el;
  	bool need_swap = false;
  	int i, addr, size;
-@@ -276,27 +276,16 @@ static int ath9k_hw_def_check_eeprom(str
+@@ -272,27 +272,16 @@ static int ath9k_hw_def_check_eeprom(str
  		return false;
  	}
  
@@ -49,29 +49,29 @@
  
 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
 +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-@@ -195,7 +195,7 @@ static int ath9k_hw_4k_check_eeprom(stru
- 	int i, addr;
- 
+@@ -57,7 +57,7 @@ static bool ath9k_hw_4k_fill_eeprom(stru
+ {
+ 	struct ath_common *common = ath9k_hw_common(ah);
  
 -	if (!ath9k_hw_use_flash(ah)) {
 +	if (!(ah->ah_flags & AH_NO_EEP_SWAP)) {
- 		if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
- 					 &magic)) {
- 			ath_err(common, "Reading Magic # failed\n");
+ 		ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
+ 	}
+ 
 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
 +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-@@ -189,7 +189,7 @@ static int ath9k_hw_ar9287_check_eeprom(
- 	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+@@ -60,7 +60,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(
+ {
  	struct ath_common *common = ath9k_hw_common(ah);
  
 -	if (!ath9k_hw_use_flash(ah)) {
 +	if (!(ah->ah_flags & AH_NO_EEP_SWAP)) {
- 		if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
- 					 &magic)) {
- 			ath_err(common, "Reading Magic # failed\n");
+ 		ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n");
+ 	}
+ 
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -704,6 +704,7 @@ enum ath_cal_list {
+@@ -705,6 +705,7 @@ enum ath_cal_list {
  #define AH_USE_EEPROM   0x1
  #define AH_UNPLUGGED    0x2 /* The card has been physically removed. */
  #define AH_FASTCC       0x4
@@ -81,7 +81,7 @@
  	struct ath_ops reg_ops;
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -541,6 +541,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -591,6 +591,8 @@ static int ath9k_init_softc(u16 devid, s
  		ah->is_clk_25mhz = pdata->is_clk_25mhz;
  		ah->get_mac_revision = pdata->get_mac_revision;
  		ah->external_reset = pdata->external_reset;
@@ -92,7 +92,7 @@
  	common = ath9k_hw_common(ah);
 --- a/include/linux/ath9k_platform.h
 +++ b/include/linux/ath9k_platform.h
-@@ -29,6 +29,7 @@ struct ath9k_platform_data {
+@@ -31,6 +31,7 @@ struct ath9k_platform_data {
  	u32 gpio_mask;
  	u32 gpio_val;
  
diff --git a/package/mac80211/patches/502-ath9k_ahb_init.patch b/package/mac80211/patches/502-ath9k_ahb_init.patch
index 4c089c9cc4..21461b57db 100644
--- a/package/mac80211/patches/502-ath9k_ahb_init.patch
+++ b/package/mac80211/patches/502-ath9k_ahb_init.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -936,23 +936,23 @@ static int __init ath9k_init(void)
+@@ -994,23 +994,23 @@ static int __init ath9k_init(void)
  		goto err_out;
  	}
  
diff --git a/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
index 9760b054c9..e1f17ff1d1 100644
--- a/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
+++ b/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
@@ -47,10 +47,11 @@
  };
  
  /* policy for the key attributes */
-@@ -1652,6 +1653,22 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -1651,6 +1652,22 @@ static int nl80211_set_wiphy(struct sk_b
+ 		if (result)
  			goto bad_res;
  	}
- 
++
 +	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
 +		int idx, dbi = 0;
 +
@@ -66,10 +67,9 @@
 +		if (result)
 +			goto bad_res;
 +	}
-+
+ 
  	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
  	    info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
- 		u32 tx_ant, rx_ant;
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
 @@ -2118,6 +2118,19 @@ static int ieee80211_get_tx_power(struct
@@ -92,7 +92,7 @@
  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
  				  const u8 *addr)
  {
-@@ -3241,6 +3254,7 @@ struct cfg80211_ops mac80211_config_ops 
+@@ -3241,6 +3254,7 @@ struct cfg80211_ops mac80211_config_ops
  	.set_wiphy_params = ieee80211_set_wiphy_params,
  	.set_tx_power = ieee80211_set_tx_power,
  	.get_tx_power = ieee80211_get_tx_power,
diff --git a/package/mac80211/patches/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch
index 8da33b901f..bd428d0b23 100644
--- a/package/mac80211/patches/530-ath9k_extra_leds.patch
+++ b/package/mac80211/patches/530-ath9k_extra_leds.patch
@@ -162,7 +162,7 @@
  void ath_fill_led_pin(struct ath_softc *sc)
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -821,7 +821,7 @@ int ath9k_init_device(u16 devid, struct 
+@@ -878,7 +878,7 @@ int ath9k_init_device(u16 devid, struct
  
  #ifdef CONFIG_MAC80211_LEDS
  	/* must be initialized before ieee80211_register_hw */
diff --git a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
index c64c89a369..d07fc4eaa6 100644
--- a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
+++ b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
@@ -1,6 +1,6 @@
 --- a/include/linux/ath9k_platform.h
 +++ b/include/linux/ath9k_platform.h
-@@ -33,6 +33,9 @@ struct ath9k_platform_data {
+@@ -35,6 +35,9 @@ struct ath9k_platform_data {
  	bool is_clk_25mhz;
  	int (*get_mac_revision)(void);
  	int (*external_reset)(void);
diff --git a/package/mac80211/patches/553-ath9k_debugfs_diag.patch b/package/mac80211/patches/553-ath9k_debugfs_diag.patch
index 34fca90e0c..2590d92f42 100644
--- a/package/mac80211/patches/553-ath9k_debugfs_diag.patch
+++ b/package/mac80211/patches/553-ath9k_debugfs_diag.patch
@@ -62,7 +62,7 @@
  	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -497,6 +497,12 @@ enum {
+@@ -498,6 +498,12 @@ enum {
  	ATH9K_RESET_COLD,
  };
  
@@ -75,7 +75,7 @@
  struct ath9k_hw_version {
  	u32 magic;
  	u16 devid;
-@@ -741,6 +747,8 @@ struct ath_hw {
+@@ -742,6 +748,8 @@ struct ath_hw {
  	u32 rfkill_polarity;
  	u32 ah_flags;
  
@@ -84,7 +84,7 @@
  	bool reset_power_on;
  	bool htc_reset_init;
  
-@@ -1007,6 +1015,7 @@ void ath9k_hw_set_sta_beacon_timers(stru
+@@ -1010,6 +1018,7 @@ void ath9k_hw_set_sta_beacon_timers(stru
  bool ath9k_hw_check_alive(struct ath_hw *ah);
  
  bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
diff --git a/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
index 9d0d28ee91..37a09b25aa 100644
--- a/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
+++ b/package/mac80211/patches/555-ath9k-allow-to-disable-bands-via-platform-data.patch
@@ -1,6 +1,6 @@
 --- a/include/linux/ath9k_platform.h
 +++ b/include/linux/ath9k_platform.h
-@@ -31,6 +31,9 @@ struct ath9k_platform_data {
+@@ -33,6 +33,9 @@ struct ath9k_platform_data {
  
  	bool endian_check;
  	bool is_clk_25mhz;
@@ -48,18 +48,18 @@
  	    AR_SREV_9285(ah) ||
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -929,6 +929,8 @@ struct ath_hw {
+@@ -930,6 +930,8 @@ struct ath_hw {
  	bool is_clk_25mhz;
  	int (*get_mac_revision)(void);
  	int (*external_reset)(void);
 +	bool disable_2ghz;
 +	bool disable_5ghz;
- };
  
- struct ath_bus_ops {
+ 	const struct firmware *eeprom_blob;
+ };
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -541,6 +541,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -591,6 +591,8 @@ static int ath9k_init_softc(u16 devid, s
  		ah->is_clk_25mhz = pdata->is_clk_25mhz;
  		ah->get_mac_revision = pdata->get_mac_revision;
  		ah->external_reset = pdata->external_reset;
diff --git a/target/linux/generic/files/include/linux/ath9k_platform.h b/target/linux/generic/files/include/linux/ath9k_platform.h
index 53b25d2296..a0b7531fdb 100644
--- a/target/linux/generic/files/include/linux/ath9k_platform.h
+++ b/target/linux/generic/files/include/linux/ath9k_platform.h
@@ -22,6 +22,8 @@
 #define ATH9K_PLAT_EEP_MAX_WORDS	2048
 
 struct ath9k_platform_data {
+	const char *eeprom_name;
+
 	u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
 	u8 *macaddr;