ath9k: get EEPROM contents from platform data on AHB bus
On the AR913x SOCs we have to provide EEPROM contents via platform_data,
because accessing the flash via MMIO is not safe. Additionally different
boards may store the radio calibration data at different locations.
Changes-licensed-under: ISC
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Tested-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c
index 8cbd4c2..7f2c3a0 100644
--- a/drivers/net/wireless/ath9k/ahb.c
+++ b/drivers/net/wireless/ath9k/ahb.c
@@ -18,6 +18,7 @@
#include <linux/nl80211.h>
#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
#include "core.h"
#include "reg.h"
#include "hw.h"
@@ -33,9 +34,29 @@
iounmap(sc->mem);
}
+static bool ath_ahb_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
+{
+ struct ath_softc *sc = ah->ah_sc;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ath9k_platform_data *pdata;
+
+ pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
+ if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "%s: flash read failed, offset %08x is out of range\n",
+ __func__, off);
+ return false;
+ }
+
+ *data = pdata->eeprom_data[off];
+ return true;
+}
+
static struct ath_bus_ops ath_ahb_bus_ops = {
.read_cachesize = ath_ahb_read_cachesize,
.cleanup = ath_ahb_cleanup,
+
+ .eeprom_read = ath_ahb_eeprom_read,
};
static int ath_ahb_probe(struct platform_device *pdev)
@@ -48,6 +69,12 @@
int ret = 0;
struct ath_hal *ah;
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "no platform data specified\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no memory resource found\n");
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index c5dae11..b687ae9 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -696,6 +696,7 @@
struct ath_bus_ops {
void (*read_cachesize)(struct ath_softc *sc, int *csz);
void (*cleanup)(struct ath_softc *sc);
+ bool (*eeprom_read)(struct ath_hal *ah, u32 off, u16 *data);
};
struct ath_softc {
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
index 1ef8b5a..50cb388 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -91,53 +91,11 @@
return false;
}
-static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
-{
- (void)REG_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)) {
- return false;
- }
-
- *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
- AR_EEPROM_STATUS_DATA_VAL);
-
- return true;
-}
-
-static int ath9k_hw_flash_map(struct ath_hal *ah)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
-
- if (!ahp->ah_cal_mem) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "cannot remap eeprom region \n");
- return -EIO;
- }
-
- return 0;
-}
-
-static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- *data = ioread16(ahp->ah_cal_mem + off);
-
- return true;
-}
-
static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
{
- if (ath9k_hw_use_flash(ah))
- return ath9k_hw_flash_read(ah, off, data);
- else
- return ath9k_hw_eeprom_read(ah, off, data);
+ struct ath_softc *sc = ah->ah_sc;
+
+ return sc->bus_ops->eeprom_read(ah, off, data);
}
static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
@@ -2825,9 +2783,6 @@
int status;
struct ath_hal_5416 *ahp = AH5416(ah);
- if (ath9k_hw_use_flash(ah))
- ath9k_hw_flash_map(ah);
-
if (AR_SREV_9285(ah))
ahp->ah_eep_map = EEP_MAP_4KBITS;
else
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
index 4ff1caa..05612bf 100644
--- a/drivers/net/wireless/ath9k/pci.c
+++ b/drivers/net/wireless/ath9k/pci.c
@@ -58,9 +58,27 @@
pci_disable_device(pdev);
}
+static bool ath_pci_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
+{
+ (void)REG_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)) {
+ return false;
+ }
+
+ *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+ AR_EEPROM_STATUS_DATA_VAL);
+
+ return true;
+}
+
static struct ath_bus_ops ath_pci_bus_ops = {
.read_cachesize = ath_pci_read_cachesize,
.cleanup = ath_pci_cleanup,
+ .eeprom_read = ath_pci_eeprom_read,
};
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)