2412d8f11b9317fd3624a71b3522e55e7249491e
[openwrt.git] / package / mac80211 / patches / 407-ath9k-get-EEPROM-contents-from-platform-data-on-AHB.patch
1 From d0d8545c85b03c2e7e3c9957a94d0d6fc8168bef Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Mon, 5 Jan 2009 11:05:05 +0100
4 Subject: [PATCH 07/11] 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   |    1 +
15  drivers/net/wireless/ath9k/eeprom.c |   51 ++--------------------------------
16  drivers/net/wireless/ath9k/pci.c    |   18 ++++++++++++
17  include/linux/ath9k_platform.h      |   28 +++++++++++++++++++
18  5 files changed, 77 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 @@ -39,9 +40,29 @@ static void ath_ahb_cleanup(struct ath_s
31         ieee80211_free_hw(hw);
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         .read_cachesize = ath_ahb_read_cachesize,
54         .cleanup = ath_ahb_cleanup,
55 +
56 +       .eeprom_read = ath_ahb_eeprom_read,
57  };
58  
59  static int ath_ahb_probe(struct platform_device *pdev)
60 @@ -54,6 +75,12 @@ static int ath_ahb_probe(struct platform
61         int ret = 0;
62         struct ath_hal *ah;
63  
64 +       if (!pdev->dev.platform_data) {
65 +               dev_err(&pdev->dev, "no platform data specified\n");
66 +               ret = -EINVAL;
67 +               goto err_out;
68 +       }
69 +
70         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
71         if (res == NULL) {
72                 dev_err(&pdev->dev, "no memory resource found\n");
73 --- a/drivers/net/wireless/ath9k/core.h
74 +++ b/drivers/net/wireless/ath9k/core.h
75 @@ -696,6 +696,7 @@ enum PROT_MODE {
76  struct ath_bus_ops {
77         void            (*read_cachesize)(struct ath_softc *sc, int *csz);
78         void            (*cleanup)(struct ath_softc *sc);
79 +       bool            (*eeprom_read)(struct ath_hal *ah, u32 off, u16 *data);
80  };
81  
82  struct ath_softc {
83 --- a/drivers/net/wireless/ath9k/eeprom.c
84 +++ b/drivers/net/wireless/ath9k/eeprom.c
85 @@ -91,53 +91,11 @@ static inline bool ath9k_hw_get_lower_up
86         return false;
87  }
88  
89 -static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
90 -{
91 -       (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
92 -
93 -       if (!ath9k_hw_wait(ah,
94 -                          AR_EEPROM_STATUS_DATA,
95 -                          AR_EEPROM_STATUS_DATA_BUSY |
96 -                          AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
97 -               return false;
98 -       }
99 -
100 -       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
101 -                  AR_EEPROM_STATUS_DATA_VAL);
102 -
103 -       return true;
104 -}
105 -
106 -static int ath9k_hw_flash_map(struct ath_hal *ah)
107 -{
108 -       struct ath_hal_5416 *ahp = AH5416(ah);
109 -
110 -       ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
111 -
112 -       if (!ahp->ah_cal_mem) {
113 -               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
114 -                       "cannot remap eeprom region \n");
115 -               return -EIO;
116 -       }
117 -
118 -       return 0;
119 -}
120 -
121 -static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
122 -{
123 -       struct ath_hal_5416 *ahp = AH5416(ah);
124 -
125 -       *data = ioread16(ahp->ah_cal_mem + off);
126 -
127 -       return true;
128 -}
129 -
130  static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
131  {
132 -       if (ath9k_hw_use_flash(ah))
133 -               return ath9k_hw_flash_read(ah, off, data);
134 -       else
135 -               return ath9k_hw_eeprom_read(ah, off, data);
136 +       struct ath_softc *sc = ah->ah_sc;
137 +
138 +       return sc->bus_ops->eeprom_read(ah, off, data);
139  }
140  
141  static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
142 @@ -2825,9 +2783,6 @@ int ath9k_hw_eeprom_attach(struct ath_ha
143         int status;
144         struct ath_hal_5416 *ahp = AH5416(ah);
145  
146 -       if (ath9k_hw_use_flash(ah))
147 -               ath9k_hw_flash_map(ah);
148 -
149         if (AR_SREV_9285(ah))
150                 ahp->ah_eep_map = EEP_MAP_4KBITS;
151         else
152 --- a/drivers/net/wireless/ath9k/pci.c
153 +++ b/drivers/net/wireless/ath9k/pci.c
154 @@ -62,9 +62,27 @@ static void ath_pci_cleanup(struct ath_s
155         ieee80211_free_hw(sc->hw);
156  }
157  
158 +static bool ath_pci_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
159 +{
160 +       (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
161 +
162 +       if (!ath9k_hw_wait(ah,
163 +                          AR_EEPROM_STATUS_DATA,
164 +                          AR_EEPROM_STATUS_DATA_BUSY |
165 +                          AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
166 +               return false;
167 +       }
168 +
169 +       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
170 +                  AR_EEPROM_STATUS_DATA_VAL);
171 +
172 +       return true;
173 +}
174 +
175  static struct ath_bus_ops ath_pci_bus_ops = {
176         .read_cachesize = ath_pci_read_cachesize,
177         .cleanup = ath_pci_cleanup,
178 +       .eeprom_read = ath_pci_eeprom_read,
179  };
180  
181  static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
182 --- /dev/null
183 +++ b/include/linux/ath9k_platform.h
184 @@ -0,0 +1,28 @@
185 +/*
186 + * Copyright (c) 2008 Atheros Communications Inc.
187 + * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
188 + * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
189 + *
190 + * Permission to use, copy, modify, and/or distribute this software for any
191 + * purpose with or without fee is hereby granted, provided that the above
192 + * copyright notice and this permission notice appear in all copies.
193 + *
194 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
195 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
196 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
197 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
198 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
199 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
200 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201 + */
202 +
203 +#ifndef _LINUX_ATH9K_PLATFORM_H
204 +#define _LINUX_ATH9K_PLATFORM_H
205 +
206 +#define ATH9K_PLAT_EEP_MAX_WORDS       2048
207 +
208 +struct ath9k_platform_data {
209 +       u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
210 +};
211 +
212 +#endif /* _LINUX_ATH9K_PLATFORM_H */