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