diff options
author | Assaf Krauss <assaf.krauss@intel.com> | 2008-03-06 13:40:20 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-07 16:03:01 -0500 |
commit | 34cf6ff6dd42cbc61fd652f893dcf71eed6052a5 (patch) | |
tree | 8ad12f52846b359c4fe773b04305f3b5e8368723 /drivers/net/wireless/iwlwifi/iwl-eeprom.c | |
parent | df48c3235c90095a2f7dbcaba444add363ffb0ef (diff) |
iwlwifi: Moving EEPROM handling in iwlcore module
This patch move EEPROM code into iwl core module
Signed-off-by: Assaf Krauss <assaf.krauss@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-eeprom.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c new file mode 100644 index 000000000000..0064387dea91 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Tomas Winkler <tomas.winkler@intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | |||
63 | |||
64 | #include <linux/kernel.h> | ||
65 | #include <linux/module.h> | ||
66 | #include <linux/version.h> | ||
67 | #include <linux/init.h> | ||
68 | |||
69 | #include <net/mac80211.h> | ||
70 | |||
71 | #include "iwl-4965-commands.h" | ||
72 | #include "iwl-4965.h" | ||
73 | #include "iwl-core.h" | ||
74 | #include "iwl-4965-debug.h" | ||
75 | #include "iwl-eeprom.h" | ||
76 | #include "iwl-4965-io.h" | ||
77 | |||
78 | /****************************************************************************** | ||
79 | * | ||
80 | * EEPROM related functions | ||
81 | * | ||
82 | ******************************************************************************/ | ||
83 | |||
84 | int iwlcore_eeprom_verify_signature(struct iwl4965_priv *priv) | ||
85 | { | ||
86 | u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP); | ||
87 | if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { | ||
88 | IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); | ||
89 | return -ENOENT; | ||
90 | } | ||
91 | return 0; | ||
92 | } | ||
93 | EXPORT_SYMBOL(iwlcore_eeprom_verify_signature); | ||
94 | |||
95 | /* | ||
96 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
97 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
98 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
99 | * weren't arbitrated by the semaphore. | ||
100 | */ | ||
101 | int iwlcore_eeprom_acquire_semaphore(struct iwl4965_priv *priv) | ||
102 | { | ||
103 | u16 count; | ||
104 | int ret; | ||
105 | |||
106 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
107 | /* Request semaphore */ | ||
108 | iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
109 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
110 | |||
111 | /* See if we got it */ | ||
112 | ret = iwl4965_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
113 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
114 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
115 | EEPROM_SEM_TIMEOUT); | ||
116 | if (ret >= 0) { | ||
117 | IWL_DEBUG_IO("Acquired semaphore after %d tries.\n", | ||
118 | count+1); | ||
119 | return ret; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | return ret; | ||
124 | } | ||
125 | EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore); | ||
126 | |||
127 | void iwlcore_eeprom_release_semaphore(struct iwl4965_priv *priv) | ||
128 | { | ||
129 | iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
130 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
131 | |||
132 | } | ||
133 | EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore); | ||
134 | |||
135 | |||
136 | /** | ||
137 | * iwl_eeprom_init - read EEPROM contents | ||
138 | * | ||
139 | * Load the EEPROM contents from adapter into priv->eeprom | ||
140 | * | ||
141 | * NOTE: This routine uses the non-debug IO access functions. | ||
142 | */ | ||
143 | int iwl_eeprom_init(struct iwl4965_priv *priv) | ||
144 | { | ||
145 | u16 *e = (u16 *)&priv->eeprom; | ||
146 | u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP); | ||
147 | u32 r; | ||
148 | int sz = sizeof(priv->eeprom); | ||
149 | int ret; | ||
150 | int i; | ||
151 | u16 addr; | ||
152 | |||
153 | /* The EEPROM structure has several padding buffers within it | ||
154 | * and when adding new EEPROM maps is subject to programmer errors | ||
155 | * which may be very difficult to identify without explicitly | ||
156 | * checking the resulting size of the eeprom map. */ | ||
157 | BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE); | ||
158 | |||
159 | if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { | ||
160 | IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); | ||
161 | return -ENOENT; | ||
162 | } | ||
163 | |||
164 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
165 | ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); | ||
166 | if (ret < 0) { | ||
167 | IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); | ||
168 | return -ENOENT; | ||
169 | } | ||
170 | |||
171 | /* eeprom is an array of 16bit values */ | ||
172 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | ||
173 | _iwl4965_write32(priv, CSR_EEPROM_REG, addr << 1); | ||
174 | _iwl4965_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD); | ||
175 | |||
176 | for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT; | ||
177 | i += IWL_EEPROM_ACCESS_DELAY) { | ||
178 | r = _iwl4965_read_direct32(priv, CSR_EEPROM_REG); | ||
179 | if (r & CSR_EEPROM_REG_READ_VALID_MSK) | ||
180 | break; | ||
181 | udelay(IWL_EEPROM_ACCESS_DELAY); | ||
182 | } | ||
183 | |||
184 | if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) { | ||
185 | IWL_ERROR("Time out reading EEPROM[%d]", addr); | ||
186 | ret = -ETIMEDOUT; | ||
187 | goto done; | ||
188 | } | ||
189 | e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); | ||
190 | } | ||
191 | ret = 0; | ||
192 | |||
193 | done: | ||
194 | priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); | ||
195 | return ret; | ||
196 | } | ||
197 | EXPORT_SYMBOL(iwl_eeprom_init); | ||
198 | |||
199 | |||
200 | void iwl_eeprom_get_mac(const struct iwl4965_priv *priv, u8 *mac) | ||
201 | { | ||
202 | memcpy(mac, priv->eeprom.mac_address, 6); | ||
203 | } | ||
204 | EXPORT_SYMBOL(iwl_eeprom_get_mac); | ||
205 | |||