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