mac80211: add preliminary support for the AR913x SoCs
[openwrt/openwrt.git] / package / mac80211 / patches / 408-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch
1 From 1781a259c5c34d63279b997bded2db672b3665d2 Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Fri, 2 Jan 2009 16:13:46 +0100
4 Subject: [RFC 08/12] ath9k: get EEPROM contents from platform data on AHB bus
5
6 On the AR913x SOCs we have to provide EEPROM contents via platform_data,
7 because accessing the flash via MMIO is not safe. Additionally different
8 boards may store the radio calibration data at different locations.
9
10 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
11 Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
12 ---
13 drivers/net/wireless/ath9k/ahb.c | 27 ++++++++++++++++++
14 drivers/net/wireless/ath9k/core.h | 2 +
15 drivers/net/wireless/ath9k/eeprom.c | 51 ++--------------------------------
16 drivers/net/wireless/ath9k/pci.c | 19 +++++++++++++
17 include/linux/ath9k_platform.h | 28 +++++++++++++++++++
18 5 files changed, 79 insertions(+), 48 deletions(-)
19
20 --- a/drivers/net/wireless/ath9k/ahb.c
21 +++ b/drivers/net/wireless/ath9k/ahb.c
22 @@ -18,6 +18,7 @@
23
24 #include <linux/nl80211.h>
25 #include <linux/platform_device.h>
26 +#include <linux/ath9k_platform.h>
27 #include "core.h"
28 #include "reg.h"
29 #include "hw.h"
30 @@ -101,6 +102,24 @@ static void ath_ahb_cleanup(struct ath_s
31 platform_set_drvdata(pdev, NULL);
32 }
33
34 +static bool ath_ahb_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
35 +{
36 + struct ath_softc *sc = ah->ah_sc;
37 + struct platform_device *pdev = to_platform_device(sc->dev);
38 + struct ath9k_platform_data *pdata;
39 +
40 + pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
41 + if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
42 + DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
43 + "%s: flash read failed, offset %08x is out of range\n",
44 + __func__, off);
45 + return false;
46 + }
47 +
48 + *data = pdata->eeprom_data[off];
49 + return true;
50 +}
51 +
52 static struct ath_bus_ops ath_ahb_bus_ops = {
53 .dma_map_single_to_device = ath_ahb_map_single_to_device,
54 .dma_unmap_single_to_device = ath_ahb_unmap_single_to_device,
55 @@ -118,6 +137,8 @@ static struct ath_bus_ops ath_ahb_bus_op
56 .read_cachesize = ath_ahb_read_cachesize,
57
58 .cleanup = ath_ahb_cleanup,
59 +
60 + .eeprom_read = ath_ahb_eeprom_read,
61 };
62
63 static int ath_ahb_probe(struct platform_device *pdev)
64 @@ -130,6 +151,12 @@ static int ath_ahb_probe(struct platform
65 int ret = 0;
66 struct ath_hal *ah;
67
68 + if (!pdev->dev.platform_data) {
69 + dev_err(&pdev->dev, "no platform data specified\n");
70 + ret = -EINVAL;
71 + goto err_out;
72 + }
73 +
74 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
75 if (res == NULL) {
76 dev_err(&pdev->dev, "no memory resource found\n");
77 --- a/drivers/net/wireless/ath9k/core.h
78 +++ b/drivers/net/wireless/ath9k/core.h
79 @@ -726,6 +726,8 @@ struct ath_bus_ops {
80 void (*read_cachesize)(struct ath_softc *sc, int *csz);
81
82 void (*cleanup)(struct ath_softc *sc);
83 +
84 + bool (*eeprom_read)(struct ath_hal *ah, u32 off, u16 *data);
85 };
86
87 struct ath_softc {
88 --- a/drivers/net/wireless/ath9k/eeprom.c
89 +++ b/drivers/net/wireless/ath9k/eeprom.c
90 @@ -91,53 +91,11 @@ static inline bool ath9k_hw_get_lower_up
91 return false;
92 }
93
94 -static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
95 -{
96 - (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
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;
109 -}
110 -
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 + struct ath_softc *sc = ah->ah_sc;
142 +
143 + return sc->bus_ops->eeprom_read(ah, off, data);
144 }
145
146 static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
147 @@ -2805,9 +2763,6 @@ int ath9k_hw_eeprom_attach(struct ath_ha
148 int status;
149 struct ath_hal_5416 *ahp = AH5416(ah);
150
151 - if (ath9k_hw_use_flash(ah))
152 - ath9k_hw_flash_map(ah);
153 -
154 if (AR_SREV_9285(ah))
155 ahp->ah_eep_map = EEP_MAP_4KBITS;
156 else
157 --- a/drivers/net/wireless/ath9k/pci.c
158 +++ b/drivers/net/wireless/ath9k/pci.c
159 @@ -121,6 +121,23 @@ static void ath_pci_cleanup(struct ath_s
160 ieee80211_free_hw(sc->hw);
161 }
162
163 +static bool ath_pci_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
164 +{
165 + (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
166 +
167 + if (!ath9k_hw_wait(ah,
168 + AR_EEPROM_STATUS_DATA,
169 + AR_EEPROM_STATUS_DATA_BUSY |
170 + AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
171 + return false;
172 + }
173 +
174 + *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
175 + AR_EEPROM_STATUS_DATA_VAL);
176 +
177 + return true;
178 +}
179 +
180 static struct ath_bus_ops ath_pci_bus_ops = {
181 .dma_map_single_to_device = ath_pci_map_single_to_device,
182 .dma_unmap_single_to_device = ath_pci_unmap_single_to_device,
183 @@ -138,6 +155,8 @@ static struct ath_bus_ops ath_pci_bus_op
184 .read_cachesize = ath_pci_read_cachesize,
185
186 .cleanup = ath_pci_cleanup,
187 +
188 + .eeprom_read = ath_pci_eeprom_read,
189 };
190
191 static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
192 --- /dev/null
193 +++ b/include/linux/ath9k_platform.h
194 @@ -0,0 +1,28 @@
195 +/*
196 + * Copyright (c) 2008 Atheros Communications Inc.
197 + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
198 + * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
199 + *
200 + * Permission to use, copy, modify, and/or distribute this software for any
201 + * purpose with or without fee is hereby granted, provided that the above
202 + * copyright notice and this permission notice appear in all copies.
203 + *
204 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
205 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
206 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
207 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
208 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
209 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
210 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
211 + */
212 +
213 +#ifndef _LINUX_ATH9K_PLATFORM_H
214 +#define _LINUX_ATH9L_PLATFORM_H
215 +
216 +#define ATH9K_PLAT_EEP_MAX_WORDS 2048
217 +
218 +struct ath9k_platform_data {
219 + u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
220 +};
221 +
222 +#endif /* _LINUX_ATH9K_PLATFORM_H */