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