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