]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/wireless/ipw2x00/ipw2200.c
ath9k: stomp audio profiles on weak signal strength
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / ipw2x00 / 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 27 Contact Information:
c1eb2c82 28 Intel Linux Wireless <ilw@linux.intel.com>
43f66a6c
JK
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32
d43c36dc 33#include <linux/sched.h>
5a0e3ad6 34#include <linux/slab.h>
262eb9b2 35#include <net/cfg80211-wext.h>
43f66a6c 36#include "ipw2200.h"
a141e6a0 37#include "ipw.h"
43f66a6c 38
ae4af61f
ZY
39
40#ifndef KBUILD_EXTMOD
41#define VK "k"
42#else
43#define VK
44#endif
45
46#ifdef CONFIG_IPW2200_DEBUG
47#define VD "d"
48#else
49#define VD
50#endif
51
52#ifdef CONFIG_IPW2200_MONITOR
53#define VM "m"
54#else
55#define VM
56#endif
57
58#ifdef CONFIG_IPW2200_PROMISCUOUS
59#define VP "p"
60#else
61#define VP
62#endif
63
459d4087 64#ifdef CONFIG_IPW2200_RADIOTAP
ae4af61f
ZY
65#define VR "r"
66#else
67#define VR
68#endif
69
70#ifdef CONFIG_IPW2200_QOS
71#define VQ "q"
72#else
73#define VQ
74#endif
75
ee2c4add 76#define IPW2200_VERSION "1.2.2" VK VD VM VP VR VQ
43f66a6c 77#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
171e7b2f 78#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
43f66a6c
JK
79#define DRV_VERSION IPW2200_VERSION
80
b095c381
JK
81#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
82
43f66a6c
JK
83MODULE_DESCRIPTION(DRV_DESCRIPTION);
84MODULE_VERSION(DRV_VERSION);
85MODULE_AUTHOR(DRV_COPYRIGHT);
86MODULE_LICENSE("GPL");
873395a9
BH
87MODULE_FIRMWARE("ipw2200-ibss.fw");
88#ifdef CONFIG_IPW2200_MONITOR
89MODULE_FIRMWARE("ipw2200-sniffer.fw");
90#endif
91MODULE_FIRMWARE("ipw2200-bss.fw");
43f66a6c 92
f6c5cb7c 93static int cmdlog = 0;
43f66a6c 94static int debug = 0;
21f8a73f
RC
95static int default_channel = 0;
96static int network_mode = 0;
43f66a6c
JK
97
98static u32 ipw_debug_level;
5c7f9b73 99static int associate;
43f66a6c 100static int auto_create = 1;
c086abae 101static int led_support = 1;
43f66a6c 102static int disable = 0;
810dabd4 103static int bt_coexist = 0;
bde37d03 104static int hwcrypto = 0;
4bfdb91d 105static int roaming = 1;
43f66a6c
JK
106static const char ipw_modes[] = {
107 'a', 'b', 'g', '?'
108};
d2b83e12 109static int antenna = CFG_SYS_ANTENNA_BOTH;
43f66a6c 110
d685b8c2
ZY
111#ifdef CONFIG_IPW2200_PROMISCUOUS
112static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */
113#endif
114
a3caa99e
JL
115static struct ieee80211_rate ipw2200_rates[] = {
116 { .bitrate = 10 },
117 { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
118 { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
119 { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
120 { .bitrate = 60 },
121 { .bitrate = 90 },
122 { .bitrate = 120 },
123 { .bitrate = 180 },
124 { .bitrate = 240 },
125 { .bitrate = 360 },
126 { .bitrate = 480 },
127 { .bitrate = 540 }
128};
129
130#define ipw2200_a_rates (ipw2200_rates + 4)
131#define ipw2200_num_a_rates 8
132#define ipw2200_bg_rates (ipw2200_rates + 0)
133#define ipw2200_num_bg_rates 12
d685b8c2 134
776d68f8
JB
135/* Ugly macro to convert literal channel numbers into their mhz equivalents
136 * There are certianly some conditions that will break this (like feeding it '30')
137 * but they shouldn't arise since nothing talks on channel 30. */
138#define ieee80211chan2mhz(x) \
139 (((x) <= 14) ? \
140 (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
141 ((x) + 1000) * 5)
142
e43e3c1e 143#ifdef CONFIG_IPW2200_QOS
b095c381
JK
144static int qos_enable = 0;
145static int qos_burst_enable = 0;
146static int qos_no_ack_mask = 0;
147static int burst_duration_CCK = 0;
148static int burst_duration_OFDM = 0;
149
b0a4e7d8 150static struct libipw_qos_parameters def_qos_parameters_OFDM = {
b095c381
JK
151 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
152 QOS_TX3_CW_MIN_OFDM},
153 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
154 QOS_TX3_CW_MAX_OFDM},
155 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
156 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
157 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
158 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
159};
160
b0a4e7d8 161static struct libipw_qos_parameters def_qos_parameters_CCK = {
b095c381
JK
162 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
163 QOS_TX3_CW_MIN_CCK},
164 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
165 QOS_TX3_CW_MAX_CCK},
166 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
167 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
168 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
169 QOS_TX3_TXOP_LIMIT_CCK}
170};
171
b0a4e7d8 172static struct libipw_qos_parameters def_parameters_OFDM = {
b095c381
JK
173 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
174 DEF_TX3_CW_MIN_OFDM},
175 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
176 DEF_TX3_CW_MAX_OFDM},
177 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
178 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
179 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
180 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
181};
182
b0a4e7d8 183static struct libipw_qos_parameters def_parameters_CCK = {
b095c381
JK
184 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
185 DEF_TX3_CW_MIN_CCK},
186 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
187 DEF_TX3_CW_MAX_CCK},
188 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
189 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
190 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
191 DEF_TX3_TXOP_LIMIT_CCK}
192};
193
194static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
195
196static int from_priority_to_tx_queue[] = {
197 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
198 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
199};
200
201static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
202
b0a4e7d8 203static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters
b095c381 204 *qos_param);
b0a4e7d8 205static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element
b095c381 206 *qos_param);
e43e3c1e 207#endif /* CONFIG_IPW2200_QOS */
b095c381 208
97a78ca9 209static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
b095c381 210static void ipw_remove_current_network(struct ipw_priv *priv);
43f66a6c 211static void ipw_rx(struct ipw_priv *priv);
bf79451e 212static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
213 struct clx2_tx_queue *txq, int qindex);
214static int ipw_queue_reset(struct ipw_priv *priv);
215
216static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
217 int len, int sync);
218
219static void ipw_tx_queue_free(struct ipw_priv *);
220
221static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
222static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
223static void ipw_rx_queue_replenish(void *);
43f66a6c 224static int ipw_up(struct ipw_priv *);
c4028958 225static void ipw_bg_up(struct work_struct *work);
43f66a6c 226static void ipw_down(struct ipw_priv *);
c4028958 227static void ipw_bg_down(struct work_struct *work);
43f66a6c 228static int ipw_config(struct ipw_priv *);
0edd5b44
JG
229static int init_supported_rates(struct ipw_priv *priv,
230 struct ipw_supported_rates *prates);
b095c381
JK
231static void ipw_set_hwcrypto_keys(struct ipw_priv *);
232static void ipw_send_wep_keys(struct ipw_priv *, int);
43f66a6c 233
f6c5cb7c
JK
234static int snprint_line(char *buf, size_t count,
235 const u8 * data, u32 len, u32 ofs)
43f66a6c
JK
236{
237 int out, i, j, l;
238 char c;
bf79451e 239
43f66a6c
JK
240 out = snprintf(buf, count, "%08X", ofs);
241
242 for (l = 0, i = 0; i < 2; i++) {
243 out += snprintf(buf + out, count - out, " ");
bf79451e
JG
244 for (j = 0; j < 8 && l < len; j++, l++)
245 out += snprintf(buf + out, count - out, "%02X ",
43f66a6c
JK
246 data[(i * 8 + j)]);
247 for (; j < 8; j++)
248 out += snprintf(buf + out, count - out, " ");
249 }
bf79451e 250
43f66a6c
JK
251 out += snprintf(buf + out, count - out, " ");
252 for (l = 0, i = 0; i < 2; i++) {
253 out += snprintf(buf + out, count - out, " ");
254 for (j = 0; j < 8 && l < len; j++, l++) {
255 c = data[(i * 8 + j)];
256 if (!isascii(c) || !isprint(c))
257 c = '.';
bf79451e 258
43f66a6c
JK
259 out += snprintf(buf + out, count - out, "%c", c);
260 }
261
262 for (; j < 8; j++)
263 out += snprintf(buf + out, count - out, " ");
264 }
bf79451e 265
f6c5cb7c 266 return out;
43f66a6c
JK
267}
268
0edd5b44 269static void printk_buf(int level, const u8 * data, u32 len)
43f66a6c
JK
270{
271 char line[81];
272 u32 ofs = 0;
273 if (!(ipw_debug_level & level))
274 return;
275
276 while (len) {
f6c5cb7c
JK
277 snprint_line(line, sizeof(line), &data[ofs],
278 min(len, 16U), ofs);
279 printk(KERN_DEBUG "%s\n", line);
43f66a6c
JK
280 ofs += 16;
281 len -= min(len, 16U);
282 }
283}
284
f6c5cb7c
JK
285static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
286{
287 size_t out = size;
288 u32 ofs = 0;
289 int total = 0;
290
291 while (size && len) {
292 out = snprint_line(output, size, &data[ofs],
293 min_t(size_t, len, 16U), ofs);
294
295 ofs += 16;
296 output += out;
297 size -= out;
298 len -= min_t(size_t, len, 16U);
299 total += out;
300 }
301 return total;
302}
303
c8fe6679 304/* alias for 32-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
43f66a6c
JK
305static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
306#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
307
c8fe6679 308/* alias for 8-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
43f66a6c
JK
309static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
310#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
311
c8fe6679 312/* 8-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
43f66a6c
JK
313static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
314static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
315{
0edd5b44
JG
316 IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__,
317 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
318 _ipw_write_reg8(a, b, c);
319}
320
c8fe6679 321/* 16-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
43f66a6c
JK
322static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
323static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
324{
0edd5b44
JG
325 IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__,
326 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
327 _ipw_write_reg16(a, b, c);
328}
329
c8fe6679 330/* 32-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
43f66a6c
JK
331static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
332static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
333{
0edd5b44
JG
334 IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__,
335 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
336 _ipw_write_reg32(a, b, c);
337}
338
c8fe6679 339/* 8-bit direct write (low 4K) */
1788bcd1
JS
340static inline void _ipw_write8(struct ipw_priv *ipw, unsigned long ofs,
341 u8 val)
342{
343 writeb(val, ipw->hw_base + ofs);
344}
c8fe6679
ZY
345
346/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
fb55d887 347#define ipw_write8(ipw, ofs, val) do { \
1788bcd1
JS
348 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, \
349 __LINE__, (u32)(ofs), (u32)(val)); \
350 _ipw_write8(ipw, ofs, val); \
351} while (0)
43f66a6c 352
c8fe6679 353/* 16-bit direct write (low 4K) */
1788bcd1
JS
354static inline void _ipw_write16(struct ipw_priv *ipw, unsigned long ofs,
355 u16 val)
356{
357 writew(val, ipw->hw_base + ofs);
358}
c8fe6679
ZY
359
360/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
1788bcd1
JS
361#define ipw_write16(ipw, ofs, val) do { \
362 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, \
363 __LINE__, (u32)(ofs), (u32)(val)); \
364 _ipw_write16(ipw, ofs, val); \
365} while (0)
43f66a6c 366
c8fe6679 367/* 32-bit direct write (low 4K) */
1788bcd1
JS
368static inline void _ipw_write32(struct ipw_priv *ipw, unsigned long ofs,
369 u32 val)
370{
371 writel(val, ipw->hw_base + ofs);
372}
c8fe6679
ZY
373
374/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
1788bcd1
JS
375#define ipw_write32(ipw, ofs, val) do { \
376 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, \
377 __LINE__, (u32)(ofs), (u32)(val)); \
378 _ipw_write32(ipw, ofs, val); \
379} while (0)
43f66a6c 380
c8fe6679 381/* 8-bit direct read (low 4K) */
1788bcd1 382static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs)
0edd5b44 383{
1788bcd1 384 return readb(ipw->hw_base + ofs);
43f66a6c 385}
0edd5b44 386
c8fe6679 387/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
1788bcd1
JS
388#define ipw_read8(ipw, ofs) ({ \
389 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", __FILE__, __LINE__, \
390 (u32)(ofs)); \
391 _ipw_read8(ipw, ofs); \
392})
43f66a6c 393
c8fe6679 394/* 16-bit direct read (low 4K) */
1788bcd1 395static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs)
0edd5b44 396{
1788bcd1 397 return readw(ipw->hw_base + ofs);
43f66a6c 398}
0edd5b44 399
c8fe6679 400/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
1788bcd1
JS
401#define ipw_read16(ipw, ofs) ({ \
402 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", __FILE__, __LINE__, \
403 (u32)(ofs)); \
404 _ipw_read16(ipw, ofs); \
405})
43f66a6c 406
c8fe6679 407/* 32-bit direct read (low 4K) */
1788bcd1 408static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs)
0edd5b44 409{
1788bcd1 410 return readl(ipw->hw_base + ofs);
43f66a6c 411}
0edd5b44 412
c8fe6679 413/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
1788bcd1
JS
414#define ipw_read32(ipw, ofs) ({ \
415 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", __FILE__, __LINE__, \
416 (u32)(ofs)); \
417 _ipw_read32(ipw, ofs); \
418})
43f66a6c
JK
419
420static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
c8fe6679 421/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
1788bcd1
JS
422#define ipw_read_indirect(a, b, c, d) ({ \
423 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %u bytes\n", __FILE__, \
424 __LINE__, (u32)(b), (u32)(d)); \
425 _ipw_read_indirect(a, b, c, d); \
426})
43f66a6c 427
c8fe6679 428/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
0edd5b44
JG
429static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
430 int num);
1788bcd1
JS
431#define ipw_write_indirect(a, b, c, d) do { \
432 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %u bytes\n", __FILE__, \
433 __LINE__, (u32)(b), (u32)(d)); \
434 _ipw_write_indirect(a, b, c, d); \
435} while (0)
43f66a6c 436
c8fe6679 437/* 32-bit indirect write (above 4K) */
0edd5b44 438static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
43f66a6c 439{
0edd5b44 440 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
b095c381
JK
441 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
442 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
43f66a6c
JK
443}
444
c8fe6679 445/* 8-bit indirect write (above 4K) */
43f66a6c
JK
446static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
447{
2638bc39 448 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */
c8fe6679
ZY
449 u32 dif_len = reg - aligned_addr;
450
43f66a6c 451 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
c8fe6679
ZY
452 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
453 _ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value);
43f66a6c
JK
454}
455
c8fe6679 456/* 16-bit indirect write (above 4K) */
0edd5b44 457static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
43f66a6c 458{
2638bc39 459 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */
c8fe6679
ZY
460 u32 dif_len = (reg - aligned_addr) & (~0x1ul);
461
43f66a6c 462 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
c8fe6679
ZY
463 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
464 _ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value);
43f66a6c
JK
465}
466
c8fe6679 467/* 8-bit indirect read (above 4K) */
43f66a6c
JK
468static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
469{
470 u32 word;
b095c381 471 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
9fd1ea42 472 IPW_DEBUG_IO(" reg = 0x%8X :\n", reg);
b095c381 473 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
0edd5b44 474 return (word >> ((reg & 0x3) * 8)) & 0xff;
43f66a6c
JK
475}
476
c8fe6679 477/* 32-bit indirect read (above 4K) */
43f66a6c
JK
478static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
479{
480 u32 value;
481
482 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
483
b095c381
JK
484 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
485 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
9fd1ea42 486 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x\n", reg, value);
43f66a6c
JK
487 return value;
488}
489
c8fe6679
ZY
490/* General purpose, no alignment requirement, iterative (multi-byte) read, */
491/* for area above 1st 4K of SRAM/reg space */
43f66a6c
JK
492static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
493 int num)
494{
2638bc39 495 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */
43f66a6c 496 u32 dif_len = addr - aligned_addr;
43f66a6c 497 u32 i;
bf79451e 498
43f66a6c
JK
499 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
500
ea2b26e0
JK
501 if (num <= 0) {
502 return;
503 }
504
c8fe6679 505 /* Read the first dword (or portion) byte by byte */
43f66a6c 506 if (unlikely(dif_len)) {
b095c381 507 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
43f66a6c 508 /* Start reading at aligned_addr + dif_len */
ea2b26e0 509 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
b095c381 510 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
43f66a6c
JK
511 aligned_addr += 4;
512 }
513
c8fe6679 514 /* Read all of the middle dwords as dwords, with auto-increment */
b095c381 515 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
ea2b26e0 516 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
b095c381 517 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
bf79451e 518
c8fe6679 519 /* Read the last dword (or portion) byte by byte */
ea2b26e0 520 if (unlikely(num)) {
b095c381 521 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0 522 for (i = 0; num > 0; i++, num--)
b095c381 523 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
ea2b26e0 524 }
43f66a6c
JK
525}
526
c8fe6679
ZY
527/* General purpose, no alignment requirement, iterative (multi-byte) write, */
528/* for area above 1st 4K of SRAM/reg space */
0edd5b44 529static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
43f66a6c
JK
530 int num)
531{
2638bc39 532 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */
43f66a6c 533 u32 dif_len = addr - aligned_addr;
43f66a6c 534 u32 i;
bf79451e 535
43f66a6c 536 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
bf79451e 537
ea2b26e0
JK
538 if (num <= 0) {
539 return;
540 }
541
c8fe6679 542 /* Write the first dword (or portion) byte by byte */
43f66a6c 543 if (unlikely(dif_len)) {
b095c381 544 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
c8fe6679 545 /* Start writing at aligned_addr + dif_len */
ea2b26e0 546 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
b095c381 547 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
43f66a6c
JK
548 aligned_addr += 4;
549 }
bf79451e 550
c8fe6679 551 /* Write all of the middle dwords as dwords, with auto-increment */
b095c381 552 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
ea2b26e0 553 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
b095c381 554 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
bf79451e 555
c8fe6679 556 /* Write the last dword (or portion) byte by byte */
ea2b26e0 557 if (unlikely(num)) {
b095c381 558 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0 559 for (i = 0; num > 0; i++, num--, buf++)
b095c381 560 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
ea2b26e0 561 }
43f66a6c
JK
562}
563
c8fe6679
ZY
564/* General purpose, no alignment requirement, iterative (multi-byte) write, */
565/* for 1st 4K of SRAM/regs space */
bf79451e 566static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
43f66a6c
JK
567 int num)
568{
569 memcpy_toio((priv->hw_base + addr), buf, num);
570}
571
c8fe6679 572/* Set bit(s) in low 4K of SRAM/regs */
43f66a6c
JK
573static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
574{
575 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
576}
577
c8fe6679 578/* Clear bit(s) in low 4K of SRAM/regs */
43f66a6c
JK
579static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
580{
581 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
582}
583
89c318ed 584static inline void __ipw_enable_interrupts(struct ipw_priv *priv)
43f66a6c
JK
585{
586 if (priv->status & STATUS_INT_ENABLED)
587 return;
588 priv->status |= STATUS_INT_ENABLED;
b095c381 589 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
43f66a6c
JK
590}
591
89c318ed 592static inline void __ipw_disable_interrupts(struct ipw_priv *priv)
43f66a6c
JK
593{
594 if (!(priv->status & STATUS_INT_ENABLED))
595 return;
596 priv->status &= ~STATUS_INT_ENABLED;
b095c381 597 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
43f66a6c
JK
598}
599
89c318ed
ZY
600static inline void ipw_enable_interrupts(struct ipw_priv *priv)
601{
602 unsigned long flags;
603
604 spin_lock_irqsave(&priv->irq_lock, flags);
605 __ipw_enable_interrupts(priv);
606 spin_unlock_irqrestore(&priv->irq_lock, flags);
607}
608
609static inline void ipw_disable_interrupts(struct ipw_priv *priv)
610{
611 unsigned long flags;
612
613 spin_lock_irqsave(&priv->irq_lock, flags);
614 __ipw_disable_interrupts(priv);
615 spin_unlock_irqrestore(&priv->irq_lock, flags);
616}
617
43f66a6c
JK
618static char *ipw_error_desc(u32 val)
619{
620 switch (val) {
bf79451e 621 case IPW_FW_ERROR_OK:
43f66a6c 622 return "ERROR_OK";
bf79451e 623 case IPW_FW_ERROR_FAIL:
43f66a6c 624 return "ERROR_FAIL";
bf79451e 625 case IPW_FW_ERROR_MEMORY_UNDERFLOW:
43f66a6c 626 return "MEMORY_UNDERFLOW";
bf79451e 627 case IPW_FW_ERROR_MEMORY_OVERFLOW:
43f66a6c 628 return "MEMORY_OVERFLOW";
bf79451e 629 case IPW_FW_ERROR_BAD_PARAM:
b095c381 630 return "BAD_PARAM";
bf79451e 631 case IPW_FW_ERROR_BAD_CHECKSUM:
b095c381 632 return "BAD_CHECKSUM";
bf79451e 633 case IPW_FW_ERROR_NMI_INTERRUPT:
b095c381 634 return "NMI_INTERRUPT";
bf79451e 635 case IPW_FW_ERROR_BAD_DATABASE:
b095c381 636 return "BAD_DATABASE";
bf79451e 637 case IPW_FW_ERROR_ALLOC_FAIL:
b095c381 638 return "ALLOC_FAIL";
bf79451e 639 case IPW_FW_ERROR_DMA_UNDERRUN:
b095c381 640 return "DMA_UNDERRUN";
bf79451e 641 case IPW_FW_ERROR_DMA_STATUS:
b095c381
JK
642 return "DMA_STATUS";
643 case IPW_FW_ERROR_DINO_ERROR:
644 return "DINO_ERROR";
645 case IPW_FW_ERROR_EEPROM_ERROR:
646 return "EEPROM_ERROR";
bf79451e 647 case IPW_FW_ERROR_SYSASSERT:
b095c381 648 return "SYSASSERT";
bf79451e 649 case IPW_FW_ERROR_FATAL_ERROR:
b095c381 650 return "FATAL_ERROR";
bf79451e 651 default:
b095c381 652 return "UNKNOWN_ERROR";
43f66a6c
JK
653 }
654}
655
b39860c6
JK
656static void ipw_dump_error_log(struct ipw_priv *priv,
657 struct ipw_fw_error *error)
43f66a6c 658{
b39860c6 659 u32 i;
bf79451e 660
b39860c6
JK
661 if (!error) {
662 IPW_ERROR("Error allocating and capturing error log. "
663 "Nothing to dump.\n");
664 return;
43f66a6c
JK
665 }
666
b39860c6
JK
667 IPW_ERROR("Start IPW Error Log Dump:\n");
668 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
669 error->status, error->config);
43f66a6c 670
b39860c6 671 for (i = 0; i < error->elem_len; i++)
0edd5b44 672 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
b39860c6
JK
673 ipw_error_desc(error->elem[i].desc),
674 error->elem[i].time,
675 error->elem[i].blink1,
676 error->elem[i].blink2,
677 error->elem[i].link1,
678 error->elem[i].link2, error->elem[i].data);
679 for (i = 0; i < error->log_len; i++)
680 IPW_ERROR("%i\t0x%08x\t%i\n",
681 error->log[i].time,
286568ab 682 error->log[i].data, error->log[i].event);
43f66a6c
JK
683}
684
c848d0af 685static inline int ipw_is_init(struct ipw_priv *priv)
43f66a6c 686{
c848d0af 687 return (priv->status & STATUS_INIT) ? 1 : 0;
43f66a6c
JK
688}
689
0edd5b44 690static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
43f66a6c
JK
691{
692 u32 addr, field_info, field_len, field_count, total_len;
693
694 IPW_DEBUG_ORD("ordinal = %i\n", ord);
695
696 if (!priv || !val || !len) {
697 IPW_DEBUG_ORD("Invalid argument\n");
698 return -EINVAL;
699 }
bf79451e 700
43f66a6c
JK
701 /* verify device ordinal tables have been initialized */
702 if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {
703 IPW_DEBUG_ORD("Access ordinals before initialization\n");
704 return -EINVAL;
705 }
706
707 switch (IPW_ORD_TABLE_ID_MASK & ord) {
708 case IPW_ORD_TABLE_0_MASK:
709 /*
710 * TABLE 0: Direct access to a table of 32 bit values
711 *
bf79451e 712 * This is a very simple table with the data directly
43f66a6c
JK
713 * read from the table
714 */
715
716 /* remove the table id from the ordinal */
717 ord &= IPW_ORD_TABLE_VALUE_MASK;
718
719 /* boundary check */
720 if (ord > priv->table0_len) {
721 IPW_DEBUG_ORD("ordinal value (%i) longer then "
722 "max (%i)\n", ord, priv->table0_len);
723 return -EINVAL;
724 }
725
726 /* verify we have enough room to store the value */
727 if (*len < sizeof(u32)) {
728 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 729 "need %zd\n", sizeof(u32));
43f66a6c
JK
730 return -EINVAL;
731 }
732
733 IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",
0edd5b44 734 ord, priv->table0_addr + (ord << 2));
43f66a6c
JK
735
736 *len = sizeof(u32);
737 ord <<= 2;
0edd5b44 738 *((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord);
43f66a6c
JK
739 break;
740
741 case IPW_ORD_TABLE_1_MASK:
742 /*
743 * TABLE 1: Indirect access to a table of 32 bit values
bf79451e
JG
744 *
745 * This is a fairly large table of u32 values each
43f66a6c
JK
746 * representing starting addr for the data (which is
747 * also a u32)
748 */
749
750 /* remove the table id from the ordinal */
751 ord &= IPW_ORD_TABLE_VALUE_MASK;
bf79451e 752
43f66a6c
JK
753 /* boundary check */
754 if (ord > priv->table1_len) {
755 IPW_DEBUG_ORD("ordinal value too long\n");
756 return -EINVAL;
757 }
758
759 /* verify we have enough room to store the value */
760 if (*len < sizeof(u32)) {
761 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 762 "need %zd\n", sizeof(u32));
43f66a6c
JK
763 return -EINVAL;
764 }
765
0edd5b44
JG
766 *((u32 *) val) =
767 ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));
43f66a6c
JK
768 *len = sizeof(u32);
769 break;
770
771 case IPW_ORD_TABLE_2_MASK:
772 /*
773 * TABLE 2: Indirect access to a table of variable sized values
774 *
775 * This table consist of six values, each containing
776 * - dword containing the starting offset of the data
777 * - dword containing the lengh in the first 16bits
778 * and the count in the second 16bits
779 */
780
781 /* remove the table id from the ordinal */
782 ord &= IPW_ORD_TABLE_VALUE_MASK;
783
784 /* boundary check */
785 if (ord > priv->table2_len) {
786 IPW_DEBUG_ORD("ordinal value too long\n");
787 return -EINVAL;
788 }
789
790 /* get the address of statistic */
791 addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));
bf79451e
JG
792
793 /* get the second DW of statistics ;
43f66a6c 794 * two 16-bit words - first is length, second is count */
0edd5b44
JG
795 field_info =
796 ipw_read_reg32(priv,
797 priv->table2_addr + (ord << 3) +
798 sizeof(u32));
bf79451e 799
43f66a6c 800 /* get each entry length */
0edd5b44 801 field_len = *((u16 *) & field_info);
bf79451e 802
43f66a6c 803 /* get number of entries */
0edd5b44 804 field_count = *(((u16 *) & field_info) + 1);
bf79451e 805
af901ca1 806 /* abort if not enough memory */
43f66a6c
JK
807 total_len = field_len * field_count;
808 if (total_len > *len) {
809 *len = total_len;
810 return -EINVAL;
811 }
bf79451e 812
43f66a6c
JK
813 *len = total_len;
814 if (!total_len)
815 return 0;
816
817 IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "
bf79451e 818 "field_info = 0x%08x\n",
43f66a6c
JK
819 addr, total_len, field_info);
820 ipw_read_indirect(priv, addr, val, total_len);
821 break;
822
823 default:
824 IPW_DEBUG_ORD("Invalid ordinal!\n");
825 return -EINVAL;
826
827 }
828
43f66a6c
JK
829 return 0;
830}
831
832static void ipw_init_ordinals(struct ipw_priv *priv)
833{
834 priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;
bf79451e 835 priv->table0_len = ipw_read32(priv, priv->table0_addr);
43f66a6c
JK
836
837 IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",
838 priv->table0_addr, priv->table0_len);
839
840 priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);
841 priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);
842
843 IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",
844 priv->table1_addr, priv->table1_len);
845
846 priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);
847 priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);
0edd5b44 848 priv->table2_len &= 0x0000ffff; /* use first two bytes */
43f66a6c
JK
849
850 IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",
851 priv->table2_addr, priv->table2_len);
852
853}
854
a73e22b2 855static u32 ipw_register_toggle(u32 reg)
a613bffd 856{
b095c381
JK
857 reg &= ~IPW_START_STANDBY;
858 if (reg & IPW_GATE_ODMA)
859 reg &= ~IPW_GATE_ODMA;
860 if (reg & IPW_GATE_IDMA)
861 reg &= ~IPW_GATE_IDMA;
862 if (reg & IPW_GATE_ADMA)
863 reg &= ~IPW_GATE_ADMA;
a613bffd
JK
864 return reg;
865}
866
867/*
868 * LED behavior:
869 * - On radio ON, turn on any LEDs that require to be on during start
870 * - On initialization, start unassociated blink
871 * - On association, disable unassociated blink
872 * - On disassociation, start unassociated blink
873 * - On radio OFF, turn off any LEDs started during radio on
874 *
875 */
ede6111c
ZY
876#define LD_TIME_LINK_ON msecs_to_jiffies(300)
877#define LD_TIME_LINK_OFF msecs_to_jiffies(2700)
878#define LD_TIME_ACT_ON msecs_to_jiffies(250)
a613bffd 879
a73e22b2 880static void ipw_led_link_on(struct ipw_priv *priv)
a613bffd
JK
881{
882 unsigned long flags;
883 u32 led;
884
885 /* If configured to not use LEDs, or nic_type is 1,
886 * then we don't toggle a LINK led */
887 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
888 return;
889
890 spin_lock_irqsave(&priv->lock, flags);
891
892 if (!(priv->status & STATUS_RF_KILL_MASK) &&
893 !(priv->status & STATUS_LED_LINK_ON)) {
894 IPW_DEBUG_LED("Link LED On\n");
b095c381 895 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
896 led |= priv->led_association_on;
897
898 led = ipw_register_toggle(led);
899
900 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 901 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
902
903 priv->status |= STATUS_LED_LINK_ON;
904
905 /* If we aren't associated, schedule turning the LED off */
906 if (!(priv->status & STATUS_ASSOCIATED))
bcb6d916
TH
907 schedule_delayed_work(&priv->led_link_off,
908 LD_TIME_LINK_ON);
a613bffd
JK
909 }
910
911 spin_unlock_irqrestore(&priv->lock, flags);
912}
913
c4028958 914static void ipw_bg_led_link_on(struct work_struct *work)
c848d0af 915{
c4028958
DH
916 struct ipw_priv *priv =
917 container_of(work, struct ipw_priv, led_link_on.work);
4644151b 918 mutex_lock(&priv->mutex);
c4028958 919 ipw_led_link_on(priv);
4644151b 920 mutex_unlock(&priv->mutex);
c848d0af
JK
921}
922
a73e22b2 923static void ipw_led_link_off(struct ipw_priv *priv)
a613bffd
JK
924{
925 unsigned long flags;
926 u32 led;
927
928 /* If configured not to use LEDs, or nic type is 1,
929 * then we don't goggle the LINK led. */
930 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
931 return;
932
933 spin_lock_irqsave(&priv->lock, flags);
934
935 if (priv->status & STATUS_LED_LINK_ON) {
b095c381 936 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
937 led &= priv->led_association_off;
938 led = ipw_register_toggle(led);
939
940 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 941 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
942
943 IPW_DEBUG_LED("Link LED Off\n");
944
945 priv->status &= ~STATUS_LED_LINK_ON;
946
947 /* If we aren't associated and the radio is on, schedule
948 * turning the LED on (blink while unassociated) */
949 if (!(priv->status & STATUS_RF_KILL_MASK) &&
950 !(priv->status & STATUS_ASSOCIATED))
bcb6d916
TH
951 schedule_delayed_work(&priv->led_link_on,
952 LD_TIME_LINK_OFF);
a613bffd
JK
953
954 }
955
956 spin_unlock_irqrestore(&priv->lock, flags);
957}
958
c4028958 959static void ipw_bg_led_link_off(struct work_struct *work)
c848d0af 960{
c4028958
DH
961 struct ipw_priv *priv =
962 container_of(work, struct ipw_priv, led_link_off.work);
4644151b 963 mutex_lock(&priv->mutex);
c4028958 964 ipw_led_link_off(priv);
4644151b 965 mutex_unlock(&priv->mutex);
c848d0af
JK
966}
967
858119e1 968static void __ipw_led_activity_on(struct ipw_priv *priv)
a613bffd 969{
a613bffd
JK
970 u32 led;
971
972 if (priv->config & CFG_NO_LED)
973 return;
974
b095c381 975 if (priv->status & STATUS_RF_KILL_MASK)
a613bffd 976 return;
a613bffd
JK
977
978 if (!(priv->status & STATUS_LED_ACT_ON)) {
b095c381 979 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
980 led |= priv->led_activity_on;
981
982 led = ipw_register_toggle(led);
983
984 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 985 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
986
987 IPW_DEBUG_LED("Activity LED On\n");
988
989 priv->status |= STATUS_LED_ACT_ON;
990
c848d0af 991 cancel_delayed_work(&priv->led_act_off);
bcb6d916 992 schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
a613bffd
JK
993 } else {
994 /* Reschedule LED off for full time period */
995 cancel_delayed_work(&priv->led_act_off);
bcb6d916 996 schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
a613bffd 997 }
b095c381 998}
a613bffd 999
a73e22b2 1000#if 0
b095c381
JK
1001void ipw_led_activity_on(struct ipw_priv *priv)
1002{
1003 unsigned long flags;
1004 spin_lock_irqsave(&priv->lock, flags);
1005 __ipw_led_activity_on(priv);
a613bffd
JK
1006 spin_unlock_irqrestore(&priv->lock, flags);
1007}
a73e22b2 1008#endif /* 0 */
a613bffd 1009
a73e22b2 1010static void ipw_led_activity_off(struct ipw_priv *priv)
a613bffd
JK
1011{
1012 unsigned long flags;
1013 u32 led;
1014
1015 if (priv->config & CFG_NO_LED)
1016 return;
1017
1018 spin_lock_irqsave(&priv->lock, flags);
1019
1020 if (priv->status & STATUS_LED_ACT_ON) {
b095c381 1021 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
1022 led &= priv->led_activity_off;
1023
1024 led = ipw_register_toggle(led);
1025
1026 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 1027 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
1028
1029 IPW_DEBUG_LED("Activity LED Off\n");
1030
1031 priv->status &= ~STATUS_LED_ACT_ON;
1032 }
1033
1034 spin_unlock_irqrestore(&priv->lock, flags);
1035}
1036
c4028958 1037static void ipw_bg_led_activity_off(struct work_struct *work)
c848d0af 1038{
c4028958
DH
1039 struct ipw_priv *priv =
1040 container_of(work, struct ipw_priv, led_act_off.work);
4644151b 1041 mutex_lock(&priv->mutex);
c4028958 1042 ipw_led_activity_off(priv);
4644151b 1043 mutex_unlock(&priv->mutex);
c848d0af
JK
1044}
1045
a73e22b2 1046static void ipw_led_band_on(struct ipw_priv *priv)
a613bffd
JK
1047{
1048 unsigned long flags;
1049 u32 led;
1050
1051 /* Only nic type 1 supports mode LEDs */
c848d0af
JK
1052 if (priv->config & CFG_NO_LED ||
1053 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
a613bffd
JK
1054 return;
1055
1056 spin_lock_irqsave(&priv->lock, flags);
1057
b095c381 1058 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
1059 if (priv->assoc_network->mode == IEEE_A) {
1060 led |= priv->led_ofdm_on;
1061 led &= priv->led_association_off;
1062 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
1063 } else if (priv->assoc_network->mode == IEEE_G) {
1064 led |= priv->led_ofdm_on;
1065 led |= priv->led_association_on;
1066 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
1067 } else {
1068 led &= priv->led_ofdm_off;
1069 led |= priv->led_association_on;
1070 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
1071 }
1072
1073 led = ipw_register_toggle(led);
1074
1075 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 1076 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
1077
1078 spin_unlock_irqrestore(&priv->lock, flags);
1079}
1080
a73e22b2 1081static void ipw_led_band_off(struct ipw_priv *priv)
a613bffd
JK
1082{
1083 unsigned long flags;
1084 u32 led;
1085
1086 /* Only nic type 1 supports mode LEDs */
1087 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
1088 return;
1089
1090 spin_lock_irqsave(&priv->lock, flags);
1091
b095c381 1092 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
1093 led &= priv->led_ofdm_off;
1094 led &= priv->led_association_off;
1095
1096 led = ipw_register_toggle(led);
1097
1098 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 1099 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
1100
1101 spin_unlock_irqrestore(&priv->lock, flags);
1102}
1103
a73e22b2 1104static void ipw_led_radio_on(struct ipw_priv *priv)
a613bffd
JK
1105{
1106 ipw_led_link_on(priv);
1107}
1108
a73e22b2 1109static void ipw_led_radio_off(struct ipw_priv *priv)
a613bffd
JK
1110{
1111 ipw_led_activity_off(priv);
1112 ipw_led_link_off(priv);
1113}
1114
a73e22b2 1115static void ipw_led_link_up(struct ipw_priv *priv)
a613bffd
JK
1116{
1117 /* Set the Link Led on for all nic types */
1118 ipw_led_link_on(priv);
1119}
1120
a73e22b2 1121static void ipw_led_link_down(struct ipw_priv *priv)
a613bffd
JK
1122{
1123 ipw_led_activity_off(priv);
1124 ipw_led_link_off(priv);
1125
1126 if (priv->status & STATUS_RF_KILL_MASK)
1127 ipw_led_radio_off(priv);
1128}
1129
a73e22b2 1130static void ipw_led_init(struct ipw_priv *priv)
a613bffd
JK
1131{
1132 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
1133
1134 /* Set the default PINs for the link and activity leds */
b095c381
JK
1135 priv->led_activity_on = IPW_ACTIVITY_LED;
1136 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
a613bffd 1137
b095c381
JK
1138 priv->led_association_on = IPW_ASSOCIATED_LED;
1139 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
a613bffd
JK
1140
1141 /* Set the default PINs for the OFDM leds */
b095c381
JK
1142 priv->led_ofdm_on = IPW_OFDM_LED;
1143 priv->led_ofdm_off = ~(IPW_OFDM_LED);
a613bffd
JK
1144
1145 switch (priv->nic_type) {
1146 case EEPROM_NIC_TYPE_1:
1147 /* In this NIC type, the LEDs are reversed.... */
b095c381
JK
1148 priv->led_activity_on = IPW_ASSOCIATED_LED;
1149 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
1150 priv->led_association_on = IPW_ACTIVITY_LED;
1151 priv->led_association_off = ~(IPW_ACTIVITY_LED);
a613bffd
JK
1152
1153 if (!(priv->config & CFG_NO_LED))
1154 ipw_led_band_on(priv);
1155
1156 /* And we don't blink link LEDs for this nic, so
1157 * just return here */
1158 return;
1159
1160 case EEPROM_NIC_TYPE_3:
1161 case EEPROM_NIC_TYPE_2:
1162 case EEPROM_NIC_TYPE_4:
1163 case EEPROM_NIC_TYPE_0:
1164 break;
1165
1166 default:
1167 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1168 priv->nic_type);
1169 priv->nic_type = EEPROM_NIC_TYPE_0;
1170 break;
1171 }
1172
1173 if (!(priv->config & CFG_NO_LED)) {
1174 if (priv->status & STATUS_ASSOCIATED)
1175 ipw_led_link_on(priv);
1176 else
1177 ipw_led_link_off(priv);
1178 }
1179}
1180
a73e22b2 1181static void ipw_led_shutdown(struct ipw_priv *priv)
a613bffd 1182{
a613bffd
JK
1183 ipw_led_activity_off(priv);
1184 ipw_led_link_off(priv);
1185 ipw_led_band_off(priv);
afbf30a2
JK
1186 cancel_delayed_work(&priv->led_link_on);
1187 cancel_delayed_work(&priv->led_link_off);
1188 cancel_delayed_work(&priv->led_act_off);
a613bffd
JK
1189}
1190
43f66a6c
JK
1191/*
1192 * The following adds a new attribute to the sysfs representation
1193 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
25985edc 1194 * used for controlling the debug level.
bf79451e 1195 *
43f66a6c
JK
1196 * See the level definitions in ipw for details.
1197 */
1198static ssize_t show_debug_level(struct device_driver *d, char *buf)
1199{
1200 return sprintf(buf, "0x%08X\n", ipw_debug_level);
1201}
a613bffd
JK
1202
1203static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1204 size_t count)
43f66a6c
JK
1205{
1206 char *p = (char *)buf;
1207 u32 val;
1208
1209 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1210 p++;
1211 if (p[0] == 'x' || p[0] == 'X')
1212 p++;
1213 val = simple_strtoul(p, &p, 16);
1214 } else
1215 val = simple_strtoul(p, &p, 10);
bf79451e
JG
1216 if (p == buf)
1217 printk(KERN_INFO DRV_NAME
43f66a6c
JK
1218 ": %s is not in hex or decimal form.\n", buf);
1219 else
1220 ipw_debug_level = val;
1221
1222 return strnlen(buf, count);
1223}
1224
bf79451e 1225static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
43f66a6c
JK
1226 show_debug_level, store_debug_level);
1227
b39860c6 1228static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
43f66a6c 1229{
c8fe6679 1230 /* length = 1st dword in log */
b39860c6 1231 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
43f66a6c 1232}
0edd5b44 1233
b39860c6
JK
1234static void ipw_capture_event_log(struct ipw_priv *priv,
1235 u32 log_len, struct ipw_event *log)
43f66a6c 1236{
b39860c6 1237 u32 base;
0edd5b44 1238
b39860c6
JK
1239 if (log_len) {
1240 base = ipw_read32(priv, IPW_EVENT_LOG);
1241 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
1242 (u8 *) log, sizeof(*log) * log_len);
1243 }
1244}
43f66a6c 1245
b39860c6 1246static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
43f66a6c 1247{
b39860c6
JK
1248 struct ipw_fw_error *error;
1249 u32 log_len = ipw_get_event_log_len(priv);
1250 u32 base = ipw_read32(priv, IPW_ERROR_LOG);
1251 u32 elem_len = ipw_read_reg32(priv, base);
43f66a6c 1252
b39860c6
JK
1253 error = kmalloc(sizeof(*error) +
1254 sizeof(*error->elem) * elem_len +
1255 sizeof(*error->log) * log_len, GFP_ATOMIC);
1256 if (!error) {
1257 IPW_ERROR("Memory allocation for firmware error log "
1258 "failed.\n");
1259 return NULL;
43f66a6c 1260 }
f6c5cb7c 1261 error->jiffies = jiffies;
b39860c6
JK
1262 error->status = priv->status;
1263 error->config = priv->config;
1264 error->elem_len = elem_len;
1265 error->log_len = log_len;
1266 error->elem = (struct ipw_error_elem *)error->payload;
3b26b110 1267 error->log = (struct ipw_event *)(error->elem + elem_len);
b39860c6
JK
1268
1269 ipw_capture_event_log(priv, log_len, error->log);
bf79451e 1270
b39860c6
JK
1271 if (elem_len)
1272 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
1273 sizeof(*error->elem) * elem_len);
1274
1275 return error;
43f66a6c 1276}
0edd5b44 1277
b39860c6
JK
1278static ssize_t show_event_log(struct device *d,
1279 struct device_attribute *attr, char *buf)
43f66a6c 1280{
b39860c6
JK
1281 struct ipw_priv *priv = dev_get_drvdata(d);
1282 u32 log_len = ipw_get_event_log_len(priv);
412e9e78
RC
1283 u32 log_size;
1284 struct ipw_event *log;
b39860c6 1285 u32 len = 0, i;
43f66a6c 1286
412e9e78
RC
1287 /* not using min() because of its strict type checking */
1288 log_size = PAGE_SIZE / sizeof(*log) > log_len ?
1289 sizeof(*log) * log_len : PAGE_SIZE;
1290 log = kzalloc(log_size, GFP_KERNEL);
1291 if (!log) {
1292 IPW_ERROR("Unable to allocate memory for log\n");
1293 return 0;
1294 }
1295 log_len = log_size / sizeof(*log);
b39860c6 1296 ipw_capture_event_log(priv, log_len, log);
43f66a6c 1297
b39860c6
JK
1298 len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1299 for (i = 0; i < log_len; i++)
1300 len += snprintf(buf + len, PAGE_SIZE - len,
1301 "\n%08X%08X%08X",
1302 log[i].time, log[i].event, log[i].data);
1303 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
412e9e78 1304 kfree(log);
b39860c6 1305 return len;
43f66a6c 1306}
0edd5b44 1307
b39860c6 1308static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
43f66a6c 1309
b39860c6
JK
1310static ssize_t show_error(struct device *d,
1311 struct device_attribute *attr, char *buf)
43f66a6c 1312{
b39860c6
JK
1313 struct ipw_priv *priv = dev_get_drvdata(d);
1314 u32 len = 0, i;
1315 if (!priv->error)
1316 return 0;
1317 len += snprintf(buf + len, PAGE_SIZE - len,
f6c5cb7c
JK
1318 "%08lX%08X%08X%08X",
1319 priv->error->jiffies,
b39860c6
JK
1320 priv->error->status,
1321 priv->error->config, priv->error->elem_len);
1322 for (i = 0; i < priv->error->elem_len; i++)
1323 len += snprintf(buf + len, PAGE_SIZE - len,
1324 "\n%08X%08X%08X%08X%08X%08X%08X",
1325 priv->error->elem[i].time,
1326 priv->error->elem[i].desc,
1327 priv->error->elem[i].blink1,
1328 priv->error->elem[i].blink2,
1329 priv->error->elem[i].link1,
1330 priv->error->elem[i].link2,
1331 priv->error->elem[i].data);
1332
1333 len += snprintf(buf + len, PAGE_SIZE - len,
1334 "\n%08X", priv->error->log_len);
1335 for (i = 0; i < priv->error->log_len; i++)
1336 len += snprintf(buf + len, PAGE_SIZE - len,
1337 "\n%08X%08X%08X",
1338 priv->error->log[i].time,
1339 priv->error->log[i].event,
1340 priv->error->log[i].data);
1341 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1342 return len;
1343}
1344
1345static ssize_t clear_error(struct device *d,
1346 struct device_attribute *attr,
1347 const char *buf, size_t count)
1348{
1349 struct ipw_priv *priv = dev_get_drvdata(d);
8f760780
JJ
1350
1351 kfree(priv->error);
1352 priv->error = NULL;
b39860c6
JK
1353 return count;
1354}
43f66a6c 1355
b39860c6 1356static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
43f66a6c 1357
f6c5cb7c
JK
1358static ssize_t show_cmd_log(struct device *d,
1359 struct device_attribute *attr, char *buf)
1360{
1361 struct ipw_priv *priv = dev_get_drvdata(d);
1362 u32 len = 0, i;
1363 if (!priv->cmdlog)
1364 return 0;
1365 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
1366 (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
1367 i = (i + 1) % priv->cmdlog_len) {
1368 len +=
1369 snprintf(buf + len, PAGE_SIZE - len,
1370 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
1371 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
1372 priv->cmdlog[i].cmd.len);
1373 len +=
1374 snprintk_buf(buf + len, PAGE_SIZE - len,
1375 (u8 *) priv->cmdlog[i].cmd.param,
1376 priv->cmdlog[i].cmd.len);
1377 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1378 }
1379 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1380 return len;
43f66a6c 1381}
0edd5b44 1382
f6c5cb7c 1383static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
43f66a6c 1384
d685b8c2
ZY
1385#ifdef CONFIG_IPW2200_PROMISCUOUS
1386static void ipw_prom_free(struct ipw_priv *priv);
1387static int ipw_prom_alloc(struct ipw_priv *priv);
1388static ssize_t store_rtap_iface(struct device *d,
1389 struct device_attribute *attr,
1390 const char *buf, size_t count)
1391{
1392 struct ipw_priv *priv = dev_get_drvdata(d);
1393 int rc = 0;
1394
1395 if (count < 1)
1396 return -EINVAL;
1397
1398 switch (buf[0]) {
1399 case '0':
1400 if (!rtap_iface)
1401 return count;
1402
1403 if (netif_running(priv->prom_net_dev)) {
1404 IPW_WARNING("Interface is up. Cannot unregister.\n");
1405 return count;
1406 }
1407
1408 ipw_prom_free(priv);
1409 rtap_iface = 0;
1410 break;
1411
1412 case '1':
1413 if (rtap_iface)
1414 return count;
1415
1416 rc = ipw_prom_alloc(priv);
1417 if (!rc)
1418 rtap_iface = 1;
1419 break;
1420
1421 default:
1422 return -EINVAL;
1423 }
1424
1425 if (rc) {
1426 IPW_ERROR("Failed to register promiscuous network "
1427 "device (error %d).\n", rc);
1428 }
1429
1430 return count;
1431}
1432
1433static ssize_t show_rtap_iface(struct device *d,
1434 struct device_attribute *attr,
1435 char *buf)
1436{
1437 struct ipw_priv *priv = dev_get_drvdata(d);
1438 if (rtap_iface)
1439 return sprintf(buf, "%s", priv->prom_net_dev->name);
1440 else {
1441 buf[0] = '-';
1442 buf[1] = '1';
1443 buf[2] = '\0';
1444 return 3;
1445 }
1446}
1447
1448static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface,
1449 store_rtap_iface);
1450
1451static ssize_t store_rtap_filter(struct device *d,
1452 struct device_attribute *attr,
1453 const char *buf, size_t count)
1454{
1455 struct ipw_priv *priv = dev_get_drvdata(d);
1456
1457 if (!priv->prom_priv) {
1458 IPW_ERROR("Attempting to set filter without "
1459 "rtap_iface enabled.\n");
1460 return -EPERM;
1461 }
1462
1463 priv->prom_priv->filter = simple_strtol(buf, NULL, 0);
1464
1465 IPW_DEBUG_INFO("Setting rtap filter to " BIT_FMT16 "\n",
1466 BIT_ARG16(priv->prom_priv->filter));
1467
1468 return count;
1469}
1470
1471static ssize_t show_rtap_filter(struct device *d,
1472 struct device_attribute *attr,
1473 char *buf)
1474{
1475 struct ipw_priv *priv = dev_get_drvdata(d);
1476 return sprintf(buf, "0x%04X",
1477 priv->prom_priv ? priv->prom_priv->filter : 0);
1478}
1479
1480static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter,
1481 store_rtap_filter);
1482#endif
1483
a613bffd
JK
1484static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
1485 char *buf)
43f66a6c 1486{
a613bffd
JK
1487 struct ipw_priv *priv = dev_get_drvdata(d);
1488 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1489}
1490
1491static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
1492 const char *buf, size_t count)
1493{
1494 struct ipw_priv *priv = dev_get_drvdata(d);
1495 struct net_device *dev = priv->net_dev;
1496 char buffer[] = "00000000";
1497 unsigned long len =
1498 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1499 unsigned long val;
1500 char *p = buffer;
1501
1502 IPW_DEBUG_INFO("enter\n");
1503
1504 strncpy(buffer, buf, len);
1505 buffer[len] = 0;
1506
1507 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1508 p++;
1509 if (p[0] == 'x' || p[0] == 'X')
1510 p++;
1511 val = simple_strtoul(p, &p, 16);
1512 } else
1513 val = simple_strtoul(p, &p, 10);
1514 if (p == buffer) {
1515 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1516 } else {
1517 priv->ieee->scan_age = val;
1518 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1519 }
1520
1521 IPW_DEBUG_INFO("exit\n");
1522 return len;
1523}
1524
1525static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
1526
1527static ssize_t show_led(struct device *d, struct device_attribute *attr,
1528 char *buf)
1529{
1530 struct ipw_priv *priv = dev_get_drvdata(d);
1531 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1532}
1533
1534static ssize_t store_led(struct device *d, struct device_attribute *attr,
1535 const char *buf, size_t count)
1536{
1537 struct ipw_priv *priv = dev_get_drvdata(d);
1538
1539 IPW_DEBUG_INFO("enter\n");
1540
1541 if (count == 0)
1542 return 0;
1543
1544 if (*buf == 0) {
1545 IPW_DEBUG_LED("Disabling LED control.\n");
1546 priv->config |= CFG_NO_LED;
1547 ipw_led_shutdown(priv);
1548 } else {
1549 IPW_DEBUG_LED("Enabling LED control.\n");
1550 priv->config &= ~CFG_NO_LED;
1551 ipw_led_init(priv);
1552 }
1553
1554 IPW_DEBUG_INFO("exit\n");
1555 return count;
1556}
1557
1558static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1559
ad3fee56 1560static ssize_t show_status(struct device *d,
0edd5b44 1561 struct device_attribute *attr, char *buf)
43f66a6c 1562{
928841b1 1563 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c
JK
1564 return sprintf(buf, "0x%08x\n", (int)p->status);
1565}
0edd5b44 1566
43f66a6c
JK
1567static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1568
ad3fee56
AM
1569static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1570 char *buf)
43f66a6c 1571{
928841b1 1572 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c
JK
1573 return sprintf(buf, "0x%08x\n", (int)p->config);
1574}
0edd5b44 1575
43f66a6c
JK
1576static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1577
ad3fee56 1578static ssize_t show_nic_type(struct device *d,
0edd5b44 1579 struct device_attribute *attr, char *buf)
43f66a6c 1580{
928841b1 1581 struct ipw_priv *priv = dev_get_drvdata(d);
a613bffd 1582 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
43f66a6c 1583}
0edd5b44 1584
43f66a6c
JK
1585static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
1586
ad3fee56 1587static ssize_t show_ucode_version(struct device *d,
0edd5b44 1588 struct device_attribute *attr, char *buf)
43f66a6c
JK
1589{
1590 u32 len = sizeof(u32), tmp = 0;
928841b1 1591 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c 1592
0edd5b44 1593 if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
43f66a6c
JK
1594 return 0;
1595
1596 return sprintf(buf, "0x%08x\n", tmp);
1597}
0edd5b44
JG
1598
1599static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL);
43f66a6c 1600
ad3fee56
AM
1601static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
1602 char *buf)
43f66a6c
JK
1603{
1604 u32 len = sizeof(u32), tmp = 0;
928841b1 1605 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c 1606
0edd5b44 1607 if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
43f66a6c
JK
1608 return 0;
1609
1610 return sprintf(buf, "0x%08x\n", tmp);
1611}
0edd5b44
JG
1612
1613static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
43f66a6c
JK
1614
1615/*
1616 * Add a device attribute to view/control the delay between eeprom
1617 * operations.
1618 */
ad3fee56 1619static ssize_t show_eeprom_delay(struct device *d,
0edd5b44 1620 struct device_attribute *attr, char *buf)
43f66a6c 1621{
928841b1
GKH
1622 struct ipw_priv *p = dev_get_drvdata(d);
1623 int n = p->eeprom_delay;
43f66a6c
JK
1624 return sprintf(buf, "%i\n", n);
1625}
ad3fee56 1626static ssize_t store_eeprom_delay(struct device *d,
0edd5b44
JG
1627 struct device_attribute *attr,
1628 const char *buf, size_t count)
43f66a6c 1629{
928841b1 1630 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c
JK
1631 sscanf(buf, "%i", &p->eeprom_delay);
1632 return strnlen(buf, count);
1633}
0edd5b44
JG
1634
1635static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO,
1636 show_eeprom_delay, store_eeprom_delay);
43f66a6c 1637
ad3fee56 1638static ssize_t show_command_event_reg(struct device *d,
0edd5b44 1639 struct device_attribute *attr, char *buf)
43f66a6c
JK
1640{
1641 u32 reg = 0;
928841b1 1642 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c 1643
b095c381 1644 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
43f66a6c
JK
1645 return sprintf(buf, "0x%08x\n", reg);
1646}
ad3fee56 1647static ssize_t store_command_event_reg(struct device *d,
0edd5b44
JG
1648 struct device_attribute *attr,
1649 const char *buf, size_t count)
43f66a6c
JK
1650{
1651 u32 reg;
928841b1 1652 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c
JK
1653
1654 sscanf(buf, "%x", &reg);
b095c381 1655 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
43f66a6c
JK
1656 return strnlen(buf, count);
1657}
0edd5b44
JG
1658
1659static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO,
1660 show_command_event_reg, store_command_event_reg);
43f66a6c 1661
ad3fee56 1662static ssize_t show_mem_gpio_reg(struct device *d,
0edd5b44 1663 struct device_attribute *attr, char *buf)
43f66a6c
JK
1664{
1665 u32 reg = 0;
928841b1 1666 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c
JK
1667
1668 reg = ipw_read_reg32(p, 0x301100);
1669 return sprintf(buf, "0x%08x\n", reg);
1670}
ad3fee56 1671static ssize_t store_mem_gpio_reg(struct device *d,
0edd5b44
JG
1672 struct device_attribute *attr,
1673 const char *buf, size_t count)
43f66a6c
JK
1674{
1675 u32 reg;
928841b1 1676 struct ipw_priv *p = dev_get_drvdata(d);
43f66a6c
JK
1677
1678 sscanf(buf, "%x", &reg);
1679 ipw_write_reg32(p, 0x301100, reg);
1680 return strnlen(buf, count);
1681}
0edd5b44
JG
1682
1683static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO,
1684 show_mem_gpio_reg, store_mem_gpio_reg);
43f66a6c 1685
ad3fee56 1686static ssize_t show_indirect_dword(struct device *d,
0edd5b44 1687 struct device_attribute *attr, char *buf)
43f66a6c
JK
1688{
1689 u32 reg = 0;
928841b1 1690 struct ipw_priv *priv = dev_get_drvdata(d);
afbf30a2 1691
bf79451e 1692 if (priv->status & STATUS_INDIRECT_DWORD)
43f66a6c 1693 reg = ipw_read_reg32(priv, priv->indirect_dword);
bf79451e 1694 else
43f66a6c 1695 reg = 0;
bf79451e 1696
43f66a6c
JK
1697 return sprintf(buf, "0x%08x\n", reg);
1698}
ad3fee56 1699static ssize_t store_indirect_dword(struct device *d,
0edd5b44
JG
1700 struct device_attribute *attr,
1701 const char *buf, size_t count)
43f66a6c 1702{
928841b1 1703 struct ipw_priv *priv = dev_get_drvdata(d);
43f66a6c
JK
1704
1705 sscanf(buf, "%x", &priv->indirect_dword);
1706 priv->status |= STATUS_INDIRECT_DWORD;
1707 return strnlen(buf, count);
1708}
0edd5b44
JG
1709
1710static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO,
1711 show_indirect_dword, store_indirect_dword);
43f66a6c 1712
ad3fee56 1713static ssize_t show_indirect_byte(struct device *d,
0edd5b44 1714 struct device_attribute *attr, char *buf)
43f66a6c
JK
1715{
1716 u8 reg = 0;
928841b1 1717 struct ipw_priv *priv = dev_get_drvdata(d);
afbf30a2 1718
bf79451e 1719 if (priv->status & STATUS_INDIRECT_BYTE)
43f66a6c 1720 reg = ipw_read_reg8(priv, priv->indirect_byte);
bf79451e 1721 else
43f66a6c
JK
1722 reg = 0;
1723
1724 return sprintf(buf, "0x%02x\n", reg);
1725}
ad3fee56 1726static ssize_t store_indirect_byte(struct device *d,
0edd5b44
JG
1727 struct device_attribute *attr,
1728 const char *buf, size_t count)
43f66a6c 1729{
928841b1 1730 struct ipw_priv *priv = dev_get_drvdata(d);
43f66a6c
JK
1731
1732 sscanf(buf, "%x", &priv->indirect_byte);
1733 priv->status |= STATUS_INDIRECT_BYTE;
1734 return strnlen(buf, count);
1735}
0edd5b44
JG
1736
1737static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO,
43f66a6c
JK
1738 show_indirect_byte, store_indirect_byte);
1739
ad3fee56 1740static ssize_t show_direct_dword(struct device *d,
0edd5b44 1741 struct device_attribute *attr, char *buf)
43f66a6c
JK
1742{
1743 u32 reg = 0;
928841b1 1744 struct ipw_priv *priv = dev_get_drvdata(d);
43f66a6c 1745
bf79451e 1746 if (priv->status & STATUS_DIRECT_DWORD)
43f66a6c 1747 reg = ipw_read32(priv, priv->direct_dword);
bf79451e 1748 else
43f66a6c
JK
1749 reg = 0;
1750
1751 return sprintf(buf, "0x%08x\n", reg);
1752}
ad3fee56 1753static ssize_t store_direct_dword(struct device *d,
0edd5b44
JG
1754 struct device_attribute *attr,
1755 const char *buf, size_t count)
43f66a6c 1756{
928841b1 1757 struct ipw_priv *priv = dev_get_drvdata(d);
43f66a6c
JK
1758
1759 sscanf(buf, "%x", &priv->direct_dword);
1760 priv->status |= STATUS_DIRECT_DWORD;
1761 return strnlen(buf, count);
1762}
43f66a6c 1763
0edd5b44
JG
1764static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO,
1765 show_direct_dword, store_direct_dword);
43f66a6c 1766
858119e1 1767static int rf_kill_active(struct ipw_priv *priv)
43f66a6c 1768{
25f94aea 1769 if (0 == (ipw_read32(priv, 0x30) & 0x10000)) {
43f66a6c 1770 priv->status |= STATUS_RF_KILL_HW;
25f94aea
MG
1771 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
1772 } else {
43f66a6c 1773 priv->status &= ~STATUS_RF_KILL_HW;
25f94aea
MG
1774 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
1775 }
43f66a6c
JK
1776
1777 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
1778}
1779
ad3fee56 1780static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
0edd5b44 1781 char *buf)
43f66a6c
JK
1782{
1783 /* 0 - RF kill not enabled
bf79451e 1784 1 - SW based RF kill active (sysfs)
43f66a6c
JK
1785 2 - HW based RF kill active
1786 3 - Both HW and SW baed RF kill active */
928841b1 1787 struct ipw_priv *priv = dev_get_drvdata(d);
43f66a6c 1788 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
0edd5b44 1789 (rf_kill_active(priv) ? 0x2 : 0x0);
43f66a6c
JK
1790 return sprintf(buf, "%i\n", val);
1791}
1792
1793static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
1794{
bf79451e 1795 if ((disable_radio ? 1 : 0) ==
ea2b26e0 1796 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
0edd5b44 1797 return 0;
43f66a6c
JK
1798
1799 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
1800 disable_radio ? "OFF" : "ON");
1801
1802 if (disable_radio) {
1803 priv->status |= STATUS_RF_KILL_SW;
1804
bcb6d916
TH
1805 cancel_delayed_work(&priv->request_scan);
1806 cancel_delayed_work(&priv->request_direct_scan);
1807 cancel_delayed_work(&priv->request_passive_scan);
1808 cancel_delayed_work(&priv->scan_event);
1809 schedule_work(&priv->down);
43f66a6c
JK
1810 } else {
1811 priv->status &= ~STATUS_RF_KILL_SW;
1812 if (rf_kill_active(priv)) {
1813 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
1814 "disabled by HW switch\n");
1815 /* Make sure the RF_KILL check timer is running */
1816 cancel_delayed_work(&priv->rf_kill);
bcb6d916
TH
1817 schedule_delayed_work(&priv->rf_kill,
1818 round_jiffies_relative(2 * HZ));
bf79451e 1819 } else
bcb6d916 1820 schedule_work(&priv->up);
43f66a6c
JK
1821 }
1822
1823 return 1;
1824}
1825
0edd5b44
JG
1826static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
1827 const char *buf, size_t count)
43f66a6c 1828{
928841b1 1829 struct ipw_priv *priv = dev_get_drvdata(d);
bf79451e 1830
43f66a6c
JK
1831 ipw_radio_kill_sw(priv, buf[0] == '1');
1832
1833 return count;
1834}
0edd5b44
JG
1835
1836static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
43f66a6c 1837
b095c381
JK
1838static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1839 char *buf)
1840{
928841b1 1841 struct ipw_priv *priv = dev_get_drvdata(d);
b095c381
JK
1842 int pos = 0, len = 0;
1843 if (priv->config & CFG_SPEED_SCAN) {
1844 while (priv->speed_scan[pos] != 0)
1845 len += sprintf(&buf[len], "%d ",
1846 priv->speed_scan[pos++]);
1847 return len + sprintf(&buf[len], "\n");
1848 }
1849
1850 return sprintf(buf, "0\n");
1851}
1852
1853static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1854 const char *buf, size_t count)
1855{
928841b1 1856 struct ipw_priv *priv = dev_get_drvdata(d);
b095c381
JK
1857 int channel, pos = 0;
1858 const char *p = buf;
1859
1860 /* list of space separated channels to scan, optionally ending with 0 */
1861 while ((channel = simple_strtol(p, NULL, 0))) {
1862 if (pos == MAX_SPEED_SCAN - 1) {
1863 priv->speed_scan[pos] = 0;
1864 break;
1865 }
1866
b0a4e7d8 1867 if (libipw_is_valid_channel(priv->ieee, channel))
b095c381
JK
1868 priv->speed_scan[pos++] = channel;
1869 else
1870 IPW_WARNING("Skipping invalid channel request: %d\n",
1871 channel);
1872 p = strchr(p, ' ');
1873 if (!p)
1874 break;
1875 while (*p == ' ' || *p == '\t')
1876 p++;
1877 }
1878
1879 if (pos == 0)
1880 priv->config &= ~CFG_SPEED_SCAN;
1881 else {
1882 priv->speed_scan_pos = 0;
1883 priv->config |= CFG_SPEED_SCAN;
1884 }
1885
1886 return count;
1887}
1888
1889static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1890 store_speed_scan);
1891
1892static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1893 char *buf)
1894{
928841b1 1895 struct ipw_priv *priv = dev_get_drvdata(d);
b095c381
JK
1896 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1897}
1898
1899static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1900 const char *buf, size_t count)
1901{
928841b1 1902 struct ipw_priv *priv = dev_get_drvdata(d);
b095c381
JK
1903 if (buf[0] == '1')
1904 priv->config |= CFG_NET_STATS;
1905 else
1906 priv->config &= ~CFG_NET_STATS;
1907
1908 return count;
1909}
1910
afbf30a2
JK
1911static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1912 show_net_stats, store_net_stats);
b095c381 1913
375dd244
ZY
1914static ssize_t show_channels(struct device *d,
1915 struct device_attribute *attr,
1916 char *buf)
1917{
1918 struct ipw_priv *priv = dev_get_drvdata(d);
b0a4e7d8 1919 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
375dd244
ZY
1920 int len = 0, i;
1921
1922 len = sprintf(&buf[len],
1923 "Displaying %d channels in 2.4Ghz band "
1924 "(802.11bg):\n", geo->bg_channels);
1925
1926 for (i = 0; i < geo->bg_channels; i++) {
1927 len += sprintf(&buf[len], "%d: BSS%s%s, %s, Band %s.\n",
1928 geo->bg[i].channel,
b0a4e7d8 1929 geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT ?
375dd244 1930 " (radar spectrum)" : "",
b0a4e7d8
JL
1931 ((geo->bg[i].flags & LIBIPW_CH_NO_IBSS) ||
1932 (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT))
375dd244 1933 ? "" : ", IBSS",
b0a4e7d8 1934 geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY ?
375dd244 1935 "passive only" : "active/passive",
b0a4e7d8 1936 geo->bg[i].flags & LIBIPW_CH_B_ONLY ?
375dd244
ZY
1937 "B" : "B/G");
1938 }
1939
1940 len += sprintf(&buf[len],
1941 "Displaying %d channels in 5.2Ghz band "
1942 "(802.11a):\n", geo->a_channels);
1943 for (i = 0; i < geo->a_channels; i++) {
1944 len += sprintf(&buf[len], "%d: BSS%s%s, %s.\n",
1945 geo->a[i].channel,
b0a4e7d8 1946 geo->a[i].flags & LIBIPW_CH_RADAR_DETECT ?
375dd244 1947 " (radar spectrum)" : "",
b0a4e7d8
JL
1948 ((geo->a[i].flags & LIBIPW_CH_NO_IBSS) ||
1949 (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT))
375dd244 1950 ? "" : ", IBSS",
b0a4e7d8 1951 geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY ?
375dd244
ZY
1952 "passive only" : "active/passive");
1953 }
1954
1955 return len;
1956}
1957
1958static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
1959
ea2b26e0
JK
1960static void notify_wx_assoc_event(struct ipw_priv *priv)
1961{
1962 union iwreq_data wrqu;
1963 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1964 if (priv->status & STATUS_ASSOCIATED)
1965 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1966 else
1967 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1968 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1969}
1970
43f66a6c
JK
1971static void ipw_irq_tasklet(struct ipw_priv *priv)
1972{
1973 u32 inta, inta_mask, handled = 0;
1974 unsigned long flags;
1975 int rc = 0;
1976
89c318ed 1977 spin_lock_irqsave(&priv->irq_lock, flags);
43f66a6c 1978
b095c381
JK
1979 inta = ipw_read32(priv, IPW_INTA_RW);
1980 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
3c4a8cc4
IZ
1981
1982 if (inta == 0xFFFFFFFF) {
1983 /* Hardware disappeared */
1984 IPW_WARNING("TASKLET INTA == 0xFFFFFFFF\n");
1985 /* Only handle the cached INTA values */
1986 inta = 0;
1987 }
b095c381 1988 inta &= (IPW_INTA_MASK_ALL & inta_mask);
43f66a6c
JK
1989
1990 /* Add any cached INTA values that need to be handled */
1991 inta |= priv->isr_inta;
1992
89c318ed
ZY
1993 spin_unlock_irqrestore(&priv->irq_lock, flags);
1994
1995 spin_lock_irqsave(&priv->lock, flags);
1996
43f66a6c 1997 /* handle all the justifications for the interrupt */
b095c381 1998 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
43f66a6c 1999 ipw_rx(priv);
b095c381 2000 handled |= IPW_INTA_BIT_RX_TRANSFER;
43f66a6c
JK
2001 }
2002
b095c381 2003 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
43f66a6c 2004 IPW_DEBUG_HC("Command completed.\n");
0edd5b44 2005 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
43f66a6c
JK
2006 priv->status &= ~STATUS_HCMD_ACTIVE;
2007 wake_up_interruptible(&priv->wait_command_queue);
b095c381 2008 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
43f66a6c
JK
2009 }
2010
b095c381 2011 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
43f66a6c 2012 IPW_DEBUG_TX("TX_QUEUE_1\n");
0edd5b44 2013 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
b095c381 2014 handled |= IPW_INTA_BIT_TX_QUEUE_1;
43f66a6c
JK
2015 }
2016
b095c381 2017 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
43f66a6c 2018 IPW_DEBUG_TX("TX_QUEUE_2\n");
0edd5b44 2019 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
b095c381 2020 handled |= IPW_INTA_BIT_TX_QUEUE_2;
43f66a6c
JK
2021 }
2022
b095c381 2023 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
43f66a6c 2024 IPW_DEBUG_TX("TX_QUEUE_3\n");
0edd5b44 2025 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
b095c381 2026 handled |= IPW_INTA_BIT_TX_QUEUE_3;
43f66a6c
JK
2027 }
2028
b095c381 2029 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
43f66a6c 2030 IPW_DEBUG_TX("TX_QUEUE_4\n");
0edd5b44 2031 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
b095c381 2032 handled |= IPW_INTA_BIT_TX_QUEUE_4;
43f66a6c
JK
2033 }
2034
b095c381 2035 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
43f66a6c 2036 IPW_WARNING("STATUS_CHANGE\n");
b095c381 2037 handled |= IPW_INTA_BIT_STATUS_CHANGE;
43f66a6c
JK
2038 }
2039
b095c381 2040 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
43f66a6c 2041 IPW_WARNING("TX_PERIOD_EXPIRED\n");
b095c381 2042 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
43f66a6c
JK
2043 }
2044
b095c381 2045 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
43f66a6c 2046 IPW_WARNING("HOST_CMD_DONE\n");
b095c381 2047 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
43f66a6c
JK
2048 }
2049
b095c381 2050 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
43f66a6c 2051 IPW_WARNING("FW_INITIALIZATION_DONE\n");
b095c381 2052 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
43f66a6c
JK
2053 }
2054
b095c381 2055 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
43f66a6c 2056 IPW_WARNING("PHY_OFF_DONE\n");
b095c381 2057 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
43f66a6c
JK
2058 }
2059
b095c381 2060 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
43f66a6c
JK
2061 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
2062 priv->status |= STATUS_RF_KILL_HW;
25f94aea 2063 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
43f66a6c 2064 wake_up_interruptible(&priv->wait_command_queue);
ea2b26e0 2065 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
43f66a6c 2066 cancel_delayed_work(&priv->request_scan);
ea177305
DW
2067 cancel_delayed_work(&priv->request_direct_scan);
2068 cancel_delayed_work(&priv->request_passive_scan);
0b531676 2069 cancel_delayed_work(&priv->scan_event);
a613bffd 2070 schedule_work(&priv->link_down);
bcb6d916 2071 schedule_delayed_work(&priv->rf_kill, 2 * HZ);
b095c381 2072 handled |= IPW_INTA_BIT_RF_KILL_DONE;
43f66a6c 2073 }
bf79451e 2074
b095c381 2075 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
1d1b09eb 2076 IPW_WARNING("Firmware error detected. Restarting.\n");
b39860c6 2077 if (priv->error) {
1d1b09eb 2078 IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");
b39860c6
JK
2079 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
2080 struct ipw_fw_error *error =
2081 ipw_alloc_error_log(priv);
2082 ipw_dump_error_log(priv, error);
8f760780 2083 kfree(error);
b39860c6 2084 }
b39860c6
JK
2085 } else {
2086 priv->error = ipw_alloc_error_log(priv);
2087 if (priv->error)
1d1b09eb 2088 IPW_DEBUG_FW("Sysfs 'error' log captured.\n");
b39860c6 2089 else
1d1b09eb
ZY
2090 IPW_DEBUG_FW("Error allocating sysfs 'error' "
2091 "log.\n");
b39860c6
JK
2092 if (ipw_debug_level & IPW_DL_FW_ERRORS)
2093 ipw_dump_error_log(priv, priv->error);
b39860c6
JK
2094 }
2095
b095c381
JK
2096 /* XXX: If hardware encryption is for WPA/WPA2,
2097 * we have to notify the supplicant. */
2098 if (priv->ieee->sec.encrypt) {
2099 priv->status &= ~STATUS_ASSOCIATED;
2100 notify_wx_assoc_event(priv);
2101 }
2102
2103 /* Keep the restart process from trying to send host
2104 * commands by clearing the INIT status bit */
2105 priv->status &= ~STATUS_INIT;
afbf30a2
JK
2106
2107 /* Cancel currently queued command. */
2108 priv->status &= ~STATUS_HCMD_ACTIVE;
2109 wake_up_interruptible(&priv->wait_command_queue);
2110
bcb6d916 2111 schedule_work(&priv->adapter_restart);
b095c381 2112 handled |= IPW_INTA_BIT_FATAL_ERROR;
43f66a6c
JK
2113 }
2114
b095c381 2115 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
43f66a6c 2116 IPW_ERROR("Parity error\n");
b095c381 2117 handled |= IPW_INTA_BIT_PARITY_ERROR;
43f66a6c
JK
2118 }
2119
2120 if (handled != inta) {
0edd5b44 2121 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
43f66a6c
JK
2122 }
2123
89c318ed
ZY
2124 spin_unlock_irqrestore(&priv->lock, flags);
2125
43f66a6c
JK
2126 /* enable all interrupts */
2127 ipw_enable_interrupts(priv);
43f66a6c 2128}
bf79451e 2129
43f66a6c
JK
2130#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
2131static char *get_cmd_string(u8 cmd)
2132{
2133 switch (cmd) {
2134 IPW_CMD(HOST_COMPLETE);
bf79451e
JG
2135 IPW_CMD(POWER_DOWN);
2136 IPW_CMD(SYSTEM_CONFIG);
2137 IPW_CMD(MULTICAST_ADDRESS);
2138 IPW_CMD(SSID);
2139 IPW_CMD(ADAPTER_ADDRESS);
2140 IPW_CMD(PORT_TYPE);
2141 IPW_CMD(RTS_THRESHOLD);
2142 IPW_CMD(FRAG_THRESHOLD);
2143 IPW_CMD(POWER_MODE);
2144 IPW_CMD(WEP_KEY);
2145 IPW_CMD(TGI_TX_KEY);
2146 IPW_CMD(SCAN_REQUEST);
2147 IPW_CMD(SCAN_REQUEST_EXT);
2148 IPW_CMD(ASSOCIATE);
2149 IPW_CMD(SUPPORTED_RATES);
2150 IPW_CMD(SCAN_ABORT);
2151 IPW_CMD(TX_FLUSH);
2152 IPW_CMD(QOS_PARAMETERS);
2153 IPW_CMD(DINO_CONFIG);
2154 IPW_CMD(RSN_CAPABILITIES);
2155 IPW_CMD(RX_KEY);
2156 IPW_CMD(CARD_DISABLE);
2157 IPW_CMD(SEED_NUMBER);
2158 IPW_CMD(TX_POWER);
2159 IPW_CMD(COUNTRY_INFO);
2160 IPW_CMD(AIRONET_INFO);
2161 IPW_CMD(AP_TX_POWER);
2162 IPW_CMD(CCKM_INFO);
2163 IPW_CMD(CCX_VER_INFO);
2164 IPW_CMD(SET_CALIBRATION);
2165 IPW_CMD(SENSITIVITY_CALIB);
2166 IPW_CMD(RETRY_LIMIT);
2167 IPW_CMD(IPW_PRE_POWER_DOWN);
2168 IPW_CMD(VAP_BEACON_TEMPLATE);
2169 IPW_CMD(VAP_DTIM_PERIOD);
2170 IPW_CMD(EXT_SUPPORTED_RATES);
2171 IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);
2172 IPW_CMD(VAP_QUIET_INTERVALS);
2173 IPW_CMD(VAP_CHANNEL_SWITCH);
2174 IPW_CMD(VAP_MANDATORY_CHANNELS);
2175 IPW_CMD(VAP_CELL_PWR_LIMIT);
2176 IPW_CMD(VAP_CF_PARAM_SET);
2177 IPW_CMD(VAP_SET_BEACONING_STATE);
2178 IPW_CMD(MEASUREMENT);
2179 IPW_CMD(POWER_CAPABILITY);
2180 IPW_CMD(SUPPORTED_CHANNELS);
2181 IPW_CMD(TPC_REPORT);
2182 IPW_CMD(WME_INFO);
2183 IPW_CMD(PRODUCTION_COMMAND);
2184 default:
43f66a6c
JK
2185 return "UNKNOWN";
2186 }
2187}
43f66a6c
JK
2188
2189#define HOST_COMPLETE_TIMEOUT HZ
0a7bcf26
ZY
2190
2191static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
43f66a6c
JK
2192{
2193 int rc = 0;
a613bffd 2194 unsigned long flags;
dd447319 2195 unsigned long now, end;
43f66a6c 2196
a613bffd 2197 spin_lock_irqsave(&priv->lock, flags);
43f66a6c 2198 if (priv->status & STATUS_HCMD_ACTIVE) {
9ddf84f6
JK
2199 IPW_ERROR("Failed to send %s: Already sending a command.\n",
2200 get_cmd_string(cmd->cmd));
a613bffd 2201 spin_unlock_irqrestore(&priv->lock, flags);
9ddf84f6 2202 return -EAGAIN;
43f66a6c
JK
2203 }
2204
2205 priv->status |= STATUS_HCMD_ACTIVE;
bf79451e 2206
f6c5cb7c
JK
2207 if (priv->cmdlog) {
2208 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
2209 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
2210 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
2211 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
2212 cmd->len);
2213 priv->cmdlog[priv->cmdlog_pos].retcode = -1;
2214 }
2215
b095c381
JK
2216 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
2217 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
2218 priv->status);
f516dbcd
ZY
2219
2220#ifndef DEBUG_CMD_WEP_KEY
2221 if (cmd->cmd == IPW_CMD_WEP_KEY)
2222 IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n");
2223 else
2224#endif
2225 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
2226
0a7bcf26 2227 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0);
a613bffd
JK
2228 if (rc) {
2229 priv->status &= ~STATUS_HCMD_ACTIVE;
9ddf84f6
JK
2230 IPW_ERROR("Failed to send %s: Reason %d\n",
2231 get_cmd_string(cmd->cmd), rc);
a613bffd 2232 spin_unlock_irqrestore(&priv->lock, flags);
f6c5cb7c 2233 goto exit;
a613bffd
JK
2234 }
2235 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 2236
dd447319
SY
2237 now = jiffies;
2238 end = now + HOST_COMPLETE_TIMEOUT;
2239again:
0edd5b44
JG
2240 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
2241 !(priv->
2242 status & STATUS_HCMD_ACTIVE),
dd447319
SY
2243 end - now);
2244 if (rc < 0) {
2245 now = jiffies;
2246 if (time_before(now, end))
2247 goto again;
2248 rc = 0;
2249 }
2250
43f66a6c 2251 if (rc == 0) {
a613bffd
JK
2252 spin_lock_irqsave(&priv->lock, flags);
2253 if (priv->status & STATUS_HCMD_ACTIVE) {
9ddf84f6
JK
2254 IPW_ERROR("Failed to send %s: Command timed out.\n",
2255 get_cmd_string(cmd->cmd));
a613bffd
JK
2256 priv->status &= ~STATUS_HCMD_ACTIVE;
2257 spin_unlock_irqrestore(&priv->lock, flags);
f6c5cb7c
JK
2258 rc = -EIO;
2259 goto exit;
a613bffd
JK
2260 }
2261 spin_unlock_irqrestore(&priv->lock, flags);
3b9990cb
JK
2262 } else
2263 rc = 0;
a613bffd 2264
b095c381 2265 if (priv->status & STATUS_RF_KILL_HW) {
9ddf84f6
JK
2266 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
2267 get_cmd_string(cmd->cmd));
f6c5cb7c
JK
2268 rc = -EIO;
2269 goto exit;
43f66a6c
JK
2270 }
2271
2638bc39 2272 exit:
f6c5cb7c
JK
2273 if (priv->cmdlog) {
2274 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
2275 priv->cmdlog_pos %= priv->cmdlog_len;
2276 }
2277 return rc;
43f66a6c
JK
2278}
2279
0a7bcf26
ZY
2280static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command)
2281{
2282 struct host_cmd cmd = {
2283 .cmd = command,
2284 };
2285
2286 return __ipw_send_cmd(priv, &cmd);
2287}
2288
2289static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len,
2290 void *data)
43f66a6c
JK
2291{
2292 struct host_cmd cmd = {
0a7bcf26
ZY
2293 .cmd = command,
2294 .len = len,
2295 .param = data,
43f66a6c
JK
2296 };
2297
0a7bcf26
ZY
2298 return __ipw_send_cmd(priv, &cmd);
2299}
2300
2301static int ipw_send_host_complete(struct ipw_priv *priv)
2302{
43f66a6c
JK
2303 if (!priv) {
2304 IPW_ERROR("Invalid args\n");
2305 return -1;
2306 }
2307
0a7bcf26 2308 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
43f66a6c
JK
2309}
2310
d685b8c2 2311static int ipw_send_system_config(struct ipw_priv *priv)
43f66a6c 2312{
d685b8c2
ZY
2313 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG,
2314 sizeof(priv->sys_config),
2315 &priv->sys_config);
43f66a6c
JK
2316}
2317
0edd5b44 2318static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
43f66a6c 2319{
43f66a6c
JK
2320 if (!priv || !ssid) {
2321 IPW_ERROR("Invalid args\n");
2322 return -1;
2323 }
2324
0a7bcf26 2325 return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE),
2638bc39 2326 ssid);
43f66a6c
JK
2327}
2328
0edd5b44 2329static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
43f66a6c 2330{
43f66a6c
JK
2331 if (!priv || !mac) {
2332 IPW_ERROR("Invalid args\n");
2333 return -1;
2334 }
2335
e174961c
JB
2336 IPW_DEBUG_INFO("%s: Setting MAC to %pM\n",
2337 priv->net_dev->name, mac);
43f66a6c 2338
2638bc39 2339 return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
43f66a6c
JK
2340}
2341
2342static void ipw_adapter_restart(void *adapter)
2343{
2344 struct ipw_priv *priv = adapter;
2345
2346 if (priv->status & STATUS_RF_KILL_MASK)
2347 return;
2348
2349 ipw_down(priv);
b095c381
JK
2350
2351 if (priv->assoc_network &&
2352 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
2353 ipw_remove_current_network(priv);
2354
43f66a6c
JK
2355 if (ipw_up(priv)) {
2356 IPW_ERROR("Failed to up device\n");
2357 return;
2358 }
2359}
2360
c4028958 2361static void ipw_bg_adapter_restart(struct work_struct *work)
c848d0af 2362{
c4028958
DH
2363 struct ipw_priv *priv =
2364 container_of(work, struct ipw_priv, adapter_restart);
4644151b 2365 mutex_lock(&priv->mutex);
c4028958 2366 ipw_adapter_restart(priv);
4644151b 2367 mutex_unlock(&priv->mutex);
c848d0af
JK
2368}
2369
e65054b6
ZY
2370static void ipw_abort_scan(struct ipw_priv *priv);
2371
2372#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
43f66a6c
JK
2373
2374static void ipw_scan_check(void *data)
2375{
2376 struct ipw_priv *priv = data;
e65054b6
ZY
2377
2378 if (priv->status & STATUS_SCAN_ABORTING) {
43f66a6c 2379 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
c7b6a674
ZY
2380 "adapter after (%dms).\n",
2381 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
bcb6d916 2382 schedule_work(&priv->adapter_restart);
e65054b6
ZY
2383 } else if (priv->status & STATUS_SCANNING) {
2384 IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "
2385 "after (%dms).\n",
2386 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2387 ipw_abort_scan(priv);
bcb6d916 2388 schedule_delayed_work(&priv->scan_check, HZ);
43f66a6c
JK
2389 }
2390}
2391
c4028958 2392static void ipw_bg_scan_check(struct work_struct *work)
c848d0af 2393{
c4028958
DH
2394 struct ipw_priv *priv =
2395 container_of(work, struct ipw_priv, scan_check.work);
4644151b 2396 mutex_lock(&priv->mutex);
c4028958 2397 ipw_scan_check(priv);
4644151b 2398 mutex_unlock(&priv->mutex);
c848d0af
JK
2399}
2400
43f66a6c
JK
2401static int ipw_send_scan_request_ext(struct ipw_priv *priv,
2402 struct ipw_scan_request_ext *request)
2403{
0a7bcf26 2404 return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT,
2638bc39 2405 sizeof(*request), request);
43f66a6c
JK
2406}
2407
2408static int ipw_send_scan_abort(struct ipw_priv *priv)
2409{
43f66a6c
JK
2410 if (!priv) {
2411 IPW_ERROR("Invalid args\n");
2412 return -1;
2413 }
2414
0a7bcf26 2415 return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT);
43f66a6c
JK
2416}
2417
2418static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
2419{
0a7bcf26 2420 struct ipw_sensitivity_calib calib = {
851ca268 2421 .beacon_rssi_raw = cpu_to_le16(sens),
43f66a6c 2422 };
0a7bcf26
ZY
2423
2424 return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),
2638bc39 2425 &calib);
43f66a6c
JK
2426}
2427
2428static int ipw_send_associate(struct ipw_priv *priv,
2429 struct ipw_associate *associate)
2430{
0a7bcf26
ZY
2431 if (!priv || !associate) {
2432 IPW_ERROR("Invalid args\n");
2433 return -1;
2434 }
2435
5b5e807f
AV
2436 return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(*associate),
2437 associate);
43f66a6c
JK
2438}
2439
2440static int ipw_send_supported_rates(struct ipw_priv *priv,
2441 struct ipw_supported_rates *rates)
2442{
43f66a6c
JK
2443 if (!priv || !rates) {
2444 IPW_ERROR("Invalid args\n");
2445 return -1;
2446 }
2447
0a7bcf26 2448 return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates),
2638bc39 2449 rates);
43f66a6c
JK
2450}
2451
2452static int ipw_set_random_seed(struct ipw_priv *priv)
2453{
0a7bcf26 2454 u32 val;
43f66a6c
JK
2455
2456 if (!priv) {
2457 IPW_ERROR("Invalid args\n");
2458 return -1;
2459 }
2460
0a7bcf26 2461 get_random_bytes(&val, sizeof(val));
43f66a6c 2462
0a7bcf26 2463 return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val);
43f66a6c
JK
2464}
2465
43f66a6c
JK
2466static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
2467{
e62e1ee0 2468 __le32 v = cpu_to_le32(phy_off);
43f66a6c
JK
2469 if (!priv) {
2470 IPW_ERROR("Invalid args\n");
2471 return -1;
2472 }
2473
e62e1ee0 2474 return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(v), &v);
43f66a6c 2475}
43f66a6c 2476
0edd5b44 2477static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
43f66a6c 2478{
43f66a6c
JK
2479 if (!priv || !power) {
2480 IPW_ERROR("Invalid args\n");
2481 return -1;
2482 }
2483
2638bc39 2484 return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power);
43f66a6c
JK
2485}
2486
6de9f7f2
ZY
2487static int ipw_set_tx_power(struct ipw_priv *priv)
2488{
b0a4e7d8 2489 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
6de9f7f2
ZY
2490 struct ipw_tx_power tx_power;
2491 s8 max_power;
2492 int i;
2493
2494 memset(&tx_power, 0, sizeof(tx_power));
2495
2496 /* configure device for 'G' band */
2497 tx_power.ieee_mode = IPW_G_MODE;
2498 tx_power.num_channels = geo->bg_channels;
2499 for (i = 0; i < geo->bg_channels; i++) {
2500 max_power = geo->bg[i].max_power;
2501 tx_power.channels_tx_power[i].channel_number =
2502 geo->bg[i].channel;
2503 tx_power.channels_tx_power[i].tx_power = max_power ?
2504 min(max_power, priv->tx_power) : priv->tx_power;
43f66a6c 2505 }
6de9f7f2
ZY
2506 if (ipw_send_tx_power(priv, &tx_power))
2507 return -EIO;
2508
2509 /* configure device to also handle 'B' band */
2510 tx_power.ieee_mode = IPW_B_MODE;
2511 if (ipw_send_tx_power(priv, &tx_power))
2512 return -EIO;
bf79451e 2513
6de9f7f2
ZY
2514 /* configure device to also handle 'A' band */
2515 if (priv->ieee->abg_true) {
2516 tx_power.ieee_mode = IPW_A_MODE;
2517 tx_power.num_channels = geo->a_channels;
2518 for (i = 0; i < tx_power.num_channels; i++) {
2519 max_power = geo->a[i].max_power;
2520 tx_power.channels_tx_power[i].channel_number =
2521 geo->a[i].channel;
2522 tx_power.channels_tx_power[i].tx_power = max_power ?
2523 min(max_power, priv->tx_power) : priv->tx_power;
2524 }
2525 if (ipw_send_tx_power(priv, &tx_power))
2526 return -EIO;
2527 }
43f66a6c
JK
2528 return 0;
2529}
2530
2531static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2532{
2533 struct ipw_rts_threshold rts_threshold = {
851ca268 2534 .rts_threshold = cpu_to_le16(rts),
43f66a6c 2535 };
43f66a6c
JK
2536
2537 if (!priv) {
2538 IPW_ERROR("Invalid args\n");
2539 return -1;
2540 }
2541
0a7bcf26
ZY
2542 return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD,
2543 sizeof(rts_threshold), &rts_threshold);
43f66a6c
JK
2544}
2545
2546static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
2547{
2548 struct ipw_frag_threshold frag_threshold = {
851ca268 2549 .frag_threshold = cpu_to_le16(frag),
43f66a6c 2550 };
43f66a6c
JK
2551
2552 if (!priv) {
2553 IPW_ERROR("Invalid args\n");
2554 return -1;
2555 }
2556
0a7bcf26
ZY
2557 return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD,
2558 sizeof(frag_threshold), &frag_threshold);
43f66a6c
JK
2559}
2560
2561static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2562{
e62e1ee0 2563 __le32 param;
43f66a6c
JK
2564
2565 if (!priv) {
2566 IPW_ERROR("Invalid args\n");
2567 return -1;
2568 }
bf79451e 2569
43f66a6c
JK
2570 /* If on battery, set to 3, if AC set to CAM, else user
2571 * level */
2572 switch (mode) {
2573 case IPW_POWER_BATTERY:
e62e1ee0 2574 param = cpu_to_le32(IPW_POWER_INDEX_3);
43f66a6c
JK
2575 break;
2576 case IPW_POWER_AC:
e62e1ee0 2577 param = cpu_to_le32(IPW_POWER_MODE_CAM);
43f66a6c
JK
2578 break;
2579 default:
e62e1ee0 2580 param = cpu_to_le32(mode);
43f66a6c
JK
2581 break;
2582 }
2583
0a7bcf26 2584 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
2638bc39 2585 &param);
43f66a6c
JK
2586}
2587
afbf30a2
JK
2588static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2589{
2590 struct ipw_retry_limit retry_limit = {
2591 .short_retry_limit = slimit,
2592 .long_retry_limit = llimit
2593 };
afbf30a2
JK
2594
2595 if (!priv) {
2596 IPW_ERROR("Invalid args\n");
2597 return -1;
2598 }
2599
0a7bcf26 2600 return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit),
2638bc39 2601 &retry_limit);
afbf30a2
JK
2602}
2603
43f66a6c
JK
2604/*
2605 * The IPW device contains a Microwire compatible EEPROM that stores
2606 * various data like the MAC address. Usually the firmware has exclusive
2607 * access to the eeprom, but during device initialization (before the
2608 * device driver has sent the HostComplete command to the firmware) the
2609 * device driver has read access to the EEPROM by way of indirect addressing
2610 * through a couple of memory mapped registers.
2611 *
2612 * The following is a simplified implementation for pulling data out of the
2613 * the eeprom, along with some helper functions to find information in
2614 * the per device private data's copy of the eeprom.
2615 *
2616 * NOTE: To better understand how these functions work (i.e what is a chip
2617 * select and why do have to keep driving the eeprom clock?), read
2618 * just about any data sheet for a Microwire compatible EEPROM.
2619 */
2620
2621/* write a 32 bit value into the indirect accessor register */
2622static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
2623{
2624 ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);
bf79451e 2625
43f66a6c
JK
2626 /* the eeprom requires some time to complete the operation */
2627 udelay(p->eeprom_delay);
43f66a6c
JK
2628}
2629
2630/* perform a chip select operation */
858119e1 2631static void eeprom_cs(struct ipw_priv *priv)
43f66a6c 2632{
0edd5b44
JG
2633 eeprom_write_reg(priv, 0);
2634 eeprom_write_reg(priv, EEPROM_BIT_CS);
2635 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2636 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2637}
2638
2639/* perform a chip select operation */
858119e1 2640static void eeprom_disable_cs(struct ipw_priv *priv)
43f66a6c 2641{
0edd5b44
JG
2642 eeprom_write_reg(priv, EEPROM_BIT_CS);
2643 eeprom_write_reg(priv, 0);
2644 eeprom_write_reg(priv, EEPROM_BIT_SK);
43f66a6c
JK
2645}
2646
2647/* push a single bit down to the eeprom */
0edd5b44 2648static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit)
43f66a6c 2649{
0edd5b44
JG
2650 int d = (bit ? EEPROM_BIT_DI : 0);
2651 eeprom_write_reg(p, EEPROM_BIT_CS | d);
2652 eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK);
43f66a6c
JK
2653}
2654
2655/* push an opcode followed by an address down to the eeprom */
0edd5b44 2656static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr)
43f66a6c
JK
2657{
2658 int i;
2659
2660 eeprom_cs(priv);
0edd5b44
JG
2661 eeprom_write_bit(priv, 1);
2662 eeprom_write_bit(priv, op & 2);
2663 eeprom_write_bit(priv, op & 1);
2664 for (i = 7; i >= 0; i--) {
2665 eeprom_write_bit(priv, addr & (1 << i));
43f66a6c
JK
2666 }
2667}
2668
2669/* pull 16 bits off the eeprom, one bit at a time */
0edd5b44 2670static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
43f66a6c
JK
2671{
2672 int i;
0edd5b44 2673 u16 r = 0;
bf79451e 2674
43f66a6c 2675 /* Send READ Opcode */
0edd5b44 2676 eeprom_op(priv, EEPROM_CMD_READ, addr);
43f66a6c
JK
2677
2678 /* Send dummy bit */
0edd5b44 2679 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2680
2681 /* Read the byte off the eeprom one bit at a time */
0edd5b44 2682 for (i = 0; i < 16; i++) {
43f66a6c 2683 u32 data = 0;
0edd5b44
JG
2684 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2685 eeprom_write_reg(priv, EEPROM_BIT_CS);
2686 data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS);
2687 r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0);
43f66a6c 2688 }
bf79451e 2689
43f66a6c 2690 /* Send another dummy bit */
0edd5b44 2691 eeprom_write_reg(priv, 0);
43f66a6c 2692 eeprom_disable_cs(priv);
bf79451e 2693
43f66a6c
JK
2694 return r;
2695}
2696
2697/* helper function for pulling the mac address out of the private */
2698/* data's copy of the eeprom data */
0edd5b44 2699static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
43f66a6c 2700{
afbf30a2 2701 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
43f66a6c
JK
2702}
2703
fdbfff73
SY
2704static void ipw_read_eeprom(struct ipw_priv *priv)
2705{
2706 int i;
2707 __le16 *eeprom = (__le16 *) priv->eeprom;
2708
2709 IPW_DEBUG_TRACE(">>\n");
2710
2711 /* read entire contents of eeprom into private buffer */
2712 for (i = 0; i < 128; i++)
2713 eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i));
2714
2715 IPW_DEBUG_TRACE("<<\n");
2716}
2717
43f66a6c
JK
2718/*
2719 * Either the device driver (i.e. the host) or the firmware can
2720 * load eeprom data into the designated region in SRAM. If neither
2721 * happens then the FW will shutdown with a fatal error.
2722 *
2723 * In order to signal the FW to load the EEPROM, the EEPROM_LOAD_DISABLE
2724 * bit needs region of shared SRAM needs to be non-zero.
2725 */
2726static void ipw_eeprom_init_sram(struct ipw_priv *priv)
2727{
2728 int i;
bf79451e 2729
43f66a6c
JK
2730 IPW_DEBUG_TRACE(">>\n");
2731
bf79451e
JG
2732 /*
2733 If the data looks correct, then copy it to our private
43f66a6c 2734 copy. Otherwise let the firmware know to perform the operation
c7b6a674 2735 on its own.
0edd5b44 2736 */
386093ef 2737 if (priv->eeprom[EEPROM_VERSION] != 0) {
43f66a6c
JK
2738 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
2739
2740 /* write the eeprom data to sram */
b095c381 2741 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
0edd5b44 2742 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
43f66a6c
JK
2743
2744 /* Do not load eeprom data on fatal error or suspend */
2745 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
2746 } else {
2747 IPW_DEBUG_INFO("Enabling FW initializationg of SRAM\n");
2748
2749 /* Load eeprom data on fatal error or suspend */
2750 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);
2751 }
2752
2753 IPW_DEBUG_TRACE("<<\n");
2754}
2755
858119e1 2756static void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
43f66a6c
JK
2757{
2758 count >>= 2;
0edd5b44
JG
2759 if (!count)
2760 return;
b095c381 2761 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
bf79451e 2762 while (count--)
b095c381 2763 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
43f66a6c
JK
2764}
2765
2766static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
2767{
b095c381 2768 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
bf79451e 2769 CB_NUMBER_OF_ELEMENTS_SMALL *
43f66a6c
JK
2770 sizeof(struct command_block));
2771}
2772
2773static int ipw_fw_dma_enable(struct ipw_priv *priv)
0edd5b44 2774{ /* start dma engine but no transfers yet */
43f66a6c 2775
9fd1ea42 2776 IPW_DEBUG_FW(">> :\n");
bf79451e 2777
43f66a6c
JK
2778 /* Start the dma */
2779 ipw_fw_dma_reset_command_blocks(priv);
bf79451e 2780
43f66a6c 2781 /* Write CB base address */
b095c381 2782 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
43f66a6c 2783
9fd1ea42 2784 IPW_DEBUG_FW("<< :\n");
43f66a6c
JK
2785 return 0;
2786}
2787
2788static void ipw_fw_dma_abort(struct ipw_priv *priv)
2789{
2790 u32 control = 0;
2791
2792 IPW_DEBUG_FW(">> :\n");
bf79451e 2793
67fd6b45 2794 /* set the Stop and Abort bit */
43f66a6c 2795 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
b095c381 2796 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
43f66a6c 2797 priv->sram_desc.last_cb_index = 0;
bf79451e 2798
9fd1ea42 2799 IPW_DEBUG_FW("<<\n");
43f66a6c
JK
2800}
2801
0edd5b44
JG
2802static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
2803 struct command_block *cb)
43f66a6c 2804{
0edd5b44 2805 u32 address =
b095c381 2806 IPW_SHARED_SRAM_DMA_CONTROL +
0edd5b44 2807 (sizeof(struct command_block) * index);
43f66a6c
JK
2808 IPW_DEBUG_FW(">> :\n");
2809
0edd5b44
JG
2810 ipw_write_indirect(priv, address, (u8 *) cb,
2811 (int)sizeof(struct command_block));
43f66a6c
JK
2812
2813 IPW_DEBUG_FW("<< :\n");
2814 return 0;
2815
2816}
2817
2818static int ipw_fw_dma_kick(struct ipw_priv *priv)
2819{
2820 u32 control = 0;
0edd5b44 2821 u32 index = 0;
43f66a6c
JK
2822
2823 IPW_DEBUG_FW(">> :\n");
bf79451e 2824
43f66a6c 2825 for (index = 0; index < priv->sram_desc.last_cb_index; index++)
0edd5b44
JG
2826 ipw_fw_dma_write_command_block(priv, index,
2827 &priv->sram_desc.cb_list[index]);
43f66a6c
JK
2828
2829 /* Enable the DMA in the CSR register */
b095c381
JK
2830 ipw_clear_bit(priv, IPW_RESET_REG,
2831 IPW_RESET_REG_MASTER_DISABLED |
2832 IPW_RESET_REG_STOP_MASTER);
bf79451e 2833
0edd5b44 2834 /* Set the Start bit. */
43f66a6c 2835 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
b095c381 2836 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
43f66a6c
JK
2837
2838 IPW_DEBUG_FW("<< :\n");
2839 return 0;
2840}
2841
2842static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
2843{
2844 u32 address;
0edd5b44
JG
2845 u32 register_value = 0;
2846 u32 cb_fields_address = 0;
43f66a6c
JK
2847
2848 IPW_DEBUG_FW(">> :\n");
b095c381 2849 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
9fd1ea42 2850 IPW_DEBUG_FW_INFO("Current CB is 0x%x\n", address);
43f66a6c
JK
2851
2852 /* Read the DMA Controlor register */
b095c381 2853 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
9fd1ea42 2854 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x\n", register_value);
43f66a6c 2855
0edd5b44 2856 /* Print the CB values */
43f66a6c
JK
2857 cb_fields_address = address;
2858 register_value = ipw_read_reg32(priv, cb_fields_address);
9fd1ea42 2859 IPW_DEBUG_FW_INFO("Current CB Control Field is 0x%x\n", register_value);
43f66a6c
JK
2860
2861 cb_fields_address += sizeof(u32);
2862 register_value = ipw_read_reg32(priv, cb_fields_address);
9fd1ea42 2863 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x\n", register_value);
43f66a6c
JK
2864
2865 cb_fields_address += sizeof(u32);
2866 register_value = ipw_read_reg32(priv, cb_fields_address);
9fd1ea42 2867 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x\n",
43f66a6c
JK
2868 register_value);
2869
2870 cb_fields_address += sizeof(u32);
2871 register_value = ipw_read_reg32(priv, cb_fields_address);
9fd1ea42 2872 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x\n", register_value);
43f66a6c
JK
2873
2874 IPW_DEBUG_FW(">> :\n");
2875}
2876
2877static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
2878{
2879 u32 current_cb_address = 0;
2880 u32 current_cb_index = 0;
2881
2882 IPW_DEBUG_FW("<< :\n");
b095c381 2883 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
bf79451e 2884
b095c381 2885 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
0edd5b44 2886 sizeof(struct command_block);
bf79451e 2887
9fd1ea42 2888 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X\n",
0edd5b44 2889 current_cb_index, current_cb_address);
43f66a6c
JK
2890
2891 IPW_DEBUG_FW(">> :\n");
2892 return current_cb_index;
2893
2894}
2895
2896static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
2897 u32 src_address,
2898 u32 dest_address,
2899 u32 length,
0edd5b44 2900 int interrupt_enabled, int is_last)
43f66a6c
JK
2901{
2902
bf79451e 2903 u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC |
0edd5b44
JG
2904 CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG |
2905 CB_DEST_SIZE_LONG;
43f66a6c 2906 struct command_block *cb;
0edd5b44 2907 u32 last_cb_element = 0;
43f66a6c
JK
2908
2909 IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n",
2910 src_address, dest_address, length);
2911
2912 if (priv->sram_desc.last_cb_index >= CB_NUMBER_OF_ELEMENTS_SMALL)
2913 return -1;
2914
2915 last_cb_element = priv->sram_desc.last_cb_index;
2916 cb = &priv->sram_desc.cb_list[last_cb_element];
2917 priv->sram_desc.last_cb_index++;
2918
2919 /* Calculate the new CB control word */
0edd5b44 2920 if (interrupt_enabled)
43f66a6c
JK
2921 control |= CB_INT_ENABLED;
2922
2923 if (is_last)
2924 control |= CB_LAST_VALID;
bf79451e 2925
43f66a6c
JK
2926 control |= length;
2927
2928 /* Calculate the CB Element's checksum value */
0edd5b44 2929 cb->status = control ^ src_address ^ dest_address;
43f66a6c
JK
2930
2931 /* Copy the Source and Destination addresses */
2932 cb->dest_addr = dest_address;
2933 cb->source_addr = src_address;
2934
2935 /* Copy the Control Word last */
2936 cb->control = control;
2937
2938 return 0;
2939}
2940
11ebd1bf
ZY
2941static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
2942 int nr, u32 dest_address, u32 len)
43f66a6c 2943{
11ebd1bf
ZY
2944 int ret, i;
2945 u32 size;
2946
9fd1ea42 2947 IPW_DEBUG_FW(">>\n");
11ebd1bf
ZY
2948 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",
2949 nr, dest_address, len);
2950
2951 for (i = 0; i < nr; i++) {
2952 size = min_t(u32, len - i * CB_MAX_LENGTH, CB_MAX_LENGTH);
2953 ret = ipw_fw_dma_add_command_block(priv, src_address[i],
2954 dest_address +
2955 i * CB_MAX_LENGTH, size,
2956 0, 0);
2957 if (ret) {
43f66a6c
JK
2958 IPW_DEBUG_FW_INFO(": Failed\n");
2959 return -1;
bf79451e 2960 } else
43f66a6c 2961 IPW_DEBUG_FW_INFO(": Added new cb\n");
43f66a6c 2962 }
bf79451e 2963
9fd1ea42 2964 IPW_DEBUG_FW("<<\n");
43f66a6c
JK
2965 return 0;
2966}
2967
2968static int ipw_fw_dma_wait(struct ipw_priv *priv)
2969{
397ae121 2970 u32 current_index = 0, previous_index;
43f66a6c
JK
2971 u32 watchdog = 0;
2972
9fd1ea42 2973 IPW_DEBUG_FW(">> :\n");
43f66a6c
JK
2974
2975 current_index = ipw_fw_dma_command_block_index(priv);
397ae121 2976 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
0edd5b44 2977 (int)priv->sram_desc.last_cb_index);
43f66a6c
JK
2978
2979 while (current_index < priv->sram_desc.last_cb_index) {
2980 udelay(50);
397ae121 2981 previous_index = current_index;
43f66a6c
JK
2982 current_index = ipw_fw_dma_command_block_index(priv);
2983
397ae121
ZY
2984 if (previous_index < current_index) {
2985 watchdog = 0;
2986 continue;
2987 }
2988 if (++watchdog > 400) {
43f66a6c
JK
2989 IPW_DEBUG_FW_INFO("Timeout\n");
2990 ipw_fw_dma_dump_command_block(priv);
2991 ipw_fw_dma_abort(priv);
2992 return -1;
2993 }
2994 }
2995
2996 ipw_fw_dma_abort(priv);
2997
0edd5b44 2998 /*Disable the DMA in the CSR register */
b095c381
JK
2999 ipw_set_bit(priv, IPW_RESET_REG,
3000 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
43f66a6c 3001
9fd1ea42 3002 IPW_DEBUG_FW("<< dmaWaitSync\n");
43f66a6c
JK
3003 return 0;
3004}
3005
bf79451e 3006static void ipw_remove_current_network(struct ipw_priv *priv)
43f66a6c
JK
3007{
3008 struct list_head *element, *safe;
b0a4e7d8 3009 struct libipw_network *network = NULL;
a613bffd
JK
3010 unsigned long flags;
3011
3012 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c 3013 list_for_each_safe(element, safe, &priv->ieee->network_list) {
b0a4e7d8 3014 network = list_entry(element, struct libipw_network, list);
43f66a6c
JK
3015 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
3016 list_del(element);
bf79451e 3017 list_add_tail(&network->list,
43f66a6c
JK
3018 &priv->ieee->network_free_list);
3019 }
3020 }
a613bffd 3021 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c
JK
3022}
3023
3024/**
bf79451e 3025 * Check that card is still alive.
43f66a6c
JK
3026 * Reads debug register from domain0.
3027 * If card is present, pre-defined value should
3028 * be found there.
bf79451e 3029 *
43f66a6c
JK
3030 * @param priv
3031 * @return 1 if card is present, 0 otherwise
3032 */
3033static inline int ipw_alive(struct ipw_priv *priv)
3034{
3035 return ipw_read32(priv, 0x90) == 0xd55555d5;
3036}
3037
c7b6a674 3038/* timeout in msec, attempted in 10-msec quanta */
858119e1 3039static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
43f66a6c
JK
3040 int timeout)
3041{
3042 int i = 0;
3043
3044 do {
bf79451e 3045 if ((ipw_read32(priv, addr) & mask) == mask)
43f66a6c
JK
3046 return i;
3047 mdelay(10);
3048 i += 10;
3049 } while (i < timeout);
bf79451e 3050
43f66a6c
JK
3051 return -ETIME;
3052}
3053
bf79451e 3054/* These functions load the firmware and micro code for the operation of
43f66a6c
JK
3055 * the ipw hardware. It assumes the buffer has all the bits for the
3056 * image and the caller is handling the memory allocation and clean up.
3057 */
3058
0edd5b44 3059static int ipw_stop_master(struct ipw_priv *priv)
43f66a6c
JK
3060{
3061 int rc;
bf79451e 3062
9fd1ea42 3063 IPW_DEBUG_TRACE(">>\n");
43f66a6c 3064 /* stop master. typical delay - 0 */
b095c381 3065 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
43f66a6c 3066
c7b6a674 3067 /* timeout is in msec, polled in 10-msec quanta */
b095c381
JK
3068 rc = ipw_poll_bit(priv, IPW_RESET_REG,
3069 IPW_RESET_REG_MASTER_DISABLED, 100);
43f66a6c 3070 if (rc < 0) {
c7b6a674 3071 IPW_ERROR("wait for stop master failed after 100ms\n");
43f66a6c
JK
3072 return -1;
3073 }
3074
3075 IPW_DEBUG_INFO("stop master %dms\n", rc);
3076
3077 return rc;
3078}
3079
3080static void ipw_arc_release(struct ipw_priv *priv)
3081{
9fd1ea42 3082 IPW_DEBUG_TRACE(">>\n");
43f66a6c
JK
3083 mdelay(5);
3084
b095c381 3085 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
43f66a6c
JK
3086
3087 /* no one knows timing, for safety add some delay */
3088 mdelay(5);
3089}
3090
43f66a6c 3091struct fw_chunk {
e62e1ee0
AV
3092 __le32 address;
3093 __le32 length;
43f66a6c
JK
3094};
3095
0edd5b44 3096static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c
JK
3097{
3098 int rc = 0, i, addr;
3099 u8 cr = 0;
e62e1ee0 3100 __le16 *image;
43f66a6c 3101
e62e1ee0 3102 image = (__le16 *) data;
bf79451e 3103
9fd1ea42 3104 IPW_DEBUG_TRACE(">>\n");
43f66a6c
JK
3105
3106 rc = ipw_stop_master(priv);
3107
3108 if (rc < 0)
3109 return rc;
bf79451e 3110
b095c381
JK
3111 for (addr = IPW_SHARED_LOWER_BOUND;
3112 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
43f66a6c
JK
3113 ipw_write32(priv, addr, 0);
3114 }
3115
3116 /* no ucode (yet) */
3117 memset(&priv->dino_alive, 0, sizeof(priv->dino_alive));
3118 /* destroy DMA queues */
3119 /* reset sequence */
3120
b095c381 3121 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
43f66a6c 3122 ipw_arc_release(priv);
b095c381 3123 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
43f66a6c
JK
3124 mdelay(1);
3125
3126 /* reset PHY */
b095c381 3127 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
43f66a6c 3128 mdelay(1);
bf79451e 3129
b095c381 3130 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
43f66a6c 3131 mdelay(1);
bf79451e 3132
43f66a6c 3133 /* enable ucode store */
c8fe6679
ZY
3134 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0);
3135 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS);
43f66a6c
JK
3136 mdelay(1);
3137
3138 /* write ucode */
3139 /**
3140 * @bug
3141 * Do NOT set indirect address register once and then
3142 * store data to indirect data register in the loop.
3143 * It seems very reasonable, but in this case DINO do not
3144 * accept ucode. It is essential to set address each time.
3145 */
3146 /* load new ipw uCode */
3147 for (i = 0; i < len / 2; i++)
b095c381 3148 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
e62e1ee0 3149 le16_to_cpu(image[i]));
43f66a6c 3150
43f66a6c 3151 /* enable DINO */
b095c381
JK
3152 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
3153 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
43f66a6c 3154
0edd5b44 3155 /* this is where the igx / win driver deveates from the VAP driver. */
43f66a6c
JK
3156
3157 /* wait for alive response */
3158 for (i = 0; i < 100; i++) {
3159 /* poll for incoming data */
b095c381 3160 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
43f66a6c
JK
3161 if (cr & DINO_RXFIFO_DATA)
3162 break;
3163 mdelay(1);
3164 }
3165
3166 if (cr & DINO_RXFIFO_DATA) {
3167 /* alive_command_responce size is NOT multiple of 4 */
e62e1ee0 3168 __le32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
bf79451e
JG
3169
3170 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
43f66a6c 3171 response_buffer[i] =
e62e1ee0 3172 cpu_to_le32(ipw_read_reg32(priv,
b095c381 3173 IPW_BASEBAND_RX_FIFO_READ));
43f66a6c
JK
3174 memcpy(&priv->dino_alive, response_buffer,
3175 sizeof(priv->dino_alive));
3176 if (priv->dino_alive.alive_command == 1
3177 && priv->dino_alive.ucode_valid == 1) {
3178 rc = 0;
0edd5b44
JG
3179 IPW_DEBUG_INFO
3180 ("Microcode OK, rev. %d (0x%x) dev. %d (0x%x) "
3181 "of %02d/%02d/%02d %02d:%02d\n",
3182 priv->dino_alive.software_revision,
3183 priv->dino_alive.software_revision,
3184 priv->dino_alive.device_identifier,
3185 priv->dino_alive.device_identifier,
3186 priv->dino_alive.time_stamp[0],
3187 priv->dino_alive.time_stamp[1],
3188 priv->dino_alive.time_stamp[2],
3189 priv->dino_alive.time_stamp[3],
3190 priv->dino_alive.time_stamp[4]);
43f66a6c
JK
3191 } else {
3192 IPW_DEBUG_INFO("Microcode is not alive\n");
3193 rc = -EINVAL;
3194 }
3195 } else {
3196 IPW_DEBUG_INFO("No alive response from DINO\n");
3197 rc = -ETIME;
3198 }
3199
3200 /* disable DINO, otherwise for some reason
3201 firmware have problem getting alive resp. */
b095c381 3202 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
43f66a6c 3203
43f66a6c
JK
3204 return rc;
3205}
3206
0edd5b44 3207static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c 3208{
11ebd1bf 3209 int ret = -1;
43f66a6c
JK
3210 int offset = 0;
3211 struct fw_chunk *chunk;
11ebd1bf
ZY
3212 int total_nr = 0;
3213 int i;
3214 struct pci_pool *pool;
41093167
ZY
3215 void **virts;
3216 dma_addr_t *phys;
43f66a6c 3217
9fd1ea42 3218 IPW_DEBUG_TRACE("<< :\n");
43f66a6c 3219
41093167
ZY
3220 virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
3221 GFP_KERNEL);
3222 if (!virts)
3223 return -ENOMEM;
3224
3225 phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
3226 GFP_KERNEL);
3227 if (!phys) {
3228 kfree(virts);
3229 return -ENOMEM;
3230 }
11ebd1bf
ZY
3231 pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
3232 if (!pool) {
3233 IPW_ERROR("pci_pool_create failed\n");
41093167
ZY
3234 kfree(phys);
3235 kfree(virts);
43f66a6c 3236 return -ENOMEM;
11ebd1bf 3237 }
43f66a6c
JK
3238
3239 /* Start the Dma */
11ebd1bf 3240 ret = ipw_fw_dma_enable(priv);
43f66a6c 3241
0ee904c3
AB
3242 /* the DMA is already ready this would be a bug. */
3243 BUG_ON(priv->sram_desc.last_cb_index > 0);
43f66a6c
JK
3244
3245 do {
11ebd1bf
ZY
3246 u32 chunk_len;
3247 u8 *start;
3248 int size;
3249 int nr = 0;
3250
43f66a6c
JK
3251 chunk = (struct fw_chunk *)(data + offset);
3252 offset += sizeof(struct fw_chunk);
11ebd1bf
ZY
3253 chunk_len = le32_to_cpu(chunk->length);
3254 start = data + offset;
3255
3256 nr = (chunk_len + CB_MAX_LENGTH - 1) / CB_MAX_LENGTH;
3257 for (i = 0; i < nr; i++) {
3258 virts[total_nr] = pci_pool_alloc(pool, GFP_KERNEL,
3259 &phys[total_nr]);
3260 if (!virts[total_nr]) {
3261 ret = -ENOMEM;
3262 goto out;
3263 }
3264 size = min_t(u32, chunk_len - i * CB_MAX_LENGTH,
3265 CB_MAX_LENGTH);
3266 memcpy(virts[total_nr], start, size);
3267 start += size;
3268 total_nr++;
3269 /* We don't support fw chunk larger than 64*8K */
3270 BUG_ON(total_nr > CB_NUMBER_OF_ELEMENTS_SMALL);
3271 }
3272
43f66a6c 3273 /* build DMA packet and queue up for sending */
bf79451e 3274 /* dma to chunk->address, the chunk->length bytes from data +
43f66a6c
JK
3275 * offeset*/
3276 /* Dma loading */
11ebd1bf
ZY
3277 ret = ipw_fw_dma_add_buffer(priv, &phys[total_nr - nr],
3278 nr, le32_to_cpu(chunk->address),
3279 chunk_len);
3280 if (ret) {
43f66a6c
JK
3281 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
3282 goto out;
3283 }
bf79451e 3284
11ebd1bf 3285 offset += chunk_len;
43f66a6c
JK
3286 } while (offset < len);
3287
0edd5b44 3288 /* Run the DMA and wait for the answer */
11ebd1bf
ZY
3289 ret = ipw_fw_dma_kick(priv);
3290 if (ret) {
43f66a6c
JK
3291 IPW_ERROR("dmaKick Failed\n");
3292 goto out;
3293 }
3294
11ebd1bf
ZY
3295 ret = ipw_fw_dma_wait(priv);
3296 if (ret) {
43f66a6c
JK
3297 IPW_ERROR("dmaWaitSync Failed\n");
3298 goto out;
3299 }
11ebd1bf
ZY
3300 out:
3301 for (i = 0; i < total_nr; i++)
3302 pci_pool_free(pool, virts[i], phys[i]);
3303
3304 pci_pool_destroy(pool);
41093167
ZY
3305 kfree(phys);
3306 kfree(virts);
11ebd1bf
ZY
3307
3308 return ret;
43f66a6c
JK
3309}
3310
3311/* stop nic */
3312static int ipw_stop_nic(struct ipw_priv *priv)
3313{
3314 int rc = 0;
3315
0edd5b44 3316 /* stop */
b095c381 3317 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
bf79451e 3318
b095c381
JK
3319 rc = ipw_poll_bit(priv, IPW_RESET_REG,
3320 IPW_RESET_REG_MASTER_DISABLED, 500);
43f66a6c 3321 if (rc < 0) {
c7b6a674 3322 IPW_ERROR("wait for reg master disabled failed after 500ms\n");
43f66a6c 3323 return rc;
bf79451e 3324 }
43f66a6c 3325
b095c381 3326 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
bf79451e 3327
43f66a6c
JK
3328 return rc;
3329}
3330
3331static void ipw_start_nic(struct ipw_priv *priv)
3332{
3333 IPW_DEBUG_TRACE(">>\n");
3334
0edd5b44 3335 /* prvHwStartNic release ARC */
b095c381
JK
3336 ipw_clear_bit(priv, IPW_RESET_REG,
3337 IPW_RESET_REG_MASTER_DISABLED |
3338 IPW_RESET_REG_STOP_MASTER |
43f66a6c 3339 CBD_RESET_REG_PRINCETON_RESET);
bf79451e 3340
43f66a6c 3341 /* enable power management */
b095c381
JK
3342 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
3343 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
43f66a6c
JK
3344
3345 IPW_DEBUG_TRACE("<<\n");
3346}
bf79451e 3347
43f66a6c
JK
3348static int ipw_init_nic(struct ipw_priv *priv)
3349{
3350 int rc;
3351
3352 IPW_DEBUG_TRACE(">>\n");
bf79451e 3353 /* reset */
43f66a6c
JK
3354 /*prvHwInitNic */
3355 /* set "initialization complete" bit to move adapter to D0 state */
b095c381 3356 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
43f66a6c
JK
3357
3358 /* low-level PLL activation */
b095c381
JK
3359 ipw_write32(priv, IPW_READ_INT_REGISTER,
3360 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
43f66a6c
JK
3361
3362 /* wait for clock stabilization */
b095c381
JK
3363 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
3364 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
0edd5b44 3365 if (rc < 0)
43f66a6c
JK
3366 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
3367
3368 /* assert SW reset */
b095c381 3369 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
43f66a6c
JK
3370
3371 udelay(10);
3372
3373 /* set "initialization complete" bit to move adapter to D0 state */
b095c381 3374 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
43f66a6c
JK
3375
3376 IPW_DEBUG_TRACE(">>\n");
3377 return 0;
3378}
3379
bf79451e 3380/* Call this function from process context, it will sleep in request_firmware.
43f66a6c
JK
3381 * Probe is an ok place to call this from.
3382 */
3383static int ipw_reset_nic(struct ipw_priv *priv)
3384{
3385 int rc = 0;
a613bffd 3386 unsigned long flags;
43f66a6c
JK
3387
3388 IPW_DEBUG_TRACE(">>\n");
bf79451e 3389
43f66a6c 3390 rc = ipw_init_nic(priv);
bf79451e 3391
a613bffd 3392 spin_lock_irqsave(&priv->lock, flags);
43f66a6c
JK
3393 /* Clear the 'host command active' bit... */
3394 priv->status &= ~STATUS_HCMD_ACTIVE;
3395 wake_up_interruptible(&priv->wait_command_queue);
afbf30a2
JK
3396 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3397 wake_up_interruptible(&priv->wait_state);
a613bffd 3398 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
3399
3400 IPW_DEBUG_TRACE("<<\n");
3401 return rc;
bf79451e 3402}
43f66a6c 3403
9006ea75
JK
3404
3405struct ipw_fw {
0070f8c7
ZY
3406 __le32 ver;
3407 __le32 boot_size;
3408 __le32 ucode_size;
3409 __le32 fw_size;
9006ea75
JK
3410 u8 data[0];
3411};
3412
bf79451e 3413static int ipw_get_fw(struct ipw_priv *priv,
9006ea75 3414 const struct firmware **raw, const char *name)
43f66a6c 3415{
9006ea75 3416 struct ipw_fw *fw;
43f66a6c
JK
3417 int rc;
3418
3419 /* ask firmware_class module to get the boot firmware off disk */
9006ea75 3420 rc = request_firmware(raw, name, &priv->pci_dev->dev);
43f66a6c 3421 if (rc < 0) {
9006ea75 3422 IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc);
43f66a6c 3423 return rc;
bf79451e 3424 }
43f66a6c 3425
9006ea75
JK
3426 if ((*raw)->size < sizeof(*fw)) {
3427 IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size);
3428 return -EINVAL;
3429 }
3430
3431 fw = (void *)(*raw)->data;
3432
0070f8c7
ZY
3433 if ((*raw)->size < sizeof(*fw) + le32_to_cpu(fw->boot_size) +
3434 le32_to_cpu(fw->ucode_size) + le32_to_cpu(fw->fw_size)) {
9006ea75
JK
3435 IPW_ERROR("%s is too small or corrupt (%zd)\n",
3436 name, (*raw)->size);
43f66a6c
JK
3437 return -EINVAL;
3438 }
3439
9006ea75 3440 IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n",
43f66a6c 3441 name,
9006ea75
JK
3442 le32_to_cpu(fw->ver) >> 16,
3443 le32_to_cpu(fw->ver) & 0xff,
3444 (*raw)->size - sizeof(*fw));
43f66a6c
JK
3445 return 0;
3446}
3447
b095c381 3448#define IPW_RX_BUF_SIZE (3000)
43f66a6c 3449
858119e1 3450static void ipw_rx_queue_reset(struct ipw_priv *priv,
43f66a6c
JK
3451 struct ipw_rx_queue *rxq)
3452{
3453 unsigned long flags;
3454 int i;
3455
3456 spin_lock_irqsave(&rxq->lock, flags);
3457
3458 INIT_LIST_HEAD(&rxq->rx_free);
3459 INIT_LIST_HEAD(&rxq->rx_used);
3460
3461 /* Fill the rx_used queue with _all_ of the Rx buffers */
3462 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
3463 /* In the reset function, these buffers may have been allocated
3464 * to an SKB, so we need to unmap and free potential storage */
3465 if (rxq->pool[i].skb != NULL) {
3466 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
b095c381 3467 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c 3468 dev_kfree_skb(rxq->pool[i].skb);
a613bffd 3469 rxq->pool[i].skb = NULL;
43f66a6c
JK
3470 }
3471 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
3472 }
bf79451e 3473
43f66a6c
JK
3474 /* Set us so that we have processed and used all buffers, but have
3475 * not restocked the Rx queue with fresh buffers */
3476 rxq->read = rxq->write = 0;
43f66a6c
JK
3477 rxq->free_count = 0;
3478 spin_unlock_irqrestore(&rxq->lock, flags);
3479}
3480
3481#ifdef CONFIG_PM
3482static int fw_loaded = 0;
9006ea75 3483static const struct firmware *raw = NULL;
afbf30a2
JK
3484
3485static void free_firmware(void)
3486{
3487 if (fw_loaded) {
9006ea75
JK
3488 release_firmware(raw);
3489 raw = NULL;
afbf30a2
JK
3490 fw_loaded = 0;
3491 }
3492}
3493#else
3494#define free_firmware() do {} while (0)
43f66a6c
JK
3495#endif
3496
3497static int ipw_load(struct ipw_priv *priv)
3498{
3499#ifndef CONFIG_PM
9006ea75 3500 const struct firmware *raw = NULL;
43f66a6c 3501#endif
9006ea75
JK
3502 struct ipw_fw *fw;
3503 u8 *boot_img, *ucode_img, *fw_img;
3504 u8 *name = NULL;
43f66a6c
JK
3505 int rc = 0, retries = 3;
3506
397ae121
ZY
3507 switch (priv->ieee->iw_mode) {
3508 case IW_MODE_ADHOC:
9006ea75 3509 name = "ipw2200-ibss.fw";
397ae121 3510 break;
b095c381 3511#ifdef CONFIG_IPW2200_MONITOR
397ae121 3512 case IW_MODE_MONITOR:
9006ea75 3513 name = "ipw2200-sniffer.fw";
397ae121 3514 break;
43f66a6c 3515#endif
397ae121 3516 case IW_MODE_INFRA:
9006ea75 3517 name = "ipw2200-bss.fw";
397ae121 3518 break;
9006ea75
JK
3519 }
3520
3521 if (!name) {
397ae121 3522 rc = -EINVAL;
9006ea75
JK
3523 goto error;
3524 }
3525
3526#ifdef CONFIG_PM
3527 if (!fw_loaded) {
3528#endif
3529 rc = ipw_get_fw(priv, &raw, name);
3530 if (rc < 0)
3531 goto error;
3532#ifdef CONFIG_PM
43f66a6c 3533 }
9006ea75
JK
3534#endif
3535
3536 fw = (void *)raw->data;
3537 boot_img = &fw->data[0];
0070f8c7
ZY
3538 ucode_img = &fw->data[le32_to_cpu(fw->boot_size)];
3539 fw_img = &fw->data[le32_to_cpu(fw->boot_size) +
3540 le32_to_cpu(fw->ucode_size)];
397ae121
ZY
3541
3542 if (rc < 0)
3543 goto error;
43f66a6c
JK
3544
3545 if (!priv->rxq)
3546 priv->rxq = ipw_rx_queue_alloc(priv);
3547 else
3548 ipw_rx_queue_reset(priv, priv->rxq);
3549 if (!priv->rxq) {
3550 IPW_ERROR("Unable to initialize Rx queue\n");
3551 goto error;
3552 }
3553
0edd5b44 3554 retry:
43f66a6c 3555 /* Ensure interrupts are disabled */
b095c381 3556 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
43f66a6c
JK
3557 priv->status &= ~STATUS_INT_ENABLED;
3558
3559 /* ack pending interrupts */
b095c381 3560 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
bf79451e 3561
43f66a6c
JK
3562 ipw_stop_nic(priv);
3563
3564 rc = ipw_reset_nic(priv);
397ae121 3565 if (rc < 0) {
43f66a6c
JK
3566 IPW_ERROR("Unable to reset NIC\n");
3567 goto error;
3568 }
3569
b095c381
JK
3570 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
3571 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
43f66a6c
JK
3572
3573 /* DMA the initial boot firmware into the device */
0070f8c7 3574 rc = ipw_load_firmware(priv, boot_img, le32_to_cpu(fw->boot_size));
43f66a6c 3575 if (rc < 0) {
a4f6bbb3 3576 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
43f66a6c
JK
3577 goto error;
3578 }
3579
3580 /* kick start the device */
3581 ipw_start_nic(priv);
3582
c7b6a674 3583 /* wait for the device to finish its initial startup sequence */
b095c381
JK
3584 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3585 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c
JK
3586 if (rc < 0) {
3587 IPW_ERROR("device failed to boot initial fw image\n");
3588 goto error;
3589 }
3590 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
3591
bf79451e 3592 /* ack fw init done interrupt */
b095c381 3593 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
43f66a6c
JK
3594
3595 /* DMA the ucode into the device */
0070f8c7 3596 rc = ipw_load_ucode(priv, ucode_img, le32_to_cpu(fw->ucode_size));
43f66a6c 3597 if (rc < 0) {
a4f6bbb3 3598 IPW_ERROR("Unable to load ucode: %d\n", rc);
43f66a6c
JK
3599 goto error;
3600 }
bf79451e 3601
43f66a6c
JK
3602 /* stop nic */
3603 ipw_stop_nic(priv);
3604
3605 /* DMA bss firmware into the device */
0070f8c7 3606 rc = ipw_load_firmware(priv, fw_img, le32_to_cpu(fw->fw_size));
0edd5b44 3607 if (rc < 0) {
a4f6bbb3 3608 IPW_ERROR("Unable to load firmware: %d\n", rc);
43f66a6c
JK
3609 goto error;
3610 }
397ae121
ZY
3611#ifdef CONFIG_PM
3612 fw_loaded = 1;
3613#endif
3614
43f66a6c
JK
3615 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
3616
3617 rc = ipw_queue_reset(priv);
397ae121 3618 if (rc < 0) {
43f66a6c
JK
3619 IPW_ERROR("Unable to initialize queues\n");
3620 goto error;
3621 }
3622
3623 /* Ensure interrupts are disabled */
b095c381 3624 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
c848d0af 3625 /* ack pending interrupts */
b095c381 3626 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
bf79451e 3627
43f66a6c
JK
3628 /* kick start the device */
3629 ipw_start_nic(priv);
3630
b095c381 3631 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
43f66a6c
JK
3632 if (retries > 0) {
3633 IPW_WARNING("Parity error. Retrying init.\n");
3634 retries--;
3635 goto retry;
3636 }
3637
3638 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");
3639 rc = -EIO;
3640 goto error;
3641 }
3642
3643 /* wait for the device */
b095c381
JK
3644 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3645 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c 3646 if (rc < 0) {
c7b6a674 3647 IPW_ERROR("device failed to start within 500ms\n");
43f66a6c
JK
3648 goto error;
3649 }
3650 IPW_DEBUG_INFO("device response after %dms\n", rc);
3651
3652 /* ack fw init done interrupt */
b095c381 3653 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
43f66a6c 3654
fdbfff73 3655 /* read eeprom data */
43f66a6c 3656 priv->eeprom_delay = 1;
fdbfff73
SY
3657 ipw_read_eeprom(priv);
3658 /* initialize the eeprom region of sram */
bf79451e 3659 ipw_eeprom_init_sram(priv);
43f66a6c
JK
3660
3661 /* enable interrupts */
3662 ipw_enable_interrupts(priv);
3663
3664 /* Ensure our queue has valid packets */
3665 ipw_rx_queue_replenish(priv);
3666
b095c381 3667 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
43f66a6c
JK
3668
3669 /* ack pending interrupts */
b095c381 3670 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
43f66a6c
JK
3671
3672#ifndef CONFIG_PM
9006ea75 3673 release_firmware(raw);
43f66a6c
JK
3674#endif
3675 return 0;
3676
0edd5b44 3677 error:
43f66a6c
JK
3678 if (priv->rxq) {
3679 ipw_rx_queue_free(priv, priv->rxq);
3680 priv->rxq = NULL;
3681 }
3682 ipw_tx_queue_free(priv);
d144f536 3683 release_firmware(raw);
43f66a6c
JK
3684#ifdef CONFIG_PM
3685 fw_loaded = 0;
9006ea75 3686 raw = NULL;
43f66a6c
JK
3687#endif
3688
3689 return rc;
3690}
3691
bf79451e 3692/**
43f66a6c
JK
3693 * DMA services
3694 *
3695 * Theory of operation
3696 *
3697 * A queue is a circular buffers with 'Read' and 'Write' pointers.
3698 * 2 empty entries always kept in the buffer to protect from overflow.
3699 *
3700 * For Tx queue, there are low mark and high mark limits. If, after queuing
bf79451e
JG
3701 * the packet for Tx, free space become < low mark, Tx queue stopped. When
3702 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
43f66a6c
JK
3703 * Tx queue resumed.
3704 *
3705 * The IPW operates with six queues, one receive queue in the device's
3706 * sram, one transmit queue for sending commands to the device firmware,
bf79451e 3707 * and four transmit queues for data.
43f66a6c 3708 *
bf79451e 3709 * The four transmit queues allow for performing quality of service (qos)
43f66a6c 3710 * transmissions as per the 802.11 protocol. Currently Linux does not
bf79451e 3711 * provide a mechanism to the user for utilizing prioritized queues, so
43f66a6c
JK
3712 * we only utilize the first data transmit queue (queue1).
3713 */
3714
3715/**
3716 * Driver allocates buffers of this size for Rx
3717 */
3718
943dbef4
DW
3719/**
3720 * ipw_rx_queue_space - Return number of free slots available in queue.
3721 */
3722static int ipw_rx_queue_space(const struct ipw_rx_queue *q)
3723{
3724 int s = q->read - q->write;
3725 if (s <= 0)
3726 s += RX_QUEUE_SIZE;
3727 /* keep some buffer to not confuse full and empty queue */
3728 s -= 2;
3729 if (s < 0)
3730 s = 0;
3731 return s;
3732}
3733
3734static inline int ipw_tx_queue_space(const struct clx2_queue *q)
43f66a6c
JK
3735{
3736 int s = q->last_used - q->first_empty;
3737 if (s <= 0)
3738 s += q->n_bd;
3739 s -= 2; /* keep some reserve to not confuse empty and full situations */
3740 if (s < 0)
3741 s = 0;
3742 return s;
3743}
3744
3745static inline int ipw_queue_inc_wrap(int index, int n_bd)
3746{
3747 return (++index == n_bd) ? 0 : index;
3748}
3749
3750/**
3751 * Initialize common DMA queue structure
bf79451e 3752 *
43f66a6c
JK
3753 * @param q queue to init
3754 * @param count Number of BD's to allocate. Should be power of 2
3755 * @param read_register Address for 'read' register
3756 * (not offset within BAR, full address)
3757 * @param write_register Address for 'write' register
3758 * (not offset within BAR, full address)
3759 * @param base_register Address for 'base' register
3760 * (not offset within BAR, full address)
3761 * @param size Address for 'size' register
3762 * (not offset within BAR, full address)
3763 */
bf79451e 3764static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,
0edd5b44 3765 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3766{
3767 q->n_bd = count;
3768
3769 q->low_mark = q->n_bd / 4;
3770 if (q->low_mark < 4)
3771 q->low_mark = 4;
3772
3773 q->high_mark = q->n_bd / 8;
3774 if (q->high_mark < 2)
3775 q->high_mark = 2;
3776
3777 q->first_empty = q->last_used = 0;
3778 q->reg_r = read;
3779 q->reg_w = write;
3780
3781 ipw_write32(priv, base, q->dma_addr);
3782 ipw_write32(priv, size, count);
3783 ipw_write32(priv, read, 0);
3784 ipw_write32(priv, write, 0);
3785
3786 _ipw_read32(priv, 0x90);
3787}
3788
bf79451e 3789static int ipw_queue_tx_init(struct ipw_priv *priv,
43f66a6c 3790 struct clx2_tx_queue *q,
0edd5b44 3791 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3792{
3793 struct pci_dev *dev = priv->pci_dev;
3794
3795 q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL);
3796 if (!q->txb) {
25985edc 3797 IPW_ERROR("vmalloc for auxiliary BD structures failed\n");
43f66a6c
JK
3798 return -ENOMEM;
3799 }
3800
0edd5b44
JG
3801 q->bd =
3802 pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr);
43f66a6c 3803 if (!q->bd) {
aaa4d308 3804 IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
0edd5b44 3805 sizeof(q->bd[0]) * count);
43f66a6c
JK
3806 kfree(q->txb);
3807 q->txb = NULL;
3808 return -ENOMEM;
3809 }
3810
3811 ipw_queue_init(priv, &q->q, count, read, write, base, size);
3812 return 0;
3813}
3814
3815/**
3816 * Free one TFD, those at index [txq->q.last_used].
3817 * Do NOT advance any indexes
bf79451e 3818 *
43f66a6c
JK
3819 * @param dev
3820 * @param txq
3821 */
3822static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
3823 struct clx2_tx_queue *txq)
3824{
3825 struct tfd_frame *bd = &txq->bd[txq->q.last_used];
3826 struct pci_dev *dev = priv->pci_dev;
3827 int i;
bf79451e 3828
43f66a6c
JK
3829 /* classify bd */
3830 if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE)
3831 /* nothing to cleanup after for host commands */
3832 return;
3833
3834 /* sanity check */
a613bffd
JK
3835 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
3836 IPW_ERROR("Too many chunks: %i\n",
3837 le32_to_cpu(bd->u.data.num_chunks));
43f66a6c
JK
3838 /** @todo issue fatal error, it is quite serious situation */
3839 return;
3840 }
3841
3842 /* unmap chunks if any */
a613bffd
JK
3843 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
3844 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
3845 le16_to_cpu(bd->u.data.chunk_len[i]),
3846 PCI_DMA_TODEVICE);
43f66a6c 3847 if (txq->txb[txq->q.last_used]) {
b0a4e7d8 3848 libipw_txb_free(txq->txb[txq->q.last_used]);
43f66a6c
JK
3849 txq->txb[txq->q.last_used] = NULL;
3850 }
3851 }
3852}
3853
3854/**
3855 * Deallocate DMA queue.
bf79451e 3856 *
43f66a6c
JK
3857 * Empty queue by removing and destroying all BD's.
3858 * Free all buffers.
bf79451e 3859 *
43f66a6c
JK
3860 * @param dev
3861 * @param q
3862 */
0edd5b44 3863static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)
43f66a6c
JK
3864{
3865 struct clx2_queue *q = &txq->q;
3866 struct pci_dev *dev = priv->pci_dev;
3867
bf79451e
JG
3868 if (q->n_bd == 0)
3869 return;
43f66a6c
JK
3870
3871 /* first, empty all BD's */
3872 for (; q->first_empty != q->last_used;
3873 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
3874 ipw_queue_tx_free_tfd(priv, txq);
3875 }
bf79451e 3876
43f66a6c 3877 /* free buffers belonging to queue itself */
0edd5b44 3878 pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
43f66a6c
JK
3879 q->dma_addr);
3880 kfree(txq->txb);
3881
3882 /* 0 fill whole structure */
3883 memset(txq, 0, sizeof(*txq));
3884}
3885
43f66a6c
JK
3886/**
3887 * Destroy all DMA queues and structures
bf79451e 3888 *
43f66a6c
JK
3889 * @param priv
3890 */
3891static void ipw_tx_queue_free(struct ipw_priv *priv)
3892{
3893 /* Tx CMD queue */
3894 ipw_queue_tx_free(priv, &priv->txq_cmd);
3895
3896 /* Tx queues */
3897 ipw_queue_tx_free(priv, &priv->txq[0]);
3898 ipw_queue_tx_free(priv, &priv->txq[1]);
3899 ipw_queue_tx_free(priv, &priv->txq[2]);
3900 ipw_queue_tx_free(priv, &priv->txq[3]);
3901}
3902
858119e1 3903static void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3904{
3905 /* First 3 bytes are manufacturer */
3906 bssid[0] = priv->mac_addr[0];
3907 bssid[1] = priv->mac_addr[1];
3908 bssid[2] = priv->mac_addr[2];
3909
3910 /* Last bytes are random */
0edd5b44 3911 get_random_bytes(&bssid[3], ETH_ALEN - 3);
43f66a6c 3912
0edd5b44
JG
3913 bssid[0] &= 0xfe; /* clear multicast bit */
3914 bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */
43f66a6c
JK
3915}
3916
858119e1 3917static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3918{
3919 struct ipw_station_entry entry;
3920 int i;
3921
3922 for (i = 0; i < priv->num_stations; i++) {
3923 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
3924 /* Another node is active in network */
3925 priv->missed_adhoc_beacons = 0;
3926 if (!(priv->config & CFG_STATIC_CHANNEL))
3927 /* when other nodes drop out, we drop out */
3928 priv->config &= ~CFG_ADHOC_PERSIST;
3929
3930 return i;
3931 }
3932 }
3933
3934 if (i == MAX_STATIONS)
3935 return IPW_INVALID_STATION;
3936
e174961c 3937 IPW_DEBUG_SCAN("Adding AdHoc station: %pM\n", bssid);
43f66a6c
JK
3938
3939 entry.reserved = 0;
3940 entry.support_mode = 0;
3941 memcpy(entry.mac_addr, bssid, ETH_ALEN);
3942 memcpy(priv->stations[i], bssid, ETH_ALEN);
3943 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),
0edd5b44 3944 &entry, sizeof(entry));
43f66a6c
JK
3945 priv->num_stations++;
3946
3947 return i;
3948}
3949
858119e1 3950static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3951{
3952 int i;
3953
bf79451e
JG
3954 for (i = 0; i < priv->num_stations; i++)
3955 if (!memcmp(priv->stations[i], bssid, ETH_ALEN))
43f66a6c
JK
3956 return i;
3957
3958 return IPW_INVALID_STATION;
3959}
3960
3961static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
3962{
3963 int err;
3964
7b99659f
HL
3965 if (priv->status & STATUS_ASSOCIATING) {
3966 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
bcb6d916 3967 schedule_work(&priv->disassociate);
7b99659f
HL
3968 return;
3969 }
3970
3971 if (!(priv->status & STATUS_ASSOCIATED)) {
43f66a6c
JK
3972 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
3973 return;
3974 }
3975
e174961c 3976 IPW_DEBUG_ASSOC("Disassocation attempt from %pM "
43f66a6c 3977 "on channel %d.\n",
e174961c 3978 priv->assoc_request.bssid,
43f66a6c
JK
3979 priv->assoc_request.channel);
3980
3981 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
3982 priv->status |= STATUS_DISASSOCIATING;
3983
3984 if (quiet)
3985 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
3986 else
3987 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
e6324726 3988
43f66a6c
JK
3989 err = ipw_send_associate(priv, &priv->assoc_request);
3990 if (err) {
3991 IPW_DEBUG_HC("Attempt to send [dis]associate command "
3992 "failed.\n");
3993 return;
3994 }
3995
3996}
3997
c848d0af 3998static int ipw_disassociate(void *data)
43f66a6c 3999{
c848d0af
JK
4000 struct ipw_priv *priv = data;
4001 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
4002 return 0;
43f66a6c 4003 ipw_send_disassociate(data, 0);
b8ddafd7 4004 netif_carrier_off(priv->net_dev);
c848d0af 4005 return 1;
43f66a6c
JK
4006}
4007
c4028958 4008static void ipw_bg_disassociate(struct work_struct *work)
43f66a6c 4009{
c4028958
DH
4010 struct ipw_priv *priv =
4011 container_of(work, struct ipw_priv, disassociate);
4644151b 4012 mutex_lock(&priv->mutex);
c4028958 4013 ipw_disassociate(priv);
4644151b 4014 mutex_unlock(&priv->mutex);
43f66a6c
JK
4015}
4016
c4028958 4017static void ipw_system_config(struct work_struct *work)
d8bad6df 4018{
c4028958
DH
4019 struct ipw_priv *priv =
4020 container_of(work, struct ipw_priv, system_config);
d685b8c2
ZY
4021
4022#ifdef CONFIG_IPW2200_PROMISCUOUS
4023 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
4024 priv->sys_config.accept_all_data_frames = 1;
4025 priv->sys_config.accept_non_directed_frames = 1;
4026 priv->sys_config.accept_all_mgmt_bcpr = 1;
4027 priv->sys_config.accept_all_mgmt_frames = 1;
4028 }
4029#endif
4030
4031 ipw_send_system_config(priv);
43f66a6c
JK
4032}
4033
4034struct ipw_status_code {
4035 u16 status;
4036 const char *reason;
4037};
4038
4039static const struct ipw_status_code ipw_status_codes[] = {
4040 {0x00, "Successful"},
4041 {0x01, "Unspecified failure"},
4042 {0x0A, "Cannot support all requested capabilities in the "
4043 "Capability information field"},
4044 {0x0B, "Reassociation denied due to inability to confirm that "
4045 "association exists"},
4046 {0x0C, "Association denied due to reason outside the scope of this "
4047 "standard"},
0edd5b44
JG
4048 {0x0D,
4049 "Responding station does not support the specified authentication "
43f66a6c 4050 "algorithm"},
0edd5b44
JG
4051 {0x0E,
4052 "Received an Authentication frame with authentication sequence "
43f66a6c
JK
4053 "transaction sequence number out of expected sequence"},
4054 {0x0F, "Authentication rejected because of challenge failure"},
4055 {0x10, "Authentication rejected due to timeout waiting for next "
4056 "frame in sequence"},
4057 {0x11, "Association denied because AP is unable to handle additional "
4058 "associated stations"},
0edd5b44
JG
4059 {0x12,
4060 "Association denied due to requesting station not supporting all "
43f66a6c 4061 "of the datarates in the BSSBasicServiceSet Parameter"},
0edd5b44
JG
4062 {0x13,
4063 "Association denied due to requesting station not supporting "
43f66a6c 4064 "short preamble operation"},
0edd5b44
JG
4065 {0x14,
4066 "Association denied due to requesting station not supporting "
43f66a6c 4067 "PBCC encoding"},
0edd5b44
JG
4068 {0x15,
4069 "Association denied due to requesting station not supporting "
43f66a6c 4070 "channel agility"},
0edd5b44
JG
4071 {0x19,
4072 "Association denied due to requesting station not supporting "
43f66a6c 4073 "short slot operation"},
0edd5b44
JG
4074 {0x1A,
4075 "Association denied due to requesting station not supporting "
43f66a6c
JK
4076 "DSSS-OFDM operation"},
4077 {0x28, "Invalid Information Element"},
4078 {0x29, "Group Cipher is not valid"},
4079 {0x2A, "Pairwise Cipher is not valid"},
4080 {0x2B, "AKMP is not valid"},
4081 {0x2C, "Unsupported RSN IE version"},
4082 {0x2D, "Invalid RSN IE Capabilities"},
4083 {0x2E, "Cipher suite is rejected per security policy"},
4084};
4085
bf79451e 4086static const char *ipw_get_status_code(u16 status)
43f66a6c
JK
4087{
4088 int i;
bf79451e 4089 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
ea2b26e0 4090 if (ipw_status_codes[i].status == (status & 0xff))
43f66a6c
JK
4091 return ipw_status_codes[i].reason;
4092 return "Unknown status value.";
4093}
43f66a6c
JK
4094
4095static void inline average_init(struct average *avg)
4096{
4097 memset(avg, 0, sizeof(*avg));
4098}
4099
00d21de5
ZY
4100#define DEPTH_RSSI 8
4101#define DEPTH_NOISE 16
4102static s16 exponential_average(s16 prev_avg, s16 val, u8 depth)
4103{
4104 return ((depth-1)*prev_avg + val)/depth;
4105}
4106
858119e1 4107static void average_add(struct average *avg, s16 val)
43f66a6c
JK
4108{
4109 avg->sum -= avg->entries[avg->pos];
4110 avg->sum += val;
4111 avg->entries[avg->pos++] = val;
4112 if (unlikely(avg->pos == AVG_ENTRIES)) {
4113 avg->init = 1;
4114 avg->pos = 0;
4115 }
4116}
4117
858119e1 4118static s16 average_value(struct average *avg)
43f66a6c
JK
4119{
4120 if (!unlikely(avg->init)) {
4121 if (avg->pos)
4122 return avg->sum / avg->pos;
4123 return 0;
4124 }
4125
4126 return avg->sum / AVG_ENTRIES;
4127}
4128
4129static void ipw_reset_stats(struct ipw_priv *priv)
4130{
4131 u32 len = sizeof(u32);
4132
4133 priv->quality = 0;
4134
4135 average_init(&priv->average_missed_beacons);
00d21de5
ZY
4136 priv->exp_avg_rssi = -60;
4137 priv->exp_avg_noise = -85 + 0x100;
43f66a6c
JK
4138
4139 priv->last_rate = 0;
4140 priv->last_missed_beacons = 0;
4141 priv->last_rx_packets = 0;
4142 priv->last_tx_packets = 0;
4143 priv->last_tx_failures = 0;
bf79451e 4144
43f66a6c
JK
4145 /* Firmware managed, reset only when NIC is restarted, so we have to
4146 * normalize on the current value */
bf79451e 4147 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,
43f66a6c 4148 &priv->last_rx_err, &len);
bf79451e 4149 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,
43f66a6c
JK
4150 &priv->last_tx_failures, &len);
4151
4152 /* Driver managed, reset with each association */
4153 priv->missed_adhoc_beacons = 0;
4154 priv->missed_beacons = 0;
4155 priv->tx_packets = 0;
4156 priv->rx_packets = 0;
4157
4158}
4159
858119e1 4160static u32 ipw_get_max_rate(struct ipw_priv *priv)
43f66a6c
JK
4161{
4162 u32 i = 0x80000000;
4163 u32 mask = priv->rates_mask;
4164 /* If currently associated in B mode, restrict the maximum
4165 * rate match to B rates */
4166 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
b0a4e7d8 4167 mask &= LIBIPW_CCK_RATES_MASK;
43f66a6c
JK
4168
4169 /* TODO: Verify that the rate is supported by the current rates
4170 * list. */
4171
0edd5b44
JG
4172 while (i && !(mask & i))
4173 i >>= 1;
43f66a6c 4174 switch (i) {
b0a4e7d8 4175 case LIBIPW_CCK_RATE_1MB_MASK:
ea2b26e0 4176 return 1000000;
b0a4e7d8 4177 case LIBIPW_CCK_RATE_2MB_MASK:
ea2b26e0 4178 return 2000000;
b0a4e7d8 4179 case LIBIPW_CCK_RATE_5MB_MASK:
ea2b26e0 4180 return 5500000;
b0a4e7d8 4181 case LIBIPW_OFDM_RATE_6MB_MASK:
ea2b26e0 4182 return 6000000;
b0a4e7d8 4183 case LIBIPW_OFDM_RATE_9MB_MASK:
ea2b26e0 4184 return 9000000;
b0a4e7d8 4185 case LIBIPW_CCK_RATE_11MB_MASK:
ea2b26e0 4186 return 11000000;
b0a4e7d8 4187 case LIBIPW_OFDM_RATE_12MB_MASK:
ea2b26e0 4188 return 12000000;
b0a4e7d8 4189 case LIBIPW_OFDM_RATE_18MB_MASK:
ea2b26e0 4190 return 18000000;
b0a4e7d8 4191 case LIBIPW_OFDM_RATE_24MB_MASK:
ea2b26e0 4192 return 24000000;
b0a4e7d8 4193 case LIBIPW_OFDM_RATE_36MB_MASK:
ea2b26e0 4194 return 36000000;
b0a4e7d8 4195 case LIBIPW_OFDM_RATE_48MB_MASK:
ea2b26e0 4196 return 48000000;
b0a4e7d8 4197 case LIBIPW_OFDM_RATE_54MB_MASK:
ea2b26e0 4198 return 54000000;
43f66a6c
JK
4199 }
4200
bf79451e 4201 if (priv->ieee->mode == IEEE_B)
43f66a6c
JK
4202 return 11000000;
4203 else
4204 return 54000000;
4205}
4206
4207static u32 ipw_get_current_rate(struct ipw_priv *priv)
4208{
4209 u32 rate, len = sizeof(rate);
4210 int err;
4211
bf79451e 4212 if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c
JK
4213 return 0;
4214
4215 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {
bf79451e 4216 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,
43f66a6c
JK
4217 &len);
4218 if (err) {
4219 IPW_DEBUG_INFO("failed querying ordinals.\n");
4220 return 0;
4221 }
bf79451e 4222 } else
43f66a6c
JK
4223 return ipw_get_max_rate(priv);
4224
4225 switch (rate) {
ea2b26e0
JK
4226 case IPW_TX_RATE_1MB:
4227 return 1000000;
4228 case IPW_TX_RATE_2MB:
4229 return 2000000;
4230 case IPW_TX_RATE_5MB:
4231 return 5500000;
4232 case IPW_TX_RATE_6MB:
4233 return 6000000;
4234 case IPW_TX_RATE_9MB:
4235 return 9000000;
4236 case IPW_TX_RATE_11MB:
4237 return 11000000;
4238 case IPW_TX_RATE_12MB:
4239 return 12000000;
4240 case IPW_TX_RATE_18MB:
4241 return 18000000;
4242 case IPW_TX_RATE_24MB:
4243 return 24000000;
4244 case IPW_TX_RATE_36MB:
4245 return 36000000;
4246 case IPW_TX_RATE_48MB:
4247 return 48000000;
4248 case IPW_TX_RATE_54MB:
4249 return 54000000;
43f66a6c
JK
4250 }
4251
4252 return 0;
4253}
4254
43f66a6c
JK
4255#define IPW_STATS_INTERVAL (2 * HZ)
4256static void ipw_gather_stats(struct ipw_priv *priv)
4257{
4258 u32 rx_err, rx_err_delta, rx_packets_delta;
4259 u32 tx_failures, tx_failures_delta, tx_packets_delta;
4260 u32 missed_beacons_percent, missed_beacons_delta;
4261 u32 quality = 0;
4262 u32 len = sizeof(u32);
4263 s16 rssi;
bf79451e 4264 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
0edd5b44 4265 rate_quality;
ea2b26e0 4266 u32 max_rate;
43f66a6c
JK
4267
4268 if (!(priv->status & STATUS_ASSOCIATED)) {
4269 priv->quality = 0;
4270 return;
4271 }
4272
4273 /* Update the statistics */
bf79451e 4274 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,
43f66a6c 4275 &priv->missed_beacons, &len);
0edd5b44 4276 missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons;
43f66a6c
JK
4277 priv->last_missed_beacons = priv->missed_beacons;
4278 if (priv->assoc_request.beacon_interval) {
4279 missed_beacons_percent = missed_beacons_delta *
5b5e807f 4280 (HZ * le16_to_cpu(priv->assoc_request.beacon_interval)) /
0edd5b44 4281 (IPW_STATS_INTERVAL * 10);
43f66a6c
JK
4282 } else {
4283 missed_beacons_percent = 0;
4284 }
4285 average_add(&priv->average_missed_beacons, missed_beacons_percent);
4286
4287 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);
4288 rx_err_delta = rx_err - priv->last_rx_err;
4289 priv->last_rx_err = rx_err;
4290
4291 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);
4292 tx_failures_delta = tx_failures - priv->last_tx_failures;
4293 priv->last_tx_failures = tx_failures;
4294
4295 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;
4296 priv->last_rx_packets = priv->rx_packets;
4297
4298 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;
4299 priv->last_tx_packets = priv->tx_packets;
4300
4301 /* Calculate quality based on the following:
bf79451e 4302 *
43f66a6c
JK
4303 * Missed beacon: 100% = 0, 0% = 70% missed
4304 * Rate: 60% = 1Mbs, 100% = Max
4305 * Rx and Tx errors represent a straight % of total Rx/Tx
4306 * RSSI: 100% = > -50, 0% = < -80
4307 * Rx errors: 100% = 0, 0% = 50% missed
bf79451e 4308 *
43f66a6c
JK
4309 * The lowest computed quality is used.
4310 *
4311 */
4312#define BEACON_THRESHOLD 5
4313 beacon_quality = 100 - missed_beacons_percent;
4314 if (beacon_quality < BEACON_THRESHOLD)
4315 beacon_quality = 0;
4316 else
bf79451e 4317 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /
0edd5b44 4318 (100 - BEACON_THRESHOLD);
bf79451e 4319 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",
43f66a6c 4320 beacon_quality, missed_beacons_percent);
bf79451e 4321
43f66a6c 4322 priv->last_rate = ipw_get_current_rate(priv);
ea2b26e0
JK
4323 max_rate = ipw_get_max_rate(priv);
4324 rate_quality = priv->last_rate * 40 / max_rate + 60;
43f66a6c
JK
4325 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
4326 rate_quality, priv->last_rate / 1000000);
bf79451e 4327
0edd5b44 4328 if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta)
bf79451e 4329 rx_quality = 100 - (rx_err_delta * 100) /
0edd5b44 4330 (rx_packets_delta + rx_err_delta);
43f66a6c
JK
4331 else
4332 rx_quality = 100;
4333 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",
4334 rx_quality, rx_err_delta, rx_packets_delta);
bf79451e 4335
0edd5b44 4336 if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta)
bf79451e 4337 tx_quality = 100 - (tx_failures_delta * 100) /
0edd5b44 4338 (tx_packets_delta + tx_failures_delta);
43f66a6c
JK
4339 else
4340 tx_quality = 100;
4341 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",
4342 tx_quality, tx_failures_delta, tx_packets_delta);
bf79451e 4343
00d21de5 4344 rssi = priv->exp_avg_rssi;
c848d0af
JK
4345 signal_quality =
4346 (100 *
4347 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4348 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4349 (priv->ieee->perfect_rssi - rssi) *
4350 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4351 62 * (priv->ieee->perfect_rssi - rssi))) /
4352 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4353 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4354 if (signal_quality > 100)
43f66a6c 4355 signal_quality = 100;
c848d0af 4356 else if (signal_quality < 1)
43f66a6c 4357 signal_quality = 0;
ea2b26e0 4358
61fb9ed9 4359 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
43f66a6c 4360 signal_quality, rssi);
bf79451e 4361
21f8a73f
RC
4362 quality = min(rx_quality, signal_quality);
4363 quality = min(tx_quality, quality);
4364 quality = min(rate_quality, quality);
4365 quality = min(beacon_quality, quality);
43f66a6c 4366 if (quality == beacon_quality)
0edd5b44
JG
4367 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
4368 quality);
43f66a6c 4369 if (quality == rate_quality)
0edd5b44
JG
4370 IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n",
4371 quality);
43f66a6c 4372 if (quality == tx_quality)
0edd5b44
JG
4373 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n",
4374 quality);
43f66a6c 4375 if (quality == rx_quality)
0edd5b44
JG
4376 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n",
4377 quality);
43f66a6c 4378 if (quality == signal_quality)
0edd5b44
JG
4379 IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n",
4380 quality);
43f66a6c
JK
4381
4382 priv->quality = quality;
bf79451e 4383
bcb6d916 4384 schedule_delayed_work(&priv->gather_stats, IPW_STATS_INTERVAL);
43f66a6c
JK
4385}
4386
c4028958 4387static void ipw_bg_gather_stats(struct work_struct *work)
c848d0af 4388{
c4028958
DH
4389 struct ipw_priv *priv =
4390 container_of(work, struct ipw_priv, gather_stats.work);
4644151b 4391 mutex_lock(&priv->mutex);
c4028958 4392 ipw_gather_stats(priv);
4644151b 4393 mutex_unlock(&priv->mutex);
c848d0af
JK
4394}
4395
e7582561
BC
4396/* Missed beacon behavior:
4397 * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
4398 * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
4399 * Above disassociate threshold, give up and stop scanning.
4400 * Roaming is disabled if disassociate_threshold <= roaming_threshold */
858119e1 4401static void ipw_handle_missed_beacon(struct ipw_priv *priv,
ea2b26e0
JK
4402 int missed_count)
4403{
4404 priv->notif_missed_beacons = missed_count;
4405
afbf30a2 4406 if (missed_count > priv->disassociate_threshold &&
ea2b26e0
JK
4407 priv->status & STATUS_ASSOCIATED) {
4408 /* If associated and we've hit the missed
4409 * beacon threshold, disassociate, turn
4410 * off roaming, and abort any active scans */
4411 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
afbf30a2 4412 IPW_DL_STATE | IPW_DL_ASSOC,
ea2b26e0
JK
4413 "Missed beacon: %d - disassociate\n", missed_count);
4414 priv->status &= ~STATUS_ROAMING;
a613bffd
JK
4415 if (priv->status & STATUS_SCANNING) {
4416 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4417 IPW_DL_STATE,
4418 "Aborting scan with missed beacon.\n");
bcb6d916 4419 schedule_work(&priv->abort_scan);
a613bffd
JK
4420 }
4421
bcb6d916 4422 schedule_work(&priv->disassociate);
ea2b26e0
JK
4423 return;
4424 }
4425
4426 if (priv->status & STATUS_ROAMING) {
4427 /* If we are currently roaming, then just
4428 * print a debug statement... */
4429 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4430 "Missed beacon: %d - roam in progress\n",
4431 missed_count);
4432 return;
4433 }
4434
4bfdb91d
ZY
4435 if (roaming &&
4436 (missed_count > priv->roaming_threshold &&
4437 missed_count <= priv->disassociate_threshold)) {
ea2b26e0 4438 /* If we are not already roaming, set the ROAM
e7582561
BC
4439 * bit in the status and kick off a scan.
4440 * This can happen several times before we reach
4441 * disassociate_threshold. */
ea2b26e0
JK
4442 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4443 "Missed beacon: %d - initiate "
4444 "roaming\n", missed_count);
4445 if (!(priv->status & STATUS_ROAMING)) {
4446 priv->status |= STATUS_ROAMING;
4447 if (!(priv->status & STATUS_SCANNING))
bcb6d916 4448 schedule_delayed_work(&priv->request_scan, 0);
ea2b26e0
JK
4449 }
4450 return;
4451 }
4452
14a4dfe2
HS
4453 if (priv->status & STATUS_SCANNING &&
4454 missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {
ea2b26e0
JK
4455 /* Stop scan to keep fw from getting
4456 * stuck (only if we aren't roaming --
4457 * otherwise we'll never scan more than 2 or 3
4458 * channels..) */
b095c381
JK
4459 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4460 "Aborting scan with missed beacon.\n");
bcb6d916 4461 schedule_work(&priv->abort_scan);
ea2b26e0
JK
4462 }
4463
4464 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
ea2b26e0
JK
4465}
4466
0b531676
DW
4467static void ipw_scan_event(struct work_struct *work)
4468{
4469 union iwreq_data wrqu;
4470
4471 struct ipw_priv *priv =
4472 container_of(work, struct ipw_priv, scan_event.work);
4473
4474 wrqu.data.length = 0;
4475 wrqu.data.flags = 0;
4476 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
4477}
4478
4479static void handle_scan_event(struct ipw_priv *priv)
4480{
4481 /* Only userspace-requested scan completion events go out immediately */
4482 if (!priv->user_requested_scan) {
4483 if (!delayed_work_pending(&priv->scan_event))
bcb6d916
TH
4484 schedule_delayed_work(&priv->scan_event,
4485 round_jiffies_relative(msecs_to_jiffies(4000)));
0b531676
DW
4486 } else {
4487 union iwreq_data wrqu;
4488
4489 priv->user_requested_scan = 0;
4490 cancel_delayed_work(&priv->scan_event);
4491
4492 wrqu.data.length = 0;
4493 wrqu.data.flags = 0;
4494 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
4495 }
4496}
4497
43f66a6c
JK
4498/**
4499 * Handle host notification packet.
4500 * Called from interrupt routine
4501 */
858119e1 4502static void ipw_rx_notification(struct ipw_priv *priv,
43f66a6c
JK
4503 struct ipw_rx_notification *notif)
4504{
9387b7ca 4505 DECLARE_SSID_BUF(ssid);
e62e1ee0 4506 u16 size = le16_to_cpu(notif->size);
a613bffd 4507
e62e1ee0 4508 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
bf79451e 4509
43f66a6c 4510 switch (notif->subtype) {
0edd5b44
JG
4511 case HOST_NOTIFICATION_STATUS_ASSOCIATED:{
4512 struct notif_association *assoc = &notif->u.assoc;
4513
4514 switch (assoc->state) {
4515 case CMAS_ASSOCIATED:{
4516 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4517 IPW_DL_ASSOC,
9fd1ea42 4518 "associated: '%s' %pM\n",
9387b7ca
JL
4519 print_ssid(ssid, priv->essid,
4520 priv->essid_len),
e174961c 4521 priv->bssid);
0edd5b44
JG
4522
4523 switch (priv->ieee->iw_mode) {
4524 case IW_MODE_INFRA:
4525 memcpy(priv->ieee->bssid,
4526 priv->bssid, ETH_ALEN);
4527 break;
4528
4529 case IW_MODE_ADHOC:
4530 memcpy(priv->ieee->bssid,
4531 priv->bssid, ETH_ALEN);
4532
4533 /* clear out the station table */
4534 priv->num_stations = 0;
4535
4536 IPW_DEBUG_ASSOC
4537 ("queueing adhoc check\n");
bcb6d916
TH
4538 schedule_delayed_work(
4539 &priv->adhoc_check,
4540 le16_to_cpu(priv->
4541 assoc_request.
4542 beacon_interval));
0edd5b44
JG
4543 break;
4544 }
4545
4546 priv->status &= ~STATUS_ASSOCIATING;
4547 priv->status |= STATUS_ASSOCIATED;
bcb6d916 4548 schedule_work(&priv->system_config);
0edd5b44 4549
e43e3c1e 4550#ifdef CONFIG_IPW2200_QOS
afbf30a2 4551#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
72118015 4552 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_control))
afbf30a2
JK
4553 if ((priv->status & STATUS_AUTH) &&
4554 (IPW_GET_PACKET_STYPE(&notif->u.raw)
4555 == IEEE80211_STYPE_ASSOC_RESP)) {
b095c381
JK
4556 if ((sizeof
4557 (struct
b0a4e7d8 4558 libipw_assoc_response)
e62e1ee0
AV
4559 <= size)
4560 && (size <= 2314)) {
b095c381 4561 struct
b0a4e7d8 4562 libipw_rx_stats
b095c381 4563 stats = {
e62e1ee0 4564 .len = size - 1,
b095c381
JK
4565 };
4566
4567 IPW_DEBUG_QOS
4568 ("QoS Associate "
e62e1ee0 4569 "size %d\n", size);
b0a4e7d8 4570 libipw_rx_mgt(priv->
b095c381
JK
4571 ieee,
4572 (struct
b0a4e7d8 4573 libipw_hdr_4addr
b095c381
JK
4574 *)
4575 &notif->u.raw, &stats);
4576 }
0edd5b44 4577 }
b095c381 4578#endif
0edd5b44 4579
a613bffd 4580 schedule_work(&priv->link_up);
43f66a6c 4581
0edd5b44
JG
4582 break;
4583 }
bf79451e 4584
0edd5b44
JG
4585 case CMAS_AUTHENTICATED:{
4586 if (priv->
4587 status & (STATUS_ASSOCIATED |
4588 STATUS_AUTH)) {
0edd5b44
JG
4589 struct notif_authenticate *auth
4590 = &notif->u.auth;
4591 IPW_DEBUG(IPW_DL_NOTIF |
4592 IPW_DL_STATE |
4593 IPW_DL_ASSOC,
4594 "deauthenticated: '%s' "
e174961c 4595 "%pM"
9fd1ea42 4596 ": (0x%04X) - %s\n",
9387b7ca
JL
4597 print_ssid(ssid,
4598 priv->
4599 essid,
4600 priv->
4601 essid_len),
e174961c 4602 priv->bssid,
83f7d57c 4603 le16_to_cpu(auth->status),
0edd5b44 4604 ipw_get_status_code
83f7d57c 4605 (le16_to_cpu
0edd5b44 4606 (auth->status)));
43f66a6c 4607
0edd5b44
JG
4608 priv->status &=
4609 ~(STATUS_ASSOCIATING |
4610 STATUS_AUTH |
4611 STATUS_ASSOCIATED);
4612
a613bffd 4613 schedule_work(&priv->link_down);
0edd5b44
JG
4614 break;
4615 }
4616
4617 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4618 IPW_DL_ASSOC,
e174961c 4619 "authenticated: '%s' %pM\n",
9387b7ca
JL
4620 print_ssid(ssid, priv->essid,
4621 priv->essid_len),
e174961c 4622 priv->bssid);
0edd5b44
JG
4623 break;
4624 }
4625
4626 case CMAS_INIT:{
ea2b26e0
JK
4627 if (priv->status & STATUS_AUTH) {
4628 struct
b0a4e7d8 4629 libipw_assoc_response
ea2b26e0
JK
4630 *resp;
4631 resp =
4632 (struct
b0a4e7d8 4633 libipw_assoc_response
ea2b26e0
JK
4634 *)&notif->u.raw;
4635 IPW_DEBUG(IPW_DL_NOTIF |
4636 IPW_DL_STATE |
4637 IPW_DL_ASSOC,
4638 "association failed (0x%04X): %s\n",
83f7d57c 4639 le16_to_cpu(resp->status),
ea2b26e0 4640 ipw_get_status_code
83f7d57c 4641 (le16_to_cpu
ea2b26e0
JK
4642 (resp->status)));
4643 }
4644
0edd5b44
JG
4645 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4646 IPW_DL_ASSOC,
9fd1ea42 4647 "disassociated: '%s' %pM\n",
9387b7ca
JL
4648 print_ssid(ssid, priv->essid,
4649 priv->essid_len),
e174961c 4650 priv->bssid);
0edd5b44
JG
4651
4652 priv->status &=
4653 ~(STATUS_DISASSOCIATING |
4654 STATUS_ASSOCIATING |
4655 STATUS_ASSOCIATED | STATUS_AUTH);
b095c381
JK
4656 if (priv->assoc_network
4657 && (priv->assoc_network->
4658 capability &
4659 WLAN_CAPABILITY_IBSS))
4660 ipw_remove_current_network
4661 (priv);
0edd5b44 4662
a613bffd 4663 schedule_work(&priv->link_down);
0edd5b44 4664
0edd5b44
JG
4665 break;
4666 }
43f66a6c 4667
b095c381
JK
4668 case CMAS_RX_ASSOC_RESP:
4669 break;
4670
0edd5b44
JG
4671 default:
4672 IPW_ERROR("assoc: unknown (%d)\n",
4673 assoc->state);
43f66a6c 4674 break;
bf79451e 4675 }
43f66a6c 4676
43f66a6c
JK
4677 break;
4678 }
bf79451e 4679
0edd5b44
JG
4680 case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{
4681 struct notif_authenticate *auth = &notif->u.auth;
4682 switch (auth->state) {
4683 case CMAS_AUTHENTICATED:
4684 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
9fd1ea42 4685 "authenticated: '%s' %pM\n",
9387b7ca
JL
4686 print_ssid(ssid, priv->essid,
4687 priv->essid_len),
e174961c 4688 priv->bssid);
0edd5b44
JG
4689 priv->status |= STATUS_AUTH;
4690 break;
43f66a6c 4691
0edd5b44
JG
4692 case CMAS_INIT:
4693 if (priv->status & STATUS_AUTH) {
4694 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4695 IPW_DL_ASSOC,
4696 "authentication failed (0x%04X): %s\n",
83f7d57c
AV
4697 le16_to_cpu(auth->status),
4698 ipw_get_status_code(le16_to_cpu
0edd5b44
JG
4699 (auth->
4700 status)));
4701 }
4702 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4703 IPW_DL_ASSOC,
e174961c 4704 "deauthenticated: '%s' %pM\n",
9387b7ca
JL
4705 print_ssid(ssid, priv->essid,
4706 priv->essid_len),
e174961c 4707 priv->bssid);
bf79451e 4708
0edd5b44
JG
4709 priv->status &= ~(STATUS_ASSOCIATING |
4710 STATUS_AUTH |
4711 STATUS_ASSOCIATED);
43f66a6c 4712
a613bffd 4713 schedule_work(&priv->link_down);
0edd5b44 4714 break;
43f66a6c 4715
0edd5b44
JG
4716 case CMAS_TX_AUTH_SEQ_1:
4717 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4718 IPW_DL_ASSOC, "AUTH_SEQ_1\n");
4719 break;
4720 case CMAS_RX_AUTH_SEQ_2:
4721 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4722 IPW_DL_ASSOC, "AUTH_SEQ_2\n");
4723 break;
4724 case CMAS_AUTH_SEQ_1_PASS:
4725 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4726 IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n");
4727 break;
4728 case CMAS_AUTH_SEQ_1_FAIL:
4729 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4730 IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n");
4731 break;
4732 case CMAS_TX_AUTH_SEQ_3:
4733 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4734 IPW_DL_ASSOC, "AUTH_SEQ_3\n");
4735 break;
4736 case CMAS_RX_AUTH_SEQ_4:
4737 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4738 IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n");
4739 break;
4740 case CMAS_AUTH_SEQ_2_PASS:
4741 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4742 IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n");
4743 break;
4744 case CMAS_AUTH_SEQ_2_FAIL:
4745 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4746 IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n");
4747 break;
4748 case CMAS_TX_ASSOC:
4749 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4750 IPW_DL_ASSOC, "TX_ASSOC\n");
4751 break;
4752 case CMAS_RX_ASSOC_RESP:
4753 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4754 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
b095c381 4755
0edd5b44
JG
4756 break;
4757 case CMAS_ASSOCIATED:
4758 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4759 IPW_DL_ASSOC, "ASSOCIATED\n");
4760 break;
4761 default:
4762 IPW_DEBUG_NOTIF("auth: failure - %d\n",
4763 auth->state);
4764 break;
43f66a6c 4765 }
43f66a6c
JK
4766 break;
4767 }
4768
0edd5b44
JG
4769 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{
4770 struct notif_channel_result *x =
4771 &notif->u.channel_result;
43f66a6c 4772
e62e1ee0 4773 if (size == sizeof(*x)) {
0edd5b44
JG
4774 IPW_DEBUG_SCAN("Scan result for channel %d\n",
4775 x->channel_num);
4776 } else {
4777 IPW_DEBUG_SCAN("Scan result of wrong size %d "
4778 "(should be %zd)\n",
e62e1ee0 4779 size, sizeof(*x));
bf79451e 4780 }
43f66a6c
JK
4781 break;
4782 }
43f66a6c 4783
0edd5b44
JG
4784 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{
4785 struct notif_scan_complete *x = &notif->u.scan_complete;
e62e1ee0 4786 if (size == sizeof(*x)) {
0edd5b44
JG
4787 IPW_DEBUG_SCAN
4788 ("Scan completed: type %d, %d channels, "
4789 "%d status\n", x->scan_type,
4790 x->num_channels, x->status);
4791 } else {
4792 IPW_ERROR("Scan completed of wrong size %d "
4793 "(should be %zd)\n",
e62e1ee0 4794 size, sizeof(*x));
0edd5b44 4795 }
43f66a6c 4796
0edd5b44
JG
4797 priv->status &=
4798 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
4799
a0e04ab3 4800 wake_up_interruptible(&priv->wait_state);
0edd5b44
JG
4801 cancel_delayed_work(&priv->scan_check);
4802
b095c381
JK
4803 if (priv->status & STATUS_EXIT_PENDING)
4804 break;
4805
4806 priv->ieee->scans++;
4807
4808#ifdef CONFIG_IPW2200_MONITOR
4809 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
afbf30a2 4810 priv->status |= STATUS_SCAN_FORCED;
bcb6d916 4811 schedule_delayed_work(&priv->request_scan, 0);
b095c381
JK
4812 break;
4813 }
afbf30a2 4814 priv->status &= ~STATUS_SCAN_FORCED;
b095c381
JK
4815#endif /* CONFIG_IPW2200_MONITOR */
4816
ea177305 4817 /* Do queued direct scans first */
bcb6d916
TH
4818 if (priv->status & STATUS_DIRECT_SCAN_PENDING)
4819 schedule_delayed_work(&priv->request_direct_scan, 0);
ea177305 4820
0edd5b44
JG
4821 if (!(priv->status & (STATUS_ASSOCIATED |
4822 STATUS_ASSOCIATING |
4823 STATUS_ROAMING |
4824 STATUS_DISASSOCIATING)))
bcb6d916 4825 schedule_work(&priv->associate);
0edd5b44 4826 else if (priv->status & STATUS_ROAMING) {
e7582561
BC
4827 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
4828 /* If a scan completed and we are in roam mode, then
4829 * the scan that completed was the one requested as a
4830 * result of entering roam... so, schedule the
4831 * roam work */
bcb6d916 4832 schedule_work(&priv->roam);
e7582561
BC
4833 else
4834 /* Don't schedule if we aborted the scan */
4835 priv->status &= ~STATUS_ROAMING;
0edd5b44 4836 } else if (priv->status & STATUS_SCAN_PENDING)
bcb6d916 4837 schedule_delayed_work(&priv->request_scan, 0);
a613bffd
JK
4838 else if (priv->config & CFG_BACKGROUND_SCAN
4839 && priv->status & STATUS_ASSOCIATED)
bcb6d916
TH
4840 schedule_delayed_work(&priv->request_scan,
4841 round_jiffies_relative(HZ));
07f02e46
ZY
4842
4843 /* Send an empty event to user space.
4844 * We don't send the received data on the event because
4845 * it would require us to do complex transcoding, and
4846 * we want to minimise the work done in the irq handler
4847 * Use a request to extract the data.
4848 * Also, we generate this even for any scan, regardless
4849 * on how the scan was initiated. User space can just
4850 * sync on periodic scan to get fresh data...
4851 * Jean II */
0b531676
DW
4852 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
4853 handle_scan_event(priv);
0edd5b44 4854 break;
43f66a6c 4855 }
43f66a6c 4856
0edd5b44
JG
4857 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
4858 struct notif_frag_length *x = &notif->u.frag_len;
43f66a6c 4859
e62e1ee0 4860 if (size == sizeof(*x))
a613bffd
JK
4861 IPW_ERROR("Frag length: %d\n",
4862 le16_to_cpu(x->frag_length));
4863 else
0edd5b44
JG
4864 IPW_ERROR("Frag length of wrong size %d "
4865 "(should be %zd)\n",
e62e1ee0 4866 size, sizeof(*x));
0edd5b44 4867 break;
43f66a6c 4868 }
43f66a6c 4869
0edd5b44
JG
4870 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
4871 struct notif_link_deterioration *x =
4872 &notif->u.link_deterioration;
afbf30a2 4873
e62e1ee0 4874 if (size == sizeof(*x)) {
0edd5b44 4875 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
12977154
BC
4876 "link deterioration: type %d, cnt %d\n",
4877 x->silence_notification_type,
4878 x->silence_count);
0edd5b44
JG
4879 memcpy(&priv->last_link_deterioration, x,
4880 sizeof(*x));
4881 } else {
4882 IPW_ERROR("Link Deterioration of wrong size %d "
4883 "(should be %zd)\n",
e62e1ee0 4884 size, sizeof(*x));
0edd5b44 4885 }
43f66a6c
JK
4886 break;
4887 }
4888
0edd5b44
JG
4889 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
4890 IPW_ERROR("Dino config\n");
4891 if (priv->hcmd
a613bffd 4892 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
0edd5b44 4893 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
a613bffd 4894
0edd5b44
JG
4895 break;
4896 }
43f66a6c 4897
0edd5b44
JG
4898 case HOST_NOTIFICATION_STATUS_BEACON_STATE:{
4899 struct notif_beacon_state *x = &notif->u.beacon_state;
e62e1ee0 4900 if (size != sizeof(*x)) {
0edd5b44
JG
4901 IPW_ERROR
4902 ("Beacon state of wrong size %d (should "
e62e1ee0 4903 "be %zd)\n", size, sizeof(*x));
0edd5b44 4904 break;
43f66a6c
JK
4905 }
4906
a613bffd
JK
4907 if (le32_to_cpu(x->state) ==
4908 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
4909 ipw_handle_missed_beacon(priv,
4910 le32_to_cpu(x->
4911 number));
43f66a6c 4912
0edd5b44
JG
4913 break;
4914 }
43f66a6c 4915
0edd5b44
JG
4916 case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{
4917 struct notif_tgi_tx_key *x = &notif->u.tgi_tx_key;
e62e1ee0 4918 if (size == sizeof(*x)) {
0edd5b44
JG
4919 IPW_ERROR("TGi Tx Key: state 0x%02x sec type "
4920 "0x%02x station %d\n",
4921 x->key_state, x->security_type,
4922 x->station_index);
4923 break;
4924 }
43f66a6c 4925
0edd5b44
JG
4926 IPW_ERROR
4927 ("TGi Tx Key of wrong size %d (should be %zd)\n",
e62e1ee0 4928 size, sizeof(*x));
43f66a6c 4929 break;
bf79451e 4930 }
43f66a6c 4931
0edd5b44
JG
4932 case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{
4933 struct notif_calibration *x = &notif->u.calibration;
43f66a6c 4934
e62e1ee0 4935 if (size == sizeof(*x)) {
0edd5b44
JG
4936 memcpy(&priv->calib, x, sizeof(*x));
4937 IPW_DEBUG_INFO("TODO: Calibration\n");
4938 break;
4939 }
43f66a6c 4940
0edd5b44
JG
4941 IPW_ERROR
4942 ("Calibration of wrong size %d (should be %zd)\n",
e62e1ee0 4943 size, sizeof(*x));
43f66a6c 4944 break;
bf79451e
JG
4945 }
4946
0edd5b44 4947 case HOST_NOTIFICATION_NOISE_STATS:{
e62e1ee0 4948 if (size == sizeof(u32)) {
00d21de5
ZY
4949 priv->exp_avg_noise =
4950 exponential_average(priv->exp_avg_noise,
4951 (u8) (le32_to_cpu(notif->u.noise.value) & 0xff),
4952 DEPTH_NOISE);
0edd5b44
JG
4953 break;
4954 }
43f66a6c 4955
0edd5b44
JG
4956 IPW_ERROR
4957 ("Noise stat is wrong size %d (should be %zd)\n",
e62e1ee0 4958 size, sizeof(u32));
43f66a6c
JK
4959 break;
4960 }
4961
43f66a6c 4962 default:
1dd31b6c
ZY
4963 IPW_DEBUG_NOTIF("Unknown notification: "
4964 "subtype=%d,flags=0x%2x,size=%d\n",
e62e1ee0 4965 notif->subtype, notif->flags, size);
43f66a6c
JK
4966 }
4967}
4968
4969/**
4970 * Destroys all DMA structures and initialise them again
bf79451e 4971 *
43f66a6c
JK
4972 * @param priv
4973 * @return error code
4974 */
4975static int ipw_queue_reset(struct ipw_priv *priv)
4976{
4977 int rc = 0;
4978 /** @todo customize queue sizes */
4979 int nTx = 64, nTxCmd = 8;
4980 ipw_tx_queue_free(priv);
4981 /* Tx CMD queue */
4982 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
b095c381
JK
4983 IPW_TX_CMD_QUEUE_READ_INDEX,
4984 IPW_TX_CMD_QUEUE_WRITE_INDEX,
4985 IPW_TX_CMD_QUEUE_BD_BASE,
4986 IPW_TX_CMD_QUEUE_BD_SIZE);
43f66a6c
JK
4987 if (rc) {
4988 IPW_ERROR("Tx Cmd queue init failed\n");
4989 goto error;
4990 }
4991 /* Tx queue(s) */
4992 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
b095c381
JK
4993 IPW_TX_QUEUE_0_READ_INDEX,
4994 IPW_TX_QUEUE_0_WRITE_INDEX,
4995 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
43f66a6c
JK
4996 if (rc) {
4997 IPW_ERROR("Tx 0 queue init failed\n");
4998 goto error;
4999 }
5000 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
b095c381
JK
5001 IPW_TX_QUEUE_1_READ_INDEX,
5002 IPW_TX_QUEUE_1_WRITE_INDEX,
5003 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
43f66a6c
JK
5004 if (rc) {
5005 IPW_ERROR("Tx 1 queue init failed\n");
5006 goto error;
5007 }
5008 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
b095c381
JK
5009 IPW_TX_QUEUE_2_READ_INDEX,
5010 IPW_TX_QUEUE_2_WRITE_INDEX,
5011 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
43f66a6c
JK
5012 if (rc) {
5013 IPW_ERROR("Tx 2 queue init failed\n");
5014 goto error;
5015 }
5016 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
b095c381
JK
5017 IPW_TX_QUEUE_3_READ_INDEX,
5018 IPW_TX_QUEUE_3_WRITE_INDEX,
5019 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
43f66a6c
JK
5020 if (rc) {
5021 IPW_ERROR("Tx 3 queue init failed\n");
5022 goto error;
5023 }
5024 /* statistics */
5025 priv->rx_bufs_min = 0;
5026 priv->rx_pend_max = 0;
5027 return rc;
5028
0edd5b44 5029 error:
43f66a6c
JK
5030 ipw_tx_queue_free(priv);
5031 return rc;
5032}
5033
5034/**
5035 * Reclaim Tx queue entries no more used by NIC.
bf79451e 5036 *
8ff9d21e 5037 * When FW advances 'R' index, all entries between old and
43f66a6c
JK
5038 * new 'R' index need to be reclaimed. As result, some free space
5039 * forms. If there is enough free space (> low mark), wake Tx queue.
bf79451e 5040 *
43f66a6c
JK
5041 * @note Need to protect against garbage in 'R' index
5042 * @param priv
5043 * @param txq
5044 * @param qindex
5045 * @return Number of used entries remains in the queue
5046 */
bf79451e 5047static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
5048 struct clx2_tx_queue *txq, int qindex)
5049{
5050 u32 hw_tail;
5051 int used;
5052 struct clx2_queue *q = &txq->q;
5053
5054 hw_tail = ipw_read32(priv, q->reg_r);
5055 if (hw_tail >= q->n_bd) {
5056 IPW_ERROR
0edd5b44
JG
5057 ("Read index for DMA queue (%d) is out of range [0-%d)\n",
5058 hw_tail, q->n_bd);
43f66a6c
JK
5059 goto done;
5060 }
5061 for (; q->last_used != hw_tail;
5062 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
5063 ipw_queue_tx_free_tfd(priv, txq);
5064 priv->tx_packets++;
5065 }
0edd5b44 5066 done:
943dbef4 5067 if ((ipw_tx_queue_space(q) > q->low_mark) &&
521c4d96 5068 (qindex >= 0))
9ddf84f6 5069 netif_wake_queue(priv->net_dev);
43f66a6c
JK
5070 used = q->first_empty - q->last_used;
5071 if (used < 0)
5072 used += q->n_bd;
5073
5074 return used;
5075}
5076
5077static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
5078 int len, int sync)
5079{
5080 struct clx2_tx_queue *txq = &priv->txq_cmd;
5081 struct clx2_queue *q = &txq->q;
5082 struct tfd_frame *tfd;
5083
943dbef4 5084 if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) {
43f66a6c
JK
5085 IPW_ERROR("No space for Tx\n");
5086 return -EBUSY;
5087 }
5088
5089 tfd = &txq->bd[q->first_empty];
5090 txq->txb[q->first_empty] = NULL;
5091
5092 memset(tfd, 0, sizeof(*tfd));
5093 tfd->control_flags.message_type = TX_HOST_COMMAND_TYPE;
5094 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
5095 priv->hcmd_seq++;
5096 tfd->u.cmd.index = hcmd;
5097 tfd->u.cmd.length = len;
5098 memcpy(tfd->u.cmd.payload, buf, len);
5099 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
5100 ipw_write32(priv, q->reg_w, q->first_empty);
5101 _ipw_read32(priv, 0x90);
5102
5103 return 0;
5104}
5105
bf79451e 5106/*
43f66a6c
JK
5107 * Rx theory of operation
5108 *
5109 * The host allocates 32 DMA target addresses and passes the host address
b095c381 5110 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
43f66a6c
JK
5111 * 0 to 31
5112 *
5113 * Rx Queue Indexes
5114 * The host/firmware share two index registers for managing the Rx buffers.
5115 *
bf79451e
JG
5116 * The READ index maps to the first position that the firmware may be writing
5117 * to -- the driver can read up to (but not including) this position and get
5118 * good data.
43f66a6c
JK
5119 * The READ index is managed by the firmware once the card is enabled.
5120 *
5121 * The WRITE index maps to the last position the driver has read from -- the
5122 * position preceding WRITE is the last slot the firmware can place a packet.
5123 *
5124 * The queue is empty (no good data) if WRITE = READ - 1, and is full if
bf79451e 5125 * WRITE = READ.
43f66a6c 5126 *
bf79451e 5127 * During initialization the host sets up the READ queue position to the first
43f66a6c
JK
5128 * INDEX position, and WRITE to the last (READ - 1 wrapped)
5129 *
5130 * When the firmware places a packet in a buffer it will advance the READ index
5131 * and fire the RX interrupt. The driver can then query the READ index and
5132 * process as many packets as possible, moving the WRITE index forward as it
5133 * resets the Rx queue buffers with new memory.
bf79451e 5134 *
43f66a6c 5135 * The management in the driver is as follows:
bf79451e 5136 * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When
43f66a6c 5137 * ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
bf79451e 5138 * to replensish the ipw->rxq->rx_free.
43f66a6c
JK
5139 * + In ipw_rx_queue_replenish (scheduled) if 'processed' != 'read' then the
5140 * ipw->rxq is replenished and the READ INDEX is updated (updating the
5141 * 'processed' and 'read' driver indexes as well)
5142 * + A received packet is processed and handed to the kernel network stack,
5143 * detached from the ipw->rxq. The driver 'processed' index is updated.
5144 * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free
bf79451e
JG
5145 * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ
5146 * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there
43f66a6c
JK
5147 * were enough free buffers and RX_STALLED is set it is cleared.
5148 *
5149 *
5150 * Driver sequence:
5151 *
bf79451e 5152 * ipw_rx_queue_alloc() Allocates rx_free
43f66a6c
JK
5153 * ipw_rx_queue_replenish() Replenishes rx_free list from rx_used, and calls
5154 * ipw_rx_queue_restock
5155 * ipw_rx_queue_restock() Moves available buffers from rx_free into Rx
5156 * queue, updates firmware pointers, and updates
5157 * the WRITE index. If insufficient rx_free buffers
5158 * are available, schedules ipw_rx_queue_replenish
5159 *
5160 * -- enable interrupts --
5161 * ISR - ipw_rx() Detach ipw_rx_mem_buffers from pool up to the
bf79451e 5162 * READ INDEX, detaching the SKB from the pool.
43f66a6c
JK
5163 * Moves the packet buffer from queue to rx_used.
5164 * Calls ipw_rx_queue_restock to refill any empty
5165 * slots.
5166 * ...
5167 *
5168 */
5169
bf79451e 5170/*
43f66a6c
JK
5171 * If there are slots in the RX queue that need to be restocked,
5172 * and we have free pre-allocated buffers, fill the ranks as much
5173 * as we can pulling from rx_free.
5174 *
5175 * This moves the 'write' index forward to catch up with 'processed', and
5176 * also updates the memory address in the firmware to reference the new
5177 * target buffer.
5178 */
5179static void ipw_rx_queue_restock(struct ipw_priv *priv)
5180{
5181 struct ipw_rx_queue *rxq = priv->rxq;
5182 struct list_head *element;
5183 struct ipw_rx_mem_buffer *rxb;
5184 unsigned long flags;
5185 int write;
5186
5187 spin_lock_irqsave(&rxq->lock, flags);
5188 write = rxq->write;
943dbef4 5189 while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
43f66a6c
JK
5190 element = rxq->rx_free.next;
5191 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
5192 list_del(element);
5193
b095c381 5194 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
43f66a6c
JK
5195 rxb->dma_addr);
5196 rxq->queue[rxq->write] = rxb;
5197 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
5198 rxq->free_count--;
5199 }
5200 spin_unlock_irqrestore(&rxq->lock, flags);
5201
bf79451e 5202 /* If the pre-allocated buffer pool is dropping low, schedule to
43f66a6c
JK
5203 * refill it */
5204 if (rxq->free_count <= RX_LOW_WATERMARK)
bcb6d916 5205 schedule_work(&priv->rx_replenish);
43f66a6c
JK
5206
5207 /* If we've added more space for the firmware to place data, tell it */
bf79451e 5208 if (write != rxq->write)
b095c381 5209 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
43f66a6c
JK
5210}
5211
5212/*
5213 * Move all used packet from rx_used to rx_free, allocating a new SKB for each.
bf79451e
JG
5214 * Also restock the Rx queue via ipw_rx_queue_restock.
5215 *
43f66a6c
JK
5216 * This is called as a scheduled work item (except for during intialization)
5217 */
5218static void ipw_rx_queue_replenish(void *data)
5219{
5220 struct ipw_priv *priv = data;
5221 struct ipw_rx_queue *rxq = priv->rxq;
5222 struct list_head *element;
5223 struct ipw_rx_mem_buffer *rxb;
5224 unsigned long flags;
5225
5226 spin_lock_irqsave(&rxq->lock, flags);
5227 while (!list_empty(&rxq->rx_used)) {
5228 element = rxq->rx_used.next;
5229 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
b095c381 5230 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
43f66a6c
JK
5231 if (!rxb->skb) {
5232 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
5233 priv->net_dev->name);
5234 /* We don't reschedule replenish work here -- we will
5235 * call the restock method and if it still needs
5236 * more buffers it will schedule replenish */
5237 break;
5238 }
5239 list_del(element);
bf79451e 5240
0edd5b44
JG
5241 rxb->dma_addr =
5242 pci_map_single(priv->pci_dev, rxb->skb->data,
b095c381 5243 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
bf79451e 5244
43f66a6c
JK
5245 list_add_tail(&rxb->list, &rxq->rx_free);
5246 rxq->free_count++;
5247 }
5248 spin_unlock_irqrestore(&rxq->lock, flags);
5249
5250 ipw_rx_queue_restock(priv);
5251}
5252
c4028958 5253static void ipw_bg_rx_queue_replenish(struct work_struct *work)
c848d0af 5254{
c4028958
DH
5255 struct ipw_priv *priv =
5256 container_of(work, struct ipw_priv, rx_replenish);
4644151b 5257 mutex_lock(&priv->mutex);
c4028958 5258 ipw_rx_queue_replenish(priv);
4644151b 5259 mutex_unlock(&priv->mutex);
c848d0af
JK
5260}
5261
43f66a6c 5262/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
c7b6a674 5263 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
bf79451e 5264 * This free routine walks the list of POOL entries and if SKB is set to
43f66a6c
JK
5265 * non NULL it is unmapped and freed
5266 */
0edd5b44 5267static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
43f66a6c
JK
5268{
5269 int i;
5270
5271 if (!rxq)
5272 return;
bf79451e 5273
43f66a6c
JK
5274 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
5275 if (rxq->pool[i].skb != NULL) {
5276 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
b095c381 5277 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c
JK
5278 dev_kfree_skb(rxq->pool[i].skb);
5279 }
5280 }
5281
5282 kfree(rxq);
5283}
5284
5285static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
5286{
5287 struct ipw_rx_queue *rxq;
5288 int i;
5289
c75f4742 5290 rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);
ad18b0ea
PI
5291 if (unlikely(!rxq)) {
5292 IPW_ERROR("memory allocation failed\n");
5293 return NULL;
5294 }
43f66a6c
JK
5295 spin_lock_init(&rxq->lock);
5296 INIT_LIST_HEAD(&rxq->rx_free);
5297 INIT_LIST_HEAD(&rxq->rx_used);
5298
5299 /* Fill the rx_used queue with _all_ of the Rx buffers */
bf79451e 5300 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
43f66a6c
JK
5301 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
5302
5303 /* Set us so that we have processed and used all buffers, but have
5304 * not restocked the Rx queue with fresh buffers */
5305 rxq->read = rxq->write = 0;
43f66a6c
JK
5306 rxq->free_count = 0;
5307
5308 return rxq;
5309}
5310
5311static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
5312{
b0a4e7d8 5313 rate &= ~LIBIPW_BASIC_RATE_MASK;
43f66a6c
JK
5314 if (ieee_mode == IEEE_A) {
5315 switch (rate) {
b0a4e7d8
JL
5316 case LIBIPW_OFDM_RATE_6MB:
5317 return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ?
0edd5b44 5318 1 : 0;
b0a4e7d8
JL
5319 case LIBIPW_OFDM_RATE_9MB:
5320 return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ?
0edd5b44 5321 1 : 0;
b0a4e7d8 5322 case LIBIPW_OFDM_RATE_12MB:
0edd5b44 5323 return priv->
b0a4e7d8
JL
5324 rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;
5325 case LIBIPW_OFDM_RATE_18MB:
0edd5b44 5326 return priv->
b0a4e7d8
JL
5327 rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;
5328 case LIBIPW_OFDM_RATE_24MB:
0edd5b44 5329 return priv->
b0a4e7d8
JL
5330 rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;
5331 case LIBIPW_OFDM_RATE_36MB:
0edd5b44 5332 return priv->
b0a4e7d8
JL
5333 rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;
5334 case LIBIPW_OFDM_RATE_48MB:
0edd5b44 5335 return priv->
b0a4e7d8
JL
5336 rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;
5337 case LIBIPW_OFDM_RATE_54MB:
0edd5b44 5338 return priv->
b0a4e7d8 5339 rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;
43f66a6c
JK
5340 default:
5341 return 0;
5342 }
5343 }
bf79451e 5344
43f66a6c
JK
5345 /* B and G mixed */
5346 switch (rate) {
b0a4e7d8
JL
5347 case LIBIPW_CCK_RATE_1MB:
5348 return priv->rates_mask & LIBIPW_CCK_RATE_1MB_MASK ? 1 : 0;
5349 case LIBIPW_CCK_RATE_2MB:
5350 return priv->rates_mask & LIBIPW_CCK_RATE_2MB_MASK ? 1 : 0;
5351 case LIBIPW_CCK_RATE_5MB:
5352 return priv->rates_mask & LIBIPW_CCK_RATE_5MB_MASK ? 1 : 0;
5353 case LIBIPW_CCK_RATE_11MB:
5354 return priv->rates_mask & LIBIPW_CCK_RATE_11MB_MASK ? 1 : 0;
43f66a6c
JK
5355 }
5356
5357 /* If we are limited to B modulations, bail at this point */
5358 if (ieee_mode == IEEE_B)
5359 return 0;
5360
5361 /* G */
5362 switch (rate) {
b0a4e7d8
JL
5363 case LIBIPW_OFDM_RATE_6MB:
5364 return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ? 1 : 0;
5365 case LIBIPW_OFDM_RATE_9MB:
5366 return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ? 1 : 0;
5367 case LIBIPW_OFDM_RATE_12MB:
5368 return priv->rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;
5369 case LIBIPW_OFDM_RATE_18MB:
5370 return priv->rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;
5371 case LIBIPW_OFDM_RATE_24MB:
5372 return priv->rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;
5373 case LIBIPW_OFDM_RATE_36MB:
5374 return priv->rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;
5375 case LIBIPW_OFDM_RATE_48MB:
5376 return priv->rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;
5377 case LIBIPW_OFDM_RATE_54MB:
5378 return priv->rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;
43f66a6c
JK
5379 }
5380
5381 return 0;
5382}
5383
bf79451e 5384static int ipw_compatible_rates(struct ipw_priv *priv,
b0a4e7d8 5385 const struct libipw_network *network,
43f66a6c
JK
5386 struct ipw_supported_rates *rates)
5387{
5388 int num_rates, i;
5389
5390 memset(rates, 0, sizeof(*rates));
0edd5b44 5391 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
43f66a6c
JK
5392 rates->num_rates = 0;
5393 for (i = 0; i < num_rates; i++) {
a613bffd
JK
5394 if (!ipw_is_rate_in_mask(priv, network->mode,
5395 network->rates[i])) {
5396
b0a4e7d8 5397 if (network->rates[i] & LIBIPW_BASIC_RATE_MASK) {
a613bffd
JK
5398 IPW_DEBUG_SCAN("Adding masked mandatory "
5399 "rate %02X\n",
5400 network->rates[i]);
5401 rates->supported_rates[rates->num_rates++] =
5402 network->rates[i];
5403 continue;
ea2b26e0
JK
5404 }
5405
43f66a6c
JK
5406 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
5407 network->rates[i], priv->rates_mask);
5408 continue;
5409 }
bf79451e 5410
43f66a6c
JK
5411 rates->supported_rates[rates->num_rates++] = network->rates[i];
5412 }
5413
a613bffd
JK
5414 num_rates = min(network->rates_ex_len,
5415 (u8) (IPW_MAX_RATES - num_rates));
43f66a6c 5416 for (i = 0; i < num_rates; i++) {
a613bffd
JK
5417 if (!ipw_is_rate_in_mask(priv, network->mode,
5418 network->rates_ex[i])) {
b0a4e7d8 5419 if (network->rates_ex[i] & LIBIPW_BASIC_RATE_MASK) {
a613bffd
JK
5420 IPW_DEBUG_SCAN("Adding masked mandatory "
5421 "rate %02X\n",
5422 network->rates_ex[i]);
5423 rates->supported_rates[rates->num_rates++] =
5424 network->rates[i];
5425 continue;
ea2b26e0
JK
5426 }
5427
43f66a6c
JK
5428 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
5429 network->rates_ex[i], priv->rates_mask);
5430 continue;
5431 }
bf79451e 5432
0edd5b44
JG
5433 rates->supported_rates[rates->num_rates++] =
5434 network->rates_ex[i];
43f66a6c
JK
5435 }
5436
ea2b26e0 5437 return 1;
43f66a6c
JK
5438}
5439
858119e1 5440static void ipw_copy_rates(struct ipw_supported_rates *dest,
43f66a6c
JK
5441 const struct ipw_supported_rates *src)
5442{
5443 u8 i;
5444 for (i = 0; i < src->num_rates; i++)
5445 dest->supported_rates[i] = src->supported_rates[i];
5446 dest->num_rates = src->num_rates;
5447}
5448
5449/* TODO: Look at sniffed packets in the air to determine if the basic rate
5450 * mask should ever be used -- right now all callers to add the scan rates are
5451 * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */
5452static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 5453 u8 modulation, u32 rate_mask)
43f66a6c 5454{
b0a4e7d8
JL
5455 u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?
5456 LIBIPW_BASIC_RATE_MASK : 0;
bf79451e 5457
b0a4e7d8 5458 if (rate_mask & LIBIPW_CCK_RATE_1MB_MASK)
bf79451e 5459 rates->supported_rates[rates->num_rates++] =
b0a4e7d8 5460 LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_1MB;
43f66a6c 5461
b0a4e7d8 5462 if (rate_mask & LIBIPW_CCK_RATE_2MB_MASK)
bf79451e 5463 rates->supported_rates[rates->num_rates++] =
b0a4e7d8 5464 LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_2MB;
43f66a6c 5465
b0a4e7d8 5466 if (rate_mask & LIBIPW_CCK_RATE_5MB_MASK)
bf79451e 5467 rates->supported_rates[rates->num_rates++] = basic_mask |
b0a4e7d8 5468 LIBIPW_CCK_RATE_5MB;
43f66a6c 5469
b0a4e7d8 5470 if (rate_mask & LIBIPW_CCK_RATE_11MB_MASK)
bf79451e 5471 rates->supported_rates[rates->num_rates++] = basic_mask |
b0a4e7d8 5472 LIBIPW_CCK_RATE_11MB;
43f66a6c
JK
5473}
5474
5475static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 5476 u8 modulation, u32 rate_mask)
43f66a6c 5477{
b0a4e7d8
JL
5478 u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?
5479 LIBIPW_BASIC_RATE_MASK : 0;
43f66a6c 5480
b0a4e7d8 5481 if (rate_mask & LIBIPW_OFDM_RATE_6MB_MASK)
bf79451e 5482 rates->supported_rates[rates->num_rates++] = basic_mask |
b0a4e7d8 5483 LIBIPW_OFDM_RATE_6MB;
43f66a6c 5484
b0a4e7d8 5485 if (rate_mask & LIBIPW_OFDM_RATE_9MB_MASK)
bf79451e 5486 rates->supported_rates[rates->num_rates++] =
b0a4e7d8 5487 LIBIPW_OFDM_RATE_9MB;
43f66a6c 5488
b0a4e7d8 5489 if (rate_mask & LIBIPW_OFDM_RATE_12MB_MASK)
bf79451e 5490 rates->supported_rates[rates->num_rates++] = basic_mask |
b0a4e7d8 5491 LIBIPW_OFDM_RATE_12MB;
43f66a6c 5492
b0a4e7d8 5493 if (rate_mask & LIBIPW_OFDM_RATE_18MB_MASK)
bf79451e 5494 rates->supported_rates[rates->num_rates++] =
b0a4e7d8 5495 LIBIPW_OFDM_RATE_18MB;
43f66a6c 5496
b0a4e7d8 5497 if (rate_mask & LIBIPW_OFDM_RATE_24MB_MASK)
bf79451e 5498 rates->supported_rates[rates->num_rates++] = basic_mask |
b0a4e7d8 5499 LIBIPW_OFDM_RATE_24MB;
43f66a6c 5500
b0a4e7d8 5501 if (rate_mask & LIBIPW_OFDM_RATE_36MB_MASK)
bf79451e 5502 rates->supported_rates[rates->num_rates++] =
b0a4e7d8 5503 LIBIPW_OFDM_RATE_36MB;
43f66a6c 5504
b0a4e7d8 5505 if (rate_mask & LIBIPW_OFDM_RATE_48MB_MASK)
bf79451e 5506 rates->supported_rates[rates->num_rates++] =
b0a4e7d8 5507 LIBIPW_OFDM_RATE_48MB;
43f66a6c 5508
b0a4e7d8 5509 if (rate_mask & LIBIPW_OFDM_RATE_54MB_MASK)
bf79451e 5510 rates->supported_rates[rates->num_rates++] =
b0a4e7d8 5511 LIBIPW_OFDM_RATE_54MB;
43f66a6c
JK
5512}
5513
5514struct ipw_network_match {
b0a4e7d8 5515 struct libipw_network *network;
43f66a6c
JK
5516 struct ipw_supported_rates rates;
5517};
5518
c848d0af
JK
5519static int ipw_find_adhoc_network(struct ipw_priv *priv,
5520 struct ipw_network_match *match,
b0a4e7d8 5521 struct libipw_network *network,
c848d0af 5522 int roaming)
43f66a6c
JK
5523{
5524 struct ipw_supported_rates rates;
9387b7ca 5525 DECLARE_SSID_BUF(ssid);
43f66a6c
JK
5526
5527 /* Verify that this network's capability is compatible with the
5528 * current mode (AdHoc or Infrastructure) */
c848d0af 5529 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
43f66a6c 5530 !(network->capability & WLAN_CAPABILITY_IBSS))) {
e174961c 5531 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to "
bf79451e 5532 "capability mismatch.\n",
9387b7ca
JL
5533 print_ssid(ssid, network->ssid,
5534 network->ssid_len),
e174961c 5535 network->bssid);
43f66a6c
JK
5536 return 0;
5537 }
5538
43f66a6c
JK
5539 if (unlikely(roaming)) {
5540 /* If we are roaming, then ensure check if this is a valid
5541 * network to try and roam to */
5542 if ((network->ssid_len != match->network->ssid_len) ||
bf79451e 5543 memcmp(network->ssid, match->network->ssid,
43f66a6c 5544 network->ssid_len)) {
e174961c 5545 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
43f66a6c 5546 "because of non-network ESSID.\n",
9387b7ca
JL
5547 print_ssid(ssid, network->ssid,
5548 network->ssid_len),
e174961c 5549 network->bssid);
43f66a6c
JK
5550 return 0;
5551 }
5552 } else {
bf79451e
JG
5553 /* If an ESSID has been configured then compare the broadcast
5554 * ESSID to ours */
5555 if ((priv->config & CFG_STATIC_ESSID) &&
43f66a6c 5556 ((network->ssid_len != priv->essid_len) ||
bf79451e 5557 memcmp(network->ssid, priv->essid,
43f66a6c
JK
5558 min(network->ssid_len, priv->essid_len)))) {
5559 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
afbf30a2 5560
0edd5b44 5561 strncpy(escaped,
9387b7ca
JL
5562 print_ssid(ssid, network->ssid,
5563 network->ssid_len),
43f66a6c 5564 sizeof(escaped));
e174961c 5565 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
bf79451e 5566 "because of ESSID mismatch: '%s'.\n",
e174961c 5567 escaped, network->bssid,
9387b7ca
JL
5568 print_ssid(ssid, priv->essid,
5569 priv->essid_len));
43f66a6c
JK
5570 return 0;
5571 }
5572 }
5573
5574 /* If the old network rate is better than this one, don't bother
5575 * testing everything else. */
c848d0af
JK
5576
5577 if (network->time_stamp[0] < match->network->time_stamp[0]) {
afbf30a2
JK
5578 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5579 "current network.\n",
9387b7ca
JL
5580 print_ssid(ssid, match->network->ssid,
5581 match->network->ssid_len));
43f66a6c 5582 return 0;
c848d0af 5583 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
afbf30a2
JK
5584 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5585 "current network.\n",
9387b7ca
JL
5586 print_ssid(ssid, match->network->ssid,
5587 match->network->ssid_len));
43f66a6c
JK
5588 return 0;
5589 }
5590
5591 /* Now go through and see if the requested network is valid... */
bf79451e 5592 if (priv->ieee->scan_age != 0 &&
c848d0af 5593 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
e174961c 5594 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
c7b6a674 5595 "because of age: %ums.\n",
9387b7ca
JL
5596 print_ssid(ssid, network->ssid,
5597 network->ssid_len),
e174961c 5598 network->bssid,
2638bc39
ZY
5599 jiffies_to_msecs(jiffies -
5600 network->last_scanned));
43f66a6c 5601 return 0;
bf79451e 5602 }
43f66a6c 5603
bf79451e 5604 if ((priv->config & CFG_STATIC_CHANNEL) &&
43f66a6c 5605 (network->channel != priv->channel)) {
e174961c 5606 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
43f66a6c 5607 "because of channel mismatch: %d != %d.\n",
9387b7ca
JL
5608 print_ssid(ssid, network->ssid,
5609 network->ssid_len),
e174961c 5610 network->bssid,
43f66a6c
JK
5611 network->channel, priv->channel);
5612 return 0;
5613 }
bf79451e 5614
25985edc 5615 /* Verify privacy compatibility */
bf79451e 5616 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
43f66a6c 5617 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
e174961c 5618 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
43f66a6c 5619 "because of privacy mismatch: %s != %s.\n",
9387b7ca
JL
5620 print_ssid(ssid, network->ssid,
5621 network->ssid_len),
e174961c 5622 network->bssid,
afbf30a2
JK
5623 priv->
5624 capability & CAP_PRIVACY_ON ? "on" : "off",
5625 network->
5626 capability & WLAN_CAPABILITY_PRIVACY ? "on" :
5627 "off");
43f66a6c
JK
5628 return 0;
5629 }
bf79451e 5630
c848d0af 5631 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
e174961c
JB
5632 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
5633 "because of the same BSSID match: %pM"
9387b7ca
JL
5634 ".\n", print_ssid(ssid, network->ssid,
5635 network->ssid_len),
e174961c
JB
5636 network->bssid,
5637 priv->bssid);
43f66a6c
JK
5638 return 0;
5639 }
bf79451e 5640
43f66a6c 5641 /* Filter out any incompatible freq / mode combinations */
b0a4e7d8 5642 if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
e174961c 5643 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
43f66a6c
JK
5644 "because of invalid frequency/mode "
5645 "combination.\n",
9387b7ca
JL
5646 print_ssid(ssid, network->ssid,
5647 network->ssid_len),
e174961c 5648 network->bssid);
43f66a6c
JK
5649 return 0;
5650 }
bf79451e 5651
c848d0af
JK
5652 /* Ensure that the rates supported by the driver are compatible with
5653 * this AP, including verification of basic rates (mandatory) */
5654 if (!ipw_compatible_rates(priv, network, &rates)) {
e174961c 5655 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
c848d0af
JK
5656 "because configured rate mask excludes "
5657 "AP mandatory rate.\n",
9387b7ca
JL
5658 print_ssid(ssid, network->ssid,
5659 network->ssid_len),
e174961c 5660 network->bssid);
c848d0af
JK
5661 return 0;
5662 }
5663
43f66a6c 5664 if (rates.num_rates == 0) {
e174961c 5665 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
43f66a6c 5666 "because of no compatible rates.\n",
9387b7ca
JL
5667 print_ssid(ssid, network->ssid,
5668 network->ssid_len),
e174961c 5669 network->bssid);
43f66a6c
JK
5670 return 0;
5671 }
bf79451e 5672
43f66a6c
JK
5673 /* TODO: Perform any further minimal comparititive tests. We do not
5674 * want to put too much policy logic here; intelligent scan selection
5675 * should occur within a generic IEEE 802.11 user space tool. */
5676
5677 /* Set up 'new' AP to this network */
5678 ipw_copy_rates(&match->rates, &rates);
5679 match->network = network;
e174961c 5680 IPW_DEBUG_MERGE("Network '%s (%pM)' is a viable match.\n",
9387b7ca 5681 print_ssid(ssid, network->ssid, network->ssid_len),
e174961c 5682 network->bssid);
43f66a6c
JK
5683
5684 return 1;
5685}
5686
c4028958 5687static void ipw_merge_adhoc_network(struct work_struct *work)
43f66a6c 5688{
9387b7ca 5689 DECLARE_SSID_BUF(ssid);
c4028958
DH
5690 struct ipw_priv *priv =
5691 container_of(work, struct ipw_priv, merge_networks);
b0a4e7d8 5692 struct libipw_network *network = NULL;
c848d0af
JK
5693 struct ipw_network_match match = {
5694 .network = priv->assoc_network
5695 };
5696
afbf30a2
JK
5697 if ((priv->status & STATUS_ASSOCIATED) &&
5698 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
c848d0af
JK
5699 /* First pass through ROAM process -- look for a better
5700 * network */
5701 unsigned long flags;
5702
5703 spin_lock_irqsave(&priv->ieee->lock, flags);
5704 list_for_each_entry(network, &priv->ieee->network_list, list) {
5705 if (network != priv->assoc_network)
5706 ipw_find_adhoc_network(priv, &match, network,
5707 1);
5708 }
5709 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5710
5711 if (match.network == priv->assoc_network) {
5712 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5713 "merge to.\n");
5714 return;
5715 }
5716
4644151b 5717 mutex_lock(&priv->mutex);
c848d0af
JK
5718 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5719 IPW_DEBUG_MERGE("remove network %s\n",
9387b7ca
JL
5720 print_ssid(ssid, priv->essid,
5721 priv->essid_len));
c848d0af 5722 ipw_remove_current_network(priv);
43f66a6c 5723 }
c848d0af
JK
5724
5725 ipw_disassociate(priv);
5726 priv->assoc_network = match.network;
4644151b 5727 mutex_unlock(&priv->mutex);
c848d0af 5728 return;
43f66a6c 5729 }
c848d0af 5730}
43f66a6c 5731
0edd5b44
JG
5732static int ipw_best_network(struct ipw_priv *priv,
5733 struct ipw_network_match *match,
b0a4e7d8 5734 struct libipw_network *network, int roaming)
43f66a6c
JK
5735{
5736 struct ipw_supported_rates rates;
9387b7ca 5737 DECLARE_SSID_BUF(ssid);
43f66a6c
JK
5738
5739 /* Verify that this network's capability is compatible with the
5740 * current mode (AdHoc or Infrastructure) */
5741 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
2474385e 5742 !(network->capability & WLAN_CAPABILITY_ESS)) ||
43f66a6c
JK
5743 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
5744 !(network->capability & WLAN_CAPABILITY_IBSS))) {
e174961c 5745 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to "
bf79451e 5746 "capability mismatch.\n",
9387b7ca
JL
5747 print_ssid(ssid, network->ssid,
5748 network->ssid_len),
e174961c 5749 network->bssid);
43f66a6c
JK
5750 return 0;
5751 }
5752
43f66a6c
JK
5753 if (unlikely(roaming)) {
5754 /* If we are roaming, then ensure check if this is a valid
5755 * network to try and roam to */
5756 if ((network->ssid_len != match->network->ssid_len) ||
bf79451e 5757 memcmp(network->ssid, match->network->ssid,
43f66a6c 5758 network->ssid_len)) {
e174961c 5759 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
43f66a6c 5760 "because of non-network ESSID.\n",
9387b7ca
JL
5761 print_ssid(ssid, network->ssid,
5762 network->ssid_len),
e174961c 5763 network->bssid);
43f66a6c
JK
5764 return 0;
5765 }
5766 } else {
bf79451e
JG
5767 /* If an ESSID has been configured then compare the broadcast
5768 * ESSID to ours */
5769 if ((priv->config & CFG_STATIC_ESSID) &&
43f66a6c 5770 ((network->ssid_len != priv->essid_len) ||
bf79451e 5771 memcmp(network->ssid, priv->essid,
43f66a6c
JK
5772 min(network->ssid_len, priv->essid_len)))) {
5773 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
0edd5b44 5774 strncpy(escaped,
9387b7ca
JL
5775 print_ssid(ssid, network->ssid,
5776 network->ssid_len),
43f66a6c 5777 sizeof(escaped));
e174961c 5778 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
bf79451e 5779 "because of ESSID mismatch: '%s'.\n",
e174961c 5780 escaped, network->bssid,
9387b7ca
JL
5781 print_ssid(ssid, priv->essid,
5782 priv->essid_len));
43f66a6c
JK
5783 return 0;
5784 }
5785 }
5786
5787 /* If the old network rate is better than this one, don't bother
5788 * testing everything else. */
0edd5b44 5789 if (match->network && match->network->stats.rssi > network->stats.rssi) {
43f66a6c 5790 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
bf79451e 5791 strncpy(escaped,
9387b7ca 5792 print_ssid(ssid, network->ssid, network->ssid_len),
43f66a6c 5793 sizeof(escaped));
e174961c
JB
5794 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
5795 "'%s (%pM)' has a stronger signal.\n",
5796 escaped, network->bssid,
9387b7ca
JL
5797 print_ssid(ssid, match->network->ssid,
5798 match->network->ssid_len),
e174961c 5799 match->network->bssid);
43f66a6c
JK
5800 return 0;
5801 }
bf79451e 5802
43f66a6c
JK
5803 /* If this network has already had an association attempt within the
5804 * last 3 seconds, do not try and associate again... */
5805 if (network->last_associate &&
ea2b26e0 5806 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
e174961c 5807 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
c7b6a674 5808 "because of storming (%ums since last "
43f66a6c 5809 "assoc attempt).\n",
9387b7ca
JL
5810 print_ssid(ssid, network->ssid,
5811 network->ssid_len),
e174961c 5812 network->bssid,
2638bc39
ZY
5813 jiffies_to_msecs(jiffies -
5814 network->last_associate));
43f66a6c
JK
5815 return 0;
5816 }
5817
5818 /* Now go through and see if the requested network is valid... */
bf79451e 5819 if (priv->ieee->scan_age != 0 &&
ea2b26e0 5820 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
e174961c 5821 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
c7b6a674 5822 "because of age: %ums.\n",
9387b7ca
JL
5823 print_ssid(ssid, network->ssid,
5824 network->ssid_len),
e174961c 5825 network->bssid,
2638bc39
ZY
5826 jiffies_to_msecs(jiffies -
5827 network->last_scanned));
43f66a6c 5828 return 0;
bf79451e 5829 }
43f66a6c 5830
bf79451e 5831 if ((priv->config & CFG_STATIC_CHANNEL) &&
43f66a6c 5832 (network->channel != priv->channel)) {
e174961c 5833 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
43f66a6c 5834 "because of channel mismatch: %d != %d.\n",
9387b7ca
JL
5835 print_ssid(ssid, network->ssid,
5836 network->ssid_len),
e174961c 5837 network->bssid,
43f66a6c
JK
5838 network->channel, priv->channel);
5839 return 0;
5840 }
bf79451e 5841
25985edc 5842 /* Verify privacy compatibility */
bf79451e 5843 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
43f66a6c 5844 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
e174961c 5845 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
43f66a6c 5846 "because of privacy mismatch: %s != %s.\n",
9387b7ca
JL
5847 print_ssid(ssid, network->ssid,
5848 network->ssid_len),
e174961c 5849 network->bssid,
bf79451e 5850 priv->capability & CAP_PRIVACY_ON ? "on" :
43f66a6c 5851 "off",
bf79451e 5852 network->capability &
0edd5b44 5853 WLAN_CAPABILITY_PRIVACY ? "on" : "off");
43f66a6c
JK
5854 return 0;
5855 }
bf79451e
JG
5856
5857 if ((priv->config & CFG_STATIC_BSSID) &&
43f66a6c 5858 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
e174961c
JB
5859 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
5860 "because of BSSID mismatch: %pM.\n",
9387b7ca
JL
5861 print_ssid(ssid, network->ssid,
5862 network->ssid_len),
e174961c 5863 network->bssid, priv->bssid);
43f66a6c
JK
5864 return 0;
5865 }
bf79451e 5866
43f66a6c 5867 /* Filter out any incompatible freq / mode combinations */
b0a4e7d8 5868 if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
e174961c 5869 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
43f66a6c
JK
5870 "because of invalid frequency/mode "
5871 "combination.\n",
9387b7ca
JL
5872 print_ssid(ssid, network->ssid,
5873 network->ssid_len),
e174961c 5874 network->bssid);
43f66a6c
JK
5875 return 0;
5876 }
bf79451e 5877
1fe0adb4 5878 /* Filter out invalid channel in current GEO */
b0a4e7d8 5879 if (!libipw_is_valid_channel(priv->ieee, network->channel)) {
e174961c 5880 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
1fe0adb4 5881 "because of invalid channel in current GEO\n",
9387b7ca
JL
5882 print_ssid(ssid, network->ssid,
5883 network->ssid_len),
e174961c 5884 network->bssid);
1fe0adb4
LH
5885 return 0;
5886 }
5887
ea2b26e0
JK
5888 /* Ensure that the rates supported by the driver are compatible with
5889 * this AP, including verification of basic rates (mandatory) */
5890 if (!ipw_compatible_rates(priv, network, &rates)) {
e174961c 5891 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
ea2b26e0
JK
5892 "because configured rate mask excludes "
5893 "AP mandatory rate.\n",
9387b7ca
JL
5894 print_ssid(ssid, network->ssid,
5895 network->ssid_len),
e174961c 5896 network->bssid);
ea2b26e0
JK
5897 return 0;
5898 }
5899
43f66a6c 5900 if (rates.num_rates == 0) {
e174961c 5901 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
43f66a6c 5902 "because of no compatible rates.\n",
9387b7ca
JL
5903 print_ssid(ssid, network->ssid,
5904 network->ssid_len),
e174961c 5905 network->bssid);
43f66a6c
JK
5906 return 0;
5907 }
bf79451e 5908
43f66a6c
JK
5909 /* TODO: Perform any further minimal comparititive tests. We do not
5910 * want to put too much policy logic here; intelligent scan selection
5911 * should occur within a generic IEEE 802.11 user space tool. */
5912
5913 /* Set up 'new' AP to this network */
5914 ipw_copy_rates(&match->rates, &rates);
5915 match->network = network;
5916
e174961c 5917 IPW_DEBUG_ASSOC("Network '%s (%pM)' is a viable match.\n",
9387b7ca 5918 print_ssid(ssid, network->ssid, network->ssid_len),
e174961c 5919 network->bssid);
43f66a6c
JK
5920
5921 return 1;
5922}
5923
bf79451e 5924static void ipw_adhoc_create(struct ipw_priv *priv,
b0a4e7d8 5925 struct libipw_network *network)
43f66a6c 5926{
b0a4e7d8 5927 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
afbf30a2
JK
5928 int i;
5929
43f66a6c
JK
5930 /*
5931 * For the purposes of scanning, we can set our wireless mode
5932 * to trigger scans across combinations of bands, but when it
5933 * comes to creating a new ad-hoc network, we have tell the FW
5934 * exactly which band to use.
5935 *
bf79451e 5936 * We also have the possibility of an invalid channel for the
43f66a6c
JK
5937 * chossen band. Attempting to create a new ad-hoc network
5938 * with an invalid channel for wireless mode will trigger a
5939 * FW fatal error.
afbf30a2 5940 *
43f66a6c 5941 */
b0a4e7d8
JL
5942 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
5943 case LIBIPW_52GHZ_BAND:
afbf30a2 5944 network->mode = IEEE_A;
b0a4e7d8 5945 i = libipw_channel_to_index(priv->ieee, priv->channel);
5d9428de 5946 BUG_ON(i == -1);
b0a4e7d8 5947 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) {
afbf30a2
JK
5948 IPW_WARNING("Overriding invalid channel\n");
5949 priv->channel = geo->a[0].channel;
5950 }
5951 break;
5952
b0a4e7d8 5953 case LIBIPW_24GHZ_BAND:
afbf30a2
JK
5954 if (priv->ieee->mode & IEEE_G)
5955 network->mode = IEEE_G;
5956 else
5957 network->mode = IEEE_B;
b0a4e7d8 5958 i = libipw_channel_to_index(priv->ieee, priv->channel);
5d9428de 5959 BUG_ON(i == -1);
b0a4e7d8 5960 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) {
1fe0adb4
LH
5961 IPW_WARNING("Overriding invalid channel\n");
5962 priv->channel = geo->bg[0].channel;
5963 }
afbf30a2
JK
5964 break;
5965
5966 default:
43f66a6c
JK
5967 IPW_WARNING("Overriding invalid channel\n");
5968 if (priv->ieee->mode & IEEE_A) {
5969 network->mode = IEEE_A;
b095c381 5970 priv->channel = geo->a[0].channel;
43f66a6c
JK
5971 } else if (priv->ieee->mode & IEEE_G) {
5972 network->mode = IEEE_G;
b095c381 5973 priv->channel = geo->bg[0].channel;
43f66a6c
JK
5974 } else {
5975 network->mode = IEEE_B;
b095c381 5976 priv->channel = geo->bg[0].channel;
43f66a6c 5977 }
afbf30a2
JK
5978 break;
5979 }
43f66a6c
JK
5980
5981 network->channel = priv->channel;
5982 priv->config |= CFG_ADHOC_PERSIST;
5983 ipw_create_bssid(priv, network->bssid);
5984 network->ssid_len = priv->essid_len;
5985 memcpy(network->ssid, priv->essid, priv->essid_len);
5986 memset(&network->stats, 0, sizeof(network->stats));
5987 network->capability = WLAN_CAPABILITY_IBSS;
ea2b26e0
JK
5988 if (!(priv->config & CFG_PREAMBLE_LONG))
5989 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
43f66a6c
JK
5990 if (priv->capability & CAP_PRIVACY_ON)
5991 network->capability |= WLAN_CAPABILITY_PRIVACY;
5992 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
0edd5b44 5993 memcpy(network->rates, priv->rates.supported_rates, network->rates_len);
43f66a6c 5994 network->rates_ex_len = priv->rates.num_rates - network->rates_len;
bf79451e 5995 memcpy(network->rates_ex,
43f66a6c
JK
5996 &priv->rates.supported_rates[network->rates_len],
5997 network->rates_ex_len);
5998 network->last_scanned = 0;
5999 network->flags = 0;
6000 network->last_associate = 0;
6001 network->time_stamp[0] = 0;
6002 network->time_stamp[1] = 0;
0edd5b44
JG
6003 network->beacon_interval = 100; /* Default */
6004 network->listen_interval = 10; /* Default */
6005 network->atim_window = 0; /* Default */
43f66a6c
JK
6006 network->wpa_ie_len = 0;
6007 network->rsn_ie_len = 0;
43f66a6c
JK
6008}
6009
b095c381
JK
6010static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
6011{
0a7bcf26 6012 struct ipw_tgi_tx_key key;
b095c381
JK
6013
6014 if (!(priv->ieee->sec.flags & (1 << index)))
6015 return;
6016
0a7bcf26
ZY
6017 key.key_id = index;
6018 memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
6019 key.security_type = type;
6020 key.station_index = 0; /* always 0 for BSS */
6021 key.flags = 0;
b095c381 6022 /* 0 for new key; previous value of counter (after fatal error) */
851ca268
ZY
6023 key.tx_counter[0] = cpu_to_le32(0);
6024 key.tx_counter[1] = cpu_to_le32(0);
b095c381 6025
0a7bcf26 6026 ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key);
b095c381
JK
6027}
6028
6029static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
43f66a6c 6030{
0a7bcf26 6031 struct ipw_wep_key key;
43f66a6c 6032 int i;
43f66a6c 6033
0a7bcf26
ZY
6034 key.cmd_id = DINO_CMD_WEP_KEY;
6035 key.seq_num = 0;
43f66a6c 6036
b095c381
JK
6037 /* Note: AES keys cannot be set for multiple times.
6038 * Only set it at the first time. */
bf79451e 6039 for (i = 0; i < 4; i++) {
0a7bcf26 6040 key.key_index = i | type;
b095c381 6041 if (!(priv->ieee->sec.flags & (1 << i))) {
0a7bcf26 6042 key.key_size = 0;
b095c381 6043 continue;
43f66a6c
JK
6044 }
6045
0a7bcf26
ZY
6046 key.key_size = priv->ieee->sec.key_sizes[i];
6047 memcpy(key.key, priv->ieee->sec.keys[i], key.key_size);
b095c381 6048
0a7bcf26 6049 ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key);
bf79451e 6050 }
43f66a6c
JK
6051}
6052
1fbfea54 6053static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
43f66a6c 6054{
1fbfea54 6055 if (priv->ieee->host_encrypt)
43f66a6c 6056 return;
43f66a6c 6057
1fbfea54
ZY
6058 switch (level) {
6059 case SEC_LEVEL_3:
6060 priv->sys_config.disable_unicast_decryption = 0;
6061 priv->ieee->host_decrypt = 0;
6062 break;
6063 case SEC_LEVEL_2:
6064 priv->sys_config.disable_unicast_decryption = 1;
6065 priv->ieee->host_decrypt = 1;
6066 break;
6067 case SEC_LEVEL_1:
6068 priv->sys_config.disable_unicast_decryption = 0;
6069 priv->ieee->host_decrypt = 0;
6070 break;
6071 case SEC_LEVEL_0:
6072 priv->sys_config.disable_unicast_decryption = 1;
6073 break;
6074 default:
6075 break;
6076 }
6077}
6078
6079static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
6080{
6081 if (priv->ieee->host_encrypt)
6082 return;
6083
6084 switch (level) {
6085 case SEC_LEVEL_3:
6086 priv->sys_config.disable_multicast_decryption = 0;
6087 break;
6088 case SEC_LEVEL_2:
6089 priv->sys_config.disable_multicast_decryption = 1;
6090 break;
6091 case SEC_LEVEL_1:
6092 priv->sys_config.disable_multicast_decryption = 0;
6093 break;
6094 case SEC_LEVEL_0:
6095 priv->sys_config.disable_multicast_decryption = 1;
6096 break;
6097 default:
6098 break;
6099 }
6100}
6101
b095c381
JK
6102static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
6103{
6104 switch (priv->ieee->sec.level) {
6105 case SEC_LEVEL_3:
d8bad6df
ZY
6106 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
6107 ipw_send_tgi_tx_key(priv,
6108 DCT_FLAG_EXT_SECURITY_CCM,
6109 priv->ieee->sec.active_key);
afbf30a2 6110
567deaf6
HL
6111 if (!priv->ieee->host_mc_decrypt)
6112 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
b095c381
JK
6113 break;
6114 case SEC_LEVEL_2:
d8bad6df
ZY
6115 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
6116 ipw_send_tgi_tx_key(priv,
6117 DCT_FLAG_EXT_SECURITY_TKIP,
6118 priv->ieee->sec.active_key);
b095c381
JK
6119 break;
6120 case SEC_LEVEL_1:
6121 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
29cb843e
HL
6122 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
6123 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
b095c381
JK
6124 break;
6125 case SEC_LEVEL_0:
6126 default:
6127 break;
6128 }
6129}
6130
43f66a6c
JK
6131static void ipw_adhoc_check(void *data)
6132{
6133 struct ipw_priv *priv = data;
bf79451e 6134
afbf30a2 6135 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
43f66a6c 6136 !(priv->config & CFG_ADHOC_PERSIST)) {
afbf30a2
JK
6137 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
6138 IPW_DL_STATE | IPW_DL_ASSOC,
6139 "Missed beacon: %d - disassociate\n",
6140 priv->missed_adhoc_beacons);
43f66a6c
JK
6141 ipw_remove_current_network(priv);
6142 ipw_disassociate(priv);
6143 return;
6144 }
6145
bcb6d916
TH
6146 schedule_delayed_work(&priv->adhoc_check,
6147 le16_to_cpu(priv->assoc_request.beacon_interval));
43f66a6c
JK
6148}
6149
c4028958 6150static void ipw_bg_adhoc_check(struct work_struct *work)
c848d0af 6151{
c4028958
DH
6152 struct ipw_priv *priv =
6153 container_of(work, struct ipw_priv, adhoc_check.work);
4644151b 6154 mutex_lock(&priv->mutex);
c4028958 6155 ipw_adhoc_check(priv);
4644151b 6156 mutex_unlock(&priv->mutex);
c848d0af
JK
6157}
6158
43f66a6c
JK
6159static void ipw_debug_config(struct ipw_priv *priv)
6160{
9387b7ca 6161 DECLARE_SSID_BUF(ssid);
43f66a6c
JK
6162 IPW_DEBUG_INFO("Scan completed, no valid APs matched "
6163 "[CFG 0x%08X]\n", priv->config);
6164 if (priv->config & CFG_STATIC_CHANNEL)
0edd5b44 6165 IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel);
43f66a6c
JK
6166 else
6167 IPW_DEBUG_INFO("Channel unlocked.\n");
6168 if (priv->config & CFG_STATIC_ESSID)
bf79451e 6169 IPW_DEBUG_INFO("ESSID locked to '%s'\n",
9387b7ca 6170 print_ssid(ssid, priv->essid, priv->essid_len));
43f66a6c
JK
6171 else
6172 IPW_DEBUG_INFO("ESSID unlocked.\n");
6173 if (priv->config & CFG_STATIC_BSSID)
e174961c 6174 IPW_DEBUG_INFO("BSSID locked to %pM\n", priv->bssid);
43f66a6c
JK
6175 else
6176 IPW_DEBUG_INFO("BSSID unlocked.\n");
6177 if (priv->capability & CAP_PRIVACY_ON)
6178 IPW_DEBUG_INFO("PRIVACY on\n");
6179 else
6180 IPW_DEBUG_INFO("PRIVACY off\n");
6181 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);
6182}
43f66a6c 6183
858119e1 6184static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
43f66a6c
JK
6185{
6186 /* TODO: Verify that this works... */
21f8a73f 6187 struct ipw_fixed_rate fr;
43f66a6c
JK
6188 u32 reg;
6189 u16 mask = 0;
21f8a73f 6190 u16 new_tx_rates = priv->rates_mask;
43f66a6c 6191
bf79451e 6192 /* Identify 'current FW band' and match it with the fixed
43f66a6c 6193 * Tx rates */
bf79451e 6194
43f66a6c 6195 switch (priv->ieee->freq_band) {
b0a4e7d8 6196 case LIBIPW_52GHZ_BAND: /* A only */
43f66a6c 6197 /* IEEE_A */
b0a4e7d8 6198 if (priv->rates_mask & ~LIBIPW_OFDM_RATES_MASK) {
43f66a6c 6199 /* Invalid fixed rate mask */
ea2b26e0
JK
6200 IPW_DEBUG_WX
6201 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
21f8a73f 6202 new_tx_rates = 0;
43f66a6c
JK
6203 break;
6204 }
bf79451e 6205
b0a4e7d8 6206 new_tx_rates >>= LIBIPW_OFDM_SHIFT_MASK_A;
43f66a6c
JK
6207 break;
6208
0edd5b44 6209 default: /* 2.4Ghz or Mixed */
43f66a6c 6210 /* IEEE_B */
b095c381 6211 if (mode == IEEE_B) {
b0a4e7d8 6212 if (new_tx_rates & ~LIBIPW_CCK_RATES_MASK) {
43f66a6c 6213 /* Invalid fixed rate mask */
ea2b26e0
JK
6214 IPW_DEBUG_WX
6215 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
21f8a73f 6216 new_tx_rates = 0;
43f66a6c
JK
6217 }
6218 break;
bf79451e 6219 }
43f66a6c
JK
6220
6221 /* IEEE_G */
b0a4e7d8
JL
6222 if (new_tx_rates & ~(LIBIPW_CCK_RATES_MASK |
6223 LIBIPW_OFDM_RATES_MASK)) {
43f66a6c 6224 /* Invalid fixed rate mask */
ea2b26e0
JK
6225 IPW_DEBUG_WX
6226 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
21f8a73f 6227 new_tx_rates = 0;
43f66a6c
JK
6228 break;
6229 }
bf79451e 6230
b0a4e7d8
JL
6231 if (LIBIPW_OFDM_RATE_6MB_MASK & new_tx_rates) {
6232 mask |= (LIBIPW_OFDM_RATE_6MB_MASK >> 1);
6233 new_tx_rates &= ~LIBIPW_OFDM_RATE_6MB_MASK;
43f66a6c 6234 }
bf79451e 6235
b0a4e7d8
JL
6236 if (LIBIPW_OFDM_RATE_9MB_MASK & new_tx_rates) {
6237 mask |= (LIBIPW_OFDM_RATE_9MB_MASK >> 1);
6238 new_tx_rates &= ~LIBIPW_OFDM_RATE_9MB_MASK;
43f66a6c 6239 }
bf79451e 6240
b0a4e7d8
JL
6241 if (LIBIPW_OFDM_RATE_12MB_MASK & new_tx_rates) {
6242 mask |= (LIBIPW_OFDM_RATE_12MB_MASK >> 1);
6243 new_tx_rates &= ~LIBIPW_OFDM_RATE_12MB_MASK;
43f66a6c 6244 }
bf79451e 6245
21f8a73f 6246 new_tx_rates |= mask;
43f66a6c
JK
6247 break;
6248 }
6249
21f8a73f
RC
6250 fr.tx_rates = cpu_to_le16(new_tx_rates);
6251
43f66a6c 6252 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
0edd5b44 6253 ipw_write_reg32(priv, reg, *(u32 *) & fr);
43f66a6c
JK
6254}
6255
ea2b26e0 6256static void ipw_abort_scan(struct ipw_priv *priv)
43f66a6c
JK
6257{
6258 int err;
6259
ea2b26e0
JK
6260 if (priv->status & STATUS_SCAN_ABORTING) {
6261 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
6262 return;
6263 }
6264 priv->status |= STATUS_SCAN_ABORTING;
43f66a6c 6265
ea2b26e0
JK
6266 err = ipw_send_scan_abort(priv);
6267 if (err)
6268 IPW_DEBUG_HC("Request to abort scan failed.\n");
6269}
6270
afbf30a2
JK
6271static void ipw_add_scan_channels(struct ipw_priv *priv,
6272 struct ipw_scan_request_ext *scan,
6273 int scan_type)
ea2b26e0 6274{
ea2b26e0 6275 int channel_index = 0;
b0a4e7d8 6276 const struct libipw_geo *geo;
afbf30a2 6277 int i;
b095c381 6278
b0a4e7d8 6279 geo = libipw_get_geo(priv->ieee);
43f66a6c 6280
b0a4e7d8 6281 if (priv->ieee->freq_band & LIBIPW_52GHZ_BAND) {
afbf30a2
JK
6282 int start = channel_index;
6283 for (i = 0; i < geo->a_channels; i++) {
6284 if ((priv->status & STATUS_ASSOCIATED) &&
6285 geo->a[i].channel == priv->channel)
6286 continue;
6287 channel_index++;
6288 scan->channels_list[channel_index] = geo->a[i].channel;
1fe0adb4
LH
6289 ipw_set_scan_type(scan, channel_index,
6290 geo->a[i].
b0a4e7d8 6291 flags & LIBIPW_CH_PASSIVE_ONLY ?
1fe0adb4
LH
6292 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
6293 scan_type);
afbf30a2
JK
6294 }
6295
6296 if (start != channel_index) {
6297 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
6298 (channel_index - start);
6299 channel_index++;
6300 }
6301 }
6302
b0a4e7d8 6303 if (priv->ieee->freq_band & LIBIPW_24GHZ_BAND) {
afbf30a2
JK
6304 int start = channel_index;
6305 if (priv->config & CFG_SPEED_SCAN) {
1fe0adb4 6306 int index;
b0a4e7d8 6307 u8 channels[LIBIPW_24GHZ_CHANNELS] = {
afbf30a2
JK
6308 /* nop out the list */
6309 [0] = 0
6310 };
6311
6312 u8 channel;
7dd2459d 6313 while (channel_index < IPW_SCAN_CHANNELS - 1) {
afbf30a2
JK
6314 channel =
6315 priv->speed_scan[priv->speed_scan_pos];
6316 if (channel == 0) {
6317 priv->speed_scan_pos = 0;
6318 channel = priv->speed_scan[0];
6319 }
6320 if ((priv->status & STATUS_ASSOCIATED) &&
6321 channel == priv->channel) {
6322 priv->speed_scan_pos++;
6323 continue;
6324 }
6325
6326 /* If this channel has already been
6327 * added in scan, break from loop
6328 * and this will be the first channel
6329 * in the next scan.
6330 */
6331 if (channels[channel - 1] != 0)
6332 break;
6333
6334 channels[channel - 1] = 1;
6335 priv->speed_scan_pos++;
6336 channel_index++;
6337 scan->channels_list[channel_index] = channel;
1fe0adb4 6338 index =
b0a4e7d8 6339 libipw_channel_to_index(priv->ieee, channel);
afbf30a2 6340 ipw_set_scan_type(scan, channel_index,
1fe0adb4
LH
6341 geo->bg[index].
6342 flags &
b0a4e7d8 6343 LIBIPW_CH_PASSIVE_ONLY ?
1fe0adb4
LH
6344 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6345 : scan_type);
afbf30a2
JK
6346 }
6347 } else {
6348 for (i = 0; i < geo->bg_channels; i++) {
6349 if ((priv->status & STATUS_ASSOCIATED) &&
6350 geo->bg[i].channel == priv->channel)
6351 continue;
6352 channel_index++;
6353 scan->channels_list[channel_index] =
6354 geo->bg[i].channel;
6355 ipw_set_scan_type(scan, channel_index,
1fe0adb4
LH
6356 geo->bg[i].
6357 flags &
b0a4e7d8 6358 LIBIPW_CH_PASSIVE_ONLY ?
1fe0adb4
LH
6359 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6360 : scan_type);
afbf30a2
JK
6361 }
6362 }
6363
6364 if (start != channel_index) {
6365 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
6366 (channel_index - start);
6367 }
6368 }
6369}
6370
14a4dfe2
HS
6371static int ipw_passive_dwell_time(struct ipw_priv *priv)
6372{
6373 /* staying on passive channels longer than the DTIM interval during a
6374 * scan, while associated, causes the firmware to cancel the scan
6375 * without notification. Hence, don't stay on passive channels longer
6376 * than the beacon interval.
6377 */
6378 if (priv->status & STATUS_ASSOCIATED
6379 && priv->assoc_network->beacon_interval > 10)
6380 return priv->assoc_network->beacon_interval - 10;
6381 else
6382 return 120;
6383}
6384
ea177305 6385static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
afbf30a2
JK
6386{
6387 struct ipw_scan_request_ext scan;
6388 int err = 0, scan_type;
6389
6390 if (!(priv->status & STATUS_INIT) ||
6391 (priv->status & STATUS_EXIT_PENDING))
6392 return 0;
6393
4644151b 6394 mutex_lock(&priv->mutex);
afbf30a2 6395
ea177305
DW
6396 if (direct && (priv->direct_scan_ssid_len == 0)) {
6397 IPW_DEBUG_HC("Direct scan requested but no SSID to scan for\n");
6398 priv->status &= ~STATUS_DIRECT_SCAN_PENDING;
6399 goto done;
6400 }
6401
ea2b26e0 6402 if (priv->status & STATUS_SCANNING) {
ea177305
DW
6403 IPW_DEBUG_HC("Concurrent scan requested. Queuing.\n");
6404 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
6405 STATUS_SCAN_PENDING;
b095c381 6406 goto done;
ea2b26e0 6407 }
43f66a6c 6408
afbf30a2
JK
6409 if (!(priv->status & STATUS_SCAN_FORCED) &&
6410 priv->status & STATUS_SCAN_ABORTING) {
ea2b26e0 6411 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
ea177305
DW
6412 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
6413 STATUS_SCAN_PENDING;
b095c381 6414 goto done;
43f66a6c
JK
6415 }
6416
ea2b26e0 6417 if (priv->status & STATUS_RF_KILL_MASK) {
ea177305
DW
6418 IPW_DEBUG_HC("Queuing scan due to RF Kill activation\n");
6419 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
6420 STATUS_SCAN_PENDING;
b095c381 6421 goto done;
ea2b26e0 6422 }
43f66a6c 6423
ea2b26e0 6424 memset(&scan, 0, sizeof(scan));
b0a4e7d8 6425 scan.full_scan_index = cpu_to_le32(libipw_get_scans(priv->ieee));
43f66a6c 6426
094c4d2d 6427 if (type == IW_SCAN_TYPE_PASSIVE) {
14a4dfe2
HS
6428 IPW_DEBUG_WX("use passive scanning\n");
6429 scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
094c4d2d 6430 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
14a4dfe2 6431 cpu_to_le16(ipw_passive_dwell_time(priv));
094c4d2d
ZY
6432 ipw_add_scan_channels(priv, &scan, scan_type);
6433 goto send_request;
6434 }
6435
6436 /* Use active scan by default. */
14a4dfe2 6437 if (priv->config & CFG_SPEED_SCAN)
b095c381 6438 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
094c4d2d 6439 cpu_to_le16(30);
b095c381
JK
6440 else
6441 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
094c4d2d 6442 cpu_to_le16(20);
b095c381 6443
a613bffd 6444 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
094c4d2d 6445 cpu_to_le16(20);
43f66a6c 6446
14a4dfe2
HS
6447 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6448 cpu_to_le16(ipw_passive_dwell_time(priv));
ea177305 6449 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
43f66a6c 6450
b095c381 6451#ifdef CONFIG_IPW2200_MONITOR
ea2b26e0 6452 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
afbf30a2 6453 u8 channel;
b095c381 6454 u8 band = 0;
43f66a6c 6455
b0a4e7d8
JL
6456 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
6457 case LIBIPW_52GHZ_BAND:
ea2b26e0 6458 band = (u8) (IPW_A_MODE << 6) | 1;
b095c381
JK
6459 channel = priv->channel;
6460 break;
ea2b26e0 6461
b0a4e7d8 6462 case LIBIPW_24GHZ_BAND:
ea2b26e0 6463 band = (u8) (IPW_B_MODE << 6) | 1;
b095c381
JK
6464 channel = priv->channel;
6465 break;
ea2b26e0 6466
b095c381 6467 default:
ea2b26e0
JK
6468 band = (u8) (IPW_B_MODE << 6) | 1;
6469 channel = 9;
b095c381 6470 break;
ea2b26e0
JK
6471 }
6472
b095c381
JK
6473 scan.channels_list[0] = band;
6474 scan.channels_list[1] = channel;
6475 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
ea2b26e0 6476
b095c381
JK
6477 /* NOTE: The card will sit on this channel for this time
6478 * period. Scan aborts are timing sensitive and frequently
6479 * result in firmware restarts. As such, it is best to
6480 * set a small dwell_time here and just keep re-issuing
6481 * scans. Otherwise fast channel hopping will not actually
6482 * hop channels.
6483 *
6484 * TODO: Move SPEED SCAN support to all modes and bands */
a613bffd 6485 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
094c4d2d 6486 cpu_to_le16(2000);
43f66a6c 6487 } else {
b095c381 6488#endif /* CONFIG_IPW2200_MONITOR */
ea177305
DW
6489 /* Honor direct scans first, otherwise if we are roaming make
6490 * this a direct scan for the current network. Finally,
6491 * ensure that every other scan is a fast channel hop scan */
6492 if (direct) {
6493 err = ipw_send_ssid(priv, priv->direct_scan_ssid,
6494 priv->direct_scan_ssid_len);
6495 if (err) {
6496 IPW_DEBUG_HC("Attempt to send SSID command "
6497 "failed\n");
6498 goto done;
6499 }
6500
6501 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
6502 } else if ((priv->status & STATUS_ROAMING)
6503 || (!(priv->status & STATUS_ASSOCIATED)
6504 && (priv->config & CFG_STATIC_ESSID)
6505 && (le32_to_cpu(scan.full_scan_index) % 2))) {
ea2b26e0
JK
6506 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6507 if (err) {
b095c381
JK
6508 IPW_DEBUG_HC("Attempt to send SSID command "
6509 "failed.\n");
6510 goto done;
ea2b26e0 6511 }
43f66a6c 6512
ea2b26e0 6513 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
afbf30a2 6514 } else
ea2b26e0 6515 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
ea2b26e0 6516
afbf30a2 6517 ipw_add_scan_channels(priv, &scan, scan_type);
b095c381 6518#ifdef CONFIG_IPW2200_MONITOR
43f66a6c 6519 }
ea2b26e0 6520#endif
bf79451e 6521
094c4d2d 6522send_request:
ea2b26e0 6523 err = ipw_send_scan_request_ext(priv, &scan);
43f66a6c 6524 if (err) {
ea2b26e0 6525 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
b095c381 6526 goto done;
43f66a6c
JK
6527 }
6528
ea2b26e0 6529 priv->status |= STATUS_SCANNING;
ea177305
DW
6530 if (direct) {
6531 priv->status &= ~STATUS_DIRECT_SCAN_PENDING;
6532 priv->direct_scan_ssid_len = 0;
6533 } else
6534 priv->status &= ~STATUS_SCAN_PENDING;
6535
bcb6d916 6536 schedule_delayed_work(&priv->scan_check, IPW_SCAN_CHECK_WATCHDOG);
094c4d2d 6537done:
4644151b 6538 mutex_unlock(&priv->mutex);
b095c381 6539 return err;
c848d0af
JK
6540}
6541
c4028958
DH
6542static void ipw_request_passive_scan(struct work_struct *work)
6543{
6544 struct ipw_priv *priv =
ea177305
DW
6545 container_of(work, struct ipw_priv, request_passive_scan.work);
6546 ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE, 0);
094c4d2d
ZY
6547}
6548
c4028958
DH
6549static void ipw_request_scan(struct work_struct *work)
6550{
6551 struct ipw_priv *priv =
6552 container_of(work, struct ipw_priv, request_scan.work);
ea177305
DW
6553 ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 0);
6554}
6555
6556static void ipw_request_direct_scan(struct work_struct *work)
6557{
6558 struct ipw_priv *priv =
6559 container_of(work, struct ipw_priv, request_direct_scan.work);
6560 ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 1);
094c4d2d
ZY
6561}
6562
c4028958 6563static void ipw_bg_abort_scan(struct work_struct *work)
c848d0af 6564{
c4028958
DH
6565 struct ipw_priv *priv =
6566 container_of(work, struct ipw_priv, abort_scan);
4644151b 6567 mutex_lock(&priv->mutex);
c4028958 6568 ipw_abort_scan(priv);
4644151b 6569 mutex_unlock(&priv->mutex);
c848d0af
JK
6570}
6571
ea2b26e0
JK
6572static int ipw_wpa_enable(struct ipw_priv *priv, int value)
6573{
b095c381
JK
6574 /* This is called when wpa_supplicant loads and closes the driver
6575 * interface. */
cdd1fa1e 6576 priv->ieee->wpa_enabled = value;
b095c381 6577 return 0;
ea2b26e0
JK
6578}
6579
ea2b26e0
JK
6580static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6581{
b0a4e7d8
JL
6582 struct libipw_device *ieee = priv->ieee;
6583 struct libipw_security sec = {
ea2b26e0
JK
6584 .flags = SEC_AUTH_MODE,
6585 };
6586 int ret = 0;
6587
afbf30a2 6588 if (value & IW_AUTH_ALG_SHARED_KEY) {
ea2b26e0
JK
6589 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
6590 ieee->open_wep = 0;
afbf30a2 6591 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
ea2b26e0
JK
6592 sec.auth_mode = WLAN_AUTH_OPEN;
6593 ieee->open_wep = 1;
3e234b4e
ZY
6594 } else if (value & IW_AUTH_ALG_LEAP) {
6595 sec.auth_mode = WLAN_AUTH_LEAP;
6596 ieee->open_wep = 1;
afbf30a2
JK
6597 } else
6598 return -EINVAL;
ea2b26e0
JK
6599
6600 if (ieee->set_security)
6601 ieee->set_security(ieee->dev, &sec);
6602 else
6603 ret = -EOPNOTSUPP;
6604
6605 return ret;
6606}
6607
a73e22b2
AB
6608static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie,
6609 int wpa_ie_len)
afbf30a2
JK
6610{
6611 /* make sure WPA is enabled */
6612 ipw_wpa_enable(priv, 1);
afbf30a2
JK
6613}
6614
6615static int ipw_set_rsn_capa(struct ipw_priv *priv,
6616 char *capabilities, int length)
6617{
afbf30a2
JK
6618 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6619
0a7bcf26 6620 return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length,
2638bc39 6621 capabilities);
afbf30a2
JK
6622}
6623
b095c381 6624/*
afbf30a2
JK
6625 * WE-18 support
6626 */
6627
6628/* SIOCSIWGENIE */
6629static int ipw_wx_set_genie(struct net_device *dev,
6630 struct iw_request_info *info,
6631 union iwreq_data *wrqu, char *extra)
ea2b26e0 6632{
b0a4e7d8
JL
6633 struct ipw_priv *priv = libipw_priv(dev);
6634 struct libipw_device *ieee = priv->ieee;
afbf30a2
JK
6635 u8 *buf;
6636 int err = 0;
ea2b26e0 6637
afbf30a2
JK
6638 if (wrqu->data.length > MAX_WPA_IE_LEN ||
6639 (wrqu->data.length && extra == NULL))
6640 return -EINVAL;
ea2b26e0 6641
afbf30a2 6642 if (wrqu->data.length) {
d3e5033d 6643 buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);
afbf30a2
JK
6644 if (buf == NULL) {
6645 err = -ENOMEM;
6646 goto out;
6647 }
6648
afbf30a2
JK
6649 kfree(ieee->wpa_ie);
6650 ieee->wpa_ie = buf;
6651 ieee->wpa_ie_len = wrqu->data.length;
b095c381 6652 } else {
afbf30a2
JK
6653 kfree(ieee->wpa_ie);
6654 ieee->wpa_ie = NULL;
6655 ieee->wpa_ie_len = 0;
ea2b26e0 6656 }
afbf30a2
JK
6657
6658 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6659 out:
afbf30a2
JK
6660 return err;
6661}
6662
6663/* SIOCGIWGENIE */
6664static int ipw_wx_get_genie(struct net_device *dev,
6665 struct iw_request_info *info,
6666 union iwreq_data *wrqu, char *extra)
6667{
b0a4e7d8
JL
6668 struct ipw_priv *priv = libipw_priv(dev);
6669 struct libipw_device *ieee = priv->ieee;
afbf30a2
JK
6670 int err = 0;
6671
afbf30a2
JK
6672 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6673 wrqu->data.length = 0;
6674 goto out;
6675 }
6676
6677 if (wrqu->data.length < ieee->wpa_ie_len) {
6678 err = -E2BIG;
6679 goto out;
6680 }
6681
6682 wrqu->data.length = ieee->wpa_ie_len;
6683 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6684
6685 out:
afbf30a2
JK
6686 return err;
6687}
6688
1fbfea54
ZY
6689static int wext_cipher2level(int cipher)
6690{
6691 switch (cipher) {
6692 case IW_AUTH_CIPHER_NONE:
6693 return SEC_LEVEL_0;
6694 case IW_AUTH_CIPHER_WEP40:
6695 case IW_AUTH_CIPHER_WEP104:
6696 return SEC_LEVEL_1;
6697 case IW_AUTH_CIPHER_TKIP:
6698 return SEC_LEVEL_2;
6699 case IW_AUTH_CIPHER_CCMP:
6700 return SEC_LEVEL_3;
6701 default:
6702 return -1;
6703 }
6704}
6705
afbf30a2
JK
6706/* SIOCSIWAUTH */
6707static int ipw_wx_set_auth(struct net_device *dev,
6708 struct iw_request_info *info,
6709 union iwreq_data *wrqu, char *extra)
6710{
b0a4e7d8
JL
6711 struct ipw_priv *priv = libipw_priv(dev);
6712 struct libipw_device *ieee = priv->ieee;
afbf30a2 6713 struct iw_param *param = &wrqu->param;
274bfb8d 6714 struct lib80211_crypt_data *crypt;
afbf30a2
JK
6715 unsigned long flags;
6716 int ret = 0;
6717
6718 switch (param->flags & IW_AUTH_INDEX) {
6719 case IW_AUTH_WPA_VERSION:
1fbfea54 6720 break;
afbf30a2 6721 case IW_AUTH_CIPHER_PAIRWISE:
1fbfea54
ZY
6722 ipw_set_hw_decrypt_unicast(priv,
6723 wext_cipher2level(param->value));
6724 break;
afbf30a2 6725 case IW_AUTH_CIPHER_GROUP:
1fbfea54
ZY
6726 ipw_set_hw_decrypt_multicast(priv,
6727 wext_cipher2level(param->value));
6728 break;
afbf30a2
JK
6729 case IW_AUTH_KEY_MGMT:
6730 /*
6731 * ipw2200 does not use these parameters
6732 */
6733 break;
6734
6735 case IW_AUTH_TKIP_COUNTERMEASURES:
274bfb8d 6736 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
991d1cc5 6737 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
afbf30a2 6738 break;
afbf30a2
JK
6739
6740 flags = crypt->ops->get_flags(crypt->priv);
6741
6742 if (param->value)
6743 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6744 else
6745 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6746
6747 crypt->ops->set_flags(flags, crypt->priv);
6748
6749 break;
6750
6751 case IW_AUTH_DROP_UNENCRYPTED:{
6752 /* HACK:
6753 *
6754 * wpa_supplicant calls set_wpa_enabled when the driver
6755 * is loaded and unloaded, regardless of if WPA is being
6756 * used. No other calls are made which can be used to
6757 * determine if encryption will be used or not prior to
6758 * association being expected. If encryption is not being
6759 * used, drop_unencrypted is set to false, else true -- we
6760 * can use this to determine if the CAP_PRIVACY_ON bit should
6761 * be set.
6762 */
b0a4e7d8 6763 struct libipw_security sec = {
afbf30a2
JK
6764 .flags = SEC_ENABLED,
6765 .enabled = param->value,
6766 };
6767 priv->ieee->drop_unencrypted = param->value;
6768 /* We only change SEC_LEVEL for open mode. Others
6769 * are set by ipw_wpa_set_encryption.
6770 */
6771 if (!param->value) {
6772 sec.flags |= SEC_LEVEL;
6773 sec.level = SEC_LEVEL_0;
6774 } else {
6775 sec.flags |= SEC_LEVEL;
6776 sec.level = SEC_LEVEL_1;
6777 }
6778 if (priv->ieee->set_security)
6779 priv->ieee->set_security(priv->ieee->dev, &sec);
6780 break;
6781 }
6782
6783 case IW_AUTH_80211_AUTH_ALG:
6784 ret = ipw_wpa_set_auth_algs(priv, param->value);
6785 break;
6786
6787 case IW_AUTH_WPA_ENABLED:
6788 ret = ipw_wpa_enable(priv, param->value);
e3c5a64e 6789 ipw_disassociate(priv);
afbf30a2
JK
6790 break;
6791
6792 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6793 ieee->ieee802_1x = param->value;
6794 break;
6795
afbf30a2
JK
6796 case IW_AUTH_PRIVACY_INVOKED:
6797 ieee->privacy_invoked = param->value;
6798 break;
6799
6800 default:
6801 return -EOPNOTSUPP;
6802 }
6803 return ret;
6804}
6805
6806/* SIOCGIWAUTH */
6807static int ipw_wx_get_auth(struct net_device *dev,
6808 struct iw_request_info *info,
6809 union iwreq_data *wrqu, char *extra)
6810{
b0a4e7d8
JL
6811 struct ipw_priv *priv = libipw_priv(dev);
6812 struct libipw_device *ieee = priv->ieee;
274bfb8d 6813 struct lib80211_crypt_data *crypt;
afbf30a2
JK
6814 struct iw_param *param = &wrqu->param;
6815 int ret = 0;
6816
6817 switch (param->flags & IW_AUTH_INDEX) {
6818 case IW_AUTH_WPA_VERSION:
6819 case IW_AUTH_CIPHER_PAIRWISE:
6820 case IW_AUTH_CIPHER_GROUP:
6821 case IW_AUTH_KEY_MGMT:
6822 /*
6823 * wpa_supplicant will control these internally
6824 */
6825 ret = -EOPNOTSUPP;
6826 break;
6827
6828 case IW_AUTH_TKIP_COUNTERMEASURES:
274bfb8d 6829 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
991d1cc5 6830 if (!crypt || !crypt->ops->get_flags)
afbf30a2 6831 break;
afbf30a2
JK
6832
6833 param->value = (crypt->ops->get_flags(crypt->priv) &
6834 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
6835
6836 break;
6837
6838 case IW_AUTH_DROP_UNENCRYPTED:
6839 param->value = ieee->drop_unencrypted;
6840 break;
6841
6842 case IW_AUTH_80211_AUTH_ALG:
6843 param->value = ieee->sec.auth_mode;
6844 break;
6845
6846 case IW_AUTH_WPA_ENABLED:
6847 param->value = ieee->wpa_enabled;
6848 break;
6849
6850 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6851 param->value = ieee->ieee802_1x;
6852 break;
6853
6854 case IW_AUTH_ROAMING_CONTROL:
6855 case IW_AUTH_PRIVACY_INVOKED:
6856 param->value = ieee->privacy_invoked;
6857 break;
6858
6859 default:
6860 return -EOPNOTSUPP;
6861 }
6862 return 0;
6863}
6864
6865/* SIOCSIWENCODEEXT */
6866static int ipw_wx_set_encodeext(struct net_device *dev,
6867 struct iw_request_info *info,
6868 union iwreq_data *wrqu, char *extra)
6869{
b0a4e7d8 6870 struct ipw_priv *priv = libipw_priv(dev);
afbf30a2
JK
6871 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6872
6873 if (hwcrypto) {
afbf30a2 6874 if (ext->alg == IW_ENCODE_ALG_TKIP) {
567deaf6
HL
6875 /* IPW HW can't build TKIP MIC,
6876 host decryption still needed */
6877 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6878 priv->ieee->host_mc_decrypt = 1;
6879 else {
6880 priv->ieee->host_encrypt = 0;
6881 priv->ieee->host_encrypt_msdu = 1;
6882 priv->ieee->host_decrypt = 1;
6883 }
afbf30a2
JK
6884 } else {
6885 priv->ieee->host_encrypt = 0;
6886 priv->ieee->host_encrypt_msdu = 0;
6887 priv->ieee->host_decrypt = 0;
567deaf6 6888 priv->ieee->host_mc_decrypt = 0;
afbf30a2
JK
6889 }
6890 }
6891
b0a4e7d8 6892 return libipw_wx_set_encodeext(priv->ieee, info, wrqu, extra);
afbf30a2
JK
6893}
6894
6895/* SIOCGIWENCODEEXT */
6896static int ipw_wx_get_encodeext(struct net_device *dev,
6897 struct iw_request_info *info,
6898 union iwreq_data *wrqu, char *extra)
6899{
b0a4e7d8
JL
6900 struct ipw_priv *priv = libipw_priv(dev);
6901 return libipw_wx_get_encodeext(priv->ieee, info, wrqu, extra);
afbf30a2
JK
6902}
6903
6904/* SIOCSIWMLME */
6905static int ipw_wx_set_mlme(struct net_device *dev,
6906 struct iw_request_info *info,
6907 union iwreq_data *wrqu, char *extra)
6908{
b0a4e7d8 6909 struct ipw_priv *priv = libipw_priv(dev);
afbf30a2 6910 struct iw_mlme *mlme = (struct iw_mlme *)extra;
e62e1ee0 6911 __le16 reason;
afbf30a2
JK
6912
6913 reason = cpu_to_le16(mlme->reason_code);
6914
6915 switch (mlme->cmd) {
6916 case IW_MLME_DEAUTH:
67fd6b45 6917 /* silently ignore */
afbf30a2
JK
6918 break;
6919
6920 case IW_MLME_DISASSOC:
6921 ipw_disassociate(priv);
6922 break;
6923
6924 default:
6925 return -EOPNOTSUPP;
6926 }
6927 return 0;
6928}
afbf30a2 6929
e43e3c1e 6930#ifdef CONFIG_IPW2200_QOS
afbf30a2
JK
6931
6932/* QoS */
6933/*
6934* get the modulation type of the current network or
6935* the card current mode
6936*/
53d0bcf8 6937static u8 ipw_qos_current_mode(struct ipw_priv * priv)
afbf30a2
JK
6938{
6939 u8 mode = 0;
6940
6941 if (priv->status & STATUS_ASSOCIATED) {
6942 unsigned long flags;
6943
6944 spin_lock_irqsave(&priv->ieee->lock, flags);
6945 mode = priv->assoc_network->mode;
6946 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6947 } else {
6948 mode = priv->ieee->mode;
6949 }
9fd1ea42 6950 IPW_DEBUG_QOS("QoS network/card mode %d\n", mode);
afbf30a2 6951 return mode;
b095c381 6952}
ea2b26e0 6953
b095c381
JK
6954/*
6955* Handle management frame beacon and probe response
6956*/
3b9990cb
JK
6957static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6958 int active_network,
b0a4e7d8 6959 struct libipw_network *network)
b095c381 6960{
b0a4e7d8 6961 u32 size = sizeof(struct libipw_qos_parameters);
b095c381 6962
afbf30a2 6963 if (network->capability & WLAN_CAPABILITY_IBSS)
b095c381
JK
6964 network->qos_data.active = network->qos_data.supported;
6965
6966 if (network->flags & NETWORK_HAS_QOS_MASK) {
afbf30a2
JK
6967 if (active_network &&
6968 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
b095c381
JK
6969 network->qos_data.active = network->qos_data.supported;
6970
6971 if ((network->qos_data.active == 1) && (active_network == 1) &&
6972 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6973 (network->qos_data.old_param_count !=
6974 network->qos_data.param_count)) {
6975 network->qos_data.old_param_count =
6976 network->qos_data.param_count;
6977 schedule_work(&priv->qos_activate);
afbf30a2
JK
6978 IPW_DEBUG_QOS("QoS parameters change call "
6979 "qos_activate\n");
b095c381 6980 }
ea2b26e0 6981 } else {
afbf30a2
JK
6982 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
6983 memcpy(&network->qos_data.parameters,
b095c381 6984 &def_parameters_CCK, size);
afbf30a2
JK
6985 else
6986 memcpy(&network->qos_data.parameters,
b095c381 6987 &def_parameters_OFDM, size);
afbf30a2 6988
b095c381 6989 if ((network->qos_data.active == 1) && (active_network == 1)) {
9fd1ea42 6990 IPW_DEBUG_QOS("QoS was disabled call qos_activate\n");
b095c381
JK
6991 schedule_work(&priv->qos_activate);
6992 }
6993
6994 network->qos_data.active = 0;
6995 network->qos_data.supported = 0;
ea2b26e0 6996 }
afbf30a2
JK
6997 if ((priv->status & STATUS_ASSOCIATED) &&
6998 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6999 if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
c5d3dce8 7000 if (network->capability & WLAN_CAPABILITY_IBSS)
b095c381 7001 if ((network->ssid_len ==
afbf30a2
JK
7002 priv->assoc_network->ssid_len) &&
7003 !memcmp(network->ssid,
7004 priv->assoc_network->ssid,
7005 network->ssid_len)) {
bcb6d916 7006 schedule_work(&priv->merge_networks);
b095c381 7007 }
b095c381 7008 }
ea2b26e0 7009
b095c381
JK
7010 return 0;
7011}
7012
7013/*
7014* This function set up the firmware to support QoS. It sends
7015* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
7016*/
7017static int ipw_qos_activate(struct ipw_priv *priv,
b0a4e7d8 7018 struct libipw_qos_data *qos_network_data)
b095c381
JK
7019{
7020 int err;
b0a4e7d8
JL
7021 struct libipw_qos_parameters qos_parameters[QOS_QOS_SETS];
7022 struct libipw_qos_parameters *active_one = NULL;
7023 u32 size = sizeof(struct libipw_qos_parameters);
b095c381
JK
7024 u32 burst_duration;
7025 int i;
7026 u8 type;
7027
7028 type = ipw_qos_current_mode(priv);
7029
7030 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
7031 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
7032 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
7033 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
7034
7035 if (qos_network_data == NULL) {
7036 if (type == IEEE_B) {
7037 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
7038 active_one = &def_parameters_CCK;
7039 } else
7040 active_one = &def_parameters_OFDM;
7041
afbf30a2 7042 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
b095c381
JK
7043 burst_duration = ipw_qos_get_burst_duration(priv);
7044 for (i = 0; i < QOS_QUEUE_NUM; i++)
afbf30a2 7045 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
8fffc15d 7046 cpu_to_le16(burst_duration);
afbf30a2 7047 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
b095c381 7048 if (type == IEEE_B) {
fd9071ec 7049 IPW_DEBUG_QOS("QoS activate IBSS network mode %d\n",
b095c381
JK
7050 type);
7051 if (priv->qos_data.qos_enable == 0)
7052 active_one = &def_parameters_CCK;
7053 else
7054 active_one = priv->qos_data.def_qos_parm_CCK;
7055 } else {
7056 if (priv->qos_data.qos_enable == 0)
7057 active_one = &def_parameters_OFDM;
7058 else
7059 active_one = priv->qos_data.def_qos_parm_OFDM;
7060 }
afbf30a2 7061 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
b095c381
JK
7062 } else {
7063 unsigned long flags;
7064 int active;
7065
7066 spin_lock_irqsave(&priv->ieee->lock, flags);
7067 active_one = &(qos_network_data->parameters);
7068 qos_network_data->old_param_count =
7069 qos_network_data->param_count;
afbf30a2 7070 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
b095c381
JK
7071 active = qos_network_data->supported;
7072 spin_unlock_irqrestore(&priv->ieee->lock, flags);
7073
7074 if (active == 0) {
7075 burst_duration = ipw_qos_get_burst_duration(priv);
7076 for (i = 0; i < QOS_QUEUE_NUM; i++)
7077 qos_parameters[QOS_PARAM_SET_ACTIVE].
8fffc15d 7078 tx_op_limit[i] = cpu_to_le16(burst_duration);
b095c381
JK
7079 }
7080 }
7081
7082 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
2c208890 7083 err = ipw_send_qos_params_command(priv, &qos_parameters[0]);
b095c381
JK
7084 if (err)
7085 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
7086
7087 return err;
7088}
7089
7090/*
7091* send IPW_CMD_WME_INFO to the firmware
7092*/
7093static int ipw_qos_set_info_element(struct ipw_priv *priv)
7094{
7095 int ret = 0;
b0a4e7d8 7096 struct libipw_qos_information_element qos_info;
b095c381
JK
7097
7098 if (priv == NULL)
7099 return -1;
7100
7101 qos_info.elementID = QOS_ELEMENT_ID;
b0a4e7d8 7102 qos_info.length = sizeof(struct libipw_qos_information_element) - 2;
b095c381
JK
7103
7104 qos_info.version = QOS_VERSION_1;
7105 qos_info.ac_info = 0;
7106
7107 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
7108 qos_info.qui_type = QOS_OUI_TYPE;
7109 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
7110
7111 ret = ipw_send_qos_info_command(priv, &qos_info);
7112 if (ret != 0) {
7113 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
7114 }
7115 return ret;
7116}
7117
7118/*
7119* Set the QoS parameter with the association request structure
7120*/
7121static int ipw_qos_association(struct ipw_priv *priv,
b0a4e7d8 7122 struct libipw_network *network)
b095c381
JK
7123{
7124 int err = 0;
b0a4e7d8
JL
7125 struct libipw_qos_data *qos_data = NULL;
7126 struct libipw_qos_data ibss_data = {
b095c381
JK
7127 .supported = 1,
7128 .active = 1,
7129 };
7130
7131 switch (priv->ieee->iw_mode) {
7132 case IW_MODE_ADHOC:
5d9428de 7133 BUG_ON(!(network->capability & WLAN_CAPABILITY_IBSS));
b095c381
JK
7134
7135 qos_data = &ibss_data;
7136 break;
7137
7138 case IW_MODE_INFRA:
7139 qos_data = &network->qos_data;
7140 break;
7141
7142 default:
7143 BUG();
7144 break;
7145 }
7146
7147 err = ipw_qos_activate(priv, qos_data);
7148 if (err) {
7149 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
7150 return err;
7151 }
7152
7153 if (priv->qos_data.qos_enable && qos_data->supported) {
7154 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
7155 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
7156 return ipw_qos_set_info_element(priv);
7157 }
7158
7159 return 0;
7160}
7161
7162/*
0779bf2d
ML
7163* handling the beaconing responses. if we get different QoS setting
7164* off the network from the associated setting, adjust the QoS
b095c381
JK
7165* setting
7166*/
7167static int ipw_qos_association_resp(struct ipw_priv *priv,
b0a4e7d8 7168 struct libipw_network *network)
b095c381
JK
7169{
7170 int ret = 0;
7171 unsigned long flags;
b0a4e7d8 7172 u32 size = sizeof(struct libipw_qos_parameters);
b095c381
JK
7173 int set_qos_param = 0;
7174
afbf30a2
JK
7175 if ((priv == NULL) || (network == NULL) ||
7176 (priv->assoc_network == NULL))
b095c381
JK
7177 return ret;
7178
7179 if (!(priv->status & STATUS_ASSOCIATED))
7180 return ret;
7181
afbf30a2 7182 if ((priv->ieee->iw_mode != IW_MODE_INFRA))
b095c381 7183 return ret;
b095c381
JK
7184
7185 spin_lock_irqsave(&priv->ieee->lock, flags);
7186 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
afbf30a2 7187 memcpy(&priv->assoc_network->qos_data, &network->qos_data,
b0a4e7d8 7188 sizeof(struct libipw_qos_data));
b095c381
JK
7189 priv->assoc_network->qos_data.active = 1;
7190 if ((network->qos_data.old_param_count !=
7191 network->qos_data.param_count)) {
7192 set_qos_param = 1;
7193 network->qos_data.old_param_count =
7194 network->qos_data.param_count;
7195 }
7196
7197 } else {
afbf30a2
JK
7198 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
7199 memcpy(&priv->assoc_network->qos_data.parameters,
b095c381 7200 &def_parameters_CCK, size);
afbf30a2
JK
7201 else
7202 memcpy(&priv->assoc_network->qos_data.parameters,
b095c381 7203 &def_parameters_OFDM, size);
b095c381
JK
7204 priv->assoc_network->qos_data.active = 0;
7205 priv->assoc_network->qos_data.supported = 0;
7206 set_qos_param = 1;
7207 }
7208
7209 spin_unlock_irqrestore(&priv->ieee->lock, flags);
7210
7211 if (set_qos_param == 1)
7212 schedule_work(&priv->qos_activate);
7213
7214 return ret;
7215}
7216
7217static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
7218{
7219 u32 ret = 0;
7220
7221 if ((priv == NULL))
7222 return 0;
7223
b0a4e7d8 7224 if (!(priv->ieee->modulation & LIBIPW_OFDM_MODULATION))
b095c381 7225 ret = priv->qos_data.burst_duration_CCK;
afbf30a2 7226 else
b095c381 7227 ret = priv->qos_data.burst_duration_OFDM;
afbf30a2 7228
b095c381
JK
7229 return ret;
7230}
7231
7232/*
7233* Initialize the setting of QoS global
7234*/
7235static void ipw_qos_init(struct ipw_priv *priv, int enable,
7236 int burst_enable, u32 burst_duration_CCK,
7237 u32 burst_duration_OFDM)
7238{
7239 priv->qos_data.qos_enable = enable;
7240
7241 if (priv->qos_data.qos_enable) {
7242 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
7243 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
7244 IPW_DEBUG_QOS("QoS is enabled\n");
7245 } else {
7246 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
7247 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
7248 IPW_DEBUG_QOS("QoS is not enabled\n");
7249 }
7250
7251 priv->qos_data.burst_enable = burst_enable;
7252
7253 if (burst_enable) {
7254 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
7255 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
7256 } else {
7257 priv->qos_data.burst_duration_CCK = 0;
7258 priv->qos_data.burst_duration_OFDM = 0;
7259 }
7260}
7261
7262/*
7263* map the packet priority to the right TX Queue
7264*/
7265static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
7266{
7267 if (priority > 7 || !priv->qos_data.qos_enable)
7268 priority = 0;
7269
7270 return from_priority_to_tx_queue[priority] - 1;
7271}
7272
a5cf4fe6
ZY
7273static int ipw_is_qos_active(struct net_device *dev,
7274 struct sk_buff *skb)
b095c381 7275{
b0a4e7d8
JL
7276 struct ipw_priv *priv = libipw_priv(dev);
7277 struct libipw_qos_data *qos_data = NULL;
b095c381 7278 int active, supported;
a5cf4fe6
ZY
7279 u8 *daddr = skb->data + ETH_ALEN;
7280 int unicast = !is_multicast_ether_addr(daddr);
b095c381
JK
7281
7282 if (!(priv->status & STATUS_ASSOCIATED))
7283 return 0;
7284
7285 qos_data = &priv->assoc_network->qos_data;
7286
b095c381
JK
7287 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7288 if (unicast == 0)
7289 qos_data->active = 0;
7290 else
7291 qos_data->active = qos_data->supported;
7292 }
b095c381
JK
7293 active = qos_data->active;
7294 supported = qos_data->supported;
afbf30a2
JK
7295 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
7296 "unicast %d\n",
7297 priv->qos_data.qos_enable, active, supported, unicast);
a5cf4fe6
ZY
7298 if (active && priv->qos_data.qos_enable)
7299 return 1;
b095c381 7300
a5cf4fe6
ZY
7301 return 0;
7302
7303}
7304/*
7305* add QoS parameter to the TX command
7306*/
7307static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
7308 u16 priority,
7309 struct tfd_data *tfd)
7310{
7311 int tx_queue_id = 0;
7312
7313
7314 tx_queue_id = from_priority_to_tx_queue[priority] - 1;
7315 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
7316
7317 if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) {
7318 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
851ca268 7319 tfd->tfd.tfd_26.mchdr.qos_ctrl |= cpu_to_le16(CTRL_QOS_NO_ACK);
a5cf4fe6
ZY
7320 }
7321 return 0;
b095c381
JK
7322}
7323
7324/*
7325* background support to run QoS activate functionality
7326*/
c4028958 7327static void ipw_bg_qos_activate(struct work_struct *work)
b095c381 7328{
c4028958
DH
7329 struct ipw_priv *priv =
7330 container_of(work, struct ipw_priv, qos_activate);
b095c381 7331
4644151b 7332 mutex_lock(&priv->mutex);
b095c381
JK
7333
7334 if (priv->status & STATUS_ASSOCIATED)
7335 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
7336
4644151b 7337 mutex_unlock(&priv->mutex);
b095c381
JK
7338}
7339
3b9990cb 7340static int ipw_handle_probe_response(struct net_device *dev,
b0a4e7d8
JL
7341 struct libipw_probe_response *resp,
7342 struct libipw_network *network)
b095c381 7343{
b0a4e7d8 7344 struct ipw_priv *priv = libipw_priv(dev);
3b9990cb
JK
7345 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
7346 (network == priv->assoc_network));
43f66a6c 7347
3b9990cb 7348 ipw_qos_handle_probe_response(priv, active_network, network);
43f66a6c 7349
3b9990cb
JK
7350 return 0;
7351}
43f66a6c 7352
3b9990cb 7353static int ipw_handle_beacon(struct net_device *dev,
b0a4e7d8
JL
7354 struct libipw_beacon *resp,
7355 struct libipw_network *network)
3b9990cb 7356{
b0a4e7d8 7357 struct ipw_priv *priv = libipw_priv(dev);
3b9990cb
JK
7358 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
7359 (network == priv->assoc_network));
bf79451e 7360
3b9990cb 7361 ipw_qos_handle_probe_response(priv, active_network, network);
bf79451e 7362
b095c381
JK
7363 return 0;
7364}
bf79451e 7365
3b9990cb 7366static int ipw_handle_assoc_response(struct net_device *dev,
b0a4e7d8
JL
7367 struct libipw_assoc_response *resp,
7368 struct libipw_network *network)
3b9990cb 7369{
b0a4e7d8 7370 struct ipw_priv *priv = libipw_priv(dev);
3b9990cb
JK
7371 ipw_qos_association_resp(priv, network);
7372 return 0;
7373}
43f66a6c 7374
b0a4e7d8 7375static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters
b095c381
JK
7376 *qos_param)
7377{
4e22699f
ZY
7378 return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS,
7379 sizeof(*qos_param) * 3, qos_param);
b095c381
JK
7380}
7381
b0a4e7d8 7382static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element
b095c381
JK
7383 *qos_param)
7384{
4e22699f
ZY
7385 return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param),
7386 qos_param);
43f66a6c
JK
7387}
7388
e43e3c1e 7389#endif /* CONFIG_IPW2200_QOS */
b095c381 7390
43f66a6c 7391static int ipw_associate_network(struct ipw_priv *priv,
b0a4e7d8 7392 struct libipw_network *network,
0edd5b44 7393 struct ipw_supported_rates *rates, int roaming)
43f66a6c
JK
7394{
7395 int err;
9387b7ca 7396 DECLARE_SSID_BUF(ssid);
43f66a6c
JK
7397
7398 if (priv->config & CFG_FIXED_RATE)
b095c381 7399 ipw_set_fixed_rate(priv, network->mode);
43f66a6c
JK
7400
7401 if (!(priv->config & CFG_STATIC_ESSID)) {
bf79451e 7402 priv->essid_len = min(network->ssid_len,
0edd5b44 7403 (u8) IW_ESSID_MAX_SIZE);
43f66a6c
JK
7404 memcpy(priv->essid, network->ssid, priv->essid_len);
7405 }
7406
7407 network->last_associate = jiffies;
7408
7409 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
7410 priv->assoc_request.channel = network->channel;
3e234b4e
ZY
7411 priv->assoc_request.auth_key = 0;
7412
43f66a6c 7413 if ((priv->capability & CAP_PRIVACY_ON) &&
3e234b4e 7414 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) {
43f66a6c 7415 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
b095c381
JK
7416 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7417
1ba61e05 7418 if (priv->ieee->sec.level == SEC_LEVEL_1)
b095c381 7419 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
3e234b4e
ZY
7420
7421 } else if ((priv->capability & CAP_PRIVACY_ON) &&
7422 (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP))
7423 priv->assoc_request.auth_type = AUTH_LEAP;
7424 else
43f66a6c 7425 priv->assoc_request.auth_type = AUTH_OPEN;
43f66a6c 7426
b095c381 7427 if (priv->ieee->wpa_ie_len) {
5b5e807f 7428 priv->assoc_request.policy_support = cpu_to_le16(0x02); /* RSN active */
ea2b26e0
JK
7429 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
7430 priv->ieee->wpa_ie_len);
7431 }
43f66a6c 7432
bf79451e
JG
7433 /*
7434 * It is valid for our ieee device to support multiple modes, but
7435 * when it comes to associating to a given network we have to choose
43f66a6c
JK
7436 * just one mode.
7437 */
7438 if (network->mode & priv->ieee->mode & IEEE_A)
7439 priv->assoc_request.ieee_mode = IPW_A_MODE;
7440 else if (network->mode & priv->ieee->mode & IEEE_G)
7441 priv->assoc_request.ieee_mode = IPW_G_MODE;
7442 else if (network->mode & priv->ieee->mode & IEEE_B)
7443 priv->assoc_request.ieee_mode = IPW_B_MODE;
7444
5b5e807f 7445 priv->assoc_request.capability = cpu_to_le16(network->capability);
ea2b26e0
JK
7446 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
7447 && !(priv->config & CFG_PREAMBLE_LONG)) {
7448 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
7449 } else {
7450 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
7451
7452 /* Clear the short preamble if we won't be supporting it */
7453 priv->assoc_request.capability &=
5b5e807f 7454 ~cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
ea2b26e0
JK
7455 }
7456
afbf30a2
JK
7457 /* Clear capability bits that aren't used in Ad Hoc */
7458 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7459 priv->assoc_request.capability &=
5b5e807f 7460 ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
afbf30a2 7461
70f23fd6 7462 IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, "
ea2b26e0 7463 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
43f66a6c 7464 roaming ? "Rea" : "A",
9387b7ca 7465 print_ssid(ssid, priv->essid, priv->essid_len),
bf79451e
JG
7466 network->channel,
7467 ipw_modes[priv->assoc_request.ieee_mode],
7468 rates->num_rates,
ea2b26e0
JK
7469 (priv->assoc_request.preamble_length ==
7470 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
7471 network->capability &
7472 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
43f66a6c 7473 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
bf79451e
JG
7474 priv->capability & CAP_PRIVACY_ON ?
7475 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
43f66a6c
JK
7476 "(open)") : "",
7477 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
bf79451e 7478 priv->capability & CAP_PRIVACY_ON ?
b095c381 7479 '1' + priv->ieee->sec.active_key : '.',
0edd5b44 7480 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
43f66a6c 7481
5b5e807f 7482 priv->assoc_request.beacon_interval = cpu_to_le16(network->beacon_interval);
43f66a6c 7483 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
0edd5b44 7484 (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {
43f66a6c
JK
7485 priv->assoc_request.assoc_type = HC_IBSS_START;
7486 priv->assoc_request.assoc_tsf_msw = 0;
7487 priv->assoc_request.assoc_tsf_lsw = 0;
7488 } else {
7489 if (unlikely(roaming))
7490 priv->assoc_request.assoc_type = HC_REASSOCIATE;
7491 else
7492 priv->assoc_request.assoc_type = HC_ASSOCIATE;
5b5e807f
AV
7493 priv->assoc_request.assoc_tsf_msw = cpu_to_le32(network->time_stamp[1]);
7494 priv->assoc_request.assoc_tsf_lsw = cpu_to_le32(network->time_stamp[0]);
43f66a6c
JK
7495 }
7496
afbf30a2 7497 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
43f66a6c
JK
7498
7499 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7500 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
5b5e807f 7501 priv->assoc_request.atim_window = cpu_to_le16(network->atim_window);
43f66a6c 7502 } else {
afbf30a2 7503 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
43f66a6c
JK
7504 priv->assoc_request.atim_window = 0;
7505 }
7506
5b5e807f 7507 priv->assoc_request.listen_interval = cpu_to_le16(network->listen_interval);
bf79451e 7508
43f66a6c
JK
7509 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
7510 if (err) {
7511 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
7512 return err;
7513 }
7514
7515 rates->ieee_mode = priv->assoc_request.ieee_mode;
7516 rates->purpose = IPW_RATE_CONNECT;
7517 ipw_send_supported_rates(priv, rates);
bf79451e 7518
43f66a6c
JK
7519 if (priv->assoc_request.ieee_mode == IPW_G_MODE)
7520 priv->sys_config.dot11g_auto_detection = 1;
7521 else
7522 priv->sys_config.dot11g_auto_detection = 0;
c848d0af
JK
7523
7524 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7525 priv->sys_config.answer_broadcast_ssid_probe = 1;
7526 else
7527 priv->sys_config.answer_broadcast_ssid_probe = 0;
7528
d685b8c2 7529 err = ipw_send_system_config(priv);
43f66a6c
JK
7530 if (err) {
7531 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
7532 return err;
7533 }
bf79451e 7534
43f66a6c 7535 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
ea2b26e0 7536 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
43f66a6c
JK
7537 if (err) {
7538 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
7539 return err;
7540 }
7541
7542 /*
7543 * If preemption is enabled, it is possible for the association
7544 * to complete before we return from ipw_send_associate. Therefore
7545 * we have to be sure and update our priviate data first.
7546 */
7547 priv->channel = network->channel;
7548 memcpy(priv->bssid, network->bssid, ETH_ALEN);
bf79451e 7549 priv->status |= STATUS_ASSOCIATING;
43f66a6c
JK
7550 priv->status &= ~STATUS_SECURITY_UPDATED;
7551
7552 priv->assoc_network = network;
7553
e43e3c1e 7554#ifdef CONFIG_IPW2200_QOS
b095c381
JK
7555 ipw_qos_association(priv, network);
7556#endif
7557
43f66a6c
JK
7558 err = ipw_send_associate(priv, &priv->assoc_request);
7559 if (err) {
7560 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
7561 return err;
7562 }
bf79451e 7563
9fd1ea42 7564 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n",
9387b7ca 7565 print_ssid(ssid, priv->essid, priv->essid_len),
e174961c 7566 priv->bssid);
43f66a6c
JK
7567
7568 return 0;
7569}
7570
7571static void ipw_roam(void *data)
7572{
7573 struct ipw_priv *priv = data;
b0a4e7d8 7574 struct libipw_network *network = NULL;
43f66a6c
JK
7575 struct ipw_network_match match = {
7576 .network = priv->assoc_network
7577 };
7578
7579 /* The roaming process is as follows:
bf79451e
JG
7580 *
7581 * 1. Missed beacon threshold triggers the roaming process by
43f66a6c
JK
7582 * setting the status ROAM bit and requesting a scan.
7583 * 2. When the scan completes, it schedules the ROAM work
7584 * 3. The ROAM work looks at all of the known networks for one that
7585 * is a better network than the currently associated. If none
7586 * found, the ROAM process is over (ROAM bit cleared)
7587 * 4. If a better network is found, a disassociation request is
7588 * sent.
7589 * 5. When the disassociation completes, the roam work is again
7590 * scheduled. The second time through, the driver is no longer
7591 * associated, and the newly selected network is sent an
bf79451e 7592 * association request.
43f66a6c
JK
7593 * 6. At this point ,the roaming process is complete and the ROAM
7594 * status bit is cleared.
7595 */
7596
7597 /* If we are no longer associated, and the roaming bit is no longer
7598 * set, then we are not actively roaming, so just return */
7599 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING)))
7600 return;
bf79451e 7601
43f66a6c 7602 if (priv->status & STATUS_ASSOCIATED) {
bf79451e 7603 /* First pass through ROAM process -- look for a better
43f66a6c 7604 * network */
a613bffd 7605 unsigned long flags;
43f66a6c
JK
7606 u8 rssi = priv->assoc_network->stats.rssi;
7607 priv->assoc_network->stats.rssi = -128;
a613bffd 7608 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c
JK
7609 list_for_each_entry(network, &priv->ieee->network_list, list) {
7610 if (network != priv->assoc_network)
7611 ipw_best_network(priv, &match, network, 1);
7612 }
a613bffd 7613 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c 7614 priv->assoc_network->stats.rssi = rssi;
bf79451e 7615
43f66a6c
JK
7616 if (match.network == priv->assoc_network) {
7617 IPW_DEBUG_ASSOC("No better APs in this network to "
7618 "roam to.\n");
7619 priv->status &= ~STATUS_ROAMING;
7620 ipw_debug_config(priv);
7621 return;
7622 }
bf79451e 7623
43f66a6c
JK
7624 ipw_send_disassociate(priv, 1);
7625 priv->assoc_network = match.network;
7626
7627 return;
bf79451e 7628 }
43f66a6c
JK
7629
7630 /* Second pass through ROAM process -- request association */
7631 ipw_compatible_rates(priv, priv->assoc_network, &match.rates);
7632 ipw_associate_network(priv, priv->assoc_network, &match.rates, 1);
7633 priv->status &= ~STATUS_ROAMING;
7634}
7635
c4028958 7636static void ipw_bg_roam(struct work_struct *work)
c848d0af 7637{
c4028958
DH
7638 struct ipw_priv *priv =
7639 container_of(work, struct ipw_priv, roam);
4644151b 7640 mutex_lock(&priv->mutex);
c4028958 7641 ipw_roam(priv);
4644151b 7642 mutex_unlock(&priv->mutex);
c848d0af
JK
7643}
7644
7645static int ipw_associate(void *data)
43f66a6c
JK
7646{
7647 struct ipw_priv *priv = data;
7648
b0a4e7d8 7649 struct libipw_network *network = NULL;
43f66a6c
JK
7650 struct ipw_network_match match = {
7651 .network = NULL
7652 };
7653 struct ipw_supported_rates *rates;
7654 struct list_head *element;
a613bffd 7655 unsigned long flags;
9387b7ca 7656 DECLARE_SSID_BUF(ssid);
43f66a6c 7657
b095c381
JK
7658 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7659 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7660 return 0;
7661 }
7662
c848d0af 7663 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
afbf30a2
JK
7664 IPW_DEBUG_ASSOC("Not attempting association (already in "
7665 "progress)\n");
c848d0af
JK
7666 return 0;
7667 }
7668
e6324726
HL
7669 if (priv->status & STATUS_DISASSOCIATING) {
7670 IPW_DEBUG_ASSOC("Not attempting association (in "
7671 "disassociating)\n ");
bcb6d916 7672 schedule_work(&priv->associate);
e6324726
HL
7673 return 0;
7674 }
7675
c848d0af 7676 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
afbf30a2
JK
7677 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
7678 "initialized)\n");
c848d0af
JK
7679 return 0;
7680 }
43f66a6c
JK
7681
7682 if (!(priv->config & CFG_ASSOCIATE) &&
3e4127fa 7683 !(priv->config & (CFG_STATIC_ESSID | CFG_STATIC_BSSID))) {
43f66a6c 7684 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
c848d0af 7685 return 0;
43f66a6c
JK
7686 }
7687
a613bffd
JK
7688 /* Protect our use of the network_list */
7689 spin_lock_irqsave(&priv->ieee->lock, flags);
bf79451e 7690 list_for_each_entry(network, &priv->ieee->network_list, list)
0edd5b44 7691 ipw_best_network(priv, &match, network, 0);
43f66a6c
JK
7692
7693 network = match.network;
7694 rates = &match.rates;
7695
7696 if (network == NULL &&
7697 priv->ieee->iw_mode == IW_MODE_ADHOC &&
7698 priv->config & CFG_ADHOC_CREATE &&
7699 priv->config & CFG_STATIC_ESSID &&
a6d4eae8
DW
7700 priv->config & CFG_STATIC_CHANNEL) {
7701 /* Use oldest network if the free list is empty */
7702 if (list_empty(&priv->ieee->network_free_list)) {
b0a4e7d8
JL
7703 struct libipw_network *oldest = NULL;
7704 struct libipw_network *target;
a6d4eae8
DW
7705
7706 list_for_each_entry(target, &priv->ieee->network_list, list) {
7707 if ((oldest == NULL) ||
7708 (target->last_scanned < oldest->last_scanned))
7709 oldest = target;
7710 }
7711
7712 /* If there are no more slots, expire the oldest */
7713 list_del(&oldest->list);
7714 target = oldest;
e174961c 7715 IPW_DEBUG_ASSOC("Expired '%s' (%pM) from "
a6d4eae8 7716 "network list.\n",
9387b7ca
JL
7717 print_ssid(ssid, target->ssid,
7718 target->ssid_len),
e174961c 7719 target->bssid);
a6d4eae8
DW
7720 list_add_tail(&target->list,
7721 &priv->ieee->network_free_list);
7722 }
7723
43f66a6c 7724 element = priv->ieee->network_free_list.next;
b0a4e7d8 7725 network = list_entry(element, struct libipw_network, list);
43f66a6c
JK
7726 ipw_adhoc_create(priv, network);
7727 rates = &priv->rates;
7728 list_del(element);
7729 list_add_tail(&network->list, &priv->ieee->network_list);
7730 }
a613bffd 7731 spin_unlock_irqrestore(&priv->ieee->lock, flags);
bf79451e 7732
43f66a6c
JK
7733 /* If we reached the end of the list, then we don't have any valid
7734 * matching APs */
7735 if (!network) {
7736 ipw_debug_config(priv);
7737
b095c381
JK
7738 if (!(priv->status & STATUS_SCANNING)) {
7739 if (!(priv->config & CFG_SPEED_SCAN))
bcb6d916
TH
7740 schedule_delayed_work(&priv->request_scan,
7741 SCAN_INTERVAL);
b095c381 7742 else
bcb6d916 7743 schedule_delayed_work(&priv->request_scan, 0);
b095c381 7744 }
bf79451e 7745
c848d0af 7746 return 0;
43f66a6c
JK
7747 }
7748
7749 ipw_associate_network(priv, network, rates, 0);
c848d0af
JK
7750
7751 return 1;
7752}
7753
c4028958 7754static void ipw_bg_associate(struct work_struct *work)
c848d0af 7755{
c4028958
DH
7756 struct ipw_priv *priv =
7757 container_of(work, struct ipw_priv, associate);
4644151b 7758 mutex_lock(&priv->mutex);
c4028958 7759 ipw_associate(priv);
4644151b 7760 mutex_unlock(&priv->mutex);
43f66a6c 7761}
bf79451e 7762
b095c381
JK
7763static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7764 struct sk_buff *skb)
7765{
7766 struct ieee80211_hdr *hdr;
7767 u16 fc;
7768
7769 hdr = (struct ieee80211_hdr *)skb->data;
72118015 7770 fc = le16_to_cpu(hdr->frame_control);
b095c381
JK
7771 if (!(fc & IEEE80211_FCTL_PROTECTED))
7772 return;
7773
7774 fc &= ~IEEE80211_FCTL_PROTECTED;
72118015 7775 hdr->frame_control = cpu_to_le16(fc);
b095c381
JK
7776 switch (priv->ieee->sec.level) {
7777 case SEC_LEVEL_3:
7778 /* Remove CCMP HDR */
b0a4e7d8
JL
7779 memmove(skb->data + LIBIPW_3ADDR_LEN,
7780 skb->data + LIBIPW_3ADDR_LEN + 8,
7781 skb->len - LIBIPW_3ADDR_LEN - 8);
f4ff497d 7782 skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */
b095c381
JK
7783 break;
7784 case SEC_LEVEL_2:
7785 break;
7786 case SEC_LEVEL_1:
7787 /* Remove IV */
b0a4e7d8
JL
7788 memmove(skb->data + LIBIPW_3ADDR_LEN,
7789 skb->data + LIBIPW_3ADDR_LEN + 4,
7790 skb->len - LIBIPW_3ADDR_LEN - 4);
f4ff497d 7791 skb_trim(skb, skb->len - 8); /* IV + ICV */
b095c381
JK
7792 break;
7793 case SEC_LEVEL_0:
7794 break;
7795 default:
af901ca1 7796 printk(KERN_ERR "Unknown security level %d\n",
b095c381
JK
7797 priv->ieee->sec.level);
7798 break;
7799 }
43f66a6c 7800}
bf79451e 7801
b095c381
JK
7802static void ipw_handle_data_packet(struct ipw_priv *priv,
7803 struct ipw_rx_mem_buffer *rxb,
b0a4e7d8 7804 struct libipw_rx_stats *stats)
43f66a6c 7805{
ce55cbaf 7806 struct net_device *dev = priv->net_dev;
b0a4e7d8 7807 struct libipw_hdr_4addr *hdr;
43f66a6c
JK
7808 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7809
7810 /* We received data from the HW, so stop the watchdog */
ce55cbaf 7811 dev->trans_start = jiffies;
43f66a6c 7812
bf79451e 7813 /* We only process data packets if the
43f66a6c 7814 * interface is open */
a613bffd 7815 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
43f66a6c 7816 skb_tailroom(rxb->skb))) {
ce55cbaf 7817 dev->stats.rx_errors++;
43f66a6c
JK
7818 priv->wstats.discard.misc++;
7819 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7820 return;
7821 } else if (unlikely(!netif_running(priv->net_dev))) {
ce55cbaf 7822 dev->stats.rx_dropped++;
43f66a6c
JK
7823 priv->wstats.discard.misc++;
7824 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7825 return;
7826 }
7827
7828 /* Advance skb->data to the start of the actual payload */
aaa4d308 7829 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
43f66a6c
JK
7830
7831 /* Set the size of the skb to the size of the frame */
a613bffd 7832 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
43f66a6c
JK
7833
7834 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7835
b095c381 7836 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
b0a4e7d8 7837 hdr = (struct libipw_hdr_4addr *)rxb->skb->data;
567deaf6 7838 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
3c19065a 7839 (is_multicast_ether_addr(hdr->addr1) ?
567deaf6 7840 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
b095c381
JK
7841 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7842
b0a4e7d8 7843 if (!libipw_rx(priv->ieee, rxb->skb, stats))
ce55cbaf 7844 dev->stats.rx_errors++;
b0a4e7d8 7845 else { /* libipw_rx succeeded, so it now owns the SKB */
43f66a6c 7846 rxb->skb = NULL;
b095c381 7847 __ipw_led_activity_on(priv);
a613bffd 7848 }
43f66a6c
JK
7849}
7850
459d4087 7851#ifdef CONFIG_IPW2200_RADIOTAP
24a47dbd
MK
7852static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7853 struct ipw_rx_mem_buffer *rxb,
b0a4e7d8 7854 struct libipw_rx_stats *stats)
24a47dbd 7855{
ce55cbaf 7856 struct net_device *dev = priv->net_dev;
24a47dbd
MK
7857 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7858 struct ipw_rx_frame *frame = &pkt->u.frame;
7859
7860 /* initial pull of some data */
7861 u16 received_channel = frame->received_channel;
7862 u8 antennaAndPhy = frame->antennaAndPhy;
7863 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */
7864 u16 pktrate = frame->rate;
7865
7866 /* Magic struct that slots into the radiotap header -- no reason
7867 * to build this manually element by element, we can write it much
7868 * more efficiently than we can parse it. ORDER MATTERS HERE */
d685b8c2 7869 struct ipw_rt_hdr *ipw_rt;
24a47dbd 7870
92c1ff1f 7871 unsigned short len = le16_to_cpu(pkt->u.frame.length);
24a47dbd
MK
7872
7873 /* We received data from the HW, so stop the watchdog */
ce55cbaf 7874 dev->trans_start = jiffies;
24a47dbd
MK
7875
7876 /* We only process data packets if the
7877 * interface is open */
7878 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7879 skb_tailroom(rxb->skb))) {
ce55cbaf 7880 dev->stats.rx_errors++;
24a47dbd
MK
7881 priv->wstats.discard.misc++;
7882 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7883 return;
7884 } else if (unlikely(!netif_running(priv->net_dev))) {
ce55cbaf 7885 dev->stats.rx_dropped++;
24a47dbd
MK
7886 priv->wstats.discard.misc++;
7887 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7888 return;
7889 }
7890
7891 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7892 * that now */
7893 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7894 /* FIXME: Should alloc bigger skb instead */
ce55cbaf 7895 dev->stats.rx_dropped++;
24a47dbd
MK
7896 priv->wstats.discard.misc++;
7897 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7898 return;
7899 }
7900
7901 /* copy the frame itself */
7902 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
7903 rxb->skb->data + IPW_RX_FRAME_SIZE, len);
7904
24a47dbd
MK
7905 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
7906
7907 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7908 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
743b84d2 7909 ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct ipw_rt_hdr)); /* total header+data */
24a47dbd
MK
7910
7911 /* Big bitfield of all the fields we provide in radiotap */
743b84d2
AV
7912 ipw_rt->rt_hdr.it_present = cpu_to_le32(
7913 (1 << IEEE80211_RADIOTAP_TSFT) |
4b1f8a99 7914 (1 << IEEE80211_RADIOTAP_FLAGS) |
24a47dbd
MK
7915 (1 << IEEE80211_RADIOTAP_RATE) |
7916 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7917 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
d685b8c2 7918 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
24a47dbd
MK
7919 (1 << IEEE80211_RADIOTAP_ANTENNA));
7920
7921 /* Zero the flags, we'll add to them as we go */
7922 ipw_rt->rt_flags = 0;
4b1f8a99
ZY
7923 ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
7924 frame->parent_tsf[2] << 16 |
7925 frame->parent_tsf[1] << 8 |
7926 frame->parent_tsf[0]);
24a47dbd
MK
7927
7928 /* Convert signal to DBM */
7929 ipw_rt->rt_dbmsignal = antsignal;
21f8a73f 7930 ipw_rt->rt_dbmnoise = (s8) le16_to_cpu(frame->noise);
24a47dbd
MK
7931
7932 /* Convert the channel data and set the flags */
7933 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
7934 if (received_channel > 14) { /* 802.11a */
7935 ipw_rt->rt_chbitmask =
7936 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7937 } else if (antennaAndPhy & 32) { /* 802.11b */
7938 ipw_rt->rt_chbitmask =
7939 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7940 } else { /* 802.11g */
7941 ipw_rt->rt_chbitmask =
472caf8c 7942 cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
24a47dbd
MK
7943 }
7944
7945 /* set the rate in multiples of 500k/s */
7946 switch (pktrate) {
7947 case IPW_TX_RATE_1MB:
7948 ipw_rt->rt_rate = 2;
7949 break;
7950 case IPW_TX_RATE_2MB:
7951 ipw_rt->rt_rate = 4;
7952 break;
7953 case IPW_TX_RATE_5MB:
7954 ipw_rt->rt_rate = 10;
7955 break;
7956 case IPW_TX_RATE_6MB:
7957 ipw_rt->rt_rate = 12;
7958 break;
7959 case IPW_TX_RATE_9MB:
7960 ipw_rt->rt_rate = 18;
7961 break;
7962 case IPW_TX_RATE_11MB:
7963 ipw_rt->rt_rate = 22;
7964 break;
7965 case IPW_TX_RATE_12MB:
7966 ipw_rt->rt_rate = 24;
7967 break;
7968 case IPW_TX_RATE_18MB:
7969 ipw_rt->rt_rate = 36;
7970 break;
7971 case IPW_TX_RATE_24MB:
7972 ipw_rt->rt_rate = 48;
7973 break;
7974 case IPW_TX_RATE_36MB:
7975 ipw_rt->rt_rate = 72;
7976 break;
7977 case IPW_TX_RATE_48MB:
7978 ipw_rt->rt_rate = 96;
7979 break;
7980 case IPW_TX_RATE_54MB:
7981 ipw_rt->rt_rate = 108;
7982 break;
7983 default:
7984 ipw_rt->rt_rate = 0;
7985 break;
7986 }
7987
7988 /* antenna number */
7989 ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */
7990
7991 /* set the preamble flag if we have it */
7992 if ((antennaAndPhy & 64))
7993 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7994
7995 /* Set the size of the skb to the size of the frame */
7996 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
43f66a6c
JK
7997
7998 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7999
b0a4e7d8 8000 if (!libipw_rx(priv->ieee, rxb->skb, stats))
ce55cbaf 8001 dev->stats.rx_errors++;
b0a4e7d8 8002 else { /* libipw_rx succeeded, so it now owns the SKB */
24a47dbd
MK
8003 rxb->skb = NULL;
8004 /* no LED during capture */
8005 }
8006}
8007#endif
8008
d685b8c2 8009#ifdef CONFIG_IPW2200_PROMISCUOUS
b0a4e7d8 8010#define libipw_is_probe_response(fc) \
d685b8c2
ZY
8011 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && \
8012 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP )
8013
b0a4e7d8 8014#define libipw_is_management(fc) \
d685b8c2
ZY
8015 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
8016
b0a4e7d8 8017#define libipw_is_control(fc) \
d685b8c2
ZY
8018 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
8019
b0a4e7d8 8020#define libipw_is_data(fc) \
d685b8c2
ZY
8021 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
8022
b0a4e7d8 8023#define libipw_is_assoc_request(fc) \
d685b8c2
ZY
8024 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ)
8025
b0a4e7d8 8026#define libipw_is_reassoc_request(fc) \
d685b8c2
ZY
8027 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
8028
8029static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
8030 struct ipw_rx_mem_buffer *rxb,
b0a4e7d8 8031 struct libipw_rx_stats *stats)
d685b8c2 8032{
ce55cbaf 8033 struct net_device *dev = priv->prom_net_dev;
d685b8c2
ZY
8034 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
8035 struct ipw_rx_frame *frame = &pkt->u.frame;
8036 struct ipw_rt_hdr *ipw_rt;
8037
8038 /* First cache any information we need before we overwrite
8039 * the information provided in the skb from the hardware */
8040 struct ieee80211_hdr *hdr;
8041 u16 channel = frame->received_channel;
8042 u8 phy_flags = frame->antennaAndPhy;
8043 s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
21f8a73f 8044 s8 noise = (s8) le16_to_cpu(frame->noise);
d685b8c2 8045 u8 rate = frame->rate;
92c1ff1f 8046 unsigned short len = le16_to_cpu(pkt->u.frame.length);
d685b8c2
ZY
8047 struct sk_buff *skb;
8048 int hdr_only = 0;
8049 u16 filter = priv->prom_priv->filter;
8050
8051 /* If the filter is set to not include Rx frames then return */
8052 if (filter & IPW_PROM_NO_RX)
8053 return;
8054
d685b8c2 8055 /* We received data from the HW, so stop the watchdog */
ce55cbaf 8056 dev->trans_start = jiffies;
d685b8c2
ZY
8057
8058 if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
ce55cbaf 8059 dev->stats.rx_errors++;
d685b8c2
ZY
8060 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
8061 return;
8062 }
8063
8064 /* We only process data packets if the interface is open */
ce55cbaf
SH
8065 if (unlikely(!netif_running(dev))) {
8066 dev->stats.rx_dropped++;
d685b8c2
ZY
8067 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
8068 return;
8069 }
8070
8071 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
8072 * that now */
8073 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
8074 /* FIXME: Should alloc bigger skb instead */
ce55cbaf 8075 dev->stats.rx_dropped++;
d685b8c2
ZY
8076 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
8077 return;
8078 }
8079
8080 hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
b0a4e7d8 8081 if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {
d685b8c2
ZY
8082 if (filter & IPW_PROM_NO_MGMT)
8083 return;
8084 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
8085 hdr_only = 1;
b0a4e7d8 8086 } else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {
d685b8c2
ZY
8087 if (filter & IPW_PROM_NO_CTL)
8088 return;
8089 if (filter & IPW_PROM_CTL_HEADER_ONLY)
8090 hdr_only = 1;
b0a4e7d8 8091 } else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {
d685b8c2
ZY
8092 if (filter & IPW_PROM_NO_DATA)
8093 return;
8094 if (filter & IPW_PROM_DATA_HEADER_ONLY)
8095 hdr_only = 1;
8096 }
8097
8098 /* Copy the SKB since this is for the promiscuous side */
8099 skb = skb_copy(rxb->skb, GFP_ATOMIC);
8100 if (skb == NULL) {
8101 IPW_ERROR("skb_clone failed for promiscuous copy.\n");
8102 return;
8103 }
8104
8105 /* copy the frame data to write after where the radiotap header goes */
8106 ipw_rt = (void *)skb->data;
8107
8108 if (hdr_only)
b0a4e7d8 8109 len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));
d685b8c2
ZY
8110
8111 memcpy(ipw_rt->payload, hdr, len);
8112
d685b8c2
ZY
8113 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
8114 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
743b84d2 8115 ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt)); /* total header+data */
d685b8c2
ZY
8116
8117 /* Set the size of the skb to the size of the frame */
743b84d2 8118 skb_put(skb, sizeof(*ipw_rt) + len);
d685b8c2
ZY
8119
8120 /* Big bitfield of all the fields we provide in radiotap */
743b84d2
AV
8121 ipw_rt->rt_hdr.it_present = cpu_to_le32(
8122 (1 << IEEE80211_RADIOTAP_TSFT) |
4b1f8a99 8123 (1 << IEEE80211_RADIOTAP_FLAGS) |
d685b8c2
ZY
8124 (1 << IEEE80211_RADIOTAP_RATE) |
8125 (1 << IEEE80211_RADIOTAP_CHANNEL) |
8126 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
8127 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
8128 (1 << IEEE80211_RADIOTAP_ANTENNA));
8129
8130 /* Zero the flags, we'll add to them as we go */
8131 ipw_rt->rt_flags = 0;
4b1f8a99
ZY
8132 ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
8133 frame->parent_tsf[2] << 16 |
8134 frame->parent_tsf[1] << 8 |
8135 frame->parent_tsf[0]);
d685b8c2
ZY
8136
8137 /* Convert to DBM */
8138 ipw_rt->rt_dbmsignal = signal;
8139 ipw_rt->rt_dbmnoise = noise;
8140
8141 /* Convert the channel data and set the flags */
8142 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(channel));
8143 if (channel > 14) { /* 802.11a */
8144 ipw_rt->rt_chbitmask =
8145 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
8146 } else if (phy_flags & (1 << 5)) { /* 802.11b */
8147 ipw_rt->rt_chbitmask =
8148 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
8149 } else { /* 802.11g */
8150 ipw_rt->rt_chbitmask =
472caf8c 8151 cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
d685b8c2
ZY
8152 }
8153
8154 /* set the rate in multiples of 500k/s */
8155 switch (rate) {
8156 case IPW_TX_RATE_1MB:
8157 ipw_rt->rt_rate = 2;
8158 break;
8159 case IPW_TX_RATE_2MB:
8160 ipw_rt->rt_rate = 4;
8161 break;
8162 case IPW_TX_RATE_5MB:
8163 ipw_rt->rt_rate = 10;
8164 break;
8165 case IPW_TX_RATE_6MB:
8166 ipw_rt->rt_rate = 12;
8167 break;
8168 case IPW_TX_RATE_9MB:
8169 ipw_rt->rt_rate = 18;
8170 break;
8171 case IPW_TX_RATE_11MB:
8172 ipw_rt->rt_rate = 22;
8173 break;
8174 case IPW_TX_RATE_12MB:
8175 ipw_rt->rt_rate = 24;
8176 break;
8177 case IPW_TX_RATE_18MB:
8178 ipw_rt->rt_rate = 36;
8179 break;
8180 case IPW_TX_RATE_24MB:
8181 ipw_rt->rt_rate = 48;
8182 break;
8183 case IPW_TX_RATE_36MB:
8184 ipw_rt->rt_rate = 72;
8185 break;
8186 case IPW_TX_RATE_48MB:
8187 ipw_rt->rt_rate = 96;
8188 break;
8189 case IPW_TX_RATE_54MB:
8190 ipw_rt->rt_rate = 108;
8191 break;
8192 default:
8193 ipw_rt->rt_rate = 0;
8194 break;
8195 }
8196
8197 /* antenna number */
8198 ipw_rt->rt_antenna = (phy_flags & 3);
8199
8200 /* set the preamble flag if we have it */
8201 if (phy_flags & (1 << 6))
8202 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
8203
8204 IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
8205
b0a4e7d8 8206 if (!libipw_rx(priv->prom_priv->ieee, skb, stats)) {
ce55cbaf 8207 dev->stats.rx_errors++;
d685b8c2
ZY
8208 dev_kfree_skb_any(skb);
8209 }
8210}
8211#endif
8212
858119e1 8213static int is_network_packet(struct ipw_priv *priv,
b0a4e7d8 8214 struct libipw_hdr_4addr *header)
ea2b26e0 8215{
25985edc 8216 /* Filter incoming packets to determine if they are targeted toward
ea2b26e0
JK
8217 * this network, discarding packets coming from ourselves */
8218 switch (priv->ieee->iw_mode) {
a613bffd 8219 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
c848d0af
JK
8220 /* packets from our adapter are dropped (echo) */
8221 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
8222 return 0;
8223
90700fd9 8224 /* {broad,multi}cast packets to our BSSID go through */
3c19065a 8225 if (is_multicast_ether_addr(header->addr1))
ea2b26e0 8226 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
a613bffd
JK
8227
8228 /* packets to our adapter go through */
8229 return !memcmp(header->addr1, priv->net_dev->dev_addr,
8230 ETH_ALEN);
a613bffd 8231
90700fd9 8232 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
c848d0af
JK
8233 /* packets from our adapter are dropped (echo) */
8234 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
8235 return 0;
8236
90700fd9 8237 /* {broad,multi}cast packets to our BSS go through */
3c19065a 8238 if (is_multicast_ether_addr(header->addr1))
a613bffd
JK
8239 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
8240
8241 /* packets to our adapter go through */
8242 return !memcmp(header->addr1, priv->net_dev->dev_addr,
8243 ETH_ALEN);
ea2b26e0 8244 }
a613bffd 8245
ea2b26e0
JK
8246 return 1;
8247}
8248
afbf30a2
JK
8249#define IPW_PACKET_RETRY_TIME HZ
8250
858119e1 8251static int is_duplicate_packet(struct ipw_priv *priv,
b0a4e7d8 8252 struct libipw_hdr_4addr *header)
afbf30a2 8253{
afbf30a2
JK
8254 u16 sc = le16_to_cpu(header->seq_ctl);
8255 u16 seq = WLAN_GET_SEQ_SEQ(sc);
8256 u16 frag = WLAN_GET_SEQ_FRAG(sc);
8257 u16 *last_seq, *last_frag;
8258 unsigned long *last_time;
8259
8260 switch (priv->ieee->iw_mode) {
8261 case IW_MODE_ADHOC:
8262 {
8263 struct list_head *p;
8264 struct ipw_ibss_seq *entry = NULL;
8265 u8 *mac = header->addr2;
8266 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
8267
8268 __list_for_each(p, &priv->ibss_mac_hash[index]) {
8269 entry =
8270 list_entry(p, struct ipw_ibss_seq, list);
8271 if (!memcmp(entry->mac, mac, ETH_ALEN))
8272 break;
8273 }
8274 if (p == &priv->ibss_mac_hash[index]) {
8275 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
8276 if (!entry) {
8277 IPW_ERROR
8278 ("Cannot malloc new mac entry\n");
8279 return 0;
8280 }
8281 memcpy(entry->mac, mac, ETH_ALEN);
8282 entry->seq_num = seq;
8283 entry->frag_num = frag;
8284 entry->packet_time = jiffies;
8285 list_add(&entry->list,
8286 &priv->ibss_mac_hash[index]);
8287 return 0;
8288 }
8289 last_seq = &entry->seq_num;
8290 last_frag = &entry->frag_num;
8291 last_time = &entry->packet_time;
8292 break;
8293 }
8294 case IW_MODE_INFRA:
8295 last_seq = &priv->last_seq_num;
8296 last_frag = &priv->last_frag_num;
8297 last_time = &priv->last_packet_time;
8298 break;
8299 default:
8300 return 0;
8301 }
8302 if ((*last_seq == seq) &&
8303 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
8304 if (*last_frag == frag)
8305 goto drop;
8306 if (*last_frag + 1 != frag)
8307 /* out-of-order fragment */
8308 goto drop;
afbf30a2
JK
8309 } else
8310 *last_seq = seq;
8311
f57ce7ce 8312 *last_frag = frag;
afbf30a2
JK
8313 *last_time = jiffies;
8314 return 0;
8315
8316 drop:
87b016cb
ZY
8317 /* Comment this line now since we observed the card receives
8318 * duplicate packets but the FCTL_RETRY bit is not set in the
8319 * IBSS mode with fragmentation enabled.
72118015 8320 BUG_ON(!(le16_to_cpu(header->frame_control) & IEEE80211_FCTL_RETRY)); */
afbf30a2
JK
8321 return 1;
8322}
8323
b095c381
JK
8324static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
8325 struct ipw_rx_mem_buffer *rxb,
b0a4e7d8 8326 struct libipw_rx_stats *stats)
b095c381
JK
8327{
8328 struct sk_buff *skb = rxb->skb;
8329 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
b0a4e7d8 8330 struct libipw_hdr_4addr *header = (struct libipw_hdr_4addr *)
b095c381
JK
8331 (skb->data + IPW_RX_FRAME_SIZE);
8332
b0a4e7d8 8333 libipw_rx_mgt(priv->ieee, header, stats);
b095c381
JK
8334
8335 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
8336 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
8337 IEEE80211_STYPE_PROBE_RESP) ||
8338 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
8339 IEEE80211_STYPE_BEACON))) {
8340 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
8341 ipw_add_station(priv, header->addr2);
8342 }
8343
8344 if (priv->config & CFG_NET_STATS) {
8345 IPW_DEBUG_HC("sending stat packet\n");
8346
8347 /* Set the size of the skb to the size of the full
8348 * ipw header and 802.11 frame */
8349 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
8350 IPW_RX_FRAME_SIZE);
8351
8352 /* Advance past the ipw packet header to the 802.11 frame */
8353 skb_pull(skb, IPW_RX_FRAME_SIZE);
8354
b0a4e7d8 8355 /* Push the libipw_rx_stats before the 802.11 frame */
b095c381
JK
8356 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
8357
8358 skb->dev = priv->ieee->dev;
8359
b0a4e7d8 8360 /* Point raw at the libipw_stats */
459a98ed 8361 skb_reset_mac_header(skb);
b095c381
JK
8362
8363 skb->pkt_type = PACKET_OTHERHOST;
c1b4aa3f 8364 skb->protocol = cpu_to_be16(ETH_P_80211_STATS);
b095c381
JK
8365 memset(skb->cb, 0, sizeof(rxb->skb->cb));
8366 netif_rx(skb);
43f66a6c 8367 rxb->skb = NULL;
b095c381 8368 }
43f66a6c
JK
8369}
8370
43f66a6c 8371/*
25985edc 8372 * Main entry function for receiving a packet with 80211 headers. This
43f66a6c 8373 * should be called when ever the FW has notified us that there is a new
25985edc 8374 * skb in the receive queue.
43f66a6c
JK
8375 */
8376static void ipw_rx(struct ipw_priv *priv)
8377{
8378 struct ipw_rx_mem_buffer *rxb;
8379 struct ipw_rx_packet *pkt;
b0a4e7d8 8380 struct libipw_hdr_4addr *header;
43f66a6c
JK
8381 u32 r, w, i;
8382 u8 network_packet;
943dbef4 8383 u8 fill_rx = 0;
43f66a6c 8384
b095c381
JK
8385 r = ipw_read32(priv, IPW_RX_READ_INDEX);
8386 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
943dbef4
DW
8387 i = priv->rxq->read;
8388
8389 if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2))
8390 fill_rx = 1;
43f66a6c
JK
8391
8392 while (i != r) {
8393 rxb = priv->rxq->queue[i];
43f66a6c
JK
8394 if (unlikely(rxb == NULL)) {
8395 printk(KERN_CRIT "Queue not allocated!\n");
8396 break;
8397 }
43f66a6c
JK
8398 priv->rxq->queue[i] = NULL;
8399
8400 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
b095c381 8401 IPW_RX_BUF_SIZE,
43f66a6c
JK
8402 PCI_DMA_FROMDEVICE);
8403
8404 pkt = (struct ipw_rx_packet *)rxb->skb->data;
8405 IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",
8406 pkt->header.message_type,
0edd5b44 8407 pkt->header.rx_seq_num, pkt->header.control_bits);
43f66a6c
JK
8408
8409 switch (pkt->header.message_type) {
0edd5b44 8410 case RX_FRAME_TYPE: /* 802.11 frame */ {
b0a4e7d8 8411 struct libipw_rx_stats stats = {
851ca268 8412 .rssi = pkt->u.frame.rssi_dbm -
0edd5b44 8413 IPW_RSSI_TO_DBM,
c848d0af 8414 .signal =
21f8a73f 8415 pkt->u.frame.rssi_dbm -
b191608a 8416 IPW_RSSI_TO_DBM + 0x100,
c848d0af
JK
8417 .noise =
8418 le16_to_cpu(pkt->u.frame.noise),
0edd5b44
JG
8419 .rate = pkt->u.frame.rate,
8420 .mac_time = jiffies,
8421 .received_channel =
8422 pkt->u.frame.received_channel,
8423 .freq =
8424 (pkt->u.frame.
8425 control & (1 << 0)) ?
b0a4e7d8
JL
8426 LIBIPW_24GHZ_BAND :
8427 LIBIPW_52GHZ_BAND,
a613bffd 8428 .len = le16_to_cpu(pkt->u.frame.length),
0edd5b44
JG
8429 };
8430
8431 if (stats.rssi != 0)
b0a4e7d8 8432 stats.mask |= LIBIPW_STATMASK_RSSI;
0edd5b44 8433 if (stats.signal != 0)
b0a4e7d8 8434 stats.mask |= LIBIPW_STATMASK_SIGNAL;
c848d0af 8435 if (stats.noise != 0)
b0a4e7d8 8436 stats.mask |= LIBIPW_STATMASK_NOISE;
0edd5b44 8437 if (stats.rate != 0)
b0a4e7d8 8438 stats.mask |= LIBIPW_STATMASK_RATE;
0edd5b44
JG
8439
8440 priv->rx_packets++;
43f66a6c 8441
d685b8c2
ZY
8442#ifdef CONFIG_IPW2200_PROMISCUOUS
8443 if (priv->prom_net_dev && netif_running(priv->prom_net_dev))
8444 ipw_handle_promiscuous_rx(priv, rxb, &stats);
8445#endif
8446
b095c381 8447#ifdef CONFIG_IPW2200_MONITOR
0edd5b44 8448 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
459d4087 8449#ifdef CONFIG_IPW2200_RADIOTAP
d685b8c2
ZY
8450
8451 ipw_handle_data_packet_monitor(priv,
8452 rxb,
8453 &stats);
24a47dbd 8454#else
d685b8c2
ZY
8455 ipw_handle_data_packet(priv, rxb,
8456 &stats);
24a47dbd 8457#endif
0edd5b44
JG
8458 break;
8459 }
43f66a6c 8460#endif
bf79451e 8461
0edd5b44 8462 header =
b0a4e7d8 8463 (struct libipw_hdr_4addr *)(rxb->skb->
0dacca1f
JK
8464 data +
8465 IPW_RX_FRAME_SIZE);
43f66a6c
JK
8466 /* TODO: Check Ad-Hoc dest/source and make sure
8467 * that we are actually parsing these packets
bf79451e 8468 * correctly -- we should probably use the
43f66a6c
JK
8469 * frame control of the packet and disregard
8470 * the current iw_mode */
0edd5b44 8471
ea2b26e0
JK
8472 network_packet =
8473 is_network_packet(priv, header);
0edd5b44
JG
8474 if (network_packet && priv->assoc_network) {
8475 priv->assoc_network->stats.rssi =
8476 stats.rssi;
00d21de5
ZY
8477 priv->exp_avg_rssi =
8478 exponential_average(priv->exp_avg_rssi,
8479 stats.rssi, DEPTH_RSSI);
0edd5b44
JG
8480 }
8481
8482 IPW_DEBUG_RX("Frame: len=%u\n",
a613bffd 8483 le16_to_cpu(pkt->u.frame.length));
0edd5b44 8484
a613bffd 8485 if (le16_to_cpu(pkt->u.frame.length) <
b0a4e7d8 8486 libipw_get_hdrlen(le16_to_cpu(
9d0be03a 8487 header->frame_ctl))) {
0edd5b44
JG
8488 IPW_DEBUG_DROP
8489 ("Received packet is too small. "
8490 "Dropping.\n");
ce55cbaf 8491 priv->net_dev->stats.rx_errors++;
0edd5b44
JG
8492 priv->wstats.discard.misc++;
8493 break;
8494 }
8495
a613bffd
JK
8496 switch (WLAN_FC_GET_TYPE
8497 (le16_to_cpu(header->frame_ctl))) {
b095c381 8498
0edd5b44 8499 case IEEE80211_FTYPE_MGMT:
b095c381
JK
8500 ipw_handle_mgmt_packet(priv, rxb,
8501 &stats);
0edd5b44
JG
8502 break;
8503
8504 case IEEE80211_FTYPE_CTL:
8505 break;
8506
8507 case IEEE80211_FTYPE_DATA:
afbf30a2
JK
8508 if (unlikely(!network_packet ||
8509 is_duplicate_packet(priv,
8510 header)))
8511 {
0edd5b44 8512 IPW_DEBUG_DROP("Dropping: "
e174961c
JB
8513 "%pM, "
8514 "%pM, "
8515 "%pM\n",
8516 header->addr1,
8517 header->addr2,
8518 header->addr3);
b095c381
JK
8519 break;
8520 }
8521
8522 ipw_handle_data_packet(priv, rxb,
8523 &stats);
8524
0edd5b44
JG
8525 break;
8526 }
43f66a6c
JK
8527 break;
8528 }
bf79451e 8529
0edd5b44
JG
8530 case RX_HOST_NOTIFICATION_TYPE:{
8531 IPW_DEBUG_RX
8532 ("Notification: subtype=%02X flags=%02X size=%d\n",
43f66a6c
JK
8533 pkt->u.notification.subtype,
8534 pkt->u.notification.flags,
720eeb43 8535 le16_to_cpu(pkt->u.notification.size));
0edd5b44
JG
8536 ipw_rx_notification(priv, &pkt->u.notification);
8537 break;
8538 }
43f66a6c
JK
8539
8540 default:
8541 IPW_DEBUG_RX("Bad Rx packet of type %d\n",
8542 pkt->header.message_type);
8543 break;
8544 }
bf79451e
JG
8545
8546 /* For now we just don't re-use anything. We can tweak this
8547 * later to try and re-use notification packets and SKBs that
43f66a6c
JK
8548 * fail to Rx correctly */
8549 if (rxb->skb != NULL) {
8550 dev_kfree_skb_any(rxb->skb);
8551 rxb->skb = NULL;
8552 }
bf79451e 8553
43f66a6c 8554 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
b095c381 8555 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c 8556 list_add_tail(&rxb->list, &priv->rxq->rx_used);
bf79451e 8557
43f66a6c 8558 i = (i + 1) % RX_QUEUE_SIZE;
943dbef4
DW
8559
8560 /* If there are a lot of unsued frames, restock the Rx queue
8561 * so the ucode won't assert */
8562 if (fill_rx) {
8563 priv->rxq->read = i;
8564 ipw_rx_queue_replenish(priv);
8565 }
43f66a6c
JK
8566 }
8567
8568 /* Backtrack one entry */
943dbef4 8569 priv->rxq->read = i;
43f66a6c
JK
8570 ipw_rx_queue_restock(priv);
8571}
8572
afbf30a2
JK
8573#define DEFAULT_RTS_THRESHOLD 2304U
8574#define MIN_RTS_THRESHOLD 1U
8575#define MAX_RTS_THRESHOLD 2304U
8576#define DEFAULT_BEACON_INTERVAL 100U
8577#define DEFAULT_SHORT_RETRY_LIMIT 7U
8578#define DEFAULT_LONG_RETRY_LIMIT 4U
8579
d6d5b5c1
ZY
8580/**
8581 * ipw_sw_reset
8582 * @option: options to control different reset behaviour
8583 * 0 = reset everything except the 'disable' module_param
8584 * 1 = reset everything and print out driver info (for probe only)
8585 * 2 = reset everything
8586 */
8587static int ipw_sw_reset(struct ipw_priv *priv, int option)
43f66a6c 8588{
afbf30a2
JK
8589 int band, modulation;
8590 int old_mode = priv->ieee->iw_mode;
43f66a6c 8591
afbf30a2
JK
8592 /* Initialize module parameter values here */
8593 priv->config = 0;
43f66a6c 8594
afbf30a2
JK
8595 /* We default to disabling the LED code as right now it causes
8596 * too many systems to lock up... */
21f8a73f 8597 if (!led_support)
afbf30a2 8598 priv->config |= CFG_NO_LED;
43f66a6c 8599
afbf30a2
JK
8600 if (associate)
8601 priv->config |= CFG_ASSOCIATE;
8602 else
8603 IPW_DEBUG_INFO("Auto associate disabled.\n");
bf79451e 8604
afbf30a2
JK
8605 if (auto_create)
8606 priv->config |= CFG_ADHOC_CREATE;
8607 else
8608 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
43f66a6c 8609
17ed081d
ZY
8610 priv->config &= ~CFG_STATIC_ESSID;
8611 priv->essid_len = 0;
8612 memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
8613
d6d5b5c1 8614 if (disable && option) {
afbf30a2
JK
8615 priv->status |= STATUS_RF_KILL_SW;
8616 IPW_DEBUG_INFO("Radio disabled.\n");
43f66a6c 8617 }
bf79451e 8618
21f8a73f 8619 if (default_channel != 0) {
afbf30a2 8620 priv->config |= CFG_STATIC_CHANNEL;
21f8a73f
RC
8621 priv->channel = default_channel;
8622 IPW_DEBUG_INFO("Bind to static channel %d\n", default_channel);
afbf30a2 8623 /* TODO: Validate that provided channel is in range */
43f66a6c 8624 }
e43e3c1e 8625#ifdef CONFIG_IPW2200_QOS
afbf30a2
JK
8626 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8627 burst_duration_CCK, burst_duration_OFDM);
e43e3c1e 8628#endif /* CONFIG_IPW2200_QOS */
43f66a6c 8629
21f8a73f 8630 switch (network_mode) {
afbf30a2
JK
8631 case 1:
8632 priv->ieee->iw_mode = IW_MODE_ADHOC;
8633 priv->net_dev->type = ARPHRD_ETHER;
8634
8635 break;
8636#ifdef CONFIG_IPW2200_MONITOR
8637 case 2:
8638 priv->ieee->iw_mode = IW_MODE_MONITOR;
459d4087 8639#ifdef CONFIG_IPW2200_RADIOTAP
24a47dbd
MK
8640 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8641#else
afbf30a2 8642 priv->net_dev->type = ARPHRD_IEEE80211;
24a47dbd 8643#endif
afbf30a2
JK
8644 break;
8645#endif
8646 default:
8647 case 0:
8648 priv->net_dev->type = ARPHRD_ETHER;
8649 priv->ieee->iw_mode = IW_MODE_INFRA;
8650 break;
43f66a6c
JK
8651 }
8652
afbf30a2
JK
8653 if (hwcrypto) {
8654 priv->ieee->host_encrypt = 0;
8655 priv->ieee->host_encrypt_msdu = 0;
8656 priv->ieee->host_decrypt = 0;
567deaf6 8657 priv->ieee->host_mc_decrypt = 0;
afbf30a2
JK
8658 }
8659 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
43f66a6c 8660
e402c937
ZY
8661 /* IPW2200/2915 is abled to do hardware fragmentation. */
8662 priv->ieee->host_open_frag = 0;
bf79451e 8663
afbf30a2
JK
8664 if ((priv->pci_dev->device == 0x4223) ||
8665 (priv->pci_dev->device == 0x4224)) {
e8c69e27 8666 if (option == 1)
afbf30a2
JK
8667 printk(KERN_INFO DRV_NAME
8668 ": Detected Intel PRO/Wireless 2915ABG Network "
8669 "Connection\n");
8670 priv->ieee->abg_true = 1;
b0a4e7d8
JL
8671 band = LIBIPW_52GHZ_BAND | LIBIPW_24GHZ_BAND;
8672 modulation = LIBIPW_OFDM_MODULATION |
8673 LIBIPW_CCK_MODULATION;
afbf30a2
JK
8674 priv->adapter = IPW_2915ABG;
8675 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
43f66a6c 8676 } else {
e8c69e27 8677 if (option == 1)
afbf30a2
JK
8678 printk(KERN_INFO DRV_NAME
8679 ": Detected Intel PRO/Wireless 2200BG Network "
8680 "Connection\n");
bf79451e 8681
afbf30a2 8682 priv->ieee->abg_true = 0;
b0a4e7d8
JL
8683 band = LIBIPW_24GHZ_BAND;
8684 modulation = LIBIPW_OFDM_MODULATION |
8685 LIBIPW_CCK_MODULATION;
afbf30a2
JK
8686 priv->adapter = IPW_2200BG;
8687 priv->ieee->mode = IEEE_G | IEEE_B;
43f66a6c
JK
8688 }
8689
afbf30a2
JK
8690 priv->ieee->freq_band = band;
8691 priv->ieee->modulation = modulation;
43f66a6c 8692
b0a4e7d8 8693 priv->rates_mask = LIBIPW_DEFAULT_RATES_MASK;
bf79451e 8694
afbf30a2
JK
8695 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
8696 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
43f66a6c 8697
afbf30a2
JK
8698 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8699 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
8700 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
43f66a6c 8701
afbf30a2
JK
8702 /* If power management is turned on, default to AC mode */
8703 priv->power_mode = IPW_POWER_AC;
8704 priv->tx_power = IPW_TX_POWER_DEFAULT;
8705
0ece35b5 8706 return old_mode == priv->ieee->iw_mode;
43f66a6c
JK
8707}
8708
8709/*
8710 * This file defines the Wireless Extension handlers. It does not
8711 * define any methods of hardware manipulation and relies on the
8712 * functions defined in ipw_main to provide the HW interaction.
bf79451e
JG
8713 *
8714 * The exception to this is the use of the ipw_get_ordinal()
25985edc 8715 * function used to poll the hardware vs. making unnecessary calls.
43f66a6c
JK
8716 *
8717 */
8718
43f66a6c
JK
8719static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
8720{
8721 if (channel == 0) {
8722 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
8723 priv->config &= ~CFG_STATIC_CHANNEL;
c848d0af
JK
8724 IPW_DEBUG_ASSOC("Attempting to associate with new "
8725 "parameters.\n");
8726 ipw_associate(priv);
43f66a6c
JK
8727 return 0;
8728 }
8729
8730 priv->config |= CFG_STATIC_CHANNEL;
8731
8732 if (priv->channel == channel) {
0edd5b44
JG
8733 IPW_DEBUG_INFO("Request to set channel to current value (%d)\n",
8734 channel);
43f66a6c
JK
8735 return 0;
8736 }
8737
8738 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
8739 priv->channel = channel;
8740
b095c381
JK
8741#ifdef CONFIG_IPW2200_MONITOR
8742 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
afbf30a2 8743 int i;
b095c381 8744 if (priv->status & STATUS_SCANNING) {
afbf30a2 8745 IPW_DEBUG_SCAN("Scan abort triggered due to "
b095c381 8746 "channel change.\n");
afbf30a2 8747 ipw_abort_scan(priv);
b095c381
JK
8748 }
8749
8750 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
8751 udelay(10);
8752
8753 if (priv->status & STATUS_SCANNING)
8754 IPW_DEBUG_SCAN("Still scanning...\n");
8755 else
8756 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
8757 1000 - i);
8758
8759 return 0;
43f66a6c 8760 }
b095c381
JK
8761#endif /* CONFIG_IPW2200_MONITOR */
8762
c848d0af
JK
8763 /* Network configuration changed -- force [re]association */
8764 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
8765 if (!ipw_disassociate(priv))
43f66a6c 8766 ipw_associate(priv);
43f66a6c
JK
8767
8768 return 0;
8769}
8770
bf79451e
JG
8771static int ipw_wx_set_freq(struct net_device *dev,
8772 struct iw_request_info *info,
8773 union iwreq_data *wrqu, char *extra)
43f66a6c 8774{
b0a4e7d8
JL
8775 struct ipw_priv *priv = libipw_priv(dev);
8776 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
43f66a6c 8777 struct iw_freq *fwrq = &wrqu->freq;
afbf30a2 8778 int ret = 0, i;
1fe0adb4
LH
8779 u8 channel, flags;
8780 int band;
b095c381
JK
8781
8782 if (fwrq->m == 0) {
8783 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
4644151b 8784 mutex_lock(&priv->mutex);
b095c381 8785 ret = ipw_set_channel(priv, 0);
4644151b 8786 mutex_unlock(&priv->mutex);
b095c381
JK
8787 return ret;
8788 }
43f66a6c
JK
8789 /* if setting by freq convert to channel */
8790 if (fwrq->e == 1) {
b0a4e7d8 8791 channel = libipw_freq_to_channel(priv->ieee, fwrq->m);
b095c381
JK
8792 if (channel == 0)
8793 return -EINVAL;
8794 } else
8795 channel = fwrq->m;
bf79451e 8796
b0a4e7d8 8797 if (!(band = libipw_is_valid_channel(priv->ieee, channel)))
b095c381 8798 return -EINVAL;
43f66a6c 8799
1fe0adb4 8800 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
b0a4e7d8 8801 i = libipw_channel_to_index(priv->ieee, channel);
afbf30a2
JK
8802 if (i == -1)
8803 return -EINVAL;
bf79451e 8804
b0a4e7d8 8805 flags = (band == LIBIPW_24GHZ_BAND) ?
1fe0adb4 8806 geo->bg[i].flags : geo->a[i].flags;
b0a4e7d8 8807 if (flags & LIBIPW_CH_PASSIVE_ONLY) {
afbf30a2
JK
8808 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
8809 return -EINVAL;
43f66a6c
JK
8810 }
8811 }
bf79451e 8812
9fd1ea42 8813 IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
4644151b 8814 mutex_lock(&priv->mutex);
b095c381 8815 ret = ipw_set_channel(priv, channel);
4644151b 8816 mutex_unlock(&priv->mutex);
c848d0af 8817 return ret;
43f66a6c
JK
8818}
8819
bf79451e
JG
8820static int ipw_wx_get_freq(struct net_device *dev,
8821 struct iw_request_info *info,
43f66a6c
JK
8822 union iwreq_data *wrqu, char *extra)
8823{
b0a4e7d8 8824 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
8825
8826 wrqu->freq.e = 0;
8827
8828 /* If we are associated, trying to associate, or have a statically
8829 * configured CHANNEL then return that; otherwise return ANY */
4644151b 8830 mutex_lock(&priv->mutex);
43f66a6c 8831 if (priv->config & CFG_STATIC_CHANNEL ||
c580f67f
ZY
8832 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) {
8833 int i;
8834
b0a4e7d8 8835 i = libipw_channel_to_index(priv->ieee, priv->channel);
c580f67f
ZY
8836 BUG_ON(i == -1);
8837 wrqu->freq.e = 1;
8838
b0a4e7d8
JL
8839 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
8840 case LIBIPW_52GHZ_BAND:
c580f67f
ZY
8841 wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000;
8842 break;
8843
b0a4e7d8 8844 case LIBIPW_24GHZ_BAND:
c580f67f
ZY
8845 wrqu->freq.m = priv->ieee->geo.bg[i].freq * 100000;
8846 break;
8847
8848 default:
8849 BUG();
8850 }
8851 } else
43f66a6c
JK
8852 wrqu->freq.m = 0;
8853
4644151b 8854 mutex_unlock(&priv->mutex);
9fd1ea42 8855 IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
43f66a6c
JK
8856 return 0;
8857}
8858
bf79451e
JG
8859static int ipw_wx_set_mode(struct net_device *dev,
8860 struct iw_request_info *info,
43f66a6c
JK
8861 union iwreq_data *wrqu, char *extra)
8862{
b0a4e7d8 8863 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
8864 int err = 0;
8865
8866 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
8867
43f66a6c 8868 switch (wrqu->mode) {
b095c381 8869#ifdef CONFIG_IPW2200_MONITOR
43f66a6c
JK
8870 case IW_MODE_MONITOR:
8871#endif
8872 case IW_MODE_ADHOC:
8873 case IW_MODE_INFRA:
8874 break;
8875 case IW_MODE_AUTO:
8876 wrqu->mode = IW_MODE_INFRA;
8877 break;
8878 default:
8879 return -EINVAL;
8880 }
b095c381
JK
8881 if (wrqu->mode == priv->ieee->iw_mode)
8882 return 0;
43f66a6c 8883
4644151b 8884 mutex_lock(&priv->mutex);
43f66a6c 8885
afbf30a2
JK
8886 ipw_sw_reset(priv, 0);
8887
b095c381 8888#ifdef CONFIG_IPW2200_MONITOR
bf79451e 8889 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
43f66a6c 8890 priv->net_dev->type = ARPHRD_ETHER;
bf79451e
JG
8891
8892 if (wrqu->mode == IW_MODE_MONITOR)
459d4087 8893#ifdef CONFIG_IPW2200_RADIOTAP
24a47dbd
MK
8894 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8895#else
43f66a6c 8896 priv->net_dev->type = ARPHRD_IEEE80211;
24a47dbd 8897#endif
b095c381 8898#endif /* CONFIG_IPW2200_MONITOR */
bf79451e 8899
bf79451e 8900 /* Free the existing firmware and reset the fw_loaded
877d0310 8901 * flag so ipw_load() will bring in the new firmware */
afbf30a2 8902 free_firmware();
43f66a6c
JK
8903
8904 priv->ieee->iw_mode = wrqu->mode;
bf79451e 8905
bcb6d916 8906 schedule_work(&priv->adapter_restart);
4644151b 8907 mutex_unlock(&priv->mutex);
0edd5b44 8908 return err;
43f66a6c
JK
8909}
8910
bf79451e 8911static int ipw_wx_get_mode(struct net_device *dev,
0edd5b44
JG
8912 struct iw_request_info *info,
8913 union iwreq_data *wrqu, char *extra)
43f66a6c 8914{
b0a4e7d8 8915 struct ipw_priv *priv = libipw_priv(dev);
4644151b 8916 mutex_lock(&priv->mutex);
43f66a6c
JK
8917 wrqu->mode = priv->ieee->iw_mode;
8918 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
4644151b 8919 mutex_unlock(&priv->mutex);
43f66a6c
JK
8920 return 0;
8921}
8922
43f66a6c
JK
8923/* Values are in microsecond */
8924static const s32 timeout_duration[] = {
8925 350000,
8926 250000,
8927 75000,
8928 37000,
8929 25000,
8930};
8931
8932static const s32 period_duration[] = {
8933 400000,
8934 700000,
8935 1000000,
8936 1000000,
8937 1000000
8938};
8939
bf79451e
JG
8940static int ipw_wx_get_range(struct net_device *dev,
8941 struct iw_request_info *info,
43f66a6c
JK
8942 union iwreq_data *wrqu, char *extra)
8943{
b0a4e7d8 8944 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 8945 struct iw_range *range = (struct iw_range *)extra;
b0a4e7d8 8946 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
b095c381 8947 int i = 0, j;
43f66a6c
JK
8948
8949 wrqu->data.length = sizeof(*range);
8950 memset(range, 0, sizeof(*range));
8951
8952 /* 54Mbs == ~27 Mb/s real (802.11g) */
bf79451e 8953 range->throughput = 27 * 1000 * 1000;
43f66a6c
JK
8954
8955 range->max_qual.qual = 100;
8956 /* TODO: Find real max RSSI and stick here */
8957 range->max_qual.level = 0;
b191608a 8958 range->max_qual.noise = 0;
0edd5b44 8959 range->max_qual.updated = 7; /* Updated all three */
43f66a6c
JK
8960
8961 range->avg_qual.qual = 70;
af901ca1 8962 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
0edd5b44 8963 range->avg_qual.level = 0; /* FIXME to real average level */
43f66a6c 8964 range->avg_qual.noise = 0;
0edd5b44 8965 range->avg_qual.updated = 7; /* Updated all three */
4644151b 8966 mutex_lock(&priv->mutex);
0edd5b44 8967 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
43f66a6c 8968
bf79451e
JG
8969 for (i = 0; i < range->num_bitrates; i++)
8970 range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) *
0edd5b44 8971 500000;
bf79451e 8972
43f66a6c
JK
8973 range->max_rts = DEFAULT_RTS_THRESHOLD;
8974 range->min_frag = MIN_FRAG_THRESHOLD;
8975 range->max_frag = MAX_FRAG_THRESHOLD;
8976
8977 range->encoding_size[0] = 5;
bf79451e 8978 range->encoding_size[1] = 13;
43f66a6c
JK
8979 range->num_encoding_sizes = 2;
8980 range->max_encoding_tokens = WEP_KEYS;
8981
8982 /* Set the Wireless Extension versions */
8983 range->we_version_compiled = WIRELESS_EXT;
f1b50863 8984 range->we_version_source = 18;
43f66a6c 8985
b095c381
JK
8986 i = 0;
8987 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
e815de42
ZY
8988 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {
8989 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
b0a4e7d8 8990 (geo->bg[j].flags & LIBIPW_CH_PASSIVE_ONLY))
e815de42
ZY
8991 continue;
8992
b095c381
JK
8993 range->freq[i].i = geo->bg[j].channel;
8994 range->freq[i].m = geo->bg[j].freq * 100000;
8995 range->freq[i].e = 1;
e815de42 8996 i++;
b095c381
JK
8997 }
8998 }
43f66a6c 8999
b095c381 9000 if (priv->ieee->mode & IEEE_A) {
e815de42
ZY
9001 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {
9002 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
b0a4e7d8 9003 (geo->a[j].flags & LIBIPW_CH_PASSIVE_ONLY))
e815de42
ZY
9004 continue;
9005
b095c381
JK
9006 range->freq[i].i = geo->a[j].channel;
9007 range->freq[i].m = geo->a[j].freq * 100000;
9008 range->freq[i].e = 1;
e815de42 9009 i++;
b095c381 9010 }
43f66a6c 9011 }
b095c381
JK
9012
9013 range->num_channels = i;
9014 range->num_frequency = i;
9015
4644151b 9016 mutex_unlock(&priv->mutex);
97a78ca9
BB
9017
9018 /* Event capability (kernel + driver) */
9019 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
9020 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
07f02e46
ZY
9021 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
9022 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
97a78ca9 9023 range->event_capa[1] = IW_EVENT_CAPA_K_1;
43f66a6c 9024
f1b50863
DW
9025 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
9026 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
9027
374fdfbc
DW
9028 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
9029
43f66a6c
JK
9030 IPW_DEBUG_WX("GET Range\n");
9031 return 0;
9032}
9033
bf79451e
JG
9034static int ipw_wx_set_wap(struct net_device *dev,
9035 struct iw_request_info *info,
43f66a6c
JK
9036 union iwreq_data *wrqu, char *extra)
9037{
b0a4e7d8 9038 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 9039
bf79451e 9040 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
43f66a6c 9041 return -EINVAL;
4644151b 9042 mutex_lock(&priv->mutex);
7949d20c
WY
9043 if (is_broadcast_ether_addr(wrqu->ap_addr.sa_data) ||
9044 is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
43f66a6c
JK
9045 /* we disable mandatory BSSID association */
9046 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
9047 priv->config &= ~CFG_STATIC_BSSID;
c848d0af
JK
9048 IPW_DEBUG_ASSOC("Attempting to associate with new "
9049 "parameters.\n");
9050 ipw_associate(priv);
4644151b 9051 mutex_unlock(&priv->mutex);
43f66a6c
JK
9052 return 0;
9053 }
9054
9055 priv->config |= CFG_STATIC_BSSID;
9056 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
9057 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
4644151b 9058 mutex_unlock(&priv->mutex);
43f66a6c
JK
9059 return 0;
9060 }
9061
e174961c
JB
9062 IPW_DEBUG_WX("Setting mandatory BSSID to %pM\n",
9063 wrqu->ap_addr.sa_data);
43f66a6c
JK
9064
9065 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
9066
c848d0af
JK
9067 /* Network configuration changed -- force [re]association */
9068 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
9069 if (!ipw_disassociate(priv))
43f66a6c 9070 ipw_associate(priv);
43f66a6c 9071
4644151b 9072 mutex_unlock(&priv->mutex);
43f66a6c
JK
9073 return 0;
9074}
9075
bf79451e
JG
9076static int ipw_wx_get_wap(struct net_device *dev,
9077 struct iw_request_info *info,
43f66a6c
JK
9078 union iwreq_data *wrqu, char *extra)
9079{
b0a4e7d8 9080 struct ipw_priv *priv = libipw_priv(dev);
0795af57 9081
43f66a6c
JK
9082 /* If we are associated, trying to associate, or have a statically
9083 * configured BSSID then return that; otherwise return ANY */
4644151b 9084 mutex_lock(&priv->mutex);
bf79451e 9085 if (priv->config & CFG_STATIC_BSSID ||
43f66a6c
JK
9086 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
9087 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
afbf30a2 9088 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
43f66a6c
JK
9089 } else
9090 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
9091
e174961c
JB
9092 IPW_DEBUG_WX("Getting WAP BSSID: %pM\n",
9093 wrqu->ap_addr.sa_data);
4644151b 9094 mutex_unlock(&priv->mutex);
43f66a6c
JK
9095 return 0;
9096}
9097
bf79451e
JG
9098static int ipw_wx_set_essid(struct net_device *dev,
9099 struct iw_request_info *info,
43f66a6c
JK
9100 union iwreq_data *wrqu, char *extra)
9101{
b0a4e7d8 9102 struct ipw_priv *priv = libipw_priv(dev);
ab644b0b 9103 int length;
9387b7ca 9104 DECLARE_SSID_BUF(ssid);
ab644b0b
ZY
9105
9106 mutex_lock(&priv->mutex);
43f66a6c 9107
ab644b0b
ZY
9108 if (!wrqu->essid.flags)
9109 {
9110 IPW_DEBUG_WX("Setting ESSID to ANY\n");
9111 ipw_disassociate(priv);
9112 priv->config &= ~CFG_STATIC_ESSID;
9113 ipw_associate(priv);
9114 mutex_unlock(&priv->mutex);
9115 return 0;
9116 }
43f66a6c 9117
a9f0d423 9118 length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
43f66a6c
JK
9119
9120 priv->config |= CFG_STATIC_ESSID;
9121
a9f0d423
ZY
9122 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)
9123 && (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
43f66a6c 9124 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
4644151b 9125 mutex_unlock(&priv->mutex);
43f66a6c
JK
9126 return 0;
9127 }
9128
9387b7ca
JL
9129 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n",
9130 print_ssid(ssid, extra, length), length);
43f66a6c
JK
9131
9132 priv->essid_len = length;
a9f0d423 9133 memcpy(priv->essid, extra, priv->essid_len);
bf79451e 9134
c848d0af
JK
9135 /* Network configuration changed -- force [re]association */
9136 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
9137 if (!ipw_disassociate(priv))
43f66a6c 9138 ipw_associate(priv);
43f66a6c 9139
4644151b 9140 mutex_unlock(&priv->mutex);
43f66a6c
JK
9141 return 0;
9142}
9143
bf79451e
JG
9144static int ipw_wx_get_essid(struct net_device *dev,
9145 struct iw_request_info *info,
43f66a6c
JK
9146 union iwreq_data *wrqu, char *extra)
9147{
b0a4e7d8 9148 struct ipw_priv *priv = libipw_priv(dev);
9387b7ca 9149 DECLARE_SSID_BUF(ssid);
43f66a6c
JK
9150
9151 /* If we are associated, trying to associate, or have a statically
9152 * configured ESSID then return that; otherwise return ANY */
4644151b 9153 mutex_lock(&priv->mutex);
43f66a6c 9154 if (priv->config & CFG_STATIC_ESSID ||
bf79451e
JG
9155 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
9156 IPW_DEBUG_WX("Getting essid: '%s'\n",
9387b7ca 9157 print_ssid(ssid, priv->essid, priv->essid_len));
bf79451e 9158 memcpy(extra, priv->essid, priv->essid_len);
43f66a6c 9159 wrqu->essid.length = priv->essid_len;
0edd5b44 9160 wrqu->essid.flags = 1; /* active */
43f66a6c
JK
9161 } else {
9162 IPW_DEBUG_WX("Getting essid: ANY\n");
9163 wrqu->essid.length = 0;
0edd5b44 9164 wrqu->essid.flags = 0; /* active */
43f66a6c 9165 }
4644151b 9166 mutex_unlock(&priv->mutex);
43f66a6c
JK
9167 return 0;
9168}
9169
bf79451e
JG
9170static int ipw_wx_set_nick(struct net_device *dev,
9171 struct iw_request_info *info,
43f66a6c 9172 union iwreq_data *wrqu, char *extra)
bf79451e 9173{
b0a4e7d8 9174 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
9175
9176 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
9177 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
9178 return -E2BIG;
4644151b 9179 mutex_lock(&priv->mutex);
0edd5b44 9180 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
43f66a6c 9181 memset(priv->nick, 0, sizeof(priv->nick));
0edd5b44 9182 memcpy(priv->nick, extra, wrqu->data.length);
43f66a6c 9183 IPW_DEBUG_TRACE("<<\n");
4644151b 9184 mutex_unlock(&priv->mutex);
43f66a6c
JK
9185 return 0;
9186
9187}
9188
bf79451e
JG
9189static int ipw_wx_get_nick(struct net_device *dev,
9190 struct iw_request_info *info,
43f66a6c 9191 union iwreq_data *wrqu, char *extra)
bf79451e 9192{
b0a4e7d8 9193 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 9194 IPW_DEBUG_WX("Getting nick\n");
4644151b 9195 mutex_lock(&priv->mutex);
919ee6dd 9196 wrqu->data.length = strlen(priv->nick);
43f66a6c 9197 memcpy(extra, priv->nick, wrqu->data.length);
0edd5b44 9198 wrqu->data.flags = 1; /* active */
4644151b 9199 mutex_unlock(&priv->mutex);
43f66a6c
JK
9200 return 0;
9201}
9202
651be26f
OH
9203static int ipw_wx_set_sens(struct net_device *dev,
9204 struct iw_request_info *info,
9205 union iwreq_data *wrqu, char *extra)
9206{
b0a4e7d8 9207 struct ipw_priv *priv = libipw_priv(dev);
651be26f
OH
9208 int err = 0;
9209
9210 IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value);
9211 IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value);
9212 mutex_lock(&priv->mutex);
9213
9214 if (wrqu->sens.fixed == 0)
9215 {
9216 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
9217 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
9218 goto out;
9219 }
9220 if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) ||
9221 (wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) {
9222 err = -EINVAL;
9223 goto out;
9224 }
9225
9226 priv->roaming_threshold = wrqu->sens.value;
9227 priv->disassociate_threshold = 3*wrqu->sens.value;
9228 out:
9229 mutex_unlock(&priv->mutex);
9230 return err;
9231}
9232
9233static int ipw_wx_get_sens(struct net_device *dev,
9234 struct iw_request_info *info,
9235 union iwreq_data *wrqu, char *extra)
9236{
b0a4e7d8 9237 struct ipw_priv *priv = libipw_priv(dev);
651be26f
OH
9238 mutex_lock(&priv->mutex);
9239 wrqu->sens.fixed = 1;
9240 wrqu->sens.value = priv->roaming_threshold;
9241 mutex_unlock(&priv->mutex);
9242
9fd1ea42 9243 IPW_DEBUG_WX("GET roaming threshold -> %s %d\n",
651be26f
OH
9244 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
9245
9246 return 0;
9247}
9248
43f66a6c
JK
9249static int ipw_wx_set_rate(struct net_device *dev,
9250 struct iw_request_info *info,
9251 union iwreq_data *wrqu, char *extra)
bf79451e 9252{
ea2b26e0 9253 /* TODO: We should use semaphores or locks for access to priv */
b0a4e7d8 9254 struct ipw_priv *priv = libipw_priv(dev);
ea2b26e0
JK
9255 u32 target_rate = wrqu->bitrate.value;
9256 u32 fixed, mask;
9257
9258 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
9259 /* value = X, fixed = 1 means only rate X */
9260 /* value = X, fixed = 0 means all rates lower equal X */
9261
9262 if (target_rate == -1) {
9263 fixed = 0;
b0a4e7d8 9264 mask = LIBIPW_DEFAULT_RATES_MASK;
ea2b26e0
JK
9265 /* Now we should reassociate */
9266 goto apply;
9267 }
9268
9269 mask = 0;
9270 fixed = wrqu->bitrate.fixed;
9271
9272 if (target_rate == 1000000 || !fixed)
b0a4e7d8 9273 mask |= LIBIPW_CCK_RATE_1MB_MASK;
ea2b26e0
JK
9274 if (target_rate == 1000000)
9275 goto apply;
9276
9277 if (target_rate == 2000000 || !fixed)
b0a4e7d8 9278 mask |= LIBIPW_CCK_RATE_2MB_MASK;
ea2b26e0
JK
9279 if (target_rate == 2000000)
9280 goto apply;
9281
9282 if (target_rate == 5500000 || !fixed)
b0a4e7d8 9283 mask |= LIBIPW_CCK_RATE_5MB_MASK;
ea2b26e0
JK
9284 if (target_rate == 5500000)
9285 goto apply;
9286
9287 if (target_rate == 6000000 || !fixed)
b0a4e7d8 9288 mask |= LIBIPW_OFDM_RATE_6MB_MASK;
ea2b26e0
JK
9289 if (target_rate == 6000000)
9290 goto apply;
9291
9292 if (target_rate == 9000000 || !fixed)
b0a4e7d8 9293 mask |= LIBIPW_OFDM_RATE_9MB_MASK;
ea2b26e0
JK
9294 if (target_rate == 9000000)
9295 goto apply;
9296
9297 if (target_rate == 11000000 || !fixed)
b0a4e7d8 9298 mask |= LIBIPW_CCK_RATE_11MB_MASK;
ea2b26e0
JK
9299 if (target_rate == 11000000)
9300 goto apply;
9301
9302 if (target_rate == 12000000 || !fixed)
b0a4e7d8 9303 mask |= LIBIPW_OFDM_RATE_12MB_MASK;
ea2b26e0
JK
9304 if (target_rate == 12000000)
9305 goto apply;
9306
9307 if (target_rate == 18000000 || !fixed)
b0a4e7d8 9308 mask |= LIBIPW_OFDM_RATE_18MB_MASK;
ea2b26e0
JK
9309 if (target_rate == 18000000)
9310 goto apply;
9311
9312 if (target_rate == 24000000 || !fixed)
b0a4e7d8 9313 mask |= LIBIPW_OFDM_RATE_24MB_MASK;
ea2b26e0
JK
9314 if (target_rate == 24000000)
9315 goto apply;
9316
9317 if (target_rate == 36000000 || !fixed)
b0a4e7d8 9318 mask |= LIBIPW_OFDM_RATE_36MB_MASK;
ea2b26e0
JK
9319 if (target_rate == 36000000)
9320 goto apply;
9321
9322 if (target_rate == 48000000 || !fixed)
b0a4e7d8 9323 mask |= LIBIPW_OFDM_RATE_48MB_MASK;
ea2b26e0
JK
9324 if (target_rate == 48000000)
9325 goto apply;
9326
9327 if (target_rate == 54000000 || !fixed)
b0a4e7d8 9328 mask |= LIBIPW_OFDM_RATE_54MB_MASK;
ea2b26e0
JK
9329 if (target_rate == 54000000)
9330 goto apply;
9331
9332 IPW_DEBUG_WX("invalid rate specified, returning error\n");
9333 return -EINVAL;
9334
9335 apply:
9336 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
9337 mask, fixed ? "fixed" : "sub-rates");
4644151b 9338 mutex_lock(&priv->mutex);
b0a4e7d8 9339 if (mask == LIBIPW_DEFAULT_RATES_MASK) {
ea2b26e0 9340 priv->config &= ~CFG_FIXED_RATE;
b095c381
JK
9341 ipw_set_fixed_rate(priv, priv->ieee->mode);
9342 } else
ea2b26e0
JK
9343 priv->config |= CFG_FIXED_RATE;
9344
c848d0af
JK
9345 if (priv->rates_mask == mask) {
9346 IPW_DEBUG_WX("Mask set to current mask.\n");
4644151b 9347 mutex_unlock(&priv->mutex);
c848d0af 9348 return 0;
ea2b26e0
JK
9349 }
9350
c848d0af
JK
9351 priv->rates_mask = mask;
9352
9353 /* Network configuration changed -- force [re]association */
9354 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
9355 if (!ipw_disassociate(priv))
9356 ipw_associate(priv);
9357
4644151b 9358 mutex_unlock(&priv->mutex);
ea2b26e0 9359 return 0;
43f66a6c
JK
9360}
9361
bf79451e
JG
9362static int ipw_wx_get_rate(struct net_device *dev,
9363 struct iw_request_info *info,
43f66a6c 9364 union iwreq_data *wrqu, char *extra)
bf79451e 9365{
b0a4e7d8 9366 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9367 mutex_lock(&priv->mutex);
43f66a6c 9368 wrqu->bitrate.value = priv->last_rate;
455936c7 9369 wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;
4644151b 9370 mutex_unlock(&priv->mutex);
9fd1ea42 9371 IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
43f66a6c
JK
9372 return 0;
9373}
9374
bf79451e
JG
9375static int ipw_wx_set_rts(struct net_device *dev,
9376 struct iw_request_info *info,
43f66a6c 9377 union iwreq_data *wrqu, char *extra)
bf79451e 9378{
b0a4e7d8 9379 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9380 mutex_lock(&priv->mutex);
ea8862dc 9381 if (wrqu->rts.disabled || !wrqu->rts.fixed)
43f66a6c
JK
9382 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
9383 else {
9384 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
c848d0af 9385 wrqu->rts.value > MAX_RTS_THRESHOLD) {
4644151b 9386 mutex_unlock(&priv->mutex);
43f66a6c 9387 return -EINVAL;
c848d0af 9388 }
43f66a6c
JK
9389 priv->rts_threshold = wrqu->rts.value;
9390 }
9391
9392 ipw_send_rts_threshold(priv, priv->rts_threshold);
4644151b 9393 mutex_unlock(&priv->mutex);
9fd1ea42 9394 IPW_DEBUG_WX("SET RTS Threshold -> %d\n", priv->rts_threshold);
43f66a6c
JK
9395 return 0;
9396}
9397
bf79451e
JG
9398static int ipw_wx_get_rts(struct net_device *dev,
9399 struct iw_request_info *info,
43f66a6c 9400 union iwreq_data *wrqu, char *extra)
bf79451e 9401{
b0a4e7d8 9402 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9403 mutex_lock(&priv->mutex);
43f66a6c
JK
9404 wrqu->rts.value = priv->rts_threshold;
9405 wrqu->rts.fixed = 0; /* no auto select */
0edd5b44 9406 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
4644151b 9407 mutex_unlock(&priv->mutex);
9fd1ea42 9408 IPW_DEBUG_WX("GET RTS Threshold -> %d\n", wrqu->rts.value);
43f66a6c
JK
9409 return 0;
9410}
9411
bf79451e
JG
9412static int ipw_wx_set_txpow(struct net_device *dev,
9413 struct iw_request_info *info,
43f66a6c 9414 union iwreq_data *wrqu, char *extra)
bf79451e 9415{
b0a4e7d8 9416 struct ipw_priv *priv = libipw_priv(dev);
6de9f7f2 9417 int err = 0;
43f66a6c 9418
4644151b 9419 mutex_lock(&priv->mutex);
c848d0af 9420 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
6de9f7f2
ZY
9421 err = -EINPROGRESS;
9422 goto out;
43f66a6c 9423 }
43f66a6c 9424
b095c381
JK
9425 if (!wrqu->power.fixed)
9426 wrqu->power.value = IPW_TX_POWER_DEFAULT;
9427
c848d0af 9428 if (wrqu->power.flags != IW_TXPOW_DBM) {
6de9f7f2
ZY
9429 err = -EINVAL;
9430 goto out;
c848d0af 9431 }
43f66a6c 9432
b095c381 9433 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
afbf30a2 9434 (wrqu->power.value < IPW_TX_POWER_MIN)) {
6de9f7f2
ZY
9435 err = -EINVAL;
9436 goto out;
c848d0af 9437 }
43f66a6c 9438
43f66a6c 9439 priv->tx_power = wrqu->power.value;
6de9f7f2
ZY
9440 err = ipw_set_tx_power(priv);
9441 out:
4644151b 9442 mutex_unlock(&priv->mutex);
6de9f7f2 9443 return err;
43f66a6c
JK
9444}
9445
bf79451e
JG
9446static int ipw_wx_get_txpow(struct net_device *dev,
9447 struct iw_request_info *info,
43f66a6c 9448 union iwreq_data *wrqu, char *extra)
bf79451e 9449{
b0a4e7d8 9450 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9451 mutex_lock(&priv->mutex);
43f66a6c
JK
9452 wrqu->power.value = priv->tx_power;
9453 wrqu->power.fixed = 1;
9454 wrqu->power.flags = IW_TXPOW_DBM;
9455 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
4644151b 9456 mutex_unlock(&priv->mutex);
43f66a6c 9457
9fd1ea42 9458 IPW_DEBUG_WX("GET TX Power -> %s %d\n",
22501c8e 9459 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
43f66a6c
JK
9460
9461 return 0;
9462}
9463
bf79451e 9464static int ipw_wx_set_frag(struct net_device *dev,
0edd5b44
JG
9465 struct iw_request_info *info,
9466 union iwreq_data *wrqu, char *extra)
43f66a6c 9467{
b0a4e7d8 9468 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9469 mutex_lock(&priv->mutex);
ea8862dc 9470 if (wrqu->frag.disabled || !wrqu->frag.fixed)
43f66a6c
JK
9471 priv->ieee->fts = DEFAULT_FTS;
9472 else {
9473 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
b095c381 9474 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
4644151b 9475 mutex_unlock(&priv->mutex);
43f66a6c 9476 return -EINVAL;
b095c381 9477 }
bf79451e 9478
43f66a6c
JK
9479 priv->ieee->fts = wrqu->frag.value & ~0x1;
9480 }
9481
9482 ipw_send_frag_threshold(priv, wrqu->frag.value);
4644151b 9483 mutex_unlock(&priv->mutex);
9fd1ea42 9484 IPW_DEBUG_WX("SET Frag Threshold -> %d\n", wrqu->frag.value);
43f66a6c
JK
9485 return 0;
9486}
9487
bf79451e 9488static int ipw_wx_get_frag(struct net_device *dev,
0edd5b44
JG
9489 struct iw_request_info *info,
9490 union iwreq_data *wrqu, char *extra)
43f66a6c 9491{
b0a4e7d8 9492 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9493 mutex_lock(&priv->mutex);
43f66a6c
JK
9494 wrqu->frag.value = priv->ieee->fts;
9495 wrqu->frag.fixed = 0; /* no auto select */
0edd5b44 9496 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
4644151b 9497 mutex_unlock(&priv->mutex);
9fd1ea42 9498 IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
43f66a6c
JK
9499
9500 return 0;
9501}
9502
bf79451e
JG
9503static int ipw_wx_set_retry(struct net_device *dev,
9504 struct iw_request_info *info,
43f66a6c 9505 union iwreq_data *wrqu, char *extra)
bf79451e 9506{
b0a4e7d8 9507 struct ipw_priv *priv = libipw_priv(dev);
afbf30a2
JK
9508
9509 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
9510 return -EINVAL;
9511
9512 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
9513 return 0;
9514
d5f7ac20 9515 if (wrqu->retry.value < 0 || wrqu->retry.value >= 255)
afbf30a2
JK
9516 return -EINVAL;
9517
4644151b 9518 mutex_lock(&priv->mutex);
919ee6dd 9519 if (wrqu->retry.flags & IW_RETRY_SHORT)
afbf30a2 9520 priv->short_retry_limit = (u8) wrqu->retry.value;
919ee6dd 9521 else if (wrqu->retry.flags & IW_RETRY_LONG)
afbf30a2
JK
9522 priv->long_retry_limit = (u8) wrqu->retry.value;
9523 else {
9524 priv->short_retry_limit = (u8) wrqu->retry.value;
9525 priv->long_retry_limit = (u8) wrqu->retry.value;
9526 }
9527
9528 ipw_send_retry_limit(priv, priv->short_retry_limit,
9529 priv->long_retry_limit);
4644151b 9530 mutex_unlock(&priv->mutex);
afbf30a2
JK
9531 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
9532 priv->short_retry_limit, priv->long_retry_limit);
9533 return 0;
43f66a6c
JK
9534}
9535
bf79451e
JG
9536static int ipw_wx_get_retry(struct net_device *dev,
9537 struct iw_request_info *info,
43f66a6c 9538 union iwreq_data *wrqu, char *extra)
bf79451e 9539{
b0a4e7d8 9540 struct ipw_priv *priv = libipw_priv(dev);
afbf30a2 9541
4644151b 9542 mutex_lock(&priv->mutex);
afbf30a2
JK
9543 wrqu->retry.disabled = 0;
9544
9545 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
4644151b 9546 mutex_unlock(&priv->mutex);
afbf30a2
JK
9547 return -EINVAL;
9548 }
9549
919ee6dd
JT
9550 if (wrqu->retry.flags & IW_RETRY_LONG) {
9551 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
afbf30a2 9552 wrqu->retry.value = priv->long_retry_limit;
919ee6dd
JT
9553 } else if (wrqu->retry.flags & IW_RETRY_SHORT) {
9554 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
afbf30a2
JK
9555 wrqu->retry.value = priv->short_retry_limit;
9556 } else {
9557 wrqu->retry.flags = IW_RETRY_LIMIT;
9558 wrqu->retry.value = priv->short_retry_limit;
9559 }
4644151b 9560 mutex_unlock(&priv->mutex);
afbf30a2 9561
9fd1ea42 9562 IPW_DEBUG_WX("GET retry -> %d\n", wrqu->retry.value);
afbf30a2
JK
9563
9564 return 0;
9565}
9566
bf79451e
JG
9567static int ipw_wx_set_scan(struct net_device *dev,
9568 struct iw_request_info *info,
43f66a6c
JK
9569 union iwreq_data *wrqu, char *extra)
9570{
b0a4e7d8 9571 struct ipw_priv *priv = libipw_priv(dev);
094c4d2d 9572 struct iw_scan_req *req = (struct iw_scan_req *)extra;
ea177305 9573 struct delayed_work *work = NULL;
094c4d2d 9574
0b531676 9575 mutex_lock(&priv->mutex);
ea177305 9576
0b531676 9577 priv->user_requested_scan = 1;
0b531676 9578
094c4d2d 9579 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
afbf30a2 9580 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
ea177305
DW
9581 int len = min((int)req->essid_len,
9582 (int)sizeof(priv->direct_scan_ssid));
9583 memcpy(priv->direct_scan_ssid, req->essid, len);
9584 priv->direct_scan_ssid_len = len;
9585 work = &priv->request_direct_scan;
9586 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
9587 work = &priv->request_passive_scan;
094c4d2d 9588 }
ea177305
DW
9589 } else {
9590 /* Normal active broadcast scan */
9591 work = &priv->request_scan;
afbf30a2 9592 }
8935f39e 9593
ea177305
DW
9594 mutex_unlock(&priv->mutex);
9595
43f66a6c 9596 IPW_DEBUG_WX("Start scan\n");
b095c381 9597
bcb6d916 9598 schedule_delayed_work(work, 0);
b095c381 9599
43f66a6c
JK
9600 return 0;
9601}
9602
bf79451e
JG
9603static int ipw_wx_get_scan(struct net_device *dev,
9604 struct iw_request_info *info,
43f66a6c 9605 union iwreq_data *wrqu, char *extra)
bf79451e 9606{
b0a4e7d8
JL
9607 struct ipw_priv *priv = libipw_priv(dev);
9608 return libipw_wx_get_scan(priv->ieee, info, wrqu, extra);
43f66a6c
JK
9609}
9610
bf79451e 9611static int ipw_wx_set_encode(struct net_device *dev,
0edd5b44
JG
9612 struct iw_request_info *info,
9613 union iwreq_data *wrqu, char *key)
43f66a6c 9614{
b0a4e7d8 9615 struct ipw_priv *priv = libipw_priv(dev);
afbf30a2 9616 int ret;
caeff81b 9617 u32 cap = priv->capability;
afbf30a2 9618
4644151b 9619 mutex_lock(&priv->mutex);
b0a4e7d8 9620 ret = libipw_wx_set_encode(priv->ieee, info, wrqu, key);
afbf30a2 9621
caeff81b
HL
9622 /* In IBSS mode, we need to notify the firmware to update
9623 * the beacon info after we changed the capability. */
9624 if (cap != priv->capability &&
9625 priv->ieee->iw_mode == IW_MODE_ADHOC &&
9626 priv->status & STATUS_ASSOCIATED)
9627 ipw_disassociate(priv);
9628
4644151b 9629 mutex_unlock(&priv->mutex);
afbf30a2 9630 return ret;
43f66a6c
JK
9631}
9632
bf79451e 9633static int ipw_wx_get_encode(struct net_device *dev,
0edd5b44
JG
9634 struct iw_request_info *info,
9635 union iwreq_data *wrqu, char *key)
43f66a6c 9636{
b0a4e7d8
JL
9637 struct ipw_priv *priv = libipw_priv(dev);
9638 return libipw_wx_get_encode(priv->ieee, info, wrqu, key);
43f66a6c
JK
9639}
9640
bf79451e 9641static int ipw_wx_set_power(struct net_device *dev,
0edd5b44
JG
9642 struct iw_request_info *info,
9643 union iwreq_data *wrqu, char *extra)
43f66a6c 9644{
b0a4e7d8 9645 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 9646 int err;
4644151b 9647 mutex_lock(&priv->mutex);
43f66a6c
JK
9648 if (wrqu->power.disabled) {
9649 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
9650 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
9651 if (err) {
9652 IPW_DEBUG_WX("failed setting power mode.\n");
4644151b 9653 mutex_unlock(&priv->mutex);
43f66a6c
JK
9654 return err;
9655 }
43f66a6c 9656 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
4644151b 9657 mutex_unlock(&priv->mutex);
43f66a6c 9658 return 0;
bf79451e 9659 }
43f66a6c
JK
9660
9661 switch (wrqu->power.flags & IW_POWER_MODE) {
0edd5b44
JG
9662 case IW_POWER_ON: /* If not specified */
9663 case IW_POWER_MODE: /* If set all mask */
c03983ac 9664 case IW_POWER_ALL_R: /* If explicitly state all */
43f66a6c 9665 break;
0edd5b44 9666 default: /* Otherwise we don't support it */
43f66a6c
JK
9667 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
9668 wrqu->power.flags);
4644151b 9669 mutex_unlock(&priv->mutex);
bf79451e 9670 return -EOPNOTSUPP;
43f66a6c 9671 }
bf79451e 9672
43f66a6c
JK
9673 /* If the user hasn't specified a power management mode yet, default
9674 * to BATTERY */
0edd5b44 9675 if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)
43f66a6c 9676 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
bf79451e 9677 else
43f66a6c 9678 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
4e157f08 9679
43f66a6c
JK
9680 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
9681 if (err) {
9682 IPW_DEBUG_WX("failed setting power mode.\n");
4644151b 9683 mutex_unlock(&priv->mutex);
43f66a6c
JK
9684 return err;
9685 }
9686
0edd5b44 9687 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
4644151b 9688 mutex_unlock(&priv->mutex);
43f66a6c
JK
9689 return 0;
9690}
9691
bf79451e 9692static int ipw_wx_get_power(struct net_device *dev,
0edd5b44
JG
9693 struct iw_request_info *info,
9694 union iwreq_data *wrqu, char *extra)
43f66a6c 9695{
b0a4e7d8 9696 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9697 mutex_lock(&priv->mutex);
a613bffd 9698 if (!(priv->power_mode & IPW_POWER_ENABLED))
43f66a6c 9699 wrqu->power.disabled = 1;
a613bffd 9700 else
43f66a6c 9701 wrqu->power.disabled = 0;
43f66a6c 9702
4644151b 9703 mutex_unlock(&priv->mutex);
43f66a6c 9704 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
bf79451e 9705
43f66a6c
JK
9706 return 0;
9707}
9708
bf79451e 9709static int ipw_wx_set_powermode(struct net_device *dev,
0edd5b44
JG
9710 struct iw_request_info *info,
9711 union iwreq_data *wrqu, char *extra)
43f66a6c 9712{
b0a4e7d8 9713 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
9714 int mode = *(int *)extra;
9715 int err;
4e157f08 9716
4644151b 9717 mutex_lock(&priv->mutex);
4e157f08 9718 if ((mode < 1) || (mode > IPW_POWER_LIMIT))
43f66a6c 9719 mode = IPW_POWER_AC;
bf79451e 9720
4e157f08 9721 if (IPW_POWER_LEVEL(priv->power_mode) != mode) {
43f66a6c 9722 err = ipw_send_power_mode(priv, mode);
43f66a6c
JK
9723 if (err) {
9724 IPW_DEBUG_WX("failed setting power mode.\n");
4644151b 9725 mutex_unlock(&priv->mutex);
43f66a6c
JK
9726 return err;
9727 }
4e157f08 9728 priv->power_mode = IPW_POWER_ENABLED | mode;
43f66a6c 9729 }
4644151b 9730 mutex_unlock(&priv->mutex);
43f66a6c
JK
9731 return 0;
9732}
9733
9734#define MAX_WX_STRING 80
bf79451e 9735static int ipw_wx_get_powermode(struct net_device *dev,
0edd5b44
JG
9736 struct iw_request_info *info,
9737 union iwreq_data *wrqu, char *extra)
43f66a6c 9738{
b0a4e7d8 9739 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
9740 int level = IPW_POWER_LEVEL(priv->power_mode);
9741 char *p = extra;
9742
9743 p += snprintf(p, MAX_WX_STRING, "Power save level: %d ", level);
9744
9745 switch (level) {
9746 case IPW_POWER_AC:
9747 p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
9748 break;
9749 case IPW_POWER_BATTERY:
9750 p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
9751 break;
9752 default:
9753 p += snprintf(p, MAX_WX_STRING - (p - extra),
bf79451e 9754 "(Timeout %dms, Period %dms)",
43f66a6c
JK
9755 timeout_duration[level - 1] / 1000,
9756 period_duration[level - 1] / 1000);
9757 }
9758
9759 if (!(priv->power_mode & IPW_POWER_ENABLED))
0edd5b44 9760 p += snprintf(p, MAX_WX_STRING - (p - extra), " OFF");
43f66a6c
JK
9761
9762 wrqu->data.length = p - extra + 1;
9763
9764 return 0;
9765}
9766
9767static int ipw_wx_set_wireless_mode(struct net_device *dev,
0edd5b44
JG
9768 struct iw_request_info *info,
9769 union iwreq_data *wrqu, char *extra)
43f66a6c 9770{
b0a4e7d8 9771 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
9772 int mode = *(int *)extra;
9773 u8 band = 0, modulation = 0;
9774
9775 if (mode == 0 || mode & ~IEEE_MODE_MASK) {
0edd5b44 9776 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
43f66a6c
JK
9777 return -EINVAL;
9778 }
4644151b 9779 mutex_lock(&priv->mutex);
43f66a6c 9780 if (priv->adapter == IPW_2915ABG) {
a33a1982 9781 priv->ieee->abg_true = 1;
43f66a6c 9782 if (mode & IEEE_A) {
b0a4e7d8
JL
9783 band |= LIBIPW_52GHZ_BAND;
9784 modulation |= LIBIPW_OFDM_MODULATION;
43f66a6c 9785 } else
a33a1982 9786 priv->ieee->abg_true = 0;
43f66a6c
JK
9787 } else {
9788 if (mode & IEEE_A) {
9789 IPW_WARNING("Attempt to set 2200BG into "
9790 "802.11a mode\n");
4644151b 9791 mutex_unlock(&priv->mutex);
43f66a6c
JK
9792 return -EINVAL;
9793 }
9794
a33a1982 9795 priv->ieee->abg_true = 0;
43f66a6c
JK
9796 }
9797
9798 if (mode & IEEE_B) {
b0a4e7d8
JL
9799 band |= LIBIPW_24GHZ_BAND;
9800 modulation |= LIBIPW_CCK_MODULATION;
43f66a6c 9801 } else
a33a1982 9802 priv->ieee->abg_true = 0;
bf79451e 9803
43f66a6c 9804 if (mode & IEEE_G) {
b0a4e7d8
JL
9805 band |= LIBIPW_24GHZ_BAND;
9806 modulation |= LIBIPW_OFDM_MODULATION;
43f66a6c 9807 } else
a33a1982 9808 priv->ieee->abg_true = 0;
43f66a6c
JK
9809
9810 priv->ieee->mode = mode;
9811 priv->ieee->freq_band = band;
9812 priv->ieee->modulation = modulation;
0edd5b44 9813 init_supported_rates(priv, &priv->rates);
43f66a6c 9814
c848d0af
JK
9815 /* Network configuration changed -- force [re]association */
9816 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
9817 if (!ipw_disassociate(priv)) {
43f66a6c 9818 ipw_send_supported_rates(priv, &priv->rates);
c848d0af
JK
9819 ipw_associate(priv);
9820 }
43f66a6c 9821
a613bffd
JK
9822 /* Update the band LEDs */
9823 ipw_led_band_on(priv);
43f66a6c 9824
bf79451e 9825 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
43f66a6c 9826 mode & IEEE_A ? 'a' : '.',
0edd5b44 9827 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
4644151b 9828 mutex_unlock(&priv->mutex);
43f66a6c
JK
9829 return 0;
9830}
9831
9832static int ipw_wx_get_wireless_mode(struct net_device *dev,
0edd5b44
JG
9833 struct iw_request_info *info,
9834 union iwreq_data *wrqu, char *extra)
43f66a6c 9835{
b0a4e7d8 9836 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9837 mutex_lock(&priv->mutex);
ea2b26e0
JK
9838 switch (priv->ieee->mode) {
9839 case IEEE_A:
43f66a6c
JK
9840 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
9841 break;
ea2b26e0
JK
9842 case IEEE_B:
9843 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
9844 break;
9845 case IEEE_A | IEEE_B:
9846 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
9847 break;
9848 case IEEE_G:
9849 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
9850 break;
9851 case IEEE_A | IEEE_G:
9852 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
9853 break;
9854 case IEEE_B | IEEE_G:
9855 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
9856 break;
9857 case IEEE_A | IEEE_B | IEEE_G:
9858 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
9859 break;
9860 default:
9861 strncpy(extra, "unknown", MAX_WX_STRING);
43f66a6c 9862 break;
bf79451e
JG
9863 }
9864
43f66a6c
JK
9865 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
9866
0edd5b44 9867 wrqu->data.length = strlen(extra) + 1;
4644151b 9868 mutex_unlock(&priv->mutex);
b095c381
JK
9869
9870 return 0;
9871}
9872
9873static int ipw_wx_set_preamble(struct net_device *dev,
9874 struct iw_request_info *info,
9875 union iwreq_data *wrqu, char *extra)
9876{
b0a4e7d8 9877 struct ipw_priv *priv = libipw_priv(dev);
b095c381 9878 int mode = *(int *)extra;
4644151b 9879 mutex_lock(&priv->mutex);
b095c381
JK
9880 /* Switching from SHORT -> LONG requires a disassociation */
9881 if (mode == 1) {
9882 if (!(priv->config & CFG_PREAMBLE_LONG)) {
9883 priv->config |= CFG_PREAMBLE_LONG;
9884
9885 /* Network configuration changed -- force [re]association */
9886 IPW_DEBUG_ASSOC
9887 ("[re]association triggered due to preamble change.\n");
9888 if (!ipw_disassociate(priv))
9889 ipw_associate(priv);
9890 }
9891 goto done;
9892 }
43f66a6c 9893
b095c381
JK
9894 if (mode == 0) {
9895 priv->config &= ~CFG_PREAMBLE_LONG;
9896 goto done;
9897 }
4644151b 9898 mutex_unlock(&priv->mutex);
b095c381
JK
9899 return -EINVAL;
9900
9901 done:
4644151b 9902 mutex_unlock(&priv->mutex);
b095c381
JK
9903 return 0;
9904}
9905
9906static int ipw_wx_get_preamble(struct net_device *dev,
9907 struct iw_request_info *info,
9908 union iwreq_data *wrqu, char *extra)
9909{
b0a4e7d8 9910 struct ipw_priv *priv = libipw_priv(dev);
4644151b 9911 mutex_lock(&priv->mutex);
b095c381
JK
9912 if (priv->config & CFG_PREAMBLE_LONG)
9913 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9914 else
9915 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
4644151b 9916 mutex_unlock(&priv->mutex);
0edd5b44 9917 return 0;
43f66a6c
JK
9918}
9919
b095c381
JK
9920#ifdef CONFIG_IPW2200_MONITOR
9921static int ipw_wx_set_monitor(struct net_device *dev,
bf79451e 9922 struct iw_request_info *info,
43f66a6c 9923 union iwreq_data *wrqu, char *extra)
bf79451e 9924{
b0a4e7d8 9925 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
9926 int *parms = (int *)extra;
9927 int enable = (parms[0] > 0);
4644151b 9928 mutex_lock(&priv->mutex);
b095c381 9929 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
43f66a6c
JK
9930 if (enable) {
9931 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
459d4087 9932#ifdef CONFIG_IPW2200_RADIOTAP
24a47dbd
MK
9933 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
9934#else
43f66a6c 9935 priv->net_dev->type = ARPHRD_IEEE80211;
24a47dbd 9936#endif
bcb6d916 9937 schedule_work(&priv->adapter_restart);
43f66a6c 9938 }
bf79451e 9939
43f66a6c
JK
9940 ipw_set_channel(priv, parms[1]);
9941 } else {
b095c381 9942 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
4644151b 9943 mutex_unlock(&priv->mutex);
43f66a6c 9944 return 0;
b095c381 9945 }
43f66a6c 9946 priv->net_dev->type = ARPHRD_ETHER;
bcb6d916 9947 schedule_work(&priv->adapter_restart);
43f66a6c 9948 }
4644151b 9949 mutex_unlock(&priv->mutex);
43f66a6c
JK
9950 return 0;
9951}
9952
67fd6b45 9953#endif /* CONFIG_IPW2200_MONITOR */
b095c381 9954
bf79451e
JG
9955static int ipw_wx_reset(struct net_device *dev,
9956 struct iw_request_info *info,
43f66a6c 9957 union iwreq_data *wrqu, char *extra)
bf79451e 9958{
b0a4e7d8 9959 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 9960 IPW_DEBUG_WX("RESET\n");
bcb6d916 9961 schedule_work(&priv->adapter_restart);
b095c381
JK
9962 return 0;
9963}
9964
b095c381
JK
9965static int ipw_wx_sw_reset(struct net_device *dev,
9966 struct iw_request_info *info,
9967 union iwreq_data *wrqu, char *extra)
ea2b26e0 9968{
b0a4e7d8 9969 struct ipw_priv *priv = libipw_priv(dev);
b095c381
JK
9970 union iwreq_data wrqu_sec = {
9971 .encoding = {
9972 .flags = IW_ENCODE_DISABLED,
9973 },
9974 };
afbf30a2 9975 int ret;
c848d0af 9976
b095c381 9977 IPW_DEBUG_WX("SW_RESET\n");
ea2b26e0 9978
4644151b 9979 mutex_lock(&priv->mutex);
ea2b26e0 9980
d6d5b5c1 9981 ret = ipw_sw_reset(priv, 2);
afbf30a2
JK
9982 if (!ret) {
9983 free_firmware();
9984 ipw_adapter_restart(priv);
9985 }
ea2b26e0 9986
b095c381
JK
9987 /* The SW reset bit might have been toggled on by the 'disable'
9988 * module parameter, so take appropriate action */
9989 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
ea2b26e0 9990
4644151b 9991 mutex_unlock(&priv->mutex);
b0a4e7d8 9992 libipw_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
4644151b 9993 mutex_lock(&priv->mutex);
bf79451e 9994
b095c381
JK
9995 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9996 /* Configuration likely changed -- force [re]association */
9997 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
9998 "reset.\n");
9999 if (!ipw_disassociate(priv))
10000 ipw_associate(priv);
43f66a6c 10001 }
b095c381 10002
4644151b 10003 mutex_unlock(&priv->mutex);
43f66a6c 10004
43f66a6c
JK
10005 return 0;
10006}
43f66a6c
JK
10007
10008/* Rebase the WE IOCTLs to zero for the handler array */
0edd5b44 10009static iw_handler ipw_wx_handlers[] = {
56b632e8
JP
10010 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
10011 IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
10012 IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
10013 IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
10014 IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),
10015 IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),
10016 IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),
10017 IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),
10018 IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),
10019 IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),
10020 IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),
10021 IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),
10022 IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),
10023 IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),
10024 IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),
10025 IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),
10026 IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),
10027 IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),
10028 IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),
10029 IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),
10030 IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),
10031 IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),
10032 IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),
10033 IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),
10034 IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),
10035 IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),
10036 IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),
10037 IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
10038 IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
10039 IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
10040 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
10041 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
10042 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
10043 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
10044 IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
10045 IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
10046 IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
10047 IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),
10048 IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),
10049 IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),
10050 IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),
43f66a6c
JK
10051};
10052
b095c381
JK
10053enum {
10054 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
10055 IPW_PRIV_GET_POWER,
10056 IPW_PRIV_SET_MODE,
10057 IPW_PRIV_GET_MODE,
10058 IPW_PRIV_SET_PREAMBLE,
10059 IPW_PRIV_GET_PREAMBLE,
10060 IPW_PRIV_RESET,
10061 IPW_PRIV_SW_RESET,
10062#ifdef CONFIG_IPW2200_MONITOR
10063 IPW_PRIV_SET_MONITOR,
10064#endif
10065};
43f66a6c 10066
bf79451e 10067static struct iw_priv_args ipw_priv_args[] = {
43f66a6c 10068 {
0edd5b44
JG
10069 .cmd = IPW_PRIV_SET_POWER,
10070 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10071 .name = "set_power"},
43f66a6c 10072 {
0edd5b44
JG
10073 .cmd = IPW_PRIV_GET_POWER,
10074 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
10075 .name = "get_power"},
43f66a6c 10076 {
0edd5b44
JG
10077 .cmd = IPW_PRIV_SET_MODE,
10078 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10079 .name = "set_mode"},
43f66a6c 10080 {
0edd5b44
JG
10081 .cmd = IPW_PRIV_GET_MODE,
10082 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
10083 .name = "get_mode"},
43f66a6c 10084 {
ea2b26e0
JK
10085 .cmd = IPW_PRIV_SET_PREAMBLE,
10086 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10087 .name = "set_preamble"},
10088 {
10089 .cmd = IPW_PRIV_GET_PREAMBLE,
10090 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
10091 .name = "get_preamble"},
43f66a6c 10092 {
0edd5b44
JG
10093 IPW_PRIV_RESET,
10094 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
b095c381
JK
10095 {
10096 IPW_PRIV_SW_RESET,
10097 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
10098#ifdef CONFIG_IPW2200_MONITOR
10099 {
10100 IPW_PRIV_SET_MONITOR,
10101 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
10102#endif /* CONFIG_IPW2200_MONITOR */
43f66a6c
JK
10103};
10104
10105static iw_handler ipw_priv_handler[] = {
10106 ipw_wx_set_powermode,
10107 ipw_wx_get_powermode,
10108 ipw_wx_set_wireless_mode,
10109 ipw_wx_get_wireless_mode,
ea2b26e0
JK
10110 ipw_wx_set_preamble,
10111 ipw_wx_get_preamble,
bf79451e 10112 ipw_wx_reset,
b095c381
JK
10113 ipw_wx_sw_reset,
10114#ifdef CONFIG_IPW2200_MONITOR
10115 ipw_wx_set_monitor,
43f66a6c
JK
10116#endif
10117};
10118
0edd5b44 10119static struct iw_handler_def ipw_wx_handler_def = {
ea2b26e0
JK
10120 .standard = ipw_wx_handlers,
10121 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
10122 .num_private = ARRAY_SIZE(ipw_priv_handler),
10123 .num_private_args = ARRAY_SIZE(ipw_priv_args),
10124 .private = ipw_priv_handler,
10125 .private_args = ipw_priv_args,
97a78ca9 10126 .get_wireless_stats = ipw_get_wireless_stats,
43f66a6c
JK
10127};
10128
43f66a6c
JK
10129/*
10130 * Get wireless statistics.
10131 * Called by /proc/net/wireless
10132 * Also called by SIOCGIWSTATS
10133 */
0edd5b44 10134static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
43f66a6c 10135{
b0a4e7d8 10136 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 10137 struct iw_statistics *wstats;
bf79451e 10138
43f66a6c
JK
10139 wstats = &priv->wstats;
10140
ea2b26e0 10141 /* if hw is disabled, then ipw_get_ordinal() can't be called.
afbf30a2 10142 * netdev->get_wireless_stats seems to be called before fw is
43f66a6c
JK
10143 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
10144 * and associated; if not associcated, the values are all meaningless
10145 * anyway, so set them all to NULL and INVALID */
10146 if (!(priv->status & STATUS_ASSOCIATED)) {
10147 wstats->miss.beacon = 0;
10148 wstats->discard.retries = 0;
10149 wstats->qual.qual = 0;
10150 wstats->qual.level = 0;
10151 wstats->qual.noise = 0;
10152 wstats->qual.updated = 7;
10153 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
0edd5b44 10154 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
43f66a6c 10155 return wstats;
bf79451e 10156 }
43f66a6c
JK
10157
10158 wstats->qual.qual = priv->quality;
00d21de5
ZY
10159 wstats->qual.level = priv->exp_avg_rssi;
10160 wstats->qual.noise = priv->exp_avg_noise;
43f66a6c 10161 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
b191608a 10162 IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
43f66a6c
JK
10163
10164 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
10165 wstats->discard.retries = priv->last_tx_failures;
10166 wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable;
bf79451e 10167
43f66a6c
JK
10168/* if (ipw_get_ordinal(priv, IPW_ORD_STAT_TX_RETRY, &tx_retry, &len))
10169 goto fail_get_ordinal;
10170 wstats->discard.retries += tx_retry; */
bf79451e 10171
43f66a6c
JK
10172 return wstats;
10173}
10174
43f66a6c
JK
10175/* net device stuff */
10176
858119e1 10177static void init_sys_config(struct ipw_sys_config *sys_config)
43f66a6c 10178{
0edd5b44 10179 memset(sys_config, 0, sizeof(struct ipw_sys_config));
810dabd4 10180 sys_config->bt_coexistence = 0;
43f66a6c
JK
10181 sys_config->answer_broadcast_ssid_probe = 0;
10182 sys_config->accept_all_data_frames = 0;
10183 sys_config->accept_non_directed_frames = 1;
10184 sys_config->exclude_unicast_unencrypted = 0;
10185 sys_config->disable_unicast_decryption = 1;
10186 sys_config->exclude_multicast_unencrypted = 0;
10187 sys_config->disable_multicast_decryption = 1;
d2b83e12
ZY
10188 if (antenna < CFG_SYS_ANTENNA_BOTH || antenna > CFG_SYS_ANTENNA_B)
10189 antenna = CFG_SYS_ANTENNA_BOTH;
10190 sys_config->antenna_diversity = antenna;
0edd5b44 10191 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */
43f66a6c 10192 sys_config->dot11g_auto_detection = 0;
bf79451e 10193 sys_config->enable_cts_to_self = 0;
43f66a6c 10194 sys_config->bt_coexist_collision_thr = 0;
67fd6b45 10195 sys_config->pass_noise_stats_to_host = 1; /* 1 -- fix for 256 */
12977154 10196 sys_config->silence_threshold = 0x1e;
43f66a6c
JK
10197}
10198
10199static int ipw_net_open(struct net_device *dev)
10200{
43f66a6c 10201 IPW_DEBUG_INFO("dev->open\n");
521c4d96 10202 netif_start_queue(dev);
43f66a6c
JK
10203 return 0;
10204}
10205
10206static int ipw_net_stop(struct net_device *dev)
10207{
10208 IPW_DEBUG_INFO("dev->close\n");
10209 netif_stop_queue(dev);
10210 return 0;
10211}
10212
10213/*
10214todo:
10215
10216modify to send one tfd per fragment instead of using chunking. otherwise
b0a4e7d8 10217we need to heavily modify the libipw_skb_to_txb.
43f66a6c
JK
10218*/
10219
b0a4e7d8 10220static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb,
227d2dc1 10221 int pri)
43f66a6c 10222{
b0a4e7d8 10223 struct libipw_hdr_3addrqos *hdr = (struct libipw_hdr_3addrqos *)
0edd5b44 10224 txb->fragments[0]->data;
43f66a6c
JK
10225 int i = 0;
10226 struct tfd_frame *tfd;
e43e3c1e 10227#ifdef CONFIG_IPW2200_QOS
b095c381
JK
10228 int tx_id = ipw_get_tx_queue_number(priv, pri);
10229 struct clx2_tx_queue *txq = &priv->txq[tx_id];
10230#else
43f66a6c 10231 struct clx2_tx_queue *txq = &priv->txq[0];
b095c381 10232#endif
43f66a6c
JK
10233 struct clx2_queue *q = &txq->q;
10234 u8 id, hdr_len, unicast;
c848d0af 10235 int fc;
43f66a6c 10236
b8ddafd7
ZY
10237 if (!(priv->status & STATUS_ASSOCIATED))
10238 goto drop;
10239
b0a4e7d8 10240 hdr_len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
43f66a6c
JK
10241 switch (priv->ieee->iw_mode) {
10242 case IW_MODE_ADHOC:
3c19065a 10243 unicast = !is_multicast_ether_addr(hdr->addr1);
43f66a6c
JK
10244 id = ipw_find_station(priv, hdr->addr1);
10245 if (id == IPW_INVALID_STATION) {
10246 id = ipw_add_station(priv, hdr->addr1);
10247 if (id == IPW_INVALID_STATION) {
10248 IPW_WARNING("Attempt to send data to "
e174961c
JB
10249 "invalid cell: %pM\n",
10250 hdr->addr1);
43f66a6c
JK
10251 goto drop;
10252 }
10253 }
10254 break;
10255
10256 case IW_MODE_INFRA:
10257 default:
3c19065a 10258 unicast = !is_multicast_ether_addr(hdr->addr3);
43f66a6c
JK
10259 id = 0;
10260 break;
10261 }
10262
10263 tfd = &txq->bd[q->first_empty];
10264 txq->txb[q->first_empty] = txb;
10265 memset(tfd, 0, sizeof(*tfd));
10266 tfd->u.data.station_number = id;
10267
10268 tfd->control_flags.message_type = TX_FRAME_TYPE;
10269 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
10270
10271 tfd->u.data.cmd_id = DINO_CMD_TX;
a613bffd 10272 tfd->u.data.len = cpu_to_le16(txb->payload_size);
bf79451e 10273
43f66a6c 10274 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
b095c381 10275 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
43f66a6c 10276 else
b095c381 10277 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
43f66a6c 10278
ea2b26e0
JK
10279 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
10280 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
43f66a6c 10281
c848d0af
JK
10282 fc = le16_to_cpu(hdr->frame_ctl);
10283 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
43f66a6c
JK
10284
10285 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
10286
b095c381
JK
10287 if (likely(unicast))
10288 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
10289
10290 if (txb->encrypted && !priv->ieee->host_encrypt) {
10291 switch (priv->ieee->sec.level) {
10292 case SEC_LEVEL_3:
10293 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
851ca268 10294 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
b095c381
JK
10295 /* XXX: ACK flag must be set for CCMP even if it
10296 * is a multicast/broadcast packet, because CCMP
10297 * group communication encrypted by GTK is
10298 * actually done by the AP. */
10299 if (!unicast)
10300 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
10301
10302 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
10303 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
10304 tfd->u.data.key_index = 0;
10305 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
10306 break;
10307 case SEC_LEVEL_2:
10308 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
851ca268 10309 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
b095c381
JK
10310 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
10311 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
10312 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
10313 break;
10314 case SEC_LEVEL_1:
10315 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
851ca268 10316 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
274bfb8d
JL
10317 tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx;
10318 if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <=
b095c381
JK
10319 40)
10320 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
10321 else
10322 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
10323 break;
10324 case SEC_LEVEL_0:
10325 break;
10326 default:
af901ca1 10327 printk(KERN_ERR "Unknown security level %d\n",
b095c381
JK
10328 priv->ieee->sec.level);
10329 break;
10330 }
10331 } else
10332 /* No hardware encryption */
10333 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
10334
e43e3c1e 10335#ifdef CONFIG_IPW2200_QOS
a5cf4fe6
ZY
10336 if (fc & IEEE80211_STYPE_QOS_DATA)
10337 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data));
e43e3c1e 10338#endif /* CONFIG_IPW2200_QOS */
b095c381 10339
43f66a6c 10340 /* payload */
a613bffd
JK
10341 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
10342 txb->nr_frags));
10343 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
10344 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
10345 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
10346 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
10347 i, le32_to_cpu(tfd->u.data.num_chunks),
10348 txb->fragments[i]->len - hdr_len);
bf79451e 10349 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
43f66a6c
JK
10350 i, tfd->u.data.num_chunks,
10351 txb->fragments[i]->len - hdr_len);
bf79451e 10352 printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len,
43f66a6c
JK
10353 txb->fragments[i]->len - hdr_len);
10354
0edd5b44 10355 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
10356 cpu_to_le32(pci_map_single
10357 (priv->pci_dev,
10358 txb->fragments[i]->data + hdr_len,
10359 txb->fragments[i]->len - hdr_len,
10360 PCI_DMA_TODEVICE));
10361 tfd->u.data.chunk_len[i] =
10362 cpu_to_le16(txb->fragments[i]->len - hdr_len);
43f66a6c
JK
10363 }
10364
10365 if (i != txb->nr_frags) {
10366 struct sk_buff *skb;
10367 u16 remaining_bytes = 0;
10368 int j;
10369
10370 for (j = i; j < txb->nr_frags; j++)
10371 remaining_bytes += txb->fragments[j]->len - hdr_len;
10372
10373 printk(KERN_INFO "Trying to reallocate for %d bytes\n",
10374 remaining_bytes);
10375 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
10376 if (skb != NULL) {
a613bffd 10377 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
43f66a6c
JK
10378 for (j = i; j < txb->nr_frags; j++) {
10379 int size = txb->fragments[j]->len - hdr_len;
afbf30a2 10380
43f66a6c 10381 printk(KERN_INFO "Adding frag %d %d...\n",
0edd5b44 10382 j, size);
43f66a6c 10383 memcpy(skb_put(skb, size),
0edd5b44 10384 txb->fragments[j]->data + hdr_len, size);
43f66a6c
JK
10385 }
10386 dev_kfree_skb_any(txb->fragments[i]);
10387 txb->fragments[i] = skb;
0edd5b44 10388 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
10389 cpu_to_le32(pci_map_single
10390 (priv->pci_dev, skb->data,
4958730e 10391 remaining_bytes,
a613bffd
JK
10392 PCI_DMA_TODEVICE));
10393
5c05863d 10394 le32_add_cpu(&tfd->u.data.num_chunks, 1);
bf79451e 10395 }
43f66a6c
JK
10396 }
10397
10398 /* kick DMA */
10399 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
10400 ipw_write32(priv, q->reg_w, q->first_empty);
10401
943dbef4 10402 if (ipw_tx_queue_space(q) < q->high_mark)
f697014a
JK
10403 netif_stop_queue(priv->net_dev);
10404
227d2dc1 10405 return NETDEV_TX_OK;
43f66a6c 10406
0edd5b44 10407 drop:
43f66a6c 10408 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
b0a4e7d8 10409 libipw_txb_free(txb);
227d2dc1
JK
10410 return NETDEV_TX_OK;
10411}
10412
10413static int ipw_net_is_queue_full(struct net_device *dev, int pri)
10414{
b0a4e7d8 10415 struct ipw_priv *priv = libipw_priv(dev);
e43e3c1e 10416#ifdef CONFIG_IPW2200_QOS
227d2dc1
JK
10417 int tx_id = ipw_get_tx_queue_number(priv, pri);
10418 struct clx2_tx_queue *txq = &priv->txq[tx_id];
10419#else
10420 struct clx2_tx_queue *txq = &priv->txq[0];
e43e3c1e 10421#endif /* CONFIG_IPW2200_QOS */
227d2dc1 10422
943dbef4 10423 if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark)
227d2dc1
JK
10424 return 1;
10425
10426 return 0;
43f66a6c
JK
10427}
10428
d685b8c2
ZY
10429#ifdef CONFIG_IPW2200_PROMISCUOUS
10430static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
b0a4e7d8 10431 struct libipw_txb *txb)
d685b8c2 10432{
b0a4e7d8 10433 struct libipw_rx_stats dummystats;
d685b8c2
ZY
10434 struct ieee80211_hdr *hdr;
10435 u8 n;
10436 u16 filter = priv->prom_priv->filter;
10437 int hdr_only = 0;
10438
10439 if (filter & IPW_PROM_NO_TX)
10440 return;
10441
10442 memset(&dummystats, 0, sizeof(dummystats));
10443
25985edc 10444 /* Filtering of fragment chains is done against the first fragment */
d685b8c2 10445 hdr = (void *)txb->fragments[0]->data;
b0a4e7d8 10446 if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {
d685b8c2
ZY
10447 if (filter & IPW_PROM_NO_MGMT)
10448 return;
10449 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
10450 hdr_only = 1;
b0a4e7d8 10451 } else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {
d685b8c2
ZY
10452 if (filter & IPW_PROM_NO_CTL)
10453 return;
10454 if (filter & IPW_PROM_CTL_HEADER_ONLY)
10455 hdr_only = 1;
b0a4e7d8 10456 } else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {
d685b8c2
ZY
10457 if (filter & IPW_PROM_NO_DATA)
10458 return;
10459 if (filter & IPW_PROM_DATA_HEADER_ONLY)
10460 hdr_only = 1;
10461 }
10462
10463 for(n=0; n<txb->nr_frags; ++n) {
10464 struct sk_buff *src = txb->fragments[n];
10465 struct sk_buff *dst;
10466 struct ieee80211_radiotap_header *rt_hdr;
10467 int len;
10468
10469 if (hdr_only) {
10470 hdr = (void *)src->data;
b0a4e7d8 10471 len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));
d685b8c2
ZY
10472 } else
10473 len = src->len;
10474
bf11315e 10475 dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC);
007e5ddd
JB
10476 if (!dst)
10477 continue;
d685b8c2
ZY
10478
10479 rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr));
10480
10481 rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
10482 rt_hdr->it_pad = 0;
10483 rt_hdr->it_present = 0; /* after all, it's just an idea */
743b84d2 10484 rt_hdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_CHANNEL);
d685b8c2 10485
e62e1ee0 10486 *(__le16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(
d685b8c2
ZY
10487 ieee80211chan2mhz(priv->channel));
10488 if (priv->channel > 14) /* 802.11a */
e62e1ee0 10489 *(__le16*)skb_put(dst, sizeof(u16)) =
d685b8c2
ZY
10490 cpu_to_le16(IEEE80211_CHAN_OFDM |
10491 IEEE80211_CHAN_5GHZ);
10492 else if (priv->ieee->mode == IEEE_B) /* 802.11b */
e62e1ee0 10493 *(__le16*)skb_put(dst, sizeof(u16)) =
d685b8c2
ZY
10494 cpu_to_le16(IEEE80211_CHAN_CCK |
10495 IEEE80211_CHAN_2GHZ);
10496 else /* 802.11g */
e62e1ee0 10497 *(__le16*)skb_put(dst, sizeof(u16)) =
d685b8c2
ZY
10498 cpu_to_le16(IEEE80211_CHAN_OFDM |
10499 IEEE80211_CHAN_2GHZ);
10500
743b84d2 10501 rt_hdr->it_len = cpu_to_le16(dst->len);
d685b8c2 10502
d626f62b 10503 skb_copy_from_linear_data(src, skb_put(dst, len), len);
d685b8c2 10504
b0a4e7d8 10505 if (!libipw_rx(priv->prom_priv->ieee, dst, &dummystats))
d685b8c2
ZY
10506 dev_kfree_skb_any(dst);
10507 }
10508}
10509#endif
10510
d0cf9c0d
SH
10511static netdev_tx_t ipw_net_hard_start_xmit(struct libipw_txb *txb,
10512 struct net_device *dev, int pri)
43f66a6c 10513{
b0a4e7d8 10514 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 10515 unsigned long flags;
d0cf9c0d 10516 netdev_tx_t ret;
43f66a6c
JK
10517
10518 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
43f66a6c
JK
10519 spin_lock_irqsave(&priv->lock, flags);
10520
d685b8c2
ZY
10521#ifdef CONFIG_IPW2200_PROMISCUOUS
10522 if (rtap_iface && netif_running(priv->prom_net_dev))
10523 ipw_handle_promiscuous_tx(priv, txb);
10524#endif
10525
227d2dc1
JK
10526 ret = ipw_tx_skb(priv, txb, pri);
10527 if (ret == NETDEV_TX_OK)
10528 __ipw_led_activity_on(priv);
43f66a6c 10529 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 10530
227d2dc1 10531 return ret;
43f66a6c
JK
10532}
10533
43f66a6c
JK
10534static void ipw_net_set_multicast_list(struct net_device *dev)
10535{
10536
10537}
10538
10539static int ipw_net_set_mac_address(struct net_device *dev, void *p)
10540{
b0a4e7d8 10541 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 10542 struct sockaddr *addr = p;
0795af57 10543
43f66a6c
JK
10544 if (!is_valid_ether_addr(addr->sa_data))
10545 return -EADDRNOTAVAIL;
4644151b 10546 mutex_lock(&priv->mutex);
43f66a6c
JK
10547 priv->config |= CFG_CUSTOM_MAC;
10548 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
e174961c
JB
10549 printk(KERN_INFO "%s: Setting MAC to %pM\n",
10550 priv->net_dev->name, priv->mac_addr);
bcb6d916 10551 schedule_work(&priv->adapter_restart);
4644151b 10552 mutex_unlock(&priv->mutex);
43f66a6c
JK
10553 return 0;
10554}
10555
bf79451e 10556static void ipw_ethtool_get_drvinfo(struct net_device *dev,
43f66a6c
JK
10557 struct ethtool_drvinfo *info)
10558{
b0a4e7d8 10559 struct ipw_priv *p = libipw_priv(dev);
43f66a6c
JK
10560 char vers[64];
10561 char date[32];
10562 u32 len;
10563
1f80c230
RJ
10564 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
10565 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
43f66a6c
JK
10566
10567 len = sizeof(vers);
10568 ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
10569 len = sizeof(date);
10570 ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len);
10571
0edd5b44 10572 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
43f66a6c 10573 vers, date);
1f80c230
RJ
10574 strlcpy(info->bus_info, pci_name(p->pci_dev),
10575 sizeof(info->bus_info));
b095c381 10576 info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
43f66a6c
JK
10577}
10578
10579static u32 ipw_ethtool_get_link(struct net_device *dev)
10580{
b0a4e7d8 10581 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c
JK
10582 return (priv->status & STATUS_ASSOCIATED) != 0;
10583}
10584
10585static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
10586{
b095c381 10587 return IPW_EEPROM_IMAGE_SIZE;
43f66a6c
JK
10588}
10589
10590static int ipw_ethtool_get_eeprom(struct net_device *dev,
0edd5b44 10591 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c 10592{
b0a4e7d8 10593 struct ipw_priv *p = libipw_priv(dev);
43f66a6c 10594
b095c381 10595 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
43f66a6c 10596 return -EINVAL;
4644151b 10597 mutex_lock(&p->mutex);
afbf30a2 10598 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
4644151b 10599 mutex_unlock(&p->mutex);
43f66a6c
JK
10600 return 0;
10601}
10602
10603static int ipw_ethtool_set_eeprom(struct net_device *dev,
0edd5b44 10604 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c 10605{
b0a4e7d8 10606 struct ipw_priv *p = libipw_priv(dev);
43f66a6c
JK
10607 int i;
10608
b095c381 10609 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
43f66a6c 10610 return -EINVAL;
4644151b 10611 mutex_lock(&p->mutex);
afbf30a2 10612 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
71e585fc
AB
10613 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
10614 ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]);
4644151b 10615 mutex_unlock(&p->mutex);
43f66a6c
JK
10616 return 0;
10617}
10618
7282d491 10619static const struct ethtool_ops ipw_ethtool_ops = {
ea2b26e0
JK
10620 .get_link = ipw_ethtool_get_link,
10621 .get_drvinfo = ipw_ethtool_get_drvinfo,
10622 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
10623 .get_eeprom = ipw_ethtool_get_eeprom,
10624 .set_eeprom = ipw_ethtool_set_eeprom,
43f66a6c
JK
10625};
10626
7d12e780 10627static irqreturn_t ipw_isr(int irq, void *data)
43f66a6c
JK
10628{
10629 struct ipw_priv *priv = data;
10630 u32 inta, inta_mask;
bf79451e 10631
43f66a6c
JK
10632 if (!priv)
10633 return IRQ_NONE;
10634
89c318ed 10635 spin_lock(&priv->irq_lock);
43f66a6c
JK
10636
10637 if (!(priv->status & STATUS_INT_ENABLED)) {
d00d0121 10638 /* IRQ is disabled */
43f66a6c
JK
10639 goto none;
10640 }
10641
b095c381
JK
10642 inta = ipw_read32(priv, IPW_INTA_RW);
10643 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
bf79451e 10644
43f66a6c
JK
10645 if (inta == 0xFFFFFFFF) {
10646 /* Hardware disappeared */
10647 IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n");
10648 goto none;
10649 }
10650
b095c381 10651 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
43f66a6c
JK
10652 /* Shared interrupt */
10653 goto none;
10654 }
10655
10656 /* tell the device to stop sending interrupts */
89c318ed 10657 __ipw_disable_interrupts(priv);
bf79451e 10658
43f66a6c 10659 /* ack current interrupts */
b095c381
JK
10660 inta &= (IPW_INTA_MASK_ALL & inta_mask);
10661 ipw_write32(priv, IPW_INTA_RW, inta);
bf79451e 10662
43f66a6c
JK
10663 /* Cache INTA value for our tasklet */
10664 priv->isr_inta = inta;
10665
10666 tasklet_schedule(&priv->irq_tasklet);
10667
89c318ed 10668 spin_unlock(&priv->irq_lock);
43f66a6c
JK
10669
10670 return IRQ_HANDLED;
0edd5b44 10671 none:
89c318ed 10672 spin_unlock(&priv->irq_lock);
43f66a6c
JK
10673 return IRQ_NONE;
10674}
10675
10676static void ipw_rf_kill(void *adapter)
10677{
10678 struct ipw_priv *priv = adapter;
10679 unsigned long flags;
bf79451e 10680
43f66a6c
JK
10681 spin_lock_irqsave(&priv->lock, flags);
10682
10683 if (rf_kill_active(priv)) {
10684 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
bcb6d916 10685 schedule_delayed_work(&priv->rf_kill, 2 * HZ);
43f66a6c
JK
10686 goto exit_unlock;
10687 }
10688
10689 /* RF Kill is now disabled, so bring the device back up */
10690
10691 if (!(priv->status & STATUS_RF_KILL_MASK)) {
10692 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
10693 "device\n");
10694
10695 /* we can not do an adapter restart while inside an irq lock */
bcb6d916 10696 schedule_work(&priv->adapter_restart);
bf79451e 10697 } else
43f66a6c
JK
10698 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
10699 "enabled\n");
10700
0edd5b44 10701 exit_unlock:
43f66a6c
JK
10702 spin_unlock_irqrestore(&priv->lock, flags);
10703}
10704
c4028958 10705static void ipw_bg_rf_kill(struct work_struct *work)
c848d0af 10706{
c4028958
DH
10707 struct ipw_priv *priv =
10708 container_of(work, struct ipw_priv, rf_kill.work);
4644151b 10709 mutex_lock(&priv->mutex);
c4028958 10710 ipw_rf_kill(priv);
4644151b 10711 mutex_unlock(&priv->mutex);
c848d0af
JK
10712}
10713
a73e22b2 10714static void ipw_link_up(struct ipw_priv *priv)
a613bffd 10715{
afbf30a2
JK
10716 priv->last_seq_num = -1;
10717 priv->last_frag_num = -1;
10718 priv->last_packet_time = 0;
10719
a613bffd 10720 netif_carrier_on(priv->net_dev);
a613bffd 10721
c848d0af 10722 cancel_delayed_work(&priv->request_scan);
ea177305
DW
10723 cancel_delayed_work(&priv->request_direct_scan);
10724 cancel_delayed_work(&priv->request_passive_scan);
0b531676 10725 cancel_delayed_work(&priv->scan_event);
a613bffd
JK
10726 ipw_reset_stats(priv);
10727 /* Ensure the rate is updated immediately */
10728 priv->last_rate = ipw_get_current_rate(priv);
10729 ipw_gather_stats(priv);
10730 ipw_led_link_up(priv);
10731 notify_wx_assoc_event(priv);
10732
10733 if (priv->config & CFG_BACKGROUND_SCAN)
bcb6d916 10734 schedule_delayed_work(&priv->request_scan, HZ);
a613bffd
JK
10735}
10736
c4028958 10737static void ipw_bg_link_up(struct work_struct *work)
c848d0af 10738{
c4028958
DH
10739 struct ipw_priv *priv =
10740 container_of(work, struct ipw_priv, link_up);
4644151b 10741 mutex_lock(&priv->mutex);
c4028958 10742 ipw_link_up(priv);
4644151b 10743 mutex_unlock(&priv->mutex);
c848d0af
JK
10744}
10745
a73e22b2 10746static void ipw_link_down(struct ipw_priv *priv)
a613bffd
JK
10747{
10748 ipw_led_link_down(priv);
10749 netif_carrier_off(priv->net_dev);
a613bffd
JK
10750 notify_wx_assoc_event(priv);
10751
10752 /* Cancel any queued work ... */
10753 cancel_delayed_work(&priv->request_scan);
ea177305
DW
10754 cancel_delayed_work(&priv->request_direct_scan);
10755 cancel_delayed_work(&priv->request_passive_scan);
a613bffd
JK
10756 cancel_delayed_work(&priv->adhoc_check);
10757 cancel_delayed_work(&priv->gather_stats);
10758
10759 ipw_reset_stats(priv);
10760
afbf30a2
JK
10761 if (!(priv->status & STATUS_EXIT_PENDING)) {
10762 /* Queue up another scan... */
bcb6d916 10763 schedule_delayed_work(&priv->request_scan, 0);
0b531676
DW
10764 } else
10765 cancel_delayed_work(&priv->scan_event);
a613bffd
JK
10766}
10767
c4028958 10768static void ipw_bg_link_down(struct work_struct *work)
c848d0af 10769{
c4028958
DH
10770 struct ipw_priv *priv =
10771 container_of(work, struct ipw_priv, link_down);
4644151b 10772 mutex_lock(&priv->mutex);
c4028958 10773 ipw_link_down(priv);
4644151b 10774 mutex_unlock(&priv->mutex);
43f66a6c
JK
10775}
10776
2ef19e63 10777static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv)
43f66a6c
JK
10778{
10779 int ret = 0;
10780
43f66a6c 10781 init_waitqueue_head(&priv->wait_command_queue);
afbf30a2 10782 init_waitqueue_head(&priv->wait_state);
43f66a6c 10783
c4028958
DH
10784 INIT_DELAYED_WORK(&priv->adhoc_check, ipw_bg_adhoc_check);
10785 INIT_WORK(&priv->associate, ipw_bg_associate);
10786 INIT_WORK(&priv->disassociate, ipw_bg_disassociate);
10787 INIT_WORK(&priv->system_config, ipw_system_config);
10788 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish);
10789 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart);
10790 INIT_DELAYED_WORK(&priv->rf_kill, ipw_bg_rf_kill);
10791 INIT_WORK(&priv->up, ipw_bg_up);
10792 INIT_WORK(&priv->down, ipw_bg_down);
10793 INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan);
ea177305
DW
10794 INIT_DELAYED_WORK(&priv->request_direct_scan, ipw_request_direct_scan);
10795 INIT_DELAYED_WORK(&priv->request_passive_scan, ipw_request_passive_scan);
0b531676 10796 INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event);
c4028958
DH
10797 INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats);
10798 INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan);
10799 INIT_WORK(&priv->roam, ipw_bg_roam);
10800 INIT_DELAYED_WORK(&priv->scan_check, ipw_bg_scan_check);
10801 INIT_WORK(&priv->link_up, ipw_bg_link_up);
10802 INIT_WORK(&priv->link_down, ipw_bg_link_down);
10803 INIT_DELAYED_WORK(&priv->led_link_on, ipw_bg_led_link_on);
10804 INIT_DELAYED_WORK(&priv->led_link_off, ipw_bg_led_link_off);
10805 INIT_DELAYED_WORK(&priv->led_act_off, ipw_bg_led_activity_off);
10806 INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network);
43f66a6c 10807
e43e3c1e 10808#ifdef CONFIG_IPW2200_QOS
c4028958 10809 INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate);
e43e3c1e 10810#endif /* CONFIG_IPW2200_QOS */
43f66a6c
JK
10811
10812 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
10813 ipw_irq_tasklet, (unsigned long)priv);
10814
10815 return ret;
10816}
10817
43f66a6c 10818static void shim__set_security(struct net_device *dev,
b0a4e7d8 10819 struct libipw_security *sec)
43f66a6c 10820{
b0a4e7d8 10821 struct ipw_priv *priv = libipw_priv(dev);
43f66a6c 10822 int i;
bf79451e 10823 for (i = 0; i < 4; i++) {
43f66a6c 10824 if (sec->flags & (1 << i)) {
afbf30a2 10825 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
b095c381 10826 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
43f66a6c 10827 if (sec->key_sizes[i] == 0)
b095c381
JK
10828 priv->ieee->sec.flags &= ~(1 << i);
10829 else {
10830 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
43f66a6c 10831 sec->key_sizes[i]);
b095c381
JK
10832 priv->ieee->sec.flags |= (1 << i);
10833 }
43f66a6c 10834 priv->status |= STATUS_SECURITY_UPDATED;
b095c381
JK
10835 } else if (sec->level != SEC_LEVEL_1)
10836 priv->ieee->sec.flags &= ~(1 << i);
43f66a6c
JK
10837 }
10838
b095c381 10839 if (sec->flags & SEC_ACTIVE_KEY) {
43f66a6c 10840 if (sec->active_key <= 3) {
b095c381
JK
10841 priv->ieee->sec.active_key = sec->active_key;
10842 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
bf79451e 10843 } else
b095c381 10844 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
43f66a6c 10845 priv->status |= STATUS_SECURITY_UPDATED;
b095c381
JK
10846 } else
10847 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
43f66a6c
JK
10848
10849 if ((sec->flags & SEC_AUTH_MODE) &&
b095c381
JK
10850 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
10851 priv->ieee->sec.auth_mode = sec->auth_mode;
10852 priv->ieee->sec.flags |= SEC_AUTH_MODE;
43f66a6c
JK
10853 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
10854 priv->capability |= CAP_SHARED_KEY;
10855 else
10856 priv->capability &= ~CAP_SHARED_KEY;
10857 priv->status |= STATUS_SECURITY_UPDATED;
10858 }
bf79451e 10859
b095c381
JK
10860 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
10861 priv->ieee->sec.flags |= SEC_ENABLED;
10862 priv->ieee->sec.enabled = sec->enabled;
43f66a6c 10863 priv->status |= STATUS_SECURITY_UPDATED;
bf79451e 10864 if (sec->enabled)
43f66a6c
JK
10865 priv->capability |= CAP_PRIVACY_ON;
10866 else
10867 priv->capability &= ~CAP_PRIVACY_ON;
10868 }
bf79451e 10869
afbf30a2
JK
10870 if (sec->flags & SEC_ENCRYPT)
10871 priv->ieee->sec.encrypt = sec->encrypt;
bf79451e 10872
b095c381
JK
10873 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
10874 priv->ieee->sec.level = sec->level;
10875 priv->ieee->sec.flags |= SEC_LEVEL;
43f66a6c
JK
10876 priv->status |= STATUS_SECURITY_UPDATED;
10877 }
10878
1fbfea54
ZY
10879 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
10880 ipw_set_hwcrypto_keys(priv);
10881
bf79451e
JG
10882 /* To match current functionality of ipw2100 (which works well w/
10883 * various supplicants, we don't force a disassociate if the
43f66a6c
JK
10884 * privacy capability changes ... */
10885#if 0
10886 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
bf79451e 10887 (((priv->assoc_request.capability &
5b5e807f 10888 cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && !sec->enabled) ||
bf79451e 10889 (!(priv->assoc_request.capability &
5b5e807f 10890 cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && sec->enabled))) {
43f66a6c
JK
10891 IPW_DEBUG_ASSOC("Disassociating due to capability "
10892 "change.\n");
10893 ipw_disassociate(priv);
10894 }
10895#endif
10896}
10897
bf79451e 10898static int init_supported_rates(struct ipw_priv *priv,
43f66a6c
JK
10899 struct ipw_supported_rates *rates)
10900{
10901 /* TODO: Mask out rates based on priv->rates_mask */
10902
10903 memset(rates, 0, sizeof(*rates));
0edd5b44 10904 /* configure supported rates */
43f66a6c 10905 switch (priv->ieee->freq_band) {
b0a4e7d8 10906 case LIBIPW_52GHZ_BAND:
43f66a6c
JK
10907 rates->ieee_mode = IPW_A_MODE;
10908 rates->purpose = IPW_RATE_CAPABILITIES;
b0a4e7d8
JL
10909 ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,
10910 LIBIPW_OFDM_DEFAULT_RATES_MASK);
43f66a6c
JK
10911 break;
10912
0edd5b44 10913 default: /* Mixed or 2.4Ghz */
43f66a6c
JK
10914 rates->ieee_mode = IPW_G_MODE;
10915 rates->purpose = IPW_RATE_CAPABILITIES;
b0a4e7d8
JL
10916 ipw_add_cck_scan_rates(rates, LIBIPW_CCK_MODULATION,
10917 LIBIPW_CCK_DEFAULT_RATES_MASK);
10918 if (priv->ieee->modulation & LIBIPW_OFDM_MODULATION) {
10919 ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,
10920 LIBIPW_OFDM_DEFAULT_RATES_MASK);
43f66a6c
JK
10921 }
10922 break;
10923 }
10924
10925 return 0;
10926}
10927
bf79451e 10928static int ipw_config(struct ipw_priv *priv)
43f66a6c 10929{
43f66a6c
JK
10930 /* This is only called from ipw_up, which resets/reloads the firmware
10931 so, we don't need to first disable the card before we configure
10932 it */
6de9f7f2 10933 if (ipw_set_tx_power(priv))
43f66a6c
JK
10934 goto error;
10935
10936 /* initialize adapter address */
10937 if (ipw_send_adapter_address(priv, priv->net_dev->dev_addr))
10938 goto error;
10939
10940 /* set basic system config settings */
10941 init_sys_config(&priv->sys_config);
810dabd4
ZY
10942
10943 /* Support Bluetooth if we have BT h/w on board, and user wants to.
10944 * Does not support BT priority yet (don't abort or defer our Tx) */
10945 if (bt_coexist) {
2638bc39 10946 unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY];
810dabd4
ZY
10947
10948 if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG)
10949 priv->sys_config.bt_coexistence
2638bc39 10950 |= CFG_BT_COEXISTENCE_SIGNAL_CHNL;
810dabd4
ZY
10951 if (bt_caps & EEPROM_SKU_CAP_BT_OOB)
10952 priv->sys_config.bt_coexistence
2638bc39 10953 |= CFG_BT_COEXISTENCE_OOB;
810dabd4
ZY
10954 }
10955
d685b8c2
ZY
10956#ifdef CONFIG_IPW2200_PROMISCUOUS
10957 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
10958 priv->sys_config.accept_all_data_frames = 1;
10959 priv->sys_config.accept_non_directed_frames = 1;
10960 priv->sys_config.accept_all_mgmt_bcpr = 1;
10961 priv->sys_config.accept_all_mgmt_frames = 1;
10962 }
10963#endif
10964
c848d0af
JK
10965 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10966 priv->sys_config.answer_broadcast_ssid_probe = 1;
10967 else
10968 priv->sys_config.answer_broadcast_ssid_probe = 0;
10969
d685b8c2 10970 if (ipw_send_system_config(priv))
43f66a6c
JK
10971 goto error;
10972
0edd5b44
JG
10973 init_supported_rates(priv, &priv->rates);
10974 if (ipw_send_supported_rates(priv, &priv->rates))
43f66a6c
JK
10975 goto error;
10976
10977 /* Set request-to-send threshold */
10978 if (priv->rts_threshold) {
10979 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
10980 goto error;
10981 }
e43e3c1e 10982#ifdef CONFIG_IPW2200_QOS
b095c381
JK
10983 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
10984 ipw_qos_activate(priv, NULL);
e43e3c1e 10985#endif /* CONFIG_IPW2200_QOS */
43f66a6c
JK
10986
10987 if (ipw_set_random_seed(priv))
10988 goto error;
bf79451e 10989
43f66a6c
JK
10990 /* final state transition to the RUN state */
10991 if (ipw_send_host_complete(priv))
10992 goto error;
10993
e666619e
JK
10994 priv->status |= STATUS_INIT;
10995
10996 ipw_led_init(priv);
10997 ipw_led_radio_on(priv);
10998 priv->notif_missed_beacons = 0;
10999
11000 /* Set hardware WEP key if it is configured. */
11001 if ((priv->capability & CAP_PRIVACY_ON) &&
11002 (priv->ieee->sec.level == SEC_LEVEL_1) &&
11003 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
11004 ipw_set_hwcrypto_keys(priv);
43f66a6c
JK
11005
11006 return 0;
bf79451e 11007
0edd5b44 11008 error:
43f66a6c
JK
11009 return -EIO;
11010}
11011
4f36f808
JK
11012/*
11013 * NOTE:
11014 *
11015 * These tables have been tested in conjunction with the
11016 * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
11017 *
11018 * Altering this values, using it on other hardware, or in geographies
11019 * not intended for resale of the above mentioned Intel adapters has
11020 * not been tested.
11021 *
48a84770
HBA
11022 * Remember to update the table in README.ipw2200 when changing this
11023 * table.
11024 *
4f36f808 11025 */
b0a4e7d8 11026static const struct libipw_geo ipw_geos[] = {
4f36f808
JK
11027 { /* Restricted */
11028 "---",
11029 .bg_channels = 11,
11030 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11031 {2427, 4}, {2432, 5}, {2437, 6},
11032 {2442, 7}, {2447, 8}, {2452, 9},
11033 {2457, 10}, {2462, 11}},
11034 },
11035
11036 { /* Custom US/Canada */
11037 "ZZF",
11038 .bg_channels = 11,
11039 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11040 {2427, 4}, {2432, 5}, {2437, 6},
11041 {2442, 7}, {2447, 8}, {2452, 9},
11042 {2457, 10}, {2462, 11}},
11043 .a_channels = 8,
11044 .a = {{5180, 36},
11045 {5200, 40},
11046 {5220, 44},
11047 {5240, 48},
b0a4e7d8
JL
11048 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11049 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11050 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11051 {5320, 64, LIBIPW_CH_PASSIVE_ONLY}},
4f36f808
JK
11052 },
11053
11054 { /* Rest of World */
11055 "ZZD",
11056 .bg_channels = 13,
11057 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11058 {2427, 4}, {2432, 5}, {2437, 6},
11059 {2442, 7}, {2447, 8}, {2452, 9},
11060 {2457, 10}, {2462, 11}, {2467, 12},
11061 {2472, 13}},
11062 },
11063
11064 { /* Custom USA & Europe & High */
11065 "ZZA",
11066 .bg_channels = 11,
11067 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11068 {2427, 4}, {2432, 5}, {2437, 6},
11069 {2442, 7}, {2447, 8}, {2452, 9},
11070 {2457, 10}, {2462, 11}},
11071 .a_channels = 13,
11072 .a = {{5180, 36},
11073 {5200, 40},
11074 {5220, 44},
11075 {5240, 48},
b0a4e7d8
JL
11076 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11077 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11078 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11079 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
4f36f808
JK
11080 {5745, 149},
11081 {5765, 153},
11082 {5785, 157},
11083 {5805, 161},
11084 {5825, 165}},
11085 },
11086
11087 { /* Custom NA & Europe */
11088 "ZZB",
11089 .bg_channels = 11,
11090 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11091 {2427, 4}, {2432, 5}, {2437, 6},
11092 {2442, 7}, {2447, 8}, {2452, 9},
11093 {2457, 10}, {2462, 11}},
11094 .a_channels = 13,
11095 .a = {{5180, 36},
11096 {5200, 40},
11097 {5220, 44},
11098 {5240, 48},
b0a4e7d8
JL
11099 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11100 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11101 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11102 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
11103 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
11104 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
11105 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
11106 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
11107 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
4f36f808
JK
11108 },
11109
11110 { /* Custom Japan */
11111 "ZZC",
11112 .bg_channels = 11,
11113 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11114 {2427, 4}, {2432, 5}, {2437, 6},
11115 {2442, 7}, {2447, 8}, {2452, 9},
11116 {2457, 10}, {2462, 11}},
11117 .a_channels = 4,
11118 .a = {{5170, 34}, {5190, 38},
11119 {5210, 42}, {5230, 46}},
11120 },
11121
11122 { /* Custom */
11123 "ZZM",
11124 .bg_channels = 11,
11125 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11126 {2427, 4}, {2432, 5}, {2437, 6},
11127 {2442, 7}, {2447, 8}, {2452, 9},
11128 {2457, 10}, {2462, 11}},
11129 },
11130
11131 { /* Europe */
11132 "ZZE",
11133 .bg_channels = 13,
11134 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11135 {2427, 4}, {2432, 5}, {2437, 6},
11136 {2442, 7}, {2447, 8}, {2452, 9},
11137 {2457, 10}, {2462, 11}, {2467, 12},
11138 {2472, 13}},
11139 .a_channels = 19,
11140 .a = {{5180, 36},
11141 {5200, 40},
11142 {5220, 44},
11143 {5240, 48},
b0a4e7d8
JL
11144 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11145 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11146 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11147 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
11148 {5500, 100, LIBIPW_CH_PASSIVE_ONLY},
11149 {5520, 104, LIBIPW_CH_PASSIVE_ONLY},
11150 {5540, 108, LIBIPW_CH_PASSIVE_ONLY},
11151 {5560, 112, LIBIPW_CH_PASSIVE_ONLY},
11152 {5580, 116, LIBIPW_CH_PASSIVE_ONLY},
11153 {5600, 120, LIBIPW_CH_PASSIVE_ONLY},
11154 {5620, 124, LIBIPW_CH_PASSIVE_ONLY},
11155 {5640, 128, LIBIPW_CH_PASSIVE_ONLY},
11156 {5660, 132, LIBIPW_CH_PASSIVE_ONLY},
11157 {5680, 136, LIBIPW_CH_PASSIVE_ONLY},
11158 {5700, 140, LIBIPW_CH_PASSIVE_ONLY}},
4f36f808
JK
11159 },
11160
11161 { /* Custom Japan */
11162 "ZZJ",
11163 .bg_channels = 14,
11164 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11165 {2427, 4}, {2432, 5}, {2437, 6},
11166 {2442, 7}, {2447, 8}, {2452, 9},
11167 {2457, 10}, {2462, 11}, {2467, 12},
b0a4e7d8 11168 {2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY}},
4f36f808
JK
11169 .a_channels = 4,
11170 .a = {{5170, 34}, {5190, 38},
11171 {5210, 42}, {5230, 46}},
11172 },
11173
03520576
JK
11174 { /* Rest of World */
11175 "ZZR",
11176 .bg_channels = 14,
11177 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11178 {2427, 4}, {2432, 5}, {2437, 6},
11179 {2442, 7}, {2447, 8}, {2452, 9},
11180 {2457, 10}, {2462, 11}, {2467, 12},
b0a4e7d8
JL
11181 {2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY |
11182 LIBIPW_CH_PASSIVE_ONLY}},
03520576
JK
11183 },
11184
4f36f808
JK
11185 { /* High Band */
11186 "ZZH",
11187 .bg_channels = 13,
11188 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11189 {2427, 4}, {2432, 5}, {2437, 6},
11190 {2442, 7}, {2447, 8}, {2452, 9},
11191 {2457, 10}, {2462, 11},
b0a4e7d8
JL
11192 {2467, 12, LIBIPW_CH_PASSIVE_ONLY},
11193 {2472, 13, LIBIPW_CH_PASSIVE_ONLY}},
4f36f808
JK
11194 .a_channels = 4,
11195 .a = {{5745, 149}, {5765, 153},
11196 {5785, 157}, {5805, 161}},
11197 },
11198
11199 { /* Custom Europe */
11200 "ZZG",
11201 .bg_channels = 13,
11202 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11203 {2427, 4}, {2432, 5}, {2437, 6},
11204 {2442, 7}, {2447, 8}, {2452, 9},
11205 {2457, 10}, {2462, 11},
11206 {2467, 12}, {2472, 13}},
11207 .a_channels = 4,
11208 .a = {{5180, 36}, {5200, 40},
11209 {5220, 44}, {5240, 48}},
11210 },
11211
11212 { /* Europe */
11213 "ZZK",
11214 .bg_channels = 13,
11215 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11216 {2427, 4}, {2432, 5}, {2437, 6},
11217 {2442, 7}, {2447, 8}, {2452, 9},
11218 {2457, 10}, {2462, 11},
b0a4e7d8
JL
11219 {2467, 12, LIBIPW_CH_PASSIVE_ONLY},
11220 {2472, 13, LIBIPW_CH_PASSIVE_ONLY}},
4f36f808 11221 .a_channels = 24,
b0a4e7d8
JL
11222 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},
11223 {5200, 40, LIBIPW_CH_PASSIVE_ONLY},
11224 {5220, 44, LIBIPW_CH_PASSIVE_ONLY},
11225 {5240, 48, LIBIPW_CH_PASSIVE_ONLY},
11226 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11227 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11228 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11229 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
11230 {5500, 100, LIBIPW_CH_PASSIVE_ONLY},
11231 {5520, 104, LIBIPW_CH_PASSIVE_ONLY},
11232 {5540, 108, LIBIPW_CH_PASSIVE_ONLY},
11233 {5560, 112, LIBIPW_CH_PASSIVE_ONLY},
11234 {5580, 116, LIBIPW_CH_PASSIVE_ONLY},
11235 {5600, 120, LIBIPW_CH_PASSIVE_ONLY},
11236 {5620, 124, LIBIPW_CH_PASSIVE_ONLY},
11237 {5640, 128, LIBIPW_CH_PASSIVE_ONLY},
11238 {5660, 132, LIBIPW_CH_PASSIVE_ONLY},
11239 {5680, 136, LIBIPW_CH_PASSIVE_ONLY},
11240 {5700, 140, LIBIPW_CH_PASSIVE_ONLY},
11241 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
11242 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
11243 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
11244 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
11245 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
4f36f808
JK
11246 },
11247
11248 { /* Europe */
11249 "ZZL",
11250 .bg_channels = 11,
11251 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11252 {2427, 4}, {2432, 5}, {2437, 6},
11253 {2442, 7}, {2447, 8}, {2452, 9},
11254 {2457, 10}, {2462, 11}},
11255 .a_channels = 13,
b0a4e7d8
JL
11256 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},
11257 {5200, 40, LIBIPW_CH_PASSIVE_ONLY},
11258 {5220, 44, LIBIPW_CH_PASSIVE_ONLY},
11259 {5240, 48, LIBIPW_CH_PASSIVE_ONLY},
11260 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11261 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11262 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11263 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
11264 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
11265 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
11266 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
11267 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
11268 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
4f36f808 11269 }
afbf30a2
JK
11270};
11271
43f66a6c
JK
11272#define MAX_HW_RESTARTS 5
11273static int ipw_up(struct ipw_priv *priv)
11274{
4f36f808 11275 int rc, i, j;
43f66a6c 11276
c3d72b96
DW
11277 /* Age scan list entries found before suspend */
11278 if (priv->suspend_time) {
b0a4e7d8 11279 libipw_networks_age(priv->ieee, priv->suspend_time);
c3d72b96
DW
11280 priv->suspend_time = 0;
11281 }
11282
43f66a6c
JK
11283 if (priv->status & STATUS_EXIT_PENDING)
11284 return -EIO;
11285
f6c5cb7c 11286 if (cmdlog && !priv->cmdlog) {
e6e3f12a 11287 priv->cmdlog = kcalloc(cmdlog, sizeof(*priv->cmdlog),
f6c5cb7c
JK
11288 GFP_KERNEL);
11289 if (priv->cmdlog == NULL) {
11290 IPW_ERROR("Error allocating %d command log entries.\n",
11291 cmdlog);
d0b526b7 11292 return -ENOMEM;
f6c5cb7c 11293 } else {
f6c5cb7c
JK
11294 priv->cmdlog_len = cmdlog;
11295 }
11296 }
11297
0edd5b44 11298 for (i = 0; i < MAX_HW_RESTARTS; i++) {
bf79451e 11299 /* Load the microcode, firmware, and eeprom.
43f66a6c
JK
11300 * Also start the clocks. */
11301 rc = ipw_load(priv);
11302 if (rc) {
a4f6bbb3 11303 IPW_ERROR("Unable to load firmware: %d\n", rc);
43f66a6c
JK
11304 return rc;
11305 }
11306
11307 ipw_init_ordinals(priv);
11308 if (!(priv->config & CFG_CUSTOM_MAC))
11309 eeprom_parse_mac(priv, priv->mac_addr);
11310 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
5e5eab5d 11311 memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN);
43f66a6c 11312
4f36f808
JK
11313 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
11314 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
11315 ipw_geos[j].name, 3))
11316 break;
11317 }
03520576
JK
11318 if (j == ARRAY_SIZE(ipw_geos)) {
11319 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
11320 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
11321 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
11322 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
4f36f808 11323 j = 0;
03520576 11324 }
9c033bed 11325 libipw_set_geo(priv->ieee, &ipw_geos[j]);
4f36f808 11326
b095c381
JK
11327 if (priv->status & STATUS_RF_KILL_SW) {
11328 IPW_WARNING("Radio disabled by module parameter.\n");
11329 return 0;
11330 } else if (rf_kill_active(priv)) {
11331 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
11332 "Kill switch must be turned off for "
11333 "wireless networking to work.\n");
bcb6d916 11334 schedule_delayed_work(&priv->rf_kill, 2 * HZ);
43f66a6c 11335 return 0;
c848d0af 11336 }
43f66a6c
JK
11337
11338 rc = ipw_config(priv);
11339 if (!rc) {
11340 IPW_DEBUG_INFO("Configured device on count %i\n", i);
e666619e
JK
11341
11342 /* If configure to try and auto-associate, kick
11343 * off a scan. */
bcb6d916 11344 schedule_delayed_work(&priv->request_scan, 0);
afbf30a2 11345
43f66a6c 11346 return 0;
43f66a6c 11347 }
bf79451e 11348
c848d0af 11349 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
43f66a6c
JK
11350 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
11351 i, MAX_HW_RESTARTS);
11352
11353 /* We had an error bringing up the hardware, so take it
11354 * all the way back down so we can try again */
11355 ipw_down(priv);
11356 }
11357
bf79451e 11358 /* tried to restart and config the device for as long as our
43f66a6c 11359 * patience could withstand */
0edd5b44 11360 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
c848d0af 11361
43f66a6c
JK
11362 return -EIO;
11363}
11364
c4028958 11365static void ipw_bg_up(struct work_struct *work)
c848d0af 11366{
c4028958
DH
11367 struct ipw_priv *priv =
11368 container_of(work, struct ipw_priv, up);
4644151b 11369 mutex_lock(&priv->mutex);
c4028958 11370 ipw_up(priv);
4644151b 11371 mutex_unlock(&priv->mutex);
c848d0af
JK
11372}
11373
b095c381 11374static void ipw_deinit(struct ipw_priv *priv)
43f66a6c 11375{
b095c381
JK
11376 int i;
11377
11378 if (priv->status & STATUS_SCANNING) {
11379 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
11380 ipw_abort_scan(priv);
11381 }
11382
11383 if (priv->status & STATUS_ASSOCIATED) {
11384 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
11385 ipw_disassociate(priv);
11386 }
11387
11388 ipw_led_shutdown(priv);
11389
11390 /* Wait up to 1s for status to change to not scanning and not
11391 * associated (disassociation can take a while for a ful 802.11
11392 * exchange */
11393 for (i = 1000; i && (priv->status &
11394 (STATUS_DISASSOCIATING |
11395 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
11396 udelay(10);
11397
11398 if (priv->status & (STATUS_DISASSOCIATING |
11399 STATUS_ASSOCIATED | STATUS_SCANNING))
11400 IPW_DEBUG_INFO("Still associated or scanning...\n");
11401 else
11402 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
11403
43f66a6c 11404 /* Attempt to disable the card */
43f66a6c 11405 ipw_send_card_disable(priv, 0);
b095c381
JK
11406
11407 priv->status &= ~STATUS_INIT;
11408}
11409
11410static void ipw_down(struct ipw_priv *priv)
11411{
11412 int exit_pending = priv->status & STATUS_EXIT_PENDING;
11413
11414 priv->status |= STATUS_EXIT_PENDING;
11415
11416 if (ipw_is_init(priv))
11417 ipw_deinit(priv);
11418
11419 /* Wipe out the EXIT_PENDING status bit if we are not actually
11420 * exiting the module */
11421 if (!exit_pending)
11422 priv->status &= ~STATUS_EXIT_PENDING;
43f66a6c
JK
11423
11424 /* tell the device to stop sending interrupts */
11425 ipw_disable_interrupts(priv);
11426
11427 /* Clear all bits but the RF Kill */
b095c381 11428 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
43f66a6c 11429 netif_carrier_off(priv->net_dev);
43f66a6c
JK
11430
11431 ipw_stop_nic(priv);
a613bffd
JK
11432
11433 ipw_led_radio_off(priv);
43f66a6c
JK
11434}
11435
c4028958 11436static void ipw_bg_down(struct work_struct *work)
c848d0af 11437{
c4028958
DH
11438 struct ipw_priv *priv =
11439 container_of(work, struct ipw_priv, down);
4644151b 11440 mutex_lock(&priv->mutex);
c4028958 11441 ipw_down(priv);
4644151b 11442 mutex_unlock(&priv->mutex);
43f66a6c
JK
11443}
11444
7cabafce 11445static int ipw_wdev_init(struct net_device *dev)
43f66a6c 11446{
a3caa99e 11447 int i, rc = 0;
b0a4e7d8 11448 struct ipw_priv *priv = libipw_priv(dev);
a3caa99e
JL
11449 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
11450 struct wireless_dev *wdev = &priv->ieee->wdev;
b8ecd988 11451
a3caa99e
JL
11452 memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
11453
11454 /* fill-out priv->ieee->bg_band */
11455 if (geo->bg_channels) {
11456 struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
11457
11458 bg_band->band = IEEE80211_BAND_2GHZ;
11459 bg_band->n_channels = geo->bg_channels;
baeb2ffa
JP
11460 bg_band->channels = kcalloc(geo->bg_channels,
11461 sizeof(struct ieee80211_channel),
11462 GFP_KERNEL);
2ee4e27c
DC
11463 if (!bg_band->channels) {
11464 rc = -ENOMEM;
11465 goto out;
11466 }
a3caa99e
JL
11467 /* translate geo->bg to bg_band.channels */
11468 for (i = 0; i < geo->bg_channels; i++) {
11469 bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
11470 bg_band->channels[i].center_freq = geo->bg[i].freq;
11471 bg_band->channels[i].hw_value = geo->bg[i].channel;
11472 bg_band->channels[i].max_power = geo->bg[i].max_power;
11473 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11474 bg_band->channels[i].flags |=
11475 IEEE80211_CHAN_PASSIVE_SCAN;
11476 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
11477 bg_band->channels[i].flags |=
11478 IEEE80211_CHAN_NO_IBSS;
11479 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
11480 bg_band->channels[i].flags |=
11481 IEEE80211_CHAN_RADAR;
11482 /* No equivalent for LIBIPW_CH_80211H_RULES,
11483 LIBIPW_CH_UNIFORM_SPREADING, or
11484 LIBIPW_CH_B_ONLY... */
11485 }
11486 /* point at bitrate info */
11487 bg_band->bitrates = ipw2200_bg_rates;
11488 bg_band->n_bitrates = ipw2200_num_bg_rates;
11489
11490 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
b8ecd988
JL
11491 }
11492
a3caa99e
JL
11493 /* fill-out priv->ieee->a_band */
11494 if (geo->a_channels) {
11495 struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
11496
11497 a_band->band = IEEE80211_BAND_5GHZ;
11498 a_band->n_channels = geo->a_channels;
baeb2ffa
JP
11499 a_band->channels = kcalloc(geo->a_channels,
11500 sizeof(struct ieee80211_channel),
11501 GFP_KERNEL);
2ee4e27c
DC
11502 if (!a_band->channels) {
11503 rc = -ENOMEM;
11504 goto out;
11505 }
75836b8d 11506 /* translate geo->a to a_band.channels */
a3caa99e 11507 for (i = 0; i < geo->a_channels; i++) {
75836b8d 11508 a_band->channels[i].band = IEEE80211_BAND_5GHZ;
a3caa99e
JL
11509 a_band->channels[i].center_freq = geo->a[i].freq;
11510 a_band->channels[i].hw_value = geo->a[i].channel;
11511 a_band->channels[i].max_power = geo->a[i].max_power;
11512 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11513 a_band->channels[i].flags |=
11514 IEEE80211_CHAN_PASSIVE_SCAN;
11515 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
11516 a_band->channels[i].flags |=
11517 IEEE80211_CHAN_NO_IBSS;
11518 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
11519 a_band->channels[i].flags |=
11520 IEEE80211_CHAN_RADAR;
11521 /* No equivalent for LIBIPW_CH_80211H_RULES,
11522 LIBIPW_CH_UNIFORM_SPREADING, or
11523 LIBIPW_CH_B_ONLY... */
11524 }
11525 /* point at bitrate info */
11526 a_band->bitrates = ipw2200_a_rates;
11527 a_band->n_bitrates = ipw2200_num_a_rates;
11528
11529 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
11530 }
11531
a141e6a0
SY
11532 wdev->wiphy->cipher_suites = ipw_cipher_suites;
11533 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);
11534
a3caa99e
JL
11535 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
11536
11537 /* With that information in place, we can now register the wiphy... */
7cabafce 11538 if (wiphy_register(wdev->wiphy))
a3caa99e 11539 rc = -EIO;
a3caa99e 11540out:
a3caa99e 11541 return rc;
43f66a6c
JK
11542}
11543
11544/* PCI driver stuff */
a3aa1884 11545static DEFINE_PCI_DEVICE_TABLE(card_ids) = {
43f66a6c
JK
11546 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
11547 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
11548 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
11549 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2712, 0, 0, 0},
11550 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2721, 0, 0, 0},
11551 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2722, 0, 0, 0},
11552 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2731, 0, 0, 0},
11553 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2732, 0, 0, 0},
11554 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2741, 0, 0, 0},
11555 {PCI_VENDOR_ID_INTEL, 0x1043, 0x103c, 0x2741, 0, 0, 0},
11556 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2742, 0, 0, 0},
11557 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2751, 0, 0, 0},
11558 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2752, 0, 0, 0},
11559 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2753, 0, 0, 0},
11560 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},
11561 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},
11562 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
8ab0ea77
JP
11563 {PCI_VDEVICE(INTEL, 0x104f), 0},
11564 {PCI_VDEVICE(INTEL, 0x4220), 0}, /* BG */
11565 {PCI_VDEVICE(INTEL, 0x4221), 0}, /* BG */
11566 {PCI_VDEVICE(INTEL, 0x4223), 0}, /* ABG */
11567 {PCI_VDEVICE(INTEL, 0x4224), 0}, /* ABG */
bf79451e 11568
43f66a6c
JK
11569 /* required last entry */
11570 {0,}
11571};
11572
11573MODULE_DEVICE_TABLE(pci, card_ids);
11574
11575static struct attribute *ipw_sysfs_entries[] = {
11576 &dev_attr_rf_kill.attr,
11577 &dev_attr_direct_dword.attr,
11578 &dev_attr_indirect_byte.attr,
11579 &dev_attr_indirect_dword.attr,
11580 &dev_attr_mem_gpio_reg.attr,
11581 &dev_attr_command_event_reg.attr,
11582 &dev_attr_nic_type.attr,
11583 &dev_attr_status.attr,
11584 &dev_attr_cfg.attr,
b39860c6
JK
11585 &dev_attr_error.attr,
11586 &dev_attr_event_log.attr,
f6c5cb7c 11587 &dev_attr_cmd_log.attr,
43f66a6c
JK
11588 &dev_attr_eeprom_delay.attr,
11589 &dev_attr_ucode_version.attr,
11590 &dev_attr_rtc.attr,
a613bffd
JK
11591 &dev_attr_scan_age.attr,
11592 &dev_attr_led.attr,
b095c381
JK
11593 &dev_attr_speed_scan.attr,
11594 &dev_attr_net_stats.attr,
375dd244 11595 &dev_attr_channels.attr,
d685b8c2
ZY
11596#ifdef CONFIG_IPW2200_PROMISCUOUS
11597 &dev_attr_rtap_iface.attr,
11598 &dev_attr_rtap_filter.attr,
11599#endif
43f66a6c
JK
11600 NULL
11601};
11602
11603static struct attribute_group ipw_attribute_group = {
11604 .name = NULL, /* put in device directory */
0edd5b44 11605 .attrs = ipw_sysfs_entries,
43f66a6c
JK
11606};
11607
d685b8c2
ZY
11608#ifdef CONFIG_IPW2200_PROMISCUOUS
11609static int ipw_prom_open(struct net_device *dev)
11610{
b0a4e7d8 11611 struct ipw_prom_priv *prom_priv = libipw_priv(dev);
d685b8c2
ZY
11612 struct ipw_priv *priv = prom_priv->priv;
11613
11614 IPW_DEBUG_INFO("prom dev->open\n");
11615 netif_carrier_off(dev);
d685b8c2
ZY
11616
11617 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11618 priv->sys_config.accept_all_data_frames = 1;
11619 priv->sys_config.accept_non_directed_frames = 1;
11620 priv->sys_config.accept_all_mgmt_bcpr = 1;
11621 priv->sys_config.accept_all_mgmt_frames = 1;
11622
11623 ipw_send_system_config(priv);
11624 }
11625
11626 return 0;
11627}
11628
11629static int ipw_prom_stop(struct net_device *dev)
11630{
b0a4e7d8 11631 struct ipw_prom_priv *prom_priv = libipw_priv(dev);
d685b8c2
ZY
11632 struct ipw_priv *priv = prom_priv->priv;
11633
11634 IPW_DEBUG_INFO("prom dev->stop\n");
11635
11636 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11637 priv->sys_config.accept_all_data_frames = 0;
11638 priv->sys_config.accept_non_directed_frames = 0;
11639 priv->sys_config.accept_all_mgmt_bcpr = 0;
11640 priv->sys_config.accept_all_mgmt_frames = 0;
11641
11642 ipw_send_system_config(priv);
11643 }
11644
11645 return 0;
11646}
11647
d0cf9c0d
SH
11648static netdev_tx_t ipw_prom_hard_start_xmit(struct sk_buff *skb,
11649 struct net_device *dev)
d685b8c2
ZY
11650{
11651 IPW_DEBUG_INFO("prom dev->xmit\n");
4153e775
PM
11652 dev_kfree_skb(skb);
11653 return NETDEV_TX_OK;
d685b8c2
ZY
11654}
11655
44e9ad0b
SH
11656static const struct net_device_ops ipw_prom_netdev_ops = {
11657 .ndo_open = ipw_prom_open,
11658 .ndo_stop = ipw_prom_stop,
11659 .ndo_start_xmit = ipw_prom_hard_start_xmit,
b0a4e7d8 11660 .ndo_change_mtu = libipw_change_mtu,
44e9ad0b
SH
11661 .ndo_set_mac_address = eth_mac_addr,
11662 .ndo_validate_addr = eth_validate_addr,
11663};
11664
d685b8c2
ZY
11665static int ipw_prom_alloc(struct ipw_priv *priv)
11666{
11667 int rc = 0;
11668
11669 if (priv->prom_net_dev)
11670 return -EPERM;
11671
27ae60f8 11672 priv->prom_net_dev = alloc_libipw(sizeof(struct ipw_prom_priv), 1);
d685b8c2
ZY
11673 if (priv->prom_net_dev == NULL)
11674 return -ENOMEM;
11675
b0a4e7d8 11676 priv->prom_priv = libipw_priv(priv->prom_net_dev);
d685b8c2
ZY
11677 priv->prom_priv->ieee = netdev_priv(priv->prom_net_dev);
11678 priv->prom_priv->priv = priv;
11679
11680 strcpy(priv->prom_net_dev->name, "rtap%d");
3f2eeac9 11681 memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
d685b8c2
ZY
11682
11683 priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
44e9ad0b 11684 priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
d685b8c2
ZY
11685
11686 priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
229ce3ab 11687 SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
d685b8c2
ZY
11688
11689 rc = register_netdev(priv->prom_net_dev);
11690 if (rc) {
27ae60f8 11691 free_libipw(priv->prom_net_dev, 1);
d685b8c2
ZY
11692 priv->prom_net_dev = NULL;
11693 return rc;
11694 }
11695
11696 return 0;
11697}
11698
11699static void ipw_prom_free(struct ipw_priv *priv)
11700{
11701 if (!priv->prom_net_dev)
11702 return;
11703
11704 unregister_netdev(priv->prom_net_dev);
27ae60f8 11705 free_libipw(priv->prom_net_dev, 1);
d685b8c2
ZY
11706
11707 priv->prom_net_dev = NULL;
11708}
11709
11710#endif
11711
44e9ad0b 11712static const struct net_device_ops ipw_netdev_ops = {
44e9ad0b
SH
11713 .ndo_open = ipw_net_open,
11714 .ndo_stop = ipw_net_stop,
afc4b13d 11715 .ndo_set_rx_mode = ipw_net_set_multicast_list,
44e9ad0b 11716 .ndo_set_mac_address = ipw_net_set_mac_address,
b0a4e7d8
JL
11717 .ndo_start_xmit = libipw_xmit,
11718 .ndo_change_mtu = libipw_change_mtu,
44e9ad0b
SH
11719 .ndo_validate_addr = eth_validate_addr,
11720};
d685b8c2 11721
2ef19e63
AB
11722static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11723 const struct pci_device_id *ent)
43f66a6c
JK
11724{
11725 int err = 0;
11726 struct net_device *net_dev;
11727 void __iomem *base;
11728 u32 length, val;
11729 struct ipw_priv *priv;
afbf30a2 11730 int i;
43f66a6c 11731
27ae60f8 11732 net_dev = alloc_libipw(sizeof(struct ipw_priv), 0);
43f66a6c
JK
11733 if (net_dev == NULL) {
11734 err = -ENOMEM;
11735 goto out;
11736 }
11737
b0a4e7d8 11738 priv = libipw_priv(net_dev);
43f66a6c 11739 priv->ieee = netdev_priv(net_dev);
a613bffd 11740
43f66a6c
JK
11741 priv->net_dev = net_dev;
11742 priv->pci_dev = pdev;
43f66a6c 11743 ipw_debug_level = debug;
89c318ed 11744 spin_lock_init(&priv->irq_lock);
43f66a6c 11745 spin_lock_init(&priv->lock);
afbf30a2
JK
11746 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
11747 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
43f66a6c 11748
4644151b 11749 mutex_init(&priv->mutex);
43f66a6c
JK
11750 if (pci_enable_device(pdev)) {
11751 err = -ENODEV;
27ae60f8 11752 goto out_free_libipw;
43f66a6c
JK
11753 }
11754
11755 pci_set_master(pdev);
11756
284901a9 11757 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
bf79451e 11758 if (!err)
284901a9 11759 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
43f66a6c
JK
11760 if (err) {
11761 printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
11762 goto out_pci_disable_device;
11763 }
11764
11765 pci_set_drvdata(pdev, priv);
11766
11767 err = pci_request_regions(pdev, DRV_NAME);
bf79451e 11768 if (err)
43f66a6c
JK
11769 goto out_pci_disable_device;
11770
bf79451e 11771 /* We disable the RETRY_TIMEOUT register (0x41) to keep
43f66a6c 11772 * PCI Tx retries from interfering with C3 CPU state */
bf79451e
JG
11773 pci_read_config_dword(pdev, 0x40, &val);
11774 if ((val & 0x0000ff00) != 0)
43f66a6c 11775 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
bf79451e 11776
43f66a6c
JK
11777 length = pci_resource_len(pdev, 0);
11778 priv->hw_len = length;
bf79451e 11779
275f165f 11780 base = pci_ioremap_bar(pdev, 0);
43f66a6c
JK
11781 if (!base) {
11782 err = -ENODEV;
11783 goto out_pci_release_regions;
11784 }
11785
11786 priv->hw_base = base;
11787 IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);
11788 IPW_DEBUG_INFO("pci_resource_base = %p\n", base);
11789
11790 err = ipw_setup_deferred_work(priv);
11791 if (err) {
11792 IPW_ERROR("Unable to setup deferred work\n");
11793 goto out_iounmap;
11794 }
11795
b095c381 11796 ipw_sw_reset(priv, 1);
43f66a6c 11797
1fb9df5d 11798 err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv);
43f66a6c
JK
11799 if (err) {
11800 IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
bcb6d916 11801 goto out_iounmap;
43f66a6c
JK
11802 }
11803
43f66a6c
JK
11804 SET_NETDEV_DEV(net_dev, &pdev->dev);
11805
4644151b 11806 mutex_lock(&priv->mutex);
c848d0af 11807
43f66a6c
JK
11808 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
11809 priv->ieee->set_security = shim__set_security;
227d2dc1 11810 priv->ieee->is_queue_full = ipw_net_is_queue_full;
43f66a6c 11811
e43e3c1e 11812#ifdef CONFIG_IPW2200_QOS
a5cf4fe6 11813 priv->ieee->is_qos_active = ipw_is_qos_active;
3b9990cb
JK
11814 priv->ieee->handle_probe_response = ipw_handle_beacon;
11815 priv->ieee->handle_beacon = ipw_handle_probe_response;
11816 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
e43e3c1e 11817#endif /* CONFIG_IPW2200_QOS */
b095c381 11818
c848d0af
JK
11819 priv->ieee->perfect_rssi = -20;
11820 priv->ieee->worst_rssi = -85;
43f66a6c 11821
44e9ad0b 11822 net_dev->netdev_ops = &ipw_netdev_ops;
97a78ca9 11823 priv->wireless_data.spy_data = &priv->ieee->spy_data;
97a78ca9 11824 net_dev->wireless_data = &priv->wireless_data;
43f66a6c
JK
11825 net_dev->wireless_handlers = &ipw_wx_handler_def;
11826 net_dev->ethtool_ops = &ipw_ethtool_ops;
43f66a6c
JK
11827
11828 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
11829 if (err) {
11830 IPW_ERROR("failed to create sysfs device attributes\n");
4644151b 11831 mutex_unlock(&priv->mutex);
43f66a6c
JK
11832 goto out_release_irq;
11833 }
11834
7ed85b65
SY
11835 if (ipw_up(priv)) {
11836 mutex_unlock(&priv->mutex);
11837 err = -EIO;
11838 goto out_remove_sysfs;
11839 }
11840
4644151b 11841 mutex_unlock(&priv->mutex);
b4050790
BH
11842
11843 err = ipw_wdev_init(net_dev);
43f66a6c 11844 if (err) {
b4050790 11845 IPW_ERROR("failed to register wireless device\n");
a613bffd 11846 goto out_remove_sysfs;
43f66a6c 11847 }
48a84770 11848
b4050790 11849 err = register_netdev(net_dev);
7cabafce 11850 if (err) {
b4050790
BH
11851 IPW_ERROR("failed to register network device\n");
11852 goto out_unregister_wiphy;
7cabafce
SG
11853 }
11854
d685b8c2
ZY
11855#ifdef CONFIG_IPW2200_PROMISCUOUS
11856 if (rtap_iface) {
11857 err = ipw_prom_alloc(priv);
11858 if (err) {
11859 IPW_ERROR("Failed to register promiscuous network "
11860 "device (error %d).\n", err);
b4050790
BH
11861 unregister_netdev(priv->net_dev);
11862 goto out_unregister_wiphy;
d685b8c2
ZY
11863 }
11864 }
11865#endif
11866
48a84770
HBA
11867 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "
11868 "channels, %d 802.11a channels)\n",
11869 priv->ieee->geo.name, priv->ieee->geo.bg_channels,
11870 priv->ieee->geo.a_channels);
11871
43f66a6c
JK
11872 return 0;
11873
b4050790
BH
11874 out_unregister_wiphy:
11875 wiphy_unregister(priv->ieee->wdev.wiphy);
11876 kfree(priv->ieee->a_band.channels);
11877 kfree(priv->ieee->bg_band.channels);
a613bffd 11878 out_remove_sysfs:
43f66a6c 11879 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
0edd5b44 11880 out_release_irq:
43f66a6c 11881 free_irq(pdev->irq, priv);
0edd5b44 11882 out_iounmap:
43f66a6c 11883 iounmap(priv->hw_base);
0edd5b44 11884 out_pci_release_regions:
43f66a6c 11885 pci_release_regions(pdev);
0edd5b44 11886 out_pci_disable_device:
43f66a6c
JK
11887 pci_disable_device(pdev);
11888 pci_set_drvdata(pdev, NULL);
27ae60f8
PR
11889 out_free_libipw:
11890 free_libipw(priv->net_dev, 0);
0edd5b44 11891 out:
43f66a6c
JK
11892 return err;
11893}
11894
2ef19e63 11895static void __devexit ipw_pci_remove(struct pci_dev *pdev)
43f66a6c
JK
11896{
11897 struct ipw_priv *priv = pci_get_drvdata(pdev);
afbf30a2
JK
11898 struct list_head *p, *q;
11899 int i;
b095c381 11900
43f66a6c
JK
11901 if (!priv)
11902 return;
11903
4644151b 11904 mutex_lock(&priv->mutex);
43f66a6c 11905
afbf30a2 11906 priv->status |= STATUS_EXIT_PENDING;
43f66a6c 11907 ipw_down(priv);
43f66a6c
JK
11908 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
11909
4644151b 11910 mutex_unlock(&priv->mutex);
43f66a6c
JK
11911
11912 unregister_netdev(priv->net_dev);
11913
11914 if (priv->rxq) {
11915 ipw_rx_queue_free(priv, priv->rxq);
11916 priv->rxq = NULL;
11917 }
11918 ipw_tx_queue_free(priv);
11919
f6c5cb7c
JK
11920 if (priv->cmdlog) {
11921 kfree(priv->cmdlog);
11922 priv->cmdlog = NULL;
11923 }
bcb6d916
TH
11924
11925 /* make sure all works are inactive */
11926 cancel_delayed_work_sync(&priv->adhoc_check);
11927 cancel_work_sync(&priv->associate);
11928 cancel_work_sync(&priv->disassociate);
11929 cancel_work_sync(&priv->system_config);
11930 cancel_work_sync(&priv->rx_replenish);
11931 cancel_work_sync(&priv->adapter_restart);
11932 cancel_delayed_work_sync(&priv->rf_kill);
11933 cancel_work_sync(&priv->up);
11934 cancel_work_sync(&priv->down);
11935 cancel_delayed_work_sync(&priv->request_scan);
11936 cancel_delayed_work_sync(&priv->request_direct_scan);
11937 cancel_delayed_work_sync(&priv->request_passive_scan);
11938 cancel_delayed_work_sync(&priv->scan_event);
11939 cancel_delayed_work_sync(&priv->gather_stats);
11940 cancel_work_sync(&priv->abort_scan);
11941 cancel_work_sync(&priv->roam);
11942 cancel_delayed_work_sync(&priv->scan_check);
11943 cancel_work_sync(&priv->link_up);
11944 cancel_work_sync(&priv->link_down);
11945 cancel_delayed_work_sync(&priv->led_link_on);
11946 cancel_delayed_work_sync(&priv->led_link_off);
11947 cancel_delayed_work_sync(&priv->led_act_off);
11948 cancel_work_sync(&priv->merge_networks);
43f66a6c 11949
afbf30a2
JK
11950 /* Free MAC hash list for ADHOC */
11951 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
11952 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
afbf30a2 11953 list_del(p);
489f4458 11954 kfree(list_entry(p, struct ipw_ibss_seq, list));
afbf30a2
JK
11955 }
11956 }
11957
8f760780
JJ
11958 kfree(priv->error);
11959 priv->error = NULL;
43f66a6c 11960
d685b8c2
ZY
11961#ifdef CONFIG_IPW2200_PROMISCUOUS
11962 ipw_prom_free(priv);
11963#endif
11964
43f66a6c
JK
11965 free_irq(pdev->irq, priv);
11966 iounmap(priv->hw_base);
11967 pci_release_regions(pdev);
11968 pci_disable_device(pdev);
11969 pci_set_drvdata(pdev, NULL);
27ae60f8 11970 /* wiphy_unregister needs to be here, before free_libipw */
a3caa99e
JL
11971 wiphy_unregister(priv->ieee->wdev.wiphy);
11972 kfree(priv->ieee->a_band.channels);
11973 kfree(priv->ieee->bg_band.channels);
27ae60f8 11974 free_libipw(priv->net_dev, 0);
afbf30a2 11975 free_firmware();
43f66a6c
JK
11976}
11977
43f66a6c 11978#ifdef CONFIG_PM
583a4e88 11979static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
43f66a6c
JK
11980{
11981 struct ipw_priv *priv = pci_get_drvdata(pdev);
11982 struct net_device *dev = priv->net_dev;
11983
11984 printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
11985
0edd5b44 11986 /* Take down the device; powers it off, etc. */
43f66a6c
JK
11987 ipw_down(priv);
11988
11989 /* Remove the PRESENT state of the device */
11990 netif_device_detach(dev);
11991
43f66a6c 11992 pci_save_state(pdev);
43f66a6c 11993 pci_disable_device(pdev);
583a4e88 11994 pci_set_power_state(pdev, pci_choose_state(pdev, state));
bf79451e 11995
c3d72b96
DW
11996 priv->suspend_at = get_seconds();
11997
43f66a6c
JK
11998 return 0;
11999}
12000
12001static int ipw_pci_resume(struct pci_dev *pdev)
12002{
12003 struct ipw_priv *priv = pci_get_drvdata(pdev);
12004 struct net_device *dev = priv->net_dev;
02e0e5e9 12005 int err;
43f66a6c 12006 u32 val;
bf79451e 12007
43f66a6c
JK
12008 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
12009
ea2b26e0 12010 pci_set_power_state(pdev, PCI_D0);
02e0e5e9
JL
12011 err = pci_enable_device(pdev);
12012 if (err) {
12013 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
12014 dev->name);
12015 return err;
12016 }
43f66a6c 12017 pci_restore_state(pdev);
ea2b26e0 12018
43f66a6c
JK
12019 /*
12020 * Suspend/Resume resets the PCI configuration space, so we have to
12021 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
12022 * from interfering with C3 CPU state. pci_restore_state won't help
12023 * here since it only restores the first 64 bytes pci config header.
12024 */
bf79451e
JG
12025 pci_read_config_dword(pdev, 0x40, &val);
12026 if ((val & 0x0000ff00) != 0)
43f66a6c
JK
12027 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
12028
12029 /* Set the device back into the PRESENT state; this will also wake
12030 * the queue of needed */
12031 netif_device_attach(dev);
12032
c3d72b96
DW
12033 priv->suspend_time = get_seconds() - priv->suspend_at;
12034
43f66a6c 12035 /* Bring the device back up */
bcb6d916 12036 schedule_work(&priv->up);
bf79451e 12037
43f66a6c
JK
12038 return 0;
12039}
12040#endif
12041
c8c22c94
ZY
12042static void ipw_pci_shutdown(struct pci_dev *pdev)
12043{
12044 struct ipw_priv *priv = pci_get_drvdata(pdev);
12045
12046 /* Take down the device; powers it off, etc. */
12047 ipw_down(priv);
12048
12049 pci_disable_device(pdev);
12050}
12051
43f66a6c
JK
12052/* driver initialization stuff */
12053static struct pci_driver ipw_driver = {
12054 .name = DRV_NAME,
12055 .id_table = card_ids,
12056 .probe = ipw_pci_probe,
12057 .remove = __devexit_p(ipw_pci_remove),
12058#ifdef CONFIG_PM
12059 .suspend = ipw_pci_suspend,
12060 .resume = ipw_pci_resume,
12061#endif
c8c22c94 12062 .shutdown = ipw_pci_shutdown,
43f66a6c
JK
12063};
12064
12065static int __init ipw_init(void)
12066{
12067 int ret;
12068
12069 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
12070 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
12071
29917620 12072 ret = pci_register_driver(&ipw_driver);
43f66a6c
JK
12073 if (ret) {
12074 IPW_ERROR("Unable to initialize PCI module\n");
12075 return ret;
12076 }
12077
0edd5b44 12078 ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level);
43f66a6c
JK
12079 if (ret) {
12080 IPW_ERROR("Unable to create driver sysfs file\n");
12081 pci_unregister_driver(&ipw_driver);
12082 return ret;
12083 }
12084
12085 return ret;
12086}
12087
12088static void __exit ipw_exit(void)
12089{
12090 driver_remove_file(&ipw_driver.driver, &driver_attr_debug_level);
12091 pci_unregister_driver(&ipw_driver);
12092}
12093
12094module_param(disable, int, 0444);
12095MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
12096
12097module_param(associate, int, 0444);
5c7f9b73 12098MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");
43f66a6c
JK
12099
12100module_param(auto_create, int, 0444);
12101MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
12102
21f8a73f 12103module_param_named(led, led_support, int, 0444);
c086abae 12104MODULE_PARM_DESC(led, "enable led control on some systems (default 1 on)");
a613bffd 12105
43f66a6c
JK
12106module_param(debug, int, 0444);
12107MODULE_PARM_DESC(debug, "debug output mask");
12108
21f8a73f 12109module_param_named(channel, default_channel, int, 0444);
bf79451e 12110MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
43f66a6c 12111
d685b8c2
ZY
12112#ifdef CONFIG_IPW2200_PROMISCUOUS
12113module_param(rtap_iface, int, 0444);
12114MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)");
12115#endif
12116
e43e3c1e 12117#ifdef CONFIG_IPW2200_QOS
b095c381
JK
12118module_param(qos_enable, int, 0444);
12119MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
12120
12121module_param(qos_burst_enable, int, 0444);
12122MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
12123
12124module_param(qos_no_ack_mask, int, 0444);
12125MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
43f66a6c 12126
b095c381
JK
12127module_param(burst_duration_CCK, int, 0444);
12128MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
12129
12130module_param(burst_duration_OFDM, int, 0444);
12131MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
e43e3c1e 12132#endif /* CONFIG_IPW2200_QOS */
b095c381
JK
12133
12134#ifdef CONFIG_IPW2200_MONITOR
21f8a73f 12135module_param_named(mode, network_mode, int, 0444);
43f66a6c
JK
12136MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
12137#else
21f8a73f 12138module_param_named(mode, network_mode, int, 0444);
43f66a6c
JK
12139MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
12140#endif
12141
810dabd4
ZY
12142module_param(bt_coexist, int, 0444);
12143MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)");
12144
b095c381 12145module_param(hwcrypto, int, 0444);
bde37d03 12146MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)");
b095c381 12147
f6c5cb7c
JK
12148module_param(cmdlog, int, 0444);
12149MODULE_PARM_DESC(cmdlog,
12150 "allocate a ring buffer for logging firmware commands");
12151
4bfdb91d
ZY
12152module_param(roaming, int, 0444);
12153MODULE_PARM_DESC(roaming, "enable roaming support (default on)");
12154
d2b83e12
ZY
12155module_param(antenna, int, 0444);
12156MODULE_PARM_DESC(antenna, "select antenna 1=Main, 3=Aux, default 0 [both], 2=slow_diversity (choose the one with lower background noise)");
12157
43f66a6c
JK
12158module_exit(ipw_exit);
12159module_init(ipw_init);