Commit 9dbeb91a8b97e2892c04461e28d2bdd0198b719d

Authored by Gabor Juhos
Committed by John W. Linville
1 parent 09329d371e

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>

Showing 5 changed files with 77 additions and 48 deletions Side-by-side Diff

drivers/net/wireless/ath9k/ahb.c
... ... @@ -18,6 +18,7 @@
18 18  
19 19 #include <linux/nl80211.h>
20 20 #include <linux/platform_device.h>
  21 +#include <linux/ath9k_platform.h>
21 22 #include "core.h"
22 23 #include "reg.h"
23 24 #include "hw.h"
24 25  
... ... @@ -33,9 +34,29 @@
33 34 iounmap(sc->mem);
34 35 }
35 36  
  37 +static bool ath_ahb_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
  38 +{
  39 + struct ath_softc *sc = ah->ah_sc;
  40 + struct platform_device *pdev = to_platform_device(sc->dev);
  41 + struct ath9k_platform_data *pdata;
  42 +
  43 + pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
  44 + if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
  45 + DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
  46 + "%s: flash read failed, offset %08x is out of range\n",
  47 + __func__, off);
  48 + return false;
  49 + }
  50 +
  51 + *data = pdata->eeprom_data[off];
  52 + return true;
  53 +}
  54 +
36 55 static struct ath_bus_ops ath_ahb_bus_ops = {
37 56 .read_cachesize = ath_ahb_read_cachesize,
38 57 .cleanup = ath_ahb_cleanup,
  58 +
  59 + .eeprom_read = ath_ahb_eeprom_read,
39 60 };
40 61  
41 62 static int ath_ahb_probe(struct platform_device *pdev)
... ... @@ -47,6 +68,12 @@
47 68 int irq;
48 69 int ret = 0;
49 70 struct ath_hal *ah;
  71 +
  72 + if (!pdev->dev.platform_data) {
  73 + dev_err(&pdev->dev, "no platform data specified\n");
  74 + ret = -EINVAL;
  75 + goto err_out;
  76 + }
50 77  
51 78 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
52 79 if (res == NULL) {
drivers/net/wireless/ath9k/core.h
... ... @@ -696,6 +696,7 @@
696 696 struct ath_bus_ops {
697 697 void (*read_cachesize)(struct ath_softc *sc, int *csz);
698 698 void (*cleanup)(struct ath_softc *sc);
  699 + bool (*eeprom_read)(struct ath_hal *ah, u32 off, u16 *data);
699 700 };
700 701  
701 702 struct ath_softc {
drivers/net/wireless/ath9k/eeprom.c
... ... @@ -91,55 +91,13 @@
91 91 return false;
92 92 }
93 93  
94   -static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
  94 +static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
95 95 {
96   - (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
  96 + struct ath_softc *sc = ah->ah_sc;
97 97  
98   - if (!ath9k_hw_wait(ah,
99   - AR_EEPROM_STATUS_DATA,
100   - AR_EEPROM_STATUS_DATA_BUSY |
101   - AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
102   - return false;
103   - }
104   -
105   - *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
106   - AR_EEPROM_STATUS_DATA_VAL);
107   -
108   - return true;
  98 + return sc->bus_ops->eeprom_read(ah, off, data);
109 99 }
110 100  
111   -static int ath9k_hw_flash_map(struct ath_hal *ah)
112   -{
113   - struct ath_hal_5416 *ahp = AH5416(ah);
114   -
115   - ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
116   -
117   - if (!ahp->ah_cal_mem) {
118   - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
119   - "cannot remap eeprom region \n");
120   - return -EIO;
121   - }
122   -
123   - return 0;
124   -}
125   -
126   -static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
127   -{
128   - struct ath_hal_5416 *ahp = AH5416(ah);
129   -
130   - *data = ioread16(ahp->ah_cal_mem + off);
131   -
132   - return true;
133   -}
134   -
135   -static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
136   -{
137   - if (ath9k_hw_use_flash(ah))
138   - return ath9k_hw_flash_read(ah, off, data);
139   - else
140   - return ath9k_hw_eeprom_read(ah, off, data);
141   -}
142   -
143 101 static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
144 102 {
145 103 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
... ... @@ -2824,9 +2782,6 @@
2824 2782 {
2825 2783 int status;
2826 2784 struct ath_hal_5416 *ahp = AH5416(ah);
2827   -
2828   - if (ath9k_hw_use_flash(ah))
2829   - ath9k_hw_flash_map(ah);
2830 2785  
2831 2786 if (AR_SREV_9285(ah))
2832 2787 ahp->ah_eep_map = EEP_MAP_4KBITS;
drivers/net/wireless/ath9k/pci.c
... ... @@ -58,9 +58,27 @@
58 58 pci_disable_device(pdev);
59 59 }
60 60  
  61 +static bool ath_pci_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
  62 +{
  63 + (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
  64 +
  65 + if (!ath9k_hw_wait(ah,
  66 + AR_EEPROM_STATUS_DATA,
  67 + AR_EEPROM_STATUS_DATA_BUSY |
  68 + AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
  69 + return false;
  70 + }
  71 +
  72 + *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
  73 + AR_EEPROM_STATUS_DATA_VAL);
  74 +
  75 + return true;
  76 +}
  77 +
61 78 static struct ath_bus_ops ath_pci_bus_ops = {
62 79 .read_cachesize = ath_pci_read_cachesize,
63 80 .cleanup = ath_pci_cleanup,
  81 + .eeprom_read = ath_pci_eeprom_read,
64 82 };
65 83  
66 84 static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
include/linux/ath9k_platform.h
  1 +/*
  2 + * Copyright (c) 2008 Atheros Communications Inc.
  3 + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  4 + * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
  5 + *
  6 + * Permission to use, copy, modify, and/or distribute this software for any
  7 + * purpose with or without fee is hereby granted, provided that the above
  8 + * copyright notice and this permission notice appear in all copies.
  9 + *
  10 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17 + */
  18 +
  19 +#ifndef _LINUX_ATH9K_PLATFORM_H
  20 +#define _LINUX_ATH9K_PLATFORM_H
  21 +
  22 +#define ATH9K_PLAT_EEP_MAX_WORDS 2048
  23 +
  24 +struct ath9k_platform_data {
  25 + u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
  26 +};
  27 +
  28 +#endif /* _LINUX_ATH9K_PLATFORM_H */