Commit 9dbeb91a8b97e2892c04461e28d2bdd0198b719d
Committed by
John W. Linville
1 parent
09329d371e
Exists in
master
and in
7 other branches
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
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 */ |