Fixes missed beacon logic in relation to on-network AP roaming.
[deliverable/linux.git] / drivers / net / wireless / ipw2200.c
CommitLineData
43f66a6c 1/******************************************************************************
bf79451e 2
afbf30a2 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
43f66a6c
JK
4
5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB
7 Ethereal - Network traffic analyzer
8 By Gerald Combs <gerald@ethereal.com>
9 Copyright 1998 Gerald Combs
10
bf79451e
JG
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
43f66a6c 13 published by the Free Software Foundation.
bf79451e
JG
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
43f66a6c 18 more details.
bf79451e 19
43f66a6c 20 You should have received a copy of the GNU General Public License along with
bf79451e 21 this program; if not, write to the Free Software Foundation, Inc., 59
43f66a6c 22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
bf79451e 23
43f66a6c
JK
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
bf79451e 26
43f66a6c
JK
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32
33#include "ipw2200.h"
34
9ef539d0 35#define IPW2200_VERSION "1.0.7"
43f66a6c 36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
2b184d5b 37#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
43f66a6c
JK
38#define DRV_VERSION IPW2200_VERSION
39
b095c381
JK
40#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
41
43f66a6c
JK
42MODULE_DESCRIPTION(DRV_DESCRIPTION);
43MODULE_VERSION(DRV_VERSION);
44MODULE_AUTHOR(DRV_COPYRIGHT);
45MODULE_LICENSE("GPL");
46
f6c5cb7c 47static int cmdlog = 0;
43f66a6c
JK
48static int debug = 0;
49static int channel = 0;
43f66a6c
JK
50static int mode = 0;
51
52static u32 ipw_debug_level;
53static int associate = 1;
54static int auto_create = 1;
a613bffd 55static int led = 0;
43f66a6c 56static int disable = 0;
b095c381 57static int hwcrypto = 1;
43f66a6c
JK
58static const char ipw_modes[] = {
59 'a', 'b', 'g', '?'
60};
61
b095c381
JK
62#ifdef CONFIG_IPW_QOS
63static int qos_enable = 0;
64static int qos_burst_enable = 0;
65static int qos_no_ack_mask = 0;
66static int burst_duration_CCK = 0;
67static int burst_duration_OFDM = 0;
68
69static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
70 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
71 QOS_TX3_CW_MIN_OFDM},
72 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
73 QOS_TX3_CW_MAX_OFDM},
74 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
75 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
76 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
77 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
78};
79
80static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
81 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
82 QOS_TX3_CW_MIN_CCK},
83 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
84 QOS_TX3_CW_MAX_CCK},
85 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
86 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
87 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
88 QOS_TX3_TXOP_LIMIT_CCK}
89};
90
91static struct ieee80211_qos_parameters def_parameters_OFDM = {
92 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
93 DEF_TX3_CW_MIN_OFDM},
94 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
95 DEF_TX3_CW_MAX_OFDM},
96 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
97 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
98 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
99 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
100};
101
102static struct ieee80211_qos_parameters def_parameters_CCK = {
103 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
104 DEF_TX3_CW_MIN_CCK},
105 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
106 DEF_TX3_CW_MAX_CCK},
107 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
108 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
109 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
110 DEF_TX3_TXOP_LIMIT_CCK}
111};
112
113static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
114
115static int from_priority_to_tx_queue[] = {
116 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
117 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
118};
119
120static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
121
122static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
123 *qos_param);
124static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
125 *qos_param);
126#endif /* CONFIG_IPW_QOS */
127
97a78ca9 128static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
b095c381 129static void ipw_remove_current_network(struct ipw_priv *priv);
43f66a6c 130static void ipw_rx(struct ipw_priv *priv);
bf79451e 131static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
132 struct clx2_tx_queue *txq, int qindex);
133static int ipw_queue_reset(struct ipw_priv *priv);
134
135static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
136 int len, int sync);
137
138static void ipw_tx_queue_free(struct ipw_priv *);
139
140static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
141static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
142static void ipw_rx_queue_replenish(void *);
43f66a6c 143static int ipw_up(struct ipw_priv *);
c848d0af 144static void ipw_bg_up(void *);
43f66a6c 145static void ipw_down(struct ipw_priv *);
c848d0af 146static void ipw_bg_down(void *);
43f66a6c 147static int ipw_config(struct ipw_priv *);
0edd5b44
JG
148static int init_supported_rates(struct ipw_priv *priv,
149 struct ipw_supported_rates *prates);
b095c381
JK
150static void ipw_set_hwcrypto_keys(struct ipw_priv *);
151static void ipw_send_wep_keys(struct ipw_priv *, int);
43f66a6c 152
1fe0adb4
LH
153static int ipw_is_valid_channel(struct ieee80211_device *, u8);
154static int ipw_channel_to_index(struct ieee80211_device *, u8);
155static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
156static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
157static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
158
f6c5cb7c
JK
159static int snprint_line(char *buf, size_t count,
160 const u8 * data, u32 len, u32 ofs)
43f66a6c
JK
161{
162 int out, i, j, l;
163 char c;
bf79451e 164
43f66a6c
JK
165 out = snprintf(buf, count, "%08X", ofs);
166
167 for (l = 0, i = 0; i < 2; i++) {
168 out += snprintf(buf + out, count - out, " ");
bf79451e
JG
169 for (j = 0; j < 8 && l < len; j++, l++)
170 out += snprintf(buf + out, count - out, "%02X ",
43f66a6c
JK
171 data[(i * 8 + j)]);
172 for (; j < 8; j++)
173 out += snprintf(buf + out, count - out, " ");
174 }
bf79451e 175
43f66a6c
JK
176 out += snprintf(buf + out, count - out, " ");
177 for (l = 0, i = 0; i < 2; i++) {
178 out += snprintf(buf + out, count - out, " ");
179 for (j = 0; j < 8 && l < len; j++, l++) {
180 c = data[(i * 8 + j)];
181 if (!isascii(c) || !isprint(c))
182 c = '.';
bf79451e 183
43f66a6c
JK
184 out += snprintf(buf + out, count - out, "%c", c);
185 }
186
187 for (; j < 8; j++)
188 out += snprintf(buf + out, count - out, " ");
189 }
bf79451e 190
f6c5cb7c 191 return out;
43f66a6c
JK
192}
193
0edd5b44 194static void printk_buf(int level, const u8 * data, u32 len)
43f66a6c
JK
195{
196 char line[81];
197 u32 ofs = 0;
198 if (!(ipw_debug_level & level))
199 return;
200
201 while (len) {
f6c5cb7c
JK
202 snprint_line(line, sizeof(line), &data[ofs],
203 min(len, 16U), ofs);
204 printk(KERN_DEBUG "%s\n", line);
43f66a6c
JK
205 ofs += 16;
206 len -= min(len, 16U);
207 }
208}
209
f6c5cb7c
JK
210static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
211{
212 size_t out = size;
213 u32 ofs = 0;
214 int total = 0;
215
216 while (size && len) {
217 out = snprint_line(output, size, &data[ofs],
218 min_t(size_t, len, 16U), ofs);
219
220 ofs += 16;
221 output += out;
222 size -= out;
223 len -= min_t(size_t, len, 16U);
224 total += out;
225 }
226 return total;
227}
228
43f66a6c
JK
229static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
230#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
231
232static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
233#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
234
235static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
236static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
237{
0edd5b44
JG
238 IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__,
239 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
240 _ipw_write_reg8(a, b, c);
241}
242
243static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
244static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
245{
0edd5b44
JG
246 IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__,
247 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
248 _ipw_write_reg16(a, b, c);
249}
250
251static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
252static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
253{
0edd5b44
JG
254 IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__,
255 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
256 _ipw_write_reg32(a, b, c);
257}
258
259#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
260#define ipw_write8(ipw, ofs, val) \
261 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
262 _ipw_write8(ipw, ofs, val)
263
264#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
265#define ipw_write16(ipw, ofs, val) \
266 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
267 _ipw_write16(ipw, ofs, val)
268
269#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
270#define ipw_write32(ipw, ofs, val) \
271 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
272 _ipw_write32(ipw, ofs, val)
273
274#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
0edd5b44
JG
275static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
276{
277 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
278 return _ipw_read8(ipw, ofs);
279}
0edd5b44 280
43f66a6c
JK
281#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
282
283#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
0edd5b44
JG
284static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
285{
286 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
287 return _ipw_read16(ipw, ofs);
288}
0edd5b44 289
43f66a6c
JK
290#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
291
292#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
0edd5b44
JG
293static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
294{
295 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
296 return _ipw_read32(ipw, ofs);
297}
0edd5b44 298
43f66a6c
JK
299#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
300
301static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
f6c5cb7c
JK
302static inline void __ipw_read_indirect(const char *f, int l,
303 struct ipw_priv *a, u32 b, u8 * c, int d)
304{
305 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
306 d);
307 _ipw_read_indirect(a, b, c, d);
308}
309
310#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
43f66a6c 311
0edd5b44
JG
312static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
313 int num);
43f66a6c
JK
314#define ipw_write_indirect(a, b, c, d) \
315 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
afbf30a2 316 _ipw_write_indirect(a, b, c, d)
43f66a6c
JK
317
318/* indirect write s */
0edd5b44 319static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
43f66a6c 320{
0edd5b44 321 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
b095c381
JK
322 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
323 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
43f66a6c
JK
324}
325
43f66a6c
JK
326static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
327{
328 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
b095c381
JK
329 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
330 _ipw_write8(priv, IPW_INDIRECT_DATA, value);
43f66a6c
JK
331}
332
0edd5b44 333static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
43f66a6c
JK
334{
335 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
b095c381
JK
336 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
337 _ipw_write16(priv, IPW_INDIRECT_DATA, value);
43f66a6c
JK
338}
339
340/* indirect read s */
341
342static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
343{
344 u32 word;
b095c381 345 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
43f66a6c 346 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
b095c381 347 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
0edd5b44 348 return (word >> ((reg & 0x3) * 8)) & 0xff;
43f66a6c
JK
349}
350
351static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
352{
353 u32 value;
354
355 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
356
b095c381
JK
357 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
358 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
43f66a6c
JK
359 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
360 return value;
361}
362
363/* iterative/auto-increment 32 bit reads and writes */
364static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
365 int num)
366{
b095c381 367 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
43f66a6c 368 u32 dif_len = addr - aligned_addr;
43f66a6c 369 u32 i;
bf79451e 370
43f66a6c
JK
371 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
372
ea2b26e0
JK
373 if (num <= 0) {
374 return;
375 }
376
43f66a6c
JK
377 /* Read the first nibble byte by byte */
378 if (unlikely(dif_len)) {
b095c381 379 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0
JK
380 /* Start reading at aligned_addr + dif_len */
381 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
b095c381 382 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
43f66a6c
JK
383 aligned_addr += 4;
384 }
385
b095c381 386 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
ea2b26e0 387 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
b095c381 388 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
bf79451e 389
43f66a6c 390 /* Copy the last nibble */
ea2b26e0 391 if (unlikely(num)) {
b095c381 392 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0 393 for (i = 0; num > 0; i++, num--)
b095c381 394 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
ea2b26e0 395 }
43f66a6c
JK
396}
397
0edd5b44 398static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
43f66a6c
JK
399 int num)
400{
b095c381 401 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
43f66a6c 402 u32 dif_len = addr - aligned_addr;
43f66a6c 403 u32 i;
bf79451e 404
43f66a6c 405 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
bf79451e 406
ea2b26e0
JK
407 if (num <= 0) {
408 return;
409 }
410
43f66a6c
JK
411 /* Write the first nibble byte by byte */
412 if (unlikely(dif_len)) {
b095c381 413 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0
JK
414 /* Start reading at aligned_addr + dif_len */
415 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
b095c381 416 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
43f66a6c
JK
417 aligned_addr += 4;
418 }
bf79451e 419
b095c381 420 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
ea2b26e0 421 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
b095c381 422 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
bf79451e 423
43f66a6c 424 /* Copy the last nibble */
ea2b26e0 425 if (unlikely(num)) {
b095c381 426 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0 427 for (i = 0; num > 0; i++, num--, buf++)
b095c381 428 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
ea2b26e0 429 }
43f66a6c
JK
430}
431
bf79451e 432static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
43f66a6c
JK
433 int num)
434{
435 memcpy_toio((priv->hw_base + addr), buf, num);
436}
437
438static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
439{
440 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
441}
442
443static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
444{
445 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
446}
447
448static inline void ipw_enable_interrupts(struct ipw_priv *priv)
449{
450 if (priv->status & STATUS_INT_ENABLED)
451 return;
452 priv->status |= STATUS_INT_ENABLED;
b095c381 453 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
43f66a6c
JK
454}
455
456static inline void ipw_disable_interrupts(struct ipw_priv *priv)
457{
458 if (!(priv->status & STATUS_INT_ENABLED))
459 return;
460 priv->status &= ~STATUS_INT_ENABLED;
b095c381 461 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
43f66a6c
JK
462}
463
b39860c6 464#ifdef CONFIG_IPW_DEBUG
43f66a6c
JK
465static char *ipw_error_desc(u32 val)
466{
467 switch (val) {
bf79451e 468 case IPW_FW_ERROR_OK:
43f66a6c 469 return "ERROR_OK";
bf79451e 470 case IPW_FW_ERROR_FAIL:
43f66a6c 471 return "ERROR_FAIL";
bf79451e 472 case IPW_FW_ERROR_MEMORY_UNDERFLOW:
43f66a6c 473 return "MEMORY_UNDERFLOW";
bf79451e 474 case IPW_FW_ERROR_MEMORY_OVERFLOW:
43f66a6c 475 return "MEMORY_OVERFLOW";
bf79451e 476 case IPW_FW_ERROR_BAD_PARAM:
b095c381 477 return "BAD_PARAM";
bf79451e 478 case IPW_FW_ERROR_BAD_CHECKSUM:
b095c381 479 return "BAD_CHECKSUM";
bf79451e 480 case IPW_FW_ERROR_NMI_INTERRUPT:
b095c381 481 return "NMI_INTERRUPT";
bf79451e 482 case IPW_FW_ERROR_BAD_DATABASE:
b095c381 483 return "BAD_DATABASE";
bf79451e 484 case IPW_FW_ERROR_ALLOC_FAIL:
b095c381 485 return "ALLOC_FAIL";
bf79451e 486 case IPW_FW_ERROR_DMA_UNDERRUN:
b095c381 487 return "DMA_UNDERRUN";
bf79451e 488 case IPW_FW_ERROR_DMA_STATUS:
b095c381
JK
489 return "DMA_STATUS";
490 case IPW_FW_ERROR_DINO_ERROR:
491 return "DINO_ERROR";
492 case IPW_FW_ERROR_EEPROM_ERROR:
493 return "EEPROM_ERROR";
bf79451e 494 case IPW_FW_ERROR_SYSASSERT:
b095c381 495 return "SYSASSERT";
bf79451e 496 case IPW_FW_ERROR_FATAL_ERROR:
b095c381 497 return "FATAL_ERROR";
bf79451e 498 default:
b095c381 499 return "UNKNOWN_ERROR";
43f66a6c
JK
500 }
501}
502
b39860c6
JK
503static void ipw_dump_error_log(struct ipw_priv *priv,
504 struct ipw_fw_error *error)
43f66a6c 505{
b39860c6 506 u32 i;
bf79451e 507
b39860c6
JK
508 if (!error) {
509 IPW_ERROR("Error allocating and capturing error log. "
510 "Nothing to dump.\n");
511 return;
43f66a6c
JK
512 }
513
b39860c6
JK
514 IPW_ERROR("Start IPW Error Log Dump:\n");
515 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
516 error->status, error->config);
43f66a6c 517
b39860c6 518 for (i = 0; i < error->elem_len; i++)
0edd5b44 519 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
b39860c6
JK
520 ipw_error_desc(error->elem[i].desc),
521 error->elem[i].time,
522 error->elem[i].blink1,
523 error->elem[i].blink2,
524 error->elem[i].link1,
525 error->elem[i].link2, error->elem[i].data);
526 for (i = 0; i < error->log_len; i++)
527 IPW_ERROR("%i\t0x%08x\t%i\n",
528 error->log[i].time,
529 error->log[i].event, error->log[i].data);
43f66a6c 530}
43f66a6c 531#endif
43f66a6c 532
c848d0af
JK
533static inline int ipw_is_init(struct ipw_priv *priv)
534{
535 return (priv->status & STATUS_INIT) ? 1 : 0;
536}
537
0edd5b44 538static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
43f66a6c
JK
539{
540 u32 addr, field_info, field_len, field_count, total_len;
541
542 IPW_DEBUG_ORD("ordinal = %i\n", ord);
543
544 if (!priv || !val || !len) {
545 IPW_DEBUG_ORD("Invalid argument\n");
546 return -EINVAL;
547 }
bf79451e 548
43f66a6c
JK
549 /* verify device ordinal tables have been initialized */
550 if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {
551 IPW_DEBUG_ORD("Access ordinals before initialization\n");
552 return -EINVAL;
553 }
554
555 switch (IPW_ORD_TABLE_ID_MASK & ord) {
556 case IPW_ORD_TABLE_0_MASK:
557 /*
558 * TABLE 0: Direct access to a table of 32 bit values
559 *
bf79451e 560 * This is a very simple table with the data directly
43f66a6c
JK
561 * read from the table
562 */
563
564 /* remove the table id from the ordinal */
565 ord &= IPW_ORD_TABLE_VALUE_MASK;
566
567 /* boundary check */
568 if (ord > priv->table0_len) {
569 IPW_DEBUG_ORD("ordinal value (%i) longer then "
570 "max (%i)\n", ord, priv->table0_len);
571 return -EINVAL;
572 }
573
574 /* verify we have enough room to store the value */
575 if (*len < sizeof(u32)) {
576 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 577 "need %zd\n", sizeof(u32));
43f66a6c
JK
578 return -EINVAL;
579 }
580
581 IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",
0edd5b44 582 ord, priv->table0_addr + (ord << 2));
43f66a6c
JK
583
584 *len = sizeof(u32);
585 ord <<= 2;
0edd5b44 586 *((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord);
43f66a6c
JK
587 break;
588
589 case IPW_ORD_TABLE_1_MASK:
590 /*
591 * TABLE 1: Indirect access to a table of 32 bit values
bf79451e
JG
592 *
593 * This is a fairly large table of u32 values each
43f66a6c
JK
594 * representing starting addr for the data (which is
595 * also a u32)
596 */
597
598 /* remove the table id from the ordinal */
599 ord &= IPW_ORD_TABLE_VALUE_MASK;
bf79451e 600
43f66a6c
JK
601 /* boundary check */
602 if (ord > priv->table1_len) {
603 IPW_DEBUG_ORD("ordinal value too long\n");
604 return -EINVAL;
605 }
606
607 /* verify we have enough room to store the value */
608 if (*len < sizeof(u32)) {
609 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 610 "need %zd\n", sizeof(u32));
43f66a6c
JK
611 return -EINVAL;
612 }
613
0edd5b44
JG
614 *((u32 *) val) =
615 ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));
43f66a6c
JK
616 *len = sizeof(u32);
617 break;
618
619 case IPW_ORD_TABLE_2_MASK:
620 /*
621 * TABLE 2: Indirect access to a table of variable sized values
622 *
623 * This table consist of six values, each containing
624 * - dword containing the starting offset of the data
625 * - dword containing the lengh in the first 16bits
626 * and the count in the second 16bits
627 */
628
629 /* remove the table id from the ordinal */
630 ord &= IPW_ORD_TABLE_VALUE_MASK;
631
632 /* boundary check */
633 if (ord > priv->table2_len) {
634 IPW_DEBUG_ORD("ordinal value too long\n");
635 return -EINVAL;
636 }
637
638 /* get the address of statistic */
639 addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));
bf79451e
JG
640
641 /* get the second DW of statistics ;
43f66a6c 642 * two 16-bit words - first is length, second is count */
0edd5b44
JG
643 field_info =
644 ipw_read_reg32(priv,
645 priv->table2_addr + (ord << 3) +
646 sizeof(u32));
bf79451e 647
43f66a6c 648 /* get each entry length */
0edd5b44 649 field_len = *((u16 *) & field_info);
bf79451e 650
43f66a6c 651 /* get number of entries */
0edd5b44 652 field_count = *(((u16 *) & field_info) + 1);
bf79451e 653
43f66a6c
JK
654 /* abort if not enought memory */
655 total_len = field_len * field_count;
656 if (total_len > *len) {
657 *len = total_len;
658 return -EINVAL;
659 }
bf79451e 660
43f66a6c
JK
661 *len = total_len;
662 if (!total_len)
663 return 0;
664
665 IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "
bf79451e 666 "field_info = 0x%08x\n",
43f66a6c
JK
667 addr, total_len, field_info);
668 ipw_read_indirect(priv, addr, val, total_len);
669 break;
670
671 default:
672 IPW_DEBUG_ORD("Invalid ordinal!\n");
673 return -EINVAL;
674
675 }
676
43f66a6c
JK
677 return 0;
678}
679
680static void ipw_init_ordinals(struct ipw_priv *priv)
681{
682 priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;
bf79451e 683 priv->table0_len = ipw_read32(priv, priv->table0_addr);
43f66a6c
JK
684
685 IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",
686 priv->table0_addr, priv->table0_len);
687
688 priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);
689 priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);
690
691 IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",
692 priv->table1_addr, priv->table1_len);
693
694 priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);
695 priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);
0edd5b44 696 priv->table2_len &= 0x0000ffff; /* use first two bytes */
43f66a6c
JK
697
698 IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",
699 priv->table2_addr, priv->table2_len);
700
701}
702
a613bffd
JK
703u32 ipw_register_toggle(u32 reg)
704{
b095c381
JK
705 reg &= ~IPW_START_STANDBY;
706 if (reg & IPW_GATE_ODMA)
707 reg &= ~IPW_GATE_ODMA;
708 if (reg & IPW_GATE_IDMA)
709 reg &= ~IPW_GATE_IDMA;
710 if (reg & IPW_GATE_ADMA)
711 reg &= ~IPW_GATE_ADMA;
a613bffd
JK
712 return reg;
713}
714
715/*
716 * LED behavior:
717 * - On radio ON, turn on any LEDs that require to be on during start
718 * - On initialization, start unassociated blink
719 * - On association, disable unassociated blink
720 * - On disassociation, start unassociated blink
721 * - On radio OFF, turn off any LEDs started during radio on
722 *
723 */
724#define LD_TIME_LINK_ON 300
725#define LD_TIME_LINK_OFF 2700
726#define LD_TIME_ACT_ON 250
727
728void ipw_led_link_on(struct ipw_priv *priv)
729{
730 unsigned long flags;
731 u32 led;
732
733 /* If configured to not use LEDs, or nic_type is 1,
734 * then we don't toggle a LINK led */
735 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
736 return;
737
738 spin_lock_irqsave(&priv->lock, flags);
739
740 if (!(priv->status & STATUS_RF_KILL_MASK) &&
741 !(priv->status & STATUS_LED_LINK_ON)) {
742 IPW_DEBUG_LED("Link LED On\n");
b095c381 743 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
744 led |= priv->led_association_on;
745
746 led = ipw_register_toggle(led);
747
748 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 749 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
750
751 priv->status |= STATUS_LED_LINK_ON;
752
753 /* If we aren't associated, schedule turning the LED off */
754 if (!(priv->status & STATUS_ASSOCIATED))
755 queue_delayed_work(priv->workqueue,
756 &priv->led_link_off,
757 LD_TIME_LINK_ON);
758 }
759
760 spin_unlock_irqrestore(&priv->lock, flags);
761}
762
c848d0af
JK
763static void ipw_bg_led_link_on(void *data)
764{
765 struct ipw_priv *priv = data;
766 down(&priv->sem);
767 ipw_led_link_on(data);
768 up(&priv->sem);
769}
770
a613bffd
JK
771void ipw_led_link_off(struct ipw_priv *priv)
772{
773 unsigned long flags;
774 u32 led;
775
776 /* If configured not to use LEDs, or nic type is 1,
777 * then we don't goggle the LINK led. */
778 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
779 return;
780
781 spin_lock_irqsave(&priv->lock, flags);
782
783 if (priv->status & STATUS_LED_LINK_ON) {
b095c381 784 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
785 led &= priv->led_association_off;
786 led = ipw_register_toggle(led);
787
788 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 789 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
790
791 IPW_DEBUG_LED("Link LED Off\n");
792
793 priv->status &= ~STATUS_LED_LINK_ON;
794
795 /* If we aren't associated and the radio is on, schedule
796 * turning the LED on (blink while unassociated) */
797 if (!(priv->status & STATUS_RF_KILL_MASK) &&
798 !(priv->status & STATUS_ASSOCIATED))
799 queue_delayed_work(priv->workqueue, &priv->led_link_on,
800 LD_TIME_LINK_OFF);
801
802 }
803
804 spin_unlock_irqrestore(&priv->lock, flags);
805}
806
c848d0af
JK
807static void ipw_bg_led_link_off(void *data)
808{
809 struct ipw_priv *priv = data;
810 down(&priv->sem);
811 ipw_led_link_off(data);
812 up(&priv->sem);
813}
814
b095c381 815static inline void __ipw_led_activity_on(struct ipw_priv *priv)
a613bffd 816{
a613bffd
JK
817 u32 led;
818
819 if (priv->config & CFG_NO_LED)
820 return;
821
b095c381 822 if (priv->status & STATUS_RF_KILL_MASK)
a613bffd 823 return;
a613bffd
JK
824
825 if (!(priv->status & STATUS_LED_ACT_ON)) {
b095c381 826 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
827 led |= priv->led_activity_on;
828
829 led = ipw_register_toggle(led);
830
831 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 832 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
833
834 IPW_DEBUG_LED("Activity LED On\n");
835
836 priv->status |= STATUS_LED_ACT_ON;
837
c848d0af 838 cancel_delayed_work(&priv->led_act_off);
a613bffd
JK
839 queue_delayed_work(priv->workqueue, &priv->led_act_off,
840 LD_TIME_ACT_ON);
841 } else {
842 /* Reschedule LED off for full time period */
843 cancel_delayed_work(&priv->led_act_off);
844 queue_delayed_work(priv->workqueue, &priv->led_act_off,
845 LD_TIME_ACT_ON);
846 }
b095c381 847}
a613bffd 848
b095c381
JK
849void ipw_led_activity_on(struct ipw_priv *priv)
850{
851 unsigned long flags;
852 spin_lock_irqsave(&priv->lock, flags);
853 __ipw_led_activity_on(priv);
a613bffd
JK
854 spin_unlock_irqrestore(&priv->lock, flags);
855}
856
857void ipw_led_activity_off(struct ipw_priv *priv)
858{
859 unsigned long flags;
860 u32 led;
861
862 if (priv->config & CFG_NO_LED)
863 return;
864
865 spin_lock_irqsave(&priv->lock, flags);
866
867 if (priv->status & STATUS_LED_ACT_ON) {
b095c381 868 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
869 led &= priv->led_activity_off;
870
871 led = ipw_register_toggle(led);
872
873 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 874 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
875
876 IPW_DEBUG_LED("Activity LED Off\n");
877
878 priv->status &= ~STATUS_LED_ACT_ON;
879 }
880
881 spin_unlock_irqrestore(&priv->lock, flags);
882}
883
c848d0af
JK
884static void ipw_bg_led_activity_off(void *data)
885{
886 struct ipw_priv *priv = data;
887 down(&priv->sem);
888 ipw_led_activity_off(data);
889 up(&priv->sem);
890}
891
a613bffd
JK
892void ipw_led_band_on(struct ipw_priv *priv)
893{
894 unsigned long flags;
895 u32 led;
896
897 /* Only nic type 1 supports mode LEDs */
c848d0af
JK
898 if (priv->config & CFG_NO_LED ||
899 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
a613bffd
JK
900 return;
901
902 spin_lock_irqsave(&priv->lock, flags);
903
b095c381 904 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
905 if (priv->assoc_network->mode == IEEE_A) {
906 led |= priv->led_ofdm_on;
907 led &= priv->led_association_off;
908 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
909 } else if (priv->assoc_network->mode == IEEE_G) {
910 led |= priv->led_ofdm_on;
911 led |= priv->led_association_on;
912 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
913 } else {
914 led &= priv->led_ofdm_off;
915 led |= priv->led_association_on;
916 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
917 }
918
919 led = ipw_register_toggle(led);
920
921 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 922 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
923
924 spin_unlock_irqrestore(&priv->lock, flags);
925}
926
927void ipw_led_band_off(struct ipw_priv *priv)
928{
929 unsigned long flags;
930 u32 led;
931
932 /* Only nic type 1 supports mode LEDs */
933 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
934 return;
935
936 spin_lock_irqsave(&priv->lock, flags);
937
b095c381 938 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
939 led &= priv->led_ofdm_off;
940 led &= priv->led_association_off;
941
942 led = ipw_register_toggle(led);
943
944 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 945 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
946
947 spin_unlock_irqrestore(&priv->lock, flags);
948}
949
950void ipw_led_radio_on(struct ipw_priv *priv)
951{
952 ipw_led_link_on(priv);
953}
954
955void ipw_led_radio_off(struct ipw_priv *priv)
956{
957 ipw_led_activity_off(priv);
958 ipw_led_link_off(priv);
959}
960
961void ipw_led_link_up(struct ipw_priv *priv)
962{
963 /* Set the Link Led on for all nic types */
964 ipw_led_link_on(priv);
965}
966
967void ipw_led_link_down(struct ipw_priv *priv)
968{
969 ipw_led_activity_off(priv);
970 ipw_led_link_off(priv);
971
972 if (priv->status & STATUS_RF_KILL_MASK)
973 ipw_led_radio_off(priv);
974}
975
976void ipw_led_init(struct ipw_priv *priv)
977{
978 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
979
980 /* Set the default PINs for the link and activity leds */
b095c381
JK
981 priv->led_activity_on = IPW_ACTIVITY_LED;
982 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
a613bffd 983
b095c381
JK
984 priv->led_association_on = IPW_ASSOCIATED_LED;
985 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
a613bffd
JK
986
987 /* Set the default PINs for the OFDM leds */
b095c381
JK
988 priv->led_ofdm_on = IPW_OFDM_LED;
989 priv->led_ofdm_off = ~(IPW_OFDM_LED);
a613bffd
JK
990
991 switch (priv->nic_type) {
992 case EEPROM_NIC_TYPE_1:
993 /* In this NIC type, the LEDs are reversed.... */
b095c381
JK
994 priv->led_activity_on = IPW_ASSOCIATED_LED;
995 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
996 priv->led_association_on = IPW_ACTIVITY_LED;
997 priv->led_association_off = ~(IPW_ACTIVITY_LED);
a613bffd
JK
998
999 if (!(priv->config & CFG_NO_LED))
1000 ipw_led_band_on(priv);
1001
1002 /* And we don't blink link LEDs for this nic, so
1003 * just return here */
1004 return;
1005
1006 case EEPROM_NIC_TYPE_3:
1007 case EEPROM_NIC_TYPE_2:
1008 case EEPROM_NIC_TYPE_4:
1009 case EEPROM_NIC_TYPE_0:
1010 break;
1011
1012 default:
1013 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1014 priv->nic_type);
1015 priv->nic_type = EEPROM_NIC_TYPE_0;
1016 break;
1017 }
1018
1019 if (!(priv->config & CFG_NO_LED)) {
1020 if (priv->status & STATUS_ASSOCIATED)
1021 ipw_led_link_on(priv);
1022 else
1023 ipw_led_link_off(priv);
1024 }
1025}
1026
1027void ipw_led_shutdown(struct ipw_priv *priv)
1028{
a613bffd
JK
1029 ipw_led_activity_off(priv);
1030 ipw_led_link_off(priv);
1031 ipw_led_band_off(priv);
afbf30a2
JK
1032 cancel_delayed_work(&priv->led_link_on);
1033 cancel_delayed_work(&priv->led_link_off);
1034 cancel_delayed_work(&priv->led_act_off);
a613bffd
JK
1035}
1036
43f66a6c
JK
1037/*
1038 * The following adds a new attribute to the sysfs representation
1039 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
1040 * used for controling the debug level.
bf79451e 1041 *
43f66a6c
JK
1042 * See the level definitions in ipw for details.
1043 */
1044static ssize_t show_debug_level(struct device_driver *d, char *buf)
1045{
1046 return sprintf(buf, "0x%08X\n", ipw_debug_level);
1047}
a613bffd
JK
1048
1049static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1050 size_t count)
43f66a6c
JK
1051{
1052 char *p = (char *)buf;
1053 u32 val;
1054
1055 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1056 p++;
1057 if (p[0] == 'x' || p[0] == 'X')
1058 p++;
1059 val = simple_strtoul(p, &p, 16);
1060 } else
1061 val = simple_strtoul(p, &p, 10);
bf79451e
JG
1062 if (p == buf)
1063 printk(KERN_INFO DRV_NAME
43f66a6c
JK
1064 ": %s is not in hex or decimal form.\n", buf);
1065 else
1066 ipw_debug_level = val;
1067
1068 return strnlen(buf, count);
1069}
1070
bf79451e 1071static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
43f66a6c
JK
1072 show_debug_level, store_debug_level);
1073
b39860c6
JK
1074static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
1075{
1076 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
1077}
1078
1079static void ipw_capture_event_log(struct ipw_priv *priv,
1080 u32 log_len, struct ipw_event *log)
1081{
1082 u32 base;
1083
1084 if (log_len) {
1085 base = ipw_read32(priv, IPW_EVENT_LOG);
1086 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
1087 (u8 *) log, sizeof(*log) * log_len);
1088 }
1089}
1090
1091static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
1092{
1093 struct ipw_fw_error *error;
1094 u32 log_len = ipw_get_event_log_len(priv);
1095 u32 base = ipw_read32(priv, IPW_ERROR_LOG);
1096 u32 elem_len = ipw_read_reg32(priv, base);
1097
1098 error = kmalloc(sizeof(*error) +
1099 sizeof(*error->elem) * elem_len +
1100 sizeof(*error->log) * log_len, GFP_ATOMIC);
1101 if (!error) {
1102 IPW_ERROR("Memory allocation for firmware error log "
1103 "failed.\n");
1104 return NULL;
1105 }
f6c5cb7c 1106 error->jiffies = jiffies;
b39860c6
JK
1107 error->status = priv->status;
1108 error->config = priv->config;
1109 error->elem_len = elem_len;
1110 error->log_len = log_len;
1111 error->elem = (struct ipw_error_elem *)error->payload;
1112 error->log = (struct ipw_event *)(error->elem +
1113 (sizeof(*error->elem) * elem_len));
1114
1115 ipw_capture_event_log(priv, log_len, error->log);
1116
1117 if (elem_len)
1118 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
1119 sizeof(*error->elem) * elem_len);
1120
1121 return error;
1122}
1123
1124static void ipw_free_error_log(struct ipw_fw_error *error)
1125{
1126 if (error)
1127 kfree(error);
1128}
1129
1130static ssize_t show_event_log(struct device *d,
1131 struct device_attribute *attr, char *buf)
1132{
1133 struct ipw_priv *priv = dev_get_drvdata(d);
1134 u32 log_len = ipw_get_event_log_len(priv);
1135 struct ipw_event log[log_len];
1136 u32 len = 0, i;
1137
1138 ipw_capture_event_log(priv, log_len, log);
1139
1140 len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1141 for (i = 0; i < log_len; i++)
1142 len += snprintf(buf + len, PAGE_SIZE - len,
1143 "\n%08X%08X%08X",
1144 log[i].time, log[i].event, log[i].data);
1145 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1146 return len;
1147}
1148
1149static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
1150
1151static ssize_t show_error(struct device *d,
1152 struct device_attribute *attr, char *buf)
1153{
1154 struct ipw_priv *priv = dev_get_drvdata(d);
1155 u32 len = 0, i;
1156 if (!priv->error)
1157 return 0;
1158 len += snprintf(buf + len, PAGE_SIZE - len,
f6c5cb7c
JK
1159 "%08lX%08X%08X%08X",
1160 priv->error->jiffies,
b39860c6
JK
1161 priv->error->status,
1162 priv->error->config, priv->error->elem_len);
1163 for (i = 0; i < priv->error->elem_len; i++)
1164 len += snprintf(buf + len, PAGE_SIZE - len,
1165 "\n%08X%08X%08X%08X%08X%08X%08X",
1166 priv->error->elem[i].time,
1167 priv->error->elem[i].desc,
1168 priv->error->elem[i].blink1,
1169 priv->error->elem[i].blink2,
1170 priv->error->elem[i].link1,
1171 priv->error->elem[i].link2,
1172 priv->error->elem[i].data);
1173
1174 len += snprintf(buf + len, PAGE_SIZE - len,
1175 "\n%08X", priv->error->log_len);
1176 for (i = 0; i < priv->error->log_len; i++)
1177 len += snprintf(buf + len, PAGE_SIZE - len,
1178 "\n%08X%08X%08X",
1179 priv->error->log[i].time,
1180 priv->error->log[i].event,
1181 priv->error->log[i].data);
1182 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1183 return len;
1184}
1185
1186static ssize_t clear_error(struct device *d,
1187 struct device_attribute *attr,
1188 const char *buf, size_t count)
1189{
1190 struct ipw_priv *priv = dev_get_drvdata(d);
1191 if (priv->error) {
1192 ipw_free_error_log(priv->error);
1193 priv->error = NULL;
1194 }
1195 return count;
1196}
1197
1198static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
1199
f6c5cb7c
JK
1200static ssize_t show_cmd_log(struct device *d,
1201 struct device_attribute *attr, char *buf)
1202{
1203 struct ipw_priv *priv = dev_get_drvdata(d);
1204 u32 len = 0, i;
1205 if (!priv->cmdlog)
1206 return 0;
1207 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
1208 (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
1209 i = (i + 1) % priv->cmdlog_len) {
1210 len +=
1211 snprintf(buf + len, PAGE_SIZE - len,
1212 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
1213 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
1214 priv->cmdlog[i].cmd.len);
1215 len +=
1216 snprintk_buf(buf + len, PAGE_SIZE - len,
1217 (u8 *) priv->cmdlog[i].cmd.param,
1218 priv->cmdlog[i].cmd.len);
1219 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1220 }
1221 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1222 return len;
1223}
1224
1225static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
1226
a613bffd
JK
1227static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
1228 char *buf)
1229{
1230 struct ipw_priv *priv = dev_get_drvdata(d);
1231 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1232}
1233
1234static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
1235 const char *buf, size_t count)
1236{
1237 struct ipw_priv *priv = dev_get_drvdata(d);
c848d0af 1238#ifdef CONFIG_IPW_DEBUG
a613bffd 1239 struct net_device *dev = priv->net_dev;
c848d0af 1240#endif
a613bffd
JK
1241 char buffer[] = "00000000";
1242 unsigned long len =
1243 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1244 unsigned long val;
1245 char *p = buffer;
1246
1247 IPW_DEBUG_INFO("enter\n");
1248
1249 strncpy(buffer, buf, len);
1250 buffer[len] = 0;
1251
1252 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1253 p++;
1254 if (p[0] == 'x' || p[0] == 'X')
1255 p++;
1256 val = simple_strtoul(p, &p, 16);
1257 } else
1258 val = simple_strtoul(p, &p, 10);
1259 if (p == buffer) {
1260 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1261 } else {
1262 priv->ieee->scan_age = val;
1263 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1264 }
1265
1266 IPW_DEBUG_INFO("exit\n");
1267 return len;
1268}
1269
1270static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
1271
1272static ssize_t show_led(struct device *d, struct device_attribute *attr,
1273 char *buf)
1274{
1275 struct ipw_priv *priv = dev_get_drvdata(d);
1276 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1277}
1278
1279static ssize_t store_led(struct device *d, struct device_attribute *attr,
1280 const char *buf, size_t count)
1281{
1282 struct ipw_priv *priv = dev_get_drvdata(d);
1283
1284 IPW_DEBUG_INFO("enter\n");
1285
1286 if (count == 0)
1287 return 0;
1288
1289 if (*buf == 0) {
1290 IPW_DEBUG_LED("Disabling LED control.\n");
1291 priv->config |= CFG_NO_LED;
1292 ipw_led_shutdown(priv);
1293 } else {
1294 IPW_DEBUG_LED("Enabling LED control.\n");
1295 priv->config &= ~CFG_NO_LED;
1296 ipw_led_init(priv);
1297 }
1298
1299 IPW_DEBUG_INFO("exit\n");
1300 return count;
1301}
1302
1303static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1304
ad3fee56 1305static ssize_t show_status(struct device *d,
0edd5b44 1306 struct device_attribute *attr, char *buf)
43f66a6c 1307{
ad3fee56 1308 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1309 return sprintf(buf, "0x%08x\n", (int)p->status);
1310}
0edd5b44 1311
43f66a6c
JK
1312static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1313
ad3fee56
AM
1314static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1315 char *buf)
43f66a6c 1316{
ad3fee56 1317 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1318 return sprintf(buf, "0x%08x\n", (int)p->config);
1319}
0edd5b44 1320
43f66a6c
JK
1321static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1322
ad3fee56 1323static ssize_t show_nic_type(struct device *d,
0edd5b44 1324 struct device_attribute *attr, char *buf)
43f66a6c 1325{
a613bffd
JK
1326 struct ipw_priv *priv = d->driver_data;
1327 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
43f66a6c 1328}
0edd5b44 1329
43f66a6c
JK
1330static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
1331
ad3fee56 1332static ssize_t show_ucode_version(struct device *d,
0edd5b44 1333 struct device_attribute *attr, char *buf)
43f66a6c
JK
1334{
1335 u32 len = sizeof(u32), tmp = 0;
ad3fee56 1336 struct ipw_priv *p = d->driver_data;
43f66a6c 1337
0edd5b44 1338 if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
43f66a6c
JK
1339 return 0;
1340
1341 return sprintf(buf, "0x%08x\n", tmp);
1342}
0edd5b44
JG
1343
1344static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL);
43f66a6c 1345
ad3fee56
AM
1346static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
1347 char *buf)
43f66a6c
JK
1348{
1349 u32 len = sizeof(u32), tmp = 0;
ad3fee56 1350 struct ipw_priv *p = d->driver_data;
43f66a6c 1351
0edd5b44 1352 if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
43f66a6c
JK
1353 return 0;
1354
1355 return sprintf(buf, "0x%08x\n", tmp);
1356}
0edd5b44
JG
1357
1358static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
43f66a6c
JK
1359
1360/*
1361 * Add a device attribute to view/control the delay between eeprom
1362 * operations.
1363 */
ad3fee56 1364static ssize_t show_eeprom_delay(struct device *d,
0edd5b44 1365 struct device_attribute *attr, char *buf)
43f66a6c 1366{
0edd5b44 1367 int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay;
43f66a6c
JK
1368 return sprintf(buf, "%i\n", n);
1369}
ad3fee56 1370static ssize_t store_eeprom_delay(struct device *d,
0edd5b44
JG
1371 struct device_attribute *attr,
1372 const char *buf, size_t count)
43f66a6c 1373{
ad3fee56 1374 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1375 sscanf(buf, "%i", &p->eeprom_delay);
1376 return strnlen(buf, count);
1377}
0edd5b44
JG
1378
1379static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO,
1380 show_eeprom_delay, store_eeprom_delay);
43f66a6c 1381
ad3fee56 1382static ssize_t show_command_event_reg(struct device *d,
0edd5b44 1383 struct device_attribute *attr, char *buf)
43f66a6c
JK
1384{
1385 u32 reg = 0;
ad3fee56 1386 struct ipw_priv *p = d->driver_data;
43f66a6c 1387
b095c381 1388 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
43f66a6c
JK
1389 return sprintf(buf, "0x%08x\n", reg);
1390}
ad3fee56 1391static ssize_t store_command_event_reg(struct device *d,
0edd5b44
JG
1392 struct device_attribute *attr,
1393 const char *buf, size_t count)
43f66a6c
JK
1394{
1395 u32 reg;
ad3fee56 1396 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1397
1398 sscanf(buf, "%x", &reg);
b095c381 1399 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
43f66a6c
JK
1400 return strnlen(buf, count);
1401}
0edd5b44
JG
1402
1403static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO,
1404 show_command_event_reg, store_command_event_reg);
43f66a6c 1405
ad3fee56 1406static ssize_t show_mem_gpio_reg(struct device *d,
0edd5b44 1407 struct device_attribute *attr, char *buf)
43f66a6c
JK
1408{
1409 u32 reg = 0;
ad3fee56 1410 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1411
1412 reg = ipw_read_reg32(p, 0x301100);
1413 return sprintf(buf, "0x%08x\n", reg);
1414}
ad3fee56 1415static ssize_t store_mem_gpio_reg(struct device *d,
0edd5b44
JG
1416 struct device_attribute *attr,
1417 const char *buf, size_t count)
43f66a6c
JK
1418{
1419 u32 reg;
ad3fee56 1420 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1421
1422 sscanf(buf, "%x", &reg);
1423 ipw_write_reg32(p, 0x301100, reg);
1424 return strnlen(buf, count);
1425}
0edd5b44
JG
1426
1427static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO,
1428 show_mem_gpio_reg, store_mem_gpio_reg);
43f66a6c 1429
ad3fee56 1430static ssize_t show_indirect_dword(struct device *d,
0edd5b44 1431 struct device_attribute *attr, char *buf)
43f66a6c
JK
1432{
1433 u32 reg = 0;
ad3fee56 1434 struct ipw_priv *priv = d->driver_data;
afbf30a2 1435
bf79451e 1436 if (priv->status & STATUS_INDIRECT_DWORD)
43f66a6c 1437 reg = ipw_read_reg32(priv, priv->indirect_dword);
bf79451e 1438 else
43f66a6c 1439 reg = 0;
bf79451e 1440
43f66a6c
JK
1441 return sprintf(buf, "0x%08x\n", reg);
1442}
ad3fee56 1443static ssize_t store_indirect_dword(struct device *d,
0edd5b44
JG
1444 struct device_attribute *attr,
1445 const char *buf, size_t count)
43f66a6c 1446{
ad3fee56 1447 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1448
1449 sscanf(buf, "%x", &priv->indirect_dword);
1450 priv->status |= STATUS_INDIRECT_DWORD;
1451 return strnlen(buf, count);
1452}
0edd5b44
JG
1453
1454static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO,
1455 show_indirect_dword, store_indirect_dword);
43f66a6c 1456
ad3fee56 1457static ssize_t show_indirect_byte(struct device *d,
0edd5b44 1458 struct device_attribute *attr, char *buf)
43f66a6c
JK
1459{
1460 u8 reg = 0;
ad3fee56 1461 struct ipw_priv *priv = d->driver_data;
afbf30a2 1462
bf79451e 1463 if (priv->status & STATUS_INDIRECT_BYTE)
43f66a6c 1464 reg = ipw_read_reg8(priv, priv->indirect_byte);
bf79451e 1465 else
43f66a6c
JK
1466 reg = 0;
1467
1468 return sprintf(buf, "0x%02x\n", reg);
1469}
ad3fee56 1470static ssize_t store_indirect_byte(struct device *d,
0edd5b44
JG
1471 struct device_attribute *attr,
1472 const char *buf, size_t count)
43f66a6c 1473{
ad3fee56 1474 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1475
1476 sscanf(buf, "%x", &priv->indirect_byte);
1477 priv->status |= STATUS_INDIRECT_BYTE;
1478 return strnlen(buf, count);
1479}
0edd5b44
JG
1480
1481static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO,
43f66a6c
JK
1482 show_indirect_byte, store_indirect_byte);
1483
ad3fee56 1484static ssize_t show_direct_dword(struct device *d,
0edd5b44 1485 struct device_attribute *attr, char *buf)
43f66a6c
JK
1486{
1487 u32 reg = 0;
ad3fee56 1488 struct ipw_priv *priv = d->driver_data;
43f66a6c 1489
bf79451e 1490 if (priv->status & STATUS_DIRECT_DWORD)
43f66a6c 1491 reg = ipw_read32(priv, priv->direct_dword);
bf79451e 1492 else
43f66a6c
JK
1493 reg = 0;
1494
1495 return sprintf(buf, "0x%08x\n", reg);
1496}
ad3fee56 1497static ssize_t store_direct_dword(struct device *d,
0edd5b44
JG
1498 struct device_attribute *attr,
1499 const char *buf, size_t count)
43f66a6c 1500{
ad3fee56 1501 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1502
1503 sscanf(buf, "%x", &priv->direct_dword);
1504 priv->status |= STATUS_DIRECT_DWORD;
1505 return strnlen(buf, count);
1506}
43f66a6c 1507
0edd5b44
JG
1508static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO,
1509 show_direct_dword, store_direct_dword);
43f66a6c
JK
1510
1511static inline int rf_kill_active(struct ipw_priv *priv)
1512{
1513 if (0 == (ipw_read32(priv, 0x30) & 0x10000))
1514 priv->status |= STATUS_RF_KILL_HW;
1515 else
1516 priv->status &= ~STATUS_RF_KILL_HW;
1517
1518 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
1519}
1520
ad3fee56 1521static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
0edd5b44 1522 char *buf)
43f66a6c
JK
1523{
1524 /* 0 - RF kill not enabled
bf79451e 1525 1 - SW based RF kill active (sysfs)
43f66a6c
JK
1526 2 - HW based RF kill active
1527 3 - Both HW and SW baed RF kill active */
ad3fee56 1528 struct ipw_priv *priv = d->driver_data;
43f66a6c 1529 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
0edd5b44 1530 (rf_kill_active(priv) ? 0x2 : 0x0);
43f66a6c
JK
1531 return sprintf(buf, "%i\n", val);
1532}
1533
1534static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
1535{
bf79451e 1536 if ((disable_radio ? 1 : 0) ==
ea2b26e0 1537 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
0edd5b44 1538 return 0;
43f66a6c
JK
1539
1540 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
1541 disable_radio ? "OFF" : "ON");
1542
1543 if (disable_radio) {
1544 priv->status |= STATUS_RF_KILL_SW;
1545
a613bffd 1546 if (priv->workqueue)
43f66a6c 1547 cancel_delayed_work(&priv->request_scan);
43f66a6c
JK
1548 queue_work(priv->workqueue, &priv->down);
1549 } else {
1550 priv->status &= ~STATUS_RF_KILL_SW;
1551 if (rf_kill_active(priv)) {
1552 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
1553 "disabled by HW switch\n");
1554 /* Make sure the RF_KILL check timer is running */
1555 cancel_delayed_work(&priv->rf_kill);
bf79451e 1556 queue_delayed_work(priv->workqueue, &priv->rf_kill,
43f66a6c 1557 2 * HZ);
bf79451e 1558 } else
43f66a6c
JK
1559 queue_work(priv->workqueue, &priv->up);
1560 }
1561
1562 return 1;
1563}
1564
0edd5b44
JG
1565static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
1566 const char *buf, size_t count)
43f66a6c 1567{
ad3fee56 1568 struct ipw_priv *priv = d->driver_data;
bf79451e 1569
43f66a6c
JK
1570 ipw_radio_kill_sw(priv, buf[0] == '1');
1571
1572 return count;
1573}
0edd5b44
JG
1574
1575static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
43f66a6c 1576
b095c381
JK
1577static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1578 char *buf)
1579{
1580 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1581 int pos = 0, len = 0;
1582 if (priv->config & CFG_SPEED_SCAN) {
1583 while (priv->speed_scan[pos] != 0)
1584 len += sprintf(&buf[len], "%d ",
1585 priv->speed_scan[pos++]);
1586 return len + sprintf(&buf[len], "\n");
1587 }
1588
1589 return sprintf(buf, "0\n");
1590}
1591
1592static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1593 const char *buf, size_t count)
1594{
1595 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1596 int channel, pos = 0;
1597 const char *p = buf;
1598
1599 /* list of space separated channels to scan, optionally ending with 0 */
1600 while ((channel = simple_strtol(p, NULL, 0))) {
1601 if (pos == MAX_SPEED_SCAN - 1) {
1602 priv->speed_scan[pos] = 0;
1603 break;
1604 }
1605
1fe0adb4 1606 if (ipw_is_valid_channel(priv->ieee, channel))
b095c381
JK
1607 priv->speed_scan[pos++] = channel;
1608 else
1609 IPW_WARNING("Skipping invalid channel request: %d\n",
1610 channel);
1611 p = strchr(p, ' ');
1612 if (!p)
1613 break;
1614 while (*p == ' ' || *p == '\t')
1615 p++;
1616 }
1617
1618 if (pos == 0)
1619 priv->config &= ~CFG_SPEED_SCAN;
1620 else {
1621 priv->speed_scan_pos = 0;
1622 priv->config |= CFG_SPEED_SCAN;
1623 }
1624
1625 return count;
1626}
1627
1628static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1629 store_speed_scan);
1630
1631static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1632 char *buf)
1633{
1634 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1635 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1636}
1637
1638static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1639 const char *buf, size_t count)
1640{
1641 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1642 if (buf[0] == '1')
1643 priv->config |= CFG_NET_STATS;
1644 else
1645 priv->config &= ~CFG_NET_STATS;
1646
1647 return count;
1648}
1649
afbf30a2
JK
1650static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1651 show_net_stats, store_net_stats);
b095c381 1652
ea2b26e0
JK
1653static void notify_wx_assoc_event(struct ipw_priv *priv)
1654{
1655 union iwreq_data wrqu;
1656 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1657 if (priv->status & STATUS_ASSOCIATED)
1658 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1659 else
1660 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1661 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1662}
1663
43f66a6c
JK
1664static void ipw_irq_tasklet(struct ipw_priv *priv)
1665{
1666 u32 inta, inta_mask, handled = 0;
1667 unsigned long flags;
1668 int rc = 0;
1669
1670 spin_lock_irqsave(&priv->lock, flags);
1671
b095c381
JK
1672 inta = ipw_read32(priv, IPW_INTA_RW);
1673 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
1674 inta &= (IPW_INTA_MASK_ALL & inta_mask);
43f66a6c
JK
1675
1676 /* Add any cached INTA values that need to be handled */
1677 inta |= priv->isr_inta;
1678
1679 /* handle all the justifications for the interrupt */
b095c381 1680 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
43f66a6c 1681 ipw_rx(priv);
b095c381 1682 handled |= IPW_INTA_BIT_RX_TRANSFER;
43f66a6c
JK
1683 }
1684
b095c381 1685 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
43f66a6c 1686 IPW_DEBUG_HC("Command completed.\n");
0edd5b44 1687 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
43f66a6c
JK
1688 priv->status &= ~STATUS_HCMD_ACTIVE;
1689 wake_up_interruptible(&priv->wait_command_queue);
b095c381 1690 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
43f66a6c
JK
1691 }
1692
b095c381 1693 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
43f66a6c 1694 IPW_DEBUG_TX("TX_QUEUE_1\n");
0edd5b44 1695 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
b095c381 1696 handled |= IPW_INTA_BIT_TX_QUEUE_1;
43f66a6c
JK
1697 }
1698
b095c381 1699 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
43f66a6c 1700 IPW_DEBUG_TX("TX_QUEUE_2\n");
0edd5b44 1701 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
b095c381 1702 handled |= IPW_INTA_BIT_TX_QUEUE_2;
43f66a6c
JK
1703 }
1704
b095c381 1705 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
43f66a6c 1706 IPW_DEBUG_TX("TX_QUEUE_3\n");
0edd5b44 1707 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
b095c381 1708 handled |= IPW_INTA_BIT_TX_QUEUE_3;
43f66a6c
JK
1709 }
1710
b095c381 1711 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
43f66a6c 1712 IPW_DEBUG_TX("TX_QUEUE_4\n");
0edd5b44 1713 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
b095c381 1714 handled |= IPW_INTA_BIT_TX_QUEUE_4;
43f66a6c
JK
1715 }
1716
b095c381 1717 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
43f66a6c 1718 IPW_WARNING("STATUS_CHANGE\n");
b095c381 1719 handled |= IPW_INTA_BIT_STATUS_CHANGE;
43f66a6c
JK
1720 }
1721
b095c381 1722 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
43f66a6c 1723 IPW_WARNING("TX_PERIOD_EXPIRED\n");
b095c381 1724 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
43f66a6c
JK
1725 }
1726
b095c381 1727 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
43f66a6c 1728 IPW_WARNING("HOST_CMD_DONE\n");
b095c381 1729 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
43f66a6c
JK
1730 }
1731
b095c381 1732 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
43f66a6c 1733 IPW_WARNING("FW_INITIALIZATION_DONE\n");
b095c381 1734 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
43f66a6c
JK
1735 }
1736
b095c381 1737 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
43f66a6c 1738 IPW_WARNING("PHY_OFF_DONE\n");
b095c381 1739 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
43f66a6c
JK
1740 }
1741
b095c381 1742 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
43f66a6c
JK
1743 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1744 priv->status |= STATUS_RF_KILL_HW;
1745 wake_up_interruptible(&priv->wait_command_queue);
ea2b26e0 1746 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
43f66a6c 1747 cancel_delayed_work(&priv->request_scan);
a613bffd 1748 schedule_work(&priv->link_down);
43f66a6c 1749 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
b095c381 1750 handled |= IPW_INTA_BIT_RF_KILL_DONE;
43f66a6c 1751 }
bf79451e 1752
b095c381 1753 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
43f66a6c 1754 IPW_ERROR("Firmware error detected. Restarting.\n");
b39860c6
JK
1755 if (priv->error) {
1756 IPW_ERROR("Sysfs 'error' log already exists.\n");
43f66a6c 1757#ifdef CONFIG_IPW_DEBUG
b39860c6
JK
1758 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1759 struct ipw_fw_error *error =
1760 ipw_alloc_error_log(priv);
1761 ipw_dump_error_log(priv, error);
1762 if (error)
1763 ipw_free_error_log(error);
1764 }
1765#endif
1766 } else {
1767 priv->error = ipw_alloc_error_log(priv);
1768 if (priv->error)
1769 IPW_ERROR("Sysfs 'error' log captured.\n");
1770 else
1771 IPW_ERROR("Error allocating sysfs 'error' "
1772 "log.\n");
1773#ifdef CONFIG_IPW_DEBUG
1774 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1775 ipw_dump_error_log(priv, priv->error);
43f66a6c 1776#endif
b39860c6
JK
1777 }
1778
b095c381
JK
1779 /* XXX: If hardware encryption is for WPA/WPA2,
1780 * we have to notify the supplicant. */
1781 if (priv->ieee->sec.encrypt) {
1782 priv->status &= ~STATUS_ASSOCIATED;
1783 notify_wx_assoc_event(priv);
1784 }
1785
1786 /* Keep the restart process from trying to send host
1787 * commands by clearing the INIT status bit */
1788 priv->status &= ~STATUS_INIT;
afbf30a2
JK
1789
1790 /* Cancel currently queued command. */
1791 priv->status &= ~STATUS_HCMD_ACTIVE;
1792 wake_up_interruptible(&priv->wait_command_queue);
1793
43f66a6c 1794 queue_work(priv->workqueue, &priv->adapter_restart);
b095c381 1795 handled |= IPW_INTA_BIT_FATAL_ERROR;
43f66a6c
JK
1796 }
1797
b095c381 1798 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
43f66a6c 1799 IPW_ERROR("Parity error\n");
b095c381 1800 handled |= IPW_INTA_BIT_PARITY_ERROR;
43f66a6c
JK
1801 }
1802
1803 if (handled != inta) {
0edd5b44 1804 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
43f66a6c
JK
1805 }
1806
1807 /* enable all interrupts */
1808 ipw_enable_interrupts(priv);
1809
1810 spin_unlock_irqrestore(&priv->lock, flags);
1811}
bf79451e 1812
43f66a6c
JK
1813#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1814static char *get_cmd_string(u8 cmd)
1815{
1816 switch (cmd) {
1817 IPW_CMD(HOST_COMPLETE);
bf79451e
JG
1818 IPW_CMD(POWER_DOWN);
1819 IPW_CMD(SYSTEM_CONFIG);
1820 IPW_CMD(MULTICAST_ADDRESS);
1821 IPW_CMD(SSID);
1822 IPW_CMD(ADAPTER_ADDRESS);
1823 IPW_CMD(PORT_TYPE);
1824 IPW_CMD(RTS_THRESHOLD);
1825 IPW_CMD(FRAG_THRESHOLD);
1826 IPW_CMD(POWER_MODE);
1827 IPW_CMD(WEP_KEY);
1828 IPW_CMD(TGI_TX_KEY);
1829 IPW_CMD(SCAN_REQUEST);
1830 IPW_CMD(SCAN_REQUEST_EXT);
1831 IPW_CMD(ASSOCIATE);
1832 IPW_CMD(SUPPORTED_RATES);
1833 IPW_CMD(SCAN_ABORT);
1834 IPW_CMD(TX_FLUSH);
1835 IPW_CMD(QOS_PARAMETERS);
1836 IPW_CMD(DINO_CONFIG);
1837 IPW_CMD(RSN_CAPABILITIES);
1838 IPW_CMD(RX_KEY);
1839 IPW_CMD(CARD_DISABLE);
1840 IPW_CMD(SEED_NUMBER);
1841 IPW_CMD(TX_POWER);
1842 IPW_CMD(COUNTRY_INFO);
1843 IPW_CMD(AIRONET_INFO);
1844 IPW_CMD(AP_TX_POWER);
1845 IPW_CMD(CCKM_INFO);
1846 IPW_CMD(CCX_VER_INFO);
1847 IPW_CMD(SET_CALIBRATION);
1848 IPW_CMD(SENSITIVITY_CALIB);
1849 IPW_CMD(RETRY_LIMIT);
1850 IPW_CMD(IPW_PRE_POWER_DOWN);
1851 IPW_CMD(VAP_BEACON_TEMPLATE);
1852 IPW_CMD(VAP_DTIM_PERIOD);
1853 IPW_CMD(EXT_SUPPORTED_RATES);
1854 IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);
1855 IPW_CMD(VAP_QUIET_INTERVALS);
1856 IPW_CMD(VAP_CHANNEL_SWITCH);
1857 IPW_CMD(VAP_MANDATORY_CHANNELS);
1858 IPW_CMD(VAP_CELL_PWR_LIMIT);
1859 IPW_CMD(VAP_CF_PARAM_SET);
1860 IPW_CMD(VAP_SET_BEACONING_STATE);
1861 IPW_CMD(MEASUREMENT);
1862 IPW_CMD(POWER_CAPABILITY);
1863 IPW_CMD(SUPPORTED_CHANNELS);
1864 IPW_CMD(TPC_REPORT);
1865 IPW_CMD(WME_INFO);
1866 IPW_CMD(PRODUCTION_COMMAND);
1867 default:
43f66a6c
JK
1868 return "UNKNOWN";
1869 }
1870}
43f66a6c
JK
1871
1872#define HOST_COMPLETE_TIMEOUT HZ
1873static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1874{
1875 int rc = 0;
a613bffd 1876 unsigned long flags;
43f66a6c 1877
a613bffd 1878 spin_lock_irqsave(&priv->lock, flags);
43f66a6c 1879 if (priv->status & STATUS_HCMD_ACTIVE) {
9ddf84f6
JK
1880 IPW_ERROR("Failed to send %s: Already sending a command.\n",
1881 get_cmd_string(cmd->cmd));
a613bffd 1882 spin_unlock_irqrestore(&priv->lock, flags);
9ddf84f6 1883 return -EAGAIN;
43f66a6c
JK
1884 }
1885
1886 priv->status |= STATUS_HCMD_ACTIVE;
bf79451e 1887
f6c5cb7c
JK
1888 if (priv->cmdlog) {
1889 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
1890 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
1891 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
1892 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
1893 cmd->len);
1894 priv->cmdlog[priv->cmdlog_pos].retcode = -1;
1895 }
1896
b095c381
JK
1897 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
1898 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
1899 priv->status);
0edd5b44 1900 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
43f66a6c
JK
1901
1902 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
a613bffd
JK
1903 if (rc) {
1904 priv->status &= ~STATUS_HCMD_ACTIVE;
9ddf84f6
JK
1905 IPW_ERROR("Failed to send %s: Reason %d\n",
1906 get_cmd_string(cmd->cmd), rc);
a613bffd 1907 spin_unlock_irqrestore(&priv->lock, flags);
f6c5cb7c 1908 goto exit;
a613bffd
JK
1909 }
1910 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 1911
0edd5b44
JG
1912 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1913 !(priv->
1914 status & STATUS_HCMD_ACTIVE),
1915 HOST_COMPLETE_TIMEOUT);
43f66a6c 1916 if (rc == 0) {
a613bffd
JK
1917 spin_lock_irqsave(&priv->lock, flags);
1918 if (priv->status & STATUS_HCMD_ACTIVE) {
9ddf84f6
JK
1919 IPW_ERROR("Failed to send %s: Command timed out.\n",
1920 get_cmd_string(cmd->cmd));
a613bffd
JK
1921 priv->status &= ~STATUS_HCMD_ACTIVE;
1922 spin_unlock_irqrestore(&priv->lock, flags);
f6c5cb7c
JK
1923 rc = -EIO;
1924 goto exit;
a613bffd
JK
1925 }
1926 spin_unlock_irqrestore(&priv->lock, flags);
3b9990cb
JK
1927 } else
1928 rc = 0;
a613bffd 1929
b095c381 1930 if (priv->status & STATUS_RF_KILL_HW) {
9ddf84f6
JK
1931 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
1932 get_cmd_string(cmd->cmd));
f6c5cb7c
JK
1933 rc = -EIO;
1934 goto exit;
43f66a6c
JK
1935 }
1936
f6c5cb7c
JK
1937 exit:
1938 if (priv->cmdlog) {
1939 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
1940 priv->cmdlog_pos %= priv->cmdlog_len;
1941 }
1942 return rc;
43f66a6c
JK
1943}
1944
1945static int ipw_send_host_complete(struct ipw_priv *priv)
1946{
1947 struct host_cmd cmd = {
1948 .cmd = IPW_CMD_HOST_COMPLETE,
1949 .len = 0
1950 };
1951
1952 if (!priv) {
1953 IPW_ERROR("Invalid args\n");
1954 return -1;
1955 }
1956
9ddf84f6 1957 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
1958}
1959
bf79451e 1960static int ipw_send_system_config(struct ipw_priv *priv,
43f66a6c
JK
1961 struct ipw_sys_config *config)
1962{
1963 struct host_cmd cmd = {
1964 .cmd = IPW_CMD_SYSTEM_CONFIG,
1965 .len = sizeof(*config)
1966 };
1967
1968 if (!priv || !config) {
1969 IPW_ERROR("Invalid args\n");
1970 return -1;
1971 }
1972
afbf30a2 1973 memcpy(cmd.param, config, sizeof(*config));
9ddf84f6 1974 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
1975}
1976
0edd5b44 1977static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
43f66a6c
JK
1978{
1979 struct host_cmd cmd = {
1980 .cmd = IPW_CMD_SSID,
1981 .len = min(len, IW_ESSID_MAX_SIZE)
1982 };
1983
1984 if (!priv || !ssid) {
1985 IPW_ERROR("Invalid args\n");
1986 return -1;
1987 }
1988
afbf30a2 1989 memcpy(cmd.param, ssid, cmd.len);
9ddf84f6 1990 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
1991}
1992
0edd5b44 1993static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
43f66a6c
JK
1994{
1995 struct host_cmd cmd = {
1996 .cmd = IPW_CMD_ADAPTER_ADDRESS,
1997 .len = ETH_ALEN
1998 };
1999
2000 if (!priv || !mac) {
2001 IPW_ERROR("Invalid args\n");
2002 return -1;
2003 }
2004
2005 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
2006 priv->net_dev->name, MAC_ARG(mac));
2007
afbf30a2 2008 memcpy(cmd.param, mac, ETH_ALEN);
9ddf84f6 2009 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2010}
2011
a613bffd
JK
2012/*
2013 * NOTE: This must be executed from our workqueue as it results in udelay
2014 * being called which may corrupt the keyboard if executed on default
2015 * workqueue
2016 */
43f66a6c
JK
2017static void ipw_adapter_restart(void *adapter)
2018{
2019 struct ipw_priv *priv = adapter;
2020
2021 if (priv->status & STATUS_RF_KILL_MASK)
2022 return;
2023
2024 ipw_down(priv);
b095c381
JK
2025
2026 if (priv->assoc_network &&
2027 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
2028 ipw_remove_current_network(priv);
2029
43f66a6c
JK
2030 if (ipw_up(priv)) {
2031 IPW_ERROR("Failed to up device\n");
2032 return;
2033 }
2034}
2035
c848d0af
JK
2036static void ipw_bg_adapter_restart(void *data)
2037{
2038 struct ipw_priv *priv = data;
2039 down(&priv->sem);
2040 ipw_adapter_restart(data);
2041 up(&priv->sem);
2042}
2043
43f66a6c
JK
2044#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
2045
2046static void ipw_scan_check(void *data)
2047{
2048 struct ipw_priv *priv = data;
2049 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
2050 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
bf79451e 2051 "adapter (%dms).\n",
43f66a6c 2052 IPW_SCAN_CHECK_WATCHDOG / 100);
a613bffd 2053 queue_work(priv->workqueue, &priv->adapter_restart);
43f66a6c
JK
2054 }
2055}
2056
c848d0af
JK
2057static void ipw_bg_scan_check(void *data)
2058{
2059 struct ipw_priv *priv = data;
2060 down(&priv->sem);
2061 ipw_scan_check(data);
2062 up(&priv->sem);
2063}
2064
43f66a6c
JK
2065static int ipw_send_scan_request_ext(struct ipw_priv *priv,
2066 struct ipw_scan_request_ext *request)
2067{
2068 struct host_cmd cmd = {
2069 .cmd = IPW_CMD_SCAN_REQUEST_EXT,
2070 .len = sizeof(*request)
2071 };
2072
afbf30a2 2073 memcpy(cmd.param, request, sizeof(*request));
9ddf84f6 2074 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2075}
2076
2077static int ipw_send_scan_abort(struct ipw_priv *priv)
2078{
2079 struct host_cmd cmd = {
2080 .cmd = IPW_CMD_SCAN_ABORT,
2081 .len = 0
2082 };
2083
2084 if (!priv) {
2085 IPW_ERROR("Invalid args\n");
2086 return -1;
2087 }
2088
9ddf84f6 2089 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2090}
2091
2092static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
2093{
2094 struct host_cmd cmd = {
2095 .cmd = IPW_CMD_SENSITIVITY_CALIB,
2096 .len = sizeof(struct ipw_sensitivity_calib)
2097 };
2098 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
0edd5b44 2099 &cmd.param;
43f66a6c 2100 calib->beacon_rssi_raw = sens;
9ddf84f6 2101 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2102}
2103
2104static int ipw_send_associate(struct ipw_priv *priv,
2105 struct ipw_associate *associate)
2106{
2107 struct host_cmd cmd = {
2108 .cmd = IPW_CMD_ASSOCIATE,
2109 .len = sizeof(*associate)
2110 };
2111
a613bffd
JK
2112 struct ipw_associate tmp_associate;
2113 memcpy(&tmp_associate, associate, sizeof(*associate));
2114 tmp_associate.policy_support =
2115 cpu_to_le16(tmp_associate.policy_support);
2116 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
2117 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
2118 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
2119 tmp_associate.listen_interval =
2120 cpu_to_le16(tmp_associate.listen_interval);
2121 tmp_associate.beacon_interval =
2122 cpu_to_le16(tmp_associate.beacon_interval);
2123 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
2124
43f66a6c
JK
2125 if (!priv || !associate) {
2126 IPW_ERROR("Invalid args\n");
2127 return -1;
2128 }
2129
afbf30a2 2130 memcpy(cmd.param, &tmp_associate, sizeof(*associate));
9ddf84f6 2131 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2132}
2133
2134static int ipw_send_supported_rates(struct ipw_priv *priv,
2135 struct ipw_supported_rates *rates)
2136{
2137 struct host_cmd cmd = {
2138 .cmd = IPW_CMD_SUPPORTED_RATES,
2139 .len = sizeof(*rates)
2140 };
2141
2142 if (!priv || !rates) {
2143 IPW_ERROR("Invalid args\n");
2144 return -1;
2145 }
2146
afbf30a2 2147 memcpy(cmd.param, rates, sizeof(*rates));
9ddf84f6 2148 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2149}
2150
2151static int ipw_set_random_seed(struct ipw_priv *priv)
2152{
2153 struct host_cmd cmd = {
2154 .cmd = IPW_CMD_SEED_NUMBER,
2155 .len = sizeof(u32)
2156 };
2157
2158 if (!priv) {
2159 IPW_ERROR("Invalid args\n");
2160 return -1;
2161 }
2162
2163 get_random_bytes(&cmd.param, sizeof(u32));
2164
9ddf84f6 2165 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2166}
2167
43f66a6c
JK
2168static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
2169{
2170 struct host_cmd cmd = {
2171 .cmd = IPW_CMD_CARD_DISABLE,
2172 .len = sizeof(u32)
2173 };
2174
2175 if (!priv) {
2176 IPW_ERROR("Invalid args\n");
2177 return -1;
2178 }
2179
0edd5b44 2180 *((u32 *) & cmd.param) = phy_off;
43f66a6c 2181
9ddf84f6 2182 return ipw_send_cmd(priv, &cmd);
43f66a6c 2183}
43f66a6c 2184
0edd5b44 2185static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
43f66a6c
JK
2186{
2187 struct host_cmd cmd = {
2188 .cmd = IPW_CMD_TX_POWER,
2189 .len = sizeof(*power)
2190 };
2191
2192 if (!priv || !power) {
2193 IPW_ERROR("Invalid args\n");
2194 return -1;
2195 }
2196
afbf30a2 2197 memcpy(cmd.param, power, sizeof(*power));
9ddf84f6 2198 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2199}
2200
6de9f7f2
ZY
2201static int ipw_set_tx_power(struct ipw_priv *priv)
2202{
1fe0adb4 2203 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
6de9f7f2
ZY
2204 struct ipw_tx_power tx_power;
2205 s8 max_power;
2206 int i;
2207
2208 memset(&tx_power, 0, sizeof(tx_power));
2209
2210 /* configure device for 'G' band */
2211 tx_power.ieee_mode = IPW_G_MODE;
2212 tx_power.num_channels = geo->bg_channels;
2213 for (i = 0; i < geo->bg_channels; i++) {
2214 max_power = geo->bg[i].max_power;
2215 tx_power.channels_tx_power[i].channel_number =
2216 geo->bg[i].channel;
2217 tx_power.channels_tx_power[i].tx_power = max_power ?
2218 min(max_power, priv->tx_power) : priv->tx_power;
2219 }
2220 if (ipw_send_tx_power(priv, &tx_power))
2221 return -EIO;
2222
2223 /* configure device to also handle 'B' band */
2224 tx_power.ieee_mode = IPW_B_MODE;
2225 if (ipw_send_tx_power(priv, &tx_power))
2226 return -EIO;
2227
2228 /* configure device to also handle 'A' band */
2229 if (priv->ieee->abg_true) {
2230 tx_power.ieee_mode = IPW_A_MODE;
2231 tx_power.num_channels = geo->a_channels;
2232 for (i = 0; i < tx_power.num_channels; i++) {
2233 max_power = geo->a[i].max_power;
2234 tx_power.channels_tx_power[i].channel_number =
2235 geo->a[i].channel;
2236 tx_power.channels_tx_power[i].tx_power = max_power ?
2237 min(max_power, priv->tx_power) : priv->tx_power;
2238 }
2239 if (ipw_send_tx_power(priv, &tx_power))
2240 return -EIO;
2241 }
2242 return 0;
2243}
2244
43f66a6c
JK
2245static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2246{
2247 struct ipw_rts_threshold rts_threshold = {
2248 .rts_threshold = rts,
2249 };
2250 struct host_cmd cmd = {
2251 .cmd = IPW_CMD_RTS_THRESHOLD,
2252 .len = sizeof(rts_threshold)
2253 };
2254
2255 if (!priv) {
2256 IPW_ERROR("Invalid args\n");
2257 return -1;
2258 }
2259
afbf30a2 2260 memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
9ddf84f6 2261 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2262}
2263
2264static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
2265{
2266 struct ipw_frag_threshold frag_threshold = {
2267 .frag_threshold = frag,
2268 };
2269 struct host_cmd cmd = {
2270 .cmd = IPW_CMD_FRAG_THRESHOLD,
2271 .len = sizeof(frag_threshold)
2272 };
2273
2274 if (!priv) {
2275 IPW_ERROR("Invalid args\n");
2276 return -1;
2277 }
2278
afbf30a2 2279 memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
9ddf84f6 2280 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2281}
2282
2283static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2284{
2285 struct host_cmd cmd = {
2286 .cmd = IPW_CMD_POWER_MODE,
2287 .len = sizeof(u32)
2288 };
0edd5b44 2289 u32 *param = (u32 *) (&cmd.param);
43f66a6c
JK
2290
2291 if (!priv) {
2292 IPW_ERROR("Invalid args\n");
2293 return -1;
2294 }
bf79451e 2295
43f66a6c
JK
2296 /* If on battery, set to 3, if AC set to CAM, else user
2297 * level */
2298 switch (mode) {
2299 case IPW_POWER_BATTERY:
2300 *param = IPW_POWER_INDEX_3;
2301 break;
2302 case IPW_POWER_AC:
2303 *param = IPW_POWER_MODE_CAM;
2304 break;
2305 default:
2306 *param = mode;
2307 break;
2308 }
2309
9ddf84f6 2310 return ipw_send_cmd(priv, &cmd);
43f66a6c
JK
2311}
2312
afbf30a2
JK
2313static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2314{
2315 struct ipw_retry_limit retry_limit = {
2316 .short_retry_limit = slimit,
2317 .long_retry_limit = llimit
2318 };
2319 struct host_cmd cmd = {
2320 .cmd = IPW_CMD_RETRY_LIMIT,
2321 .len = sizeof(retry_limit)
2322 };
2323
2324 if (!priv) {
2325 IPW_ERROR("Invalid args\n");
2326 return -1;
2327 }
2328
2329 memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
9ddf84f6 2330 return ipw_send_cmd(priv, &cmd);
afbf30a2
JK
2331}
2332
43f66a6c
JK
2333/*
2334 * The IPW device contains a Microwire compatible EEPROM that stores
2335 * various data like the MAC address. Usually the firmware has exclusive
2336 * access to the eeprom, but during device initialization (before the
2337 * device driver has sent the HostComplete command to the firmware) the
2338 * device driver has read access to the EEPROM by way of indirect addressing
2339 * through a couple of memory mapped registers.
2340 *
2341 * The following is a simplified implementation for pulling data out of the
2342 * the eeprom, along with some helper functions to find information in
2343 * the per device private data's copy of the eeprom.
2344 *
2345 * NOTE: To better understand how these functions work (i.e what is a chip
2346 * select and why do have to keep driving the eeprom clock?), read
2347 * just about any data sheet for a Microwire compatible EEPROM.
2348 */
2349
2350/* write a 32 bit value into the indirect accessor register */
2351static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
2352{
2353 ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);
bf79451e 2354
43f66a6c
JK
2355 /* the eeprom requires some time to complete the operation */
2356 udelay(p->eeprom_delay);
2357
2358 return;
2359}
2360
2361/* perform a chip select operation */
0edd5b44 2362static inline void eeprom_cs(struct ipw_priv *priv)
43f66a6c 2363{
0edd5b44
JG
2364 eeprom_write_reg(priv, 0);
2365 eeprom_write_reg(priv, EEPROM_BIT_CS);
2366 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2367 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2368}
2369
2370/* perform a chip select operation */
0edd5b44 2371static inline void eeprom_disable_cs(struct ipw_priv *priv)
43f66a6c 2372{
0edd5b44
JG
2373 eeprom_write_reg(priv, EEPROM_BIT_CS);
2374 eeprom_write_reg(priv, 0);
2375 eeprom_write_reg(priv, EEPROM_BIT_SK);
43f66a6c
JK
2376}
2377
2378/* push a single bit down to the eeprom */
0edd5b44 2379static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit)
43f66a6c 2380{
0edd5b44
JG
2381 int d = (bit ? EEPROM_BIT_DI : 0);
2382 eeprom_write_reg(p, EEPROM_BIT_CS | d);
2383 eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK);
43f66a6c
JK
2384}
2385
2386/* push an opcode followed by an address down to the eeprom */
0edd5b44 2387static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr)
43f66a6c
JK
2388{
2389 int i;
2390
2391 eeprom_cs(priv);
0edd5b44
JG
2392 eeprom_write_bit(priv, 1);
2393 eeprom_write_bit(priv, op & 2);
2394 eeprom_write_bit(priv, op & 1);
2395 for (i = 7; i >= 0; i--) {
2396 eeprom_write_bit(priv, addr & (1 << i));
43f66a6c
JK
2397 }
2398}
2399
2400/* pull 16 bits off the eeprom, one bit at a time */
0edd5b44 2401static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
43f66a6c
JK
2402{
2403 int i;
0edd5b44 2404 u16 r = 0;
bf79451e 2405
43f66a6c 2406 /* Send READ Opcode */
0edd5b44 2407 eeprom_op(priv, EEPROM_CMD_READ, addr);
43f66a6c
JK
2408
2409 /* Send dummy bit */
0edd5b44 2410 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2411
2412 /* Read the byte off the eeprom one bit at a time */
0edd5b44 2413 for (i = 0; i < 16; i++) {
43f66a6c 2414 u32 data = 0;
0edd5b44
JG
2415 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2416 eeprom_write_reg(priv, EEPROM_BIT_CS);
2417 data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS);
2418 r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0);
43f66a6c 2419 }
bf79451e 2420
43f66a6c 2421 /* Send another dummy bit */
0edd5b44 2422 eeprom_write_reg(priv, 0);
43f66a6c 2423 eeprom_disable_cs(priv);
bf79451e 2424
43f66a6c
JK
2425 return r;
2426}
2427
2428/* helper function for pulling the mac address out of the private */
2429/* data's copy of the eeprom data */
0edd5b44 2430static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
43f66a6c 2431{
afbf30a2 2432 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
43f66a6c
JK
2433}
2434
2435/*
2436 * Either the device driver (i.e. the host) or the firmware can
2437 * load eeprom data into the designated region in SRAM. If neither
2438 * happens then the FW will shutdown with a fatal error.
2439 *
2440 * In order to signal the FW to load the EEPROM, the EEPROM_LOAD_DISABLE
2441 * bit needs region of shared SRAM needs to be non-zero.
2442 */
2443static void ipw_eeprom_init_sram(struct ipw_priv *priv)
2444{
2445 int i;
0edd5b44 2446 u16 *eeprom = (u16 *) priv->eeprom;
bf79451e 2447
43f66a6c
JK
2448 IPW_DEBUG_TRACE(">>\n");
2449
2450 /* read entire contents of eeprom into private buffer */
0edd5b44 2451 for (i = 0; i < 128; i++)
a613bffd 2452 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
43f66a6c 2453
bf79451e
JG
2454 /*
2455 If the data looks correct, then copy it to our private
43f66a6c
JK
2456 copy. Otherwise let the firmware know to perform the operation
2457 on it's own
0edd5b44 2458 */
43f66a6c
JK
2459 if ((priv->eeprom + EEPROM_VERSION) != 0) {
2460 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
2461
2462 /* write the eeprom data to sram */
b095c381 2463 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
0edd5b44 2464 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
43f66a6c
JK
2465
2466 /* Do not load eeprom data on fatal error or suspend */
2467 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
2468 } else {
2469 IPW_DEBUG_INFO("Enabling FW initializationg of SRAM\n");
2470
2471 /* Load eeprom data on fatal error or suspend */
2472 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);
2473 }
2474
2475 IPW_DEBUG_TRACE("<<\n");
2476}
2477
43f66a6c
JK
2478static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
2479{
2480 count >>= 2;
0edd5b44
JG
2481 if (!count)
2482 return;
b095c381 2483 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
bf79451e 2484 while (count--)
b095c381 2485 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
43f66a6c
JK
2486}
2487
2488static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
2489{
b095c381 2490 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
bf79451e 2491 CB_NUMBER_OF_ELEMENTS_SMALL *
43f66a6c
JK
2492 sizeof(struct command_block));
2493}
2494
2495static int ipw_fw_dma_enable(struct ipw_priv *priv)
0edd5b44 2496{ /* start dma engine but no transfers yet */
43f66a6c
JK
2497
2498 IPW_DEBUG_FW(">> : \n");
bf79451e 2499
43f66a6c
JK
2500 /* Start the dma */
2501 ipw_fw_dma_reset_command_blocks(priv);
bf79451e 2502
43f66a6c 2503 /* Write CB base address */
b095c381 2504 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
43f66a6c
JK
2505
2506 IPW_DEBUG_FW("<< : \n");
2507 return 0;
2508}
2509
2510static void ipw_fw_dma_abort(struct ipw_priv *priv)
2511{
2512 u32 control = 0;
2513
2514 IPW_DEBUG_FW(">> :\n");
bf79451e
JG
2515
2516 //set the Stop and Abort bit
43f66a6c 2517 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
b095c381 2518 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
43f66a6c 2519 priv->sram_desc.last_cb_index = 0;
bf79451e 2520
43f66a6c
JK
2521 IPW_DEBUG_FW("<< \n");
2522}
2523
0edd5b44
JG
2524static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
2525 struct command_block *cb)
43f66a6c 2526{
0edd5b44 2527 u32 address =
b095c381 2528 IPW_SHARED_SRAM_DMA_CONTROL +
0edd5b44 2529 (sizeof(struct command_block) * index);
43f66a6c
JK
2530 IPW_DEBUG_FW(">> :\n");
2531
0edd5b44
JG
2532 ipw_write_indirect(priv, address, (u8 *) cb,
2533 (int)sizeof(struct command_block));
43f66a6c
JK
2534
2535 IPW_DEBUG_FW("<< :\n");
2536 return 0;
2537
2538}
2539
2540static int ipw_fw_dma_kick(struct ipw_priv *priv)
2541{
2542 u32 control = 0;
0edd5b44 2543 u32 index = 0;
43f66a6c
JK
2544
2545 IPW_DEBUG_FW(">> :\n");
bf79451e 2546
43f66a6c 2547 for (index = 0; index < priv->sram_desc.last_cb_index; index++)
0edd5b44
JG
2548 ipw_fw_dma_write_command_block(priv, index,
2549 &priv->sram_desc.cb_list[index]);
43f66a6c
JK
2550
2551 /* Enable the DMA in the CSR register */
b095c381
JK
2552 ipw_clear_bit(priv, IPW_RESET_REG,
2553 IPW_RESET_REG_MASTER_DISABLED |
2554 IPW_RESET_REG_STOP_MASTER);
bf79451e 2555
0edd5b44 2556 /* Set the Start bit. */
43f66a6c 2557 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
b095c381 2558 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
43f66a6c
JK
2559
2560 IPW_DEBUG_FW("<< :\n");
2561 return 0;
2562}
2563
2564static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
2565{
2566 u32 address;
0edd5b44
JG
2567 u32 register_value = 0;
2568 u32 cb_fields_address = 0;
43f66a6c
JK
2569
2570 IPW_DEBUG_FW(">> :\n");
b095c381 2571 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
0edd5b44 2572 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
43f66a6c
JK
2573
2574 /* Read the DMA Controlor register */
b095c381
JK
2575 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
2576 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
43f66a6c 2577
0edd5b44 2578 /* Print the CB values */
43f66a6c
JK
2579 cb_fields_address = address;
2580 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2581 IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n", register_value);
43f66a6c
JK
2582
2583 cb_fields_address += sizeof(u32);
2584 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2585 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n", register_value);
43f66a6c
JK
2586
2587 cb_fields_address += sizeof(u32);
2588 register_value = ipw_read_reg32(priv, cb_fields_address);
2589 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x \n",
2590 register_value);
2591
2592 cb_fields_address += sizeof(u32);
2593 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2594 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n", register_value);
43f66a6c
JK
2595
2596 IPW_DEBUG_FW(">> :\n");
2597}
2598
2599static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
2600{
2601 u32 current_cb_address = 0;
2602 u32 current_cb_index = 0;
2603
2604 IPW_DEBUG_FW("<< :\n");
b095c381 2605 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
bf79451e 2606
b095c381 2607 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
0edd5b44 2608 sizeof(struct command_block);
bf79451e 2609
43f66a6c 2610 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
0edd5b44 2611 current_cb_index, current_cb_address);
43f66a6c
JK
2612
2613 IPW_DEBUG_FW(">> :\n");
2614 return current_cb_index;
2615
2616}
2617
2618static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
2619 u32 src_address,
2620 u32 dest_address,
2621 u32 length,
0edd5b44 2622 int interrupt_enabled, int is_last)
43f66a6c
JK
2623{
2624
bf79451e 2625 u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC |
0edd5b44
JG
2626 CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG |
2627 CB_DEST_SIZE_LONG;
43f66a6c 2628 struct command_block *cb;
0edd5b44 2629 u32 last_cb_element = 0;
43f66a6c
JK
2630
2631 IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n",
2632 src_address, dest_address, length);
2633
2634 if (priv->sram_desc.last_cb_index >= CB_NUMBER_OF_ELEMENTS_SMALL)
2635 return -1;
2636
2637 last_cb_element = priv->sram_desc.last_cb_index;
2638 cb = &priv->sram_desc.cb_list[last_cb_element];
2639 priv->sram_desc.last_cb_index++;
2640
2641 /* Calculate the new CB control word */
0edd5b44 2642 if (interrupt_enabled)
43f66a6c
JK
2643 control |= CB_INT_ENABLED;
2644
2645 if (is_last)
2646 control |= CB_LAST_VALID;
bf79451e 2647
43f66a6c
JK
2648 control |= length;
2649
2650 /* Calculate the CB Element's checksum value */
0edd5b44 2651 cb->status = control ^ src_address ^ dest_address;
43f66a6c
JK
2652
2653 /* Copy the Source and Destination addresses */
2654 cb->dest_addr = dest_address;
2655 cb->source_addr = src_address;
2656
2657 /* Copy the Control Word last */
2658 cb->control = control;
2659
2660 return 0;
2661}
2662
2663static int ipw_fw_dma_add_buffer(struct ipw_priv *priv,
0edd5b44 2664 u32 src_phys, u32 dest_address, u32 length)
43f66a6c
JK
2665{
2666 u32 bytes_left = length;
0edd5b44
JG
2667 u32 src_offset = 0;
2668 u32 dest_offset = 0;
43f66a6c
JK
2669 int status = 0;
2670 IPW_DEBUG_FW(">> \n");
2671 IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n",
2672 src_phys, dest_address, length);
2673 while (bytes_left > CB_MAX_LENGTH) {
0edd5b44
JG
2674 status = ipw_fw_dma_add_command_block(priv,
2675 src_phys + src_offset,
2676 dest_address +
2677 dest_offset,
2678 CB_MAX_LENGTH, 0, 0);
43f66a6c
JK
2679 if (status) {
2680 IPW_DEBUG_FW_INFO(": Failed\n");
2681 return -1;
bf79451e 2682 } else
43f66a6c
JK
2683 IPW_DEBUG_FW_INFO(": Added new cb\n");
2684
2685 src_offset += CB_MAX_LENGTH;
2686 dest_offset += CB_MAX_LENGTH;
2687 bytes_left -= CB_MAX_LENGTH;
2688 }
2689
2690 /* add the buffer tail */
2691 if (bytes_left > 0) {
0edd5b44
JG
2692 status =
2693 ipw_fw_dma_add_command_block(priv, src_phys + src_offset,
2694 dest_address + dest_offset,
2695 bytes_left, 0, 0);
43f66a6c
JK
2696 if (status) {
2697 IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n");
2698 return -1;
bf79451e 2699 } else
0edd5b44
JG
2700 IPW_DEBUG_FW_INFO
2701 (": Adding new cb - the buffer tail\n");
43f66a6c 2702 }
bf79451e 2703
43f66a6c
JK
2704 IPW_DEBUG_FW("<< \n");
2705 return 0;
2706}
2707
2708static int ipw_fw_dma_wait(struct ipw_priv *priv)
2709{
2710 u32 current_index = 0;
2711 u32 watchdog = 0;
2712
2713 IPW_DEBUG_FW(">> : \n");
2714
2715 current_index = ipw_fw_dma_command_block_index(priv);
bf79451e 2716 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n",
0edd5b44 2717 (int)priv->sram_desc.last_cb_index);
43f66a6c
JK
2718
2719 while (current_index < priv->sram_desc.last_cb_index) {
2720 udelay(50);
2721 current_index = ipw_fw_dma_command_block_index(priv);
2722
2723 watchdog++;
2724
2725 if (watchdog > 400) {
2726 IPW_DEBUG_FW_INFO("Timeout\n");
2727 ipw_fw_dma_dump_command_block(priv);
2728 ipw_fw_dma_abort(priv);
2729 return -1;
2730 }
2731 }
2732
2733 ipw_fw_dma_abort(priv);
2734
0edd5b44 2735 /*Disable the DMA in the CSR register */
b095c381
JK
2736 ipw_set_bit(priv, IPW_RESET_REG,
2737 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
43f66a6c
JK
2738
2739 IPW_DEBUG_FW("<< dmaWaitSync \n");
2740 return 0;
2741}
2742
bf79451e 2743static void ipw_remove_current_network(struct ipw_priv *priv)
43f66a6c
JK
2744{
2745 struct list_head *element, *safe;
bf79451e 2746 struct ieee80211_network *network = NULL;
a613bffd
JK
2747 unsigned long flags;
2748
2749 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c
JK
2750 list_for_each_safe(element, safe, &priv->ieee->network_list) {
2751 network = list_entry(element, struct ieee80211_network, list);
2752 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
2753 list_del(element);
bf79451e 2754 list_add_tail(&network->list,
43f66a6c
JK
2755 &priv->ieee->network_free_list);
2756 }
2757 }
a613bffd 2758 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c
JK
2759}
2760
2761/**
bf79451e 2762 * Check that card is still alive.
43f66a6c
JK
2763 * Reads debug register from domain0.
2764 * If card is present, pre-defined value should
2765 * be found there.
bf79451e 2766 *
43f66a6c
JK
2767 * @param priv
2768 * @return 1 if card is present, 0 otherwise
2769 */
2770static inline int ipw_alive(struct ipw_priv *priv)
2771{
2772 return ipw_read32(priv, 0x90) == 0xd55555d5;
2773}
2774
2775static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
2776 int timeout)
2777{
2778 int i = 0;
2779
2780 do {
bf79451e 2781 if ((ipw_read32(priv, addr) & mask) == mask)
43f66a6c
JK
2782 return i;
2783 mdelay(10);
2784 i += 10;
2785 } while (i < timeout);
bf79451e 2786
43f66a6c
JK
2787 return -ETIME;
2788}
2789
bf79451e 2790/* These functions load the firmware and micro code for the operation of
43f66a6c
JK
2791 * the ipw hardware. It assumes the buffer has all the bits for the
2792 * image and the caller is handling the memory allocation and clean up.
2793 */
2794
0edd5b44 2795static int ipw_stop_master(struct ipw_priv *priv)
43f66a6c
JK
2796{
2797 int rc;
bf79451e 2798
43f66a6c
JK
2799 IPW_DEBUG_TRACE(">> \n");
2800 /* stop master. typical delay - 0 */
b095c381 2801 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
43f66a6c 2802
b095c381
JK
2803 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2804 IPW_RESET_REG_MASTER_DISABLED, 100);
43f66a6c
JK
2805 if (rc < 0) {
2806 IPW_ERROR("stop master failed in 10ms\n");
2807 return -1;
2808 }
2809
2810 IPW_DEBUG_INFO("stop master %dms\n", rc);
2811
2812 return rc;
2813}
2814
2815static void ipw_arc_release(struct ipw_priv *priv)
2816{
2817 IPW_DEBUG_TRACE(">> \n");
2818 mdelay(5);
2819
b095c381 2820 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
43f66a6c
JK
2821
2822 /* no one knows timing, for safety add some delay */
2823 mdelay(5);
2824}
2825
2826struct fw_header {
2827 u32 version;
2828 u32 mode;
2829};
2830
2831struct fw_chunk {
2832 u32 address;
2833 u32 length;
2834};
2835
2836#define IPW_FW_MAJOR_VERSION 2
b095c381 2837#define IPW_FW_MINOR_VERSION 3
43f66a6c
JK
2838
2839#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2840#define IPW_FW_MAJOR(x) (x & 0xff)
2841
afbf30a2 2842#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
43f66a6c
JK
2843
2844#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2845"." __stringify(IPW_FW_MINOR_VERSION) "-"
2846
2847#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
2848#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
2849#else
2850#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
2851#endif
2852
0edd5b44 2853static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c
JK
2854{
2855 int rc = 0, i, addr;
2856 u8 cr = 0;
2857 u16 *image;
2858
0edd5b44 2859 image = (u16 *) data;
bf79451e 2860
43f66a6c
JK
2861 IPW_DEBUG_TRACE(">> \n");
2862
2863 rc = ipw_stop_master(priv);
2864
2865 if (rc < 0)
2866 return rc;
bf79451e 2867
0edd5b44 2868// spin_lock_irqsave(&priv->lock, flags);
bf79451e 2869
b095c381
JK
2870 for (addr = IPW_SHARED_LOWER_BOUND;
2871 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
43f66a6c
JK
2872 ipw_write32(priv, addr, 0);
2873 }
2874
2875 /* no ucode (yet) */
2876 memset(&priv->dino_alive, 0, sizeof(priv->dino_alive));
2877 /* destroy DMA queues */
2878 /* reset sequence */
2879
b095c381 2880 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
43f66a6c 2881 ipw_arc_release(priv);
b095c381 2882 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
43f66a6c
JK
2883 mdelay(1);
2884
2885 /* reset PHY */
b095c381 2886 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
43f66a6c 2887 mdelay(1);
bf79451e 2888
b095c381 2889 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
43f66a6c 2890 mdelay(1);
bf79451e 2891
43f66a6c
JK
2892 /* enable ucode store */
2893 ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0);
2894 ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS);
2895 mdelay(1);
2896
2897 /* write ucode */
2898 /**
2899 * @bug
2900 * Do NOT set indirect address register once and then
2901 * store data to indirect data register in the loop.
2902 * It seems very reasonable, but in this case DINO do not
2903 * accept ucode. It is essential to set address each time.
2904 */
2905 /* load new ipw uCode */
2906 for (i = 0; i < len / 2; i++)
b095c381 2907 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
a613bffd 2908 cpu_to_le16(image[i]));
43f66a6c 2909
43f66a6c 2910 /* enable DINO */
b095c381
JK
2911 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2912 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
43f66a6c 2913
0edd5b44 2914 /* this is where the igx / win driver deveates from the VAP driver. */
43f66a6c
JK
2915
2916 /* wait for alive response */
2917 for (i = 0; i < 100; i++) {
2918 /* poll for incoming data */
b095c381 2919 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
43f66a6c
JK
2920 if (cr & DINO_RXFIFO_DATA)
2921 break;
2922 mdelay(1);
2923 }
2924
2925 if (cr & DINO_RXFIFO_DATA) {
2926 /* alive_command_responce size is NOT multiple of 4 */
2927 u32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
bf79451e
JG
2928
2929 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
43f66a6c 2930 response_buffer[i] =
a613bffd 2931 le32_to_cpu(ipw_read_reg32(priv,
b095c381 2932 IPW_BASEBAND_RX_FIFO_READ));
43f66a6c
JK
2933 memcpy(&priv->dino_alive, response_buffer,
2934 sizeof(priv->dino_alive));
2935 if (priv->dino_alive.alive_command == 1
2936 && priv->dino_alive.ucode_valid == 1) {
2937 rc = 0;
0edd5b44
JG
2938 IPW_DEBUG_INFO
2939 ("Microcode OK, rev. %d (0x%x) dev. %d (0x%x) "
2940 "of %02d/%02d/%02d %02d:%02d\n",
2941 priv->dino_alive.software_revision,
2942 priv->dino_alive.software_revision,
2943 priv->dino_alive.device_identifier,
2944 priv->dino_alive.device_identifier,
2945 priv->dino_alive.time_stamp[0],
2946 priv->dino_alive.time_stamp[1],
2947 priv->dino_alive.time_stamp[2],
2948 priv->dino_alive.time_stamp[3],
2949 priv->dino_alive.time_stamp[4]);
43f66a6c
JK
2950 } else {
2951 IPW_DEBUG_INFO("Microcode is not alive\n");
2952 rc = -EINVAL;
2953 }
2954 } else {
2955 IPW_DEBUG_INFO("No alive response from DINO\n");
2956 rc = -ETIME;
2957 }
2958
2959 /* disable DINO, otherwise for some reason
2960 firmware have problem getting alive resp. */
b095c381 2961 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
43f66a6c 2962
0edd5b44 2963// spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
2964
2965 return rc;
2966}
2967
0edd5b44 2968static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c
JK
2969{
2970 int rc = -1;
2971 int offset = 0;
2972 struct fw_chunk *chunk;
2973 dma_addr_t shared_phys;
2974 u8 *shared_virt;
2975
2976 IPW_DEBUG_TRACE("<< : \n");
2977 shared_virt = pci_alloc_consistent(priv->pci_dev, len, &shared_phys);
2978
2979 if (!shared_virt)
2980 return -ENOMEM;
2981
2982 memmove(shared_virt, data, len);
2983
2984 /* Start the Dma */
2985 rc = ipw_fw_dma_enable(priv);
2986
2987 if (priv->sram_desc.last_cb_index > 0) {
2988 /* the DMA is already ready this would be a bug. */
2989 BUG();
2990 goto out;
2991 }
2992
2993 do {
2994 chunk = (struct fw_chunk *)(data + offset);
2995 offset += sizeof(struct fw_chunk);
2996 /* build DMA packet and queue up for sending */
bf79451e 2997 /* dma to chunk->address, the chunk->length bytes from data +
43f66a6c
JK
2998 * offeset*/
2999 /* Dma loading */
3000 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
a613bffd
JK
3001 le32_to_cpu(chunk->address),
3002 le32_to_cpu(chunk->length));
43f66a6c
JK
3003 if (rc) {
3004 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
3005 goto out;
3006 }
bf79451e 3007
a613bffd 3008 offset += le32_to_cpu(chunk->length);
43f66a6c
JK
3009 } while (offset < len);
3010
0edd5b44 3011 /* Run the DMA and wait for the answer */
43f66a6c
JK
3012 rc = ipw_fw_dma_kick(priv);
3013 if (rc) {
3014 IPW_ERROR("dmaKick Failed\n");
3015 goto out;
3016 }
3017
3018 rc = ipw_fw_dma_wait(priv);
3019 if (rc) {
3020 IPW_ERROR("dmaWaitSync Failed\n");
3021 goto out;
3022 }
0edd5b44
JG
3023 out:
3024 pci_free_consistent(priv->pci_dev, len, shared_virt, shared_phys);
43f66a6c
JK
3025 return rc;
3026}
3027
3028/* stop nic */
3029static int ipw_stop_nic(struct ipw_priv *priv)
3030{
3031 int rc = 0;
3032
0edd5b44 3033 /* stop */
b095c381 3034 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
bf79451e 3035
b095c381
JK
3036 rc = ipw_poll_bit(priv, IPW_RESET_REG,
3037 IPW_RESET_REG_MASTER_DISABLED, 500);
43f66a6c
JK
3038 if (rc < 0) {
3039 IPW_ERROR("wait for reg master disabled failed\n");
3040 return rc;
bf79451e 3041 }
43f66a6c 3042
b095c381 3043 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
bf79451e 3044
43f66a6c
JK
3045 return rc;
3046}
3047
3048static void ipw_start_nic(struct ipw_priv *priv)
3049{
3050 IPW_DEBUG_TRACE(">>\n");
3051
0edd5b44 3052 /* prvHwStartNic release ARC */
b095c381
JK
3053 ipw_clear_bit(priv, IPW_RESET_REG,
3054 IPW_RESET_REG_MASTER_DISABLED |
3055 IPW_RESET_REG_STOP_MASTER |
43f66a6c 3056 CBD_RESET_REG_PRINCETON_RESET);
bf79451e 3057
43f66a6c 3058 /* enable power management */
b095c381
JK
3059 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
3060 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
43f66a6c
JK
3061
3062 IPW_DEBUG_TRACE("<<\n");
3063}
bf79451e 3064
43f66a6c
JK
3065static int ipw_init_nic(struct ipw_priv *priv)
3066{
3067 int rc;
3068
3069 IPW_DEBUG_TRACE(">>\n");
bf79451e 3070 /* reset */
43f66a6c
JK
3071 /*prvHwInitNic */
3072 /* set "initialization complete" bit to move adapter to D0 state */
b095c381 3073 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
43f66a6c
JK
3074
3075 /* low-level PLL activation */
b095c381
JK
3076 ipw_write32(priv, IPW_READ_INT_REGISTER,
3077 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
43f66a6c
JK
3078
3079 /* wait for clock stabilization */
b095c381
JK
3080 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
3081 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
0edd5b44 3082 if (rc < 0)
43f66a6c
JK
3083 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
3084
3085 /* assert SW reset */
b095c381 3086 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
43f66a6c
JK
3087
3088 udelay(10);
3089
3090 /* set "initialization complete" bit to move adapter to D0 state */
b095c381 3091 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
43f66a6c
JK
3092
3093 IPW_DEBUG_TRACE(">>\n");
3094 return 0;
3095}
3096
bf79451e 3097/* Call this function from process context, it will sleep in request_firmware.
43f66a6c
JK
3098 * Probe is an ok place to call this from.
3099 */
3100static int ipw_reset_nic(struct ipw_priv *priv)
3101{
3102 int rc = 0;
a613bffd 3103 unsigned long flags;
43f66a6c
JK
3104
3105 IPW_DEBUG_TRACE(">>\n");
bf79451e 3106
43f66a6c 3107 rc = ipw_init_nic(priv);
bf79451e 3108
a613bffd 3109 spin_lock_irqsave(&priv->lock, flags);
43f66a6c
JK
3110 /* Clear the 'host command active' bit... */
3111 priv->status &= ~STATUS_HCMD_ACTIVE;
3112 wake_up_interruptible(&priv->wait_command_queue);
afbf30a2
JK
3113 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3114 wake_up_interruptible(&priv->wait_state);
a613bffd 3115 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
3116
3117 IPW_DEBUG_TRACE("<<\n");
3118 return rc;
bf79451e 3119}
43f66a6c 3120
bf79451e 3121static int ipw_get_fw(struct ipw_priv *priv,
43f66a6c
JK
3122 const struct firmware **fw, const char *name)
3123{
3124 struct fw_header *header;
3125 int rc;
3126
3127 /* ask firmware_class module to get the boot firmware off disk */
3128 rc = request_firmware(fw, name, &priv->pci_dev->dev);
3129 if (rc < 0) {
3130 IPW_ERROR("%s load failed: Reason %d\n", name, rc);
3131 return rc;
bf79451e 3132 }
43f66a6c
JK
3133
3134 header = (struct fw_header *)(*fw)->data;
a613bffd 3135 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
43f66a6c
JK
3136 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
3137 name,
a613bffd
JK
3138 IPW_FW_MAJOR(le32_to_cpu(header->version)),
3139 IPW_FW_MAJOR_VERSION);
43f66a6c
JK
3140 return -EINVAL;
3141 }
3142
aaa4d308 3143 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
43f66a6c 3144 name,
a613bffd
JK
3145 IPW_FW_MAJOR(le32_to_cpu(header->version)),
3146 IPW_FW_MINOR(le32_to_cpu(header->version)),
43f66a6c
JK
3147 (*fw)->size - sizeof(struct fw_header));
3148 return 0;
3149}
3150
b095c381 3151#define IPW_RX_BUF_SIZE (3000)
43f66a6c
JK
3152
3153static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
3154 struct ipw_rx_queue *rxq)
3155{
3156 unsigned long flags;
3157 int i;
3158
3159 spin_lock_irqsave(&rxq->lock, flags);
3160
3161 INIT_LIST_HEAD(&rxq->rx_free);
3162 INIT_LIST_HEAD(&rxq->rx_used);
3163
3164 /* Fill the rx_used queue with _all_ of the Rx buffers */
3165 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
3166 /* In the reset function, these buffers may have been allocated
3167 * to an SKB, so we need to unmap and free potential storage */
3168 if (rxq->pool[i].skb != NULL) {
3169 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
b095c381 3170 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c 3171 dev_kfree_skb(rxq->pool[i].skb);
a613bffd 3172 rxq->pool[i].skb = NULL;
43f66a6c
JK
3173 }
3174 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
3175 }
bf79451e 3176
43f66a6c
JK
3177 /* Set us so that we have processed and used all buffers, but have
3178 * not restocked the Rx queue with fresh buffers */
3179 rxq->read = rxq->write = 0;
3180 rxq->processed = RX_QUEUE_SIZE - 1;
3181 rxq->free_count = 0;
3182 spin_unlock_irqrestore(&rxq->lock, flags);
3183}
3184
3185#ifdef CONFIG_PM
3186static int fw_loaded = 0;
3187static const struct firmware *bootfw = NULL;
3188static const struct firmware *firmware = NULL;
3189static const struct firmware *ucode = NULL;
afbf30a2
JK
3190
3191static void free_firmware(void)
3192{
3193 if (fw_loaded) {
3194 release_firmware(bootfw);
3195 release_firmware(ucode);
3196 release_firmware(firmware);
3197 bootfw = ucode = firmware = NULL;
3198 fw_loaded = 0;
3199 }
3200}
3201#else
3202#define free_firmware() do {} while (0)
43f66a6c
JK
3203#endif
3204
3205static int ipw_load(struct ipw_priv *priv)
3206{
3207#ifndef CONFIG_PM
3208 const struct firmware *bootfw = NULL;
3209 const struct firmware *firmware = NULL;
3210 const struct firmware *ucode = NULL;
3211#endif
3212 int rc = 0, retries = 3;
3213
3214#ifdef CONFIG_PM
3215 if (!fw_loaded) {
3216#endif
3217 rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
bf79451e 3218 if (rc)
43f66a6c 3219 goto error;
bf79451e 3220
43f66a6c
JK
3221 switch (priv->ieee->iw_mode) {
3222 case IW_MODE_ADHOC:
bf79451e 3223 rc = ipw_get_fw(priv, &ucode,
43f66a6c 3224 IPW_FW_NAME("ibss_ucode"));
bf79451e 3225 if (rc)
43f66a6c 3226 goto error;
bf79451e 3227
43f66a6c
JK
3228 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
3229 break;
bf79451e 3230
b095c381 3231#ifdef CONFIG_IPW2200_MONITOR
43f66a6c 3232 case IW_MODE_MONITOR:
bf79451e 3233 rc = ipw_get_fw(priv, &ucode,
ea2b26e0 3234 IPW_FW_NAME("sniffer_ucode"));
bf79451e 3235 if (rc)
43f66a6c 3236 goto error;
bf79451e 3237
0edd5b44
JG
3238 rc = ipw_get_fw(priv, &firmware,
3239 IPW_FW_NAME("sniffer"));
43f66a6c
JK
3240 break;
3241#endif
3242 case IW_MODE_INFRA:
0edd5b44 3243 rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode"));
bf79451e 3244 if (rc)
43f66a6c 3245 goto error;
bf79451e 3246
43f66a6c
JK
3247 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss"));
3248 break;
bf79451e 3249
43f66a6c
JK
3250 default:
3251 rc = -EINVAL;
3252 }
3253
bf79451e 3254 if (rc)
43f66a6c
JK
3255 goto error;
3256
3257#ifdef CONFIG_PM
3258 fw_loaded = 1;
3259 }
3260#endif
3261
3262 if (!priv->rxq)
3263 priv->rxq = ipw_rx_queue_alloc(priv);
3264 else
3265 ipw_rx_queue_reset(priv, priv->rxq);
3266 if (!priv->rxq) {
3267 IPW_ERROR("Unable to initialize Rx queue\n");
3268 goto error;
3269 }
3270
0edd5b44 3271 retry:
43f66a6c 3272 /* Ensure interrupts are disabled */
b095c381 3273 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
43f66a6c
JK
3274 priv->status &= ~STATUS_INT_ENABLED;
3275
3276 /* ack pending interrupts */
b095c381 3277 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
bf79451e 3278
43f66a6c
JK
3279 ipw_stop_nic(priv);
3280
3281 rc = ipw_reset_nic(priv);
3282 if (rc) {
3283 IPW_ERROR("Unable to reset NIC\n");
3284 goto error;
3285 }
3286
b095c381
JK
3287 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
3288 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
43f66a6c
JK
3289
3290 /* DMA the initial boot firmware into the device */
bf79451e 3291 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
43f66a6c
JK
3292 bootfw->size - sizeof(struct fw_header));
3293 if (rc < 0) {
a4f6bbb3 3294 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
43f66a6c
JK
3295 goto error;
3296 }
3297
3298 /* kick start the device */
3299 ipw_start_nic(priv);
3300
3301 /* wait for the device to finish it's initial startup sequence */
b095c381
JK
3302 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3303 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c
JK
3304 if (rc < 0) {
3305 IPW_ERROR("device failed to boot initial fw image\n");
3306 goto error;
3307 }
3308 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
3309
bf79451e 3310 /* ack fw init done interrupt */
b095c381 3311 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
43f66a6c
JK
3312
3313 /* DMA the ucode into the device */
bf79451e 3314 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
43f66a6c
JK
3315 ucode->size - sizeof(struct fw_header));
3316 if (rc < 0) {
a4f6bbb3 3317 IPW_ERROR("Unable to load ucode: %d\n", rc);
43f66a6c
JK
3318 goto error;
3319 }
bf79451e 3320
43f66a6c
JK
3321 /* stop nic */
3322 ipw_stop_nic(priv);
3323
3324 /* DMA bss firmware into the device */
bf79451e
JG
3325 rc = ipw_load_firmware(priv, firmware->data +
3326 sizeof(struct fw_header),
43f66a6c 3327 firmware->size - sizeof(struct fw_header));
0edd5b44 3328 if (rc < 0) {
a4f6bbb3 3329 IPW_ERROR("Unable to load firmware: %d\n", rc);
43f66a6c
JK
3330 goto error;
3331 }
3332
3333 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
3334
3335 rc = ipw_queue_reset(priv);
3336 if (rc) {
3337 IPW_ERROR("Unable to initialize queues\n");
3338 goto error;
3339 }
3340
3341 /* Ensure interrupts are disabled */
b095c381 3342 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
c848d0af 3343 /* ack pending interrupts */
b095c381 3344 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
bf79451e 3345
43f66a6c
JK
3346 /* kick start the device */
3347 ipw_start_nic(priv);
3348
b095c381 3349 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
43f66a6c
JK
3350 if (retries > 0) {
3351 IPW_WARNING("Parity error. Retrying init.\n");
3352 retries--;
3353 goto retry;
3354 }
3355
3356 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");
3357 rc = -EIO;
3358 goto error;
3359 }
3360
3361 /* wait for the device */
b095c381
JK
3362 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3363 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c
JK
3364 if (rc < 0) {
3365 IPW_ERROR("device failed to start after 500ms\n");
3366 goto error;
3367 }
3368 IPW_DEBUG_INFO("device response after %dms\n", rc);
3369
3370 /* ack fw init done interrupt */
b095c381 3371 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
43f66a6c
JK
3372
3373 /* read eeprom data and initialize the eeprom region of sram */
3374 priv->eeprom_delay = 1;
bf79451e 3375 ipw_eeprom_init_sram(priv);
43f66a6c
JK
3376
3377 /* enable interrupts */
3378 ipw_enable_interrupts(priv);
3379
3380 /* Ensure our queue has valid packets */
3381 ipw_rx_queue_replenish(priv);
3382
b095c381 3383 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
43f66a6c
JK
3384
3385 /* ack pending interrupts */
b095c381 3386 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
43f66a6c
JK
3387
3388#ifndef CONFIG_PM
3389 release_firmware(bootfw);
3390 release_firmware(ucode);
3391 release_firmware(firmware);
3392#endif
3393 return 0;
3394
0edd5b44 3395 error:
43f66a6c
JK
3396 if (priv->rxq) {
3397 ipw_rx_queue_free(priv, priv->rxq);
3398 priv->rxq = NULL;
3399 }
3400 ipw_tx_queue_free(priv);
3401 if (bootfw)
3402 release_firmware(bootfw);
3403 if (ucode)
3404 release_firmware(ucode);
3405 if (firmware)
3406 release_firmware(firmware);
3407#ifdef CONFIG_PM
3408 fw_loaded = 0;
3409 bootfw = ucode = firmware = NULL;
3410#endif
3411
3412 return rc;
3413}
3414
bf79451e 3415/**
43f66a6c
JK
3416 * DMA services
3417 *
3418 * Theory of operation
3419 *
3420 * A queue is a circular buffers with 'Read' and 'Write' pointers.
3421 * 2 empty entries always kept in the buffer to protect from overflow.
3422 *
3423 * For Tx queue, there are low mark and high mark limits. If, after queuing
bf79451e
JG
3424 * the packet for Tx, free space become < low mark, Tx queue stopped. When
3425 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
43f66a6c
JK
3426 * Tx queue resumed.
3427 *
3428 * The IPW operates with six queues, one receive queue in the device's
3429 * sram, one transmit queue for sending commands to the device firmware,
bf79451e 3430 * and four transmit queues for data.
43f66a6c 3431 *
bf79451e 3432 * The four transmit queues allow for performing quality of service (qos)
43f66a6c 3433 * transmissions as per the 802.11 protocol. Currently Linux does not
bf79451e 3434 * provide a mechanism to the user for utilizing prioritized queues, so
43f66a6c
JK
3435 * we only utilize the first data transmit queue (queue1).
3436 */
3437
3438/**
3439 * Driver allocates buffers of this size for Rx
3440 */
3441
3442static inline int ipw_queue_space(const struct clx2_queue *q)
3443{
3444 int s = q->last_used - q->first_empty;
3445 if (s <= 0)
3446 s += q->n_bd;
3447 s -= 2; /* keep some reserve to not confuse empty and full situations */
3448 if (s < 0)
3449 s = 0;
3450 return s;
3451}
3452
3453static inline int ipw_queue_inc_wrap(int index, int n_bd)
3454{
3455 return (++index == n_bd) ? 0 : index;
3456}
3457
3458/**
3459 * Initialize common DMA queue structure
bf79451e 3460 *
43f66a6c
JK
3461 * @param q queue to init
3462 * @param count Number of BD's to allocate. Should be power of 2
3463 * @param read_register Address for 'read' register
3464 * (not offset within BAR, full address)
3465 * @param write_register Address for 'write' register
3466 * (not offset within BAR, full address)
3467 * @param base_register Address for 'base' register
3468 * (not offset within BAR, full address)
3469 * @param size Address for 'size' register
3470 * (not offset within BAR, full address)
3471 */
bf79451e 3472static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,
0edd5b44 3473 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3474{
3475 q->n_bd = count;
3476
3477 q->low_mark = q->n_bd / 4;
3478 if (q->low_mark < 4)
3479 q->low_mark = 4;
3480
3481 q->high_mark = q->n_bd / 8;
3482 if (q->high_mark < 2)
3483 q->high_mark = 2;
3484
3485 q->first_empty = q->last_used = 0;
3486 q->reg_r = read;
3487 q->reg_w = write;
3488
3489 ipw_write32(priv, base, q->dma_addr);
3490 ipw_write32(priv, size, count);
3491 ipw_write32(priv, read, 0);
3492 ipw_write32(priv, write, 0);
3493
3494 _ipw_read32(priv, 0x90);
3495}
3496
bf79451e 3497static int ipw_queue_tx_init(struct ipw_priv *priv,
43f66a6c 3498 struct clx2_tx_queue *q,
0edd5b44 3499 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3500{
3501 struct pci_dev *dev = priv->pci_dev;
3502
3503 q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL);
3504 if (!q->txb) {
3505 IPW_ERROR("vmalloc for auxilary BD structures failed\n");
3506 return -ENOMEM;
3507 }
3508
0edd5b44
JG
3509 q->bd =
3510 pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr);
43f66a6c 3511 if (!q->bd) {
aaa4d308 3512 IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
0edd5b44 3513 sizeof(q->bd[0]) * count);
43f66a6c
JK
3514 kfree(q->txb);
3515 q->txb = NULL;
3516 return -ENOMEM;
3517 }
3518
3519 ipw_queue_init(priv, &q->q, count, read, write, base, size);
3520 return 0;
3521}
3522
3523/**
3524 * Free one TFD, those at index [txq->q.last_used].
3525 * Do NOT advance any indexes
bf79451e 3526 *
43f66a6c
JK
3527 * @param dev
3528 * @param txq
3529 */
3530static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
3531 struct clx2_tx_queue *txq)
3532{
3533 struct tfd_frame *bd = &txq->bd[txq->q.last_used];
3534 struct pci_dev *dev = priv->pci_dev;
3535 int i;
bf79451e 3536
43f66a6c
JK
3537 /* classify bd */
3538 if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE)
3539 /* nothing to cleanup after for host commands */
3540 return;
3541
3542 /* sanity check */
a613bffd
JK
3543 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
3544 IPW_ERROR("Too many chunks: %i\n",
3545 le32_to_cpu(bd->u.data.num_chunks));
43f66a6c
JK
3546 /** @todo issue fatal error, it is quite serious situation */
3547 return;
3548 }
3549
3550 /* unmap chunks if any */
a613bffd
JK
3551 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
3552 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
3553 le16_to_cpu(bd->u.data.chunk_len[i]),
3554 PCI_DMA_TODEVICE);
43f66a6c
JK
3555 if (txq->txb[txq->q.last_used]) {
3556 ieee80211_txb_free(txq->txb[txq->q.last_used]);
3557 txq->txb[txq->q.last_used] = NULL;
3558 }
3559 }
3560}
3561
3562/**
3563 * Deallocate DMA queue.
bf79451e 3564 *
43f66a6c
JK
3565 * Empty queue by removing and destroying all BD's.
3566 * Free all buffers.
bf79451e 3567 *
43f66a6c
JK
3568 * @param dev
3569 * @param q
3570 */
0edd5b44 3571static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)
43f66a6c
JK
3572{
3573 struct clx2_queue *q = &txq->q;
3574 struct pci_dev *dev = priv->pci_dev;
3575
bf79451e
JG
3576 if (q->n_bd == 0)
3577 return;
43f66a6c
JK
3578
3579 /* first, empty all BD's */
3580 for (; q->first_empty != q->last_used;
3581 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
3582 ipw_queue_tx_free_tfd(priv, txq);
3583 }
bf79451e 3584
43f66a6c 3585 /* free buffers belonging to queue itself */
0edd5b44 3586 pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
43f66a6c
JK
3587 q->dma_addr);
3588 kfree(txq->txb);
3589
3590 /* 0 fill whole structure */
3591 memset(txq, 0, sizeof(*txq));
3592}
3593
43f66a6c
JK
3594/**
3595 * Destroy all DMA queues and structures
bf79451e 3596 *
43f66a6c
JK
3597 * @param priv
3598 */
3599static void ipw_tx_queue_free(struct ipw_priv *priv)
3600{
3601 /* Tx CMD queue */
3602 ipw_queue_tx_free(priv, &priv->txq_cmd);
3603
3604 /* Tx queues */
3605 ipw_queue_tx_free(priv, &priv->txq[0]);
3606 ipw_queue_tx_free(priv, &priv->txq[1]);
3607 ipw_queue_tx_free(priv, &priv->txq[2]);
3608 ipw_queue_tx_free(priv, &priv->txq[3]);
3609}
3610
0edd5b44 3611static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3612{
3613 /* First 3 bytes are manufacturer */
3614 bssid[0] = priv->mac_addr[0];
3615 bssid[1] = priv->mac_addr[1];
3616 bssid[2] = priv->mac_addr[2];
3617
3618 /* Last bytes are random */
0edd5b44 3619 get_random_bytes(&bssid[3], ETH_ALEN - 3);
43f66a6c 3620
0edd5b44
JG
3621 bssid[0] &= 0xfe; /* clear multicast bit */
3622 bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */
43f66a6c
JK
3623}
3624
0edd5b44 3625static inline u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3626{
3627 struct ipw_station_entry entry;
3628 int i;
3629
3630 for (i = 0; i < priv->num_stations; i++) {
3631 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
3632 /* Another node is active in network */
3633 priv->missed_adhoc_beacons = 0;
3634 if (!(priv->config & CFG_STATIC_CHANNEL))
3635 /* when other nodes drop out, we drop out */
3636 priv->config &= ~CFG_ADHOC_PERSIST;
3637
3638 return i;
3639 }
3640 }
3641
3642 if (i == MAX_STATIONS)
3643 return IPW_INVALID_STATION;
3644
3645 IPW_DEBUG_SCAN("Adding AdHoc station: " MAC_FMT "\n", MAC_ARG(bssid));
3646
3647 entry.reserved = 0;
3648 entry.support_mode = 0;
3649 memcpy(entry.mac_addr, bssid, ETH_ALEN);
3650 memcpy(priv->stations[i], bssid, ETH_ALEN);
3651 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),
0edd5b44 3652 &entry, sizeof(entry));
43f66a6c
JK
3653 priv->num_stations++;
3654
3655 return i;
3656}
3657
0edd5b44 3658static inline u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3659{
3660 int i;
3661
bf79451e
JG
3662 for (i = 0; i < priv->num_stations; i++)
3663 if (!memcmp(priv->stations[i], bssid, ETH_ALEN))
43f66a6c
JK
3664 return i;
3665
3666 return IPW_INVALID_STATION;
3667}
3668
3669static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
3670{
3671 int err;
3672
7b99659f
HL
3673 if (priv->status & STATUS_ASSOCIATING) {
3674 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
3675 queue_work(priv->workqueue, &priv->disassociate);
3676 return;
3677 }
3678
3679 if (!(priv->status & STATUS_ASSOCIATED)) {
43f66a6c
JK
3680 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
3681 return;
3682 }
3683
3684 IPW_DEBUG_ASSOC("Disassocation attempt from " MAC_FMT " "
3685 "on channel %d.\n",
bf79451e 3686 MAC_ARG(priv->assoc_request.bssid),
43f66a6c
JK
3687 priv->assoc_request.channel);
3688
e6324726
HL
3689 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
3690 priv->status |= STATUS_DISASSOCIATING;
3691
43f66a6c
JK
3692 if (quiet)
3693 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
3694 else
3695 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
e6324726 3696
43f66a6c
JK
3697 err = ipw_send_associate(priv, &priv->assoc_request);
3698 if (err) {
3699 IPW_DEBUG_HC("Attempt to send [dis]associate command "
3700 "failed.\n");
3701 return;
3702 }
3703
3704}
3705
c848d0af 3706static int ipw_disassociate(void *data)
43f66a6c 3707{
c848d0af
JK
3708 struct ipw_priv *priv = data;
3709 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3710 return 0;
43f66a6c 3711 ipw_send_disassociate(data, 0);
c848d0af
JK
3712 return 1;
3713}
3714
3715static void ipw_bg_disassociate(void *data)
3716{
3717 struct ipw_priv *priv = data;
3718 down(&priv->sem);
3719 ipw_disassociate(data);
3720 up(&priv->sem);
43f66a6c
JK
3721}
3722
d8bad6df
ZY
3723static void ipw_system_config(void *data)
3724{
3725 struct ipw_priv *priv = data;
3726 ipw_send_system_config(priv, &priv->sys_config);
3727}
3728
43f66a6c
JK
3729struct ipw_status_code {
3730 u16 status;
3731 const char *reason;
3732};
3733
3734static const struct ipw_status_code ipw_status_codes[] = {
3735 {0x00, "Successful"},
3736 {0x01, "Unspecified failure"},
3737 {0x0A, "Cannot support all requested capabilities in the "
3738 "Capability information field"},
3739 {0x0B, "Reassociation denied due to inability to confirm that "
3740 "association exists"},
3741 {0x0C, "Association denied due to reason outside the scope of this "
3742 "standard"},
0edd5b44
JG
3743 {0x0D,
3744 "Responding station does not support the specified authentication "
43f66a6c 3745 "algorithm"},
0edd5b44
JG
3746 {0x0E,
3747 "Received an Authentication frame with authentication sequence "
43f66a6c
JK
3748 "transaction sequence number out of expected sequence"},
3749 {0x0F, "Authentication rejected because of challenge failure"},
3750 {0x10, "Authentication rejected due to timeout waiting for next "
3751 "frame in sequence"},
3752 {0x11, "Association denied because AP is unable to handle additional "
3753 "associated stations"},
0edd5b44
JG
3754 {0x12,
3755 "Association denied due to requesting station not supporting all "
43f66a6c 3756 "of the datarates in the BSSBasicServiceSet Parameter"},
0edd5b44
JG
3757 {0x13,
3758 "Association denied due to requesting station not supporting "
43f66a6c 3759 "short preamble operation"},
0edd5b44
JG
3760 {0x14,
3761 "Association denied due to requesting station not supporting "
43f66a6c 3762 "PBCC encoding"},
0edd5b44
JG
3763 {0x15,
3764 "Association denied due to requesting station not supporting "
43f66a6c 3765 "channel agility"},
0edd5b44
JG
3766 {0x19,
3767 "Association denied due to requesting station not supporting "
43f66a6c 3768 "short slot operation"},
0edd5b44
JG
3769 {0x1A,
3770 "Association denied due to requesting station not supporting "
43f66a6c
JK
3771 "DSSS-OFDM operation"},
3772 {0x28, "Invalid Information Element"},
3773 {0x29, "Group Cipher is not valid"},
3774 {0x2A, "Pairwise Cipher is not valid"},
3775 {0x2B, "AKMP is not valid"},
3776 {0x2C, "Unsupported RSN IE version"},
3777 {0x2D, "Invalid RSN IE Capabilities"},
3778 {0x2E, "Cipher suite is rejected per security policy"},
3779};
3780
3781#ifdef CONFIG_IPW_DEBUG
bf79451e 3782static const char *ipw_get_status_code(u16 status)
43f66a6c
JK
3783{
3784 int i;
bf79451e 3785 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
ea2b26e0 3786 if (ipw_status_codes[i].status == (status & 0xff))
43f66a6c
JK
3787 return ipw_status_codes[i].reason;
3788 return "Unknown status value.";
3789}
3790#endif
3791
3792static void inline average_init(struct average *avg)
3793{
3794 memset(avg, 0, sizeof(*avg));
3795}
3796
3797static void inline average_add(struct average *avg, s16 val)
3798{
3799 avg->sum -= avg->entries[avg->pos];
3800 avg->sum += val;
3801 avg->entries[avg->pos++] = val;
3802 if (unlikely(avg->pos == AVG_ENTRIES)) {
3803 avg->init = 1;
3804 avg->pos = 0;
3805 }
3806}
3807
3808static s16 inline average_value(struct average *avg)
3809{
3810 if (!unlikely(avg->init)) {
3811 if (avg->pos)
3812 return avg->sum / avg->pos;
3813 return 0;
3814 }
3815
3816 return avg->sum / AVG_ENTRIES;
3817}
3818
3819static void ipw_reset_stats(struct ipw_priv *priv)
3820{
3821 u32 len = sizeof(u32);
3822
3823 priv->quality = 0;
3824
3825 average_init(&priv->average_missed_beacons);
3826 average_init(&priv->average_rssi);
3827 average_init(&priv->average_noise);
3828
3829 priv->last_rate = 0;
3830 priv->last_missed_beacons = 0;
3831 priv->last_rx_packets = 0;
3832 priv->last_tx_packets = 0;
3833 priv->last_tx_failures = 0;
bf79451e 3834
43f66a6c
JK
3835 /* Firmware managed, reset only when NIC is restarted, so we have to
3836 * normalize on the current value */
bf79451e 3837 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,
43f66a6c 3838 &priv->last_rx_err, &len);
bf79451e 3839 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,
43f66a6c
JK
3840 &priv->last_tx_failures, &len);
3841
3842 /* Driver managed, reset with each association */
3843 priv->missed_adhoc_beacons = 0;
3844 priv->missed_beacons = 0;
3845 priv->tx_packets = 0;
3846 priv->rx_packets = 0;
3847
3848}
3849
43f66a6c
JK
3850static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3851{
3852 u32 i = 0x80000000;
3853 u32 mask = priv->rates_mask;
3854 /* If currently associated in B mode, restrict the maximum
3855 * rate match to B rates */
3856 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
3857 mask &= IEEE80211_CCK_RATES_MASK;
3858
3859 /* TODO: Verify that the rate is supported by the current rates
3860 * list. */
3861
0edd5b44
JG
3862 while (i && !(mask & i))
3863 i >>= 1;
43f66a6c 3864 switch (i) {
ea2b26e0
JK
3865 case IEEE80211_CCK_RATE_1MB_MASK:
3866 return 1000000;
3867 case IEEE80211_CCK_RATE_2MB_MASK:
3868 return 2000000;
3869 case IEEE80211_CCK_RATE_5MB_MASK:
3870 return 5500000;
3871 case IEEE80211_OFDM_RATE_6MB_MASK:
3872 return 6000000;
3873 case IEEE80211_OFDM_RATE_9MB_MASK:
3874 return 9000000;
3875 case IEEE80211_CCK_RATE_11MB_MASK:
3876 return 11000000;
3877 case IEEE80211_OFDM_RATE_12MB_MASK:
3878 return 12000000;
3879 case IEEE80211_OFDM_RATE_18MB_MASK:
3880 return 18000000;
3881 case IEEE80211_OFDM_RATE_24MB_MASK:
3882 return 24000000;
3883 case IEEE80211_OFDM_RATE_36MB_MASK:
3884 return 36000000;
3885 case IEEE80211_OFDM_RATE_48MB_MASK:
3886 return 48000000;
3887 case IEEE80211_OFDM_RATE_54MB_MASK:
3888 return 54000000;
43f66a6c
JK
3889 }
3890
bf79451e 3891 if (priv->ieee->mode == IEEE_B)
43f66a6c
JK
3892 return 11000000;
3893 else
3894 return 54000000;
3895}
3896
3897static u32 ipw_get_current_rate(struct ipw_priv *priv)
3898{
3899 u32 rate, len = sizeof(rate);
3900 int err;
3901
bf79451e 3902 if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c
JK
3903 return 0;
3904
3905 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {
bf79451e 3906 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,
43f66a6c
JK
3907 &len);
3908 if (err) {
3909 IPW_DEBUG_INFO("failed querying ordinals.\n");
3910 return 0;
3911 }
bf79451e 3912 } else
43f66a6c
JK
3913 return ipw_get_max_rate(priv);
3914
3915 switch (rate) {
ea2b26e0
JK
3916 case IPW_TX_RATE_1MB:
3917 return 1000000;
3918 case IPW_TX_RATE_2MB:
3919 return 2000000;
3920 case IPW_TX_RATE_5MB:
3921 return 5500000;
3922 case IPW_TX_RATE_6MB:
3923 return 6000000;
3924 case IPW_TX_RATE_9MB:
3925 return 9000000;
3926 case IPW_TX_RATE_11MB:
3927 return 11000000;
3928 case IPW_TX_RATE_12MB:
3929 return 12000000;
3930 case IPW_TX_RATE_18MB:
3931 return 18000000;
3932 case IPW_TX_RATE_24MB:
3933 return 24000000;
3934 case IPW_TX_RATE_36MB:
3935 return 36000000;
3936 case IPW_TX_RATE_48MB:
3937 return 48000000;
3938 case IPW_TX_RATE_54MB:
3939 return 54000000;
43f66a6c
JK
3940 }
3941
3942 return 0;
3943}
3944
43f66a6c
JK
3945#define IPW_STATS_INTERVAL (2 * HZ)
3946static void ipw_gather_stats(struct ipw_priv *priv)
3947{
3948 u32 rx_err, rx_err_delta, rx_packets_delta;
3949 u32 tx_failures, tx_failures_delta, tx_packets_delta;
3950 u32 missed_beacons_percent, missed_beacons_delta;
3951 u32 quality = 0;
3952 u32 len = sizeof(u32);
3953 s16 rssi;
bf79451e 3954 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
0edd5b44 3955 rate_quality;
ea2b26e0 3956 u32 max_rate;
43f66a6c
JK
3957
3958 if (!(priv->status & STATUS_ASSOCIATED)) {
3959 priv->quality = 0;
3960 return;
3961 }
3962
3963 /* Update the statistics */
bf79451e 3964 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,
43f66a6c 3965 &priv->missed_beacons, &len);
0edd5b44 3966 missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons;
43f66a6c
JK
3967 priv->last_missed_beacons = priv->missed_beacons;
3968 if (priv->assoc_request.beacon_interval) {
3969 missed_beacons_percent = missed_beacons_delta *
0edd5b44
JG
3970 (HZ * priv->assoc_request.beacon_interval) /
3971 (IPW_STATS_INTERVAL * 10);
43f66a6c
JK
3972 } else {
3973 missed_beacons_percent = 0;
3974 }
3975 average_add(&priv->average_missed_beacons, missed_beacons_percent);
3976
3977 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);
3978 rx_err_delta = rx_err - priv->last_rx_err;
3979 priv->last_rx_err = rx_err;
3980
3981 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);
3982 tx_failures_delta = tx_failures - priv->last_tx_failures;
3983 priv->last_tx_failures = tx_failures;
3984
3985 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;
3986 priv->last_rx_packets = priv->rx_packets;
3987
3988 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;
3989 priv->last_tx_packets = priv->tx_packets;
3990
3991 /* Calculate quality based on the following:
bf79451e 3992 *
43f66a6c
JK
3993 * Missed beacon: 100% = 0, 0% = 70% missed
3994 * Rate: 60% = 1Mbs, 100% = Max
3995 * Rx and Tx errors represent a straight % of total Rx/Tx
3996 * RSSI: 100% = > -50, 0% = < -80
3997 * Rx errors: 100% = 0, 0% = 50% missed
bf79451e 3998 *
43f66a6c
JK
3999 * The lowest computed quality is used.
4000 *
4001 */
4002#define BEACON_THRESHOLD 5
4003 beacon_quality = 100 - missed_beacons_percent;
4004 if (beacon_quality < BEACON_THRESHOLD)
4005 beacon_quality = 0;
4006 else
bf79451e 4007 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /
0edd5b44 4008 (100 - BEACON_THRESHOLD);
bf79451e 4009 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",
43f66a6c 4010 beacon_quality, missed_beacons_percent);
bf79451e 4011
43f66a6c 4012 priv->last_rate = ipw_get_current_rate(priv);
ea2b26e0
JK
4013 max_rate = ipw_get_max_rate(priv);
4014 rate_quality = priv->last_rate * 40 / max_rate + 60;
43f66a6c
JK
4015 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
4016 rate_quality, priv->last_rate / 1000000);
bf79451e 4017
0edd5b44 4018 if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta)
bf79451e 4019 rx_quality = 100 - (rx_err_delta * 100) /
0edd5b44 4020 (rx_packets_delta + rx_err_delta);
43f66a6c
JK
4021 else
4022 rx_quality = 100;
4023 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",
4024 rx_quality, rx_err_delta, rx_packets_delta);
bf79451e 4025
0edd5b44 4026 if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta)
bf79451e 4027 tx_quality = 100 - (tx_failures_delta * 100) /
0edd5b44 4028 (tx_packets_delta + tx_failures_delta);
43f66a6c
JK
4029 else
4030 tx_quality = 100;
4031 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",
4032 tx_quality, tx_failures_delta, tx_packets_delta);
bf79451e 4033
43f66a6c 4034 rssi = average_value(&priv->average_rssi);
c848d0af
JK
4035 signal_quality =
4036 (100 *
4037 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4038 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4039 (priv->ieee->perfect_rssi - rssi) *
4040 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4041 62 * (priv->ieee->perfect_rssi - rssi))) /
4042 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4043 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4044 if (signal_quality > 100)
43f66a6c 4045 signal_quality = 100;
c848d0af 4046 else if (signal_quality < 1)
43f66a6c 4047 signal_quality = 0;
ea2b26e0 4048
43f66a6c
JK
4049 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
4050 signal_quality, rssi);
bf79451e
JG
4051
4052 quality = min(beacon_quality,
43f66a6c
JK
4053 min(rate_quality,
4054 min(tx_quality, min(rx_quality, signal_quality))));
4055 if (quality == beacon_quality)
0edd5b44
JG
4056 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
4057 quality);
43f66a6c 4058 if (quality == rate_quality)
0edd5b44
JG
4059 IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n",
4060 quality);
43f66a6c 4061 if (quality == tx_quality)
0edd5b44
JG
4062 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n",
4063 quality);
43f66a6c 4064 if (quality == rx_quality)
0edd5b44
JG
4065 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n",
4066 quality);
43f66a6c 4067 if (quality == signal_quality)
0edd5b44
JG
4068 IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n",
4069 quality);
43f66a6c
JK
4070
4071 priv->quality = quality;
bf79451e
JG
4072
4073 queue_delayed_work(priv->workqueue, &priv->gather_stats,
43f66a6c
JK
4074 IPW_STATS_INTERVAL);
4075}
4076
c848d0af
JK
4077static void ipw_bg_gather_stats(void *data)
4078{
4079 struct ipw_priv *priv = data;
4080 down(&priv->sem);
4081 ipw_gather_stats(data);
4082 up(&priv->sem);
4083}
4084
e7582561
BC
4085/* Missed beacon behavior:
4086 * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
4087 * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
4088 * Above disassociate threshold, give up and stop scanning.
4089 * Roaming is disabled if disassociate_threshold <= roaming_threshold */
ea2b26e0
JK
4090static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
4091 int missed_count)
4092{
4093 priv->notif_missed_beacons = missed_count;
4094
afbf30a2 4095 if (missed_count > priv->disassociate_threshold &&
ea2b26e0
JK
4096 priv->status & STATUS_ASSOCIATED) {
4097 /* If associated and we've hit the missed
4098 * beacon threshold, disassociate, turn
4099 * off roaming, and abort any active scans */
4100 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
afbf30a2 4101 IPW_DL_STATE | IPW_DL_ASSOC,
ea2b26e0
JK
4102 "Missed beacon: %d - disassociate\n", missed_count);
4103 priv->status &= ~STATUS_ROAMING;
a613bffd
JK
4104 if (priv->status & STATUS_SCANNING) {
4105 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4106 IPW_DL_STATE,
4107 "Aborting scan with missed beacon.\n");
ea2b26e0 4108 queue_work(priv->workqueue, &priv->abort_scan);
a613bffd
JK
4109 }
4110
ea2b26e0
JK
4111 queue_work(priv->workqueue, &priv->disassociate);
4112 return;
4113 }
4114
4115 if (priv->status & STATUS_ROAMING) {
4116 /* If we are currently roaming, then just
4117 * print a debug statement... */
4118 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4119 "Missed beacon: %d - roam in progress\n",
4120 missed_count);
4121 return;
4122 }
4123
e7582561
BC
4124 if (missed_count > priv->roaming_threshold &&
4125 missed_count <= priv->disassociate_threshold) {
ea2b26e0 4126 /* If we are not already roaming, set the ROAM
e7582561
BC
4127 * bit in the status and kick off a scan.
4128 * This can happen several times before we reach
4129 * disassociate_threshold. */
ea2b26e0
JK
4130 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4131 "Missed beacon: %d - initiate "
4132 "roaming\n", missed_count);
4133 if (!(priv->status & STATUS_ROAMING)) {
4134 priv->status |= STATUS_ROAMING;
4135 if (!(priv->status & STATUS_SCANNING))
4136 queue_work(priv->workqueue,
4137 &priv->request_scan);
4138 }
4139 return;
4140 }
4141
4142 if (priv->status & STATUS_SCANNING) {
4143 /* Stop scan to keep fw from getting
4144 * stuck (only if we aren't roaming --
4145 * otherwise we'll never scan more than 2 or 3
4146 * channels..) */
b095c381
JK
4147 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4148 "Aborting scan with missed beacon.\n");
ea2b26e0
JK
4149 queue_work(priv->workqueue, &priv->abort_scan);
4150 }
4151
4152 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4153
4154}
4155
43f66a6c
JK
4156/**
4157 * Handle host notification packet.
4158 * Called from interrupt routine
4159 */
0edd5b44 4160static inline void ipw_rx_notification(struct ipw_priv *priv,
43f66a6c
JK
4161 struct ipw_rx_notification *notif)
4162{
a613bffd
JK
4163 notif->size = le16_to_cpu(notif->size);
4164
0edd5b44 4165 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
bf79451e 4166
43f66a6c 4167 switch (notif->subtype) {
0edd5b44
JG
4168 case HOST_NOTIFICATION_STATUS_ASSOCIATED:{
4169 struct notif_association *assoc = &notif->u.assoc;
4170
4171 switch (assoc->state) {
4172 case CMAS_ASSOCIATED:{
4173 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4174 IPW_DL_ASSOC,
4175 "associated: '%s' " MAC_FMT
4176 " \n",
4177 escape_essid(priv->essid,
4178 priv->essid_len),
4179 MAC_ARG(priv->bssid));
4180
4181 switch (priv->ieee->iw_mode) {
4182 case IW_MODE_INFRA:
4183 memcpy(priv->ieee->bssid,
4184 priv->bssid, ETH_ALEN);
4185 break;
4186
4187 case IW_MODE_ADHOC:
4188 memcpy(priv->ieee->bssid,
4189 priv->bssid, ETH_ALEN);
4190
4191 /* clear out the station table */
4192 priv->num_stations = 0;
4193
4194 IPW_DEBUG_ASSOC
4195 ("queueing adhoc check\n");
4196 queue_delayed_work(priv->
4197 workqueue,
4198 &priv->
4199 adhoc_check,
4200 priv->
4201 assoc_request.
4202 beacon_interval);
4203 break;
4204 }
4205
4206 priv->status &= ~STATUS_ASSOCIATING;
4207 priv->status |= STATUS_ASSOCIATED;
d8bad6df
ZY
4208 queue_work(priv->workqueue,
4209 &priv->system_config);
0edd5b44 4210
b095c381 4211#ifdef CONFIG_IPW_QOS
afbf30a2
JK
4212#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
4213 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
4214 if ((priv->status & STATUS_AUTH) &&
4215 (IPW_GET_PACKET_STYPE(&notif->u.raw)
4216 == IEEE80211_STYPE_ASSOC_RESP)) {
b095c381
JK
4217 if ((sizeof
4218 (struct
2b184d5b 4219 ieee80211_assoc_response)
b095c381
JK
4220 <= notif->size)
4221 && (notif->size <= 2314)) {
4222 struct
4223 ieee80211_rx_stats
4224 stats = {
4225 .len =
4226 notif->
4227 size - 1,
4228 };
4229
4230 IPW_DEBUG_QOS
4231 ("QoS Associate "
4232 "size %d\n",
4233 notif->size);
4234 ieee80211_rx_mgt(priv->
4235 ieee,
4236 (struct
2b184d5b 4237 ieee80211_hdr_4addr
b095c381
JK
4238 *)
4239 &notif->u.raw, &stats);
4240 }
4241 }
4242#endif
4243
a613bffd 4244 schedule_work(&priv->link_up);
0edd5b44 4245
0edd5b44
JG
4246 break;
4247 }
bf79451e 4248
0edd5b44
JG
4249 case CMAS_AUTHENTICATED:{
4250 if (priv->
4251 status & (STATUS_ASSOCIATED |
4252 STATUS_AUTH)) {
43f66a6c 4253#ifdef CONFIG_IPW_DEBUG
0edd5b44
JG
4254 struct notif_authenticate *auth
4255 = &notif->u.auth;
4256 IPW_DEBUG(IPW_DL_NOTIF |
4257 IPW_DL_STATE |
4258 IPW_DL_ASSOC,
4259 "deauthenticated: '%s' "
4260 MAC_FMT
4261 ": (0x%04X) - %s \n",
4262 escape_essid(priv->
4263 essid,
4264 priv->
4265 essid_len),
4266 MAC_ARG(priv->bssid),
4267 ntohs(auth->status),
4268 ipw_get_status_code
4269 (ntohs
4270 (auth->status)));
43f66a6c
JK
4271#endif
4272
0edd5b44
JG
4273 priv->status &=
4274 ~(STATUS_ASSOCIATING |
4275 STATUS_AUTH |
4276 STATUS_ASSOCIATED);
4277
a613bffd 4278 schedule_work(&priv->link_down);
0edd5b44
JG
4279 break;
4280 }
4281
4282 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4283 IPW_DL_ASSOC,
4284 "authenticated: '%s' " MAC_FMT
4285 "\n",
4286 escape_essid(priv->essid,
4287 priv->essid_len),
4288 MAC_ARG(priv->bssid));
4289 break;
4290 }
4291
4292 case CMAS_INIT:{
ea2b26e0
JK
4293 if (priv->status & STATUS_AUTH) {
4294 struct
4295 ieee80211_assoc_response
4296 *resp;
4297 resp =
4298 (struct
4299 ieee80211_assoc_response
4300 *)&notif->u.raw;
4301 IPW_DEBUG(IPW_DL_NOTIF |
4302 IPW_DL_STATE |
4303 IPW_DL_ASSOC,
4304 "association failed (0x%04X): %s\n",
4305 ntohs(resp->status),
4306 ipw_get_status_code
4307 (ntohs
4308 (resp->status)));
4309 }
4310
0edd5b44
JG
4311 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4312 IPW_DL_ASSOC,
4313 "disassociated: '%s' " MAC_FMT
4314 " \n",
4315 escape_essid(priv->essid,
4316 priv->essid_len),
4317 MAC_ARG(priv->bssid));
4318
4319 priv->status &=
4320 ~(STATUS_DISASSOCIATING |
4321 STATUS_ASSOCIATING |
4322 STATUS_ASSOCIATED | STATUS_AUTH);
b095c381
JK
4323 if (priv->assoc_network
4324 && (priv->assoc_network->
4325 capability &
4326 WLAN_CAPABILITY_IBSS))
4327 ipw_remove_current_network
4328 (priv);
0edd5b44 4329
a613bffd 4330 schedule_work(&priv->link_down);
0edd5b44 4331
0edd5b44
JG
4332 break;
4333 }
43f66a6c 4334
b095c381
JK
4335 case CMAS_RX_ASSOC_RESP:
4336 break;
4337
0edd5b44
JG
4338 default:
4339 IPW_ERROR("assoc: unknown (%d)\n",
4340 assoc->state);
43f66a6c 4341 break;
bf79451e 4342 }
43f66a6c 4343
43f66a6c
JK
4344 break;
4345 }
bf79451e 4346
0edd5b44
JG
4347 case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{
4348 struct notif_authenticate *auth = &notif->u.auth;
4349 switch (auth->state) {
4350 case CMAS_AUTHENTICATED:
4351 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4352 "authenticated: '%s' " MAC_FMT " \n",
4353 escape_essid(priv->essid,
4354 priv->essid_len),
4355 MAC_ARG(priv->bssid));
4356 priv->status |= STATUS_AUTH;
4357 break;
43f66a6c 4358
0edd5b44
JG
4359 case CMAS_INIT:
4360 if (priv->status & STATUS_AUTH) {
4361 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4362 IPW_DL_ASSOC,
4363 "authentication failed (0x%04X): %s\n",
4364 ntohs(auth->status),
4365 ipw_get_status_code(ntohs
4366 (auth->
4367 status)));
4368 }
4369 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4370 IPW_DL_ASSOC,
4371 "deauthenticated: '%s' " MAC_FMT "\n",
4372 escape_essid(priv->essid,
4373 priv->essid_len),
4374 MAC_ARG(priv->bssid));
bf79451e 4375
0edd5b44
JG
4376 priv->status &= ~(STATUS_ASSOCIATING |
4377 STATUS_AUTH |
4378 STATUS_ASSOCIATED);
43f66a6c 4379
a613bffd 4380 schedule_work(&priv->link_down);
0edd5b44 4381 break;
43f66a6c 4382
0edd5b44
JG
4383 case CMAS_TX_AUTH_SEQ_1:
4384 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4385 IPW_DL_ASSOC, "AUTH_SEQ_1\n");
4386 break;
4387 case CMAS_RX_AUTH_SEQ_2:
4388 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4389 IPW_DL_ASSOC, "AUTH_SEQ_2\n");
4390 break;
4391 case CMAS_AUTH_SEQ_1_PASS:
4392 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4393 IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n");
4394 break;
4395 case CMAS_AUTH_SEQ_1_FAIL:
4396 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4397 IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n");
4398 break;
4399 case CMAS_TX_AUTH_SEQ_3:
4400 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4401 IPW_DL_ASSOC, "AUTH_SEQ_3\n");
4402 break;
4403 case CMAS_RX_AUTH_SEQ_4:
4404 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4405 IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n");
4406 break;
4407 case CMAS_AUTH_SEQ_2_PASS:
4408 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4409 IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n");
4410 break;
4411 case CMAS_AUTH_SEQ_2_FAIL:
4412 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4413 IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n");
4414 break;
4415 case CMAS_TX_ASSOC:
4416 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4417 IPW_DL_ASSOC, "TX_ASSOC\n");
4418 break;
4419 case CMAS_RX_ASSOC_RESP:
4420 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4421 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
b095c381 4422
0edd5b44
JG
4423 break;
4424 case CMAS_ASSOCIATED:
4425 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4426 IPW_DL_ASSOC, "ASSOCIATED\n");
4427 break;
4428 default:
4429 IPW_DEBUG_NOTIF("auth: failure - %d\n",
4430 auth->state);
4431 break;
43f66a6c 4432 }
43f66a6c
JK
4433 break;
4434 }
4435
0edd5b44
JG
4436 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{
4437 struct notif_channel_result *x =
4438 &notif->u.channel_result;
43f66a6c 4439
0edd5b44
JG
4440 if (notif->size == sizeof(*x)) {
4441 IPW_DEBUG_SCAN("Scan result for channel %d\n",
4442 x->channel_num);
4443 } else {
4444 IPW_DEBUG_SCAN("Scan result of wrong size %d "
4445 "(should be %zd)\n",
4446 notif->size, sizeof(*x));
bf79451e 4447 }
43f66a6c
JK
4448 break;
4449 }
43f66a6c 4450
0edd5b44
JG
4451 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{
4452 struct notif_scan_complete *x = &notif->u.scan_complete;
4453 if (notif->size == sizeof(*x)) {
4454 IPW_DEBUG_SCAN
4455 ("Scan completed: type %d, %d channels, "
4456 "%d status\n", x->scan_type,
4457 x->num_channels, x->status);
4458 } else {
4459 IPW_ERROR("Scan completed of wrong size %d "
4460 "(should be %zd)\n",
4461 notif->size, sizeof(*x));
4462 }
43f66a6c 4463
0edd5b44
JG
4464 priv->status &=
4465 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
4466
a0e04ab3 4467 wake_up_interruptible(&priv->wait_state);
0edd5b44
JG
4468 cancel_delayed_work(&priv->scan_check);
4469
b095c381
JK
4470 if (priv->status & STATUS_EXIT_PENDING)
4471 break;
4472
4473 priv->ieee->scans++;
4474
4475#ifdef CONFIG_IPW2200_MONITOR
4476 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
afbf30a2 4477 priv->status |= STATUS_SCAN_FORCED;
b095c381
JK
4478 queue_work(priv->workqueue,
4479 &priv->request_scan);
4480 break;
4481 }
afbf30a2 4482 priv->status &= ~STATUS_SCAN_FORCED;
b095c381
JK
4483#endif /* CONFIG_IPW2200_MONITOR */
4484
0edd5b44
JG
4485 if (!(priv->status & (STATUS_ASSOCIATED |
4486 STATUS_ASSOCIATING |
4487 STATUS_ROAMING |
4488 STATUS_DISASSOCIATING)))
4489 queue_work(priv->workqueue, &priv->associate);
4490 else if (priv->status & STATUS_ROAMING) {
e7582561
BC
4491 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
4492 /* If a scan completed and we are in roam mode, then
4493 * the scan that completed was the one requested as a
4494 * result of entering roam... so, schedule the
4495 * roam work */
4496 queue_work(priv->workqueue,
4497 &priv->roam);
4498 else
4499 /* Don't schedule if we aborted the scan */
4500 priv->status &= ~STATUS_ROAMING;
0edd5b44
JG
4501 } else if (priv->status & STATUS_SCAN_PENDING)
4502 queue_work(priv->workqueue,
4503 &priv->request_scan);
a613bffd
JK
4504 else if (priv->config & CFG_BACKGROUND_SCAN
4505 && priv->status & STATUS_ASSOCIATED)
4506 queue_delayed_work(priv->workqueue,
4507 &priv->request_scan, HZ);
0edd5b44 4508 break;
43f66a6c 4509 }
43f66a6c 4510
0edd5b44
JG
4511 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
4512 struct notif_frag_length *x = &notif->u.frag_len;
43f66a6c 4513
a613bffd
JK
4514 if (notif->size == sizeof(*x))
4515 IPW_ERROR("Frag length: %d\n",
4516 le16_to_cpu(x->frag_length));
4517 else
0edd5b44
JG
4518 IPW_ERROR("Frag length of wrong size %d "
4519 "(should be %zd)\n",
4520 notif->size, sizeof(*x));
0edd5b44 4521 break;
43f66a6c 4522 }
43f66a6c 4523
0edd5b44
JG
4524 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
4525 struct notif_link_deterioration *x =
4526 &notif->u.link_deterioration;
afbf30a2 4527
0edd5b44
JG
4528 if (notif->size == sizeof(*x)) {
4529 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4530 "link deterioration: '%s' " MAC_FMT
4531 " \n", escape_essid(priv->essid,
4532 priv->essid_len),
4533 MAC_ARG(priv->bssid));
4534 memcpy(&priv->last_link_deterioration, x,
4535 sizeof(*x));
4536 } else {
4537 IPW_ERROR("Link Deterioration of wrong size %d "
4538 "(should be %zd)\n",
4539 notif->size, sizeof(*x));
4540 }
43f66a6c
JK
4541 break;
4542 }
4543
0edd5b44
JG
4544 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
4545 IPW_ERROR("Dino config\n");
4546 if (priv->hcmd
a613bffd 4547 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
0edd5b44 4548 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
a613bffd 4549
0edd5b44
JG
4550 break;
4551 }
43f66a6c 4552
0edd5b44
JG
4553 case HOST_NOTIFICATION_STATUS_BEACON_STATE:{
4554 struct notif_beacon_state *x = &notif->u.beacon_state;
4555 if (notif->size != sizeof(*x)) {
4556 IPW_ERROR
4557 ("Beacon state of wrong size %d (should "
4558 "be %zd)\n", notif->size, sizeof(*x));
4559 break;
43f66a6c
JK
4560 }
4561
a613bffd
JK
4562 if (le32_to_cpu(x->state) ==
4563 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
4564 ipw_handle_missed_beacon(priv,
4565 le32_to_cpu(x->
4566 number));
43f66a6c 4567
0edd5b44
JG
4568 break;
4569 }
43f66a6c 4570
0edd5b44
JG
4571 case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{
4572 struct notif_tgi_tx_key *x = &notif->u.tgi_tx_key;
4573 if (notif->size == sizeof(*x)) {
4574 IPW_ERROR("TGi Tx Key: state 0x%02x sec type "
4575 "0x%02x station %d\n",
4576 x->key_state, x->security_type,
4577 x->station_index);
4578 break;
4579 }
43f66a6c 4580
0edd5b44
JG
4581 IPW_ERROR
4582 ("TGi Tx Key of wrong size %d (should be %zd)\n",
4583 notif->size, sizeof(*x));
43f66a6c 4584 break;
bf79451e 4585 }
43f66a6c 4586
0edd5b44
JG
4587 case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{
4588 struct notif_calibration *x = &notif->u.calibration;
43f66a6c 4589
0edd5b44
JG
4590 if (notif->size == sizeof(*x)) {
4591 memcpy(&priv->calib, x, sizeof(*x));
4592 IPW_DEBUG_INFO("TODO: Calibration\n");
4593 break;
4594 }
43f66a6c 4595
0edd5b44
JG
4596 IPW_ERROR
4597 ("Calibration of wrong size %d (should be %zd)\n",
4598 notif->size, sizeof(*x));
43f66a6c 4599 break;
bf79451e
JG
4600 }
4601
0edd5b44
JG
4602 case HOST_NOTIFICATION_NOISE_STATS:{
4603 if (notif->size == sizeof(u32)) {
4604 priv->last_noise =
a613bffd
JK
4605 (u8) (le32_to_cpu(notif->u.noise.value) &
4606 0xff);
0edd5b44
JG
4607 average_add(&priv->average_noise,
4608 priv->last_noise);
4609 break;
4610 }
43f66a6c 4611
0edd5b44
JG
4612 IPW_ERROR
4613 ("Noise stat is wrong size %d (should be %zd)\n",
4614 notif->size, sizeof(u32));
43f66a6c
JK
4615 break;
4616 }
4617
43f66a6c
JK
4618 default:
4619 IPW_ERROR("Unknown notification: "
4620 "subtype=%d,flags=0x%2x,size=%d\n",
4621 notif->subtype, notif->flags, notif->size);
4622 }
4623}
4624
4625/**
4626 * Destroys all DMA structures and initialise them again
bf79451e 4627 *
43f66a6c
JK
4628 * @param priv
4629 * @return error code
4630 */
4631static int ipw_queue_reset(struct ipw_priv *priv)
4632{
4633 int rc = 0;
4634 /** @todo customize queue sizes */
4635 int nTx = 64, nTxCmd = 8;
4636 ipw_tx_queue_free(priv);
4637 /* Tx CMD queue */
4638 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
b095c381
JK
4639 IPW_TX_CMD_QUEUE_READ_INDEX,
4640 IPW_TX_CMD_QUEUE_WRITE_INDEX,
4641 IPW_TX_CMD_QUEUE_BD_BASE,
4642 IPW_TX_CMD_QUEUE_BD_SIZE);
43f66a6c
JK
4643 if (rc) {
4644 IPW_ERROR("Tx Cmd queue init failed\n");
4645 goto error;
4646 }
4647 /* Tx queue(s) */
4648 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
b095c381
JK
4649 IPW_TX_QUEUE_0_READ_INDEX,
4650 IPW_TX_QUEUE_0_WRITE_INDEX,
4651 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
43f66a6c
JK
4652 if (rc) {
4653 IPW_ERROR("Tx 0 queue init failed\n");
4654 goto error;
4655 }
4656 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
b095c381
JK
4657 IPW_TX_QUEUE_1_READ_INDEX,
4658 IPW_TX_QUEUE_1_WRITE_INDEX,
4659 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
43f66a6c
JK
4660 if (rc) {
4661 IPW_ERROR("Tx 1 queue init failed\n");
4662 goto error;
4663 }
4664 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
b095c381
JK
4665 IPW_TX_QUEUE_2_READ_INDEX,
4666 IPW_TX_QUEUE_2_WRITE_INDEX,
4667 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
43f66a6c
JK
4668 if (rc) {
4669 IPW_ERROR("Tx 2 queue init failed\n");
4670 goto error;
4671 }
4672 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
b095c381
JK
4673 IPW_TX_QUEUE_3_READ_INDEX,
4674 IPW_TX_QUEUE_3_WRITE_INDEX,
4675 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
43f66a6c
JK
4676 if (rc) {
4677 IPW_ERROR("Tx 3 queue init failed\n");
4678 goto error;
4679 }
4680 /* statistics */
4681 priv->rx_bufs_min = 0;
4682 priv->rx_pend_max = 0;
4683 return rc;
4684
0edd5b44 4685 error:
43f66a6c
JK
4686 ipw_tx_queue_free(priv);
4687 return rc;
4688}
4689
4690/**
4691 * Reclaim Tx queue entries no more used by NIC.
bf79451e 4692 *
43f66a6c
JK
4693 * When FW adwances 'R' index, all entries between old and
4694 * new 'R' index need to be reclaimed. As result, some free space
4695 * forms. If there is enough free space (> low mark), wake Tx queue.
bf79451e 4696 *
43f66a6c
JK
4697 * @note Need to protect against garbage in 'R' index
4698 * @param priv
4699 * @param txq
4700 * @param qindex
4701 * @return Number of used entries remains in the queue
4702 */
bf79451e 4703static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
4704 struct clx2_tx_queue *txq, int qindex)
4705{
4706 u32 hw_tail;
4707 int used;
4708 struct clx2_queue *q = &txq->q;
4709
4710 hw_tail = ipw_read32(priv, q->reg_r);
4711 if (hw_tail >= q->n_bd) {
4712 IPW_ERROR
0edd5b44
JG
4713 ("Read index for DMA queue (%d) is out of range [0-%d)\n",
4714 hw_tail, q->n_bd);
43f66a6c
JK
4715 goto done;
4716 }
4717 for (; q->last_used != hw_tail;
4718 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
4719 ipw_queue_tx_free_tfd(priv, txq);
4720 priv->tx_packets++;
4721 }
0edd5b44 4722 done:
9ddf84f6
JK
4723 if ((ipw_queue_space(q) > q->low_mark) &&
4724 (qindex >= 0) &&
4725 (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
4726 netif_wake_queue(priv->net_dev);
43f66a6c
JK
4727 used = q->first_empty - q->last_used;
4728 if (used < 0)
4729 used += q->n_bd;
4730
4731 return used;
4732}
4733
4734static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
4735 int len, int sync)
4736{
4737 struct clx2_tx_queue *txq = &priv->txq_cmd;
4738 struct clx2_queue *q = &txq->q;
4739 struct tfd_frame *tfd;
4740
4741 if (ipw_queue_space(q) < (sync ? 1 : 2)) {
4742 IPW_ERROR("No space for Tx\n");
4743 return -EBUSY;
4744 }
4745
4746 tfd = &txq->bd[q->first_empty];
4747 txq->txb[q->first_empty] = NULL;
4748
4749 memset(tfd, 0, sizeof(*tfd));
4750 tfd->control_flags.message_type = TX_HOST_COMMAND_TYPE;
4751 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
4752 priv->hcmd_seq++;
4753 tfd->u.cmd.index = hcmd;
4754 tfd->u.cmd.length = len;
4755 memcpy(tfd->u.cmd.payload, buf, len);
4756 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
4757 ipw_write32(priv, q->reg_w, q->first_empty);
4758 _ipw_read32(priv, 0x90);
4759
4760 return 0;
4761}
4762
bf79451e 4763/*
43f66a6c
JK
4764 * Rx theory of operation
4765 *
4766 * The host allocates 32 DMA target addresses and passes the host address
b095c381 4767 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
43f66a6c
JK
4768 * 0 to 31
4769 *
4770 * Rx Queue Indexes
4771 * The host/firmware share two index registers for managing the Rx buffers.
4772 *
bf79451e
JG
4773 * The READ index maps to the first position that the firmware may be writing
4774 * to -- the driver can read up to (but not including) this position and get
4775 * good data.
43f66a6c
JK
4776 * The READ index is managed by the firmware once the card is enabled.
4777 *
4778 * The WRITE index maps to the last position the driver has read from -- the
4779 * position preceding WRITE is the last slot the firmware can place a packet.
4780 *
4781 * The queue is empty (no good data) if WRITE = READ - 1, and is full if
bf79451e 4782 * WRITE = READ.
43f66a6c 4783 *
bf79451e 4784 * During initialization the host sets up the READ queue position to the first
43f66a6c
JK
4785 * INDEX position, and WRITE to the last (READ - 1 wrapped)
4786 *
4787 * When the firmware places a packet in a buffer it will advance the READ index
4788 * and fire the RX interrupt. The driver can then query the READ index and
4789 * process as many packets as possible, moving the WRITE index forward as it
4790 * resets the Rx queue buffers with new memory.
bf79451e 4791 *
43f66a6c 4792 * The management in the driver is as follows:
bf79451e 4793 * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When
43f66a6c 4794 * ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
bf79451e 4795 * to replensish the ipw->rxq->rx_free.
43f66a6c
JK
4796 * + In ipw_rx_queue_replenish (scheduled) if 'processed' != 'read' then the
4797 * ipw->rxq is replenished and the READ INDEX is updated (updating the
4798 * 'processed' and 'read' driver indexes as well)
4799 * + A received packet is processed and handed to the kernel network stack,
4800 * detached from the ipw->rxq. The driver 'processed' index is updated.
4801 * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free
bf79451e
JG
4802 * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ
4803 * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there
43f66a6c
JK
4804 * were enough free buffers and RX_STALLED is set it is cleared.
4805 *
4806 *
4807 * Driver sequence:
4808 *
bf79451e 4809 * ipw_rx_queue_alloc() Allocates rx_free
43f66a6c
JK
4810 * ipw_rx_queue_replenish() Replenishes rx_free list from rx_used, and calls
4811 * ipw_rx_queue_restock
4812 * ipw_rx_queue_restock() Moves available buffers from rx_free into Rx
4813 * queue, updates firmware pointers, and updates
4814 * the WRITE index. If insufficient rx_free buffers
4815 * are available, schedules ipw_rx_queue_replenish
4816 *
4817 * -- enable interrupts --
4818 * ISR - ipw_rx() Detach ipw_rx_mem_buffers from pool up to the
bf79451e 4819 * READ INDEX, detaching the SKB from the pool.
43f66a6c
JK
4820 * Moves the packet buffer from queue to rx_used.
4821 * Calls ipw_rx_queue_restock to refill any empty
4822 * slots.
4823 * ...
4824 *
4825 */
4826
bf79451e 4827/*
43f66a6c
JK
4828 * If there are slots in the RX queue that need to be restocked,
4829 * and we have free pre-allocated buffers, fill the ranks as much
4830 * as we can pulling from rx_free.
4831 *
4832 * This moves the 'write' index forward to catch up with 'processed', and
4833 * also updates the memory address in the firmware to reference the new
4834 * target buffer.
4835 */
4836static void ipw_rx_queue_restock(struct ipw_priv *priv)
4837{
4838 struct ipw_rx_queue *rxq = priv->rxq;
4839 struct list_head *element;
4840 struct ipw_rx_mem_buffer *rxb;
4841 unsigned long flags;
4842 int write;
4843
4844 spin_lock_irqsave(&rxq->lock, flags);
4845 write = rxq->write;
4846 while ((rxq->write != rxq->processed) && (rxq->free_count)) {
4847 element = rxq->rx_free.next;
4848 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
4849 list_del(element);
4850
b095c381 4851 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
43f66a6c
JK
4852 rxb->dma_addr);
4853 rxq->queue[rxq->write] = rxb;
4854 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
4855 rxq->free_count--;
4856 }
4857 spin_unlock_irqrestore(&rxq->lock, flags);
4858
bf79451e 4859 /* If the pre-allocated buffer pool is dropping low, schedule to
43f66a6c
JK
4860 * refill it */
4861 if (rxq->free_count <= RX_LOW_WATERMARK)
4862 queue_work(priv->workqueue, &priv->rx_replenish);
4863
4864 /* If we've added more space for the firmware to place data, tell it */
bf79451e 4865 if (write != rxq->write)
b095c381 4866 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
43f66a6c
JK
4867}
4868
4869/*
4870 * Move all used packet from rx_used to rx_free, allocating a new SKB for each.
bf79451e
JG
4871 * Also restock the Rx queue via ipw_rx_queue_restock.
4872 *
43f66a6c
JK
4873 * This is called as a scheduled work item (except for during intialization)
4874 */
4875static void ipw_rx_queue_replenish(void *data)
4876{
4877 struct ipw_priv *priv = data;
4878 struct ipw_rx_queue *rxq = priv->rxq;
4879 struct list_head *element;
4880 struct ipw_rx_mem_buffer *rxb;
4881 unsigned long flags;
4882
4883 spin_lock_irqsave(&rxq->lock, flags);
4884 while (!list_empty(&rxq->rx_used)) {
4885 element = rxq->rx_used.next;
4886 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
b095c381 4887 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
43f66a6c
JK
4888 if (!rxb->skb) {
4889 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
4890 priv->net_dev->name);
4891 /* We don't reschedule replenish work here -- we will
4892 * call the restock method and if it still needs
4893 * more buffers it will schedule replenish */
4894 break;
4895 }
4896 list_del(element);
bf79451e 4897
43f66a6c 4898 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
0edd5b44
JG
4899 rxb->dma_addr =
4900 pci_map_single(priv->pci_dev, rxb->skb->data,
b095c381 4901 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
bf79451e 4902
43f66a6c
JK
4903 list_add_tail(&rxb->list, &rxq->rx_free);
4904 rxq->free_count++;
4905 }
4906 spin_unlock_irqrestore(&rxq->lock, flags);
4907
4908 ipw_rx_queue_restock(priv);
4909}
4910
c848d0af
JK
4911static void ipw_bg_rx_queue_replenish(void *data)
4912{
4913 struct ipw_priv *priv = data;
4914 down(&priv->sem);
4915 ipw_rx_queue_replenish(data);
4916 up(&priv->sem);
4917}
4918
43f66a6c
JK
4919/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4920 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
bf79451e 4921 * This free routine walks the list of POOL entries and if SKB is set to
43f66a6c
JK
4922 * non NULL it is unmapped and freed
4923 */
0edd5b44 4924static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
43f66a6c
JK
4925{
4926 int i;
4927
4928 if (!rxq)
4929 return;
bf79451e 4930
43f66a6c
JK
4931 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4932 if (rxq->pool[i].skb != NULL) {
4933 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
b095c381 4934 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c
JK
4935 dev_kfree_skb(rxq->pool[i].skb);
4936 }
4937 }
4938
4939 kfree(rxq);
4940}
4941
4942static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
4943{
4944 struct ipw_rx_queue *rxq;
4945 int i;
4946
4947 rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
ad18b0ea
PI
4948 if (unlikely(!rxq)) {
4949 IPW_ERROR("memory allocation failed\n");
4950 return NULL;
4951 }
43f66a6c
JK
4952 memset(rxq, 0, sizeof(*rxq));
4953 spin_lock_init(&rxq->lock);
4954 INIT_LIST_HEAD(&rxq->rx_free);
4955 INIT_LIST_HEAD(&rxq->rx_used);
4956
4957 /* Fill the rx_used queue with _all_ of the Rx buffers */
bf79451e 4958 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
43f66a6c
JK
4959 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
4960
4961 /* Set us so that we have processed and used all buffers, but have
4962 * not restocked the Rx queue with fresh buffers */
4963 rxq->read = rxq->write = 0;
4964 rxq->processed = RX_QUEUE_SIZE - 1;
4965 rxq->free_count = 0;
4966
4967 return rxq;
4968}
4969
4970static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
4971{
4972 rate &= ~IEEE80211_BASIC_RATE_MASK;
4973 if (ieee_mode == IEEE_A) {
4974 switch (rate) {
bf79451e
JG
4975 case IEEE80211_OFDM_RATE_6MB:
4976 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ?
0edd5b44 4977 1 : 0;
bf79451e
JG
4978 case IEEE80211_OFDM_RATE_9MB:
4979 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ?
0edd5b44 4980 1 : 0;
bf79451e 4981 case IEEE80211_OFDM_RATE_12MB:
0edd5b44
JG
4982 return priv->
4983 rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
bf79451e 4984 case IEEE80211_OFDM_RATE_18MB:
0edd5b44
JG
4985 return priv->
4986 rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
bf79451e 4987 case IEEE80211_OFDM_RATE_24MB:
0edd5b44
JG
4988 return priv->
4989 rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
bf79451e 4990 case IEEE80211_OFDM_RATE_36MB:
0edd5b44
JG
4991 return priv->
4992 rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
bf79451e 4993 case IEEE80211_OFDM_RATE_48MB:
0edd5b44
JG
4994 return priv->
4995 rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
bf79451e 4996 case IEEE80211_OFDM_RATE_54MB:
0edd5b44
JG
4997 return priv->
4998 rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
43f66a6c
JK
4999 default:
5000 return 0;
5001 }
5002 }
bf79451e 5003
43f66a6c
JK
5004 /* B and G mixed */
5005 switch (rate) {
bf79451e 5006 case IEEE80211_CCK_RATE_1MB:
43f66a6c 5007 return priv->rates_mask & IEEE80211_CCK_RATE_1MB_MASK ? 1 : 0;
bf79451e 5008 case IEEE80211_CCK_RATE_2MB:
43f66a6c 5009 return priv->rates_mask & IEEE80211_CCK_RATE_2MB_MASK ? 1 : 0;
bf79451e 5010 case IEEE80211_CCK_RATE_5MB:
43f66a6c 5011 return priv->rates_mask & IEEE80211_CCK_RATE_5MB_MASK ? 1 : 0;
bf79451e 5012 case IEEE80211_CCK_RATE_11MB:
43f66a6c
JK
5013 return priv->rates_mask & IEEE80211_CCK_RATE_11MB_MASK ? 1 : 0;
5014 }
5015
5016 /* If we are limited to B modulations, bail at this point */
5017 if (ieee_mode == IEEE_B)
5018 return 0;
5019
5020 /* G */
5021 switch (rate) {
bf79451e 5022 case IEEE80211_OFDM_RATE_6MB:
43f66a6c 5023 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? 1 : 0;
bf79451e 5024 case IEEE80211_OFDM_RATE_9MB:
43f66a6c 5025 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? 1 : 0;
bf79451e 5026 case IEEE80211_OFDM_RATE_12MB:
43f66a6c 5027 return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
bf79451e 5028 case IEEE80211_OFDM_RATE_18MB:
43f66a6c 5029 return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
bf79451e 5030 case IEEE80211_OFDM_RATE_24MB:
43f66a6c 5031 return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
bf79451e 5032 case IEEE80211_OFDM_RATE_36MB:
43f66a6c 5033 return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
bf79451e 5034 case IEEE80211_OFDM_RATE_48MB:
43f66a6c 5035 return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
bf79451e 5036 case IEEE80211_OFDM_RATE_54MB:
43f66a6c
JK
5037 return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
5038 }
5039
5040 return 0;
5041}
5042
bf79451e 5043static int ipw_compatible_rates(struct ipw_priv *priv,
43f66a6c
JK
5044 const struct ieee80211_network *network,
5045 struct ipw_supported_rates *rates)
5046{
5047 int num_rates, i;
5048
5049 memset(rates, 0, sizeof(*rates));
0edd5b44 5050 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
43f66a6c
JK
5051 rates->num_rates = 0;
5052 for (i = 0; i < num_rates; i++) {
a613bffd
JK
5053 if (!ipw_is_rate_in_mask(priv, network->mode,
5054 network->rates[i])) {
5055
ea2b26e0 5056 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
a613bffd
JK
5057 IPW_DEBUG_SCAN("Adding masked mandatory "
5058 "rate %02X\n",
5059 network->rates[i]);
5060 rates->supported_rates[rates->num_rates++] =
5061 network->rates[i];
5062 continue;
ea2b26e0
JK
5063 }
5064
43f66a6c
JK
5065 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
5066 network->rates[i], priv->rates_mask);
5067 continue;
5068 }
bf79451e 5069
43f66a6c
JK
5070 rates->supported_rates[rates->num_rates++] = network->rates[i];
5071 }
5072
a613bffd
JK
5073 num_rates = min(network->rates_ex_len,
5074 (u8) (IPW_MAX_RATES - num_rates));
43f66a6c 5075 for (i = 0; i < num_rates; i++) {
a613bffd
JK
5076 if (!ipw_is_rate_in_mask(priv, network->mode,
5077 network->rates_ex[i])) {
ea2b26e0 5078 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
a613bffd
JK
5079 IPW_DEBUG_SCAN("Adding masked mandatory "
5080 "rate %02X\n",
5081 network->rates_ex[i]);
5082 rates->supported_rates[rates->num_rates++] =
5083 network->rates[i];
5084 continue;
ea2b26e0
JK
5085 }
5086
43f66a6c
JK
5087 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
5088 network->rates_ex[i], priv->rates_mask);
5089 continue;
5090 }
bf79451e 5091
0edd5b44
JG
5092 rates->supported_rates[rates->num_rates++] =
5093 network->rates_ex[i];
43f66a6c
JK
5094 }
5095
ea2b26e0 5096 return 1;
43f66a6c
JK
5097}
5098
5099static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
5100 const struct ipw_supported_rates *src)
5101{
5102 u8 i;
5103 for (i = 0; i < src->num_rates; i++)
5104 dest->supported_rates[i] = src->supported_rates[i];
5105 dest->num_rates = src->num_rates;
5106}
5107
5108/* TODO: Look at sniffed packets in the air to determine if the basic rate
5109 * mask should ever be used -- right now all callers to add the scan rates are
5110 * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */
5111static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 5112 u8 modulation, u32 rate_mask)
43f66a6c 5113{
bf79451e 5114 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
0edd5b44 5115 IEEE80211_BASIC_RATE_MASK : 0;
bf79451e 5116
43f66a6c 5117 if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK)
bf79451e 5118 rates->supported_rates[rates->num_rates++] =
0edd5b44 5119 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
43f66a6c
JK
5120
5121 if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK)
bf79451e 5122 rates->supported_rates[rates->num_rates++] =
0edd5b44 5123 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
43f66a6c
JK
5124
5125 if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK)
bf79451e 5126 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 5127 IEEE80211_CCK_RATE_5MB;
43f66a6c
JK
5128
5129 if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK)
bf79451e 5130 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 5131 IEEE80211_CCK_RATE_11MB;
43f66a6c
JK
5132}
5133
5134static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 5135 u8 modulation, u32 rate_mask)
43f66a6c 5136{
bf79451e 5137 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
0edd5b44 5138 IEEE80211_BASIC_RATE_MASK : 0;
43f66a6c
JK
5139
5140 if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK)
bf79451e 5141 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 5142 IEEE80211_OFDM_RATE_6MB;
43f66a6c
JK
5143
5144 if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK)
bf79451e 5145 rates->supported_rates[rates->num_rates++] =
0edd5b44 5146 IEEE80211_OFDM_RATE_9MB;
43f66a6c
JK
5147
5148 if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK)
bf79451e 5149 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 5150 IEEE80211_OFDM_RATE_12MB;
43f66a6c
JK
5151
5152 if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK)
bf79451e 5153 rates->supported_rates[rates->num_rates++] =
0edd5b44 5154 IEEE80211_OFDM_RATE_18MB;
43f66a6c
JK
5155
5156 if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK)
bf79451e 5157 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 5158 IEEE80211_OFDM_RATE_24MB;
43f66a6c
JK
5159
5160 if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK)
bf79451e 5161 rates->supported_rates[rates->num_rates++] =
0edd5b44 5162 IEEE80211_OFDM_RATE_36MB;
43f66a6c
JK
5163
5164 if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK)
bf79451e 5165 rates->supported_rates[rates->num_rates++] =
0edd5b44 5166 IEEE80211_OFDM_RATE_48MB;
43f66a6c
JK
5167
5168 if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK)
bf79451e 5169 rates->supported_rates[rates->num_rates++] =
0edd5b44 5170 IEEE80211_OFDM_RATE_54MB;
43f66a6c
JK
5171}
5172
5173struct ipw_network_match {
5174 struct ieee80211_network *network;
5175 struct ipw_supported_rates rates;
5176};
5177
c848d0af
JK
5178static int ipw_find_adhoc_network(struct ipw_priv *priv,
5179 struct ipw_network_match *match,
5180 struct ieee80211_network *network,
5181 int roaming)
5182{
5183 struct ipw_supported_rates rates;
5184
5185 /* Verify that this network's capability is compatible with the
5186 * current mode (AdHoc or Infrastructure) */
5187 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
5188 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5189 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
5190 "capability mismatch.\n",
5191 escape_essid(network->ssid, network->ssid_len),
5192 MAC_ARG(network->bssid));
5193 return 0;
5194 }
5195
5196 /* If we do not have an ESSID for this AP, we can not associate with
5197 * it */
5198 if (network->flags & NETWORK_EMPTY_ESSID) {
5199 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5200 "because of hidden ESSID.\n",
5201 escape_essid(network->ssid, network->ssid_len),
5202 MAC_ARG(network->bssid));
5203 return 0;
5204 }
5205
5206 if (unlikely(roaming)) {
5207 /* If we are roaming, then ensure check if this is a valid
5208 * network to try and roam to */
5209 if ((network->ssid_len != match->network->ssid_len) ||
5210 memcmp(network->ssid, match->network->ssid,
5211 network->ssid_len)) {
5212 IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
5213 "because of non-network ESSID.\n",
5214 escape_essid(network->ssid,
5215 network->ssid_len),
5216 MAC_ARG(network->bssid));
5217 return 0;
5218 }
5219 } else {
5220 /* If an ESSID has been configured then compare the broadcast
5221 * ESSID to ours */
5222 if ((priv->config & CFG_STATIC_ESSID) &&
5223 ((network->ssid_len != priv->essid_len) ||
5224 memcmp(network->ssid, priv->essid,
5225 min(network->ssid_len, priv->essid_len)))) {
5226 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
afbf30a2 5227
c848d0af
JK
5228 strncpy(escaped,
5229 escape_essid(network->ssid, network->ssid_len),
5230 sizeof(escaped));
5231 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5232 "because of ESSID mismatch: '%s'.\n",
5233 escaped, MAC_ARG(network->bssid),
5234 escape_essid(priv->essid,
5235 priv->essid_len));
5236 return 0;
5237 }
5238 }
5239
5240 /* If the old network rate is better than this one, don't bother
5241 * testing everything else. */
5242
5243 if (network->time_stamp[0] < match->network->time_stamp[0]) {
afbf30a2
JK
5244 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5245 "current network.\n",
5246 escape_essid(match->network->ssid,
5247 match->network->ssid_len));
c848d0af
JK
5248 return 0;
5249 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
afbf30a2
JK
5250 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5251 "current network.\n",
5252 escape_essid(match->network->ssid,
5253 match->network->ssid_len));
c848d0af
JK
5254 return 0;
5255 }
5256
5257 /* Now go through and see if the requested network is valid... */
5258 if (priv->ieee->scan_age != 0 &&
5259 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5260 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5261 "because of age: %lums.\n",
5262 escape_essid(network->ssid, network->ssid_len),
5263 MAC_ARG(network->bssid),
afbf30a2 5264 1000 * (jiffies - network->last_scanned) / HZ);
c848d0af
JK
5265 return 0;
5266 }
5267
5268 if ((priv->config & CFG_STATIC_CHANNEL) &&
5269 (network->channel != priv->channel)) {
5270 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5271 "because of channel mismatch: %d != %d.\n",
5272 escape_essid(network->ssid, network->ssid_len),
5273 MAC_ARG(network->bssid),
5274 network->channel, priv->channel);
5275 return 0;
5276 }
5277
5278 /* Verify privacy compatability */
5279 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5280 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5281 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5282 "because of privacy mismatch: %s != %s.\n",
5283 escape_essid(network->ssid, network->ssid_len),
5284 MAC_ARG(network->bssid),
afbf30a2
JK
5285 priv->
5286 capability & CAP_PRIVACY_ON ? "on" : "off",
5287 network->
5288 capability & WLAN_CAPABILITY_PRIVACY ? "on" :
5289 "off");
c848d0af
JK
5290 return 0;
5291 }
5292
5293 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5294 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5295 "because of the same BSSID match: " MAC_FMT
5296 ".\n", escape_essid(network->ssid,
5297 network->ssid_len),
5298 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
5299 return 0;
5300 }
5301
5302 /* Filter out any incompatible freq / mode combinations */
5303 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5304 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5305 "because of invalid frequency/mode "
5306 "combination.\n",
5307 escape_essid(network->ssid, network->ssid_len),
5308 MAC_ARG(network->bssid));
5309 return 0;
5310 }
5311
5312 /* Ensure that the rates supported by the driver are compatible with
5313 * this AP, including verification of basic rates (mandatory) */
5314 if (!ipw_compatible_rates(priv, network, &rates)) {
5315 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5316 "because configured rate mask excludes "
5317 "AP mandatory rate.\n",
5318 escape_essid(network->ssid, network->ssid_len),
5319 MAC_ARG(network->bssid));
5320 return 0;
5321 }
5322
5323 if (rates.num_rates == 0) {
5324 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5325 "because of no compatible rates.\n",
5326 escape_essid(network->ssid, network->ssid_len),
5327 MAC_ARG(network->bssid));
5328 return 0;
5329 }
5330
5331 /* TODO: Perform any further minimal comparititive tests. We do not
5332 * want to put too much policy logic here; intelligent scan selection
5333 * should occur within a generic IEEE 802.11 user space tool. */
5334
5335 /* Set up 'new' AP to this network */
5336 ipw_copy_rates(&match->rates, &rates);
5337 match->network = network;
5338 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
5339 escape_essid(network->ssid, network->ssid_len),
5340 MAC_ARG(network->bssid));
5341
5342 return 1;
5343}
5344
5345static void ipw_merge_adhoc_network(void *data)
5346{
5347 struct ipw_priv *priv = data;
5348 struct ieee80211_network *network = NULL;
5349 struct ipw_network_match match = {
5350 .network = priv->assoc_network
5351 };
5352
afbf30a2
JK
5353 if ((priv->status & STATUS_ASSOCIATED) &&
5354 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
c848d0af
JK
5355 /* First pass through ROAM process -- look for a better
5356 * network */
5357 unsigned long flags;
5358
5359 spin_lock_irqsave(&priv->ieee->lock, flags);
5360 list_for_each_entry(network, &priv->ieee->network_list, list) {
5361 if (network != priv->assoc_network)
5362 ipw_find_adhoc_network(priv, &match, network,
5363 1);
5364 }
5365 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5366
5367 if (match.network == priv->assoc_network) {
5368 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5369 "merge to.\n");
5370 return;
5371 }
5372
5373 down(&priv->sem);
5374 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5375 IPW_DEBUG_MERGE("remove network %s\n",
5376 escape_essid(priv->essid,
5377 priv->essid_len));
5378 ipw_remove_current_network(priv);
5379 }
5380
5381 ipw_disassociate(priv);
5382 priv->assoc_network = match.network;
5383 up(&priv->sem);
5384 return;
5385 }
c848d0af
JK
5386}
5387
0edd5b44
JG
5388static int ipw_best_network(struct ipw_priv *priv,
5389 struct ipw_network_match *match,
5390 struct ieee80211_network *network, int roaming)
43f66a6c
JK
5391{
5392 struct ipw_supported_rates rates;
5393
5394 /* Verify that this network's capability is compatible with the
5395 * current mode (AdHoc or Infrastructure) */
5396 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
2474385e 5397 !(network->capability & WLAN_CAPABILITY_ESS)) ||
43f66a6c
JK
5398 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
5399 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5400 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded due to "
bf79451e 5401 "capability mismatch.\n",
43f66a6c
JK
5402 escape_essid(network->ssid, network->ssid_len),
5403 MAC_ARG(network->bssid));
5404 return 0;
5405 }
5406
5407 /* If we do not have an ESSID for this AP, we can not associate with
5408 * it */
5409 if (network->flags & NETWORK_EMPTY_ESSID) {
5410 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5411 "because of hidden ESSID.\n",
5412 escape_essid(network->ssid, network->ssid_len),
5413 MAC_ARG(network->bssid));
5414 return 0;
5415 }
bf79451e 5416
43f66a6c
JK
5417 if (unlikely(roaming)) {
5418 /* If we are roaming, then ensure check if this is a valid
5419 * network to try and roam to */
5420 if ((network->ssid_len != match->network->ssid_len) ||
bf79451e 5421 memcmp(network->ssid, match->network->ssid,
43f66a6c
JK
5422 network->ssid_len)) {
5423 IPW_DEBUG_ASSOC("Netowrk '%s (" MAC_FMT ")' excluded "
5424 "because of non-network ESSID.\n",
bf79451e 5425 escape_essid(network->ssid,
43f66a6c
JK
5426 network->ssid_len),
5427 MAC_ARG(network->bssid));
5428 return 0;
5429 }
5430 } else {
bf79451e
JG
5431 /* If an ESSID has been configured then compare the broadcast
5432 * ESSID to ours */
5433 if ((priv->config & CFG_STATIC_ESSID) &&
43f66a6c 5434 ((network->ssid_len != priv->essid_len) ||
bf79451e 5435 memcmp(network->ssid, priv->essid,
43f66a6c
JK
5436 min(network->ssid_len, priv->essid_len)))) {
5437 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
0edd5b44
JG
5438 strncpy(escaped,
5439 escape_essid(network->ssid, network->ssid_len),
43f66a6c
JK
5440 sizeof(escaped));
5441 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
bf79451e 5442 "because of ESSID mismatch: '%s'.\n",
43f66a6c 5443 escaped, MAC_ARG(network->bssid),
0edd5b44
JG
5444 escape_essid(priv->essid,
5445 priv->essid_len));
43f66a6c
JK
5446 return 0;
5447 }
5448 }
5449
5450 /* If the old network rate is better than this one, don't bother
5451 * testing everything else. */
0edd5b44 5452 if (match->network && match->network->stats.rssi > network->stats.rssi) {
43f66a6c 5453 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
bf79451e
JG
5454 strncpy(escaped,
5455 escape_essid(network->ssid, network->ssid_len),
43f66a6c
JK
5456 sizeof(escaped));
5457 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded because "
5458 "'%s (" MAC_FMT ")' has a stronger signal.\n",
5459 escaped, MAC_ARG(network->bssid),
5460 escape_essid(match->network->ssid,
5461 match->network->ssid_len),
5462 MAC_ARG(match->network->bssid));
5463 return 0;
5464 }
bf79451e 5465
43f66a6c
JK
5466 /* If this network has already had an association attempt within the
5467 * last 3 seconds, do not try and associate again... */
5468 if (network->last_associate &&
ea2b26e0 5469 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
43f66a6c 5470 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
afbf30a2 5471 "because of storming (%lus since last "
43f66a6c
JK
5472 "assoc attempt).\n",
5473 escape_essid(network->ssid, network->ssid_len),
5474 MAC_ARG(network->bssid),
5475 (jiffies - network->last_associate) / HZ);
5476 return 0;
5477 }
5478
5479 /* Now go through and see if the requested network is valid... */
bf79451e 5480 if (priv->ieee->scan_age != 0 &&
ea2b26e0 5481 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
43f66a6c
JK
5482 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5483 "because of age: %lums.\n",
5484 escape_essid(network->ssid, network->ssid_len),
5485 MAC_ARG(network->bssid),
afbf30a2 5486 1000 * (jiffies - network->last_scanned) / HZ);
43f66a6c 5487 return 0;
bf79451e 5488 }
43f66a6c 5489
bf79451e 5490 if ((priv->config & CFG_STATIC_CHANNEL) &&
43f66a6c
JK
5491 (network->channel != priv->channel)) {
5492 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5493 "because of channel mismatch: %d != %d.\n",
5494 escape_essid(network->ssid, network->ssid_len),
5495 MAC_ARG(network->bssid),
5496 network->channel, priv->channel);
5497 return 0;
5498 }
bf79451e 5499
43f66a6c 5500 /* Verify privacy compatability */
bf79451e 5501 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
43f66a6c
JK
5502 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5503 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5504 "because of privacy mismatch: %s != %s.\n",
5505 escape_essid(network->ssid, network->ssid_len),
5506 MAC_ARG(network->bssid),
bf79451e 5507 priv->capability & CAP_PRIVACY_ON ? "on" :
43f66a6c 5508 "off",
bf79451e 5509 network->capability &
0edd5b44 5510 WLAN_CAPABILITY_PRIVACY ? "on" : "off");
43f66a6c
JK
5511 return 0;
5512 }
bf79451e 5513
cdd1fa1e
HL
5514 if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
5515 network->rsn_ie_len > 0)) {
5516 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5517 "because of WPA capability mismatch.\n",
5518 escape_essid(network->ssid, network->ssid_len),
5519 MAC_ARG(network->bssid));
5520 return 0;
5521 }
5522
bf79451e 5523 if ((priv->config & CFG_STATIC_BSSID) &&
43f66a6c
JK
5524 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5525 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5526 "because of BSSID mismatch: " MAC_FMT ".\n",
5527 escape_essid(network->ssid, network->ssid_len),
0edd5b44 5528 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
43f66a6c
JK
5529 return 0;
5530 }
bf79451e 5531
43f66a6c
JK
5532 /* Filter out any incompatible freq / mode combinations */
5533 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5534 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5535 "because of invalid frequency/mode "
5536 "combination.\n",
5537 escape_essid(network->ssid, network->ssid_len),
5538 MAC_ARG(network->bssid));
5539 return 0;
5540 }
bf79451e 5541
1fe0adb4
LH
5542 /* Filter out invalid channel in current GEO */
5543 if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
5544 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5545 "because of invalid channel in current GEO\n",
5546 escape_essid(network->ssid, network->ssid_len),
5547 MAC_ARG(network->bssid));
5548 return 0;
5549 }
5550
ea2b26e0
JK
5551 /* Ensure that the rates supported by the driver are compatible with
5552 * this AP, including verification of basic rates (mandatory) */
5553 if (!ipw_compatible_rates(priv, network, &rates)) {
5554 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5555 "because configured rate mask excludes "
5556 "AP mandatory rate.\n",
5557 escape_essid(network->ssid, network->ssid_len),
5558 MAC_ARG(network->bssid));
5559 return 0;
5560 }
5561
43f66a6c
JK
5562 if (rates.num_rates == 0) {
5563 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5564 "because of no compatible rates.\n",
5565 escape_essid(network->ssid, network->ssid_len),
5566 MAC_ARG(network->bssid));
5567 return 0;
5568 }
bf79451e 5569
43f66a6c
JK
5570 /* TODO: Perform any further minimal comparititive tests. We do not
5571 * want to put too much policy logic here; intelligent scan selection
5572 * should occur within a generic IEEE 802.11 user space tool. */
5573
5574 /* Set up 'new' AP to this network */
5575 ipw_copy_rates(&match->rates, &rates);
5576 match->network = network;
5577
5578 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' is a viable match.\n",
5579 escape_essid(network->ssid, network->ssid_len),
5580 MAC_ARG(network->bssid));
5581
5582 return 1;
5583}
5584
bf79451e 5585static void ipw_adhoc_create(struct ipw_priv *priv,
0edd5b44 5586 struct ieee80211_network *network)
43f66a6c 5587{
1fe0adb4 5588 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
afbf30a2
JK
5589 int i;
5590
43f66a6c
JK
5591 /*
5592 * For the purposes of scanning, we can set our wireless mode
5593 * to trigger scans across combinations of bands, but when it
5594 * comes to creating a new ad-hoc network, we have tell the FW
5595 * exactly which band to use.
5596 *
bf79451e 5597 * We also have the possibility of an invalid channel for the
43f66a6c
JK
5598 * chossen band. Attempting to create a new ad-hoc network
5599 * with an invalid channel for wireless mode will trigger a
5600 * FW fatal error.
afbf30a2 5601 *
43f66a6c 5602 */
1fe0adb4 5603 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
afbf30a2
JK
5604 case IEEE80211_52GHZ_BAND:
5605 network->mode = IEEE_A;
1fe0adb4 5606 i = ipw_channel_to_index(priv->ieee, priv->channel);
afbf30a2
JK
5607 if (i == -1)
5608 BUG();
5609 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5610 IPW_WARNING("Overriding invalid channel\n");
5611 priv->channel = geo->a[0].channel;
5612 }
5613 break;
5614
5615 case IEEE80211_24GHZ_BAND:
5616 if (priv->ieee->mode & IEEE_G)
5617 network->mode = IEEE_G;
5618 else
5619 network->mode = IEEE_B;
1fe0adb4
LH
5620 i = ipw_channel_to_index(priv->ieee, priv->channel);
5621 if (i == -1)
5622 BUG();
5623 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5624 IPW_WARNING("Overriding invalid channel\n");
5625 priv->channel = geo->bg[0].channel;
5626 }
afbf30a2
JK
5627 break;
5628
5629 default:
43f66a6c
JK
5630 IPW_WARNING("Overriding invalid channel\n");
5631 if (priv->ieee->mode & IEEE_A) {
5632 network->mode = IEEE_A;
b095c381 5633 priv->channel = geo->a[0].channel;
43f66a6c
JK
5634 } else if (priv->ieee->mode & IEEE_G) {
5635 network->mode = IEEE_G;
b095c381 5636 priv->channel = geo->bg[0].channel;
43f66a6c
JK
5637 } else {
5638 network->mode = IEEE_B;
b095c381 5639 priv->channel = geo->bg[0].channel;
43f66a6c 5640 }
afbf30a2
JK
5641 break;
5642 }
43f66a6c
JK
5643
5644 network->channel = priv->channel;
5645 priv->config |= CFG_ADHOC_PERSIST;
5646 ipw_create_bssid(priv, network->bssid);
5647 network->ssid_len = priv->essid_len;
5648 memcpy(network->ssid, priv->essid, priv->essid_len);
5649 memset(&network->stats, 0, sizeof(network->stats));
5650 network->capability = WLAN_CAPABILITY_IBSS;
ea2b26e0
JK
5651 if (!(priv->config & CFG_PREAMBLE_LONG))
5652 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
43f66a6c
JK
5653 if (priv->capability & CAP_PRIVACY_ON)
5654 network->capability |= WLAN_CAPABILITY_PRIVACY;
5655 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
0edd5b44 5656 memcpy(network->rates, priv->rates.supported_rates, network->rates_len);
43f66a6c 5657 network->rates_ex_len = priv->rates.num_rates - network->rates_len;
bf79451e 5658 memcpy(network->rates_ex,
43f66a6c
JK
5659 &priv->rates.supported_rates[network->rates_len],
5660 network->rates_ex_len);
5661 network->last_scanned = 0;
5662 network->flags = 0;
5663 network->last_associate = 0;
5664 network->time_stamp[0] = 0;
5665 network->time_stamp[1] = 0;
0edd5b44
JG
5666 network->beacon_interval = 100; /* Default */
5667 network->listen_interval = 10; /* Default */
5668 network->atim_window = 0; /* Default */
43f66a6c
JK
5669 network->wpa_ie_len = 0;
5670 network->rsn_ie_len = 0;
43f66a6c
JK
5671}
5672
b095c381
JK
5673static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5674{
5675 struct ipw_tgi_tx_key *key;
5676 struct host_cmd cmd = {
5677 .cmd = IPW_CMD_TGI_TX_KEY,
5678 .len = sizeof(*key)
5679 };
5680
5681 if (!(priv->ieee->sec.flags & (1 << index)))
5682 return;
5683
5684 key = (struct ipw_tgi_tx_key *)&cmd.param;
5685 key->key_id = index;
5686 memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5687 key->security_type = type;
5688 key->station_index = 0; /* always 0 for BSS */
5689 key->flags = 0;
5690 /* 0 for new key; previous value of counter (after fatal error) */
5691 key->tx_counter[0] = 0;
5692 key->tx_counter[1] = 0;
5693
9ddf84f6 5694 ipw_send_cmd(priv, &cmd);
b095c381
JK
5695}
5696
5697static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
43f66a6c
JK
5698{
5699 struct ipw_wep_key *key;
5700 int i;
5701 struct host_cmd cmd = {
5702 .cmd = IPW_CMD_WEP_KEY,
5703 .len = sizeof(*key)
5704 };
5705
5706 key = (struct ipw_wep_key *)&cmd.param;
5707 key->cmd_id = DINO_CMD_WEP_KEY;
5708 key->seq_num = 0;
5709
b095c381
JK
5710 /* Note: AES keys cannot be set for multiple times.
5711 * Only set it at the first time. */
bf79451e 5712 for (i = 0; i < 4; i++) {
b095c381
JK
5713 key->key_index = i | type;
5714 if (!(priv->ieee->sec.flags & (1 << i))) {
43f66a6c 5715 key->key_size = 0;
b095c381 5716 continue;
43f66a6c
JK
5717 }
5718
b095c381
JK
5719 key->key_size = priv->ieee->sec.key_sizes[i];
5720 memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
5721
9ddf84f6 5722 ipw_send_cmd(priv, &cmd);
bf79451e 5723 }
43f66a6c
JK
5724}
5725
1fbfea54
ZY
5726static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
5727{
5728 if (priv->ieee->host_encrypt)
5729 return;
5730
5731 switch (level) {
5732 case SEC_LEVEL_3:
5733 priv->sys_config.disable_unicast_decryption = 0;
5734 priv->ieee->host_decrypt = 0;
5735 break;
5736 case SEC_LEVEL_2:
5737 priv->sys_config.disable_unicast_decryption = 1;
5738 priv->ieee->host_decrypt = 1;
5739 break;
5740 case SEC_LEVEL_1:
5741 priv->sys_config.disable_unicast_decryption = 0;
5742 priv->ieee->host_decrypt = 0;
5743 break;
5744 case SEC_LEVEL_0:
5745 priv->sys_config.disable_unicast_decryption = 1;
5746 break;
5747 default:
5748 break;
5749 }
5750}
5751
5752static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
5753{
5754 if (priv->ieee->host_encrypt)
5755 return;
5756
5757 switch (level) {
5758 case SEC_LEVEL_3:
5759 priv->sys_config.disable_multicast_decryption = 0;
5760 break;
5761 case SEC_LEVEL_2:
5762 priv->sys_config.disable_multicast_decryption = 1;
5763 break;
5764 case SEC_LEVEL_1:
5765 priv->sys_config.disable_multicast_decryption = 0;
5766 break;
5767 case SEC_LEVEL_0:
5768 priv->sys_config.disable_multicast_decryption = 1;
5769 break;
5770 default:
5771 break;
5772 }
5773}
5774
b095c381
JK
5775static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5776{
5777 switch (priv->ieee->sec.level) {
5778 case SEC_LEVEL_3:
d8bad6df
ZY
5779 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5780 ipw_send_tgi_tx_key(priv,
5781 DCT_FLAG_EXT_SECURITY_CCM,
5782 priv->ieee->sec.active_key);
afbf30a2 5783
567deaf6
HL
5784 if (!priv->ieee->host_mc_decrypt)
5785 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
b095c381
JK
5786 break;
5787 case SEC_LEVEL_2:
d8bad6df
ZY
5788 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5789 ipw_send_tgi_tx_key(priv,
5790 DCT_FLAG_EXT_SECURITY_TKIP,
5791 priv->ieee->sec.active_key);
b095c381
JK
5792 break;
5793 case SEC_LEVEL_1:
5794 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
29cb843e
HL
5795 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
5796 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
b095c381
JK
5797 break;
5798 case SEC_LEVEL_0:
5799 default:
5800 break;
5801 }
5802}
5803
43f66a6c
JK
5804static void ipw_adhoc_check(void *data)
5805{
5806 struct ipw_priv *priv = data;
bf79451e 5807
afbf30a2 5808 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
43f66a6c 5809 !(priv->config & CFG_ADHOC_PERSIST)) {
afbf30a2
JK
5810 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
5811 IPW_DL_STATE | IPW_DL_ASSOC,
5812 "Missed beacon: %d - disassociate\n",
5813 priv->missed_adhoc_beacons);
43f66a6c
JK
5814 ipw_remove_current_network(priv);
5815 ipw_disassociate(priv);
5816 return;
5817 }
5818
bf79451e 5819 queue_delayed_work(priv->workqueue, &priv->adhoc_check,
43f66a6c
JK
5820 priv->assoc_request.beacon_interval);
5821}
5822
c848d0af
JK
5823static void ipw_bg_adhoc_check(void *data)
5824{
5825 struct ipw_priv *priv = data;
5826 down(&priv->sem);
5827 ipw_adhoc_check(data);
5828 up(&priv->sem);
5829}
5830
43f66a6c
JK
5831#ifdef CONFIG_IPW_DEBUG
5832static void ipw_debug_config(struct ipw_priv *priv)
5833{
5834 IPW_DEBUG_INFO("Scan completed, no valid APs matched "
5835 "[CFG 0x%08X]\n", priv->config);
5836 if (priv->config & CFG_STATIC_CHANNEL)
0edd5b44 5837 IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel);
43f66a6c
JK
5838 else
5839 IPW_DEBUG_INFO("Channel unlocked.\n");
5840 if (priv->config & CFG_STATIC_ESSID)
bf79451e 5841 IPW_DEBUG_INFO("ESSID locked to '%s'\n",
0edd5b44 5842 escape_essid(priv->essid, priv->essid_len));
43f66a6c
JK
5843 else
5844 IPW_DEBUG_INFO("ESSID unlocked.\n");
5845 if (priv->config & CFG_STATIC_BSSID)
ea2b26e0
JK
5846 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
5847 MAC_ARG(priv->bssid));
43f66a6c
JK
5848 else
5849 IPW_DEBUG_INFO("BSSID unlocked.\n");
5850 if (priv->capability & CAP_PRIVACY_ON)
5851 IPW_DEBUG_INFO("PRIVACY on\n");
5852 else
5853 IPW_DEBUG_INFO("PRIVACY off\n");
5854 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);
5855}
5856#else
8d45ff7d 5857#define ipw_debug_config(x) do {} while (0)
43f66a6c
JK
5858#endif
5859
b095c381 5860static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
43f66a6c
JK
5861{
5862 /* TODO: Verify that this works... */
5863 struct ipw_fixed_rate fr = {
5864 .tx_rates = priv->rates_mask
5865 };
5866 u32 reg;
5867 u16 mask = 0;
5868
bf79451e 5869 /* Identify 'current FW band' and match it with the fixed
43f66a6c 5870 * Tx rates */
bf79451e 5871
43f66a6c 5872 switch (priv->ieee->freq_band) {
0edd5b44 5873 case IEEE80211_52GHZ_BAND: /* A only */
43f66a6c
JK
5874 /* IEEE_A */
5875 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
5876 /* Invalid fixed rate mask */
ea2b26e0
JK
5877 IPW_DEBUG_WX
5878 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5879 fr.tx_rates = 0;
5880 break;
5881 }
bf79451e 5882
43f66a6c
JK
5883 fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
5884 break;
5885
0edd5b44 5886 default: /* 2.4Ghz or Mixed */
43f66a6c 5887 /* IEEE_B */
b095c381 5888 if (mode == IEEE_B) {
43f66a6c
JK
5889 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
5890 /* Invalid fixed rate mask */
ea2b26e0
JK
5891 IPW_DEBUG_WX
5892 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5893 fr.tx_rates = 0;
5894 }
5895 break;
bf79451e 5896 }
43f66a6c
JK
5897
5898 /* IEEE_G */
5899 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
5900 IEEE80211_OFDM_RATES_MASK)) {
5901 /* Invalid fixed rate mask */
ea2b26e0
JK
5902 IPW_DEBUG_WX
5903 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5904 fr.tx_rates = 0;
5905 break;
5906 }
5907
5908 if (IEEE80211_OFDM_RATE_6MB_MASK & fr.tx_rates) {
5909 mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1);
5910 fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
5911 }
bf79451e 5912
43f66a6c
JK
5913 if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) {
5914 mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1);
5915 fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
5916 }
bf79451e 5917
43f66a6c
JK
5918 if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) {
5919 mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1);
5920 fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
5921 }
bf79451e 5922
43f66a6c
JK
5923 fr.tx_rates |= mask;
5924 break;
5925 }
5926
5927 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
0edd5b44 5928 ipw_write_reg32(priv, reg, *(u32 *) & fr);
43f66a6c
JK
5929}
5930
ea2b26e0 5931static void ipw_abort_scan(struct ipw_priv *priv)
43f66a6c
JK
5932{
5933 int err;
5934
ea2b26e0
JK
5935 if (priv->status & STATUS_SCAN_ABORTING) {
5936 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5937 return;
5938 }
5939 priv->status |= STATUS_SCAN_ABORTING;
43f66a6c 5940
ea2b26e0
JK
5941 err = ipw_send_scan_abort(priv);
5942 if (err)
5943 IPW_DEBUG_HC("Request to abort scan failed.\n");
5944}
5945
afbf30a2
JK
5946static void ipw_add_scan_channels(struct ipw_priv *priv,
5947 struct ipw_scan_request_ext *scan,
5948 int scan_type)
ea2b26e0 5949{
ea2b26e0 5950 int channel_index = 0;
b095c381 5951 const struct ieee80211_geo *geo;
afbf30a2 5952 int i;
b095c381 5953
1fe0adb4 5954 geo = ipw_get_geo(priv->ieee);
43f66a6c 5955
afbf30a2
JK
5956 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5957 int start = channel_index;
5958 for (i = 0; i < geo->a_channels; i++) {
5959 if ((priv->status & STATUS_ASSOCIATED) &&
5960 geo->a[i].channel == priv->channel)
5961 continue;
5962 channel_index++;
5963 scan->channels_list[channel_index] = geo->a[i].channel;
1fe0adb4
LH
5964 ipw_set_scan_type(scan, channel_index,
5965 geo->a[i].
5966 flags & IEEE80211_CH_PASSIVE_ONLY ?
5967 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
5968 scan_type);
afbf30a2
JK
5969 }
5970
5971 if (start != channel_index) {
5972 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
5973 (channel_index - start);
5974 channel_index++;
5975 }
5976 }
5977
5978 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5979 int start = channel_index;
5980 if (priv->config & CFG_SPEED_SCAN) {
1fe0adb4 5981 int index;
afbf30a2
JK
5982 u8 channels[IEEE80211_24GHZ_CHANNELS] = {
5983 /* nop out the list */
5984 [0] = 0
5985 };
5986
5987 u8 channel;
5988 while (channel_index < IPW_SCAN_CHANNELS) {
5989 channel =
5990 priv->speed_scan[priv->speed_scan_pos];
5991 if (channel == 0) {
5992 priv->speed_scan_pos = 0;
5993 channel = priv->speed_scan[0];
5994 }
5995 if ((priv->status & STATUS_ASSOCIATED) &&
5996 channel == priv->channel) {
5997 priv->speed_scan_pos++;
5998 continue;
5999 }
6000
6001 /* If this channel has already been
6002 * added in scan, break from loop
6003 * and this will be the first channel
6004 * in the next scan.
6005 */
6006 if (channels[channel - 1] != 0)
6007 break;
6008
6009 channels[channel - 1] = 1;
6010 priv->speed_scan_pos++;
6011 channel_index++;
6012 scan->channels_list[channel_index] = channel;
1fe0adb4
LH
6013 index =
6014 ipw_channel_to_index(priv->ieee, channel);
afbf30a2 6015 ipw_set_scan_type(scan, channel_index,
1fe0adb4
LH
6016 geo->bg[index].
6017 flags &
6018 IEEE80211_CH_PASSIVE_ONLY ?
6019 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6020 : scan_type);
afbf30a2
JK
6021 }
6022 } else {
6023 for (i = 0; i < geo->bg_channels; i++) {
6024 if ((priv->status & STATUS_ASSOCIATED) &&
6025 geo->bg[i].channel == priv->channel)
6026 continue;
6027 channel_index++;
6028 scan->channels_list[channel_index] =
6029 geo->bg[i].channel;
6030 ipw_set_scan_type(scan, channel_index,
1fe0adb4
LH
6031 geo->bg[i].
6032 flags &
6033 IEEE80211_CH_PASSIVE_ONLY ?
6034 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6035 : scan_type);
afbf30a2
JK
6036 }
6037 }
6038
6039 if (start != channel_index) {
6040 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
6041 (channel_index - start);
6042 }
6043 }
6044}
6045
6046static int ipw_request_scan(struct ipw_priv *priv)
6047{
6048 struct ipw_scan_request_ext scan;
6049 int err = 0, scan_type;
6050
6051 if (!(priv->status & STATUS_INIT) ||
6052 (priv->status & STATUS_EXIT_PENDING))
6053 return 0;
6054
6055 down(&priv->sem);
6056
ea2b26e0 6057 if (priv->status & STATUS_SCANNING) {
a613bffd 6058 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
ea2b26e0 6059 priv->status |= STATUS_SCAN_PENDING;
b095c381 6060 goto done;
ea2b26e0 6061 }
43f66a6c 6062
afbf30a2
JK
6063 if (!(priv->status & STATUS_SCAN_FORCED) &&
6064 priv->status & STATUS_SCAN_ABORTING) {
ea2b26e0
JK
6065 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
6066 priv->status |= STATUS_SCAN_PENDING;
b095c381 6067 goto done;
43f66a6c
JK
6068 }
6069
ea2b26e0
JK
6070 if (priv->status & STATUS_RF_KILL_MASK) {
6071 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
6072 priv->status |= STATUS_SCAN_PENDING;
b095c381 6073 goto done;
ea2b26e0 6074 }
43f66a6c 6075
ea2b26e0 6076 memset(&scan, 0, sizeof(scan));
43f66a6c 6077
b095c381
JK
6078 if (priv->config & CFG_SPEED_SCAN)
6079 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6080 cpu_to_le16(30);
6081 else
6082 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6083 cpu_to_le16(20);
6084
a613bffd
JK
6085 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
6086 cpu_to_le16(20);
1fe0adb4 6087 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
43f66a6c 6088
a613bffd 6089 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
43f66a6c 6090
b095c381 6091#ifdef CONFIG_IPW2200_MONITOR
ea2b26e0 6092 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
afbf30a2 6093 u8 channel;
b095c381 6094 u8 band = 0;
43f66a6c 6095
1fe0adb4 6096 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
b095c381 6097 case IEEE80211_52GHZ_BAND:
ea2b26e0 6098 band = (u8) (IPW_A_MODE << 6) | 1;
b095c381
JK
6099 channel = priv->channel;
6100 break;
ea2b26e0 6101
b095c381 6102 case IEEE80211_24GHZ_BAND:
ea2b26e0 6103 band = (u8) (IPW_B_MODE << 6) | 1;
b095c381
JK
6104 channel = priv->channel;
6105 break;
ea2b26e0 6106
b095c381 6107 default:
ea2b26e0
JK
6108 band = (u8) (IPW_B_MODE << 6) | 1;
6109 channel = 9;
b095c381 6110 break;
ea2b26e0
JK
6111 }
6112
b095c381
JK
6113 scan.channels_list[0] = band;
6114 scan.channels_list[1] = channel;
6115 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
ea2b26e0 6116
b095c381
JK
6117 /* NOTE: The card will sit on this channel for this time
6118 * period. Scan aborts are timing sensitive and frequently
6119 * result in firmware restarts. As such, it is best to
6120 * set a small dwell_time here and just keep re-issuing
6121 * scans. Otherwise fast channel hopping will not actually
6122 * hop channels.
6123 *
6124 * TODO: Move SPEED SCAN support to all modes and bands */
a613bffd
JK
6125 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6126 cpu_to_le16(2000);
43f66a6c 6127 } else {
b095c381
JK
6128#endif /* CONFIG_IPW2200_MONITOR */
6129 /* If we are roaming, then make this a directed scan for the
6130 * current network. Otherwise, ensure that every other scan
6131 * is a fast channel hop scan */
6132 if ((priv->status & STATUS_ROAMING)
6133 || (!(priv->status & STATUS_ASSOCIATED)
6134 && (priv->config & CFG_STATIC_ESSID)
6135 && (le32_to_cpu(scan.full_scan_index) % 2))) {
ea2b26e0
JK
6136 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6137 if (err) {
b095c381
JK
6138 IPW_DEBUG_HC("Attempt to send SSID command "
6139 "failed.\n");
6140 goto done;
ea2b26e0 6141 }
43f66a6c 6142
ea2b26e0 6143 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
afbf30a2 6144 } else
ea2b26e0 6145 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
ea2b26e0 6146
afbf30a2 6147 ipw_add_scan_channels(priv, &scan, scan_type);
b095c381 6148#ifdef CONFIG_IPW2200_MONITOR
43f66a6c 6149 }
ea2b26e0 6150#endif
bf79451e 6151
ea2b26e0 6152 err = ipw_send_scan_request_ext(priv, &scan);
43f66a6c 6153 if (err) {
ea2b26e0 6154 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
b095c381 6155 goto done;
43f66a6c
JK
6156 }
6157
ea2b26e0
JK
6158 priv->status |= STATUS_SCANNING;
6159 priv->status &= ~STATUS_SCAN_PENDING;
afbf30a2
JK
6160 queue_delayed_work(priv->workqueue, &priv->scan_check,
6161 IPW_SCAN_CHECK_WATCHDOG);
b095c381 6162 done:
c848d0af 6163 up(&priv->sem);
b095c381 6164 return err;
c848d0af
JK
6165}
6166
6167static void ipw_bg_abort_scan(void *data)
6168{
6169 struct ipw_priv *priv = data;
6170 down(&priv->sem);
6171 ipw_abort_scan(data);
6172 up(&priv->sem);
6173}
6174
ea2b26e0
JK
6175static int ipw_wpa_enable(struct ipw_priv *priv, int value)
6176{
b095c381
JK
6177 /* This is called when wpa_supplicant loads and closes the driver
6178 * interface. */
cdd1fa1e 6179 priv->ieee->wpa_enabled = value;
b095c381 6180 return 0;
ea2b26e0
JK
6181}
6182
ea2b26e0
JK
6183static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6184{
6185 struct ieee80211_device *ieee = priv->ieee;
6186 struct ieee80211_security sec = {
6187 .flags = SEC_AUTH_MODE,
6188 };
6189 int ret = 0;
6190
afbf30a2 6191 if (value & IW_AUTH_ALG_SHARED_KEY) {
ea2b26e0
JK
6192 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
6193 ieee->open_wep = 0;
afbf30a2 6194 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
ea2b26e0
JK
6195 sec.auth_mode = WLAN_AUTH_OPEN;
6196 ieee->open_wep = 1;
afbf30a2
JK
6197 } else
6198 return -EINVAL;
ea2b26e0
JK
6199
6200 if (ieee->set_security)
6201 ieee->set_security(ieee->dev, &sec);
6202 else
6203 ret = -EOPNOTSUPP;
6204
6205 return ret;
6206}
6207
afbf30a2
JK
6208void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
6209{
6210 /* make sure WPA is enabled */
6211 ipw_wpa_enable(priv, 1);
6212
6213 ipw_disassociate(priv);
6214}
6215
6216static int ipw_set_rsn_capa(struct ipw_priv *priv,
6217 char *capabilities, int length)
6218{
6219 struct host_cmd cmd = {
6220 .cmd = IPW_CMD_RSN_CAPABILITIES,
6221 .len = length,
6222 };
6223
6224 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6225
6226 memcpy(cmd.param, capabilities, length);
9ddf84f6 6227 return ipw_send_cmd(priv, &cmd);
afbf30a2
JK
6228}
6229
b095c381 6230/*
afbf30a2
JK
6231 * WE-18 support
6232 */
6233
6234/* SIOCSIWGENIE */
6235static int ipw_wx_set_genie(struct net_device *dev,
6236 struct iw_request_info *info,
6237 union iwreq_data *wrqu, char *extra)
ea2b26e0 6238{
afbf30a2
JK
6239 struct ipw_priv *priv = ieee80211_priv(dev);
6240 struct ieee80211_device *ieee = priv->ieee;
6241 u8 *buf;
6242 int err = 0;
ea2b26e0 6243
afbf30a2
JK
6244 if (wrqu->data.length > MAX_WPA_IE_LEN ||
6245 (wrqu->data.length && extra == NULL))
6246 return -EINVAL;
ea2b26e0 6247
afbf30a2
JK
6248 //down(&priv->sem);
6249
6250 //if (!ieee->wpa_enabled) {
6251 // err = -EOPNOTSUPP;
6252 // goto out;
6253 //}
6254
6255 if (wrqu->data.length) {
6256 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
6257 if (buf == NULL) {
6258 err = -ENOMEM;
6259 goto out;
6260 }
6261
6262 memcpy(buf, extra, wrqu->data.length);
6263 kfree(ieee->wpa_ie);
6264 ieee->wpa_ie = buf;
6265 ieee->wpa_ie_len = wrqu->data.length;
b095c381 6266 } else {
afbf30a2
JK
6267 kfree(ieee->wpa_ie);
6268 ieee->wpa_ie = NULL;
6269 ieee->wpa_ie_len = 0;
ea2b26e0 6270 }
afbf30a2
JK
6271
6272 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6273 out:
6274 //up(&priv->sem);
6275 return err;
6276}
6277
6278/* SIOCGIWGENIE */
6279static int ipw_wx_get_genie(struct net_device *dev,
6280 struct iw_request_info *info,
6281 union iwreq_data *wrqu, char *extra)
6282{
6283 struct ipw_priv *priv = ieee80211_priv(dev);
6284 struct ieee80211_device *ieee = priv->ieee;
6285 int err = 0;
6286
6287 //down(&priv->sem);
6288
6289 //if (!ieee->wpa_enabled) {
6290 // err = -EOPNOTSUPP;
6291 // goto out;
6292 //}
6293
6294 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6295 wrqu->data.length = 0;
6296 goto out;
6297 }
6298
6299 if (wrqu->data.length < ieee->wpa_ie_len) {
6300 err = -E2BIG;
6301 goto out;
6302 }
6303
6304 wrqu->data.length = ieee->wpa_ie_len;
6305 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6306
6307 out:
6308 //up(&priv->sem);
6309 return err;
6310}
6311
1fbfea54
ZY
6312static int wext_cipher2level(int cipher)
6313{
6314 switch (cipher) {
6315 case IW_AUTH_CIPHER_NONE:
6316 return SEC_LEVEL_0;
6317 case IW_AUTH_CIPHER_WEP40:
6318 case IW_AUTH_CIPHER_WEP104:
6319 return SEC_LEVEL_1;
6320 case IW_AUTH_CIPHER_TKIP:
6321 return SEC_LEVEL_2;
6322 case IW_AUTH_CIPHER_CCMP:
6323 return SEC_LEVEL_3;
6324 default:
6325 return -1;
6326 }
6327}
6328
afbf30a2
JK
6329/* SIOCSIWAUTH */
6330static int ipw_wx_set_auth(struct net_device *dev,
6331 struct iw_request_info *info,
6332 union iwreq_data *wrqu, char *extra)
6333{
6334 struct ipw_priv *priv = ieee80211_priv(dev);
6335 struct ieee80211_device *ieee = priv->ieee;
6336 struct iw_param *param = &wrqu->param;
6337 struct ieee80211_crypt_data *crypt;
6338 unsigned long flags;
6339 int ret = 0;
6340
6341 switch (param->flags & IW_AUTH_INDEX) {
6342 case IW_AUTH_WPA_VERSION:
1fbfea54 6343 break;
afbf30a2 6344 case IW_AUTH_CIPHER_PAIRWISE:
1fbfea54
ZY
6345 ipw_set_hw_decrypt_unicast(priv,
6346 wext_cipher2level(param->value));
6347 break;
afbf30a2 6348 case IW_AUTH_CIPHER_GROUP:
1fbfea54
ZY
6349 ipw_set_hw_decrypt_multicast(priv,
6350 wext_cipher2level(param->value));
6351 break;
afbf30a2
JK
6352 case IW_AUTH_KEY_MGMT:
6353 /*
6354 * ipw2200 does not use these parameters
6355 */
6356 break;
6357
6358 case IW_AUTH_TKIP_COUNTERMEASURES:
6359 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6360 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
6361 IPW_WARNING("Can't set TKIP countermeasures: "
6362 "crypt not set!\n");
6363 break;
6364 }
6365
6366 flags = crypt->ops->get_flags(crypt->priv);
6367
6368 if (param->value)
6369 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6370 else
6371 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6372
6373 crypt->ops->set_flags(flags, crypt->priv);
6374
6375 break;
6376
6377 case IW_AUTH_DROP_UNENCRYPTED:{
6378 /* HACK:
6379 *
6380 * wpa_supplicant calls set_wpa_enabled when the driver
6381 * is loaded and unloaded, regardless of if WPA is being
6382 * used. No other calls are made which can be used to
6383 * determine if encryption will be used or not prior to
6384 * association being expected. If encryption is not being
6385 * used, drop_unencrypted is set to false, else true -- we
6386 * can use this to determine if the CAP_PRIVACY_ON bit should
6387 * be set.
6388 */
6389 struct ieee80211_security sec = {
6390 .flags = SEC_ENABLED,
6391 .enabled = param->value,
6392 };
6393 priv->ieee->drop_unencrypted = param->value;
6394 /* We only change SEC_LEVEL for open mode. Others
6395 * are set by ipw_wpa_set_encryption.
6396 */
6397 if (!param->value) {
6398 sec.flags |= SEC_LEVEL;
6399 sec.level = SEC_LEVEL_0;
6400 } else {
6401 sec.flags |= SEC_LEVEL;
6402 sec.level = SEC_LEVEL_1;
6403 }
6404 if (priv->ieee->set_security)
6405 priv->ieee->set_security(priv->ieee->dev, &sec);
6406 break;
6407 }
6408
6409 case IW_AUTH_80211_AUTH_ALG:
6410 ret = ipw_wpa_set_auth_algs(priv, param->value);
6411 break;
6412
6413 case IW_AUTH_WPA_ENABLED:
6414 ret = ipw_wpa_enable(priv, param->value);
6415 break;
6416
6417 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6418 ieee->ieee802_1x = param->value;
6419 break;
6420
6421 //case IW_AUTH_ROAMING_CONTROL:
6422 case IW_AUTH_PRIVACY_INVOKED:
6423 ieee->privacy_invoked = param->value;
6424 break;
6425
6426 default:
6427 return -EOPNOTSUPP;
6428 }
6429 return ret;
6430}
6431
6432/* SIOCGIWAUTH */
6433static int ipw_wx_get_auth(struct net_device *dev,
6434 struct iw_request_info *info,
6435 union iwreq_data *wrqu, char *extra)
6436{
6437 struct ipw_priv *priv = ieee80211_priv(dev);
6438 struct ieee80211_device *ieee = priv->ieee;
6439 struct ieee80211_crypt_data *crypt;
6440 struct iw_param *param = &wrqu->param;
6441 int ret = 0;
6442
6443 switch (param->flags & IW_AUTH_INDEX) {
6444 case IW_AUTH_WPA_VERSION:
6445 case IW_AUTH_CIPHER_PAIRWISE:
6446 case IW_AUTH_CIPHER_GROUP:
6447 case IW_AUTH_KEY_MGMT:
6448 /*
6449 * wpa_supplicant will control these internally
6450 */
6451 ret = -EOPNOTSUPP;
6452 break;
6453
6454 case IW_AUTH_TKIP_COUNTERMEASURES:
6455 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6456 if (!crypt || !crypt->ops->get_flags) {
6457 IPW_WARNING("Can't get TKIP countermeasures: "
6458 "crypt not set!\n");
6459 break;
6460 }
6461
6462 param->value = (crypt->ops->get_flags(crypt->priv) &
6463 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
6464
6465 break;
6466
6467 case IW_AUTH_DROP_UNENCRYPTED:
6468 param->value = ieee->drop_unencrypted;
6469 break;
6470
6471 case IW_AUTH_80211_AUTH_ALG:
6472 param->value = ieee->sec.auth_mode;
6473 break;
6474
6475 case IW_AUTH_WPA_ENABLED:
6476 param->value = ieee->wpa_enabled;
6477 break;
6478
6479 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6480 param->value = ieee->ieee802_1x;
6481 break;
6482
6483 case IW_AUTH_ROAMING_CONTROL:
6484 case IW_AUTH_PRIVACY_INVOKED:
6485 param->value = ieee->privacy_invoked;
6486 break;
6487
6488 default:
6489 return -EOPNOTSUPP;
6490 }
6491 return 0;
6492}
6493
6494/* SIOCSIWENCODEEXT */
6495static int ipw_wx_set_encodeext(struct net_device *dev,
6496 struct iw_request_info *info,
6497 union iwreq_data *wrqu, char *extra)
6498{
6499 struct ipw_priv *priv = ieee80211_priv(dev);
6500 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6501
6502 if (hwcrypto) {
afbf30a2 6503 if (ext->alg == IW_ENCODE_ALG_TKIP) {
567deaf6
HL
6504 /* IPW HW can't build TKIP MIC,
6505 host decryption still needed */
6506 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6507 priv->ieee->host_mc_decrypt = 1;
6508 else {
6509 priv->ieee->host_encrypt = 0;
6510 priv->ieee->host_encrypt_msdu = 1;
6511 priv->ieee->host_decrypt = 1;
6512 }
afbf30a2
JK
6513 } else {
6514 priv->ieee->host_encrypt = 0;
6515 priv->ieee->host_encrypt_msdu = 0;
6516 priv->ieee->host_decrypt = 0;
567deaf6 6517 priv->ieee->host_mc_decrypt = 0;
afbf30a2
JK
6518 }
6519 }
6520
6521 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
6522}
6523
6524/* SIOCGIWENCODEEXT */
6525static int ipw_wx_get_encodeext(struct net_device *dev,
6526 struct iw_request_info *info,
6527 union iwreq_data *wrqu, char *extra)
6528{
6529 struct ipw_priv *priv = ieee80211_priv(dev);
6530 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
6531}
6532
6533/* SIOCSIWMLME */
6534static int ipw_wx_set_mlme(struct net_device *dev,
6535 struct iw_request_info *info,
6536 union iwreq_data *wrqu, char *extra)
6537{
6538 struct ipw_priv *priv = ieee80211_priv(dev);
6539 struct iw_mlme *mlme = (struct iw_mlme *)extra;
6540 u16 reason;
6541
6542 reason = cpu_to_le16(mlme->reason_code);
6543
6544 switch (mlme->cmd) {
6545 case IW_MLME_DEAUTH:
6546 // silently ignore
6547 break;
6548
6549 case IW_MLME_DISASSOC:
6550 ipw_disassociate(priv);
6551 break;
6552
6553 default:
6554 return -EOPNOTSUPP;
6555 }
6556 return 0;
6557}
afbf30a2
JK
6558
6559#ifdef CONFIG_IPW_QOS
6560
6561/* QoS */
6562/*
6563* get the modulation type of the current network or
6564* the card current mode
6565*/
6566u8 ipw_qos_current_mode(struct ipw_priv * priv)
6567{
6568 u8 mode = 0;
6569
6570 if (priv->status & STATUS_ASSOCIATED) {
6571 unsigned long flags;
6572
6573 spin_lock_irqsave(&priv->ieee->lock, flags);
6574 mode = priv->assoc_network->mode;
6575 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6576 } else {
6577 mode = priv->ieee->mode;
6578 }
6579 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
6580 return mode;
b095c381 6581}
ea2b26e0 6582
b095c381
JK
6583/*
6584* Handle management frame beacon and probe response
6585*/
3b9990cb
JK
6586static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6587 int active_network,
6588 struct ieee80211_network *network)
b095c381
JK
6589{
6590 u32 size = sizeof(struct ieee80211_qos_parameters);
6591
afbf30a2 6592 if (network->capability & WLAN_CAPABILITY_IBSS)
b095c381
JK
6593 network->qos_data.active = network->qos_data.supported;
6594
6595 if (network->flags & NETWORK_HAS_QOS_MASK) {
afbf30a2
JK
6596 if (active_network &&
6597 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
b095c381
JK
6598 network->qos_data.active = network->qos_data.supported;
6599
6600 if ((network->qos_data.active == 1) && (active_network == 1) &&
6601 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6602 (network->qos_data.old_param_count !=
6603 network->qos_data.param_count)) {
6604 network->qos_data.old_param_count =
6605 network->qos_data.param_count;
6606 schedule_work(&priv->qos_activate);
afbf30a2
JK
6607 IPW_DEBUG_QOS("QoS parameters change call "
6608 "qos_activate\n");
b095c381 6609 }
ea2b26e0 6610 } else {
afbf30a2
JK
6611 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
6612 memcpy(&network->qos_data.parameters,
b095c381 6613 &def_parameters_CCK, size);
afbf30a2
JK
6614 else
6615 memcpy(&network->qos_data.parameters,
b095c381 6616 &def_parameters_OFDM, size);
afbf30a2 6617
b095c381
JK
6618 if ((network->qos_data.active == 1) && (active_network == 1)) {
6619 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
6620 schedule_work(&priv->qos_activate);
6621 }
6622
6623 network->qos_data.active = 0;
6624 network->qos_data.supported = 0;
ea2b26e0 6625 }
afbf30a2
JK
6626 if ((priv->status & STATUS_ASSOCIATED) &&
6627 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6628 if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
6629 if ((network->capability & WLAN_CAPABILITY_IBSS) &&
6630 !(network->flags & NETWORK_EMPTY_ESSID))
b095c381 6631 if ((network->ssid_len ==
afbf30a2
JK
6632 priv->assoc_network->ssid_len) &&
6633 !memcmp(network->ssid,
6634 priv->assoc_network->ssid,
6635 network->ssid_len)) {
b095c381
JK
6636 queue_work(priv->workqueue,
6637 &priv->merge_networks);
6638 }
b095c381 6639 }
ea2b26e0 6640
b095c381
JK
6641 return 0;
6642}
6643
6644/*
6645* This function set up the firmware to support QoS. It sends
6646* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
6647*/
6648static int ipw_qos_activate(struct ipw_priv *priv,
6649 struct ieee80211_qos_data *qos_network_data)
6650{
6651 int err;
6652 struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
6653 struct ieee80211_qos_parameters *active_one = NULL;
6654 u32 size = sizeof(struct ieee80211_qos_parameters);
6655 u32 burst_duration;
6656 int i;
6657 u8 type;
6658
6659 type = ipw_qos_current_mode(priv);
6660
6661 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
6662 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
6663 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
6664 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
6665
6666 if (qos_network_data == NULL) {
6667 if (type == IEEE_B) {
6668 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
6669 active_one = &def_parameters_CCK;
6670 } else
6671 active_one = &def_parameters_OFDM;
6672
afbf30a2 6673 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
b095c381
JK
6674 burst_duration = ipw_qos_get_burst_duration(priv);
6675 for (i = 0; i < QOS_QUEUE_NUM; i++)
afbf30a2
JK
6676 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
6677 (u16) burst_duration;
6678 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
b095c381
JK
6679 if (type == IEEE_B) {
6680 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
6681 type);
6682 if (priv->qos_data.qos_enable == 0)
6683 active_one = &def_parameters_CCK;
6684 else
6685 active_one = priv->qos_data.def_qos_parm_CCK;
6686 } else {
6687 if (priv->qos_data.qos_enable == 0)
6688 active_one = &def_parameters_OFDM;
6689 else
6690 active_one = priv->qos_data.def_qos_parm_OFDM;
6691 }
afbf30a2 6692 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
b095c381
JK
6693 } else {
6694 unsigned long flags;
6695 int active;
6696
6697 spin_lock_irqsave(&priv->ieee->lock, flags);
6698 active_one = &(qos_network_data->parameters);
6699 qos_network_data->old_param_count =
6700 qos_network_data->param_count;
afbf30a2 6701 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
b095c381
JK
6702 active = qos_network_data->supported;
6703 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6704
6705 if (active == 0) {
6706 burst_duration = ipw_qos_get_burst_duration(priv);
6707 for (i = 0; i < QOS_QUEUE_NUM; i++)
6708 qos_parameters[QOS_PARAM_SET_ACTIVE].
6709 tx_op_limit[i] = (u16) burst_duration;
6710 }
6711 }
6712
6713 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
afbf30a2
JK
6714 err = ipw_send_qos_params_command(priv,
6715 (struct ieee80211_qos_parameters *)
6716 &(qos_parameters[0]));
b095c381
JK
6717 if (err)
6718 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
6719
6720 return err;
6721}
6722
6723/*
6724* send IPW_CMD_WME_INFO to the firmware
6725*/
6726static int ipw_qos_set_info_element(struct ipw_priv *priv)
6727{
6728 int ret = 0;
6729 struct ieee80211_qos_information_element qos_info;
6730
6731 if (priv == NULL)
6732 return -1;
6733
6734 qos_info.elementID = QOS_ELEMENT_ID;
6735 qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
6736
6737 qos_info.version = QOS_VERSION_1;
6738 qos_info.ac_info = 0;
6739
6740 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
6741 qos_info.qui_type = QOS_OUI_TYPE;
6742 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
6743
6744 ret = ipw_send_qos_info_command(priv, &qos_info);
6745 if (ret != 0) {
6746 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
6747 }
6748 return ret;
6749}
6750
6751/*
6752* Set the QoS parameter with the association request structure
6753*/
6754static int ipw_qos_association(struct ipw_priv *priv,
6755 struct ieee80211_network *network)
6756{
6757 int err = 0;
6758 struct ieee80211_qos_data *qos_data = NULL;
6759 struct ieee80211_qos_data ibss_data = {
6760 .supported = 1,
6761 .active = 1,
6762 };
6763
6764 switch (priv->ieee->iw_mode) {
6765 case IW_MODE_ADHOC:
6766 if (!(network->capability & WLAN_CAPABILITY_IBSS))
6767 BUG();
6768
6769 qos_data = &ibss_data;
6770 break;
6771
6772 case IW_MODE_INFRA:
6773 qos_data = &network->qos_data;
6774 break;
6775
6776 default:
6777 BUG();
6778 break;
6779 }
6780
6781 err = ipw_qos_activate(priv, qos_data);
6782 if (err) {
6783 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
6784 return err;
6785 }
6786
6787 if (priv->qos_data.qos_enable && qos_data->supported) {
6788 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
6789 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
6790 return ipw_qos_set_info_element(priv);
6791 }
6792
6793 return 0;
6794}
6795
6796/*
6797* handling the beaconing responces. if we get different QoS setting
6798* of the network from the the associated setting adjust the QoS
6799* setting
6800*/
6801static int ipw_qos_association_resp(struct ipw_priv *priv,
6802 struct ieee80211_network *network)
6803{
6804 int ret = 0;
6805 unsigned long flags;
6806 u32 size = sizeof(struct ieee80211_qos_parameters);
6807 int set_qos_param = 0;
6808
afbf30a2
JK
6809 if ((priv == NULL) || (network == NULL) ||
6810 (priv->assoc_network == NULL))
b095c381
JK
6811 return ret;
6812
6813 if (!(priv->status & STATUS_ASSOCIATED))
6814 return ret;
6815
afbf30a2 6816 if ((priv->ieee->iw_mode != IW_MODE_INFRA))
b095c381 6817 return ret;
b095c381
JK
6818
6819 spin_lock_irqsave(&priv->ieee->lock, flags);
6820 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
afbf30a2 6821 memcpy(&priv->assoc_network->qos_data, &network->qos_data,
b095c381
JK
6822 sizeof(struct ieee80211_qos_data));
6823 priv->assoc_network->qos_data.active = 1;
6824 if ((network->qos_data.old_param_count !=
6825 network->qos_data.param_count)) {
6826 set_qos_param = 1;
6827 network->qos_data.old_param_count =
6828 network->qos_data.param_count;
6829 }
6830
6831 } else {
afbf30a2
JK
6832 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
6833 memcpy(&priv->assoc_network->qos_data.parameters,
b095c381 6834 &def_parameters_CCK, size);
afbf30a2
JK
6835 else
6836 memcpy(&priv->assoc_network->qos_data.parameters,
b095c381 6837 &def_parameters_OFDM, size);
b095c381
JK
6838 priv->assoc_network->qos_data.active = 0;
6839 priv->assoc_network->qos_data.supported = 0;
6840 set_qos_param = 1;
6841 }
6842
6843 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6844
6845 if (set_qos_param == 1)
6846 schedule_work(&priv->qos_activate);
6847
6848 return ret;
6849}
6850
6851static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
6852{
6853 u32 ret = 0;
6854
6855 if ((priv == NULL))
6856 return 0;
6857
afbf30a2 6858 if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION))
b095c381 6859 ret = priv->qos_data.burst_duration_CCK;
afbf30a2 6860 else
b095c381 6861 ret = priv->qos_data.burst_duration_OFDM;
afbf30a2 6862
b095c381
JK
6863 return ret;
6864}
6865
6866/*
6867* Initialize the setting of QoS global
6868*/
6869static void ipw_qos_init(struct ipw_priv *priv, int enable,
6870 int burst_enable, u32 burst_duration_CCK,
6871 u32 burst_duration_OFDM)
6872{
6873 priv->qos_data.qos_enable = enable;
6874
6875 if (priv->qos_data.qos_enable) {
6876 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
6877 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
6878 IPW_DEBUG_QOS("QoS is enabled\n");
6879 } else {
6880 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
6881 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
6882 IPW_DEBUG_QOS("QoS is not enabled\n");
6883 }
6884
6885 priv->qos_data.burst_enable = burst_enable;
6886
6887 if (burst_enable) {
6888 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
6889 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
6890 } else {
6891 priv->qos_data.burst_duration_CCK = 0;
6892 priv->qos_data.burst_duration_OFDM = 0;
6893 }
6894}
6895
6896/*
6897* map the packet priority to the right TX Queue
6898*/
6899static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
6900{
6901 if (priority > 7 || !priv->qos_data.qos_enable)
6902 priority = 0;
6903
6904 return from_priority_to_tx_queue[priority] - 1;
6905}
6906
6907/*
6908* add QoS parameter to the TX command
6909*/
6910static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
6911 u16 priority,
6912 struct tfd_data *tfd, u8 unicast)
6913{
6914 int ret = 0;
6915 int tx_queue_id = 0;
6916 struct ieee80211_qos_data *qos_data = NULL;
6917 int active, supported;
6918 unsigned long flags;
6919
6920 if (!(priv->status & STATUS_ASSOCIATED))
6921 return 0;
6922
6923 qos_data = &priv->assoc_network->qos_data;
6924
6925 spin_lock_irqsave(&priv->ieee->lock, flags);
6926
6927 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6928 if (unicast == 0)
6929 qos_data->active = 0;
6930 else
6931 qos_data->active = qos_data->supported;
6932 }
6933
6934 active = qos_data->active;
6935 supported = qos_data->supported;
6936
6937 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6938
afbf30a2
JK
6939 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
6940 "unicast %d\n",
6941 priv->qos_data.qos_enable, active, supported, unicast);
b095c381
JK
6942 if (active && priv->qos_data.qos_enable) {
6943 ret = from_priority_to_tx_queue[priority];
6944 tx_queue_id = ret - 1;
6945 IPW_DEBUG_QOS("QoS packet priority is %d \n", priority);
6946 if (priority <= 7) {
6947 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
6948 tfd->tfd.tfd_26.mchdr.qos_ctrl = priority;
6949 tfd->tfd.tfd_26.mchdr.frame_ctl |=
6950 IEEE80211_STYPE_QOS_DATA;
6951
6952 if (priv->qos_data.qos_no_ack_mask &
6953 (1UL << tx_queue_id)) {
6954 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
6955 tfd->tfd.tfd_26.mchdr.qos_ctrl |=
6956 CTRL_QOS_NO_ACK;
6957 }
6958 }
6959 }
6960
6961 return ret;
6962}
6963
6964/*
6965* background support to run QoS activate functionality
6966*/
6967static void ipw_bg_qos_activate(void *data)
6968{
6969 struct ipw_priv *priv = data;
6970
6971 if (priv == NULL)
6972 return;
6973
6974 down(&priv->sem);
6975
6976 if (priv->status & STATUS_ASSOCIATED)
6977 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
6978
6979 up(&priv->sem);
6980}
6981
3b9990cb
JK
6982static int ipw_handle_probe_response(struct net_device *dev,
6983 struct ieee80211_probe_response *resp,
6984 struct ieee80211_network *network)
b095c381
JK
6985{
6986 struct ipw_priv *priv = ieee80211_priv(dev);
3b9990cb
JK
6987 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6988 (network == priv->assoc_network));
b095c381 6989
3b9990cb 6990 ipw_qos_handle_probe_response(priv, active_network, network);
b095c381 6991
3b9990cb
JK
6992 return 0;
6993}
6994
6995static int ipw_handle_beacon(struct net_device *dev,
6996 struct ieee80211_beacon *resp,
6997 struct ieee80211_network *network)
6998{
6999 struct ipw_priv *priv = ieee80211_priv(dev);
7000 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
7001 (network == priv->assoc_network));
7002
7003 ipw_qos_handle_probe_response(priv, active_network, network);
b095c381
JK
7004
7005 return 0;
7006}
7007
3b9990cb
JK
7008static int ipw_handle_assoc_response(struct net_device *dev,
7009 struct ieee80211_assoc_response *resp,
7010 struct ieee80211_network *network)
7011{
7012 struct ipw_priv *priv = ieee80211_priv(dev);
7013 ipw_qos_association_resp(priv, network);
7014 return 0;
7015}
7016
b095c381
JK
7017static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
7018 *qos_param)
7019{
7020 struct host_cmd cmd = {
7021 .cmd = IPW_CMD_QOS_PARAMETERS,
7022 .len = (sizeof(struct ieee80211_qos_parameters) * 3)
7023 };
7024
afbf30a2 7025 memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
9ddf84f6 7026 return ipw_send_cmd(priv, &cmd);
b095c381
JK
7027}
7028
7029static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
7030 *qos_param)
7031{
7032 struct host_cmd cmd = {
7033 .cmd = IPW_CMD_WME_INFO,
7034 .len = sizeof(*qos_param)
7035 };
7036
afbf30a2 7037 memcpy(cmd.param, qos_param, sizeof(*qos_param));
9ddf84f6 7038 return ipw_send_cmd(priv, &cmd);
b095c381
JK
7039}
7040
7041#endif /* CONFIG_IPW_QOS */
7042
7043static int ipw_associate_network(struct ipw_priv *priv,
7044 struct ieee80211_network *network,
7045 struct ipw_supported_rates *rates, int roaming)
7046{
7047 int err;
7048
7049 if (priv->config & CFG_FIXED_RATE)
7050 ipw_set_fixed_rate(priv, network->mode);
7051
7052 if (!(priv->config & CFG_STATIC_ESSID)) {
7053 priv->essid_len = min(network->ssid_len,
7054 (u8) IW_ESSID_MAX_SIZE);
7055 memcpy(priv->essid, network->ssid, priv->essid_len);
7056 }
7057
7058 network->last_associate = jiffies;
7059
7060 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
7061 priv->assoc_request.channel = network->channel;
7062 if ((priv->capability & CAP_PRIVACY_ON) &&
7063 (priv->capability & CAP_SHARED_KEY)) {
7064 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
7065 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7066
7067 if ((priv->capability & CAP_PRIVACY_ON) &&
7068 (priv->ieee->sec.level == SEC_LEVEL_1) &&
7069 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
7070 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
7071 } else {
7072 priv->assoc_request.auth_type = AUTH_OPEN;
7073 priv->assoc_request.auth_key = 0;
7074 }
7075
7076 if (priv->ieee->wpa_ie_len) {
ea2b26e0
JK
7077 priv->assoc_request.policy_support = 0x02; /* RSN active */
7078 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
7079 priv->ieee->wpa_ie_len);
7080 }
ea2b26e0
JK
7081
7082 /*
7083 * It is valid for our ieee device to support multiple modes, but
7084 * when it comes to associating to a given network we have to choose
7085 * just one mode.
7086 */
7087 if (network->mode & priv->ieee->mode & IEEE_A)
7088 priv->assoc_request.ieee_mode = IPW_A_MODE;
7089 else if (network->mode & priv->ieee->mode & IEEE_G)
7090 priv->assoc_request.ieee_mode = IPW_G_MODE;
7091 else if (network->mode & priv->ieee->mode & IEEE_B)
7092 priv->assoc_request.ieee_mode = IPW_B_MODE;
7093
7094 priv->assoc_request.capability = network->capability;
7095 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
7096 && !(priv->config & CFG_PREAMBLE_LONG)) {
7097 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
7098 } else {
7099 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
7100
7101 /* Clear the short preamble if we won't be supporting it */
7102 priv->assoc_request.capability &=
7103 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
7104 }
7105
afbf30a2
JK
7106 /* Clear capability bits that aren't used in Ad Hoc */
7107 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7108 priv->assoc_request.capability &=
7109 ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
7110
ea2b26e0
JK
7111 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
7112 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
7113 roaming ? "Rea" : "A",
7114 escape_essid(priv->essid, priv->essid_len),
7115 network->channel,
7116 ipw_modes[priv->assoc_request.ieee_mode],
7117 rates->num_rates,
7118 (priv->assoc_request.preamble_length ==
7119 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
7120 network->capability &
7121 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
7122 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
7123 priv->capability & CAP_PRIVACY_ON ?
7124 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
7125 "(open)") : "",
7126 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
7127 priv->capability & CAP_PRIVACY_ON ?
b095c381 7128 '1' + priv->ieee->sec.active_key : '.',
ea2b26e0
JK
7129 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
7130
7131 priv->assoc_request.beacon_interval = network->beacon_interval;
7132 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
7133 (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {
7134 priv->assoc_request.assoc_type = HC_IBSS_START;
7135 priv->assoc_request.assoc_tsf_msw = 0;
7136 priv->assoc_request.assoc_tsf_lsw = 0;
7137 } else {
7138 if (unlikely(roaming))
7139 priv->assoc_request.assoc_type = HC_REASSOCIATE;
7140 else
7141 priv->assoc_request.assoc_type = HC_ASSOCIATE;
7142 priv->assoc_request.assoc_tsf_msw = network->time_stamp[1];
7143 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
7144 }
7145
afbf30a2 7146 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
ea2b26e0
JK
7147
7148 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7149 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
7150 priv->assoc_request.atim_window = network->atim_window;
7151 } else {
afbf30a2 7152 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
ea2b26e0
JK
7153 priv->assoc_request.atim_window = 0;
7154 }
7155
7156 priv->assoc_request.listen_interval = network->listen_interval;
7157
7158 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
7159 if (err) {
7160 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
7161 return err;
7162 }
7163
7164 rates->ieee_mode = priv->assoc_request.ieee_mode;
7165 rates->purpose = IPW_RATE_CONNECT;
7166 ipw_send_supported_rates(priv, rates);
7167
7168 if (priv->assoc_request.ieee_mode == IPW_G_MODE)
7169 priv->sys_config.dot11g_auto_detection = 1;
7170 else
7171 priv->sys_config.dot11g_auto_detection = 0;
c848d0af
JK
7172
7173 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7174 priv->sys_config.answer_broadcast_ssid_probe = 1;
7175 else
7176 priv->sys_config.answer_broadcast_ssid_probe = 0;
7177
ea2b26e0
JK
7178 err = ipw_send_system_config(priv, &priv->sys_config);
7179 if (err) {
7180 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
7181 return err;
7182 }
7183
7184 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
7185 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
7186 if (err) {
7187 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
7188 return err;
7189 }
7190
7191 /*
7192 * If preemption is enabled, it is possible for the association
7193 * to complete before we return from ipw_send_associate. Therefore
7194 * we have to be sure and update our priviate data first.
7195 */
7196 priv->channel = network->channel;
7197 memcpy(priv->bssid, network->bssid, ETH_ALEN);
e6324726
HL
7198 priv->status |= STATUS_ASSOCIATING;
7199 priv->status &= ~STATUS_SECURITY_UPDATED;
ea2b26e0
JK
7200
7201 priv->assoc_network = network;
7202
b095c381
JK
7203#ifdef CONFIG_IPW_QOS
7204 ipw_qos_association(priv, network);
7205#endif
7206
ea2b26e0
JK
7207 err = ipw_send_associate(priv, &priv->assoc_request);
7208 if (err) {
43f66a6c
JK
7209 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
7210 return err;
7211 }
bf79451e
JG
7212
7213 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n",
43f66a6c
JK
7214 escape_essid(priv->essid, priv->essid_len),
7215 MAC_ARG(priv->bssid));
7216
7217 return 0;
7218}
7219
7220static void ipw_roam(void *data)
7221{
7222 struct ipw_priv *priv = data;
7223 struct ieee80211_network *network = NULL;
7224 struct ipw_network_match match = {
7225 .network = priv->assoc_network
7226 };
7227
7228 /* The roaming process is as follows:
bf79451e
JG
7229 *
7230 * 1. Missed beacon threshold triggers the roaming process by
43f66a6c
JK
7231 * setting the status ROAM bit and requesting a scan.
7232 * 2. When the scan completes, it schedules the ROAM work
7233 * 3. The ROAM work looks at all of the known networks for one that
7234 * is a better network than the currently associated. If none
7235 * found, the ROAM process is over (ROAM bit cleared)
7236 * 4. If a better network is found, a disassociation request is
7237 * sent.
7238 * 5. When the disassociation completes, the roam work is again
7239 * scheduled. The second time through, the driver is no longer
7240 * associated, and the newly selected network is sent an
bf79451e 7241 * association request.
43f66a6c
JK
7242 * 6. At this point ,the roaming process is complete and the ROAM
7243 * status bit is cleared.
7244 */
7245
7246 /* If we are no longer associated, and the roaming bit is no longer
7247 * set, then we are not actively roaming, so just return */
7248 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING)))
7249 return;
bf79451e 7250
43f66a6c 7251 if (priv->status & STATUS_ASSOCIATED) {
bf79451e 7252 /* First pass through ROAM process -- look for a better
43f66a6c 7253 * network */
a613bffd 7254 unsigned long flags;
43f66a6c
JK
7255 u8 rssi = priv->assoc_network->stats.rssi;
7256 priv->assoc_network->stats.rssi = -128;
a613bffd 7257 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c
JK
7258 list_for_each_entry(network, &priv->ieee->network_list, list) {
7259 if (network != priv->assoc_network)
7260 ipw_best_network(priv, &match, network, 1);
7261 }
a613bffd 7262 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c 7263 priv->assoc_network->stats.rssi = rssi;
bf79451e 7264
43f66a6c
JK
7265 if (match.network == priv->assoc_network) {
7266 IPW_DEBUG_ASSOC("No better APs in this network to "
7267 "roam to.\n");
7268 priv->status &= ~STATUS_ROAMING;
7269 ipw_debug_config(priv);
7270 return;
7271 }
bf79451e 7272
43f66a6c
JK
7273 ipw_send_disassociate(priv, 1);
7274 priv->assoc_network = match.network;
7275
7276 return;
bf79451e 7277 }
43f66a6c
JK
7278
7279 /* Second pass through ROAM process -- request association */
7280 ipw_compatible_rates(priv, priv->assoc_network, &match.rates);
7281 ipw_associate_network(priv, priv->assoc_network, &match.rates, 1);
7282 priv->status &= ~STATUS_ROAMING;
7283}
7284
c848d0af
JK
7285static void ipw_bg_roam(void *data)
7286{
7287 struct ipw_priv *priv = data;
7288 down(&priv->sem);
7289 ipw_roam(data);
7290 up(&priv->sem);
7291}
7292
7293static int ipw_associate(void *data)
43f66a6c
JK
7294{
7295 struct ipw_priv *priv = data;
7296
7297 struct ieee80211_network *network = NULL;
7298 struct ipw_network_match match = {
7299 .network = NULL
7300 };
7301 struct ipw_supported_rates *rates;
7302 struct list_head *element;
a613bffd 7303 unsigned long flags;
43f66a6c 7304
b095c381
JK
7305 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7306 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7307 return 0;
7308 }
7309
c848d0af 7310 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
afbf30a2
JK
7311 IPW_DEBUG_ASSOC("Not attempting association (already in "
7312 "progress)\n");
c848d0af
JK
7313 return 0;
7314 }
7315
e6324726
HL
7316 if (priv->status & STATUS_DISASSOCIATING) {
7317 IPW_DEBUG_ASSOC("Not attempting association (in "
7318 "disassociating)\n ");
7319 queue_work(priv->workqueue, &priv->associate);
7320 return 0;
7321 }
7322
c848d0af 7323 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
afbf30a2
JK
7324 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
7325 "initialized)\n");
c848d0af
JK
7326 return 0;
7327 }
7328
43f66a6c
JK
7329 if (!(priv->config & CFG_ASSOCIATE) &&
7330 !(priv->config & (CFG_STATIC_ESSID |
0edd5b44 7331 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
43f66a6c 7332 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
c848d0af 7333 return 0;
43f66a6c
JK
7334 }
7335
a613bffd
JK
7336 /* Protect our use of the network_list */
7337 spin_lock_irqsave(&priv->ieee->lock, flags);
bf79451e 7338 list_for_each_entry(network, &priv->ieee->network_list, list)
0edd5b44 7339 ipw_best_network(priv, &match, network, 0);
43f66a6c
JK
7340
7341 network = match.network;
7342 rates = &match.rates;
7343
7344 if (network == NULL &&
7345 priv->ieee->iw_mode == IW_MODE_ADHOC &&
7346 priv->config & CFG_ADHOC_CREATE &&
7347 priv->config & CFG_STATIC_ESSID &&
a613bffd 7348 priv->config & CFG_STATIC_CHANNEL &&
43f66a6c
JK
7349 !list_empty(&priv->ieee->network_free_list)) {
7350 element = priv->ieee->network_free_list.next;
0edd5b44 7351 network = list_entry(element, struct ieee80211_network, list);
43f66a6c
JK
7352 ipw_adhoc_create(priv, network);
7353 rates = &priv->rates;
7354 list_del(element);
7355 list_add_tail(&network->list, &priv->ieee->network_list);
7356 }
a613bffd 7357 spin_unlock_irqrestore(&priv->ieee->lock, flags);
bf79451e 7358
43f66a6c
JK
7359 /* If we reached the end of the list, then we don't have any valid
7360 * matching APs */
7361 if (!network) {
7362 ipw_debug_config(priv);
7363
b095c381
JK
7364 if (!(priv->status & STATUS_SCANNING)) {
7365 if (!(priv->config & CFG_SPEED_SCAN))
7366 queue_delayed_work(priv->workqueue,
7367 &priv->request_scan,
7368 SCAN_INTERVAL);
7369 else
7370 queue_work(priv->workqueue,
7371 &priv->request_scan);
7372 }
bf79451e 7373
c848d0af 7374 return 0;
43f66a6c
JK
7375 }
7376
7377 ipw_associate_network(priv, network, rates, 0);
c848d0af
JK
7378
7379 return 1;
7380}
7381
7382static void ipw_bg_associate(void *data)
7383{
7384 struct ipw_priv *priv = data;
7385 down(&priv->sem);
7386 ipw_associate(data);
7387 up(&priv->sem);
43f66a6c 7388}
bf79451e 7389
b095c381
JK
7390static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7391 struct sk_buff *skb)
7392{
7393 struct ieee80211_hdr *hdr;
7394 u16 fc;
7395
7396 hdr = (struct ieee80211_hdr *)skb->data;
7397 fc = le16_to_cpu(hdr->frame_ctl);
7398 if (!(fc & IEEE80211_FCTL_PROTECTED))
7399 return;
7400
7401 fc &= ~IEEE80211_FCTL_PROTECTED;
7402 hdr->frame_ctl = cpu_to_le16(fc);
7403 switch (priv->ieee->sec.level) {
7404 case SEC_LEVEL_3:
7405 /* Remove CCMP HDR */
7406 memmove(skb->data + IEEE80211_3ADDR_LEN,
7407 skb->data + IEEE80211_3ADDR_LEN + 8,
7408 skb->len - IEEE80211_3ADDR_LEN - 8);
f4ff497d 7409 skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */
b095c381
JK
7410 break;
7411 case SEC_LEVEL_2:
7412 break;
7413 case SEC_LEVEL_1:
7414 /* Remove IV */
7415 memmove(skb->data + IEEE80211_3ADDR_LEN,
7416 skb->data + IEEE80211_3ADDR_LEN + 4,
7417 skb->len - IEEE80211_3ADDR_LEN - 4);
f4ff497d 7418 skb_trim(skb, skb->len - 8); /* IV + ICV */
b095c381
JK
7419 break;
7420 case SEC_LEVEL_0:
7421 break;
7422 default:
7423 printk(KERN_ERR "Unknow security level %d\n",
7424 priv->ieee->sec.level);
7425 break;
7426 }
7427}
7428
7429static void ipw_handle_data_packet(struct ipw_priv *priv,
7430 struct ipw_rx_mem_buffer *rxb,
7431 struct ieee80211_rx_stats *stats)
43f66a6c 7432{
567deaf6 7433 struct ieee80211_hdr_4addr *hdr;
43f66a6c
JK
7434 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7435
7436 /* We received data from the HW, so stop the watchdog */
7437 priv->net_dev->trans_start = jiffies;
7438
bf79451e 7439 /* We only process data packets if the
43f66a6c 7440 * interface is open */
a613bffd 7441 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
43f66a6c
JK
7442 skb_tailroom(rxb->skb))) {
7443 priv->ieee->stats.rx_errors++;
7444 priv->wstats.discard.misc++;
7445 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7446 return;
7447 } else if (unlikely(!netif_running(priv->net_dev))) {
7448 priv->ieee->stats.rx_dropped++;
7449 priv->wstats.discard.misc++;
7450 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7451 return;
7452 }
7453
7454 /* Advance skb->data to the start of the actual payload */
aaa4d308 7455 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
43f66a6c
JK
7456
7457 /* Set the size of the skb to the size of the frame */
a613bffd 7458 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
43f66a6c
JK
7459
7460 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7461
b095c381 7462 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
567deaf6
HL
7463 hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
7464 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
7465 (is_multicast_ether_addr(hdr->addr1) ?
7466 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
b095c381
JK
7467 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7468
bf79451e 7469 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
43f66a6c 7470 priv->ieee->stats.rx_errors++;
a613bffd 7471 else { /* ieee80211_rx succeeded, so it now owns the SKB */
43f66a6c 7472 rxb->skb = NULL;
b095c381 7473 __ipw_led_activity_on(priv);
a613bffd 7474 }
43f66a6c
JK
7475}
7476
24a47dbd
MK
7477#ifdef CONFIG_IEEE80211_RADIOTAP
7478static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7479 struct ipw_rx_mem_buffer *rxb,
7480 struct ieee80211_rx_stats *stats)
7481{
7482 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7483 struct ipw_rx_frame *frame = &pkt->u.frame;
7484
7485 /* initial pull of some data */
7486 u16 received_channel = frame->received_channel;
7487 u8 antennaAndPhy = frame->antennaAndPhy;
7488 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */
7489 u16 pktrate = frame->rate;
7490
7491 /* Magic struct that slots into the radiotap header -- no reason
7492 * to build this manually element by element, we can write it much
7493 * more efficiently than we can parse it. ORDER MATTERS HERE */
7494 struct ipw_rt_hdr {
7495 struct ieee80211_radiotap_header rt_hdr;
7496 u8 rt_flags; /* radiotap packet flags */
7497 u8 rt_rate; /* rate in 500kb/s */
7498 u16 rt_channel; /* channel in mhz */
7499 u16 rt_chbitmask; /* channel bitfield */
7500 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
7501 u8 rt_antenna; /* antenna number */
7502 } *ipw_rt;
7503
7504 short len = le16_to_cpu(pkt->u.frame.length);
7505
7506 /* We received data from the HW, so stop the watchdog */
7507 priv->net_dev->trans_start = jiffies;
7508
7509 /* We only process data packets if the
7510 * interface is open */
7511 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7512 skb_tailroom(rxb->skb))) {
7513 priv->ieee->stats.rx_errors++;
7514 priv->wstats.discard.misc++;
7515 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7516 return;
7517 } else if (unlikely(!netif_running(priv->net_dev))) {
7518 priv->ieee->stats.rx_dropped++;
7519 priv->wstats.discard.misc++;
7520 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7521 return;
7522 }
7523
7524 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7525 * that now */
7526 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7527 /* FIXME: Should alloc bigger skb instead */
7528 priv->ieee->stats.rx_dropped++;
7529 priv->wstats.discard.misc++;
7530 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7531 return;
7532 }
7533
7534 /* copy the frame itself */
7535 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
7536 rxb->skb->data + IPW_RX_FRAME_SIZE, len);
7537
7538 /* Zero the radiotap static buffer ... We only need to zero the bytes NOT
7539 * part of our real header, saves a little time.
7540 *
7541 * No longer necessary since we fill in all our data. Purge before merging
7542 * patch officially.
7543 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
7544 * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
7545 */
7546
7547 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
7548
7549 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7550 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
7551 ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total header+data */
7552
7553 /* Big bitfield of all the fields we provide in radiotap */
7554 ipw_rt->rt_hdr.it_present =
7555 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7556 (1 << IEEE80211_RADIOTAP_RATE) |
7557 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7558 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7559 (1 << IEEE80211_RADIOTAP_ANTENNA));
7560
7561 /* Zero the flags, we'll add to them as we go */
7562 ipw_rt->rt_flags = 0;
7563
7564 /* Convert signal to DBM */
7565 ipw_rt->rt_dbmsignal = antsignal;
7566
7567 /* Convert the channel data and set the flags */
7568 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
7569 if (received_channel > 14) { /* 802.11a */
7570 ipw_rt->rt_chbitmask =
7571 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7572 } else if (antennaAndPhy & 32) { /* 802.11b */
7573 ipw_rt->rt_chbitmask =
7574 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7575 } else { /* 802.11g */
7576 ipw_rt->rt_chbitmask =
7577 (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7578 }
7579
7580 /* set the rate in multiples of 500k/s */
7581 switch (pktrate) {
7582 case IPW_TX_RATE_1MB:
7583 ipw_rt->rt_rate = 2;
7584 break;
7585 case IPW_TX_RATE_2MB:
7586 ipw_rt->rt_rate = 4;
7587 break;
7588 case IPW_TX_RATE_5MB:
7589 ipw_rt->rt_rate = 10;
7590 break;
7591 case IPW_TX_RATE_6MB:
7592 ipw_rt->rt_rate = 12;
7593 break;
7594 case IPW_TX_RATE_9MB:
7595 ipw_rt->rt_rate = 18;
7596 break;
7597 case IPW_TX_RATE_11MB:
7598 ipw_rt->rt_rate = 22;
7599 break;
7600 case IPW_TX_RATE_12MB:
7601 ipw_rt->rt_rate = 24;
7602 break;
7603 case IPW_TX_RATE_18MB:
7604 ipw_rt->rt_rate = 36;
7605 break;
7606 case IPW_TX_RATE_24MB:
7607 ipw_rt->rt_rate = 48;
7608 break;
7609 case IPW_TX_RATE_36MB:
7610 ipw_rt->rt_rate = 72;
7611 break;
7612 case IPW_TX_RATE_48MB:
7613 ipw_rt->rt_rate = 96;
7614 break;
7615 case IPW_TX_RATE_54MB:
7616 ipw_rt->rt_rate = 108;
7617 break;
7618 default:
7619 ipw_rt->rt_rate = 0;
7620 break;
7621 }
7622
7623 /* antenna number */
7624 ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */
7625
7626 /* set the preamble flag if we have it */
7627 if ((antennaAndPhy & 64))
7628 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7629
7630 /* Set the size of the skb to the size of the frame */
7631 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
7632
7633 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7634
7635 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
7636 priv->ieee->stats.rx_errors++;
7637 else { /* ieee80211_rx succeeded, so it now owns the SKB */
7638 rxb->skb = NULL;
7639 /* no LED during capture */
7640 }
7641}
7642#endif
7643
ea2b26e0
JK
7644static inline int is_network_packet(struct ipw_priv *priv,
7645 struct ieee80211_hdr_4addr *header)
7646{
7647 /* Filter incoming packets to determine if they are targetted toward
7648 * this network, discarding packets coming from ourselves */
7649 switch (priv->ieee->iw_mode) {
a613bffd 7650 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
c848d0af
JK
7651 /* packets from our adapter are dropped (echo) */
7652 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
7653 return 0;
7654
90700fd9
PJ
7655 /* {broad,multi}cast packets to our BSSID go through */
7656 if (is_multicast_ether_addr(header->addr1) ||
7657 is_broadcast_ether_addr(header->addr1))
ea2b26e0 7658 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
a613bffd
JK
7659
7660 /* packets to our adapter go through */
7661 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7662 ETH_ALEN);
a613bffd 7663
90700fd9 7664 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
c848d0af
JK
7665 /* packets from our adapter are dropped (echo) */
7666 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
7667 return 0;
7668
90700fd9
PJ
7669 /* {broad,multi}cast packets to our BSS go through */
7670 if (is_multicast_ether_addr(header->addr1) ||
7671 is_broadcast_ether_addr(header->addr1))
a613bffd
JK
7672 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
7673
7674 /* packets to our adapter go through */
7675 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7676 ETH_ALEN);
ea2b26e0 7677 }
a613bffd 7678
ea2b26e0
JK
7679 return 1;
7680}
7681
afbf30a2
JK
7682#define IPW_PACKET_RETRY_TIME HZ
7683
7684static inline int is_duplicate_packet(struct ipw_priv *priv,
7685 struct ieee80211_hdr_4addr *header)
7686{
afbf30a2
JK
7687 u16 sc = le16_to_cpu(header->seq_ctl);
7688 u16 seq = WLAN_GET_SEQ_SEQ(sc);
7689 u16 frag = WLAN_GET_SEQ_FRAG(sc);
7690 u16 *last_seq, *last_frag;
7691 unsigned long *last_time;
7692
7693 switch (priv->ieee->iw_mode) {
7694 case IW_MODE_ADHOC:
7695 {
7696 struct list_head *p;
7697 struct ipw_ibss_seq *entry = NULL;
7698 u8 *mac = header->addr2;
7699 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
7700
7701 __list_for_each(p, &priv->ibss_mac_hash[index]) {
7702 entry =
7703 list_entry(p, struct ipw_ibss_seq, list);
7704 if (!memcmp(entry->mac, mac, ETH_ALEN))
7705 break;
7706 }
7707 if (p == &priv->ibss_mac_hash[index]) {
7708 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
7709 if (!entry) {
7710 IPW_ERROR
7711 ("Cannot malloc new mac entry\n");
7712 return 0;
7713 }
7714 memcpy(entry->mac, mac, ETH_ALEN);
7715 entry->seq_num = seq;
7716 entry->frag_num = frag;
7717 entry->packet_time = jiffies;
7718 list_add(&entry->list,
7719 &priv->ibss_mac_hash[index]);
7720 return 0;
7721 }
7722 last_seq = &entry->seq_num;
7723 last_frag = &entry->frag_num;
7724 last_time = &entry->packet_time;
7725 break;
7726 }
7727 case IW_MODE_INFRA:
7728 last_seq = &priv->last_seq_num;
7729 last_frag = &priv->last_frag_num;
7730 last_time = &priv->last_packet_time;
7731 break;
7732 default:
7733 return 0;
7734 }
7735 if ((*last_seq == seq) &&
7736 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
7737 if (*last_frag == frag)
7738 goto drop;
7739 if (*last_frag + 1 != frag)
7740 /* out-of-order fragment */
7741 goto drop;
afbf30a2
JK
7742 } else
7743 *last_seq = seq;
7744
f57ce7ce 7745 *last_frag = frag;
afbf30a2
JK
7746 *last_time = jiffies;
7747 return 0;
7748
7749 drop:
87b016cb
ZY
7750 /* Comment this line now since we observed the card receives
7751 * duplicate packets but the FCTL_RETRY bit is not set in the
7752 * IBSS mode with fragmentation enabled.
7753 BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
afbf30a2
JK
7754 return 1;
7755}
7756
b095c381
JK
7757static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
7758 struct ipw_rx_mem_buffer *rxb,
7759 struct ieee80211_rx_stats *stats)
7760{
7761 struct sk_buff *skb = rxb->skb;
7762 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
7763 struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
7764 (skb->data + IPW_RX_FRAME_SIZE);
7765
7766 ieee80211_rx_mgt(priv->ieee, header, stats);
7767
7768 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
7769 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7770 IEEE80211_STYPE_PROBE_RESP) ||
7771 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7772 IEEE80211_STYPE_BEACON))) {
7773 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
7774 ipw_add_station(priv, header->addr2);
7775 }
7776
7777 if (priv->config & CFG_NET_STATS) {
7778 IPW_DEBUG_HC("sending stat packet\n");
7779
7780 /* Set the size of the skb to the size of the full
7781 * ipw header and 802.11 frame */
7782 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
7783 IPW_RX_FRAME_SIZE);
7784
7785 /* Advance past the ipw packet header to the 802.11 frame */
7786 skb_pull(skb, IPW_RX_FRAME_SIZE);
7787
7788 /* Push the ieee80211_rx_stats before the 802.11 frame */
7789 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
7790
7791 skb->dev = priv->ieee->dev;
7792
7793 /* Point raw at the ieee80211_stats */
7794 skb->mac.raw = skb->data;
7795
7796 skb->pkt_type = PACKET_OTHERHOST;
7797 skb->protocol = __constant_htons(ETH_P_80211_STATS);
7798 memset(skb->cb, 0, sizeof(rxb->skb->cb));
7799 netif_rx(skb);
7800 rxb->skb = NULL;
7801 }
7802}
7803
43f66a6c
JK
7804/*
7805 * Main entry function for recieving a packet with 80211 headers. This
7806 * should be called when ever the FW has notified us that there is a new
7807 * skb in the recieve queue.
7808 */
7809static void ipw_rx(struct ipw_priv *priv)
7810{
7811 struct ipw_rx_mem_buffer *rxb;
7812 struct ipw_rx_packet *pkt;
0dacca1f 7813 struct ieee80211_hdr_4addr *header;
43f66a6c
JK
7814 u32 r, w, i;
7815 u8 network_packet;
7816
b095c381
JK
7817 r = ipw_read32(priv, IPW_RX_READ_INDEX);
7818 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
43f66a6c
JK
7819 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
7820
7821 while (i != r) {
7822 rxb = priv->rxq->queue[i];
7823#ifdef CONFIG_IPW_DEBUG
7824 if (unlikely(rxb == NULL)) {
7825 printk(KERN_CRIT "Queue not allocated!\n");
7826 break;
7827 }
7828#endif
7829 priv->rxq->queue[i] = NULL;
7830
7831 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
b095c381 7832 IPW_RX_BUF_SIZE,
43f66a6c
JK
7833 PCI_DMA_FROMDEVICE);
7834
7835 pkt = (struct ipw_rx_packet *)rxb->skb->data;
7836 IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",
7837 pkt->header.message_type,
0edd5b44 7838 pkt->header.rx_seq_num, pkt->header.control_bits);
43f66a6c
JK
7839
7840 switch (pkt->header.message_type) {
0edd5b44
JG
7841 case RX_FRAME_TYPE: /* 802.11 frame */ {
7842 struct ieee80211_rx_stats stats = {
c848d0af
JK
7843 .rssi =
7844 le16_to_cpu(pkt->u.frame.rssi_dbm) -
0edd5b44 7845 IPW_RSSI_TO_DBM,
c848d0af
JK
7846 .signal =
7847 le16_to_cpu(pkt->u.frame.signal),
7848 .noise =
7849 le16_to_cpu(pkt->u.frame.noise),
0edd5b44
JG
7850 .rate = pkt->u.frame.rate,
7851 .mac_time = jiffies,
7852 .received_channel =
7853 pkt->u.frame.received_channel,
7854 .freq =
7855 (pkt->u.frame.
7856 control & (1 << 0)) ?
7857 IEEE80211_24GHZ_BAND :
7858 IEEE80211_52GHZ_BAND,
a613bffd 7859 .len = le16_to_cpu(pkt->u.frame.length),
0edd5b44
JG
7860 };
7861
7862 if (stats.rssi != 0)
7863 stats.mask |= IEEE80211_STATMASK_RSSI;
7864 if (stats.signal != 0)
7865 stats.mask |= IEEE80211_STATMASK_SIGNAL;
c848d0af
JK
7866 if (stats.noise != 0)
7867 stats.mask |= IEEE80211_STATMASK_NOISE;
0edd5b44
JG
7868 if (stats.rate != 0)
7869 stats.mask |= IEEE80211_STATMASK_RATE;
7870
7871 priv->rx_packets++;
43f66a6c 7872
b095c381 7873#ifdef CONFIG_IPW2200_MONITOR
0edd5b44 7874 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
24a47dbd
MK
7875#ifdef CONFIG_IEEE80211_RADIOTAP
7876 ipw_handle_data_packet_monitor(priv,
7877 rxb,
7878 &stats);
7879#else
0edd5b44
JG
7880 ipw_handle_data_packet(priv, rxb,
7881 &stats);
24a47dbd 7882#endif
0edd5b44
JG
7883 break;
7884 }
43f66a6c 7885#endif
bf79451e 7886
0edd5b44 7887 header =
0dacca1f
JK
7888 (struct ieee80211_hdr_4addr *)(rxb->skb->
7889 data +
7890 IPW_RX_FRAME_SIZE);
43f66a6c
JK
7891 /* TODO: Check Ad-Hoc dest/source and make sure
7892 * that we are actually parsing these packets
bf79451e 7893 * correctly -- we should probably use the
43f66a6c
JK
7894 * frame control of the packet and disregard
7895 * the current iw_mode */
0edd5b44 7896
ea2b26e0
JK
7897 network_packet =
7898 is_network_packet(priv, header);
0edd5b44
JG
7899 if (network_packet && priv->assoc_network) {
7900 priv->assoc_network->stats.rssi =
7901 stats.rssi;
7902 average_add(&priv->average_rssi,
7903 stats.rssi);
7904 priv->last_rx_rssi = stats.rssi;
7905 }
7906
7907 IPW_DEBUG_RX("Frame: len=%u\n",
a613bffd 7908 le16_to_cpu(pkt->u.frame.length));
0edd5b44 7909
a613bffd
JK
7910 if (le16_to_cpu(pkt->u.frame.length) <
7911 frame_hdr_len(header)) {
0edd5b44
JG
7912 IPW_DEBUG_DROP
7913 ("Received packet is too small. "
7914 "Dropping.\n");
7915 priv->ieee->stats.rx_errors++;
7916 priv->wstats.discard.misc++;
7917 break;
7918 }
7919
a613bffd
JK
7920 switch (WLAN_FC_GET_TYPE
7921 (le16_to_cpu(header->frame_ctl))) {
b095c381 7922
0edd5b44 7923 case IEEE80211_FTYPE_MGMT:
b095c381
JK
7924 ipw_handle_mgmt_packet(priv, rxb,
7925 &stats);
0edd5b44
JG
7926 break;
7927
7928 case IEEE80211_FTYPE_CTL:
7929 break;
7930
7931 case IEEE80211_FTYPE_DATA:
afbf30a2
JK
7932 if (unlikely(!network_packet ||
7933 is_duplicate_packet(priv,
7934 header)))
7935 {
0edd5b44
JG
7936 IPW_DEBUG_DROP("Dropping: "
7937 MAC_FMT ", "
7938 MAC_FMT ", "
7939 MAC_FMT "\n",
7940 MAC_ARG(header->
7941 addr1),
7942 MAC_ARG(header->
7943 addr2),
7944 MAC_ARG(header->
7945 addr3));
b095c381
JK
7946 break;
7947 }
7948
7949 ipw_handle_data_packet(priv, rxb,
7950 &stats);
7951
0edd5b44
JG
7952 break;
7953 }
43f66a6c
JK
7954 break;
7955 }
bf79451e 7956
0edd5b44
JG
7957 case RX_HOST_NOTIFICATION_TYPE:{
7958 IPW_DEBUG_RX
7959 ("Notification: subtype=%02X flags=%02X size=%d\n",
43f66a6c
JK
7960 pkt->u.notification.subtype,
7961 pkt->u.notification.flags,
7962 pkt->u.notification.size);
0edd5b44
JG
7963 ipw_rx_notification(priv, &pkt->u.notification);
7964 break;
7965 }
43f66a6c
JK
7966
7967 default:
7968 IPW_DEBUG_RX("Bad Rx packet of type %d\n",
7969 pkt->header.message_type);
7970 break;
7971 }
bf79451e
JG
7972
7973 /* For now we just don't re-use anything. We can tweak this
7974 * later to try and re-use notification packets and SKBs that
43f66a6c
JK
7975 * fail to Rx correctly */
7976 if (rxb->skb != NULL) {
7977 dev_kfree_skb_any(rxb->skb);
7978 rxb->skb = NULL;
7979 }
bf79451e 7980
43f66a6c 7981 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
b095c381 7982 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c 7983 list_add_tail(&rxb->list, &priv->rxq->rx_used);
bf79451e 7984
43f66a6c
JK
7985 i = (i + 1) % RX_QUEUE_SIZE;
7986 }
7987
7988 /* Backtrack one entry */
7989 priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1;
7990
afbf30a2
JK
7991 ipw_rx_queue_restock(priv);
7992}
7993
7994#define DEFAULT_RTS_THRESHOLD 2304U
7995#define MIN_RTS_THRESHOLD 1U
7996#define MAX_RTS_THRESHOLD 2304U
7997#define DEFAULT_BEACON_INTERVAL 100U
7998#define DEFAULT_SHORT_RETRY_LIMIT 7U
7999#define DEFAULT_LONG_RETRY_LIMIT 4U
8000
8001static int ipw_sw_reset(struct ipw_priv *priv, int init)
8002{
8003 int band, modulation;
8004 int old_mode = priv->ieee->iw_mode;
8005
8006 /* Initialize module parameter values here */
8007 priv->config = 0;
8008
8009 /* We default to disabling the LED code as right now it causes
8010 * too many systems to lock up... */
8011 if (!led)
8012 priv->config |= CFG_NO_LED;
8013
8014 if (associate)
8015 priv->config |= CFG_ASSOCIATE;
8016 else
8017 IPW_DEBUG_INFO("Auto associate disabled.\n");
8018
8019 if (auto_create)
8020 priv->config |= CFG_ADHOC_CREATE;
8021 else
8022 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
8023
8024 if (disable) {
8025 priv->status |= STATUS_RF_KILL_SW;
8026 IPW_DEBUG_INFO("Radio disabled.\n");
8027 }
8028
8029 if (channel != 0) {
8030 priv->config |= CFG_STATIC_CHANNEL;
8031 priv->channel = channel;
8032 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
8033 /* TODO: Validate that provided channel is in range */
8034 }
8035#ifdef CONFIG_IPW_QOS
8036 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8037 burst_duration_CCK, burst_duration_OFDM);
8038#endif /* CONFIG_IPW_QOS */
8039
8040 switch (mode) {
8041 case 1:
8042 priv->ieee->iw_mode = IW_MODE_ADHOC;
8043 priv->net_dev->type = ARPHRD_ETHER;
8044
8045 break;
8046#ifdef CONFIG_IPW2200_MONITOR
8047 case 2:
8048 priv->ieee->iw_mode = IW_MODE_MONITOR;
24a47dbd
MK
8049#ifdef CONFIG_IEEE80211_RADIOTAP
8050 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8051#else
afbf30a2 8052 priv->net_dev->type = ARPHRD_IEEE80211;
24a47dbd 8053#endif
afbf30a2
JK
8054 break;
8055#endif
8056 default:
8057 case 0:
8058 priv->net_dev->type = ARPHRD_ETHER;
8059 priv->ieee->iw_mode = IW_MODE_INFRA;
8060 break;
8061 }
8062
8063 if (hwcrypto) {
8064 priv->ieee->host_encrypt = 0;
8065 priv->ieee->host_encrypt_msdu = 0;
8066 priv->ieee->host_decrypt = 0;
567deaf6 8067 priv->ieee->host_mc_decrypt = 0;
afbf30a2
JK
8068 }
8069 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
8070
e402c937
ZY
8071 /* IPW2200/2915 is abled to do hardware fragmentation. */
8072 priv->ieee->host_open_frag = 0;
8073
afbf30a2
JK
8074 if ((priv->pci_dev->device == 0x4223) ||
8075 (priv->pci_dev->device == 0x4224)) {
8076 if (init)
8077 printk(KERN_INFO DRV_NAME
8078 ": Detected Intel PRO/Wireless 2915ABG Network "
8079 "Connection\n");
8080 priv->ieee->abg_true = 1;
8081 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
8082 modulation = IEEE80211_OFDM_MODULATION |
8083 IEEE80211_CCK_MODULATION;
8084 priv->adapter = IPW_2915ABG;
8085 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
8086 } else {
8087 if (init)
8088 printk(KERN_INFO DRV_NAME
8089 ": Detected Intel PRO/Wireless 2200BG Network "
8090 "Connection\n");
8091
8092 priv->ieee->abg_true = 0;
8093 band = IEEE80211_24GHZ_BAND;
8094 modulation = IEEE80211_OFDM_MODULATION |
8095 IEEE80211_CCK_MODULATION;
8096 priv->adapter = IPW_2200BG;
8097 priv->ieee->mode = IEEE_G | IEEE_B;
8098 }
8099
8100 priv->ieee->freq_band = band;
8101 priv->ieee->modulation = modulation;
8102
8103 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
8104
8105 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
8106 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
8107
8108 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8109 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
8110 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
8111
8112 /* If power management is turned on, default to AC mode */
8113 priv->power_mode = IPW_POWER_AC;
8114 priv->tx_power = IPW_TX_POWER_DEFAULT;
8115
0ece35b5 8116 return old_mode == priv->ieee->iw_mode;
43f66a6c
JK
8117}
8118
43f66a6c
JK
8119/*
8120 * This file defines the Wireless Extension handlers. It does not
8121 * define any methods of hardware manipulation and relies on the
8122 * functions defined in ipw_main to provide the HW interaction.
bf79451e
JG
8123 *
8124 * The exception to this is the use of the ipw_get_ordinal()
43f66a6c
JK
8125 * function used to poll the hardware vs. making unecessary calls.
8126 *
8127 */
8128
bf79451e
JG
8129static int ipw_wx_get_name(struct net_device *dev,
8130 struct iw_request_info *info,
43f66a6c
JK
8131 union iwreq_data *wrqu, char *extra)
8132{
8133 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af
JK
8134 down(&priv->sem);
8135 if (priv->status & STATUS_RF_KILL_MASK)
a613bffd 8136 strcpy(wrqu->name, "radio off");
c848d0af 8137 else if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c 8138 strcpy(wrqu->name, "unassociated");
bf79451e 8139 else
43f66a6c
JK
8140 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
8141 ipw_modes[priv->assoc_request.ieee_mode]);
8142 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
c848d0af 8143 up(&priv->sem);
43f66a6c
JK
8144 return 0;
8145}
8146
8147static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
8148{
8149 if (channel == 0) {
8150 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
8151 priv->config &= ~CFG_STATIC_CHANNEL;
c848d0af
JK
8152 IPW_DEBUG_ASSOC("Attempting to associate with new "
8153 "parameters.\n");
8154 ipw_associate(priv);
43f66a6c
JK
8155 return 0;
8156 }
8157
8158 priv->config |= CFG_STATIC_CHANNEL;
8159
8160 if (priv->channel == channel) {
0edd5b44
JG
8161 IPW_DEBUG_INFO("Request to set channel to current value (%d)\n",
8162 channel);
43f66a6c
JK
8163 return 0;
8164 }
8165
8166 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
8167 priv->channel = channel;
8168
b095c381
JK
8169#ifdef CONFIG_IPW2200_MONITOR
8170 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
afbf30a2 8171 int i;
b095c381 8172 if (priv->status & STATUS_SCANNING) {
afbf30a2 8173 IPW_DEBUG_SCAN("Scan abort triggered due to "
b095c381 8174 "channel change.\n");
afbf30a2 8175 ipw_abort_scan(priv);
b095c381
JK
8176 }
8177
8178 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
8179 udelay(10);
8180
8181 if (priv->status & STATUS_SCANNING)
8182 IPW_DEBUG_SCAN("Still scanning...\n");
8183 else
8184 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
8185 1000 - i);
8186
8187 return 0;
8188 }
8189#endif /* CONFIG_IPW2200_MONITOR */
8190
c848d0af
JK
8191 /* Network configuration changed -- force [re]association */
8192 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
8193 if (!ipw_disassociate(priv))
43f66a6c 8194 ipw_associate(priv);
43f66a6c
JK
8195
8196 return 0;
8197}
8198
bf79451e
JG
8199static int ipw_wx_set_freq(struct net_device *dev,
8200 struct iw_request_info *info,
8201 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8202{
8203 struct ipw_priv *priv = ieee80211_priv(dev);
1fe0adb4 8204 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
43f66a6c 8205 struct iw_freq *fwrq = &wrqu->freq;
afbf30a2 8206 int ret = 0, i;
1fe0adb4
LH
8207 u8 channel, flags;
8208 int band;
b095c381
JK
8209
8210 if (fwrq->m == 0) {
8211 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
8212 down(&priv->sem);
8213 ret = ipw_set_channel(priv, 0);
8214 up(&priv->sem);
8215 return ret;
8216 }
43f66a6c
JK
8217 /* if setting by freq convert to channel */
8218 if (fwrq->e == 1) {
1fe0adb4 8219 channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
b095c381
JK
8220 if (channel == 0)
8221 return -EINVAL;
8222 } else
8223 channel = fwrq->m;
bf79451e 8224
1fe0adb4 8225 if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
b095c381 8226 return -EINVAL;
43f66a6c 8227
1fe0adb4
LH
8228 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
8229 i = ipw_channel_to_index(priv->ieee, channel);
afbf30a2
JK
8230 if (i == -1)
8231 return -EINVAL;
1fe0adb4
LH
8232
8233 flags = (band == IEEE80211_24GHZ_BAND) ?
8234 geo->bg[i].flags : geo->a[i].flags;
8235 if (flags & IEEE80211_CH_PASSIVE_ONLY) {
afbf30a2
JK
8236 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
8237 return -EINVAL;
8238 }
8239 }
8240
43f66a6c 8241 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
c848d0af 8242 down(&priv->sem);
b095c381 8243 ret = ipw_set_channel(priv, channel);
c848d0af
JK
8244 up(&priv->sem);
8245 return ret;
43f66a6c
JK
8246}
8247
bf79451e
JG
8248static int ipw_wx_get_freq(struct net_device *dev,
8249 struct iw_request_info *info,
43f66a6c
JK
8250 union iwreq_data *wrqu, char *extra)
8251{
8252 struct ipw_priv *priv = ieee80211_priv(dev);
8253
8254 wrqu->freq.e = 0;
8255
8256 /* If we are associated, trying to associate, or have a statically
8257 * configured CHANNEL then return that; otherwise return ANY */
c848d0af 8258 down(&priv->sem);
43f66a6c
JK
8259 if (priv->config & CFG_STATIC_CHANNEL ||
8260 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
8261 wrqu->freq.m = priv->channel;
bf79451e 8262 else
43f66a6c
JK
8263 wrqu->freq.m = 0;
8264
c848d0af 8265 up(&priv->sem);
43f66a6c
JK
8266 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
8267 return 0;
8268}
8269
bf79451e
JG
8270static int ipw_wx_set_mode(struct net_device *dev,
8271 struct iw_request_info *info,
43f66a6c
JK
8272 union iwreq_data *wrqu, char *extra)
8273{
8274 struct ipw_priv *priv = ieee80211_priv(dev);
8275 int err = 0;
8276
8277 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
43f66a6c
JK
8278
8279 switch (wrqu->mode) {
b095c381 8280#ifdef CONFIG_IPW2200_MONITOR
43f66a6c
JK
8281 case IW_MODE_MONITOR:
8282#endif
8283 case IW_MODE_ADHOC:
8284 case IW_MODE_INFRA:
8285 break;
8286 case IW_MODE_AUTO:
8287 wrqu->mode = IW_MODE_INFRA;
8288 break;
8289 default:
8290 return -EINVAL;
8291 }
b095c381
JK
8292 if (wrqu->mode == priv->ieee->iw_mode)
8293 return 0;
43f66a6c 8294
b095c381 8295 down(&priv->sem);
afbf30a2
JK
8296
8297 ipw_sw_reset(priv, 0);
8298
b095c381 8299#ifdef CONFIG_IPW2200_MONITOR
bf79451e 8300 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
43f66a6c 8301 priv->net_dev->type = ARPHRD_ETHER;
bf79451e
JG
8302
8303 if (wrqu->mode == IW_MODE_MONITOR)
24a47dbd
MK
8304#ifdef CONFIG_IEEE80211_RADIOTAP
8305 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8306#else
43f66a6c 8307 priv->net_dev->type = ARPHRD_IEEE80211;
24a47dbd 8308#endif
b095c381 8309#endif /* CONFIG_IPW2200_MONITOR */
bf79451e 8310
bf79451e 8311 /* Free the existing firmware and reset the fw_loaded
43f66a6c 8312 * flag so ipw_load() will bring in the new firmawre */
afbf30a2 8313 free_firmware();
43f66a6c
JK
8314
8315 priv->ieee->iw_mode = wrqu->mode;
bf79451e 8316
c848d0af
JK
8317 queue_work(priv->workqueue, &priv->adapter_restart);
8318 up(&priv->sem);
0edd5b44 8319 return err;
43f66a6c
JK
8320}
8321
bf79451e 8322static int ipw_wx_get_mode(struct net_device *dev,
0edd5b44
JG
8323 struct iw_request_info *info,
8324 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8325{
8326 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8327 down(&priv->sem);
43f66a6c
JK
8328 wrqu->mode = priv->ieee->iw_mode;
8329 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
c848d0af 8330 up(&priv->sem);
43f66a6c
JK
8331 return 0;
8332}
8333
43f66a6c
JK
8334/* Values are in microsecond */
8335static const s32 timeout_duration[] = {
8336 350000,
8337 250000,
8338 75000,
8339 37000,
8340 25000,
8341};
8342
8343static const s32 period_duration[] = {
8344 400000,
8345 700000,
8346 1000000,
8347 1000000,
8348 1000000
8349};
8350
bf79451e
JG
8351static int ipw_wx_get_range(struct net_device *dev,
8352 struct iw_request_info *info,
43f66a6c
JK
8353 union iwreq_data *wrqu, char *extra)
8354{
8355 struct ipw_priv *priv = ieee80211_priv(dev);
8356 struct iw_range *range = (struct iw_range *)extra;
1fe0adb4 8357 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
b095c381 8358 int i = 0, j;
43f66a6c
JK
8359
8360 wrqu->data.length = sizeof(*range);
8361 memset(range, 0, sizeof(*range));
8362
8363 /* 54Mbs == ~27 Mb/s real (802.11g) */
bf79451e 8364 range->throughput = 27 * 1000 * 1000;
43f66a6c
JK
8365
8366 range->max_qual.qual = 100;
8367 /* TODO: Find real max RSSI and stick here */
8368 range->max_qual.level = 0;
c848d0af 8369 range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
0edd5b44 8370 range->max_qual.updated = 7; /* Updated all three */
43f66a6c
JK
8371
8372 range->avg_qual.qual = 70;
8373 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
0edd5b44 8374 range->avg_qual.level = 0; /* FIXME to real average level */
43f66a6c 8375 range->avg_qual.noise = 0;
0edd5b44 8376 range->avg_qual.updated = 7; /* Updated all three */
c848d0af 8377 down(&priv->sem);
0edd5b44 8378 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
43f66a6c 8379
bf79451e
JG
8380 for (i = 0; i < range->num_bitrates; i++)
8381 range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) *
0edd5b44 8382 500000;
bf79451e 8383
43f66a6c
JK
8384 range->max_rts = DEFAULT_RTS_THRESHOLD;
8385 range->min_frag = MIN_FRAG_THRESHOLD;
8386 range->max_frag = MAX_FRAG_THRESHOLD;
8387
8388 range->encoding_size[0] = 5;
bf79451e 8389 range->encoding_size[1] = 13;
43f66a6c
JK
8390 range->num_encoding_sizes = 2;
8391 range->max_encoding_tokens = WEP_KEYS;
8392
8393 /* Set the Wireless Extension versions */
8394 range->we_version_compiled = WIRELESS_EXT;
8395 range->we_version_source = 16;
8396
b095c381
JK
8397 i = 0;
8398 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
8399 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
8400 i++, j++) {
8401 range->freq[i].i = geo->bg[j].channel;
8402 range->freq[i].m = geo->bg[j].freq * 100000;
8403 range->freq[i].e = 1;
8404 }
8405 }
43f66a6c 8406
b095c381
JK
8407 if (priv->ieee->mode & IEEE_A) {
8408 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
8409 i++, j++) {
8410 range->freq[i].i = geo->a[j].channel;
8411 range->freq[i].m = geo->a[j].freq * 100000;
8412 range->freq[i].e = 1;
8413 }
43f66a6c 8414 }
b095c381
JK
8415
8416 range->num_channels = i;
8417 range->num_frequency = i;
8418
c848d0af 8419 up(&priv->sem);
97a78ca9
BB
8420
8421 /* Event capability (kernel + driver) */
8422 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
8423 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
8424 IW_EVENT_CAPA_MASK(SIOCGIWAP));
8425 range->event_capa[1] = IW_EVENT_CAPA_K_1;
8426
43f66a6c
JK
8427 IPW_DEBUG_WX("GET Range\n");
8428 return 0;
8429}
8430
bf79451e
JG
8431static int ipw_wx_set_wap(struct net_device *dev,
8432 struct iw_request_info *info,
43f66a6c
JK
8433 union iwreq_data *wrqu, char *extra)
8434{
8435 struct ipw_priv *priv = ieee80211_priv(dev);
8436
8437 static const unsigned char any[] = {
8438 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
8439 };
8440 static const unsigned char off[] = {
8441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
8442 };
8443
bf79451e 8444 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
43f66a6c 8445 return -EINVAL;
c848d0af 8446 down(&priv->sem);
43f66a6c
JK
8447 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
8448 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
8449 /* we disable mandatory BSSID association */
8450 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
8451 priv->config &= ~CFG_STATIC_BSSID;
c848d0af
JK
8452 IPW_DEBUG_ASSOC("Attempting to associate with new "
8453 "parameters.\n");
8454 ipw_associate(priv);
8455 up(&priv->sem);
43f66a6c
JK
8456 return 0;
8457 }
8458
8459 priv->config |= CFG_STATIC_BSSID;
8460 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
8461 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
c848d0af 8462 up(&priv->sem);
43f66a6c
JK
8463 return 0;
8464 }
8465
8466 IPW_DEBUG_WX("Setting mandatory BSSID to " MAC_FMT "\n",
8467 MAC_ARG(wrqu->ap_addr.sa_data));
8468
8469 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
8470
c848d0af
JK
8471 /* Network configuration changed -- force [re]association */
8472 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
8473 if (!ipw_disassociate(priv))
43f66a6c 8474 ipw_associate(priv);
43f66a6c 8475
c848d0af 8476 up(&priv->sem);
43f66a6c
JK
8477 return 0;
8478}
8479
bf79451e
JG
8480static int ipw_wx_get_wap(struct net_device *dev,
8481 struct iw_request_info *info,
43f66a6c
JK
8482 union iwreq_data *wrqu, char *extra)
8483{
8484 struct ipw_priv *priv = ieee80211_priv(dev);
8485 /* If we are associated, trying to associate, or have a statically
8486 * configured BSSID then return that; otherwise return ANY */
c848d0af 8487 down(&priv->sem);
bf79451e 8488 if (priv->config & CFG_STATIC_BSSID ||
43f66a6c
JK
8489 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
8490 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
afbf30a2 8491 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
43f66a6c
JK
8492 } else
8493 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
8494
8495 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
8496 MAC_ARG(wrqu->ap_addr.sa_data));
c848d0af 8497 up(&priv->sem);
43f66a6c
JK
8498 return 0;
8499}
8500
bf79451e
JG
8501static int ipw_wx_set_essid(struct net_device *dev,
8502 struct iw_request_info *info,
43f66a6c
JK
8503 union iwreq_data *wrqu, char *extra)
8504{
8505 struct ipw_priv *priv = ieee80211_priv(dev);
0edd5b44 8506 char *essid = ""; /* ANY */
43f66a6c 8507 int length = 0;
c848d0af 8508 down(&priv->sem);
43f66a6c
JK
8509 if (wrqu->essid.flags && wrqu->essid.length) {
8510 length = wrqu->essid.length - 1;
8511 essid = extra;
8512 }
8513 if (length == 0) {
8514 IPW_DEBUG_WX("Setting ESSID to ANY\n");
afbf30a2
JK
8515 if ((priv->config & CFG_STATIC_ESSID) &&
8516 !(priv->status & (STATUS_ASSOCIATED |
8517 STATUS_ASSOCIATING))) {
43f66a6c
JK
8518 IPW_DEBUG_ASSOC("Attempting to associate with new "
8519 "parameters.\n");
afbf30a2 8520 priv->config &= ~CFG_STATIC_ESSID;
43f66a6c
JK
8521 ipw_associate(priv);
8522 }
c848d0af 8523 up(&priv->sem);
43f66a6c
JK
8524 return 0;
8525 }
8526
8527 length = min(length, IW_ESSID_MAX_SIZE);
8528
8529 priv->config |= CFG_STATIC_ESSID;
8530
8531 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
8532 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
c848d0af 8533 up(&priv->sem);
43f66a6c
JK
8534 return 0;
8535 }
8536
8537 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
8538 length);
8539
8540 priv->essid_len = length;
8541 memcpy(priv->essid, essid, priv->essid_len);
bf79451e 8542
c848d0af
JK
8543 /* Network configuration changed -- force [re]association */
8544 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
8545 if (!ipw_disassociate(priv))
43f66a6c 8546 ipw_associate(priv);
43f66a6c 8547
c848d0af 8548 up(&priv->sem);
43f66a6c
JK
8549 return 0;
8550}
8551
bf79451e
JG
8552static int ipw_wx_get_essid(struct net_device *dev,
8553 struct iw_request_info *info,
43f66a6c
JK
8554 union iwreq_data *wrqu, char *extra)
8555{
8556 struct ipw_priv *priv = ieee80211_priv(dev);
8557
8558 /* If we are associated, trying to associate, or have a statically
8559 * configured ESSID then return that; otherwise return ANY */
c848d0af 8560 down(&priv->sem);
43f66a6c 8561 if (priv->config & CFG_STATIC_ESSID ||
bf79451e
JG
8562 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
8563 IPW_DEBUG_WX("Getting essid: '%s'\n",
43f66a6c 8564 escape_essid(priv->essid, priv->essid_len));
bf79451e 8565 memcpy(extra, priv->essid, priv->essid_len);
43f66a6c 8566 wrqu->essid.length = priv->essid_len;
0edd5b44 8567 wrqu->essid.flags = 1; /* active */
43f66a6c
JK
8568 } else {
8569 IPW_DEBUG_WX("Getting essid: ANY\n");
8570 wrqu->essid.length = 0;
0edd5b44 8571 wrqu->essid.flags = 0; /* active */
43f66a6c 8572 }
c848d0af 8573 up(&priv->sem);
43f66a6c
JK
8574 return 0;
8575}
8576
bf79451e
JG
8577static int ipw_wx_set_nick(struct net_device *dev,
8578 struct iw_request_info *info,
43f66a6c 8579 union iwreq_data *wrqu, char *extra)
bf79451e 8580{
43f66a6c
JK
8581 struct ipw_priv *priv = ieee80211_priv(dev);
8582
8583 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
8584 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
8585 return -E2BIG;
c848d0af 8586 down(&priv->sem);
0edd5b44 8587 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
43f66a6c 8588 memset(priv->nick, 0, sizeof(priv->nick));
0edd5b44 8589 memcpy(priv->nick, extra, wrqu->data.length);
43f66a6c 8590 IPW_DEBUG_TRACE("<<\n");
c848d0af 8591 up(&priv->sem);
43f66a6c
JK
8592 return 0;
8593
8594}
8595
bf79451e
JG
8596static int ipw_wx_get_nick(struct net_device *dev,
8597 struct iw_request_info *info,
43f66a6c 8598 union iwreq_data *wrqu, char *extra)
bf79451e 8599{
43f66a6c
JK
8600 struct ipw_priv *priv = ieee80211_priv(dev);
8601 IPW_DEBUG_WX("Getting nick\n");
c848d0af 8602 down(&priv->sem);
43f66a6c
JK
8603 wrqu->data.length = strlen(priv->nick) + 1;
8604 memcpy(extra, priv->nick, wrqu->data.length);
0edd5b44 8605 wrqu->data.flags = 1; /* active */
c848d0af 8606 up(&priv->sem);
43f66a6c
JK
8607 return 0;
8608}
8609
43f66a6c
JK
8610static int ipw_wx_set_rate(struct net_device *dev,
8611 struct iw_request_info *info,
8612 union iwreq_data *wrqu, char *extra)
bf79451e 8613{
ea2b26e0
JK
8614 /* TODO: We should use semaphores or locks for access to priv */
8615 struct ipw_priv *priv = ieee80211_priv(dev);
8616 u32 target_rate = wrqu->bitrate.value;
8617 u32 fixed, mask;
8618
8619 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
8620 /* value = X, fixed = 1 means only rate X */
8621 /* value = X, fixed = 0 means all rates lower equal X */
8622
8623 if (target_rate == -1) {
8624 fixed = 0;
8625 mask = IEEE80211_DEFAULT_RATES_MASK;
8626 /* Now we should reassociate */
8627 goto apply;
8628 }
8629
8630 mask = 0;
8631 fixed = wrqu->bitrate.fixed;
8632
8633 if (target_rate == 1000000 || !fixed)
8634 mask |= IEEE80211_CCK_RATE_1MB_MASK;
8635 if (target_rate == 1000000)
8636 goto apply;
8637
8638 if (target_rate == 2000000 || !fixed)
8639 mask |= IEEE80211_CCK_RATE_2MB_MASK;
8640 if (target_rate == 2000000)
8641 goto apply;
8642
8643 if (target_rate == 5500000 || !fixed)
8644 mask |= IEEE80211_CCK_RATE_5MB_MASK;
8645 if (target_rate == 5500000)
8646 goto apply;
8647
8648 if (target_rate == 6000000 || !fixed)
8649 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
8650 if (target_rate == 6000000)
8651 goto apply;
8652
8653 if (target_rate == 9000000 || !fixed)
8654 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
8655 if (target_rate == 9000000)
8656 goto apply;
8657
8658 if (target_rate == 11000000 || !fixed)
8659 mask |= IEEE80211_CCK_RATE_11MB_MASK;
8660 if (target_rate == 11000000)
8661 goto apply;
8662
8663 if (target_rate == 12000000 || !fixed)
8664 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
8665 if (target_rate == 12000000)
8666 goto apply;
8667
8668 if (target_rate == 18000000 || !fixed)
8669 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
8670 if (target_rate == 18000000)
8671 goto apply;
8672
8673 if (target_rate == 24000000 || !fixed)
8674 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
8675 if (target_rate == 24000000)
8676 goto apply;
8677
8678 if (target_rate == 36000000 || !fixed)
8679 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
8680 if (target_rate == 36000000)
8681 goto apply;
8682
8683 if (target_rate == 48000000 || !fixed)
8684 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
8685 if (target_rate == 48000000)
8686 goto apply;
8687
8688 if (target_rate == 54000000 || !fixed)
8689 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
8690 if (target_rate == 54000000)
8691 goto apply;
8692
8693 IPW_DEBUG_WX("invalid rate specified, returning error\n");
8694 return -EINVAL;
8695
8696 apply:
8697 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
8698 mask, fixed ? "fixed" : "sub-rates");
c848d0af 8699 down(&priv->sem);
b095c381 8700 if (mask == IEEE80211_DEFAULT_RATES_MASK) {
ea2b26e0 8701 priv->config &= ~CFG_FIXED_RATE;
b095c381
JK
8702 ipw_set_fixed_rate(priv, priv->ieee->mode);
8703 } else
ea2b26e0
JK
8704 priv->config |= CFG_FIXED_RATE;
8705
c848d0af
JK
8706 if (priv->rates_mask == mask) {
8707 IPW_DEBUG_WX("Mask set to current mask.\n");
8708 up(&priv->sem);
8709 return 0;
ea2b26e0
JK
8710 }
8711
c848d0af
JK
8712 priv->rates_mask = mask;
8713
8714 /* Network configuration changed -- force [re]association */
8715 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
8716 if (!ipw_disassociate(priv))
8717 ipw_associate(priv);
8718
8719 up(&priv->sem);
ea2b26e0 8720 return 0;
43f66a6c
JK
8721}
8722
bf79451e
JG
8723static int ipw_wx_get_rate(struct net_device *dev,
8724 struct iw_request_info *info,
43f66a6c 8725 union iwreq_data *wrqu, char *extra)
bf79451e 8726{
0edd5b44 8727 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8728 down(&priv->sem);
43f66a6c 8729 wrqu->bitrate.value = priv->last_rate;
c848d0af 8730 up(&priv->sem);
43f66a6c
JK
8731 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
8732 return 0;
8733}
8734
bf79451e
JG
8735static int ipw_wx_set_rts(struct net_device *dev,
8736 struct iw_request_info *info,
43f66a6c 8737 union iwreq_data *wrqu, char *extra)
bf79451e 8738{
43f66a6c 8739 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8740 down(&priv->sem);
43f66a6c
JK
8741 if (wrqu->rts.disabled)
8742 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8743 else {
8744 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
c848d0af
JK
8745 wrqu->rts.value > MAX_RTS_THRESHOLD) {
8746 up(&priv->sem);
43f66a6c 8747 return -EINVAL;
c848d0af 8748 }
43f66a6c
JK
8749 priv->rts_threshold = wrqu->rts.value;
8750 }
8751
8752 ipw_send_rts_threshold(priv, priv->rts_threshold);
c848d0af 8753 up(&priv->sem);
43f66a6c
JK
8754 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
8755 return 0;
8756}
8757
bf79451e
JG
8758static int ipw_wx_get_rts(struct net_device *dev,
8759 struct iw_request_info *info,
43f66a6c 8760 union iwreq_data *wrqu, char *extra)
bf79451e 8761{
43f66a6c 8762 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8763 down(&priv->sem);
43f66a6c
JK
8764 wrqu->rts.value = priv->rts_threshold;
8765 wrqu->rts.fixed = 0; /* no auto select */
0edd5b44 8766 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
c848d0af 8767 up(&priv->sem);
43f66a6c
JK
8768 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
8769 return 0;
8770}
8771
bf79451e
JG
8772static int ipw_wx_set_txpow(struct net_device *dev,
8773 struct iw_request_info *info,
43f66a6c 8774 union iwreq_data *wrqu, char *extra)
bf79451e 8775{
43f66a6c 8776 struct ipw_priv *priv = ieee80211_priv(dev);
6de9f7f2 8777 int err = 0;
b095c381 8778
c848d0af
JK
8779 down(&priv->sem);
8780 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
6de9f7f2
ZY
8781 err = -EINPROGRESS;
8782 goto out;
c848d0af 8783 }
43f66a6c 8784
b095c381
JK
8785 if (!wrqu->power.fixed)
8786 wrqu->power.value = IPW_TX_POWER_DEFAULT;
8787
c848d0af 8788 if (wrqu->power.flags != IW_TXPOW_DBM) {
6de9f7f2
ZY
8789 err = -EINVAL;
8790 goto out;
c848d0af 8791 }
43f66a6c 8792
b095c381 8793 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
afbf30a2 8794 (wrqu->power.value < IPW_TX_POWER_MIN)) {
6de9f7f2
ZY
8795 err = -EINVAL;
8796 goto out;
c848d0af 8797 }
43f66a6c
JK
8798
8799 priv->tx_power = wrqu->power.value;
6de9f7f2
ZY
8800 err = ipw_set_tx_power(priv);
8801 out:
c848d0af 8802 up(&priv->sem);
6de9f7f2 8803 return err;
43f66a6c
JK
8804}
8805
bf79451e
JG
8806static int ipw_wx_get_txpow(struct net_device *dev,
8807 struct iw_request_info *info,
43f66a6c 8808 union iwreq_data *wrqu, char *extra)
bf79451e 8809{
43f66a6c 8810 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8811 down(&priv->sem);
43f66a6c
JK
8812 wrqu->power.value = priv->tx_power;
8813 wrqu->power.fixed = 1;
8814 wrqu->power.flags = IW_TXPOW_DBM;
8815 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
c848d0af 8816 up(&priv->sem);
43f66a6c 8817
bf79451e 8818 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
22501c8e 8819 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
43f66a6c
JK
8820
8821 return 0;
8822}
8823
bf79451e 8824static int ipw_wx_set_frag(struct net_device *dev,
0edd5b44
JG
8825 struct iw_request_info *info,
8826 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8827{
8828 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8829 down(&priv->sem);
43f66a6c
JK
8830 if (wrqu->frag.disabled)
8831 priv->ieee->fts = DEFAULT_FTS;
8832 else {
8833 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
b095c381
JK
8834 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
8835 up(&priv->sem);
43f66a6c 8836 return -EINVAL;
b095c381 8837 }
bf79451e 8838
43f66a6c
JK
8839 priv->ieee->fts = wrqu->frag.value & ~0x1;
8840 }
8841
8842 ipw_send_frag_threshold(priv, wrqu->frag.value);
c848d0af 8843 up(&priv->sem);
43f66a6c
JK
8844 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
8845 return 0;
8846}
8847
bf79451e 8848static int ipw_wx_get_frag(struct net_device *dev,
0edd5b44
JG
8849 struct iw_request_info *info,
8850 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8851{
8852 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8853 down(&priv->sem);
43f66a6c
JK
8854 wrqu->frag.value = priv->ieee->fts;
8855 wrqu->frag.fixed = 0; /* no auto select */
0edd5b44 8856 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
c848d0af 8857 up(&priv->sem);
43f66a6c
JK
8858 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
8859
8860 return 0;
8861}
8862
bf79451e
JG
8863static int ipw_wx_set_retry(struct net_device *dev,
8864 struct iw_request_info *info,
43f66a6c 8865 union iwreq_data *wrqu, char *extra)
bf79451e 8866{
afbf30a2
JK
8867 struct ipw_priv *priv = ieee80211_priv(dev);
8868
8869 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
8870 return -EINVAL;
8871
8872 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
8873 return 0;
8874
8875 if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
8876 return -EINVAL;
8877
8878 down(&priv->sem);
8879 if (wrqu->retry.flags & IW_RETRY_MIN)
8880 priv->short_retry_limit = (u8) wrqu->retry.value;
8881 else if (wrqu->retry.flags & IW_RETRY_MAX)
8882 priv->long_retry_limit = (u8) wrqu->retry.value;
8883 else {
8884 priv->short_retry_limit = (u8) wrqu->retry.value;
8885 priv->long_retry_limit = (u8) wrqu->retry.value;
8886 }
8887
8888 ipw_send_retry_limit(priv, priv->short_retry_limit,
8889 priv->long_retry_limit);
8890 up(&priv->sem);
8891 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
8892 priv->short_retry_limit, priv->long_retry_limit);
8893 return 0;
43f66a6c
JK
8894}
8895
bf79451e
JG
8896static int ipw_wx_get_retry(struct net_device *dev,
8897 struct iw_request_info *info,
43f66a6c 8898 union iwreq_data *wrqu, char *extra)
bf79451e 8899{
afbf30a2
JK
8900 struct ipw_priv *priv = ieee80211_priv(dev);
8901
8902 down(&priv->sem);
8903 wrqu->retry.disabled = 0;
8904
8905 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
8906 up(&priv->sem);
8907 return -EINVAL;
8908 }
8909
8910 if (wrqu->retry.flags & IW_RETRY_MAX) {
8911 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
8912 wrqu->retry.value = priv->long_retry_limit;
8913 } else if (wrqu->retry.flags & IW_RETRY_MIN) {
8914 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
8915 wrqu->retry.value = priv->short_retry_limit;
8916 } else {
8917 wrqu->retry.flags = IW_RETRY_LIMIT;
8918 wrqu->retry.value = priv->short_retry_limit;
8919 }
8920 up(&priv->sem);
8921
8922 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
8923
8924 return 0;
8925}
8926
afbf30a2
JK
8927static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
8928 int essid_len)
8929{
8930 struct ipw_scan_request_ext scan;
8931 int err = 0, scan_type;
8932
8933 down(&priv->sem);
8934
8935 if (priv->status & STATUS_RF_KILL_MASK) {
8936 IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
8937 priv->status |= STATUS_SCAN_PENDING;
8938 goto done;
8939 }
8940
8941 IPW_DEBUG_HC("starting request direct scan!\n");
8942
8943 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
8944 err = wait_event_interruptible(priv->wait_state,
8945 !(priv->
8946 status & (STATUS_SCANNING |
8947 STATUS_SCAN_ABORTING)));
8948 if (err) {
8949 IPW_DEBUG_HC("aborting direct scan");
8950 goto done;
8951 }
8952 }
8953 memset(&scan, 0, sizeof(scan));
8954
8955 if (priv->config & CFG_SPEED_SCAN)
8956 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8957 cpu_to_le16(30);
8958 else
8959 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8960 cpu_to_le16(20);
8961
8962 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
8963 cpu_to_le16(20);
1fe0adb4 8964 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
afbf30a2
JK
8965 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
8966
8967 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
8968
8969 err = ipw_send_ssid(priv, essid, essid_len);
8970 if (err) {
8971 IPW_DEBUG_HC("Attempt to send SSID command failed\n");
8972 goto done;
8973 }
8974 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
8975
8976 ipw_add_scan_channels(priv, &scan, scan_type);
8977
8978 err = ipw_send_scan_request_ext(priv, &scan);
8979 if (err) {
8980 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
8981 goto done;
8982 }
8983
8984 priv->status |= STATUS_SCANNING;
8985
8986 done:
8987 up(&priv->sem);
8988 return err;
43f66a6c
JK
8989}
8990
bf79451e
JG
8991static int ipw_wx_set_scan(struct net_device *dev,
8992 struct iw_request_info *info,
43f66a6c
JK
8993 union iwreq_data *wrqu, char *extra)
8994{
8995 struct ipw_priv *priv = ieee80211_priv(dev);
afbf30a2
JK
8996 struct iw_scan_req *req = NULL;
8997 if (wrqu->data.length
8998 && wrqu->data.length == sizeof(struct iw_scan_req)) {
8999 req = (struct iw_scan_req *)extra;
9000 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
9001 ipw_request_direct_scan(priv, req->essid,
9002 req->essid_len);
9003 return 0;
9004 }
9005 }
8935f39e 9006
43f66a6c 9007 IPW_DEBUG_WX("Start scan\n");
b095c381
JK
9008
9009 queue_work(priv->workqueue, &priv->request_scan);
9010
43f66a6c
JK
9011 return 0;
9012}
9013
bf79451e
JG
9014static int ipw_wx_get_scan(struct net_device *dev,
9015 struct iw_request_info *info,
43f66a6c 9016 union iwreq_data *wrqu, char *extra)
bf79451e 9017{
43f66a6c
JK
9018 struct ipw_priv *priv = ieee80211_priv(dev);
9019 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
9020}
9021
bf79451e 9022static int ipw_wx_set_encode(struct net_device *dev,
0edd5b44
JG
9023 struct iw_request_info *info,
9024 union iwreq_data *wrqu, char *key)
43f66a6c
JK
9025{
9026 struct ipw_priv *priv = ieee80211_priv(dev);
afbf30a2 9027 int ret;
caeff81b 9028 u32 cap = priv->capability;
afbf30a2
JK
9029
9030 down(&priv->sem);
9031 ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
afbf30a2 9032
caeff81b
HL
9033 /* In IBSS mode, we need to notify the firmware to update
9034 * the beacon info after we changed the capability. */
9035 if (cap != priv->capability &&
9036 priv->ieee->iw_mode == IW_MODE_ADHOC &&
9037 priv->status & STATUS_ASSOCIATED)
9038 ipw_disassociate(priv);
9039
9040 up(&priv->sem);
afbf30a2 9041 return ret;
43f66a6c
JK
9042}
9043
bf79451e 9044static int ipw_wx_get_encode(struct net_device *dev,
0edd5b44
JG
9045 struct iw_request_info *info,
9046 union iwreq_data *wrqu, char *key)
43f66a6c
JK
9047{
9048 struct ipw_priv *priv = ieee80211_priv(dev);
9049 return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
9050}
9051
bf79451e 9052static int ipw_wx_set_power(struct net_device *dev,
0edd5b44
JG
9053 struct iw_request_info *info,
9054 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
9055{
9056 struct ipw_priv *priv = ieee80211_priv(dev);
9057 int err;
c848d0af 9058 down(&priv->sem);
43f66a6c
JK
9059 if (wrqu->power.disabled) {
9060 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
9061 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
9062 if (err) {
9063 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 9064 up(&priv->sem);
43f66a6c
JK
9065 return err;
9066 }
43f66a6c 9067 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
c848d0af 9068 up(&priv->sem);
43f66a6c 9069 return 0;
bf79451e 9070 }
43f66a6c
JK
9071
9072 switch (wrqu->power.flags & IW_POWER_MODE) {
0edd5b44
JG
9073 case IW_POWER_ON: /* If not specified */
9074 case IW_POWER_MODE: /* If set all mask */
9075 case IW_POWER_ALL_R: /* If explicitely state all */
43f66a6c 9076 break;
0edd5b44 9077 default: /* Otherwise we don't support it */
43f66a6c
JK
9078 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
9079 wrqu->power.flags);
c848d0af 9080 up(&priv->sem);
bf79451e 9081 return -EOPNOTSUPP;
43f66a6c 9082 }
bf79451e 9083
43f66a6c
JK
9084 /* If the user hasn't specified a power management mode yet, default
9085 * to BATTERY */
0edd5b44 9086 if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)
43f66a6c 9087 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
bf79451e 9088 else
43f66a6c
JK
9089 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
9090 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
9091 if (err) {
9092 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 9093 up(&priv->sem);
43f66a6c
JK
9094 return err;
9095 }
9096
0edd5b44 9097 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
c848d0af 9098 up(&priv->sem);
43f66a6c
JK
9099 return 0;
9100}
9101
bf79451e 9102static int ipw_wx_get_power(struct net_device *dev,
0edd5b44
JG
9103 struct iw_request_info *info,
9104 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
9105{
9106 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 9107 down(&priv->sem);
a613bffd 9108 if (!(priv->power_mode & IPW_POWER_ENABLED))
43f66a6c 9109 wrqu->power.disabled = 1;
a613bffd 9110 else
43f66a6c 9111 wrqu->power.disabled = 0;
43f66a6c 9112
c848d0af 9113 up(&priv->sem);
43f66a6c 9114 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
bf79451e 9115
43f66a6c
JK
9116 return 0;
9117}
9118
bf79451e 9119static int ipw_wx_set_powermode(struct net_device *dev,
0edd5b44
JG
9120 struct iw_request_info *info,
9121 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
9122{
9123 struct ipw_priv *priv = ieee80211_priv(dev);
9124 int mode = *(int *)extra;
9125 int err;
c848d0af 9126 down(&priv->sem);
43f66a6c
JK
9127 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
9128 mode = IPW_POWER_AC;
9129 priv->power_mode = mode;
9130 } else {
9131 priv->power_mode = IPW_POWER_ENABLED | mode;
9132 }
bf79451e 9133
43f66a6c
JK
9134 if (priv->power_mode != mode) {
9135 err = ipw_send_power_mode(priv, mode);
bf79451e 9136
43f66a6c
JK
9137 if (err) {
9138 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 9139 up(&priv->sem);
43f66a6c
JK
9140 return err;
9141 }
9142 }
c848d0af 9143 up(&priv->sem);
43f66a6c
JK
9144 return 0;
9145}
9146
9147#define MAX_WX_STRING 80
bf79451e 9148static int ipw_wx_get_powermode(struct net_device *dev,
0edd5b44
JG
9149 struct iw_request_info *info,
9150 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
9151{
9152 struct ipw_priv *priv = ieee80211_priv(dev);
9153 int level = IPW_POWER_LEVEL(priv->power_mode);
9154 char *p = extra;
9155
9156 p += snprintf(p, MAX_WX_STRING, "Power save level: %d ", level);
9157
9158 switch (level) {
9159 case IPW_POWER_AC:
9160 p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
9161 break;
9162 case IPW_POWER_BATTERY:
9163 p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
9164 break;
9165 default:
9166 p += snprintf(p, MAX_WX_STRING - (p - extra),
bf79451e 9167 "(Timeout %dms, Period %dms)",
43f66a6c
JK
9168 timeout_duration[level - 1] / 1000,
9169 period_duration[level - 1] / 1000);
9170 }
9171
9172 if (!(priv->power_mode & IPW_POWER_ENABLED))
0edd5b44 9173 p += snprintf(p, MAX_WX_STRING - (p - extra), " OFF");
43f66a6c
JK
9174
9175 wrqu->data.length = p - extra + 1;
9176
9177 return 0;
9178}
9179
9180static int ipw_wx_set_wireless_mode(struct net_device *dev,
0edd5b44
JG
9181 struct iw_request_info *info,
9182 union iwreq_data *wrqu, char *extra)
43f66a6c 9183{
0edd5b44 9184 struct ipw_priv *priv = ieee80211_priv(dev);
43f66a6c
JK
9185 int mode = *(int *)extra;
9186 u8 band = 0, modulation = 0;
9187
9188 if (mode == 0 || mode & ~IEEE_MODE_MASK) {
0edd5b44 9189 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
43f66a6c
JK
9190 return -EINVAL;
9191 }
c848d0af 9192 down(&priv->sem);
43f66a6c 9193 if (priv->adapter == IPW_2915ABG) {
a33a1982 9194 priv->ieee->abg_true = 1;
43f66a6c
JK
9195 if (mode & IEEE_A) {
9196 band |= IEEE80211_52GHZ_BAND;
9197 modulation |= IEEE80211_OFDM_MODULATION;
9198 } else
a33a1982 9199 priv->ieee->abg_true = 0;
43f66a6c
JK
9200 } else {
9201 if (mode & IEEE_A) {
9202 IPW_WARNING("Attempt to set 2200BG into "
9203 "802.11a mode\n");
c848d0af 9204 up(&priv->sem);
43f66a6c
JK
9205 return -EINVAL;
9206 }
9207
a33a1982 9208 priv->ieee->abg_true = 0;
43f66a6c
JK
9209 }
9210
9211 if (mode & IEEE_B) {
9212 band |= IEEE80211_24GHZ_BAND;
9213 modulation |= IEEE80211_CCK_MODULATION;
9214 } else
a33a1982 9215 priv->ieee->abg_true = 0;
bf79451e 9216
43f66a6c
JK
9217 if (mode & IEEE_G) {
9218 band |= IEEE80211_24GHZ_BAND;
9219 modulation |= IEEE80211_OFDM_MODULATION;
9220 } else
a33a1982 9221 priv->ieee->abg_true = 0;
43f66a6c
JK
9222
9223 priv->ieee->mode = mode;
9224 priv->ieee->freq_band = band;
9225 priv->ieee->modulation = modulation;
0edd5b44 9226 init_supported_rates(priv, &priv->rates);
43f66a6c 9227
c848d0af
JK
9228 /* Network configuration changed -- force [re]association */
9229 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
9230 if (!ipw_disassociate(priv)) {
43f66a6c 9231 ipw_send_supported_rates(priv, &priv->rates);
c848d0af
JK
9232 ipw_associate(priv);
9233 }
43f66a6c 9234
a613bffd
JK
9235 /* Update the band LEDs */
9236 ipw_led_band_on(priv);
9237
bf79451e 9238 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
43f66a6c 9239 mode & IEEE_A ? 'a' : '.',
0edd5b44 9240 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
c848d0af 9241 up(&priv->sem);
43f66a6c
JK
9242 return 0;
9243}
9244
9245static int ipw_wx_get_wireless_mode(struct net_device *dev,
0edd5b44
JG
9246 struct iw_request_info *info,
9247 union iwreq_data *wrqu, char *extra)
43f66a6c 9248{
0edd5b44 9249 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 9250 down(&priv->sem);
ea2b26e0
JK
9251 switch (priv->ieee->mode) {
9252 case IEEE_A:
43f66a6c
JK
9253 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
9254 break;
ea2b26e0
JK
9255 case IEEE_B:
9256 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
9257 break;
9258 case IEEE_A | IEEE_B:
9259 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
9260 break;
9261 case IEEE_G:
9262 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
9263 break;
9264 case IEEE_A | IEEE_G:
9265 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
9266 break;
9267 case IEEE_B | IEEE_G:
9268 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
9269 break;
9270 case IEEE_A | IEEE_B | IEEE_G:
9271 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
9272 break;
9273 default:
9274 strncpy(extra, "unknown", MAX_WX_STRING);
43f66a6c 9275 break;
bf79451e
JG
9276 }
9277
b095c381
JK
9278 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
9279
9280 wrqu->data.length = strlen(extra) + 1;
9281 up(&priv->sem);
9282
9283 return 0;
9284}
9285
9286static int ipw_wx_set_preamble(struct net_device *dev,
9287 struct iw_request_info *info,
9288 union iwreq_data *wrqu, char *extra)
9289{
9290 struct ipw_priv *priv = ieee80211_priv(dev);
9291 int mode = *(int *)extra;
9292 down(&priv->sem);
9293 /* Switching from SHORT -> LONG requires a disassociation */
9294 if (mode == 1) {
9295 if (!(priv->config & CFG_PREAMBLE_LONG)) {
9296 priv->config |= CFG_PREAMBLE_LONG;
9297
9298 /* Network configuration changed -- force [re]association */
9299 IPW_DEBUG_ASSOC
9300 ("[re]association triggered due to preamble change.\n");
9301 if (!ipw_disassociate(priv))
9302 ipw_associate(priv);
9303 }
9304 goto done;
9305 }
9306
9307 if (mode == 0) {
9308 priv->config &= ~CFG_PREAMBLE_LONG;
9309 goto done;
9310 }
9311 up(&priv->sem);
9312 return -EINVAL;
9313
9314 done:
9315 up(&priv->sem);
9316 return 0;
9317}
9318
9319static int ipw_wx_get_preamble(struct net_device *dev,
9320 struct iw_request_info *info,
9321 union iwreq_data *wrqu, char *extra)
9322{
9323 struct ipw_priv *priv = ieee80211_priv(dev);
9324 down(&priv->sem);
9325 if (priv->config & CFG_PREAMBLE_LONG)
9326 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9327 else
9328 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
9329 up(&priv->sem);
9330 return 0;
9331}
9332
9333#ifdef CONFIG_IPW2200_MONITOR
9334static int ipw_wx_set_monitor(struct net_device *dev,
9335 struct iw_request_info *info,
9336 union iwreq_data *wrqu, char *extra)
9337{
9338 struct ipw_priv *priv = ieee80211_priv(dev);
9339 int *parms = (int *)extra;
9340 int enable = (parms[0] > 0);
9341 down(&priv->sem);
9342 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
9343 if (enable) {
9344 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
24a47dbd
MK
9345#ifdef CONFIG_IEEE80211_RADIOTAP
9346 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
9347#else
b095c381 9348 priv->net_dev->type = ARPHRD_IEEE80211;
24a47dbd 9349#endif
b095c381
JK
9350 queue_work(priv->workqueue, &priv->adapter_restart);
9351 }
9352
9353 ipw_set_channel(priv, parms[1]);
9354 } else {
9355 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9356 up(&priv->sem);
9357 return 0;
9358 }
9359 priv->net_dev->type = ARPHRD_ETHER;
9360 queue_work(priv->workqueue, &priv->adapter_restart);
9361 }
9362 up(&priv->sem);
9363 return 0;
9364}
9365
9366#endif // CONFIG_IPW2200_MONITOR
9367
9368static int ipw_wx_reset(struct net_device *dev,
9369 struct iw_request_info *info,
9370 union iwreq_data *wrqu, char *extra)
9371{
9372 struct ipw_priv *priv = ieee80211_priv(dev);
9373 IPW_DEBUG_WX("RESET\n");
9374 queue_work(priv->workqueue, &priv->adapter_restart);
9375 return 0;
9376}
9377
b095c381
JK
9378static int ipw_wx_sw_reset(struct net_device *dev,
9379 struct iw_request_info *info,
9380 union iwreq_data *wrqu, char *extra)
ea2b26e0
JK
9381{
9382 struct ipw_priv *priv = ieee80211_priv(dev);
b095c381
JK
9383 union iwreq_data wrqu_sec = {
9384 .encoding = {
9385 .flags = IW_ENCODE_DISABLED,
9386 },
9387 };
afbf30a2 9388 int ret;
c848d0af 9389
b095c381 9390 IPW_DEBUG_WX("SW_RESET\n");
ea2b26e0 9391
b095c381 9392 down(&priv->sem);
ea2b26e0 9393
afbf30a2
JK
9394 ret = ipw_sw_reset(priv, 0);
9395 if (!ret) {
9396 free_firmware();
9397 ipw_adapter_restart(priv);
9398 }
ea2b26e0 9399
b095c381
JK
9400 /* The SW reset bit might have been toggled on by the 'disable'
9401 * module parameter, so take appropriate action */
9402 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
ea2b26e0 9403
b095c381
JK
9404 up(&priv->sem);
9405 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
c848d0af 9406 down(&priv->sem);
bf79451e 9407
b095c381
JK
9408 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9409 /* Configuration likely changed -- force [re]association */
9410 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
9411 "reset.\n");
9412 if (!ipw_disassociate(priv))
9413 ipw_associate(priv);
43f66a6c 9414 }
b095c381 9415
c848d0af 9416 up(&priv->sem);
43f66a6c 9417
43f66a6c
JK
9418 return 0;
9419}
43f66a6c
JK
9420
9421/* Rebase the WE IOCTLs to zero for the handler array */
9422#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
0edd5b44 9423static iw_handler ipw_wx_handlers[] = {
ea2b26e0
JK
9424 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
9425 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
9426 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
9427 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
9428 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
9429 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
9430 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
9431 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
9432 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
9433 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
9434 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
9435 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
9436 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
9437 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
9438 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
9439 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
9440 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
9441 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
9442 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
9443 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
9444 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
9445 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
9446 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
9447 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
9448 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
9449 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
9450 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
9451 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
a613bffd
JK
9452 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
9453 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
9454 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
9455 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
afbf30a2
JK
9456 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
9457 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
9458 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
9459 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
9460 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
9461 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
9462 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
43f66a6c
JK
9463};
9464
b095c381
JK
9465enum {
9466 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
9467 IPW_PRIV_GET_POWER,
9468 IPW_PRIV_SET_MODE,
9469 IPW_PRIV_GET_MODE,
9470 IPW_PRIV_SET_PREAMBLE,
9471 IPW_PRIV_GET_PREAMBLE,
9472 IPW_PRIV_RESET,
9473 IPW_PRIV_SW_RESET,
9474#ifdef CONFIG_IPW2200_MONITOR
9475 IPW_PRIV_SET_MONITOR,
9476#endif
9477};
43f66a6c 9478
bf79451e 9479static struct iw_priv_args ipw_priv_args[] = {
43f66a6c 9480 {
0edd5b44
JG
9481 .cmd = IPW_PRIV_SET_POWER,
9482 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9483 .name = "set_power"},
43f66a6c 9484 {
0edd5b44
JG
9485 .cmd = IPW_PRIV_GET_POWER,
9486 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
9487 .name = "get_power"},
43f66a6c 9488 {
0edd5b44
JG
9489 .cmd = IPW_PRIV_SET_MODE,
9490 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9491 .name = "set_mode"},
43f66a6c 9492 {
0edd5b44
JG
9493 .cmd = IPW_PRIV_GET_MODE,
9494 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
9495 .name = "get_mode"},
43f66a6c 9496 {
ea2b26e0
JK
9497 .cmd = IPW_PRIV_SET_PREAMBLE,
9498 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9499 .name = "set_preamble"},
9500 {
9501 .cmd = IPW_PRIV_GET_PREAMBLE,
9502 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
9503 .name = "get_preamble"},
43f66a6c 9504 {
0edd5b44
JG
9505 IPW_PRIV_RESET,
9506 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
b095c381
JK
9507 {
9508 IPW_PRIV_SW_RESET,
9509 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
9510#ifdef CONFIG_IPW2200_MONITOR
9511 {
9512 IPW_PRIV_SET_MONITOR,
9513 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
9514#endif /* CONFIG_IPW2200_MONITOR */
43f66a6c
JK
9515};
9516
9517static iw_handler ipw_priv_handler[] = {
9518 ipw_wx_set_powermode,
9519 ipw_wx_get_powermode,
9520 ipw_wx_set_wireless_mode,
9521 ipw_wx_get_wireless_mode,
ea2b26e0
JK
9522 ipw_wx_set_preamble,
9523 ipw_wx_get_preamble,
bf79451e 9524 ipw_wx_reset,
b095c381
JK
9525 ipw_wx_sw_reset,
9526#ifdef CONFIG_IPW2200_MONITOR
9527 ipw_wx_set_monitor,
43f66a6c
JK
9528#endif
9529};
9530
0edd5b44 9531static struct iw_handler_def ipw_wx_handler_def = {
ea2b26e0
JK
9532 .standard = ipw_wx_handlers,
9533 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
9534 .num_private = ARRAY_SIZE(ipw_priv_handler),
9535 .num_private_args = ARRAY_SIZE(ipw_priv_args),
9536 .private = ipw_priv_handler,
9537 .private_args = ipw_priv_args,
97a78ca9 9538 .get_wireless_stats = ipw_get_wireless_stats,
43f66a6c
JK
9539};
9540
43f66a6c
JK
9541/*
9542 * Get wireless statistics.
9543 * Called by /proc/net/wireless
9544 * Also called by SIOCGIWSTATS
9545 */
0edd5b44 9546static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
43f66a6c
JK
9547{
9548 struct ipw_priv *priv = ieee80211_priv(dev);
9549 struct iw_statistics *wstats;
bf79451e 9550
43f66a6c
JK
9551 wstats = &priv->wstats;
9552
ea2b26e0 9553 /* if hw is disabled, then ipw_get_ordinal() can't be called.
afbf30a2 9554 * netdev->get_wireless_stats seems to be called before fw is
43f66a6c
JK
9555 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
9556 * and associated; if not associcated, the values are all meaningless
9557 * anyway, so set them all to NULL and INVALID */
9558 if (!(priv->status & STATUS_ASSOCIATED)) {
9559 wstats->miss.beacon = 0;
9560 wstats->discard.retries = 0;
9561 wstats->qual.qual = 0;
9562 wstats->qual.level = 0;
9563 wstats->qual.noise = 0;
9564 wstats->qual.updated = 7;
9565 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
0edd5b44 9566 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
43f66a6c 9567 return wstats;
bf79451e 9568 }
43f66a6c
JK
9569
9570 wstats->qual.qual = priv->quality;
9571 wstats->qual.level = average_value(&priv->average_rssi);
9572 wstats->qual.noise = average_value(&priv->average_noise);
9573 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
0edd5b44 9574 IW_QUAL_NOISE_UPDATED;
43f66a6c
JK
9575
9576 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
9577 wstats->discard.retries = priv->last_tx_failures;
9578 wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable;
bf79451e 9579
43f66a6c
JK
9580/* if (ipw_get_ordinal(priv, IPW_ORD_STAT_TX_RETRY, &tx_retry, &len))
9581 goto fail_get_ordinal;
9582 wstats->discard.retries += tx_retry; */
bf79451e 9583
43f66a6c
JK
9584 return wstats;
9585}
9586
43f66a6c
JK
9587/* net device stuff */
9588
9589static inline void init_sys_config(struct ipw_sys_config *sys_config)
9590{
0edd5b44
JG
9591 memset(sys_config, 0, sizeof(struct ipw_sys_config));
9592 sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */
43f66a6c
JK
9593 sys_config->answer_broadcast_ssid_probe = 0;
9594 sys_config->accept_all_data_frames = 0;
9595 sys_config->accept_non_directed_frames = 1;
9596 sys_config->exclude_unicast_unencrypted = 0;
9597 sys_config->disable_unicast_decryption = 1;
9598 sys_config->exclude_multicast_unencrypted = 0;
9599 sys_config->disable_multicast_decryption = 1;
9600 sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH;
0edd5b44 9601 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */
43f66a6c 9602 sys_config->dot11g_auto_detection = 0;
bf79451e 9603 sys_config->enable_cts_to_self = 0;
43f66a6c 9604 sys_config->bt_coexist_collision_thr = 0;
c848d0af 9605 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
43f66a6c
JK
9606}
9607
9608static int ipw_net_open(struct net_device *dev)
9609{
9610 struct ipw_priv *priv = ieee80211_priv(dev);
9611 IPW_DEBUG_INFO("dev->open\n");
9612 /* we should be verifying the device is ready to be opened */
c848d0af 9613 down(&priv->sem);
bf79451e
JG
9614 if (!(priv->status & STATUS_RF_KILL_MASK) &&
9615 (priv->status & STATUS_ASSOCIATED))
43f66a6c 9616 netif_start_queue(dev);
c848d0af 9617 up(&priv->sem);
43f66a6c
JK
9618 return 0;
9619}
9620
9621static int ipw_net_stop(struct net_device *dev)
9622{
9623 IPW_DEBUG_INFO("dev->close\n");
9624 netif_stop_queue(dev);
9625 return 0;
9626}
9627
9628/*
9629todo:
9630
9631modify to send one tfd per fragment instead of using chunking. otherwise
9632we need to heavily modify the ieee80211_skb_to_txb.
9633*/
9634
227d2dc1
JK
9635static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9636 int pri)
43f66a6c 9637{
0dacca1f 9638 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
0edd5b44 9639 txb->fragments[0]->data;
43f66a6c
JK
9640 int i = 0;
9641 struct tfd_frame *tfd;
b095c381
JK
9642#ifdef CONFIG_IPW_QOS
9643 int tx_id = ipw_get_tx_queue_number(priv, pri);
9644 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9645#else
43f66a6c 9646 struct clx2_tx_queue *txq = &priv->txq[0];
b095c381 9647#endif
43f66a6c
JK
9648 struct clx2_queue *q = &txq->q;
9649 u8 id, hdr_len, unicast;
9650 u16 remaining_bytes;
c848d0af 9651 int fc;
43f66a6c 9652
227d2dc1
JK
9653 /* If there isn't room in the queue, we return busy and let the
9654 * network stack requeue the packet for us */
9655 if (ipw_queue_space(q) < q->high_mark)
9656 return NETDEV_TX_BUSY;
9657
43f66a6c
JK
9658 switch (priv->ieee->iw_mode) {
9659 case IW_MODE_ADHOC:
9660 hdr_len = IEEE80211_3ADDR_LEN;
afbf30a2 9661 unicast = !is_multicast_ether_addr(hdr->addr1);
43f66a6c
JK
9662 id = ipw_find_station(priv, hdr->addr1);
9663 if (id == IPW_INVALID_STATION) {
9664 id = ipw_add_station(priv, hdr->addr1);
9665 if (id == IPW_INVALID_STATION) {
9666 IPW_WARNING("Attempt to send data to "
bf79451e 9667 "invalid cell: " MAC_FMT "\n",
43f66a6c
JK
9668 MAC_ARG(hdr->addr1));
9669 goto drop;
9670 }
9671 }
9672 break;
9673
9674 case IW_MODE_INFRA:
9675 default:
afbf30a2 9676 unicast = !is_multicast_ether_addr(hdr->addr3);
43f66a6c
JK
9677 hdr_len = IEEE80211_3ADDR_LEN;
9678 id = 0;
9679 break;
9680 }
9681
9682 tfd = &txq->bd[q->first_empty];
9683 txq->txb[q->first_empty] = txb;
9684 memset(tfd, 0, sizeof(*tfd));
9685 tfd->u.data.station_number = id;
9686
9687 tfd->control_flags.message_type = TX_FRAME_TYPE;
9688 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
9689
9690 tfd->u.data.cmd_id = DINO_CMD_TX;
a613bffd 9691 tfd->u.data.len = cpu_to_le16(txb->payload_size);
43f66a6c 9692 remaining_bytes = txb->payload_size;
bf79451e 9693
43f66a6c 9694 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
b095c381 9695 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
43f66a6c 9696 else
b095c381 9697 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
43f66a6c 9698
ea2b26e0
JK
9699 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
9700 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
43f66a6c 9701
c848d0af
JK
9702 fc = le16_to_cpu(hdr->frame_ctl);
9703 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
9704
43f66a6c
JK
9705 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
9706
b095c381
JK
9707 if (likely(unicast))
9708 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9709
9710 if (txb->encrypted && !priv->ieee->host_encrypt) {
9711 switch (priv->ieee->sec.level) {
9712 case SEC_LEVEL_3:
9713 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9714 IEEE80211_FCTL_PROTECTED;
9715 /* XXX: ACK flag must be set for CCMP even if it
9716 * is a multicast/broadcast packet, because CCMP
9717 * group communication encrypted by GTK is
9718 * actually done by the AP. */
9719 if (!unicast)
9720 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9721
9722 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9723 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
9724 tfd->u.data.key_index = 0;
9725 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
9726 break;
9727 case SEC_LEVEL_2:
9728 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9729 IEEE80211_FCTL_PROTECTED;
9730 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9731 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
9732 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
9733 break;
9734 case SEC_LEVEL_1:
9735 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9736 IEEE80211_FCTL_PROTECTED;
9737 tfd->u.data.key_index = priv->ieee->tx_keyidx;
9738 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
9739 40)
9740 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
9741 else
9742 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
9743 break;
9744 case SEC_LEVEL_0:
9745 break;
9746 default:
9747 printk(KERN_ERR "Unknow security level %d\n",
9748 priv->ieee->sec.level);
9749 break;
9750 }
9751 } else
9752 /* No hardware encryption */
9753 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
9754
9755#ifdef CONFIG_IPW_QOS
9756 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast);
9757#endif /* CONFIG_IPW_QOS */
9758
43f66a6c 9759 /* payload */
a613bffd
JK
9760 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
9761 txb->nr_frags));
9762 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
9763 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
9764 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
9765 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
9766 i, le32_to_cpu(tfd->u.data.num_chunks),
9767 txb->fragments[i]->len - hdr_len);
bf79451e 9768 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
43f66a6c
JK
9769 i, tfd->u.data.num_chunks,
9770 txb->fragments[i]->len - hdr_len);
bf79451e 9771 printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len,
43f66a6c
JK
9772 txb->fragments[i]->len - hdr_len);
9773
0edd5b44 9774 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
9775 cpu_to_le32(pci_map_single
9776 (priv->pci_dev,
9777 txb->fragments[i]->data + hdr_len,
9778 txb->fragments[i]->len - hdr_len,
9779 PCI_DMA_TODEVICE));
9780 tfd->u.data.chunk_len[i] =
9781 cpu_to_le16(txb->fragments[i]->len - hdr_len);
43f66a6c
JK
9782 }
9783
9784 if (i != txb->nr_frags) {
9785 struct sk_buff *skb;
9786 u16 remaining_bytes = 0;
9787 int j;
9788
9789 for (j = i; j < txb->nr_frags; j++)
9790 remaining_bytes += txb->fragments[j]->len - hdr_len;
9791
9792 printk(KERN_INFO "Trying to reallocate for %d bytes\n",
9793 remaining_bytes);
9794 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
9795 if (skb != NULL) {
a613bffd 9796 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
43f66a6c
JK
9797 for (j = i; j < txb->nr_frags; j++) {
9798 int size = txb->fragments[j]->len - hdr_len;
afbf30a2 9799
43f66a6c 9800 printk(KERN_INFO "Adding frag %d %d...\n",
0edd5b44 9801 j, size);
43f66a6c 9802 memcpy(skb_put(skb, size),
0edd5b44 9803 txb->fragments[j]->data + hdr_len, size);
43f66a6c
JK
9804 }
9805 dev_kfree_skb_any(txb->fragments[i]);
9806 txb->fragments[i] = skb;
0edd5b44 9807 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
9808 cpu_to_le32(pci_map_single
9809 (priv->pci_dev, skb->data,
9810 tfd->u.data.chunk_len[i],
9811 PCI_DMA_TODEVICE));
9812
9813 tfd->u.data.num_chunks =
9814 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
9815 1);
bf79451e 9816 }
43f66a6c
JK
9817 }
9818
9819 /* kick DMA */
9820 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
9821 ipw_write32(priv, q->reg_w, q->first_empty);
9822
227d2dc1 9823 return NETDEV_TX_OK;
43f66a6c 9824
0edd5b44 9825 drop:
43f66a6c
JK
9826 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
9827 ieee80211_txb_free(txb);
227d2dc1
JK
9828 return NETDEV_TX_OK;
9829}
9830
9831static int ipw_net_is_queue_full(struct net_device *dev, int pri)
9832{
9833 struct ipw_priv *priv = ieee80211_priv(dev);
9834#ifdef CONFIG_IPW_QOS
9835 int tx_id = ipw_get_tx_queue_number(priv, pri);
9836 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9837#else
9838 struct clx2_tx_queue *txq = &priv->txq[0];
9839#endif /* CONFIG_IPW_QOS */
9840
9841 if (ipw_queue_space(&txq->q) < txq->q.high_mark)
9842 return 1;
9843
9844 return 0;
43f66a6c
JK
9845}
9846
9847static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
c8d42d1a 9848 struct net_device *dev, int pri)
43f66a6c
JK
9849{
9850 struct ipw_priv *priv = ieee80211_priv(dev);
9851 unsigned long flags;
227d2dc1 9852 int ret;
43f66a6c
JK
9853
9854 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
43f66a6c
JK
9855 spin_lock_irqsave(&priv->lock, flags);
9856
9857 if (!(priv->status & STATUS_ASSOCIATED)) {
9858 IPW_DEBUG_INFO("Tx attempt while not associated.\n");
9859 priv->ieee->stats.tx_carrier_errors++;
9860 netif_stop_queue(dev);
9861 goto fail_unlock;
9862 }
9863
227d2dc1
JK
9864 ret = ipw_tx_skb(priv, txb, pri);
9865 if (ret == NETDEV_TX_OK)
9866 __ipw_led_activity_on(priv);
c848d0af 9867 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 9868
227d2dc1 9869 return ret;
43f66a6c 9870
0edd5b44 9871 fail_unlock:
43f66a6c
JK
9872 spin_unlock_irqrestore(&priv->lock, flags);
9873 return 1;
9874}
9875
9876static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
9877{
9878 struct ipw_priv *priv = ieee80211_priv(dev);
bf79451e 9879
43f66a6c
JK
9880 priv->ieee->stats.tx_packets = priv->tx_packets;
9881 priv->ieee->stats.rx_packets = priv->rx_packets;
9882 return &priv->ieee->stats;
9883}
9884
9885static void ipw_net_set_multicast_list(struct net_device *dev)
9886{
9887
9888}
9889
9890static int ipw_net_set_mac_address(struct net_device *dev, void *p)
9891{
9892 struct ipw_priv *priv = ieee80211_priv(dev);
9893 struct sockaddr *addr = p;
9894 if (!is_valid_ether_addr(addr->sa_data))
9895 return -EADDRNOTAVAIL;
c848d0af 9896 down(&priv->sem);
43f66a6c
JK
9897 priv->config |= CFG_CUSTOM_MAC;
9898 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
9899 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
9900 priv->net_dev->name, MAC_ARG(priv->mac_addr));
a613bffd 9901 queue_work(priv->workqueue, &priv->adapter_restart);
c848d0af 9902 up(&priv->sem);
43f66a6c
JK
9903 return 0;
9904}
9905
bf79451e 9906static void ipw_ethtool_get_drvinfo(struct net_device *dev,
43f66a6c
JK
9907 struct ethtool_drvinfo *info)
9908{
9909 struct ipw_priv *p = ieee80211_priv(dev);
9910 char vers[64];
9911 char date[32];
9912 u32 len;
9913
9914 strcpy(info->driver, DRV_NAME);
9915 strcpy(info->version, DRV_VERSION);
9916
9917 len = sizeof(vers);
9918 ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
9919 len = sizeof(date);
9920 ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len);
9921
0edd5b44 9922 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
43f66a6c
JK
9923 vers, date);
9924 strcpy(info->bus_info, pci_name(p->pci_dev));
b095c381 9925 info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
43f66a6c
JK
9926}
9927
9928static u32 ipw_ethtool_get_link(struct net_device *dev)
9929{
9930 struct ipw_priv *priv = ieee80211_priv(dev);
9931 return (priv->status & STATUS_ASSOCIATED) != 0;
9932}
9933
9934static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
9935{
b095c381 9936 return IPW_EEPROM_IMAGE_SIZE;
43f66a6c
JK
9937}
9938
9939static int ipw_ethtool_get_eeprom(struct net_device *dev,
0edd5b44 9940 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c
JK
9941{
9942 struct ipw_priv *p = ieee80211_priv(dev);
9943
b095c381 9944 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
43f66a6c 9945 return -EINVAL;
c848d0af 9946 down(&p->sem);
afbf30a2 9947 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
c848d0af 9948 up(&p->sem);
43f66a6c
JK
9949 return 0;
9950}
9951
9952static int ipw_ethtool_set_eeprom(struct net_device *dev,
0edd5b44 9953 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c
JK
9954{
9955 struct ipw_priv *p = ieee80211_priv(dev);
9956 int i;
9957
b095c381 9958 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
43f66a6c 9959 return -EINVAL;
c848d0af 9960 down(&p->sem);
afbf30a2 9961 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
bf79451e 9962 for (i = IPW_EEPROM_DATA;
b095c381 9963 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
43f66a6c 9964 ipw_write8(p, i, p->eeprom[i]);
c848d0af 9965 up(&p->sem);
43f66a6c
JK
9966 return 0;
9967}
9968
9969static struct ethtool_ops ipw_ethtool_ops = {
ea2b26e0
JK
9970 .get_link = ipw_ethtool_get_link,
9971 .get_drvinfo = ipw_ethtool_get_drvinfo,
9972 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
9973 .get_eeprom = ipw_ethtool_get_eeprom,
9974 .set_eeprom = ipw_ethtool_set_eeprom,
43f66a6c
JK
9975};
9976
9977static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
9978{
9979 struct ipw_priv *priv = data;
9980 u32 inta, inta_mask;
bf79451e 9981
43f66a6c
JK
9982 if (!priv)
9983 return IRQ_NONE;
9984
9985 spin_lock(&priv->lock);
9986
9987 if (!(priv->status & STATUS_INT_ENABLED)) {
9988 /* Shared IRQ */
9989 goto none;
9990 }
9991
b095c381
JK
9992 inta = ipw_read32(priv, IPW_INTA_RW);
9993 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
bf79451e 9994
43f66a6c
JK
9995 if (inta == 0xFFFFFFFF) {
9996 /* Hardware disappeared */
9997 IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n");
9998 goto none;
9999 }
10000
b095c381 10001 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
43f66a6c
JK
10002 /* Shared interrupt */
10003 goto none;
10004 }
10005
10006 /* tell the device to stop sending interrupts */
10007 ipw_disable_interrupts(priv);
bf79451e 10008
43f66a6c 10009 /* ack current interrupts */
b095c381
JK
10010 inta &= (IPW_INTA_MASK_ALL & inta_mask);
10011 ipw_write32(priv, IPW_INTA_RW, inta);
bf79451e 10012
43f66a6c
JK
10013 /* Cache INTA value for our tasklet */
10014 priv->isr_inta = inta;
10015
10016 tasklet_schedule(&priv->irq_tasklet);
10017
0edd5b44 10018 spin_unlock(&priv->lock);
43f66a6c
JK
10019
10020 return IRQ_HANDLED;
0edd5b44 10021 none:
43f66a6c
JK
10022 spin_unlock(&priv->lock);
10023 return IRQ_NONE;
10024}
10025
10026static void ipw_rf_kill(void *adapter)
10027{
10028 struct ipw_priv *priv = adapter;
10029 unsigned long flags;
bf79451e 10030
43f66a6c
JK
10031 spin_lock_irqsave(&priv->lock, flags);
10032
10033 if (rf_kill_active(priv)) {
10034 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
10035 if (priv->workqueue)
10036 queue_delayed_work(priv->workqueue,
10037 &priv->rf_kill, 2 * HZ);
10038 goto exit_unlock;
10039 }
10040
10041 /* RF Kill is now disabled, so bring the device back up */
10042
10043 if (!(priv->status & STATUS_RF_KILL_MASK)) {
10044 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
10045 "device\n");
10046
10047 /* we can not do an adapter restart while inside an irq lock */
10048 queue_work(priv->workqueue, &priv->adapter_restart);
bf79451e 10049 } else
43f66a6c
JK
10050 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
10051 "enabled\n");
10052
0edd5b44 10053 exit_unlock:
43f66a6c
JK
10054 spin_unlock_irqrestore(&priv->lock, flags);
10055}
10056
c848d0af
JK
10057static void ipw_bg_rf_kill(void *data)
10058{
10059 struct ipw_priv *priv = data;
10060 down(&priv->sem);
10061 ipw_rf_kill(data);
10062 up(&priv->sem);
10063}
10064
a613bffd
JK
10065void ipw_link_up(struct ipw_priv *priv)
10066{
afbf30a2
JK
10067 priv->last_seq_num = -1;
10068 priv->last_frag_num = -1;
10069 priv->last_packet_time = 0;
10070
a613bffd
JK
10071 netif_carrier_on(priv->net_dev);
10072 if (netif_queue_stopped(priv->net_dev)) {
10073 IPW_DEBUG_NOTIF("waking queue\n");
10074 netif_wake_queue(priv->net_dev);
10075 } else {
10076 IPW_DEBUG_NOTIF("starting queue\n");
10077 netif_start_queue(priv->net_dev);
10078 }
10079
c848d0af 10080 cancel_delayed_work(&priv->request_scan);
a613bffd
JK
10081 ipw_reset_stats(priv);
10082 /* Ensure the rate is updated immediately */
10083 priv->last_rate = ipw_get_current_rate(priv);
10084 ipw_gather_stats(priv);
10085 ipw_led_link_up(priv);
10086 notify_wx_assoc_event(priv);
10087
10088 if (priv->config & CFG_BACKGROUND_SCAN)
10089 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
10090}
10091
c848d0af
JK
10092static void ipw_bg_link_up(void *data)
10093{
10094 struct ipw_priv *priv = data;
10095 down(&priv->sem);
10096 ipw_link_up(data);
10097 up(&priv->sem);
10098}
10099
a613bffd
JK
10100void ipw_link_down(struct ipw_priv *priv)
10101{
10102 ipw_led_link_down(priv);
10103 netif_carrier_off(priv->net_dev);
10104 netif_stop_queue(priv->net_dev);
10105 notify_wx_assoc_event(priv);
10106
10107 /* Cancel any queued work ... */
10108 cancel_delayed_work(&priv->request_scan);
10109 cancel_delayed_work(&priv->adhoc_check);
10110 cancel_delayed_work(&priv->gather_stats);
10111
10112 ipw_reset_stats(priv);
10113
afbf30a2
JK
10114 if (!(priv->status & STATUS_EXIT_PENDING)) {
10115 /* Queue up another scan... */
10116 queue_work(priv->workqueue, &priv->request_scan);
10117 }
a613bffd
JK
10118}
10119
c848d0af
JK
10120static void ipw_bg_link_down(void *data)
10121{
10122 struct ipw_priv *priv = data;
10123 down(&priv->sem);
10124 ipw_link_down(data);
10125 up(&priv->sem);
10126}
10127
43f66a6c
JK
10128static int ipw_setup_deferred_work(struct ipw_priv *priv)
10129{
10130 int ret = 0;
10131
43f66a6c 10132 priv->workqueue = create_workqueue(DRV_NAME);
43f66a6c 10133 init_waitqueue_head(&priv->wait_command_queue);
afbf30a2 10134 init_waitqueue_head(&priv->wait_state);
43f66a6c 10135
c848d0af
JK
10136 INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
10137 INIT_WORK(&priv->associate, ipw_bg_associate, priv);
10138 INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
d8bad6df 10139 INIT_WORK(&priv->system_config, ipw_system_config, priv);
c848d0af
JK
10140 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
10141 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
10142 INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
10143 INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
10144 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
bf79451e 10145 INIT_WORK(&priv->request_scan,
b095c381 10146 (void (*)(void *))ipw_request_scan, priv);
bf79451e 10147 INIT_WORK(&priv->gather_stats,
c848d0af
JK
10148 (void (*)(void *))ipw_bg_gather_stats, priv);
10149 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
10150 INIT_WORK(&priv->roam, ipw_bg_roam, priv);
10151 INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
10152 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
10153 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
10154 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
10155 priv);
10156 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
a613bffd 10157 priv);
c848d0af 10158 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
a613bffd 10159 priv);
c848d0af
JK
10160 INIT_WORK(&priv->merge_networks,
10161 (void (*)(void *))ipw_merge_adhoc_network, priv);
43f66a6c 10162
b095c381
JK
10163#ifdef CONFIG_IPW_QOS
10164 INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
10165 priv);
10166#endif /* CONFIG_IPW_QOS */
10167
43f66a6c
JK
10168 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
10169 ipw_irq_tasklet, (unsigned long)priv);
10170
10171 return ret;
10172}
10173
43f66a6c
JK
10174static void shim__set_security(struct net_device *dev,
10175 struct ieee80211_security *sec)
10176{
10177 struct ipw_priv *priv = ieee80211_priv(dev);
10178 int i;
bf79451e 10179 for (i = 0; i < 4; i++) {
43f66a6c 10180 if (sec->flags & (1 << i)) {
afbf30a2 10181 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
b095c381 10182 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
43f66a6c 10183 if (sec->key_sizes[i] == 0)
b095c381
JK
10184 priv->ieee->sec.flags &= ~(1 << i);
10185 else {
10186 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
43f66a6c 10187 sec->key_sizes[i]);
b095c381
JK
10188 priv->ieee->sec.flags |= (1 << i);
10189 }
43f66a6c 10190 priv->status |= STATUS_SECURITY_UPDATED;
b095c381
JK
10191 } else if (sec->level != SEC_LEVEL_1)
10192 priv->ieee->sec.flags &= ~(1 << i);
43f66a6c
JK
10193 }
10194
b095c381 10195 if (sec->flags & SEC_ACTIVE_KEY) {
43f66a6c 10196 if (sec->active_key <= 3) {
b095c381
JK
10197 priv->ieee->sec.active_key = sec->active_key;
10198 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
bf79451e 10199 } else
b095c381 10200 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
43f66a6c 10201 priv->status |= STATUS_SECURITY_UPDATED;
b095c381
JK
10202 } else
10203 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
43f66a6c
JK
10204
10205 if ((sec->flags & SEC_AUTH_MODE) &&
b095c381
JK
10206 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
10207 priv->ieee->sec.auth_mode = sec->auth_mode;
10208 priv->ieee->sec.flags |= SEC_AUTH_MODE;
43f66a6c
JK
10209 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
10210 priv->capability |= CAP_SHARED_KEY;
10211 else
10212 priv->capability &= ~CAP_SHARED_KEY;
10213 priv->status |= STATUS_SECURITY_UPDATED;
10214 }
bf79451e 10215
b095c381
JK
10216 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
10217 priv->ieee->sec.flags |= SEC_ENABLED;
10218 priv->ieee->sec.enabled = sec->enabled;
43f66a6c 10219 priv->status |= STATUS_SECURITY_UPDATED;
bf79451e 10220 if (sec->enabled)
43f66a6c
JK
10221 priv->capability |= CAP_PRIVACY_ON;
10222 else
10223 priv->capability &= ~CAP_PRIVACY_ON;
10224 }
afbf30a2
JK
10225
10226 if (sec->flags & SEC_ENCRYPT)
10227 priv->ieee->sec.encrypt = sec->encrypt;
bf79451e 10228
b095c381
JK
10229 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
10230 priv->ieee->sec.level = sec->level;
10231 priv->ieee->sec.flags |= SEC_LEVEL;
43f66a6c 10232 priv->status |= STATUS_SECURITY_UPDATED;
d8bad6df 10233 }
b095c381 10234
1fbfea54
ZY
10235 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
10236 ipw_set_hwcrypto_keys(priv);
10237
bf79451e
JG
10238 /* To match current functionality of ipw2100 (which works well w/
10239 * various supplicants, we don't force a disassociate if the
43f66a6c
JK
10240 * privacy capability changes ... */
10241#if 0
10242 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
bf79451e 10243 (((priv->assoc_request.capability &
43f66a6c 10244 WLAN_CAPABILITY_PRIVACY) && !sec->enabled) ||
bf79451e 10245 (!(priv->assoc_request.capability &
0edd5b44 10246 WLAN_CAPABILITY_PRIVACY) && sec->enabled))) {
43f66a6c
JK
10247 IPW_DEBUG_ASSOC("Disassociating due to capability "
10248 "change.\n");
10249 ipw_disassociate(priv);
10250 }
10251#endif
10252}
10253
bf79451e 10254static int init_supported_rates(struct ipw_priv *priv,
43f66a6c
JK
10255 struct ipw_supported_rates *rates)
10256{
10257 /* TODO: Mask out rates based on priv->rates_mask */
10258
10259 memset(rates, 0, sizeof(*rates));
0edd5b44 10260 /* configure supported rates */
43f66a6c
JK
10261 switch (priv->ieee->freq_band) {
10262 case IEEE80211_52GHZ_BAND:
10263 rates->ieee_mode = IPW_A_MODE;
10264 rates->purpose = IPW_RATE_CAPABILITIES;
10265 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
10266 IEEE80211_OFDM_DEFAULT_RATES_MASK);
10267 break;
10268
0edd5b44 10269 default: /* Mixed or 2.4Ghz */
43f66a6c
JK
10270 rates->ieee_mode = IPW_G_MODE;
10271 rates->purpose = IPW_RATE_CAPABILITIES;
10272 ipw_add_cck_scan_rates(rates, IEEE80211_CCK_MODULATION,
10273 IEEE80211_CCK_DEFAULT_RATES_MASK);
10274 if (priv->ieee->modulation & IEEE80211_OFDM_MODULATION) {
10275 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
10276 IEEE80211_OFDM_DEFAULT_RATES_MASK);
10277 }
10278 break;
10279 }
10280
10281 return 0;
10282}
10283
bf79451e 10284static int ipw_config(struct ipw_priv *priv)
43f66a6c 10285{
43f66a6c
JK
10286 /* This is only called from ipw_up, which resets/reloads the firmware
10287 so, we don't need to first disable the card before we configure
10288 it */
6de9f7f2 10289 if (ipw_set_tx_power(priv))
43f66a6c
JK
10290 goto error;
10291
10292 /* initialize adapter address */
10293 if (ipw_send_adapter_address(priv, priv->net_dev->dev_addr))
10294 goto error;
10295
10296 /* set basic system config settings */
10297 init_sys_config(&priv->sys_config);
c848d0af
JK
10298 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10299 priv->sys_config.answer_broadcast_ssid_probe = 1;
10300 else
10301 priv->sys_config.answer_broadcast_ssid_probe = 0;
10302
43f66a6c
JK
10303 if (ipw_send_system_config(priv, &priv->sys_config))
10304 goto error;
10305
0edd5b44
JG
10306 init_supported_rates(priv, &priv->rates);
10307 if (ipw_send_supported_rates(priv, &priv->rates))
43f66a6c
JK
10308 goto error;
10309
10310 /* Set request-to-send threshold */
10311 if (priv->rts_threshold) {
10312 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
10313 goto error;
10314 }
b095c381
JK
10315#ifdef CONFIG_IPW_QOS
10316 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
10317 ipw_qos_activate(priv, NULL);
10318#endif /* CONFIG_IPW_QOS */
43f66a6c
JK
10319
10320 if (ipw_set_random_seed(priv))
10321 goto error;
bf79451e 10322
43f66a6c
JK
10323 /* final state transition to the RUN state */
10324 if (ipw_send_host_complete(priv))
10325 goto error;
10326
e666619e
JK
10327 priv->status |= STATUS_INIT;
10328
10329 ipw_led_init(priv);
10330 ipw_led_radio_on(priv);
10331 priv->notif_missed_beacons = 0;
10332
10333 /* Set hardware WEP key if it is configured. */
10334 if ((priv->capability & CAP_PRIVACY_ON) &&
10335 (priv->ieee->sec.level == SEC_LEVEL_1) &&
10336 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
10337 ipw_set_hwcrypto_keys(priv);
43f66a6c
JK
10338
10339 return 0;
bf79451e 10340
0edd5b44 10341 error:
43f66a6c
JK
10342 return -EIO;
10343}
10344
4f36f808
JK
10345/*
10346 * NOTE:
10347 *
10348 * These tables have been tested in conjunction with the
10349 * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
10350 *
10351 * Altering this values, using it on other hardware, or in geographies
10352 * not intended for resale of the above mentioned Intel adapters has
10353 * not been tested.
10354 *
10355 */
10356static const struct ieee80211_geo ipw_geos[] = {
10357 { /* Restricted */
10358 "---",
10359 .bg_channels = 11,
10360 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10361 {2427, 4}, {2432, 5}, {2437, 6},
10362 {2442, 7}, {2447, 8}, {2452, 9},
10363 {2457, 10}, {2462, 11}},
10364 },
10365
10366 { /* Custom US/Canada */
10367 "ZZF",
10368 .bg_channels = 11,
10369 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10370 {2427, 4}, {2432, 5}, {2437, 6},
10371 {2442, 7}, {2447, 8}, {2452, 9},
10372 {2457, 10}, {2462, 11}},
10373 .a_channels = 8,
10374 .a = {{5180, 36},
10375 {5200, 40},
10376 {5220, 44},
10377 {5240, 48},
10378 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10379 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10380 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10381 {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
10382 },
10383
10384 { /* Rest of World */
10385 "ZZD",
10386 .bg_channels = 13,
10387 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10388 {2427, 4}, {2432, 5}, {2437, 6},
10389 {2442, 7}, {2447, 8}, {2452, 9},
10390 {2457, 10}, {2462, 11}, {2467, 12},
10391 {2472, 13}},
10392 },
10393
10394 { /* Custom USA & Europe & High */
10395 "ZZA",
10396 .bg_channels = 11,
10397 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10398 {2427, 4}, {2432, 5}, {2437, 6},
10399 {2442, 7}, {2447, 8}, {2452, 9},
10400 {2457, 10}, {2462, 11}},
10401 .a_channels = 13,
10402 .a = {{5180, 36},
10403 {5200, 40},
10404 {5220, 44},
10405 {5240, 48},
10406 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10407 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10408 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10409 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10410 {5745, 149},
10411 {5765, 153},
10412 {5785, 157},
10413 {5805, 161},
10414 {5825, 165}},
10415 },
10416
10417 { /* Custom NA & Europe */
10418 "ZZB",
10419 .bg_channels = 11,
10420 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10421 {2427, 4}, {2432, 5}, {2437, 6},
10422 {2442, 7}, {2447, 8}, {2452, 9},
10423 {2457, 10}, {2462, 11}},
10424 .a_channels = 13,
10425 .a = {{5180, 36},
10426 {5200, 40},
10427 {5220, 44},
10428 {5240, 48},
10429 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10430 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10431 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10432 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10433 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10434 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10435 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10436 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10437 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10438 },
10439
10440 { /* Custom Japan */
10441 "ZZC",
10442 .bg_channels = 11,
10443 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10444 {2427, 4}, {2432, 5}, {2437, 6},
10445 {2442, 7}, {2447, 8}, {2452, 9},
10446 {2457, 10}, {2462, 11}},
10447 .a_channels = 4,
10448 .a = {{5170, 34}, {5190, 38},
10449 {5210, 42}, {5230, 46}},
10450 },
10451
10452 { /* Custom */
10453 "ZZM",
10454 .bg_channels = 11,
10455 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10456 {2427, 4}, {2432, 5}, {2437, 6},
10457 {2442, 7}, {2447, 8}, {2452, 9},
10458 {2457, 10}, {2462, 11}},
10459 },
10460
10461 { /* Europe */
10462 "ZZE",
10463 .bg_channels = 13,
10464 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10465 {2427, 4}, {2432, 5}, {2437, 6},
10466 {2442, 7}, {2447, 8}, {2452, 9},
10467 {2457, 10}, {2462, 11}, {2467, 12},
10468 {2472, 13}},
10469 .a_channels = 19,
10470 .a = {{5180, 36},
10471 {5200, 40},
10472 {5220, 44},
10473 {5240, 48},
10474 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10475 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10476 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10477 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10478 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10479 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10480 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10481 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10482 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10483 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10484 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10485 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10486 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10487 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10488 {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
10489 },
10490
10491 { /* Custom Japan */
10492 "ZZJ",
10493 .bg_channels = 14,
10494 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10495 {2427, 4}, {2432, 5}, {2437, 6},
10496 {2442, 7}, {2447, 8}, {2452, 9},
10497 {2457, 10}, {2462, 11}, {2467, 12},
10498 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
10499 .a_channels = 4,
10500 .a = {{5170, 34}, {5190, 38},
10501 {5210, 42}, {5230, 46}},
10502 },
10503
10504 { /* High Band */
10505 "ZZH",
10506 .bg_channels = 13,
10507 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10508 {2427, 4}, {2432, 5}, {2437, 6},
10509 {2442, 7}, {2447, 8}, {2452, 9},
10510 {2457, 10}, {2462, 11},
10511 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10512 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10513 .a_channels = 4,
10514 .a = {{5745, 149}, {5765, 153},
10515 {5785, 157}, {5805, 161}},
10516 },
10517
10518 { /* Custom Europe */
10519 "ZZG",
10520 .bg_channels = 13,
10521 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10522 {2427, 4}, {2432, 5}, {2437, 6},
10523 {2442, 7}, {2447, 8}, {2452, 9},
10524 {2457, 10}, {2462, 11},
10525 {2467, 12}, {2472, 13}},
10526 .a_channels = 4,
10527 .a = {{5180, 36}, {5200, 40},
10528 {5220, 44}, {5240, 48}},
10529 },
10530
10531 { /* Europe */
10532 "ZZK",
10533 .bg_channels = 13,
10534 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10535 {2427, 4}, {2432, 5}, {2437, 6},
10536 {2442, 7}, {2447, 8}, {2452, 9},
10537 {2457, 10}, {2462, 11},
10538 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10539 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10540 .a_channels = 24,
10541 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10542 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10543 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10544 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10545 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10546 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10547 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10548 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10549 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10550 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10551 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10552 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10553 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10554 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10555 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10556 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10557 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10558 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10559 {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
10560 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10561 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10562 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10563 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10564 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10565 },
10566
10567 { /* Europe */
10568 "ZZL",
10569 .bg_channels = 11,
10570 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10571 {2427, 4}, {2432, 5}, {2437, 6},
10572 {2442, 7}, {2447, 8}, {2452, 9},
10573 {2457, 10}, {2462, 11}},
10574 .a_channels = 13,
10575 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10576 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10577 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10578 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10579 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10580 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10581 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10582 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10583 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10584 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10585 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10586 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10587 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10588 }
afbf30a2
JK
10589};
10590
1fe0adb4
LH
10591/* GEO code borrowed from ieee80211_geo.c */
10592static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
10593{
10594 int i;
10595
10596 /* Driver needs to initialize the geography map before using
10597 * these helper functions */
10598 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10599
10600 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10601 for (i = 0; i < ieee->geo.bg_channels; i++)
10602 /* NOTE: If G mode is currently supported but
10603 * this is a B only channel, we don't see it
10604 * as valid. */
10605 if ((ieee->geo.bg[i].channel == channel) &&
10606 (!(ieee->mode & IEEE_G) ||
10607 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
10608 return IEEE80211_24GHZ_BAND;
10609
10610 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10611 for (i = 0; i < ieee->geo.a_channels; i++)
10612 if (ieee->geo.a[i].channel == channel)
10613 return IEEE80211_52GHZ_BAND;
10614
10615 return 0;
10616}
10617
10618static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
10619{
10620 int i;
10621
10622 /* Driver needs to initialize the geography map before using
10623 * these helper functions */
10624 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10625
10626 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10627 for (i = 0; i < ieee->geo.bg_channels; i++)
10628 if (ieee->geo.bg[i].channel == channel)
10629 return i;
10630
10631 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10632 for (i = 0; i < ieee->geo.a_channels; i++)
10633 if (ieee->geo.a[i].channel == channel)
10634 return i;
10635
10636 return -1;
10637}
10638
10639static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
10640{
10641 int i;
10642
10643 /* Driver needs to initialize the geography map before using
10644 * these helper functions */
10645 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10646
10647 freq /= 100000;
10648
10649 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10650 for (i = 0; i < ieee->geo.bg_channels; i++)
10651 if (ieee->geo.bg[i].freq == freq)
10652 return ieee->geo.bg[i].channel;
10653
10654 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10655 for (i = 0; i < ieee->geo.a_channels; i++)
10656 if (ieee->geo.a[i].freq == freq)
10657 return ieee->geo.a[i].channel;
10658
10659 return 0;
10660}
10661
10662static int ipw_set_geo(struct ieee80211_device *ieee,
10663 const struct ieee80211_geo *geo)
10664{
10665 memcpy(ieee->geo.name, geo->name, 3);
10666 ieee->geo.name[3] = '\0';
10667 ieee->geo.bg_channels = geo->bg_channels;
10668 ieee->geo.a_channels = geo->a_channels;
10669 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
10670 sizeof(struct ieee80211_channel));
10671 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
10672 sizeof(struct ieee80211_channel));
10673 return 0;
10674}
10675
10676static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
10677{
10678 return &ieee->geo;
10679}
10680
43f66a6c
JK
10681#define MAX_HW_RESTARTS 5
10682static int ipw_up(struct ipw_priv *priv)
10683{
4f36f808 10684 int rc, i, j;
43f66a6c
JK
10685
10686 if (priv->status & STATUS_EXIT_PENDING)
10687 return -EIO;
10688
f6c5cb7c
JK
10689 if (cmdlog && !priv->cmdlog) {
10690 priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
10691 GFP_KERNEL);
10692 if (priv->cmdlog == NULL) {
10693 IPW_ERROR("Error allocating %d command log entries.\n",
10694 cmdlog);
10695 } else {
10696 memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
10697 priv->cmdlog_len = cmdlog;
10698 }
10699 }
10700
0edd5b44 10701 for (i = 0; i < MAX_HW_RESTARTS; i++) {
bf79451e 10702 /* Load the microcode, firmware, and eeprom.
43f66a6c
JK
10703 * Also start the clocks. */
10704 rc = ipw_load(priv);
10705 if (rc) {
a4f6bbb3 10706 IPW_ERROR("Unable to load firmware: %d\n", rc);
43f66a6c
JK
10707 return rc;
10708 }
10709
10710 ipw_init_ordinals(priv);
10711 if (!(priv->config & CFG_CUSTOM_MAC))
10712 eeprom_parse_mac(priv, priv->mac_addr);
10713 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
10714
4f36f808
JK
10715 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
10716 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
10717 ipw_geos[j].name, 3))
10718 break;
10719 }
10720 if (j == ARRAY_SIZE(ipw_geos))
10721 j = 0;
1fe0adb4 10722 if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
4f36f808
JK
10723 IPW_WARNING("Could not set geography.");
10724 return 0;
10725 }
10726
10727 IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
10728 j, priv->ieee->geo.name);
afbf30a2 10729
b095c381
JK
10730 if (priv->status & STATUS_RF_KILL_SW) {
10731 IPW_WARNING("Radio disabled by module parameter.\n");
10732 return 0;
10733 } else if (rf_kill_active(priv)) {
10734 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
10735 "Kill switch must be turned off for "
10736 "wireless networking to work.\n");
10737 queue_delayed_work(priv->workqueue, &priv->rf_kill,
10738 2 * HZ);
43f66a6c 10739 return 0;
c848d0af 10740 }
43f66a6c
JK
10741
10742 rc = ipw_config(priv);
10743 if (!rc) {
10744 IPW_DEBUG_INFO("Configured device on count %i\n", i);
e666619e
JK
10745
10746 /* If configure to try and auto-associate, kick
10747 * off a scan. */
10748 queue_work(priv->workqueue, &priv->request_scan);
afbf30a2 10749
43f66a6c 10750 return 0;
43f66a6c 10751 }
bf79451e 10752
c848d0af 10753 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
43f66a6c
JK
10754 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
10755 i, MAX_HW_RESTARTS);
10756
10757 /* We had an error bringing up the hardware, so take it
10758 * all the way back down so we can try again */
10759 ipw_down(priv);
10760 }
10761
bf79451e 10762 /* tried to restart and config the device for as long as our
43f66a6c 10763 * patience could withstand */
0edd5b44 10764 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
c848d0af 10765
43f66a6c
JK
10766 return -EIO;
10767}
10768
c848d0af
JK
10769static void ipw_bg_up(void *data)
10770{
10771 struct ipw_priv *priv = data;
10772 down(&priv->sem);
10773 ipw_up(data);
10774 up(&priv->sem);
10775}
10776
b095c381 10777static void ipw_deinit(struct ipw_priv *priv)
43f66a6c 10778{
b095c381
JK
10779 int i;
10780
10781 if (priv->status & STATUS_SCANNING) {
10782 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
10783 ipw_abort_scan(priv);
10784 }
10785
10786 if (priv->status & STATUS_ASSOCIATED) {
10787 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
10788 ipw_disassociate(priv);
10789 }
10790
10791 ipw_led_shutdown(priv);
10792
10793 /* Wait up to 1s for status to change to not scanning and not
10794 * associated (disassociation can take a while for a ful 802.11
10795 * exchange */
10796 for (i = 1000; i && (priv->status &
10797 (STATUS_DISASSOCIATING |
10798 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
10799 udelay(10);
10800
10801 if (priv->status & (STATUS_DISASSOCIATING |
10802 STATUS_ASSOCIATED | STATUS_SCANNING))
10803 IPW_DEBUG_INFO("Still associated or scanning...\n");
10804 else
10805 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
10806
c848d0af 10807 /* Attempt to disable the card */
43f66a6c 10808 ipw_send_card_disable(priv, 0);
b095c381
JK
10809
10810 priv->status &= ~STATUS_INIT;
10811}
10812
10813static void ipw_down(struct ipw_priv *priv)
10814{
10815 int exit_pending = priv->status & STATUS_EXIT_PENDING;
10816
10817 priv->status |= STATUS_EXIT_PENDING;
10818
10819 if (ipw_is_init(priv))
10820 ipw_deinit(priv);
10821
10822 /* Wipe out the EXIT_PENDING status bit if we are not actually
10823 * exiting the module */
10824 if (!exit_pending)
10825 priv->status &= ~STATUS_EXIT_PENDING;
43f66a6c
JK
10826
10827 /* tell the device to stop sending interrupts */
10828 ipw_disable_interrupts(priv);
10829
10830 /* Clear all bits but the RF Kill */
b095c381 10831 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
43f66a6c
JK
10832 netif_carrier_off(priv->net_dev);
10833 netif_stop_queue(priv->net_dev);
10834
10835 ipw_stop_nic(priv);
a613bffd
JK
10836
10837 ipw_led_radio_off(priv);
43f66a6c
JK
10838}
10839
c848d0af
JK
10840static void ipw_bg_down(void *data)
10841{
10842 struct ipw_priv *priv = data;
10843 down(&priv->sem);
10844 ipw_down(data);
10845 up(&priv->sem);
10846}
10847
43f66a6c
JK
10848/* Called by register_netdev() */
10849static int ipw_net_init(struct net_device *dev)
10850{
10851 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 10852 down(&priv->sem);
43f66a6c 10853
c848d0af
JK
10854 if (ipw_up(priv)) {
10855 up(&priv->sem);
43f66a6c 10856 return -EIO;
c848d0af 10857 }
43f66a6c 10858
c848d0af 10859 up(&priv->sem);
43f66a6c
JK
10860 return 0;
10861}
10862
10863/* PCI driver stuff */
10864static struct pci_device_id card_ids[] = {
10865 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
10866 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
10867 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
10868 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2712, 0, 0, 0},
10869 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2721, 0, 0, 0},
10870 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2722, 0, 0, 0},
10871 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2731, 0, 0, 0},
10872 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2732, 0, 0, 0},
10873 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2741, 0, 0, 0},
10874 {PCI_VENDOR_ID_INTEL, 0x1043, 0x103c, 0x2741, 0, 0, 0},
10875 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2742, 0, 0, 0},
10876 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2751, 0, 0, 0},
10877 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2752, 0, 0, 0},
10878 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2753, 0, 0, 0},
10879 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},
10880 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},
10881 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
10882 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
0edd5b44 10883 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
a613bffd 10884 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
0edd5b44
JG
10885 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
10886 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
bf79451e 10887
43f66a6c
JK
10888 /* required last entry */
10889 {0,}
10890};
10891
10892MODULE_DEVICE_TABLE(pci, card_ids);
10893
10894static struct attribute *ipw_sysfs_entries[] = {
10895 &dev_attr_rf_kill.attr,
10896 &dev_attr_direct_dword.attr,
10897 &dev_attr_indirect_byte.attr,
10898 &dev_attr_indirect_dword.attr,
10899 &dev_attr_mem_gpio_reg.attr,
10900 &dev_attr_command_event_reg.attr,
10901 &dev_attr_nic_type.attr,
10902 &dev_attr_status.attr,
10903 &dev_attr_cfg.attr,
b39860c6
JK
10904 &dev_attr_error.attr,
10905 &dev_attr_event_log.attr,
f6c5cb7c 10906 &dev_attr_cmd_log.attr,
43f66a6c
JK
10907 &dev_attr_eeprom_delay.attr,
10908 &dev_attr_ucode_version.attr,
10909 &dev_attr_rtc.attr,
a613bffd
JK
10910 &dev_attr_scan_age.attr,
10911 &dev_attr_led.attr,
b095c381
JK
10912 &dev_attr_speed_scan.attr,
10913 &dev_attr_net_stats.attr,
43f66a6c
JK
10914 NULL
10915};
10916
10917static struct attribute_group ipw_attribute_group = {
10918 .name = NULL, /* put in device directory */
0edd5b44 10919 .attrs = ipw_sysfs_entries,
43f66a6c
JK
10920};
10921
0edd5b44 10922static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
43f66a6c
JK
10923{
10924 int err = 0;
10925 struct net_device *net_dev;
10926 void __iomem *base;
10927 u32 length, val;
10928 struct ipw_priv *priv;
afbf30a2 10929 int i;
43f66a6c
JK
10930
10931 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
10932 if (net_dev == NULL) {
10933 err = -ENOMEM;
10934 goto out;
10935 }
10936
10937 priv = ieee80211_priv(net_dev);
10938 priv->ieee = netdev_priv(net_dev);
a613bffd 10939
43f66a6c
JK
10940 priv->net_dev = net_dev;
10941 priv->pci_dev = pdev;
10942#ifdef CONFIG_IPW_DEBUG
10943 ipw_debug_level = debug;
10944#endif
10945 spin_lock_init(&priv->lock);
afbf30a2
JK
10946 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
10947 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
43f66a6c 10948
c848d0af 10949 init_MUTEX(&priv->sem);
43f66a6c
JK
10950 if (pci_enable_device(pdev)) {
10951 err = -ENODEV;
10952 goto out_free_ieee80211;
10953 }
10954
10955 pci_set_master(pdev);
10956
0e08b44e 10957 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
bf79451e 10958 if (!err)
0e08b44e 10959 err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
43f66a6c
JK
10960 if (err) {
10961 printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
10962 goto out_pci_disable_device;
10963 }
10964
10965 pci_set_drvdata(pdev, priv);
10966
10967 err = pci_request_regions(pdev, DRV_NAME);
bf79451e 10968 if (err)
43f66a6c
JK
10969 goto out_pci_disable_device;
10970
bf79451e 10971 /* We disable the RETRY_TIMEOUT register (0x41) to keep
43f66a6c 10972 * PCI Tx retries from interfering with C3 CPU state */
bf79451e
JG
10973 pci_read_config_dword(pdev, 0x40, &val);
10974 if ((val & 0x0000ff00) != 0)
43f66a6c 10975 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
bf79451e 10976
43f66a6c
JK
10977 length = pci_resource_len(pdev, 0);
10978 priv->hw_len = length;
bf79451e 10979
43f66a6c
JK
10980 base = ioremap_nocache(pci_resource_start(pdev, 0), length);
10981 if (!base) {
10982 err = -ENODEV;
10983 goto out_pci_release_regions;
10984 }
10985
10986 priv->hw_base = base;
10987 IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);
10988 IPW_DEBUG_INFO("pci_resource_base = %p\n", base);
10989
10990 err = ipw_setup_deferred_work(priv);
10991 if (err) {
10992 IPW_ERROR("Unable to setup deferred work\n");
10993 goto out_iounmap;
10994 }
10995
b095c381 10996 ipw_sw_reset(priv, 1);
43f66a6c 10997
0edd5b44 10998 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
43f66a6c
JK
10999 if (err) {
11000 IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
11001 goto out_destroy_workqueue;
11002 }
11003
11004 SET_MODULE_OWNER(net_dev);
11005 SET_NETDEV_DEV(net_dev, &pdev->dev);
11006
c848d0af
JK
11007 down(&priv->sem);
11008
43f66a6c
JK
11009 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
11010 priv->ieee->set_security = shim__set_security;
227d2dc1 11011 priv->ieee->is_queue_full = ipw_net_is_queue_full;
43f66a6c 11012
b095c381 11013#ifdef CONFIG_IPW_QOS
3b9990cb
JK
11014 priv->ieee->handle_probe_response = ipw_handle_beacon;
11015 priv->ieee->handle_beacon = ipw_handle_probe_response;
11016 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
b095c381
JK
11017#endif /* CONFIG_IPW_QOS */
11018
c848d0af
JK
11019 priv->ieee->perfect_rssi = -20;
11020 priv->ieee->worst_rssi = -85;
11021
43f66a6c
JK
11022 net_dev->open = ipw_net_open;
11023 net_dev->stop = ipw_net_stop;
11024 net_dev->init = ipw_net_init;
11025 net_dev->get_stats = ipw_net_get_stats;
11026 net_dev->set_multicast_list = ipw_net_set_multicast_list;
11027 net_dev->set_mac_address = ipw_net_set_mac_address;
97a78ca9
BB
11028 priv->wireless_data.spy_data = &priv->ieee->spy_data;
11029 priv->wireless_data.ieee80211 = priv->ieee;
11030 net_dev->wireless_data = &priv->wireless_data;
43f66a6c
JK
11031 net_dev->wireless_handlers = &ipw_wx_handler_def;
11032 net_dev->ethtool_ops = &ipw_ethtool_ops;
11033 net_dev->irq = pdev->irq;
0edd5b44 11034 net_dev->base_addr = (unsigned long)priv->hw_base;
43f66a6c
JK
11035 net_dev->mem_start = pci_resource_start(pdev, 0);
11036 net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1;
11037
11038 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
11039 if (err) {
11040 IPW_ERROR("failed to create sysfs device attributes\n");
c848d0af 11041 up(&priv->sem);
43f66a6c
JK
11042 goto out_release_irq;
11043 }
11044
c848d0af 11045 up(&priv->sem);
43f66a6c
JK
11046 err = register_netdev(net_dev);
11047 if (err) {
11048 IPW_ERROR("failed to register network device\n");
a613bffd 11049 goto out_remove_sysfs;
43f66a6c 11050 }
43f66a6c
JK
11051 return 0;
11052
a613bffd 11053 out_remove_sysfs:
43f66a6c 11054 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
0edd5b44 11055 out_release_irq:
43f66a6c 11056 free_irq(pdev->irq, priv);
0edd5b44 11057 out_destroy_workqueue:
43f66a6c
JK
11058 destroy_workqueue(priv->workqueue);
11059 priv->workqueue = NULL;
0edd5b44 11060 out_iounmap:
43f66a6c 11061 iounmap(priv->hw_base);
0edd5b44 11062 out_pci_release_regions:
43f66a6c 11063 pci_release_regions(pdev);
0edd5b44 11064 out_pci_disable_device:
43f66a6c
JK
11065 pci_disable_device(pdev);
11066 pci_set_drvdata(pdev, NULL);
0edd5b44 11067 out_free_ieee80211:
43f66a6c 11068 free_ieee80211(priv->net_dev);
0edd5b44 11069 out:
43f66a6c
JK
11070 return err;
11071}
11072
11073static void ipw_pci_remove(struct pci_dev *pdev)
11074{
11075 struct ipw_priv *priv = pci_get_drvdata(pdev);
afbf30a2
JK
11076 struct list_head *p, *q;
11077 int i;
b095c381 11078
43f66a6c
JK
11079 if (!priv)
11080 return;
11081
b095c381 11082 down(&priv->sem);
afbf30a2
JK
11083
11084 priv->status |= STATUS_EXIT_PENDING;
43f66a6c 11085 ipw_down(priv);
b095c381 11086 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
afbf30a2 11087
b095c381 11088 up(&priv->sem);
43f66a6c
JK
11089
11090 unregister_netdev(priv->net_dev);
11091
11092 if (priv->rxq) {
11093 ipw_rx_queue_free(priv, priv->rxq);
11094 priv->rxq = NULL;
11095 }
11096 ipw_tx_queue_free(priv);
11097
f6c5cb7c
JK
11098 if (priv->cmdlog) {
11099 kfree(priv->cmdlog);
11100 priv->cmdlog = NULL;
11101 }
43f66a6c
JK
11102 /* ipw_down will ensure that there is no more pending work
11103 * in the workqueue's, so we can safely remove them now. */
a613bffd
JK
11104 cancel_delayed_work(&priv->adhoc_check);
11105 cancel_delayed_work(&priv->gather_stats);
11106 cancel_delayed_work(&priv->request_scan);
11107 cancel_delayed_work(&priv->rf_kill);
11108 cancel_delayed_work(&priv->scan_check);
11109 destroy_workqueue(priv->workqueue);
11110 priv->workqueue = NULL;
43f66a6c 11111
afbf30a2
JK
11112 /* Free MAC hash list for ADHOC */
11113 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
11114 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
11115 kfree(list_entry(p, struct ipw_ibss_seq, list));
11116 list_del(p);
11117 }
11118 }
11119
b39860c6
JK
11120 if (priv->error) {
11121 ipw_free_error_log(priv->error);
11122 priv->error = NULL;
11123 }
11124
43f66a6c
JK
11125 free_irq(pdev->irq, priv);
11126 iounmap(priv->hw_base);
11127 pci_release_regions(pdev);
11128 pci_disable_device(pdev);
11129 pci_set_drvdata(pdev, NULL);
11130 free_ieee80211(priv->net_dev);
afbf30a2 11131 free_firmware();
43f66a6c
JK
11132}
11133
43f66a6c 11134#ifdef CONFIG_PM
583a4e88 11135static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
43f66a6c
JK
11136{
11137 struct ipw_priv *priv = pci_get_drvdata(pdev);
11138 struct net_device *dev = priv->net_dev;
11139
11140 printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
11141
0edd5b44 11142 /* Take down the device; powers it off, etc. */
43f66a6c
JK
11143 ipw_down(priv);
11144
11145 /* Remove the PRESENT state of the device */
11146 netif_device_detach(dev);
11147
43f66a6c 11148 pci_save_state(pdev);
43f66a6c 11149 pci_disable_device(pdev);
583a4e88 11150 pci_set_power_state(pdev, pci_choose_state(pdev, state));
bf79451e 11151
43f66a6c
JK
11152 return 0;
11153}
11154
11155static int ipw_pci_resume(struct pci_dev *pdev)
11156{
11157 struct ipw_priv *priv = pci_get_drvdata(pdev);
11158 struct net_device *dev = priv->net_dev;
11159 u32 val;
bf79451e 11160
43f66a6c
JK
11161 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
11162
ea2b26e0 11163 pci_set_power_state(pdev, PCI_D0);
43f66a6c 11164 pci_enable_device(pdev);
43f66a6c 11165 pci_restore_state(pdev);
ea2b26e0 11166
43f66a6c
JK
11167 /*
11168 * Suspend/Resume resets the PCI configuration space, so we have to
11169 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
11170 * from interfering with C3 CPU state. pci_restore_state won't help
11171 * here since it only restores the first 64 bytes pci config header.
11172 */
bf79451e
JG
11173 pci_read_config_dword(pdev, 0x40, &val);
11174 if ((val & 0x0000ff00) != 0)
43f66a6c
JK
11175 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
11176
11177 /* Set the device back into the PRESENT state; this will also wake
11178 * the queue of needed */
11179 netif_device_attach(dev);
11180
11181 /* Bring the device back up */
11182 queue_work(priv->workqueue, &priv->up);
bf79451e 11183
43f66a6c
JK
11184 return 0;
11185}
11186#endif
11187
11188/* driver initialization stuff */
11189static struct pci_driver ipw_driver = {
11190 .name = DRV_NAME,
11191 .id_table = card_ids,
11192 .probe = ipw_pci_probe,
11193 .remove = __devexit_p(ipw_pci_remove),
11194#ifdef CONFIG_PM
11195 .suspend = ipw_pci_suspend,
11196 .resume = ipw_pci_resume,
11197#endif
11198};
11199
11200static int __init ipw_init(void)
11201{
11202 int ret;
11203
11204 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
11205 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
11206
11207 ret = pci_module_init(&ipw_driver);
11208 if (ret) {
11209 IPW_ERROR("Unable to initialize PCI module\n");
11210 return ret;
11211 }
11212
0edd5b44 11213 ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level);
43f66a6c
JK
11214 if (ret) {
11215 IPW_ERROR("Unable to create driver sysfs file\n");
11216 pci_unregister_driver(&ipw_driver);
11217 return ret;
11218 }
11219
11220 return ret;
11221}
11222
11223static void __exit ipw_exit(void)
11224{
11225 driver_remove_file(&ipw_driver.driver, &driver_attr_debug_level);
11226 pci_unregister_driver(&ipw_driver);
11227}
11228
11229module_param(disable, int, 0444);
11230MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
11231
11232module_param(associate, int, 0444);
11233MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
11234
11235module_param(auto_create, int, 0444);
11236MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
11237
a613bffd 11238module_param(led, int, 0444);
c848d0af 11239MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
a613bffd 11240
43f66a6c
JK
11241module_param(debug, int, 0444);
11242MODULE_PARM_DESC(debug, "debug output mask");
11243
11244module_param(channel, int, 0444);
bf79451e 11245MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
43f66a6c 11246
b095c381
JK
11247#ifdef CONFIG_IPW_QOS
11248module_param(qos_enable, int, 0444);
11249MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
11250
11251module_param(qos_burst_enable, int, 0444);
11252MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
11253
11254module_param(qos_no_ack_mask, int, 0444);
11255MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
11256
11257module_param(burst_duration_CCK, int, 0444);
11258MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
11259
11260module_param(burst_duration_OFDM, int, 0444);
11261MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
11262#endif /* CONFIG_IPW_QOS */
11263
11264#ifdef CONFIG_IPW2200_MONITOR
43f66a6c
JK
11265module_param(mode, int, 0444);
11266MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
11267#else
11268module_param(mode, int, 0444);
11269MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
11270#endif
11271
b095c381
JK
11272module_param(hwcrypto, int, 0444);
11273MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
11274
f6c5cb7c
JK
11275module_param(cmdlog, int, 0444);
11276MODULE_PARM_DESC(cmdlog,
11277 "allocate a ring buffer for logging firmware commands");
11278
43f66a6c
JK
11279module_exit(ipw_exit);
11280module_init(ipw_init);
This page took 0.751551 seconds and 5 git commands to generate.