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