summaryrefslogtreecommitdiff
path: root/package/mac80211/patches/408-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/408-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch')
-rw-r--r--package/mac80211/patches/408-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch222
1 files changed, 222 insertions, 0 deletions
diff --git a/package/mac80211/patches/408-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch b/package/mac80211/patches/408-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch
new file mode 100644
index 0000000000..03464db7ac
--- /dev/null
+++ b/package/mac80211/patches/408-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch
@@ -0,0 +1,222 @@
+From 1781a259c5c34d63279b997bded2db672b3665d2 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Fri, 2 Jan 2009 16:13:46 +0100
+Subject: [RFC 08/12] 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.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
+---
+ drivers/net/wireless/ath9k/ahb.c | 27 ++++++++++++++++++
+ drivers/net/wireless/ath9k/core.h | 2 +
+ drivers/net/wireless/ath9k/eeprom.c | 51 ++--------------------------------
+ drivers/net/wireless/ath9k/pci.c | 19 +++++++++++++
+ include/linux/ath9k_platform.h | 28 +++++++++++++++++++
+ 5 files changed, 79 insertions(+), 48 deletions(-)
+
+--- 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"
+@@ -101,6 +102,24 @@ static void ath_ahb_cleanup(struct ath_s
+ platform_set_drvdata(pdev, NULL);
+ }
+
++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 = {
+ .dma_map_single_to_device = ath_ahb_map_single_to_device,
+ .dma_unmap_single_to_device = ath_ahb_unmap_single_to_device,
+@@ -118,6 +137,8 @@ static struct ath_bus_ops ath_ahb_bus_op
+ .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)
+@@ -130,6 +151,12 @@ static int ath_ahb_probe(struct platform
+ 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");
+--- a/drivers/net/wireless/ath9k/core.h
++++ b/drivers/net/wireless/ath9k/core.h
+@@ -726,6 +726,8 @@ 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 {
+--- a/drivers/net/wireless/ath9k/eeprom.c
++++ b/drivers/net/wireless/ath9k/eeprom.c
+@@ -91,53 +91,11 @@ static inline bool ath9k_hw_get_lower_up
+ 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)
+@@ -2805,9 +2763,6 @@ int ath9k_hw_eeprom_attach(struct ath_ha
+ 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
+--- a/drivers/net/wireless/ath9k/pci.c
++++ b/drivers/net/wireless/ath9k/pci.c
+@@ -121,6 +121,23 @@ static void ath_pci_cleanup(struct ath_s
+ ieee80211_free_hw(sc->hw);
+ }
+
++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 = {
+ .dma_map_single_to_device = ath_pci_map_single_to_device,
+ .dma_unmap_single_to_device = ath_pci_unmap_single_to_device,
+@@ -138,6 +155,8 @@ static struct ath_bus_ops ath_pci_bus_op
+ .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)
+--- /dev/null
++++ b/include/linux/ath9k_platform.h
+@@ -0,0 +1,28 @@
++/*
++ * Copyright (c) 2008 Atheros Communications Inc.
++ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _LINUX_ATH9K_PLATFORM_H
++#define _LINUX_ATH9L_PLATFORM_H
++
++#define ATH9K_PLAT_EEP_MAX_WORDS 2048
++
++struct ath9k_platform_data {
++ u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
++};
++
++#endif /* _LINUX_ATH9K_PLATFORM_H */