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