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