]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/net/wireless/ipw2200.c
Catch ipw2200 up to equivelancy with v1.0.3
[mirror_ubuntu-zesty-kernel.git] / drivers / net / wireless / ipw2200.c
CommitLineData
43f66a6c 1/******************************************************************************
bf79451e 2
43f66a6c
JK
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
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"
34
c848d0af 35#define IPW2200_VERSION "1.0.3"
43f66a6c
JK
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION
39
40MODULE_DESCRIPTION(DRV_DESCRIPTION);
41MODULE_VERSION(DRV_VERSION);
42MODULE_AUTHOR(DRV_COPYRIGHT);
43MODULE_LICENSE("GPL");
44
45static int debug = 0;
46static int channel = 0;
43f66a6c
JK
47static int mode = 0;
48
49static u32 ipw_debug_level;
50static int associate = 1;
51static int auto_create = 1;
a613bffd 52static int led = 0;
43f66a6c
JK
53static int disable = 0;
54static const char ipw_modes[] = {
55 'a', 'b', 'g', '?'
56};
57
58static void ipw_rx(struct ipw_priv *priv);
bf79451e 59static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
60 struct clx2_tx_queue *txq, int qindex);
61static int ipw_queue_reset(struct ipw_priv *priv);
62
63static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
64 int len, int sync);
65
66static void ipw_tx_queue_free(struct ipw_priv *);
67
68static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
69static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
70static void ipw_rx_queue_replenish(void *);
43f66a6c 71static int ipw_up(struct ipw_priv *);
c848d0af 72static void ipw_bg_up(void *);
43f66a6c 73static void ipw_down(struct ipw_priv *);
c848d0af 74static void ipw_bg_down(void *);
43f66a6c 75static int ipw_config(struct ipw_priv *);
0edd5b44
JG
76static int init_supported_rates(struct ipw_priv *priv,
77 struct ipw_supported_rates *prates);
43f66a6c
JK
78
79static u8 band_b_active_channel[MAX_B_CHANNELS] = {
80 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0
81};
82static u8 band_a_active_channel[MAX_A_CHANNELS] = {
83 36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0
84};
85
86static int is_valid_channel(int mode_mask, int channel)
87{
88 int i;
89
90 if (!channel)
91 return 0;
92
93 if (mode_mask & IEEE_A)
94 for (i = 0; i < MAX_A_CHANNELS; i++)
95 if (band_a_active_channel[i] == channel)
96 return IEEE_A;
97
98 if (mode_mask & (IEEE_B | IEEE_G))
99 for (i = 0; i < MAX_B_CHANNELS; i++)
100 if (band_b_active_channel[i] == channel)
101 return mode_mask & (IEEE_B | IEEE_G);
102
103 return 0;
104}
105
bf79451e 106static char *snprint_line(char *buf, size_t count,
0edd5b44 107 const u8 * data, u32 len, u32 ofs)
43f66a6c
JK
108{
109 int out, i, j, l;
110 char c;
bf79451e 111
43f66a6c
JK
112 out = snprintf(buf, count, "%08X", ofs);
113
114 for (l = 0, i = 0; i < 2; i++) {
115 out += snprintf(buf + out, count - out, " ");
bf79451e
JG
116 for (j = 0; j < 8 && l < len; j++, l++)
117 out += snprintf(buf + out, count - out, "%02X ",
43f66a6c
JK
118 data[(i * 8 + j)]);
119 for (; j < 8; j++)
120 out += snprintf(buf + out, count - out, " ");
121 }
bf79451e 122
43f66a6c
JK
123 out += snprintf(buf + out, count - out, " ");
124 for (l = 0, i = 0; i < 2; i++) {
125 out += snprintf(buf + out, count - out, " ");
126 for (j = 0; j < 8 && l < len; j++, l++) {
127 c = data[(i * 8 + j)];
128 if (!isascii(c) || !isprint(c))
129 c = '.';
bf79451e 130
43f66a6c
JK
131 out += snprintf(buf + out, count - out, "%c", c);
132 }
133
134 for (; j < 8; j++)
135 out += snprintf(buf + out, count - out, " ");
136 }
bf79451e 137
43f66a6c
JK
138 return buf;
139}
140
0edd5b44 141static void printk_buf(int level, const u8 * data, u32 len)
43f66a6c
JK
142{
143 char line[81];
144 u32 ofs = 0;
145 if (!(ipw_debug_level & level))
146 return;
147
148 while (len) {
149 printk(KERN_DEBUG "%s\n",
bf79451e 150 snprint_line(line, sizeof(line), &data[ofs],
43f66a6c
JK
151 min(len, 16U), ofs));
152 ofs += 16;
153 len -= min(len, 16U);
154 }
155}
156
157static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
158#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
159
160static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
161#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
162
163static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
164static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
165{
0edd5b44
JG
166 IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__,
167 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
168 _ipw_write_reg8(a, b, c);
169}
170
171static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
172static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
173{
0edd5b44
JG
174 IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__,
175 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
176 _ipw_write_reg16(a, b, c);
177}
178
179static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
180static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
181{
0edd5b44
JG
182 IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__,
183 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
184 _ipw_write_reg32(a, b, c);
185}
186
187#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
188#define ipw_write8(ipw, ofs, val) \
189 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
190 _ipw_write8(ipw, ofs, val)
191
192#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
193#define ipw_write16(ipw, ofs, val) \
194 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
195 _ipw_write16(ipw, ofs, val)
196
197#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
198#define ipw_write32(ipw, ofs, val) \
199 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
200 _ipw_write32(ipw, ofs, val)
201
202#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
0edd5b44
JG
203static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
204{
205 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
206 return _ipw_read8(ipw, ofs);
207}
0edd5b44 208
43f66a6c
JK
209#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
210
211#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
0edd5b44
JG
212static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
213{
214 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
215 return _ipw_read16(ipw, ofs);
216}
0edd5b44 217
43f66a6c
JK
218#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
219
220#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
0edd5b44
JG
221static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
222{
223 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
224 return _ipw_read32(ipw, ofs);
225}
0edd5b44 226
43f66a6c
JK
227#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
228
229static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
230#define ipw_read_indirect(a, b, c, d) \
231 IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
232 _ipw_read_indirect(a, b, c, d)
233
0edd5b44
JG
234static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
235 int num);
43f66a6c
JK
236#define ipw_write_indirect(a, b, c, d) \
237 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
238 _ipw_write_indirect(a, b, c, d)
239
240/* indirect write s */
0edd5b44 241static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
43f66a6c 242{
0edd5b44 243 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
43f66a6c
JK
244 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg);
245 _ipw_write32(priv, CX2_INDIRECT_DATA, value);
246}
247
43f66a6c
JK
248static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
249{
250 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
251 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
252 _ipw_write8(priv, CX2_INDIRECT_DATA, value);
bf79451e 253 IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
0edd5b44 254 (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value);
43f66a6c
JK
255}
256
0edd5b44 257static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
43f66a6c
JK
258{
259 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
260 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
261 _ipw_write16(priv, CX2_INDIRECT_DATA, value);
262}
263
264/* indirect read s */
265
266static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
267{
268 u32 word;
269 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
270 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
271 word = _ipw_read32(priv, CX2_INDIRECT_DATA);
0edd5b44 272 return (word >> ((reg & 0x3) * 8)) & 0xff;
43f66a6c
JK
273}
274
275static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
276{
277 u32 value;
278
279 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
280
281 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg);
282 value = _ipw_read32(priv, CX2_INDIRECT_DATA);
283 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
284 return value;
285}
286
287/* iterative/auto-increment 32 bit reads and writes */
288static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
289 int num)
290{
291 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
292 u32 dif_len = addr - aligned_addr;
43f66a6c 293 u32 i;
bf79451e 294
43f66a6c
JK
295 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
296
ea2b26e0
JK
297 if (num <= 0) {
298 return;
299 }
300
43f66a6c
JK
301 /* Read the first nibble byte by byte */
302 if (unlikely(dif_len)) {
43f66a6c 303 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
ea2b26e0
JK
304 /* Start reading at aligned_addr + dif_len */
305 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
306 *buf++ = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
43f66a6c
JK
307 aligned_addr += 4;
308 }
309
43f66a6c 310 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
ea2b26e0
JK
311 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
312 *(u32 *) buf = _ipw_read32(priv, CX2_AUTOINC_DATA);
bf79451e 313
43f66a6c 314 /* Copy the last nibble */
ea2b26e0
JK
315 if (unlikely(num)) {
316 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
317 for (i = 0; num > 0; i++, num--)
318 *buf++ = ipw_read8(priv, CX2_INDIRECT_DATA + i);
319 }
43f66a6c
JK
320}
321
0edd5b44 322static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
43f66a6c
JK
323 int num)
324{
325 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
326 u32 dif_len = addr - aligned_addr;
43f66a6c 327 u32 i;
bf79451e 328
43f66a6c 329 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
bf79451e 330
ea2b26e0
JK
331 if (num <= 0) {
332 return;
333 }
334
43f66a6c
JK
335 /* Write the first nibble byte by byte */
336 if (unlikely(dif_len)) {
43f66a6c 337 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
ea2b26e0
JK
338 /* Start reading at aligned_addr + dif_len */
339 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
43f66a6c 340 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
43f66a6c
JK
341 aligned_addr += 4;
342 }
bf79451e 343
43f66a6c 344 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
ea2b26e0 345 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
0edd5b44 346 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
bf79451e 347
43f66a6c 348 /* Copy the last nibble */
ea2b26e0
JK
349 if (unlikely(num)) {
350 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
351 for (i = 0; num > 0; i++, num--, buf++)
352 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
353 }
43f66a6c
JK
354}
355
bf79451e 356static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
43f66a6c
JK
357 int num)
358{
359 memcpy_toio((priv->hw_base + addr), buf, num);
360}
361
362static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
363{
364 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
365}
366
367static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
368{
369 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
370}
371
372static inline void ipw_enable_interrupts(struct ipw_priv *priv)
373{
374 if (priv->status & STATUS_INT_ENABLED)
375 return;
376 priv->status |= STATUS_INT_ENABLED;
377 ipw_write32(priv, CX2_INTA_MASK_R, CX2_INTA_MASK_ALL);
378}
379
380static inline void ipw_disable_interrupts(struct ipw_priv *priv)
381{
382 if (!(priv->status & STATUS_INT_ENABLED))
383 return;
384 priv->status &= ~STATUS_INT_ENABLED;
385 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
386}
387
388static char *ipw_error_desc(u32 val)
389{
390 switch (val) {
bf79451e 391 case IPW_FW_ERROR_OK:
43f66a6c 392 return "ERROR_OK";
bf79451e 393 case IPW_FW_ERROR_FAIL:
43f66a6c 394 return "ERROR_FAIL";
bf79451e 395 case IPW_FW_ERROR_MEMORY_UNDERFLOW:
43f66a6c 396 return "MEMORY_UNDERFLOW";
bf79451e 397 case IPW_FW_ERROR_MEMORY_OVERFLOW:
43f66a6c 398 return "MEMORY_OVERFLOW";
bf79451e 399 case IPW_FW_ERROR_BAD_PARAM:
43f66a6c 400 return "ERROR_BAD_PARAM";
bf79451e 401 case IPW_FW_ERROR_BAD_CHECKSUM:
43f66a6c 402 return "ERROR_BAD_CHECKSUM";
bf79451e 403 case IPW_FW_ERROR_NMI_INTERRUPT:
43f66a6c 404 return "ERROR_NMI_INTERRUPT";
bf79451e 405 case IPW_FW_ERROR_BAD_DATABASE:
43f66a6c 406 return "ERROR_BAD_DATABASE";
bf79451e 407 case IPW_FW_ERROR_ALLOC_FAIL:
43f66a6c 408 return "ERROR_ALLOC_FAIL";
bf79451e 409 case IPW_FW_ERROR_DMA_UNDERRUN:
43f66a6c 410 return "ERROR_DMA_UNDERRUN";
bf79451e 411 case IPW_FW_ERROR_DMA_STATUS:
43f66a6c 412 return "ERROR_DMA_STATUS";
bf79451e 413 case IPW_FW_ERROR_DINOSTATUS_ERROR:
43f66a6c 414 return "ERROR_DINOSTATUS_ERROR";
bf79451e 415 case IPW_FW_ERROR_EEPROMSTATUS_ERROR:
43f66a6c 416 return "ERROR_EEPROMSTATUS_ERROR";
bf79451e 417 case IPW_FW_ERROR_SYSASSERT:
43f66a6c 418 return "ERROR_SYSASSERT";
bf79451e 419 case IPW_FW_ERROR_FATAL_ERROR:
43f66a6c 420 return "ERROR_FATALSTATUS_ERROR";
bf79451e 421 default:
43f66a6c
JK
422 return "UNKNOWNSTATUS_ERROR";
423 }
424}
425
426static void ipw_dump_nic_error_log(struct ipw_priv *priv)
427{
428 u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base;
429
430 base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
431 count = ipw_read_reg32(priv, base);
bf79451e 432
43f66a6c
JK
433 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
434 IPW_ERROR("Start IPW Error Log Dump:\n");
435 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
436 priv->status, priv->config);
437 }
438
bf79451e 439 for (i = ERROR_START_OFFSET;
0edd5b44
JG
440 i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) {
441 desc = ipw_read_reg32(priv, base + i);
442 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
443 blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
444 blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
445 ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
446 ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
447 idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
43f66a6c 448
0edd5b44
JG
449 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
450 ipw_error_desc(desc), time, blink1, blink2,
451 ilink1, ilink2, idata);
43f66a6c
JK
452 }
453}
454
455static void ipw_dump_nic_event_log(struct ipw_priv *priv)
456{
457 u32 ev, time, data, i, count, base;
458
459 base = ipw_read32(priv, IPW_EVENT_LOG);
460 count = ipw_read_reg32(priv, base);
bf79451e 461
43f66a6c
JK
462 if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
463 IPW_ERROR("Start IPW Event Log Dump:\n");
464
bf79451e 465 for (i = EVENT_START_OFFSET;
0edd5b44 466 i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
43f66a6c 467 ev = ipw_read_reg32(priv, base + i);
0edd5b44
JG
468 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
469 data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
43f66a6c
JK
470
471#ifdef CONFIG_IPW_DEBUG
472 IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
473#endif
474 }
475}
476
c848d0af
JK
477static inline int ipw_is_init(struct ipw_priv *priv)
478{
479 return (priv->status & STATUS_INIT) ? 1 : 0;
480}
481
0edd5b44 482static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
43f66a6c
JK
483{
484 u32 addr, field_info, field_len, field_count, total_len;
485
486 IPW_DEBUG_ORD("ordinal = %i\n", ord);
487
488 if (!priv || !val || !len) {
489 IPW_DEBUG_ORD("Invalid argument\n");
490 return -EINVAL;
491 }
bf79451e 492
43f66a6c
JK
493 /* verify device ordinal tables have been initialized */
494 if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {
495 IPW_DEBUG_ORD("Access ordinals before initialization\n");
496 return -EINVAL;
497 }
498
499 switch (IPW_ORD_TABLE_ID_MASK & ord) {
500 case IPW_ORD_TABLE_0_MASK:
501 /*
502 * TABLE 0: Direct access to a table of 32 bit values
503 *
bf79451e 504 * This is a very simple table with the data directly
43f66a6c
JK
505 * read from the table
506 */
507
508 /* remove the table id from the ordinal */
509 ord &= IPW_ORD_TABLE_VALUE_MASK;
510
511 /* boundary check */
512 if (ord > priv->table0_len) {
513 IPW_DEBUG_ORD("ordinal value (%i) longer then "
514 "max (%i)\n", ord, priv->table0_len);
515 return -EINVAL;
516 }
517
518 /* verify we have enough room to store the value */
519 if (*len < sizeof(u32)) {
520 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 521 "need %zd\n", sizeof(u32));
43f66a6c
JK
522 return -EINVAL;
523 }
524
525 IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",
0edd5b44 526 ord, priv->table0_addr + (ord << 2));
43f66a6c
JK
527
528 *len = sizeof(u32);
529 ord <<= 2;
0edd5b44 530 *((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord);
43f66a6c
JK
531 break;
532
533 case IPW_ORD_TABLE_1_MASK:
534 /*
535 * TABLE 1: Indirect access to a table of 32 bit values
bf79451e
JG
536 *
537 * This is a fairly large table of u32 values each
43f66a6c
JK
538 * representing starting addr for the data (which is
539 * also a u32)
540 */
541
542 /* remove the table id from the ordinal */
543 ord &= IPW_ORD_TABLE_VALUE_MASK;
bf79451e 544
43f66a6c
JK
545 /* boundary check */
546 if (ord > priv->table1_len) {
547 IPW_DEBUG_ORD("ordinal value too long\n");
548 return -EINVAL;
549 }
550
551 /* verify we have enough room to store the value */
552 if (*len < sizeof(u32)) {
553 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 554 "need %zd\n", sizeof(u32));
43f66a6c
JK
555 return -EINVAL;
556 }
557
0edd5b44
JG
558 *((u32 *) val) =
559 ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));
43f66a6c
JK
560 *len = sizeof(u32);
561 break;
562
563 case IPW_ORD_TABLE_2_MASK:
564 /*
565 * TABLE 2: Indirect access to a table of variable sized values
566 *
567 * This table consist of six values, each containing
568 * - dword containing the starting offset of the data
569 * - dword containing the lengh in the first 16bits
570 * and the count in the second 16bits
571 */
572
573 /* remove the table id from the ordinal */
574 ord &= IPW_ORD_TABLE_VALUE_MASK;
575
576 /* boundary check */
577 if (ord > priv->table2_len) {
578 IPW_DEBUG_ORD("ordinal value too long\n");
579 return -EINVAL;
580 }
581
582 /* get the address of statistic */
583 addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));
bf79451e
JG
584
585 /* get the second DW of statistics ;
43f66a6c 586 * two 16-bit words - first is length, second is count */
0edd5b44
JG
587 field_info =
588 ipw_read_reg32(priv,
589 priv->table2_addr + (ord << 3) +
590 sizeof(u32));
bf79451e 591
43f66a6c 592 /* get each entry length */
0edd5b44 593 field_len = *((u16 *) & field_info);
bf79451e 594
43f66a6c 595 /* get number of entries */
0edd5b44 596 field_count = *(((u16 *) & field_info) + 1);
bf79451e 597
43f66a6c
JK
598 /* abort if not enought memory */
599 total_len = field_len * field_count;
600 if (total_len > *len) {
601 *len = total_len;
602 return -EINVAL;
603 }
bf79451e 604
43f66a6c
JK
605 *len = total_len;
606 if (!total_len)
607 return 0;
608
609 IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "
bf79451e 610 "field_info = 0x%08x\n",
43f66a6c
JK
611 addr, total_len, field_info);
612 ipw_read_indirect(priv, addr, val, total_len);
613 break;
614
615 default:
616 IPW_DEBUG_ORD("Invalid ordinal!\n");
617 return -EINVAL;
618
619 }
620
43f66a6c
JK
621 return 0;
622}
623
624static void ipw_init_ordinals(struct ipw_priv *priv)
625{
626 priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;
bf79451e 627 priv->table0_len = ipw_read32(priv, priv->table0_addr);
43f66a6c
JK
628
629 IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",
630 priv->table0_addr, priv->table0_len);
631
632 priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);
633 priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);
634
635 IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",
636 priv->table1_addr, priv->table1_len);
637
638 priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);
639 priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);
0edd5b44 640 priv->table2_len &= 0x0000ffff; /* use first two bytes */
43f66a6c
JK
641
642 IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",
643 priv->table2_addr, priv->table2_len);
644
645}
646
a613bffd
JK
647u32 ipw_register_toggle(u32 reg)
648{
649 reg &= ~CX2_START_STANDBY;
650 if (reg & CX2_GATE_ODMA)
651 reg &= ~CX2_GATE_ODMA;
652 if (reg & CX2_GATE_IDMA)
653 reg &= ~CX2_GATE_IDMA;
654 if (reg & CX2_GATE_ADMA)
655 reg &= ~CX2_GATE_ADMA;
656 return reg;
657}
658
659/*
660 * LED behavior:
661 * - On radio ON, turn on any LEDs that require to be on during start
662 * - On initialization, start unassociated blink
663 * - On association, disable unassociated blink
664 * - On disassociation, start unassociated blink
665 * - On radio OFF, turn off any LEDs started during radio on
666 *
667 */
668#define LD_TIME_LINK_ON 300
669#define LD_TIME_LINK_OFF 2700
670#define LD_TIME_ACT_ON 250
671
672void ipw_led_link_on(struct ipw_priv *priv)
673{
674 unsigned long flags;
675 u32 led;
676
677 /* If configured to not use LEDs, or nic_type is 1,
678 * then we don't toggle a LINK led */
679 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
680 return;
681
682 spin_lock_irqsave(&priv->lock, flags);
683
684 if (!(priv->status & STATUS_RF_KILL_MASK) &&
685 !(priv->status & STATUS_LED_LINK_ON)) {
686 IPW_DEBUG_LED("Link LED On\n");
687 led = ipw_read_reg32(priv, CX2_EVENT_REG);
688 led |= priv->led_association_on;
689
690 led = ipw_register_toggle(led);
691
692 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
693 ipw_write_reg32(priv, CX2_EVENT_REG, led);
694
695 priv->status |= STATUS_LED_LINK_ON;
696
697 /* If we aren't associated, schedule turning the LED off */
698 if (!(priv->status & STATUS_ASSOCIATED))
699 queue_delayed_work(priv->workqueue,
700 &priv->led_link_off,
701 LD_TIME_LINK_ON);
702 }
703
704 spin_unlock_irqrestore(&priv->lock, flags);
705}
706
c848d0af
JK
707static void ipw_bg_led_link_on(void *data)
708{
709 struct ipw_priv *priv = data;
710 down(&priv->sem);
711 ipw_led_link_on(data);
712 up(&priv->sem);
713}
714
a613bffd
JK
715void ipw_led_link_off(struct ipw_priv *priv)
716{
717 unsigned long flags;
718 u32 led;
719
720 /* If configured not to use LEDs, or nic type is 1,
721 * then we don't goggle the LINK led. */
722 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
723 return;
724
725 spin_lock_irqsave(&priv->lock, flags);
726
727 if (priv->status & STATUS_LED_LINK_ON) {
728 led = ipw_read_reg32(priv, CX2_EVENT_REG);
729 led &= priv->led_association_off;
730 led = ipw_register_toggle(led);
731
732 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
733 ipw_write_reg32(priv, CX2_EVENT_REG, led);
734
735 IPW_DEBUG_LED("Link LED Off\n");
736
737 priv->status &= ~STATUS_LED_LINK_ON;
738
739 /* If we aren't associated and the radio is on, schedule
740 * turning the LED on (blink while unassociated) */
741 if (!(priv->status & STATUS_RF_KILL_MASK) &&
742 !(priv->status & STATUS_ASSOCIATED))
743 queue_delayed_work(priv->workqueue, &priv->led_link_on,
744 LD_TIME_LINK_OFF);
745
746 }
747
748 spin_unlock_irqrestore(&priv->lock, flags);
749}
750
c848d0af
JK
751static void ipw_bg_led_link_off(void *data)
752{
753 struct ipw_priv *priv = data;
754 down(&priv->sem);
755 ipw_led_link_off(data);
756 up(&priv->sem);
757}
758
a613bffd
JK
759void ipw_led_activity_on(struct ipw_priv *priv)
760{
761 unsigned long flags;
762 u32 led;
763
764 if (priv->config & CFG_NO_LED)
765 return;
766
767 spin_lock_irqsave(&priv->lock, flags);
768
769 if (priv->status & STATUS_RF_KILL_MASK) {
770 spin_unlock_irqrestore(&priv->lock, flags);
771 return;
772 }
773
774 if (!(priv->status & STATUS_LED_ACT_ON)) {
775 led = ipw_read_reg32(priv, CX2_EVENT_REG);
776 led |= priv->led_activity_on;
777
778 led = ipw_register_toggle(led);
779
780 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
781 ipw_write_reg32(priv, CX2_EVENT_REG, led);
782
783 IPW_DEBUG_LED("Activity LED On\n");
784
785 priv->status |= STATUS_LED_ACT_ON;
786
c848d0af 787 cancel_delayed_work(&priv->led_act_off);
a613bffd
JK
788 queue_delayed_work(priv->workqueue, &priv->led_act_off,
789 LD_TIME_ACT_ON);
790 } else {
791 /* Reschedule LED off for full time period */
792 cancel_delayed_work(&priv->led_act_off);
793 queue_delayed_work(priv->workqueue, &priv->led_act_off,
794 LD_TIME_ACT_ON);
795 }
796
797 spin_unlock_irqrestore(&priv->lock, flags);
798}
799
800void ipw_led_activity_off(struct ipw_priv *priv)
801{
802 unsigned long flags;
803 u32 led;
804
805 if (priv->config & CFG_NO_LED)
806 return;
807
808 spin_lock_irqsave(&priv->lock, flags);
809
810 if (priv->status & STATUS_LED_ACT_ON) {
811 led = ipw_read_reg32(priv, CX2_EVENT_REG);
812 led &= priv->led_activity_off;
813
814 led = ipw_register_toggle(led);
815
816 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
817 ipw_write_reg32(priv, CX2_EVENT_REG, led);
818
819 IPW_DEBUG_LED("Activity LED Off\n");
820
821 priv->status &= ~STATUS_LED_ACT_ON;
822 }
823
824 spin_unlock_irqrestore(&priv->lock, flags);
825}
826
c848d0af
JK
827static void ipw_bg_led_activity_off(void *data)
828{
829 struct ipw_priv *priv = data;
830 down(&priv->sem);
831 ipw_led_activity_off(data);
832 up(&priv->sem);
833}
834
a613bffd
JK
835void ipw_led_band_on(struct ipw_priv *priv)
836{
837 unsigned long flags;
838 u32 led;
839
840 /* Only nic type 1 supports mode LEDs */
c848d0af
JK
841 if (priv->config & CFG_NO_LED ||
842 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
a613bffd
JK
843 return;
844
845 spin_lock_irqsave(&priv->lock, flags);
846
847 led = ipw_read_reg32(priv, CX2_EVENT_REG);
848 if (priv->assoc_network->mode == IEEE_A) {
849 led |= priv->led_ofdm_on;
850 led &= priv->led_association_off;
851 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
852 } else if (priv->assoc_network->mode == IEEE_G) {
853 led |= priv->led_ofdm_on;
854 led |= priv->led_association_on;
855 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
856 } else {
857 led &= priv->led_ofdm_off;
858 led |= priv->led_association_on;
859 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
860 }
861
862 led = ipw_register_toggle(led);
863
864 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
865 ipw_write_reg32(priv, CX2_EVENT_REG, led);
866
867 spin_unlock_irqrestore(&priv->lock, flags);
868}
869
870void ipw_led_band_off(struct ipw_priv *priv)
871{
872 unsigned long flags;
873 u32 led;
874
875 /* Only nic type 1 supports mode LEDs */
876 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
877 return;
878
879 spin_lock_irqsave(&priv->lock, flags);
880
881 led = ipw_read_reg32(priv, CX2_EVENT_REG);
882 led &= priv->led_ofdm_off;
883 led &= priv->led_association_off;
884
885 led = ipw_register_toggle(led);
886
887 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
888 ipw_write_reg32(priv, CX2_EVENT_REG, led);
889
890 spin_unlock_irqrestore(&priv->lock, flags);
891}
892
893void ipw_led_radio_on(struct ipw_priv *priv)
894{
895 ipw_led_link_on(priv);
896}
897
898void ipw_led_radio_off(struct ipw_priv *priv)
899{
900 ipw_led_activity_off(priv);
901 ipw_led_link_off(priv);
902}
903
904void ipw_led_link_up(struct ipw_priv *priv)
905{
906 /* Set the Link Led on for all nic types */
907 ipw_led_link_on(priv);
908}
909
910void ipw_led_link_down(struct ipw_priv *priv)
911{
912 ipw_led_activity_off(priv);
913 ipw_led_link_off(priv);
914
915 if (priv->status & STATUS_RF_KILL_MASK)
916 ipw_led_radio_off(priv);
917}
918
919void ipw_led_init(struct ipw_priv *priv)
920{
921 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
922
923 /* Set the default PINs for the link and activity leds */
924 priv->led_activity_on = CX2_ACTIVITY_LED;
925 priv->led_activity_off = ~(CX2_ACTIVITY_LED);
926
927 priv->led_association_on = CX2_ASSOCIATED_LED;
928 priv->led_association_off = ~(CX2_ASSOCIATED_LED);
929
930 /* Set the default PINs for the OFDM leds */
931 priv->led_ofdm_on = CX2_OFDM_LED;
932 priv->led_ofdm_off = ~(CX2_OFDM_LED);
933
934 switch (priv->nic_type) {
935 case EEPROM_NIC_TYPE_1:
936 /* In this NIC type, the LEDs are reversed.... */
937 priv->led_activity_on = CX2_ASSOCIATED_LED;
938 priv->led_activity_off = ~(CX2_ASSOCIATED_LED);
939 priv->led_association_on = CX2_ACTIVITY_LED;
940 priv->led_association_off = ~(CX2_ACTIVITY_LED);
941
942 if (!(priv->config & CFG_NO_LED))
943 ipw_led_band_on(priv);
944
945 /* And we don't blink link LEDs for this nic, so
946 * just return here */
947 return;
948
949 case EEPROM_NIC_TYPE_3:
950 case EEPROM_NIC_TYPE_2:
951 case EEPROM_NIC_TYPE_4:
952 case EEPROM_NIC_TYPE_0:
953 break;
954
955 default:
956 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
957 priv->nic_type);
958 priv->nic_type = EEPROM_NIC_TYPE_0;
959 break;
960 }
961
962 if (!(priv->config & CFG_NO_LED)) {
963 if (priv->status & STATUS_ASSOCIATED)
964 ipw_led_link_on(priv);
965 else
966 ipw_led_link_off(priv);
967 }
968}
969
970void ipw_led_shutdown(struct ipw_priv *priv)
971{
972 cancel_delayed_work(&priv->led_link_on);
973 cancel_delayed_work(&priv->led_link_off);
974 cancel_delayed_work(&priv->led_act_off);
975 ipw_led_activity_off(priv);
976 ipw_led_link_off(priv);
977 ipw_led_band_off(priv);
978}
979
43f66a6c
JK
980/*
981 * The following adds a new attribute to the sysfs representation
982 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
983 * used for controling the debug level.
bf79451e 984 *
43f66a6c
JK
985 * See the level definitions in ipw for details.
986 */
987static ssize_t show_debug_level(struct device_driver *d, char *buf)
988{
989 return sprintf(buf, "0x%08X\n", ipw_debug_level);
990}
a613bffd
JK
991
992static ssize_t store_debug_level(struct device_driver *d, const char *buf,
993 size_t count)
43f66a6c
JK
994{
995 char *p = (char *)buf;
996 u32 val;
997
998 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
999 p++;
1000 if (p[0] == 'x' || p[0] == 'X')
1001 p++;
1002 val = simple_strtoul(p, &p, 16);
1003 } else
1004 val = simple_strtoul(p, &p, 10);
bf79451e
JG
1005 if (p == buf)
1006 printk(KERN_INFO DRV_NAME
43f66a6c
JK
1007 ": %s is not in hex or decimal form.\n", buf);
1008 else
1009 ipw_debug_level = val;
1010
1011 return strnlen(buf, count);
1012}
1013
bf79451e 1014static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
43f66a6c
JK
1015 show_debug_level, store_debug_level);
1016
a613bffd
JK
1017static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
1018 char *buf)
1019{
1020 struct ipw_priv *priv = dev_get_drvdata(d);
1021 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1022}
1023
1024static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
1025 const char *buf, size_t count)
1026{
1027 struct ipw_priv *priv = dev_get_drvdata(d);
c848d0af 1028#ifdef CONFIG_IPW_DEBUG
a613bffd 1029 struct net_device *dev = priv->net_dev;
c848d0af 1030#endif
a613bffd
JK
1031 char buffer[] = "00000000";
1032 unsigned long len =
1033 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1034 unsigned long val;
1035 char *p = buffer;
1036
1037 IPW_DEBUG_INFO("enter\n");
1038
1039 strncpy(buffer, buf, len);
1040 buffer[len] = 0;
1041
1042 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1043 p++;
1044 if (p[0] == 'x' || p[0] == 'X')
1045 p++;
1046 val = simple_strtoul(p, &p, 16);
1047 } else
1048 val = simple_strtoul(p, &p, 10);
1049 if (p == buffer) {
1050 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1051 } else {
1052 priv->ieee->scan_age = val;
1053 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1054 }
1055
1056 IPW_DEBUG_INFO("exit\n");
1057 return len;
1058}
1059
1060static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
1061
1062static ssize_t show_led(struct device *d, struct device_attribute *attr,
1063 char *buf)
1064{
1065 struct ipw_priv *priv = dev_get_drvdata(d);
1066 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1067}
1068
1069static ssize_t store_led(struct device *d, struct device_attribute *attr,
1070 const char *buf, size_t count)
1071{
1072 struct ipw_priv *priv = dev_get_drvdata(d);
1073
1074 IPW_DEBUG_INFO("enter\n");
1075
1076 if (count == 0)
1077 return 0;
1078
1079 if (*buf == 0) {
1080 IPW_DEBUG_LED("Disabling LED control.\n");
1081 priv->config |= CFG_NO_LED;
1082 ipw_led_shutdown(priv);
1083 } else {
1084 IPW_DEBUG_LED("Enabling LED control.\n");
1085 priv->config &= ~CFG_NO_LED;
1086 ipw_led_init(priv);
1087 }
1088
1089 IPW_DEBUG_INFO("exit\n");
1090 return count;
1091}
1092
1093static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1094
ad3fee56 1095static ssize_t show_status(struct device *d,
0edd5b44 1096 struct device_attribute *attr, char *buf)
43f66a6c 1097{
ad3fee56 1098 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1099 return sprintf(buf, "0x%08x\n", (int)p->status);
1100}
0edd5b44 1101
43f66a6c
JK
1102static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1103
ad3fee56
AM
1104static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1105 char *buf)
43f66a6c 1106{
ad3fee56 1107 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1108 return sprintf(buf, "0x%08x\n", (int)p->config);
1109}
0edd5b44 1110
43f66a6c
JK
1111static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1112
ad3fee56 1113static ssize_t show_nic_type(struct device *d,
0edd5b44 1114 struct device_attribute *attr, char *buf)
43f66a6c 1115{
a613bffd
JK
1116 struct ipw_priv *priv = d->driver_data;
1117 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
43f66a6c 1118}
0edd5b44 1119
43f66a6c
JK
1120static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
1121
ad3fee56 1122static ssize_t dump_error_log(struct device *d,
0edd5b44
JG
1123 struct device_attribute *attr, const char *buf,
1124 size_t count)
43f66a6c
JK
1125{
1126 char *p = (char *)buf;
1127
bf79451e 1128 if (p[0] == '1')
0edd5b44 1129 ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data);
43f66a6c
JK
1130
1131 return strnlen(buf, count);
1132}
0edd5b44 1133
43f66a6c
JK
1134static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log);
1135
ad3fee56 1136static ssize_t dump_event_log(struct device *d,
0edd5b44
JG
1137 struct device_attribute *attr, const char *buf,
1138 size_t count)
43f66a6c
JK
1139{
1140 char *p = (char *)buf;
1141
bf79451e 1142 if (p[0] == '1')
0edd5b44 1143 ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data);
43f66a6c
JK
1144
1145 return strnlen(buf, count);
1146}
0edd5b44 1147
43f66a6c
JK
1148static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
1149
ad3fee56 1150static ssize_t show_ucode_version(struct device *d,
0edd5b44 1151 struct device_attribute *attr, char *buf)
43f66a6c
JK
1152{
1153 u32 len = sizeof(u32), tmp = 0;
ad3fee56 1154 struct ipw_priv *p = d->driver_data;
43f66a6c 1155
0edd5b44 1156 if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
43f66a6c
JK
1157 return 0;
1158
1159 return sprintf(buf, "0x%08x\n", tmp);
1160}
0edd5b44
JG
1161
1162static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL);
43f66a6c 1163
ad3fee56
AM
1164static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
1165 char *buf)
43f66a6c
JK
1166{
1167 u32 len = sizeof(u32), tmp = 0;
ad3fee56 1168 struct ipw_priv *p = d->driver_data;
43f66a6c 1169
0edd5b44 1170 if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
43f66a6c
JK
1171 return 0;
1172
1173 return sprintf(buf, "0x%08x\n", tmp);
1174}
0edd5b44
JG
1175
1176static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
43f66a6c
JK
1177
1178/*
1179 * Add a device attribute to view/control the delay between eeprom
1180 * operations.
1181 */
ad3fee56 1182static ssize_t show_eeprom_delay(struct device *d,
0edd5b44 1183 struct device_attribute *attr, char *buf)
43f66a6c 1184{
0edd5b44 1185 int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay;
43f66a6c
JK
1186 return sprintf(buf, "%i\n", n);
1187}
ad3fee56 1188static ssize_t store_eeprom_delay(struct device *d,
0edd5b44
JG
1189 struct device_attribute *attr,
1190 const char *buf, size_t count)
43f66a6c 1191{
ad3fee56 1192 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1193 sscanf(buf, "%i", &p->eeprom_delay);
1194 return strnlen(buf, count);
1195}
0edd5b44
JG
1196
1197static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO,
1198 show_eeprom_delay, store_eeprom_delay);
43f66a6c 1199
ad3fee56 1200static ssize_t show_command_event_reg(struct device *d,
0edd5b44 1201 struct device_attribute *attr, char *buf)
43f66a6c
JK
1202{
1203 u32 reg = 0;
ad3fee56 1204 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1205
1206 reg = ipw_read_reg32(p, CX2_INTERNAL_CMD_EVENT);
1207 return sprintf(buf, "0x%08x\n", reg);
1208}
ad3fee56 1209static ssize_t store_command_event_reg(struct device *d,
0edd5b44
JG
1210 struct device_attribute *attr,
1211 const char *buf, size_t count)
43f66a6c
JK
1212{
1213 u32 reg;
ad3fee56 1214 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1215
1216 sscanf(buf, "%x", &reg);
1217 ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg);
1218 return strnlen(buf, count);
1219}
0edd5b44
JG
1220
1221static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO,
1222 show_command_event_reg, store_command_event_reg);
43f66a6c 1223
ad3fee56 1224static ssize_t show_mem_gpio_reg(struct device *d,
0edd5b44 1225 struct device_attribute *attr, char *buf)
43f66a6c
JK
1226{
1227 u32 reg = 0;
ad3fee56 1228 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1229
1230 reg = ipw_read_reg32(p, 0x301100);
1231 return sprintf(buf, "0x%08x\n", reg);
1232}
ad3fee56 1233static ssize_t store_mem_gpio_reg(struct device *d,
0edd5b44
JG
1234 struct device_attribute *attr,
1235 const char *buf, size_t count)
43f66a6c
JK
1236{
1237 u32 reg;
ad3fee56 1238 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1239
1240 sscanf(buf, "%x", &reg);
1241 ipw_write_reg32(p, 0x301100, reg);
1242 return strnlen(buf, count);
1243}
0edd5b44
JG
1244
1245static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO,
1246 show_mem_gpio_reg, store_mem_gpio_reg);
43f66a6c 1247
ad3fee56 1248static ssize_t show_indirect_dword(struct device *d,
0edd5b44 1249 struct device_attribute *attr, char *buf)
43f66a6c
JK
1250{
1251 u32 reg = 0;
ad3fee56 1252 struct ipw_priv *priv = d->driver_data;
bf79451e 1253 if (priv->status & STATUS_INDIRECT_DWORD)
43f66a6c 1254 reg = ipw_read_reg32(priv, priv->indirect_dword);
bf79451e 1255 else
43f66a6c 1256 reg = 0;
bf79451e 1257
43f66a6c
JK
1258 return sprintf(buf, "0x%08x\n", reg);
1259}
ad3fee56 1260static ssize_t store_indirect_dword(struct device *d,
0edd5b44
JG
1261 struct device_attribute *attr,
1262 const char *buf, size_t count)
43f66a6c 1263{
ad3fee56 1264 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1265
1266 sscanf(buf, "%x", &priv->indirect_dword);
1267 priv->status |= STATUS_INDIRECT_DWORD;
1268 return strnlen(buf, count);
1269}
0edd5b44
JG
1270
1271static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO,
1272 show_indirect_dword, store_indirect_dword);
43f66a6c 1273
ad3fee56 1274static ssize_t show_indirect_byte(struct device *d,
0edd5b44 1275 struct device_attribute *attr, char *buf)
43f66a6c
JK
1276{
1277 u8 reg = 0;
ad3fee56 1278 struct ipw_priv *priv = d->driver_data;
bf79451e 1279 if (priv->status & STATUS_INDIRECT_BYTE)
43f66a6c 1280 reg = ipw_read_reg8(priv, priv->indirect_byte);
bf79451e 1281 else
43f66a6c
JK
1282 reg = 0;
1283
1284 return sprintf(buf, "0x%02x\n", reg);
1285}
ad3fee56 1286static ssize_t store_indirect_byte(struct device *d,
0edd5b44
JG
1287 struct device_attribute *attr,
1288 const char *buf, size_t count)
43f66a6c 1289{
ad3fee56 1290 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1291
1292 sscanf(buf, "%x", &priv->indirect_byte);
1293 priv->status |= STATUS_INDIRECT_BYTE;
1294 return strnlen(buf, count);
1295}
0edd5b44
JG
1296
1297static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO,
43f66a6c
JK
1298 show_indirect_byte, store_indirect_byte);
1299
ad3fee56 1300static ssize_t show_direct_dword(struct device *d,
0edd5b44 1301 struct device_attribute *attr, char *buf)
43f66a6c
JK
1302{
1303 u32 reg = 0;
ad3fee56 1304 struct ipw_priv *priv = d->driver_data;
43f66a6c 1305
bf79451e 1306 if (priv->status & STATUS_DIRECT_DWORD)
43f66a6c 1307 reg = ipw_read32(priv, priv->direct_dword);
bf79451e 1308 else
43f66a6c
JK
1309 reg = 0;
1310
1311 return sprintf(buf, "0x%08x\n", reg);
1312}
ad3fee56 1313static ssize_t store_direct_dword(struct device *d,
0edd5b44
JG
1314 struct device_attribute *attr,
1315 const char *buf, size_t count)
43f66a6c 1316{
ad3fee56 1317 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1318
1319 sscanf(buf, "%x", &priv->direct_dword);
1320 priv->status |= STATUS_DIRECT_DWORD;
1321 return strnlen(buf, count);
1322}
43f66a6c 1323
0edd5b44
JG
1324static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO,
1325 show_direct_dword, store_direct_dword);
43f66a6c
JK
1326
1327static inline int rf_kill_active(struct ipw_priv *priv)
1328{
1329 if (0 == (ipw_read32(priv, 0x30) & 0x10000))
1330 priv->status |= STATUS_RF_KILL_HW;
1331 else
1332 priv->status &= ~STATUS_RF_KILL_HW;
1333
1334 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
1335}
1336
ad3fee56 1337static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
0edd5b44 1338 char *buf)
43f66a6c
JK
1339{
1340 /* 0 - RF kill not enabled
bf79451e 1341 1 - SW based RF kill active (sysfs)
43f66a6c
JK
1342 2 - HW based RF kill active
1343 3 - Both HW and SW baed RF kill active */
ad3fee56 1344 struct ipw_priv *priv = d->driver_data;
43f66a6c 1345 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
0edd5b44 1346 (rf_kill_active(priv) ? 0x2 : 0x0);
43f66a6c
JK
1347 return sprintf(buf, "%i\n", val);
1348}
1349
1350static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
1351{
bf79451e 1352 if ((disable_radio ? 1 : 0) ==
ea2b26e0 1353 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
0edd5b44 1354 return 0;
43f66a6c
JK
1355
1356 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
1357 disable_radio ? "OFF" : "ON");
1358
1359 if (disable_radio) {
1360 priv->status |= STATUS_RF_KILL_SW;
1361
a613bffd 1362 if (priv->workqueue)
43f66a6c 1363 cancel_delayed_work(&priv->request_scan);
43f66a6c
JK
1364 wake_up_interruptible(&priv->wait_command_queue);
1365 queue_work(priv->workqueue, &priv->down);
1366 } else {
1367 priv->status &= ~STATUS_RF_KILL_SW;
1368 if (rf_kill_active(priv)) {
1369 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
1370 "disabled by HW switch\n");
1371 /* Make sure the RF_KILL check timer is running */
1372 cancel_delayed_work(&priv->rf_kill);
bf79451e 1373 queue_delayed_work(priv->workqueue, &priv->rf_kill,
43f66a6c 1374 2 * HZ);
bf79451e 1375 } else
43f66a6c
JK
1376 queue_work(priv->workqueue, &priv->up);
1377 }
1378
1379 return 1;
1380}
1381
0edd5b44
JG
1382static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
1383 const char *buf, size_t count)
43f66a6c 1384{
ad3fee56 1385 struct ipw_priv *priv = d->driver_data;
bf79451e 1386
43f66a6c
JK
1387 ipw_radio_kill_sw(priv, buf[0] == '1');
1388
1389 return count;
1390}
0edd5b44
JG
1391
1392static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
43f66a6c 1393
ea2b26e0
JK
1394static void notify_wx_assoc_event(struct ipw_priv *priv)
1395{
1396 union iwreq_data wrqu;
1397 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1398 if (priv->status & STATUS_ASSOCIATED)
1399 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1400 else
1401 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1402 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1403}
1404
43f66a6c
JK
1405static void ipw_irq_tasklet(struct ipw_priv *priv)
1406{
1407 u32 inta, inta_mask, handled = 0;
1408 unsigned long flags;
1409 int rc = 0;
1410
1411 spin_lock_irqsave(&priv->lock, flags);
1412
1413 inta = ipw_read32(priv, CX2_INTA_RW);
1414 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R);
1415 inta &= (CX2_INTA_MASK_ALL & inta_mask);
1416
1417 /* Add any cached INTA values that need to be handled */
1418 inta |= priv->isr_inta;
1419
1420 /* handle all the justifications for the interrupt */
1421 if (inta & CX2_INTA_BIT_RX_TRANSFER) {
1422 ipw_rx(priv);
1423 handled |= CX2_INTA_BIT_RX_TRANSFER;
1424 }
1425
1426 if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) {
1427 IPW_DEBUG_HC("Command completed.\n");
0edd5b44 1428 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
43f66a6c
JK
1429 priv->status &= ~STATUS_HCMD_ACTIVE;
1430 wake_up_interruptible(&priv->wait_command_queue);
1431 handled |= CX2_INTA_BIT_TX_CMD_QUEUE;
1432 }
1433
1434 if (inta & CX2_INTA_BIT_TX_QUEUE_1) {
1435 IPW_DEBUG_TX("TX_QUEUE_1\n");
0edd5b44 1436 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
43f66a6c
JK
1437 handled |= CX2_INTA_BIT_TX_QUEUE_1;
1438 }
1439
1440 if (inta & CX2_INTA_BIT_TX_QUEUE_2) {
1441 IPW_DEBUG_TX("TX_QUEUE_2\n");
0edd5b44 1442 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
43f66a6c
JK
1443 handled |= CX2_INTA_BIT_TX_QUEUE_2;
1444 }
1445
1446 if (inta & CX2_INTA_BIT_TX_QUEUE_3) {
1447 IPW_DEBUG_TX("TX_QUEUE_3\n");
0edd5b44 1448 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
43f66a6c
JK
1449 handled |= CX2_INTA_BIT_TX_QUEUE_3;
1450 }
1451
1452 if (inta & CX2_INTA_BIT_TX_QUEUE_4) {
1453 IPW_DEBUG_TX("TX_QUEUE_4\n");
0edd5b44 1454 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
43f66a6c
JK
1455 handled |= CX2_INTA_BIT_TX_QUEUE_4;
1456 }
1457
1458 if (inta & CX2_INTA_BIT_STATUS_CHANGE) {
1459 IPW_WARNING("STATUS_CHANGE\n");
1460 handled |= CX2_INTA_BIT_STATUS_CHANGE;
1461 }
1462
1463 if (inta & CX2_INTA_BIT_BEACON_PERIOD_EXPIRED) {
1464 IPW_WARNING("TX_PERIOD_EXPIRED\n");
1465 handled |= CX2_INTA_BIT_BEACON_PERIOD_EXPIRED;
1466 }
1467
1468 if (inta & CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
1469 IPW_WARNING("HOST_CMD_DONE\n");
1470 handled |= CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
1471 }
1472
1473 if (inta & CX2_INTA_BIT_FW_INITIALIZATION_DONE) {
1474 IPW_WARNING("FW_INITIALIZATION_DONE\n");
1475 handled |= CX2_INTA_BIT_FW_INITIALIZATION_DONE;
1476 }
1477
1478 if (inta & CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
1479 IPW_WARNING("PHY_OFF_DONE\n");
1480 handled |= CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
1481 }
1482
1483 if (inta & CX2_INTA_BIT_RF_KILL_DONE) {
1484 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1485 priv->status |= STATUS_RF_KILL_HW;
1486 wake_up_interruptible(&priv->wait_command_queue);
ea2b26e0 1487 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
43f66a6c 1488 cancel_delayed_work(&priv->request_scan);
a613bffd 1489 schedule_work(&priv->link_down);
43f66a6c
JK
1490 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1491 handled |= CX2_INTA_BIT_RF_KILL_DONE;
1492 }
bf79451e 1493
43f66a6c
JK
1494 if (inta & CX2_INTA_BIT_FATAL_ERROR) {
1495 IPW_ERROR("Firmware error detected. Restarting.\n");
1496#ifdef CONFIG_IPW_DEBUG
1497 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1498 ipw_dump_nic_error_log(priv);
1499 ipw_dump_nic_event_log(priv);
1500 }
1501#endif
1502 queue_work(priv->workqueue, &priv->adapter_restart);
1503 handled |= CX2_INTA_BIT_FATAL_ERROR;
1504 }
1505
1506 if (inta & CX2_INTA_BIT_PARITY_ERROR) {
1507 IPW_ERROR("Parity error\n");
1508 handled |= CX2_INTA_BIT_PARITY_ERROR;
1509 }
1510
1511 if (handled != inta) {
0edd5b44 1512 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
43f66a6c
JK
1513 }
1514
1515 /* enable all interrupts */
1516 ipw_enable_interrupts(priv);
1517
1518 spin_unlock_irqrestore(&priv->lock, flags);
1519}
bf79451e 1520
43f66a6c
JK
1521#ifdef CONFIG_IPW_DEBUG
1522#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1523static char *get_cmd_string(u8 cmd)
1524{
1525 switch (cmd) {
1526 IPW_CMD(HOST_COMPLETE);
bf79451e
JG
1527 IPW_CMD(POWER_DOWN);
1528 IPW_CMD(SYSTEM_CONFIG);
1529 IPW_CMD(MULTICAST_ADDRESS);
1530 IPW_CMD(SSID);
1531 IPW_CMD(ADAPTER_ADDRESS);
1532 IPW_CMD(PORT_TYPE);
1533 IPW_CMD(RTS_THRESHOLD);
1534 IPW_CMD(FRAG_THRESHOLD);
1535 IPW_CMD(POWER_MODE);
1536 IPW_CMD(WEP_KEY);
1537 IPW_CMD(TGI_TX_KEY);
1538 IPW_CMD(SCAN_REQUEST);
1539 IPW_CMD(SCAN_REQUEST_EXT);
1540 IPW_CMD(ASSOCIATE);
1541 IPW_CMD(SUPPORTED_RATES);
1542 IPW_CMD(SCAN_ABORT);
1543 IPW_CMD(TX_FLUSH);
1544 IPW_CMD(QOS_PARAMETERS);
1545 IPW_CMD(DINO_CONFIG);
1546 IPW_CMD(RSN_CAPABILITIES);
1547 IPW_CMD(RX_KEY);
1548 IPW_CMD(CARD_DISABLE);
1549 IPW_CMD(SEED_NUMBER);
1550 IPW_CMD(TX_POWER);
1551 IPW_CMD(COUNTRY_INFO);
1552 IPW_CMD(AIRONET_INFO);
1553 IPW_CMD(AP_TX_POWER);
1554 IPW_CMD(CCKM_INFO);
1555 IPW_CMD(CCX_VER_INFO);
1556 IPW_CMD(SET_CALIBRATION);
1557 IPW_CMD(SENSITIVITY_CALIB);
1558 IPW_CMD(RETRY_LIMIT);
1559 IPW_CMD(IPW_PRE_POWER_DOWN);
1560 IPW_CMD(VAP_BEACON_TEMPLATE);
1561 IPW_CMD(VAP_DTIM_PERIOD);
1562 IPW_CMD(EXT_SUPPORTED_RATES);
1563 IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);
1564 IPW_CMD(VAP_QUIET_INTERVALS);
1565 IPW_CMD(VAP_CHANNEL_SWITCH);
1566 IPW_CMD(VAP_MANDATORY_CHANNELS);
1567 IPW_CMD(VAP_CELL_PWR_LIMIT);
1568 IPW_CMD(VAP_CF_PARAM_SET);
1569 IPW_CMD(VAP_SET_BEACONING_STATE);
1570 IPW_CMD(MEASUREMENT);
1571 IPW_CMD(POWER_CAPABILITY);
1572 IPW_CMD(SUPPORTED_CHANNELS);
1573 IPW_CMD(TPC_REPORT);
1574 IPW_CMD(WME_INFO);
1575 IPW_CMD(PRODUCTION_COMMAND);
1576 default:
43f66a6c
JK
1577 return "UNKNOWN";
1578 }
1579}
ea2b26e0 1580#endif
43f66a6c
JK
1581
1582#define HOST_COMPLETE_TIMEOUT HZ
1583static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1584{
1585 int rc = 0;
a613bffd 1586 unsigned long flags;
43f66a6c 1587
a613bffd 1588 spin_lock_irqsave(&priv->lock, flags);
43f66a6c
JK
1589 if (priv->status & STATUS_HCMD_ACTIVE) {
1590 IPW_ERROR("Already sending a command\n");
a613bffd 1591 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
1592 return -1;
1593 }
1594
1595 priv->status |= STATUS_HCMD_ACTIVE;
bf79451e
JG
1596
1597 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
43f66a6c 1598 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len);
0edd5b44 1599 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
43f66a6c
JK
1600
1601 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
a613bffd
JK
1602 if (rc) {
1603 priv->status &= ~STATUS_HCMD_ACTIVE;
1604 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 1605 return rc;
a613bffd
JK
1606 }
1607 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 1608
0edd5b44
JG
1609 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1610 !(priv->
1611 status & STATUS_HCMD_ACTIVE),
1612 HOST_COMPLETE_TIMEOUT);
43f66a6c 1613 if (rc == 0) {
a613bffd
JK
1614 spin_lock_irqsave(&priv->lock, flags);
1615 if (priv->status & STATUS_HCMD_ACTIVE) {
1616 IPW_DEBUG_INFO("Command completion failed out after "
1617 "%dms.\n",
1618 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
1619 priv->status &= ~STATUS_HCMD_ACTIVE;
1620 spin_unlock_irqrestore(&priv->lock, flags);
1621 return -EIO;
1622 }
1623 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 1624 }
a613bffd 1625
43f66a6c
JK
1626 if (priv->status & STATUS_RF_KILL_MASK) {
1627 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n");
1628 return -EIO;
1629 }
1630
1631 return 0;
1632}
1633
1634static int ipw_send_host_complete(struct ipw_priv *priv)
1635{
1636 struct host_cmd cmd = {
1637 .cmd = IPW_CMD_HOST_COMPLETE,
1638 .len = 0
1639 };
1640
1641 if (!priv) {
1642 IPW_ERROR("Invalid args\n");
1643 return -1;
1644 }
1645
1646 if (ipw_send_cmd(priv, &cmd)) {
1647 IPW_ERROR("failed to send HOST_COMPLETE command\n");
1648 return -1;
1649 }
bf79451e 1650
43f66a6c
JK
1651 return 0;
1652}
1653
bf79451e 1654static int ipw_send_system_config(struct ipw_priv *priv,
43f66a6c
JK
1655 struct ipw_sys_config *config)
1656{
1657 struct host_cmd cmd = {
1658 .cmd = IPW_CMD_SYSTEM_CONFIG,
1659 .len = sizeof(*config)
1660 };
1661
1662 if (!priv || !config) {
1663 IPW_ERROR("Invalid args\n");
1664 return -1;
1665 }
1666
0edd5b44 1667 memcpy(&cmd.param, config, sizeof(*config));
43f66a6c
JK
1668 if (ipw_send_cmd(priv, &cmd)) {
1669 IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
1670 return -1;
1671 }
1672
1673 return 0;
1674}
1675
0edd5b44 1676static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
43f66a6c
JK
1677{
1678 struct host_cmd cmd = {
1679 .cmd = IPW_CMD_SSID,
1680 .len = min(len, IW_ESSID_MAX_SIZE)
1681 };
1682
1683 if (!priv || !ssid) {
1684 IPW_ERROR("Invalid args\n");
1685 return -1;
1686 }
1687
1688 memcpy(&cmd.param, ssid, cmd.len);
1689 if (ipw_send_cmd(priv, &cmd)) {
1690 IPW_ERROR("failed to send SSID command\n");
1691 return -1;
1692 }
bf79451e 1693
43f66a6c
JK
1694 return 0;
1695}
1696
0edd5b44 1697static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
43f66a6c
JK
1698{
1699 struct host_cmd cmd = {
1700 .cmd = IPW_CMD_ADAPTER_ADDRESS,
1701 .len = ETH_ALEN
1702 };
1703
1704 if (!priv || !mac) {
1705 IPW_ERROR("Invalid args\n");
1706 return -1;
1707 }
1708
1709 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
1710 priv->net_dev->name, MAC_ARG(mac));
1711
1712 memcpy(&cmd.param, mac, ETH_ALEN);
1713
1714 if (ipw_send_cmd(priv, &cmd)) {
1715 IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
1716 return -1;
1717 }
bf79451e 1718
43f66a6c
JK
1719 return 0;
1720}
1721
a613bffd
JK
1722/*
1723 * NOTE: This must be executed from our workqueue as it results in udelay
1724 * being called which may corrupt the keyboard if executed on default
1725 * workqueue
1726 */
43f66a6c
JK
1727static void ipw_adapter_restart(void *adapter)
1728{
1729 struct ipw_priv *priv = adapter;
1730
1731 if (priv->status & STATUS_RF_KILL_MASK)
1732 return;
1733
1734 ipw_down(priv);
1735 if (ipw_up(priv)) {
1736 IPW_ERROR("Failed to up device\n");
1737 return;
1738 }
1739}
1740
c848d0af
JK
1741static void ipw_bg_adapter_restart(void *data)
1742{
1743 struct ipw_priv *priv = data;
1744 down(&priv->sem);
1745 ipw_adapter_restart(data);
1746 up(&priv->sem);
1747}
1748
43f66a6c
JK
1749#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
1750
1751static void ipw_scan_check(void *data)
1752{
1753 struct ipw_priv *priv = data;
1754 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
1755 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
bf79451e 1756 "adapter (%dms).\n",
43f66a6c 1757 IPW_SCAN_CHECK_WATCHDOG / 100);
a613bffd 1758 queue_work(priv->workqueue, &priv->adapter_restart);
43f66a6c
JK
1759 }
1760}
1761
c848d0af
JK
1762static void ipw_bg_scan_check(void *data)
1763{
1764 struct ipw_priv *priv = data;
1765 down(&priv->sem);
1766 ipw_scan_check(data);
1767 up(&priv->sem);
1768}
1769
43f66a6c
JK
1770static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1771 struct ipw_scan_request_ext *request)
1772{
1773 struct host_cmd cmd = {
1774 .cmd = IPW_CMD_SCAN_REQUEST_EXT,
1775 .len = sizeof(*request)
1776 };
1777
1778 if (!priv || !request) {
1779 IPW_ERROR("Invalid args\n");
1780 return -1;
1781 }
1782
0edd5b44 1783 memcpy(&cmd.param, request, sizeof(*request));
43f66a6c
JK
1784 if (ipw_send_cmd(priv, &cmd)) {
1785 IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
1786 return -1;
1787 }
bf79451e
JG
1788
1789 queue_delayed_work(priv->workqueue, &priv->scan_check,
43f66a6c
JK
1790 IPW_SCAN_CHECK_WATCHDOG);
1791 return 0;
1792}
1793
1794static int ipw_send_scan_abort(struct ipw_priv *priv)
1795{
1796 struct host_cmd cmd = {
1797 .cmd = IPW_CMD_SCAN_ABORT,
1798 .len = 0
1799 };
1800
1801 if (!priv) {
1802 IPW_ERROR("Invalid args\n");
1803 return -1;
1804 }
1805
1806 if (ipw_send_cmd(priv, &cmd)) {
1807 IPW_ERROR("failed to send SCAN_ABORT command\n");
1808 return -1;
1809 }
bf79451e 1810
43f66a6c
JK
1811 return 0;
1812}
1813
1814static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
1815{
1816 struct host_cmd cmd = {
1817 .cmd = IPW_CMD_SENSITIVITY_CALIB,
1818 .len = sizeof(struct ipw_sensitivity_calib)
1819 };
1820 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
0edd5b44 1821 &cmd.param;
43f66a6c
JK
1822 calib->beacon_rssi_raw = sens;
1823 if (ipw_send_cmd(priv, &cmd)) {
1824 IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
1825 return -1;
1826 }
1827
1828 return 0;
1829}
1830
1831static int ipw_send_associate(struct ipw_priv *priv,
1832 struct ipw_associate *associate)
1833{
1834 struct host_cmd cmd = {
1835 .cmd = IPW_CMD_ASSOCIATE,
1836 .len = sizeof(*associate)
1837 };
1838
a613bffd
JK
1839 struct ipw_associate tmp_associate;
1840 memcpy(&tmp_associate, associate, sizeof(*associate));
1841 tmp_associate.policy_support =
1842 cpu_to_le16(tmp_associate.policy_support);
1843 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
1844 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
1845 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
1846 tmp_associate.listen_interval =
1847 cpu_to_le16(tmp_associate.listen_interval);
1848 tmp_associate.beacon_interval =
1849 cpu_to_le16(tmp_associate.beacon_interval);
1850 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
1851
43f66a6c
JK
1852 if (!priv || !associate) {
1853 IPW_ERROR("Invalid args\n");
1854 return -1;
1855 }
1856
a613bffd 1857 memcpy(&cmd.param, &tmp_associate, sizeof(*associate));
43f66a6c
JK
1858 if (ipw_send_cmd(priv, &cmd)) {
1859 IPW_ERROR("failed to send ASSOCIATE command\n");
1860 return -1;
1861 }
bf79451e 1862
43f66a6c
JK
1863 return 0;
1864}
1865
1866static int ipw_send_supported_rates(struct ipw_priv *priv,
1867 struct ipw_supported_rates *rates)
1868{
1869 struct host_cmd cmd = {
1870 .cmd = IPW_CMD_SUPPORTED_RATES,
1871 .len = sizeof(*rates)
1872 };
1873
1874 if (!priv || !rates) {
1875 IPW_ERROR("Invalid args\n");
1876 return -1;
1877 }
1878
0edd5b44 1879 memcpy(&cmd.param, rates, sizeof(*rates));
43f66a6c
JK
1880 if (ipw_send_cmd(priv, &cmd)) {
1881 IPW_ERROR("failed to send SUPPORTED_RATES command\n");
1882 return -1;
1883 }
bf79451e 1884
43f66a6c
JK
1885 return 0;
1886}
1887
1888static int ipw_set_random_seed(struct ipw_priv *priv)
1889{
1890 struct host_cmd cmd = {
1891 .cmd = IPW_CMD_SEED_NUMBER,
1892 .len = sizeof(u32)
1893 };
1894
1895 if (!priv) {
1896 IPW_ERROR("Invalid args\n");
1897 return -1;
1898 }
1899
1900 get_random_bytes(&cmd.param, sizeof(u32));
1901
1902 if (ipw_send_cmd(priv, &cmd)) {
1903 IPW_ERROR("failed to send SEED_NUMBER command\n");
1904 return -1;
1905 }
bf79451e 1906
43f66a6c
JK
1907 return 0;
1908}
1909
1910#if 0
1911static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1912{
1913 struct host_cmd cmd = {
1914 .cmd = IPW_CMD_CARD_DISABLE,
1915 .len = sizeof(u32)
1916 };
1917
1918 if (!priv) {
1919 IPW_ERROR("Invalid args\n");
1920 return -1;
1921 }
1922
0edd5b44 1923 *((u32 *) & cmd.param) = phy_off;
43f66a6c
JK
1924
1925 if (ipw_send_cmd(priv, &cmd)) {
1926 IPW_ERROR("failed to send CARD_DISABLE command\n");
1927 return -1;
1928 }
bf79451e 1929
43f66a6c
JK
1930 return 0;
1931}
1932#endif
1933
0edd5b44 1934static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
43f66a6c
JK
1935{
1936 struct host_cmd cmd = {
1937 .cmd = IPW_CMD_TX_POWER,
1938 .len = sizeof(*power)
1939 };
1940
1941 if (!priv || !power) {
1942 IPW_ERROR("Invalid args\n");
1943 return -1;
1944 }
1945
0edd5b44 1946 memcpy(&cmd.param, power, sizeof(*power));
43f66a6c
JK
1947 if (ipw_send_cmd(priv, &cmd)) {
1948 IPW_ERROR("failed to send TX_POWER command\n");
1949 return -1;
1950 }
bf79451e 1951
43f66a6c
JK
1952 return 0;
1953}
1954
1955static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
1956{
1957 struct ipw_rts_threshold rts_threshold = {
1958 .rts_threshold = rts,
1959 };
1960 struct host_cmd cmd = {
1961 .cmd = IPW_CMD_RTS_THRESHOLD,
1962 .len = sizeof(rts_threshold)
1963 };
1964
1965 if (!priv) {
1966 IPW_ERROR("Invalid args\n");
1967 return -1;
1968 }
1969
1970 memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold));
1971 if (ipw_send_cmd(priv, &cmd)) {
1972 IPW_ERROR("failed to send RTS_THRESHOLD command\n");
1973 return -1;
1974 }
1975
1976 return 0;
1977}
1978
1979static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
1980{
1981 struct ipw_frag_threshold frag_threshold = {
1982 .frag_threshold = frag,
1983 };
1984 struct host_cmd cmd = {
1985 .cmd = IPW_CMD_FRAG_THRESHOLD,
1986 .len = sizeof(frag_threshold)
1987 };
1988
1989 if (!priv) {
1990 IPW_ERROR("Invalid args\n");
1991 return -1;
1992 }
1993
1994 memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold));
1995 if (ipw_send_cmd(priv, &cmd)) {
1996 IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
1997 return -1;
1998 }
1999
2000 return 0;
2001}
2002
2003static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2004{
2005 struct host_cmd cmd = {
2006 .cmd = IPW_CMD_POWER_MODE,
2007 .len = sizeof(u32)
2008 };
0edd5b44 2009 u32 *param = (u32 *) (&cmd.param);
43f66a6c
JK
2010
2011 if (!priv) {
2012 IPW_ERROR("Invalid args\n");
2013 return -1;
2014 }
bf79451e 2015
43f66a6c
JK
2016 /* If on battery, set to 3, if AC set to CAM, else user
2017 * level */
2018 switch (mode) {
2019 case IPW_POWER_BATTERY:
2020 *param = IPW_POWER_INDEX_3;
2021 break;
2022 case IPW_POWER_AC:
2023 *param = IPW_POWER_MODE_CAM;
2024 break;
2025 default:
2026 *param = mode;
2027 break;
2028 }
2029
2030 if (ipw_send_cmd(priv, &cmd)) {
2031 IPW_ERROR("failed to send POWER_MODE command\n");
2032 return -1;
2033 }
2034
2035 return 0;
2036}
2037
2038/*
2039 * The IPW device contains a Microwire compatible EEPROM that stores
2040 * various data like the MAC address. Usually the firmware has exclusive
2041 * access to the eeprom, but during device initialization (before the
2042 * device driver has sent the HostComplete command to the firmware) the
2043 * device driver has read access to the EEPROM by way of indirect addressing
2044 * through a couple of memory mapped registers.
2045 *
2046 * The following is a simplified implementation for pulling data out of the
2047 * the eeprom, along with some helper functions to find information in
2048 * the per device private data's copy of the eeprom.
2049 *
2050 * NOTE: To better understand how these functions work (i.e what is a chip
2051 * select and why do have to keep driving the eeprom clock?), read
2052 * just about any data sheet for a Microwire compatible EEPROM.
2053 */
2054
2055/* write a 32 bit value into the indirect accessor register */
2056static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
2057{
2058 ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);
bf79451e 2059
43f66a6c
JK
2060 /* the eeprom requires some time to complete the operation */
2061 udelay(p->eeprom_delay);
2062
2063 return;
2064}
2065
2066/* perform a chip select operation */
0edd5b44 2067static inline void eeprom_cs(struct ipw_priv *priv)
43f66a6c 2068{
0edd5b44
JG
2069 eeprom_write_reg(priv, 0);
2070 eeprom_write_reg(priv, EEPROM_BIT_CS);
2071 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2072 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2073}
2074
2075/* perform a chip select operation */
0edd5b44 2076static inline void eeprom_disable_cs(struct ipw_priv *priv)
43f66a6c 2077{
0edd5b44
JG
2078 eeprom_write_reg(priv, EEPROM_BIT_CS);
2079 eeprom_write_reg(priv, 0);
2080 eeprom_write_reg(priv, EEPROM_BIT_SK);
43f66a6c
JK
2081}
2082
2083/* push a single bit down to the eeprom */
0edd5b44 2084static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit)
43f66a6c 2085{
0edd5b44
JG
2086 int d = (bit ? EEPROM_BIT_DI : 0);
2087 eeprom_write_reg(p, EEPROM_BIT_CS | d);
2088 eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK);
43f66a6c
JK
2089}
2090
2091/* push an opcode followed by an address down to the eeprom */
0edd5b44 2092static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr)
43f66a6c
JK
2093{
2094 int i;
2095
2096 eeprom_cs(priv);
0edd5b44
JG
2097 eeprom_write_bit(priv, 1);
2098 eeprom_write_bit(priv, op & 2);
2099 eeprom_write_bit(priv, op & 1);
2100 for (i = 7; i >= 0; i--) {
2101 eeprom_write_bit(priv, addr & (1 << i));
43f66a6c
JK
2102 }
2103}
2104
2105/* pull 16 bits off the eeprom, one bit at a time */
0edd5b44 2106static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
43f66a6c
JK
2107{
2108 int i;
0edd5b44 2109 u16 r = 0;
bf79451e 2110
43f66a6c 2111 /* Send READ Opcode */
0edd5b44 2112 eeprom_op(priv, EEPROM_CMD_READ, addr);
43f66a6c
JK
2113
2114 /* Send dummy bit */
0edd5b44 2115 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2116
2117 /* Read the byte off the eeprom one bit at a time */
0edd5b44 2118 for (i = 0; i < 16; i++) {
43f66a6c 2119 u32 data = 0;
0edd5b44
JG
2120 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2121 eeprom_write_reg(priv, EEPROM_BIT_CS);
2122 data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS);
2123 r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0);
43f66a6c 2124 }
bf79451e 2125
43f66a6c 2126 /* Send another dummy bit */
0edd5b44 2127 eeprom_write_reg(priv, 0);
43f66a6c 2128 eeprom_disable_cs(priv);
bf79451e 2129
43f66a6c
JK
2130 return r;
2131}
2132
2133/* helper function for pulling the mac address out of the private */
2134/* data's copy of the eeprom data */
0edd5b44 2135static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
43f66a6c 2136{
0edd5b44 2137 u8 *ee = (u8 *) priv->eeprom;
43f66a6c
JK
2138 memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
2139}
2140
2141/*
2142 * Either the device driver (i.e. the host) or the firmware can
2143 * load eeprom data into the designated region in SRAM. If neither
2144 * happens then the FW will shutdown with a fatal error.
2145 *
2146 * In order to signal the FW to load the EEPROM, the EEPROM_LOAD_DISABLE
2147 * bit needs region of shared SRAM needs to be non-zero.
2148 */
2149static void ipw_eeprom_init_sram(struct ipw_priv *priv)
2150{
2151 int i;
0edd5b44 2152 u16 *eeprom = (u16 *) priv->eeprom;
bf79451e 2153
43f66a6c
JK
2154 IPW_DEBUG_TRACE(">>\n");
2155
2156 /* read entire contents of eeprom into private buffer */
0edd5b44 2157 for (i = 0; i < 128; i++)
a613bffd 2158 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
43f66a6c 2159
bf79451e
JG
2160 /*
2161 If the data looks correct, then copy it to our private
43f66a6c
JK
2162 copy. Otherwise let the firmware know to perform the operation
2163 on it's own
0edd5b44 2164 */
43f66a6c
JK
2165 if ((priv->eeprom + EEPROM_VERSION) != 0) {
2166 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
2167
2168 /* write the eeprom data to sram */
0edd5b44
JG
2169 for (i = 0; i < CX2_EEPROM_IMAGE_SIZE; i++)
2170 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
43f66a6c
JK
2171
2172 /* Do not load eeprom data on fatal error or suspend */
2173 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
2174 } else {
2175 IPW_DEBUG_INFO("Enabling FW initializationg of SRAM\n");
2176
2177 /* Load eeprom data on fatal error or suspend */
2178 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);
2179 }
2180
2181 IPW_DEBUG_TRACE("<<\n");
2182}
2183
43f66a6c
JK
2184static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
2185{
2186 count >>= 2;
0edd5b44
JG
2187 if (!count)
2188 return;
43f66a6c 2189 _ipw_write32(priv, CX2_AUTOINC_ADDR, start);
bf79451e 2190 while (count--)
43f66a6c
JK
2191 _ipw_write32(priv, CX2_AUTOINC_DATA, 0);
2192}
2193
2194static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
2195{
2196 ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL,
bf79451e 2197 CB_NUMBER_OF_ELEMENTS_SMALL *
43f66a6c
JK
2198 sizeof(struct command_block));
2199}
2200
2201static int ipw_fw_dma_enable(struct ipw_priv *priv)
0edd5b44 2202{ /* start dma engine but no transfers yet */
43f66a6c
JK
2203
2204 IPW_DEBUG_FW(">> : \n");
bf79451e 2205
43f66a6c
JK
2206 /* Start the dma */
2207 ipw_fw_dma_reset_command_blocks(priv);
bf79451e 2208
43f66a6c
JK
2209 /* Write CB base address */
2210 ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL);
2211
2212 IPW_DEBUG_FW("<< : \n");
2213 return 0;
2214}
2215
2216static void ipw_fw_dma_abort(struct ipw_priv *priv)
2217{
2218 u32 control = 0;
2219
2220 IPW_DEBUG_FW(">> :\n");
bf79451e
JG
2221
2222 //set the Stop and Abort bit
43f66a6c
JK
2223 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
2224 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control);
2225 priv->sram_desc.last_cb_index = 0;
bf79451e 2226
43f66a6c
JK
2227 IPW_DEBUG_FW("<< \n");
2228}
2229
0edd5b44
JG
2230static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
2231 struct command_block *cb)
43f66a6c 2232{
0edd5b44
JG
2233 u32 address =
2234 CX2_SHARED_SRAM_DMA_CONTROL +
2235 (sizeof(struct command_block) * index);
43f66a6c
JK
2236 IPW_DEBUG_FW(">> :\n");
2237
0edd5b44
JG
2238 ipw_write_indirect(priv, address, (u8 *) cb,
2239 (int)sizeof(struct command_block));
43f66a6c
JK
2240
2241 IPW_DEBUG_FW("<< :\n");
2242 return 0;
2243
2244}
2245
2246static int ipw_fw_dma_kick(struct ipw_priv *priv)
2247{
2248 u32 control = 0;
0edd5b44 2249 u32 index = 0;
43f66a6c
JK
2250
2251 IPW_DEBUG_FW(">> :\n");
bf79451e 2252
43f66a6c 2253 for (index = 0; index < priv->sram_desc.last_cb_index; index++)
0edd5b44
JG
2254 ipw_fw_dma_write_command_block(priv, index,
2255 &priv->sram_desc.cb_list[index]);
43f66a6c
JK
2256
2257 /* Enable the DMA in the CSR register */
0edd5b44
JG
2258 ipw_clear_bit(priv, CX2_RESET_REG,
2259 CX2_RESET_REG_MASTER_DISABLED |
2260 CX2_RESET_REG_STOP_MASTER);
bf79451e 2261
0edd5b44 2262 /* Set the Start bit. */
43f66a6c
JK
2263 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
2264 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control);
2265
2266 IPW_DEBUG_FW("<< :\n");
2267 return 0;
2268}
2269
2270static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
2271{
2272 u32 address;
0edd5b44
JG
2273 u32 register_value = 0;
2274 u32 cb_fields_address = 0;
43f66a6c
JK
2275
2276 IPW_DEBUG_FW(">> :\n");
0edd5b44
JG
2277 address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB);
2278 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
43f66a6c
JK
2279
2280 /* Read the DMA Controlor register */
2281 register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL);
0edd5b44 2282 IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
43f66a6c 2283
0edd5b44 2284 /* Print the CB values */
43f66a6c
JK
2285 cb_fields_address = address;
2286 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2287 IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n", register_value);
43f66a6c
JK
2288
2289 cb_fields_address += sizeof(u32);
2290 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2291 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n", register_value);
43f66a6c
JK
2292
2293 cb_fields_address += sizeof(u32);
2294 register_value = ipw_read_reg32(priv, cb_fields_address);
2295 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x \n",
2296 register_value);
2297
2298 cb_fields_address += sizeof(u32);
2299 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2300 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n", register_value);
43f66a6c
JK
2301
2302 IPW_DEBUG_FW(">> :\n");
2303}
2304
2305static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
2306{
2307 u32 current_cb_address = 0;
2308 u32 current_cb_index = 0;
2309
2310 IPW_DEBUG_FW("<< :\n");
0edd5b44 2311 current_cb_address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB);
bf79451e 2312
0edd5b44
JG
2313 current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL) /
2314 sizeof(struct command_block);
bf79451e 2315
43f66a6c 2316 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
0edd5b44 2317 current_cb_index, current_cb_address);
43f66a6c
JK
2318
2319 IPW_DEBUG_FW(">> :\n");
2320 return current_cb_index;
2321
2322}
2323
2324static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
2325 u32 src_address,
2326 u32 dest_address,
2327 u32 length,
0edd5b44 2328 int interrupt_enabled, int is_last)
43f66a6c
JK
2329{
2330
bf79451e 2331 u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC |
0edd5b44
JG
2332 CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG |
2333 CB_DEST_SIZE_LONG;
43f66a6c 2334 struct command_block *cb;
0edd5b44 2335 u32 last_cb_element = 0;
43f66a6c
JK
2336
2337 IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n",
2338 src_address, dest_address, length);
2339
2340 if (priv->sram_desc.last_cb_index >= CB_NUMBER_OF_ELEMENTS_SMALL)
2341 return -1;
2342
2343 last_cb_element = priv->sram_desc.last_cb_index;
2344 cb = &priv->sram_desc.cb_list[last_cb_element];
2345 priv->sram_desc.last_cb_index++;
2346
2347 /* Calculate the new CB control word */
0edd5b44 2348 if (interrupt_enabled)
43f66a6c
JK
2349 control |= CB_INT_ENABLED;
2350
2351 if (is_last)
2352 control |= CB_LAST_VALID;
bf79451e 2353
43f66a6c
JK
2354 control |= length;
2355
2356 /* Calculate the CB Element's checksum value */
0edd5b44 2357 cb->status = control ^ src_address ^ dest_address;
43f66a6c
JK
2358
2359 /* Copy the Source and Destination addresses */
2360 cb->dest_addr = dest_address;
2361 cb->source_addr = src_address;
2362
2363 /* Copy the Control Word last */
2364 cb->control = control;
2365
2366 return 0;
2367}
2368
2369static int ipw_fw_dma_add_buffer(struct ipw_priv *priv,
0edd5b44 2370 u32 src_phys, u32 dest_address, u32 length)
43f66a6c
JK
2371{
2372 u32 bytes_left = length;
0edd5b44
JG
2373 u32 src_offset = 0;
2374 u32 dest_offset = 0;
43f66a6c
JK
2375 int status = 0;
2376 IPW_DEBUG_FW(">> \n");
2377 IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n",
2378 src_phys, dest_address, length);
2379 while (bytes_left > CB_MAX_LENGTH) {
0edd5b44
JG
2380 status = ipw_fw_dma_add_command_block(priv,
2381 src_phys + src_offset,
2382 dest_address +
2383 dest_offset,
2384 CB_MAX_LENGTH, 0, 0);
43f66a6c
JK
2385 if (status) {
2386 IPW_DEBUG_FW_INFO(": Failed\n");
2387 return -1;
bf79451e 2388 } else
43f66a6c
JK
2389 IPW_DEBUG_FW_INFO(": Added new cb\n");
2390
2391 src_offset += CB_MAX_LENGTH;
2392 dest_offset += CB_MAX_LENGTH;
2393 bytes_left -= CB_MAX_LENGTH;
2394 }
2395
2396 /* add the buffer tail */
2397 if (bytes_left > 0) {
0edd5b44
JG
2398 status =
2399 ipw_fw_dma_add_command_block(priv, src_phys + src_offset,
2400 dest_address + dest_offset,
2401 bytes_left, 0, 0);
43f66a6c
JK
2402 if (status) {
2403 IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n");
2404 return -1;
bf79451e 2405 } else
0edd5b44
JG
2406 IPW_DEBUG_FW_INFO
2407 (": Adding new cb - the buffer tail\n");
43f66a6c 2408 }
bf79451e 2409
43f66a6c
JK
2410 IPW_DEBUG_FW("<< \n");
2411 return 0;
2412}
2413
2414static int ipw_fw_dma_wait(struct ipw_priv *priv)
2415{
2416 u32 current_index = 0;
2417 u32 watchdog = 0;
2418
2419 IPW_DEBUG_FW(">> : \n");
2420
2421 current_index = ipw_fw_dma_command_block_index(priv);
bf79451e 2422 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n",
0edd5b44 2423 (int)priv->sram_desc.last_cb_index);
43f66a6c
JK
2424
2425 while (current_index < priv->sram_desc.last_cb_index) {
2426 udelay(50);
2427 current_index = ipw_fw_dma_command_block_index(priv);
2428
2429 watchdog++;
2430
2431 if (watchdog > 400) {
2432 IPW_DEBUG_FW_INFO("Timeout\n");
2433 ipw_fw_dma_dump_command_block(priv);
2434 ipw_fw_dma_abort(priv);
2435 return -1;
2436 }
2437 }
2438
2439 ipw_fw_dma_abort(priv);
2440
0edd5b44
JG
2441 /*Disable the DMA in the CSR register */
2442 ipw_set_bit(priv, CX2_RESET_REG,
43f66a6c
JK
2443 CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER);
2444
2445 IPW_DEBUG_FW("<< dmaWaitSync \n");
2446 return 0;
2447}
2448
bf79451e 2449static void ipw_remove_current_network(struct ipw_priv *priv)
43f66a6c
JK
2450{
2451 struct list_head *element, *safe;
bf79451e 2452 struct ieee80211_network *network = NULL;
a613bffd
JK
2453 unsigned long flags;
2454
2455 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c
JK
2456 list_for_each_safe(element, safe, &priv->ieee->network_list) {
2457 network = list_entry(element, struct ieee80211_network, list);
2458 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
2459 list_del(element);
bf79451e 2460 list_add_tail(&network->list,
43f66a6c
JK
2461 &priv->ieee->network_free_list);
2462 }
2463 }
a613bffd 2464 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c
JK
2465}
2466
2467/**
bf79451e 2468 * Check that card is still alive.
43f66a6c
JK
2469 * Reads debug register from domain0.
2470 * If card is present, pre-defined value should
2471 * be found there.
bf79451e 2472 *
43f66a6c
JK
2473 * @param priv
2474 * @return 1 if card is present, 0 otherwise
2475 */
2476static inline int ipw_alive(struct ipw_priv *priv)
2477{
2478 return ipw_read32(priv, 0x90) == 0xd55555d5;
2479}
2480
2481static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
2482 int timeout)
2483{
2484 int i = 0;
2485
2486 do {
bf79451e 2487 if ((ipw_read32(priv, addr) & mask) == mask)
43f66a6c
JK
2488 return i;
2489 mdelay(10);
2490 i += 10;
2491 } while (i < timeout);
bf79451e 2492
43f66a6c
JK
2493 return -ETIME;
2494}
2495
bf79451e 2496/* These functions load the firmware and micro code for the operation of
43f66a6c
JK
2497 * the ipw hardware. It assumes the buffer has all the bits for the
2498 * image and the caller is handling the memory allocation and clean up.
2499 */
2500
0edd5b44 2501static int ipw_stop_master(struct ipw_priv *priv)
43f66a6c
JK
2502{
2503 int rc;
bf79451e 2504
43f66a6c
JK
2505 IPW_DEBUG_TRACE(">> \n");
2506 /* stop master. typical delay - 0 */
2507 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER);
2508
2509 rc = ipw_poll_bit(priv, CX2_RESET_REG,
2510 CX2_RESET_REG_MASTER_DISABLED, 100);
2511 if (rc < 0) {
2512 IPW_ERROR("stop master failed in 10ms\n");
2513 return -1;
2514 }
2515
2516 IPW_DEBUG_INFO("stop master %dms\n", rc);
2517
2518 return rc;
2519}
2520
2521static void ipw_arc_release(struct ipw_priv *priv)
2522{
2523 IPW_DEBUG_TRACE(">> \n");
2524 mdelay(5);
2525
2526 ipw_clear_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2527
2528 /* no one knows timing, for safety add some delay */
2529 mdelay(5);
2530}
2531
2532struct fw_header {
2533 u32 version;
2534 u32 mode;
2535};
2536
2537struct fw_chunk {
2538 u32 address;
2539 u32 length;
2540};
2541
2542#define IPW_FW_MAJOR_VERSION 2
2543#define IPW_FW_MINOR_VERSION 2
2544
2545#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2546#define IPW_FW_MAJOR(x) (x & 0xff)
2547
2548#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \
2549 IPW_FW_MAJOR_VERSION)
2550
2551#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2552"." __stringify(IPW_FW_MINOR_VERSION) "-"
2553
2554#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
2555#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
2556#else
2557#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
2558#endif
2559
0edd5b44 2560static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c
JK
2561{
2562 int rc = 0, i, addr;
2563 u8 cr = 0;
2564 u16 *image;
2565
0edd5b44 2566 image = (u16 *) data;
bf79451e 2567
43f66a6c
JK
2568 IPW_DEBUG_TRACE(">> \n");
2569
2570 rc = ipw_stop_master(priv);
2571
2572 if (rc < 0)
2573 return rc;
bf79451e 2574
0edd5b44 2575// spin_lock_irqsave(&priv->lock, flags);
bf79451e 2576
43f66a6c
JK
2577 for (addr = CX2_SHARED_LOWER_BOUND;
2578 addr < CX2_REGISTER_DOMAIN1_END; addr += 4) {
2579 ipw_write32(priv, addr, 0);
2580 }
2581
2582 /* no ucode (yet) */
2583 memset(&priv->dino_alive, 0, sizeof(priv->dino_alive));
2584 /* destroy DMA queues */
2585 /* reset sequence */
2586
0edd5b44 2587 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_ON);
43f66a6c
JK
2588 ipw_arc_release(priv);
2589 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF);
2590 mdelay(1);
2591
2592 /* reset PHY */
2593 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN);
2594 mdelay(1);
bf79451e 2595
43f66a6c
JK
2596 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0);
2597 mdelay(1);
bf79451e 2598
43f66a6c
JK
2599 /* enable ucode store */
2600 ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0);
2601 ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS);
2602 mdelay(1);
2603
2604 /* write ucode */
2605 /**
2606 * @bug
2607 * Do NOT set indirect address register once and then
2608 * store data to indirect data register in the loop.
2609 * It seems very reasonable, but in this case DINO do not
2610 * accept ucode. It is essential to set address each time.
2611 */
2612 /* load new ipw uCode */
2613 for (i = 0; i < len / 2; i++)
a613bffd
JK
2614 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE,
2615 cpu_to_le16(image[i]));
43f66a6c 2616
43f66a6c
JK
2617 /* enable DINO */
2618 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
0edd5b44 2619 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
43f66a6c 2620
0edd5b44 2621 /* this is where the igx / win driver deveates from the VAP driver. */
43f66a6c
JK
2622
2623 /* wait for alive response */
2624 for (i = 0; i < 100; i++) {
2625 /* poll for incoming data */
2626 cr = ipw_read_reg8(priv, CX2_BASEBAND_CONTROL_STATUS);
2627 if (cr & DINO_RXFIFO_DATA)
2628 break;
2629 mdelay(1);
2630 }
2631
2632 if (cr & DINO_RXFIFO_DATA) {
2633 /* alive_command_responce size is NOT multiple of 4 */
2634 u32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
bf79451e
JG
2635
2636 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
43f66a6c 2637 response_buffer[i] =
a613bffd
JK
2638 le32_to_cpu(ipw_read_reg32(priv,
2639 CX2_BASEBAND_RX_FIFO_READ));
43f66a6c
JK
2640 memcpy(&priv->dino_alive, response_buffer,
2641 sizeof(priv->dino_alive));
2642 if (priv->dino_alive.alive_command == 1
2643 && priv->dino_alive.ucode_valid == 1) {
2644 rc = 0;
0edd5b44
JG
2645 IPW_DEBUG_INFO
2646 ("Microcode OK, rev. %d (0x%x) dev. %d (0x%x) "
2647 "of %02d/%02d/%02d %02d:%02d\n",
2648 priv->dino_alive.software_revision,
2649 priv->dino_alive.software_revision,
2650 priv->dino_alive.device_identifier,
2651 priv->dino_alive.device_identifier,
2652 priv->dino_alive.time_stamp[0],
2653 priv->dino_alive.time_stamp[1],
2654 priv->dino_alive.time_stamp[2],
2655 priv->dino_alive.time_stamp[3],
2656 priv->dino_alive.time_stamp[4]);
43f66a6c
JK
2657 } else {
2658 IPW_DEBUG_INFO("Microcode is not alive\n");
2659 rc = -EINVAL;
2660 }
2661 } else {
2662 IPW_DEBUG_INFO("No alive response from DINO\n");
2663 rc = -ETIME;
2664 }
2665
2666 /* disable DINO, otherwise for some reason
2667 firmware have problem getting alive resp. */
2668 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
2669
0edd5b44 2670// spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
2671
2672 return rc;
2673}
2674
0edd5b44 2675static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c
JK
2676{
2677 int rc = -1;
2678 int offset = 0;
2679 struct fw_chunk *chunk;
2680 dma_addr_t shared_phys;
2681 u8 *shared_virt;
2682
2683 IPW_DEBUG_TRACE("<< : \n");
2684 shared_virt = pci_alloc_consistent(priv->pci_dev, len, &shared_phys);
2685
2686 if (!shared_virt)
2687 return -ENOMEM;
2688
2689 memmove(shared_virt, data, len);
2690
2691 /* Start the Dma */
2692 rc = ipw_fw_dma_enable(priv);
2693
2694 if (priv->sram_desc.last_cb_index > 0) {
2695 /* the DMA is already ready this would be a bug. */
2696 BUG();
2697 goto out;
2698 }
2699
2700 do {
2701 chunk = (struct fw_chunk *)(data + offset);
2702 offset += sizeof(struct fw_chunk);
2703 /* build DMA packet and queue up for sending */
bf79451e 2704 /* dma to chunk->address, the chunk->length bytes from data +
43f66a6c
JK
2705 * offeset*/
2706 /* Dma loading */
2707 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
a613bffd
JK
2708 le32_to_cpu(chunk->address),
2709 le32_to_cpu(chunk->length));
43f66a6c
JK
2710 if (rc) {
2711 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2712 goto out;
2713 }
bf79451e 2714
a613bffd 2715 offset += le32_to_cpu(chunk->length);
43f66a6c
JK
2716 } while (offset < len);
2717
0edd5b44 2718 /* Run the DMA and wait for the answer */
43f66a6c
JK
2719 rc = ipw_fw_dma_kick(priv);
2720 if (rc) {
2721 IPW_ERROR("dmaKick Failed\n");
2722 goto out;
2723 }
2724
2725 rc = ipw_fw_dma_wait(priv);
2726 if (rc) {
2727 IPW_ERROR("dmaWaitSync Failed\n");
2728 goto out;
2729 }
0edd5b44
JG
2730 out:
2731 pci_free_consistent(priv->pci_dev, len, shared_virt, shared_phys);
43f66a6c
JK
2732 return rc;
2733}
2734
2735/* stop nic */
2736static int ipw_stop_nic(struct ipw_priv *priv)
2737{
2738 int rc = 0;
2739
0edd5b44 2740 /* stop */
43f66a6c 2741 ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER);
bf79451e
JG
2742
2743 rc = ipw_poll_bit(priv, CX2_RESET_REG,
2744 CX2_RESET_REG_MASTER_DISABLED, 500);
43f66a6c
JK
2745 if (rc < 0) {
2746 IPW_ERROR("wait for reg master disabled failed\n");
2747 return rc;
bf79451e 2748 }
43f66a6c
JK
2749
2750 ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
bf79451e 2751
43f66a6c
JK
2752 return rc;
2753}
2754
2755static void ipw_start_nic(struct ipw_priv *priv)
2756{
2757 IPW_DEBUG_TRACE(">>\n");
2758
0edd5b44 2759 /* prvHwStartNic release ARC */
43f66a6c 2760 ipw_clear_bit(priv, CX2_RESET_REG,
bf79451e
JG
2761 CX2_RESET_REG_MASTER_DISABLED |
2762 CX2_RESET_REG_STOP_MASTER |
43f66a6c 2763 CBD_RESET_REG_PRINCETON_RESET);
bf79451e 2764
43f66a6c 2765 /* enable power management */
0edd5b44
JG
2766 ipw_set_bit(priv, CX2_GP_CNTRL_RW,
2767 CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
43f66a6c
JK
2768
2769 IPW_DEBUG_TRACE("<<\n");
2770}
bf79451e 2771
43f66a6c
JK
2772static int ipw_init_nic(struct ipw_priv *priv)
2773{
2774 int rc;
2775
2776 IPW_DEBUG_TRACE(">>\n");
bf79451e 2777 /* reset */
43f66a6c
JK
2778 /*prvHwInitNic */
2779 /* set "initialization complete" bit to move adapter to D0 state */
2780 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE);
2781
2782 /* low-level PLL activation */
0edd5b44
JG
2783 ipw_write32(priv, CX2_READ_INT_REGISTER,
2784 CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
43f66a6c
JK
2785
2786 /* wait for clock stabilization */
bf79451e
JG
2787 rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW,
2788 CX2_GP_CNTRL_BIT_CLOCK_READY, 250);
0edd5b44 2789 if (rc < 0)
43f66a6c
JK
2790 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
2791
2792 /* assert SW reset */
2793 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_SW_RESET);
2794
2795 udelay(10);
2796
2797 /* set "initialization complete" bit to move adapter to D0 state */
2798 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE);
2799
2800 IPW_DEBUG_TRACE(">>\n");
2801 return 0;
2802}
2803
bf79451e 2804/* Call this function from process context, it will sleep in request_firmware.
43f66a6c
JK
2805 * Probe is an ok place to call this from.
2806 */
2807static int ipw_reset_nic(struct ipw_priv *priv)
2808{
2809 int rc = 0;
a613bffd 2810 unsigned long flags;
43f66a6c
JK
2811
2812 IPW_DEBUG_TRACE(">>\n");
bf79451e 2813
43f66a6c 2814 rc = ipw_init_nic(priv);
bf79451e 2815
a613bffd 2816 spin_lock_irqsave(&priv->lock, flags);
43f66a6c
JK
2817 /* Clear the 'host command active' bit... */
2818 priv->status &= ~STATUS_HCMD_ACTIVE;
2819 wake_up_interruptible(&priv->wait_command_queue);
a613bffd 2820 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
2821
2822 IPW_DEBUG_TRACE("<<\n");
2823 return rc;
bf79451e 2824}
43f66a6c 2825
bf79451e 2826static int ipw_get_fw(struct ipw_priv *priv,
43f66a6c
JK
2827 const struct firmware **fw, const char *name)
2828{
2829 struct fw_header *header;
2830 int rc;
2831
2832 /* ask firmware_class module to get the boot firmware off disk */
2833 rc = request_firmware(fw, name, &priv->pci_dev->dev);
2834 if (rc < 0) {
2835 IPW_ERROR("%s load failed: Reason %d\n", name, rc);
2836 return rc;
bf79451e 2837 }
43f66a6c
JK
2838
2839 header = (struct fw_header *)(*fw)->data;
a613bffd 2840 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
43f66a6c
JK
2841 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2842 name,
a613bffd
JK
2843 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2844 IPW_FW_MAJOR_VERSION);
43f66a6c
JK
2845 return -EINVAL;
2846 }
2847
aaa4d308 2848 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
43f66a6c 2849 name,
a613bffd
JK
2850 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2851 IPW_FW_MINOR(le32_to_cpu(header->version)),
43f66a6c
JK
2852 (*fw)->size - sizeof(struct fw_header));
2853 return 0;
2854}
2855
2856#define CX2_RX_BUF_SIZE (3000)
2857
2858static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2859 struct ipw_rx_queue *rxq)
2860{
2861 unsigned long flags;
2862 int i;
2863
2864 spin_lock_irqsave(&rxq->lock, flags);
2865
2866 INIT_LIST_HEAD(&rxq->rx_free);
2867 INIT_LIST_HEAD(&rxq->rx_used);
2868
2869 /* Fill the rx_used queue with _all_ of the Rx buffers */
2870 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
2871 /* In the reset function, these buffers may have been allocated
2872 * to an SKB, so we need to unmap and free potential storage */
2873 if (rxq->pool[i].skb != NULL) {
2874 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
0edd5b44 2875 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c 2876 dev_kfree_skb(rxq->pool[i].skb);
a613bffd 2877 rxq->pool[i].skb = NULL;
43f66a6c
JK
2878 }
2879 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
2880 }
bf79451e 2881
43f66a6c
JK
2882 /* Set us so that we have processed and used all buffers, but have
2883 * not restocked the Rx queue with fresh buffers */
2884 rxq->read = rxq->write = 0;
2885 rxq->processed = RX_QUEUE_SIZE - 1;
2886 rxq->free_count = 0;
2887 spin_unlock_irqrestore(&rxq->lock, flags);
2888}
2889
2890#ifdef CONFIG_PM
2891static int fw_loaded = 0;
2892static const struct firmware *bootfw = NULL;
2893static const struct firmware *firmware = NULL;
2894static const struct firmware *ucode = NULL;
2895#endif
2896
2897static int ipw_load(struct ipw_priv *priv)
2898{
2899#ifndef CONFIG_PM
2900 const struct firmware *bootfw = NULL;
2901 const struct firmware *firmware = NULL;
2902 const struct firmware *ucode = NULL;
2903#endif
2904 int rc = 0, retries = 3;
2905
2906#ifdef CONFIG_PM
2907 if (!fw_loaded) {
2908#endif
2909 rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
bf79451e 2910 if (rc)
43f66a6c 2911 goto error;
bf79451e 2912
43f66a6c
JK
2913 switch (priv->ieee->iw_mode) {
2914 case IW_MODE_ADHOC:
bf79451e 2915 rc = ipw_get_fw(priv, &ucode,
43f66a6c 2916 IPW_FW_NAME("ibss_ucode"));
bf79451e 2917 if (rc)
43f66a6c 2918 goto error;
bf79451e 2919
43f66a6c
JK
2920 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
2921 break;
bf79451e 2922
ea2b26e0 2923#ifdef CONFIG_IPW_MONITOR
43f66a6c 2924 case IW_MODE_MONITOR:
bf79451e 2925 rc = ipw_get_fw(priv, &ucode,
ea2b26e0 2926 IPW_FW_NAME("sniffer_ucode"));
bf79451e 2927 if (rc)
43f66a6c 2928 goto error;
bf79451e 2929
0edd5b44
JG
2930 rc = ipw_get_fw(priv, &firmware,
2931 IPW_FW_NAME("sniffer"));
43f66a6c
JK
2932 break;
2933#endif
2934 case IW_MODE_INFRA:
0edd5b44 2935 rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode"));
bf79451e 2936 if (rc)
43f66a6c 2937 goto error;
bf79451e 2938
43f66a6c
JK
2939 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss"));
2940 break;
bf79451e 2941
43f66a6c
JK
2942 default:
2943 rc = -EINVAL;
2944 }
2945
bf79451e 2946 if (rc)
43f66a6c
JK
2947 goto error;
2948
2949#ifdef CONFIG_PM
2950 fw_loaded = 1;
2951 }
2952#endif
2953
2954 if (!priv->rxq)
2955 priv->rxq = ipw_rx_queue_alloc(priv);
2956 else
2957 ipw_rx_queue_reset(priv, priv->rxq);
2958 if (!priv->rxq) {
2959 IPW_ERROR("Unable to initialize Rx queue\n");
2960 goto error;
2961 }
2962
0edd5b44 2963 retry:
43f66a6c
JK
2964 /* Ensure interrupts are disabled */
2965 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
2966 priv->status &= ~STATUS_INT_ENABLED;
2967
2968 /* ack pending interrupts */
2969 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
bf79451e 2970
43f66a6c
JK
2971 ipw_stop_nic(priv);
2972
2973 rc = ipw_reset_nic(priv);
2974 if (rc) {
2975 IPW_ERROR("Unable to reset NIC\n");
2976 goto error;
2977 }
2978
bf79451e 2979 ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND,
43f66a6c
JK
2980 CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND);
2981
2982 /* DMA the initial boot firmware into the device */
bf79451e 2983 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
43f66a6c
JK
2984 bootfw->size - sizeof(struct fw_header));
2985 if (rc < 0) {
2986 IPW_ERROR("Unable to load boot firmware\n");
2987 goto error;
2988 }
2989
2990 /* kick start the device */
2991 ipw_start_nic(priv);
2992
2993 /* wait for the device to finish it's initial startup sequence */
bf79451e
JG
2994 rc = ipw_poll_bit(priv, CX2_INTA_RW,
2995 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c
JK
2996 if (rc < 0) {
2997 IPW_ERROR("device failed to boot initial fw image\n");
2998 goto error;
2999 }
3000 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
3001
bf79451e 3002 /* ack fw init done interrupt */
43f66a6c
JK
3003 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE);
3004
3005 /* DMA the ucode into the device */
bf79451e 3006 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
43f66a6c
JK
3007 ucode->size - sizeof(struct fw_header));
3008 if (rc < 0) {
3009 IPW_ERROR("Unable to load ucode\n");
3010 goto error;
3011 }
bf79451e 3012
43f66a6c
JK
3013 /* stop nic */
3014 ipw_stop_nic(priv);
3015
3016 /* DMA bss firmware into the device */
bf79451e
JG
3017 rc = ipw_load_firmware(priv, firmware->data +
3018 sizeof(struct fw_header),
43f66a6c 3019 firmware->size - sizeof(struct fw_header));
0edd5b44 3020 if (rc < 0) {
43f66a6c
JK
3021 IPW_ERROR("Unable to load firmware\n");
3022 goto error;
3023 }
3024
3025 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
3026
3027 rc = ipw_queue_reset(priv);
3028 if (rc) {
3029 IPW_ERROR("Unable to initialize queues\n");
3030 goto error;
3031 }
3032
3033 /* Ensure interrupts are disabled */
3034 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
c848d0af
JK
3035 /* ack pending interrupts */
3036 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
bf79451e 3037
43f66a6c
JK
3038 /* kick start the device */
3039 ipw_start_nic(priv);
3040
3041 if (ipw_read32(priv, CX2_INTA_RW) & CX2_INTA_BIT_PARITY_ERROR) {
3042 if (retries > 0) {
3043 IPW_WARNING("Parity error. Retrying init.\n");
3044 retries--;
3045 goto retry;
3046 }
3047
3048 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");
3049 rc = -EIO;
3050 goto error;
3051 }
3052
3053 /* wait for the device */
bf79451e
JG
3054 rc = ipw_poll_bit(priv, CX2_INTA_RW,
3055 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c
JK
3056 if (rc < 0) {
3057 IPW_ERROR("device failed to start after 500ms\n");
3058 goto error;
3059 }
3060 IPW_DEBUG_INFO("device response after %dms\n", rc);
3061
3062 /* ack fw init done interrupt */
3063 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE);
3064
3065 /* read eeprom data and initialize the eeprom region of sram */
3066 priv->eeprom_delay = 1;
bf79451e 3067 ipw_eeprom_init_sram(priv);
43f66a6c
JK
3068
3069 /* enable interrupts */
3070 ipw_enable_interrupts(priv);
3071
3072 /* Ensure our queue has valid packets */
3073 ipw_rx_queue_replenish(priv);
3074
3075 ipw_write32(priv, CX2_RX_READ_INDEX, priv->rxq->read);
3076
3077 /* ack pending interrupts */
3078 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
3079
3080#ifndef CONFIG_PM
3081 release_firmware(bootfw);
3082 release_firmware(ucode);
3083 release_firmware(firmware);
3084#endif
3085 return 0;
3086
0edd5b44 3087 error:
43f66a6c
JK
3088 if (priv->rxq) {
3089 ipw_rx_queue_free(priv, priv->rxq);
3090 priv->rxq = NULL;
3091 }
3092 ipw_tx_queue_free(priv);
3093 if (bootfw)
3094 release_firmware(bootfw);
3095 if (ucode)
3096 release_firmware(ucode);
3097 if (firmware)
3098 release_firmware(firmware);
3099#ifdef CONFIG_PM
3100 fw_loaded = 0;
3101 bootfw = ucode = firmware = NULL;
3102#endif
3103
3104 return rc;
3105}
3106
bf79451e 3107/**
43f66a6c
JK
3108 * DMA services
3109 *
3110 * Theory of operation
3111 *
3112 * A queue is a circular buffers with 'Read' and 'Write' pointers.
3113 * 2 empty entries always kept in the buffer to protect from overflow.
3114 *
3115 * For Tx queue, there are low mark and high mark limits. If, after queuing
bf79451e
JG
3116 * the packet for Tx, free space become < low mark, Tx queue stopped. When
3117 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
43f66a6c
JK
3118 * Tx queue resumed.
3119 *
3120 * The IPW operates with six queues, one receive queue in the device's
3121 * sram, one transmit queue for sending commands to the device firmware,
bf79451e 3122 * and four transmit queues for data.
43f66a6c 3123 *
bf79451e 3124 * The four transmit queues allow for performing quality of service (qos)
43f66a6c 3125 * transmissions as per the 802.11 protocol. Currently Linux does not
bf79451e 3126 * provide a mechanism to the user for utilizing prioritized queues, so
43f66a6c
JK
3127 * we only utilize the first data transmit queue (queue1).
3128 */
3129
3130/**
3131 * Driver allocates buffers of this size for Rx
3132 */
3133
3134static inline int ipw_queue_space(const struct clx2_queue *q)
3135{
3136 int s = q->last_used - q->first_empty;
3137 if (s <= 0)
3138 s += q->n_bd;
3139 s -= 2; /* keep some reserve to not confuse empty and full situations */
3140 if (s < 0)
3141 s = 0;
3142 return s;
3143}
3144
3145static inline int ipw_queue_inc_wrap(int index, int n_bd)
3146{
3147 return (++index == n_bd) ? 0 : index;
3148}
3149
3150/**
3151 * Initialize common DMA queue structure
bf79451e 3152 *
43f66a6c
JK
3153 * @param q queue to init
3154 * @param count Number of BD's to allocate. Should be power of 2
3155 * @param read_register Address for 'read' register
3156 * (not offset within BAR, full address)
3157 * @param write_register Address for 'write' register
3158 * (not offset within BAR, full address)
3159 * @param base_register Address for 'base' register
3160 * (not offset within BAR, full address)
3161 * @param size Address for 'size' register
3162 * (not offset within BAR, full address)
3163 */
bf79451e 3164static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,
0edd5b44 3165 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3166{
3167 q->n_bd = count;
3168
3169 q->low_mark = q->n_bd / 4;
3170 if (q->low_mark < 4)
3171 q->low_mark = 4;
3172
3173 q->high_mark = q->n_bd / 8;
3174 if (q->high_mark < 2)
3175 q->high_mark = 2;
3176
3177 q->first_empty = q->last_used = 0;
3178 q->reg_r = read;
3179 q->reg_w = write;
3180
3181 ipw_write32(priv, base, q->dma_addr);
3182 ipw_write32(priv, size, count);
3183 ipw_write32(priv, read, 0);
3184 ipw_write32(priv, write, 0);
3185
3186 _ipw_read32(priv, 0x90);
3187}
3188
bf79451e 3189static int ipw_queue_tx_init(struct ipw_priv *priv,
43f66a6c 3190 struct clx2_tx_queue *q,
0edd5b44 3191 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3192{
3193 struct pci_dev *dev = priv->pci_dev;
3194
3195 q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL);
3196 if (!q->txb) {
3197 IPW_ERROR("vmalloc for auxilary BD structures failed\n");
3198 return -ENOMEM;
3199 }
3200
0edd5b44
JG
3201 q->bd =
3202 pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr);
43f66a6c 3203 if (!q->bd) {
aaa4d308 3204 IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
0edd5b44 3205 sizeof(q->bd[0]) * count);
43f66a6c
JK
3206 kfree(q->txb);
3207 q->txb = NULL;
3208 return -ENOMEM;
3209 }
3210
3211 ipw_queue_init(priv, &q->q, count, read, write, base, size);
3212 return 0;
3213}
3214
3215/**
3216 * Free one TFD, those at index [txq->q.last_used].
3217 * Do NOT advance any indexes
bf79451e 3218 *
43f66a6c
JK
3219 * @param dev
3220 * @param txq
3221 */
3222static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
3223 struct clx2_tx_queue *txq)
3224{
3225 struct tfd_frame *bd = &txq->bd[txq->q.last_used];
3226 struct pci_dev *dev = priv->pci_dev;
3227 int i;
bf79451e 3228
43f66a6c
JK
3229 /* classify bd */
3230 if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE)
3231 /* nothing to cleanup after for host commands */
3232 return;
3233
3234 /* sanity check */
a613bffd
JK
3235 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
3236 IPW_ERROR("Too many chunks: %i\n",
3237 le32_to_cpu(bd->u.data.num_chunks));
43f66a6c
JK
3238 /** @todo issue fatal error, it is quite serious situation */
3239 return;
3240 }
3241
3242 /* unmap chunks if any */
a613bffd
JK
3243 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
3244 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
3245 le16_to_cpu(bd->u.data.chunk_len[i]),
3246 PCI_DMA_TODEVICE);
43f66a6c
JK
3247 if (txq->txb[txq->q.last_used]) {
3248 ieee80211_txb_free(txq->txb[txq->q.last_used]);
3249 txq->txb[txq->q.last_used] = NULL;
3250 }
3251 }
3252}
3253
3254/**
3255 * Deallocate DMA queue.
bf79451e 3256 *
43f66a6c
JK
3257 * Empty queue by removing and destroying all BD's.
3258 * Free all buffers.
bf79451e 3259 *
43f66a6c
JK
3260 * @param dev
3261 * @param q
3262 */
0edd5b44 3263static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)
43f66a6c
JK
3264{
3265 struct clx2_queue *q = &txq->q;
3266 struct pci_dev *dev = priv->pci_dev;
3267
bf79451e
JG
3268 if (q->n_bd == 0)
3269 return;
43f66a6c
JK
3270
3271 /* first, empty all BD's */
3272 for (; q->first_empty != q->last_used;
3273 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
3274 ipw_queue_tx_free_tfd(priv, txq);
3275 }
bf79451e 3276
43f66a6c 3277 /* free buffers belonging to queue itself */
0edd5b44 3278 pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
43f66a6c
JK
3279 q->dma_addr);
3280 kfree(txq->txb);
3281
3282 /* 0 fill whole structure */
3283 memset(txq, 0, sizeof(*txq));
3284}
3285
43f66a6c
JK
3286/**
3287 * Destroy all DMA queues and structures
bf79451e 3288 *
43f66a6c
JK
3289 * @param priv
3290 */
3291static void ipw_tx_queue_free(struct ipw_priv *priv)
3292{
3293 /* Tx CMD queue */
3294 ipw_queue_tx_free(priv, &priv->txq_cmd);
3295
3296 /* Tx queues */
3297 ipw_queue_tx_free(priv, &priv->txq[0]);
3298 ipw_queue_tx_free(priv, &priv->txq[1]);
3299 ipw_queue_tx_free(priv, &priv->txq[2]);
3300 ipw_queue_tx_free(priv, &priv->txq[3]);
3301}
3302
3303static void inline __maybe_wake_tx(struct ipw_priv *priv)
3304{
3305 if (netif_running(priv->net_dev)) {
3306 switch (priv->port_type) {
3307 case DCR_TYPE_MU_BSS:
3308 case DCR_TYPE_MU_IBSS:
a613bffd 3309 if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c 3310 return;
43f66a6c
JK
3311 }
3312 netif_wake_queue(priv->net_dev);
3313 }
3314
3315}
3316
0edd5b44 3317static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3318{
3319 /* First 3 bytes are manufacturer */
3320 bssid[0] = priv->mac_addr[0];
3321 bssid[1] = priv->mac_addr[1];
3322 bssid[2] = priv->mac_addr[2];
3323
3324 /* Last bytes are random */
0edd5b44 3325 get_random_bytes(&bssid[3], ETH_ALEN - 3);
43f66a6c 3326
0edd5b44
JG
3327 bssid[0] &= 0xfe; /* clear multicast bit */
3328 bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */
43f66a6c
JK
3329}
3330
0edd5b44 3331static inline u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3332{
3333 struct ipw_station_entry entry;
3334 int i;
3335
3336 for (i = 0; i < priv->num_stations; i++) {
3337 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
3338 /* Another node is active in network */
3339 priv->missed_adhoc_beacons = 0;
3340 if (!(priv->config & CFG_STATIC_CHANNEL))
3341 /* when other nodes drop out, we drop out */
3342 priv->config &= ~CFG_ADHOC_PERSIST;
3343
3344 return i;
3345 }
3346 }
3347
3348 if (i == MAX_STATIONS)
3349 return IPW_INVALID_STATION;
3350
3351 IPW_DEBUG_SCAN("Adding AdHoc station: " MAC_FMT "\n", MAC_ARG(bssid));
3352
3353 entry.reserved = 0;
3354 entry.support_mode = 0;
3355 memcpy(entry.mac_addr, bssid, ETH_ALEN);
3356 memcpy(priv->stations[i], bssid, ETH_ALEN);
3357 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),
0edd5b44 3358 &entry, sizeof(entry));
43f66a6c
JK
3359 priv->num_stations++;
3360
3361 return i;
3362}
3363
0edd5b44 3364static inline u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3365{
3366 int i;
3367
bf79451e
JG
3368 for (i = 0; i < priv->num_stations; i++)
3369 if (!memcmp(priv->stations[i], bssid, ETH_ALEN))
43f66a6c
JK
3370 return i;
3371
3372 return IPW_INVALID_STATION;
3373}
3374
3375static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
3376{
3377 int err;
3378
3379 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) {
3380 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
3381 return;
3382 }
3383
3384 IPW_DEBUG_ASSOC("Disassocation attempt from " MAC_FMT " "
3385 "on channel %d.\n",
bf79451e 3386 MAC_ARG(priv->assoc_request.bssid),
43f66a6c
JK
3387 priv->assoc_request.channel);
3388
3389 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
3390 priv->status |= STATUS_DISASSOCIATING;
3391
3392 if (quiet)
3393 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
3394 else
3395 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3396 err = ipw_send_associate(priv, &priv->assoc_request);
3397 if (err) {
3398 IPW_DEBUG_HC("Attempt to send [dis]associate command "
3399 "failed.\n");
3400 return;
3401 }
3402
3403}
3404
c848d0af 3405static int ipw_disassociate(void *data)
43f66a6c 3406{
c848d0af
JK
3407 struct ipw_priv *priv = data;
3408 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3409 return 0;
43f66a6c 3410 ipw_send_disassociate(data, 0);
c848d0af
JK
3411 return 1;
3412}
3413
3414static void ipw_bg_disassociate(void *data)
3415{
3416 struct ipw_priv *priv = data;
3417 down(&priv->sem);
3418 ipw_disassociate(data);
3419 up(&priv->sem);
43f66a6c
JK
3420}
3421
43f66a6c
JK
3422struct ipw_status_code {
3423 u16 status;
3424 const char *reason;
3425};
3426
3427static const struct ipw_status_code ipw_status_codes[] = {
3428 {0x00, "Successful"},
3429 {0x01, "Unspecified failure"},
3430 {0x0A, "Cannot support all requested capabilities in the "
3431 "Capability information field"},
3432 {0x0B, "Reassociation denied due to inability to confirm that "
3433 "association exists"},
3434 {0x0C, "Association denied due to reason outside the scope of this "
3435 "standard"},
0edd5b44
JG
3436 {0x0D,
3437 "Responding station does not support the specified authentication "
43f66a6c 3438 "algorithm"},
0edd5b44
JG
3439 {0x0E,
3440 "Received an Authentication frame with authentication sequence "
43f66a6c
JK
3441 "transaction sequence number out of expected sequence"},
3442 {0x0F, "Authentication rejected because of challenge failure"},
3443 {0x10, "Authentication rejected due to timeout waiting for next "
3444 "frame in sequence"},
3445 {0x11, "Association denied because AP is unable to handle additional "
3446 "associated stations"},
0edd5b44
JG
3447 {0x12,
3448 "Association denied due to requesting station not supporting all "
43f66a6c 3449 "of the datarates in the BSSBasicServiceSet Parameter"},
0edd5b44
JG
3450 {0x13,
3451 "Association denied due to requesting station not supporting "
43f66a6c 3452 "short preamble operation"},
0edd5b44
JG
3453 {0x14,
3454 "Association denied due to requesting station not supporting "
43f66a6c 3455 "PBCC encoding"},
0edd5b44
JG
3456 {0x15,
3457 "Association denied due to requesting station not supporting "
43f66a6c 3458 "channel agility"},
0edd5b44
JG
3459 {0x19,
3460 "Association denied due to requesting station not supporting "
43f66a6c 3461 "short slot operation"},
0edd5b44
JG
3462 {0x1A,
3463 "Association denied due to requesting station not supporting "
43f66a6c
JK
3464 "DSSS-OFDM operation"},
3465 {0x28, "Invalid Information Element"},
3466 {0x29, "Group Cipher is not valid"},
3467 {0x2A, "Pairwise Cipher is not valid"},
3468 {0x2B, "AKMP is not valid"},
3469 {0x2C, "Unsupported RSN IE version"},
3470 {0x2D, "Invalid RSN IE Capabilities"},
3471 {0x2E, "Cipher suite is rejected per security policy"},
3472};
3473
3474#ifdef CONFIG_IPW_DEBUG
bf79451e 3475static const char *ipw_get_status_code(u16 status)
43f66a6c
JK
3476{
3477 int i;
bf79451e 3478 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
ea2b26e0 3479 if (ipw_status_codes[i].status == (status & 0xff))
43f66a6c
JK
3480 return ipw_status_codes[i].reason;
3481 return "Unknown status value.";
3482}
3483#endif
3484
3485static void inline average_init(struct average *avg)
3486{
3487 memset(avg, 0, sizeof(*avg));
3488}
3489
3490static void inline average_add(struct average *avg, s16 val)
3491{
3492 avg->sum -= avg->entries[avg->pos];
3493 avg->sum += val;
3494 avg->entries[avg->pos++] = val;
3495 if (unlikely(avg->pos == AVG_ENTRIES)) {
3496 avg->init = 1;
3497 avg->pos = 0;
3498 }
3499}
3500
3501static s16 inline average_value(struct average *avg)
3502{
3503 if (!unlikely(avg->init)) {
3504 if (avg->pos)
3505 return avg->sum / avg->pos;
3506 return 0;
3507 }
3508
3509 return avg->sum / AVG_ENTRIES;
3510}
3511
3512static void ipw_reset_stats(struct ipw_priv *priv)
3513{
3514 u32 len = sizeof(u32);
3515
3516 priv->quality = 0;
3517
3518 average_init(&priv->average_missed_beacons);
3519 average_init(&priv->average_rssi);
3520 average_init(&priv->average_noise);
3521
3522 priv->last_rate = 0;
3523 priv->last_missed_beacons = 0;
3524 priv->last_rx_packets = 0;
3525 priv->last_tx_packets = 0;
3526 priv->last_tx_failures = 0;
bf79451e 3527
43f66a6c
JK
3528 /* Firmware managed, reset only when NIC is restarted, so we have to
3529 * normalize on the current value */
bf79451e 3530 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,
43f66a6c 3531 &priv->last_rx_err, &len);
bf79451e 3532 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,
43f66a6c
JK
3533 &priv->last_tx_failures, &len);
3534
3535 /* Driver managed, reset with each association */
3536 priv->missed_adhoc_beacons = 0;
3537 priv->missed_beacons = 0;
3538 priv->tx_packets = 0;
3539 priv->rx_packets = 0;
3540
3541}
3542
43f66a6c
JK
3543static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3544{
3545 u32 i = 0x80000000;
3546 u32 mask = priv->rates_mask;
3547 /* If currently associated in B mode, restrict the maximum
3548 * rate match to B rates */
3549 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
3550 mask &= IEEE80211_CCK_RATES_MASK;
3551
3552 /* TODO: Verify that the rate is supported by the current rates
3553 * list. */
3554
0edd5b44
JG
3555 while (i && !(mask & i))
3556 i >>= 1;
43f66a6c 3557 switch (i) {
ea2b26e0
JK
3558 case IEEE80211_CCK_RATE_1MB_MASK:
3559 return 1000000;
3560 case IEEE80211_CCK_RATE_2MB_MASK:
3561 return 2000000;
3562 case IEEE80211_CCK_RATE_5MB_MASK:
3563 return 5500000;
3564 case IEEE80211_OFDM_RATE_6MB_MASK:
3565 return 6000000;
3566 case IEEE80211_OFDM_RATE_9MB_MASK:
3567 return 9000000;
3568 case IEEE80211_CCK_RATE_11MB_MASK:
3569 return 11000000;
3570 case IEEE80211_OFDM_RATE_12MB_MASK:
3571 return 12000000;
3572 case IEEE80211_OFDM_RATE_18MB_MASK:
3573 return 18000000;
3574 case IEEE80211_OFDM_RATE_24MB_MASK:
3575 return 24000000;
3576 case IEEE80211_OFDM_RATE_36MB_MASK:
3577 return 36000000;
3578 case IEEE80211_OFDM_RATE_48MB_MASK:
3579 return 48000000;
3580 case IEEE80211_OFDM_RATE_54MB_MASK:
3581 return 54000000;
43f66a6c
JK
3582 }
3583
bf79451e 3584 if (priv->ieee->mode == IEEE_B)
43f66a6c
JK
3585 return 11000000;
3586 else
3587 return 54000000;
3588}
3589
3590static u32 ipw_get_current_rate(struct ipw_priv *priv)
3591{
3592 u32 rate, len = sizeof(rate);
3593 int err;
3594
bf79451e 3595 if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c
JK
3596 return 0;
3597
3598 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {
bf79451e 3599 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,
43f66a6c
JK
3600 &len);
3601 if (err) {
3602 IPW_DEBUG_INFO("failed querying ordinals.\n");
3603 return 0;
3604 }
bf79451e 3605 } else
43f66a6c
JK
3606 return ipw_get_max_rate(priv);
3607
3608 switch (rate) {
ea2b26e0
JK
3609 case IPW_TX_RATE_1MB:
3610 return 1000000;
3611 case IPW_TX_RATE_2MB:
3612 return 2000000;
3613 case IPW_TX_RATE_5MB:
3614 return 5500000;
3615 case IPW_TX_RATE_6MB:
3616 return 6000000;
3617 case IPW_TX_RATE_9MB:
3618 return 9000000;
3619 case IPW_TX_RATE_11MB:
3620 return 11000000;
3621 case IPW_TX_RATE_12MB:
3622 return 12000000;
3623 case IPW_TX_RATE_18MB:
3624 return 18000000;
3625 case IPW_TX_RATE_24MB:
3626 return 24000000;
3627 case IPW_TX_RATE_36MB:
3628 return 36000000;
3629 case IPW_TX_RATE_48MB:
3630 return 48000000;
3631 case IPW_TX_RATE_54MB:
3632 return 54000000;
43f66a6c
JK
3633 }
3634
3635 return 0;
3636}
3637
43f66a6c
JK
3638#define IPW_STATS_INTERVAL (2 * HZ)
3639static void ipw_gather_stats(struct ipw_priv *priv)
3640{
3641 u32 rx_err, rx_err_delta, rx_packets_delta;
3642 u32 tx_failures, tx_failures_delta, tx_packets_delta;
3643 u32 missed_beacons_percent, missed_beacons_delta;
3644 u32 quality = 0;
3645 u32 len = sizeof(u32);
3646 s16 rssi;
bf79451e 3647 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
0edd5b44 3648 rate_quality;
ea2b26e0 3649 u32 max_rate;
43f66a6c
JK
3650
3651 if (!(priv->status & STATUS_ASSOCIATED)) {
3652 priv->quality = 0;
3653 return;
3654 }
3655
3656 /* Update the statistics */
bf79451e 3657 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,
43f66a6c 3658 &priv->missed_beacons, &len);
0edd5b44 3659 missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons;
43f66a6c
JK
3660 priv->last_missed_beacons = priv->missed_beacons;
3661 if (priv->assoc_request.beacon_interval) {
3662 missed_beacons_percent = missed_beacons_delta *
0edd5b44
JG
3663 (HZ * priv->assoc_request.beacon_interval) /
3664 (IPW_STATS_INTERVAL * 10);
43f66a6c
JK
3665 } else {
3666 missed_beacons_percent = 0;
3667 }
3668 average_add(&priv->average_missed_beacons, missed_beacons_percent);
3669
3670 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);
3671 rx_err_delta = rx_err - priv->last_rx_err;
3672 priv->last_rx_err = rx_err;
3673
3674 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);
3675 tx_failures_delta = tx_failures - priv->last_tx_failures;
3676 priv->last_tx_failures = tx_failures;
3677
3678 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;
3679 priv->last_rx_packets = priv->rx_packets;
3680
3681 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;
3682 priv->last_tx_packets = priv->tx_packets;
3683
3684 /* Calculate quality based on the following:
bf79451e 3685 *
43f66a6c
JK
3686 * Missed beacon: 100% = 0, 0% = 70% missed
3687 * Rate: 60% = 1Mbs, 100% = Max
3688 * Rx and Tx errors represent a straight % of total Rx/Tx
3689 * RSSI: 100% = > -50, 0% = < -80
3690 * Rx errors: 100% = 0, 0% = 50% missed
bf79451e 3691 *
43f66a6c
JK
3692 * The lowest computed quality is used.
3693 *
3694 */
3695#define BEACON_THRESHOLD 5
3696 beacon_quality = 100 - missed_beacons_percent;
3697 if (beacon_quality < BEACON_THRESHOLD)
3698 beacon_quality = 0;
3699 else
bf79451e 3700 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /
0edd5b44 3701 (100 - BEACON_THRESHOLD);
bf79451e 3702 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",
43f66a6c 3703 beacon_quality, missed_beacons_percent);
bf79451e 3704
43f66a6c 3705 priv->last_rate = ipw_get_current_rate(priv);
ea2b26e0
JK
3706 max_rate = ipw_get_max_rate(priv);
3707 rate_quality = priv->last_rate * 40 / max_rate + 60;
43f66a6c
JK
3708 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3709 rate_quality, priv->last_rate / 1000000);
bf79451e 3710
0edd5b44 3711 if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta)
bf79451e 3712 rx_quality = 100 - (rx_err_delta * 100) /
0edd5b44 3713 (rx_packets_delta + rx_err_delta);
43f66a6c
JK
3714 else
3715 rx_quality = 100;
3716 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",
3717 rx_quality, rx_err_delta, rx_packets_delta);
bf79451e 3718
0edd5b44 3719 if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta)
bf79451e 3720 tx_quality = 100 - (tx_failures_delta * 100) /
0edd5b44 3721 (tx_packets_delta + tx_failures_delta);
43f66a6c
JK
3722 else
3723 tx_quality = 100;
3724 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",
3725 tx_quality, tx_failures_delta, tx_packets_delta);
bf79451e 3726
43f66a6c 3727 rssi = average_value(&priv->average_rssi);
c848d0af
JK
3728 signal_quality =
3729 (100 *
3730 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
3731 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
3732 (priv->ieee->perfect_rssi - rssi) *
3733 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
3734 62 * (priv->ieee->perfect_rssi - rssi))) /
3735 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
3736 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
3737 if (signal_quality > 100)
43f66a6c 3738 signal_quality = 100;
c848d0af 3739 else if (signal_quality < 1)
43f66a6c 3740 signal_quality = 0;
ea2b26e0 3741
43f66a6c
JK
3742 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3743 signal_quality, rssi);
bf79451e
JG
3744
3745 quality = min(beacon_quality,
43f66a6c
JK
3746 min(rate_quality,
3747 min(tx_quality, min(rx_quality, signal_quality))));
3748 if (quality == beacon_quality)
0edd5b44
JG
3749 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
3750 quality);
43f66a6c 3751 if (quality == rate_quality)
0edd5b44
JG
3752 IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n",
3753 quality);
43f66a6c 3754 if (quality == tx_quality)
0edd5b44
JG
3755 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n",
3756 quality);
43f66a6c 3757 if (quality == rx_quality)
0edd5b44
JG
3758 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n",
3759 quality);
43f66a6c 3760 if (quality == signal_quality)
0edd5b44
JG
3761 IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n",
3762 quality);
43f66a6c
JK
3763
3764 priv->quality = quality;
bf79451e
JG
3765
3766 queue_delayed_work(priv->workqueue, &priv->gather_stats,
43f66a6c
JK
3767 IPW_STATS_INTERVAL);
3768}
3769
c848d0af
JK
3770static void ipw_bg_gather_stats(void *data)
3771{
3772 struct ipw_priv *priv = data;
3773 down(&priv->sem);
3774 ipw_gather_stats(data);
3775 up(&priv->sem);
3776}
3777
ea2b26e0
JK
3778static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
3779 int missed_count)
3780{
3781 priv->notif_missed_beacons = missed_count;
3782
3783 if (missed_count > priv->missed_beacon_threshold &&
3784 priv->status & STATUS_ASSOCIATED) {
3785 /* If associated and we've hit the missed
3786 * beacon threshold, disassociate, turn
3787 * off roaming, and abort any active scans */
3788 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3789 IPW_DL_STATE,
3790 "Missed beacon: %d - disassociate\n", missed_count);
3791 priv->status &= ~STATUS_ROAMING;
a613bffd
JK
3792 if (priv->status & STATUS_SCANNING) {
3793 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3794 IPW_DL_STATE,
3795 "Aborting scan with missed beacon.\n");
ea2b26e0 3796 queue_work(priv->workqueue, &priv->abort_scan);
a613bffd
JK
3797 }
3798
ea2b26e0
JK
3799 queue_work(priv->workqueue, &priv->disassociate);
3800 return;
3801 }
3802
3803 if (priv->status & STATUS_ROAMING) {
3804 /* If we are currently roaming, then just
3805 * print a debug statement... */
3806 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3807 "Missed beacon: %d - roam in progress\n",
3808 missed_count);
3809 return;
3810 }
3811
3812 if (missed_count > priv->roaming_threshold) {
3813 /* If we are not already roaming, set the ROAM
3814 * bit in the status and kick off a scan */
3815 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3816 "Missed beacon: %d - initiate "
3817 "roaming\n", missed_count);
3818 if (!(priv->status & STATUS_ROAMING)) {
3819 priv->status |= STATUS_ROAMING;
3820 if (!(priv->status & STATUS_SCANNING))
3821 queue_work(priv->workqueue,
3822 &priv->request_scan);
3823 }
3824 return;
3825 }
3826
3827 if (priv->status & STATUS_SCANNING) {
3828 /* Stop scan to keep fw from getting
3829 * stuck (only if we aren't roaming --
3830 * otherwise we'll never scan more than 2 or 3
3831 * channels..) */
a613bffd
JK
3832 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3833 IPW_DL_STATE, "Aborting scan with missed beacon.\n");
ea2b26e0
JK
3834 queue_work(priv->workqueue, &priv->abort_scan);
3835 }
3836
3837 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
3838
3839}
3840
43f66a6c
JK
3841/**
3842 * Handle host notification packet.
3843 * Called from interrupt routine
3844 */
0edd5b44 3845static inline void ipw_rx_notification(struct ipw_priv *priv,
43f66a6c
JK
3846 struct ipw_rx_notification *notif)
3847{
a613bffd
JK
3848 notif->size = le16_to_cpu(notif->size);
3849
0edd5b44 3850 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
bf79451e 3851
43f66a6c 3852 switch (notif->subtype) {
0edd5b44
JG
3853 case HOST_NOTIFICATION_STATUS_ASSOCIATED:{
3854 struct notif_association *assoc = &notif->u.assoc;
3855
3856 switch (assoc->state) {
3857 case CMAS_ASSOCIATED:{
3858 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3859 IPW_DL_ASSOC,
3860 "associated: '%s' " MAC_FMT
3861 " \n",
3862 escape_essid(priv->essid,
3863 priv->essid_len),
3864 MAC_ARG(priv->bssid));
3865
3866 switch (priv->ieee->iw_mode) {
3867 case IW_MODE_INFRA:
3868 memcpy(priv->ieee->bssid,
3869 priv->bssid, ETH_ALEN);
3870 break;
3871
3872 case IW_MODE_ADHOC:
3873 memcpy(priv->ieee->bssid,
3874 priv->bssid, ETH_ALEN);
3875
3876 /* clear out the station table */
3877 priv->num_stations = 0;
3878
3879 IPW_DEBUG_ASSOC
3880 ("queueing adhoc check\n");
3881 queue_delayed_work(priv->
3882 workqueue,
3883 &priv->
3884 adhoc_check,
3885 priv->
3886 assoc_request.
3887 beacon_interval);
3888 break;
3889 }
3890
3891 priv->status &= ~STATUS_ASSOCIATING;
3892 priv->status |= STATUS_ASSOCIATED;
3893
a613bffd 3894 schedule_work(&priv->link_up);
0edd5b44 3895
0edd5b44
JG
3896 break;
3897 }
bf79451e 3898
0edd5b44
JG
3899 case CMAS_AUTHENTICATED:{
3900 if (priv->
3901 status & (STATUS_ASSOCIATED |
3902 STATUS_AUTH)) {
43f66a6c 3903#ifdef CONFIG_IPW_DEBUG
0edd5b44
JG
3904 struct notif_authenticate *auth
3905 = &notif->u.auth;
3906 IPW_DEBUG(IPW_DL_NOTIF |
3907 IPW_DL_STATE |
3908 IPW_DL_ASSOC,
3909 "deauthenticated: '%s' "
3910 MAC_FMT
3911 ": (0x%04X) - %s \n",
3912 escape_essid(priv->
3913 essid,
3914 priv->
3915 essid_len),
3916 MAC_ARG(priv->bssid),
3917 ntohs(auth->status),
3918 ipw_get_status_code
3919 (ntohs
3920 (auth->status)));
43f66a6c
JK
3921#endif
3922
0edd5b44
JG
3923 priv->status &=
3924 ~(STATUS_ASSOCIATING |
3925 STATUS_AUTH |
3926 STATUS_ASSOCIATED);
3927
a613bffd 3928 schedule_work(&priv->link_down);
0edd5b44
JG
3929 break;
3930 }
3931
3932 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3933 IPW_DL_ASSOC,
3934 "authenticated: '%s' " MAC_FMT
3935 "\n",
3936 escape_essid(priv->essid,
3937 priv->essid_len),
3938 MAC_ARG(priv->bssid));
3939 break;
3940 }
3941
3942 case CMAS_INIT:{
ea2b26e0
JK
3943 if (priv->status & STATUS_AUTH) {
3944 struct
3945 ieee80211_assoc_response
3946 *resp;
3947 resp =
3948 (struct
3949 ieee80211_assoc_response
3950 *)&notif->u.raw;
3951 IPW_DEBUG(IPW_DL_NOTIF |
3952 IPW_DL_STATE |
3953 IPW_DL_ASSOC,
3954 "association failed (0x%04X): %s\n",
3955 ntohs(resp->status),
3956 ipw_get_status_code
3957 (ntohs
3958 (resp->status)));
3959 }
3960
0edd5b44
JG
3961 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3962 IPW_DL_ASSOC,
3963 "disassociated: '%s' " MAC_FMT
3964 " \n",
3965 escape_essid(priv->essid,
3966 priv->essid_len),
3967 MAC_ARG(priv->bssid));
3968
3969 priv->status &=
3970 ~(STATUS_DISASSOCIATING |
3971 STATUS_ASSOCIATING |
3972 STATUS_ASSOCIATED | STATUS_AUTH);
3973
a613bffd 3974 schedule_work(&priv->link_down);
0edd5b44 3975
0edd5b44
JG
3976 break;
3977 }
43f66a6c 3978
0edd5b44
JG
3979 default:
3980 IPW_ERROR("assoc: unknown (%d)\n",
3981 assoc->state);
43f66a6c 3982 break;
bf79451e 3983 }
43f66a6c 3984
43f66a6c
JK
3985 break;
3986 }
bf79451e 3987
0edd5b44
JG
3988 case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{
3989 struct notif_authenticate *auth = &notif->u.auth;
3990 switch (auth->state) {
3991 case CMAS_AUTHENTICATED:
3992 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3993 "authenticated: '%s' " MAC_FMT " \n",
3994 escape_essid(priv->essid,
3995 priv->essid_len),
3996 MAC_ARG(priv->bssid));
3997 priv->status |= STATUS_AUTH;
3998 break;
43f66a6c 3999
0edd5b44
JG
4000 case CMAS_INIT:
4001 if (priv->status & STATUS_AUTH) {
4002 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4003 IPW_DL_ASSOC,
4004 "authentication failed (0x%04X): %s\n",
4005 ntohs(auth->status),
4006 ipw_get_status_code(ntohs
4007 (auth->
4008 status)));
4009 }
4010 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4011 IPW_DL_ASSOC,
4012 "deauthenticated: '%s' " MAC_FMT "\n",
4013 escape_essid(priv->essid,
4014 priv->essid_len),
4015 MAC_ARG(priv->bssid));
bf79451e 4016
0edd5b44
JG
4017 priv->status &= ~(STATUS_ASSOCIATING |
4018 STATUS_AUTH |
4019 STATUS_ASSOCIATED);
43f66a6c 4020
a613bffd 4021 schedule_work(&priv->link_down);
0edd5b44 4022 break;
43f66a6c 4023
0edd5b44
JG
4024 case CMAS_TX_AUTH_SEQ_1:
4025 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4026 IPW_DL_ASSOC, "AUTH_SEQ_1\n");
4027 break;
4028 case CMAS_RX_AUTH_SEQ_2:
4029 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4030 IPW_DL_ASSOC, "AUTH_SEQ_2\n");
4031 break;
4032 case CMAS_AUTH_SEQ_1_PASS:
4033 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4034 IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n");
4035 break;
4036 case CMAS_AUTH_SEQ_1_FAIL:
4037 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4038 IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n");
4039 break;
4040 case CMAS_TX_AUTH_SEQ_3:
4041 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4042 IPW_DL_ASSOC, "AUTH_SEQ_3\n");
4043 break;
4044 case CMAS_RX_AUTH_SEQ_4:
4045 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4046 IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n");
4047 break;
4048 case CMAS_AUTH_SEQ_2_PASS:
4049 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4050 IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n");
4051 break;
4052 case CMAS_AUTH_SEQ_2_FAIL:
4053 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4054 IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n");
4055 break;
4056 case CMAS_TX_ASSOC:
4057 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4058 IPW_DL_ASSOC, "TX_ASSOC\n");
4059 break;
4060 case CMAS_RX_ASSOC_RESP:
4061 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4062 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
4063 break;
4064 case CMAS_ASSOCIATED:
4065 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4066 IPW_DL_ASSOC, "ASSOCIATED\n");
4067 break;
4068 default:
4069 IPW_DEBUG_NOTIF("auth: failure - %d\n",
4070 auth->state);
4071 break;
43f66a6c 4072 }
43f66a6c
JK
4073 break;
4074 }
4075
0edd5b44
JG
4076 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{
4077 struct notif_channel_result *x =
4078 &notif->u.channel_result;
43f66a6c 4079
0edd5b44
JG
4080 if (notif->size == sizeof(*x)) {
4081 IPW_DEBUG_SCAN("Scan result for channel %d\n",
4082 x->channel_num);
4083 } else {
4084 IPW_DEBUG_SCAN("Scan result of wrong size %d "
4085 "(should be %zd)\n",
4086 notif->size, sizeof(*x));
bf79451e 4087 }
43f66a6c
JK
4088 break;
4089 }
43f66a6c 4090
0edd5b44
JG
4091 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{
4092 struct notif_scan_complete *x = &notif->u.scan_complete;
4093 if (notif->size == sizeof(*x)) {
4094 IPW_DEBUG_SCAN
4095 ("Scan completed: type %d, %d channels, "
4096 "%d status\n", x->scan_type,
4097 x->num_channels, x->status);
4098 } else {
4099 IPW_ERROR("Scan completed of wrong size %d "
4100 "(should be %zd)\n",
4101 notif->size, sizeof(*x));
4102 }
43f66a6c 4103
0edd5b44
JG
4104 priv->status &=
4105 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
4106
4107 cancel_delayed_work(&priv->scan_check);
4108
4109 if (!(priv->status & (STATUS_ASSOCIATED |
4110 STATUS_ASSOCIATING |
4111 STATUS_ROAMING |
4112 STATUS_DISASSOCIATING)))
4113 queue_work(priv->workqueue, &priv->associate);
4114 else if (priv->status & STATUS_ROAMING) {
4115 /* If a scan completed and we are in roam mode, then
4116 * the scan that completed was the one requested as a
4117 * result of entering roam... so, schedule the
4118 * roam work */
4119 queue_work(priv->workqueue, &priv->roam);
4120 } else if (priv->status & STATUS_SCAN_PENDING)
4121 queue_work(priv->workqueue,
4122 &priv->request_scan);
a613bffd
JK
4123 else if (priv->config & CFG_BACKGROUND_SCAN
4124 && priv->status & STATUS_ASSOCIATED)
4125 queue_delayed_work(priv->workqueue,
4126 &priv->request_scan, HZ);
43f66a6c 4127
0edd5b44
JG
4128 priv->ieee->scans++;
4129 break;
43f66a6c 4130 }
43f66a6c 4131
0edd5b44
JG
4132 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
4133 struct notif_frag_length *x = &notif->u.frag_len;
43f66a6c 4134
a613bffd
JK
4135 if (notif->size == sizeof(*x))
4136 IPW_ERROR("Frag length: %d\n",
4137 le16_to_cpu(x->frag_length));
4138 else
0edd5b44
JG
4139 IPW_ERROR("Frag length of wrong size %d "
4140 "(should be %zd)\n",
4141 notif->size, sizeof(*x));
0edd5b44 4142 break;
43f66a6c 4143 }
43f66a6c 4144
0edd5b44
JG
4145 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
4146 struct notif_link_deterioration *x =
4147 &notif->u.link_deterioration;
4148 if (notif->size == sizeof(*x)) {
4149 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4150 "link deterioration: '%s' " MAC_FMT
4151 " \n", escape_essid(priv->essid,
4152 priv->essid_len),
4153 MAC_ARG(priv->bssid));
4154 memcpy(&priv->last_link_deterioration, x,
4155 sizeof(*x));
4156 } else {
4157 IPW_ERROR("Link Deterioration of wrong size %d "
4158 "(should be %zd)\n",
4159 notif->size, sizeof(*x));
4160 }
43f66a6c
JK
4161 break;
4162 }
4163
0edd5b44
JG
4164 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
4165 IPW_ERROR("Dino config\n");
4166 if (priv->hcmd
a613bffd 4167 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
0edd5b44 4168 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
a613bffd 4169
0edd5b44
JG
4170 break;
4171 }
43f66a6c 4172
0edd5b44
JG
4173 case HOST_NOTIFICATION_STATUS_BEACON_STATE:{
4174 struct notif_beacon_state *x = &notif->u.beacon_state;
4175 if (notif->size != sizeof(*x)) {
4176 IPW_ERROR
4177 ("Beacon state of wrong size %d (should "
4178 "be %zd)\n", notif->size, sizeof(*x));
4179 break;
43f66a6c
JK
4180 }
4181
a613bffd
JK
4182 if (le32_to_cpu(x->state) ==
4183 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
4184 ipw_handle_missed_beacon(priv,
4185 le32_to_cpu(x->
4186 number));
43f66a6c 4187
0edd5b44
JG
4188 break;
4189 }
43f66a6c 4190
0edd5b44
JG
4191 case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{
4192 struct notif_tgi_tx_key *x = &notif->u.tgi_tx_key;
4193 if (notif->size == sizeof(*x)) {
4194 IPW_ERROR("TGi Tx Key: state 0x%02x sec type "
4195 "0x%02x station %d\n",
4196 x->key_state, x->security_type,
4197 x->station_index);
4198 break;
4199 }
43f66a6c 4200
0edd5b44
JG
4201 IPW_ERROR
4202 ("TGi Tx Key of wrong size %d (should be %zd)\n",
4203 notif->size, sizeof(*x));
43f66a6c 4204 break;
bf79451e 4205 }
43f66a6c 4206
0edd5b44
JG
4207 case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{
4208 struct notif_calibration *x = &notif->u.calibration;
43f66a6c 4209
0edd5b44
JG
4210 if (notif->size == sizeof(*x)) {
4211 memcpy(&priv->calib, x, sizeof(*x));
4212 IPW_DEBUG_INFO("TODO: Calibration\n");
4213 break;
4214 }
43f66a6c 4215
0edd5b44
JG
4216 IPW_ERROR
4217 ("Calibration of wrong size %d (should be %zd)\n",
4218 notif->size, sizeof(*x));
43f66a6c 4219 break;
bf79451e
JG
4220 }
4221
0edd5b44
JG
4222 case HOST_NOTIFICATION_NOISE_STATS:{
4223 if (notif->size == sizeof(u32)) {
4224 priv->last_noise =
a613bffd
JK
4225 (u8) (le32_to_cpu(notif->u.noise.value) &
4226 0xff);
0edd5b44
JG
4227 average_add(&priv->average_noise,
4228 priv->last_noise);
4229 break;
4230 }
43f66a6c 4231
0edd5b44
JG
4232 IPW_ERROR
4233 ("Noise stat is wrong size %d (should be %zd)\n",
4234 notif->size, sizeof(u32));
43f66a6c
JK
4235 break;
4236 }
4237
43f66a6c
JK
4238 default:
4239 IPW_ERROR("Unknown notification: "
4240 "subtype=%d,flags=0x%2x,size=%d\n",
4241 notif->subtype, notif->flags, notif->size);
4242 }
4243}
4244
4245/**
4246 * Destroys all DMA structures and initialise them again
bf79451e 4247 *
43f66a6c
JK
4248 * @param priv
4249 * @return error code
4250 */
4251static int ipw_queue_reset(struct ipw_priv *priv)
4252{
4253 int rc = 0;
4254 /** @todo customize queue sizes */
4255 int nTx = 64, nTxCmd = 8;
4256 ipw_tx_queue_free(priv);
4257 /* Tx CMD queue */
4258 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
4259 CX2_TX_CMD_QUEUE_READ_INDEX,
4260 CX2_TX_CMD_QUEUE_WRITE_INDEX,
4261 CX2_TX_CMD_QUEUE_BD_BASE,
4262 CX2_TX_CMD_QUEUE_BD_SIZE);
4263 if (rc) {
4264 IPW_ERROR("Tx Cmd queue init failed\n");
4265 goto error;
4266 }
4267 /* Tx queue(s) */
4268 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
4269 CX2_TX_QUEUE_0_READ_INDEX,
4270 CX2_TX_QUEUE_0_WRITE_INDEX,
0edd5b44 4271 CX2_TX_QUEUE_0_BD_BASE, CX2_TX_QUEUE_0_BD_SIZE);
43f66a6c
JK
4272 if (rc) {
4273 IPW_ERROR("Tx 0 queue init failed\n");
4274 goto error;
4275 }
4276 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
4277 CX2_TX_QUEUE_1_READ_INDEX,
4278 CX2_TX_QUEUE_1_WRITE_INDEX,
0edd5b44 4279 CX2_TX_QUEUE_1_BD_BASE, CX2_TX_QUEUE_1_BD_SIZE);
43f66a6c
JK
4280 if (rc) {
4281 IPW_ERROR("Tx 1 queue init failed\n");
4282 goto error;
4283 }
4284 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
4285 CX2_TX_QUEUE_2_READ_INDEX,
4286 CX2_TX_QUEUE_2_WRITE_INDEX,
0edd5b44 4287 CX2_TX_QUEUE_2_BD_BASE, CX2_TX_QUEUE_2_BD_SIZE);
43f66a6c
JK
4288 if (rc) {
4289 IPW_ERROR("Tx 2 queue init failed\n");
4290 goto error;
4291 }
4292 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
4293 CX2_TX_QUEUE_3_READ_INDEX,
4294 CX2_TX_QUEUE_3_WRITE_INDEX,
0edd5b44 4295 CX2_TX_QUEUE_3_BD_BASE, CX2_TX_QUEUE_3_BD_SIZE);
43f66a6c
JK
4296 if (rc) {
4297 IPW_ERROR("Tx 3 queue init failed\n");
4298 goto error;
4299 }
4300 /* statistics */
4301 priv->rx_bufs_min = 0;
4302 priv->rx_pend_max = 0;
4303 return rc;
4304
0edd5b44 4305 error:
43f66a6c
JK
4306 ipw_tx_queue_free(priv);
4307 return rc;
4308}
4309
4310/**
4311 * Reclaim Tx queue entries no more used by NIC.
bf79451e 4312 *
43f66a6c
JK
4313 * When FW adwances 'R' index, all entries between old and
4314 * new 'R' index need to be reclaimed. As result, some free space
4315 * forms. If there is enough free space (> low mark), wake Tx queue.
bf79451e 4316 *
43f66a6c
JK
4317 * @note Need to protect against garbage in 'R' index
4318 * @param priv
4319 * @param txq
4320 * @param qindex
4321 * @return Number of used entries remains in the queue
4322 */
bf79451e 4323static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
4324 struct clx2_tx_queue *txq, int qindex)
4325{
4326 u32 hw_tail;
4327 int used;
4328 struct clx2_queue *q = &txq->q;
4329
4330 hw_tail = ipw_read32(priv, q->reg_r);
4331 if (hw_tail >= q->n_bd) {
4332 IPW_ERROR
0edd5b44
JG
4333 ("Read index for DMA queue (%d) is out of range [0-%d)\n",
4334 hw_tail, q->n_bd);
43f66a6c
JK
4335 goto done;
4336 }
4337 for (; q->last_used != hw_tail;
4338 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
4339 ipw_queue_tx_free_tfd(priv, txq);
4340 priv->tx_packets++;
4341 }
0edd5b44 4342 done:
a613bffd 4343 if (ipw_queue_space(q) > q->low_mark && qindex >= 0)
43f66a6c 4344 __maybe_wake_tx(priv);
43f66a6c
JK
4345 used = q->first_empty - q->last_used;
4346 if (used < 0)
4347 used += q->n_bd;
4348
4349 return used;
4350}
4351
4352static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
4353 int len, int sync)
4354{
4355 struct clx2_tx_queue *txq = &priv->txq_cmd;
4356 struct clx2_queue *q = &txq->q;
4357 struct tfd_frame *tfd;
4358
4359 if (ipw_queue_space(q) < (sync ? 1 : 2)) {
4360 IPW_ERROR("No space for Tx\n");
4361 return -EBUSY;
4362 }
4363
4364 tfd = &txq->bd[q->first_empty];
4365 txq->txb[q->first_empty] = NULL;
4366
4367 memset(tfd, 0, sizeof(*tfd));
4368 tfd->control_flags.message_type = TX_HOST_COMMAND_TYPE;
4369 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
4370 priv->hcmd_seq++;
4371 tfd->u.cmd.index = hcmd;
4372 tfd->u.cmd.length = len;
4373 memcpy(tfd->u.cmd.payload, buf, len);
4374 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
4375 ipw_write32(priv, q->reg_w, q->first_empty);
4376 _ipw_read32(priv, 0x90);
4377
4378 return 0;
4379}
4380
bf79451e 4381/*
43f66a6c
JK
4382 * Rx theory of operation
4383 *
4384 * The host allocates 32 DMA target addresses and passes the host address
4385 * to the firmware at register CX2_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
4386 * 0 to 31
4387 *
4388 * Rx Queue Indexes
4389 * The host/firmware share two index registers for managing the Rx buffers.
4390 *
bf79451e
JG
4391 * The READ index maps to the first position that the firmware may be writing
4392 * to -- the driver can read up to (but not including) this position and get
4393 * good data.
43f66a6c
JK
4394 * The READ index is managed by the firmware once the card is enabled.
4395 *
4396 * The WRITE index maps to the last position the driver has read from -- the
4397 * position preceding WRITE is the last slot the firmware can place a packet.
4398 *
4399 * The queue is empty (no good data) if WRITE = READ - 1, and is full if
bf79451e 4400 * WRITE = READ.
43f66a6c 4401 *
bf79451e 4402 * During initialization the host sets up the READ queue position to the first
43f66a6c
JK
4403 * INDEX position, and WRITE to the last (READ - 1 wrapped)
4404 *
4405 * When the firmware places a packet in a buffer it will advance the READ index
4406 * and fire the RX interrupt. The driver can then query the READ index and
4407 * process as many packets as possible, moving the WRITE index forward as it
4408 * resets the Rx queue buffers with new memory.
bf79451e 4409 *
43f66a6c 4410 * The management in the driver is as follows:
bf79451e 4411 * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When
43f66a6c 4412 * ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
bf79451e 4413 * to replensish the ipw->rxq->rx_free.
43f66a6c
JK
4414 * + In ipw_rx_queue_replenish (scheduled) if 'processed' != 'read' then the
4415 * ipw->rxq is replenished and the READ INDEX is updated (updating the
4416 * 'processed' and 'read' driver indexes as well)
4417 * + A received packet is processed and handed to the kernel network stack,
4418 * detached from the ipw->rxq. The driver 'processed' index is updated.
4419 * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free
bf79451e
JG
4420 * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ
4421 * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there
43f66a6c
JK
4422 * were enough free buffers and RX_STALLED is set it is cleared.
4423 *
4424 *
4425 * Driver sequence:
4426 *
bf79451e 4427 * ipw_rx_queue_alloc() Allocates rx_free
43f66a6c
JK
4428 * ipw_rx_queue_replenish() Replenishes rx_free list from rx_used, and calls
4429 * ipw_rx_queue_restock
4430 * ipw_rx_queue_restock() Moves available buffers from rx_free into Rx
4431 * queue, updates firmware pointers, and updates
4432 * the WRITE index. If insufficient rx_free buffers
4433 * are available, schedules ipw_rx_queue_replenish
4434 *
4435 * -- enable interrupts --
4436 * ISR - ipw_rx() Detach ipw_rx_mem_buffers from pool up to the
bf79451e 4437 * READ INDEX, detaching the SKB from the pool.
43f66a6c
JK
4438 * Moves the packet buffer from queue to rx_used.
4439 * Calls ipw_rx_queue_restock to refill any empty
4440 * slots.
4441 * ...
4442 *
4443 */
4444
bf79451e 4445/*
43f66a6c
JK
4446 * If there are slots in the RX queue that need to be restocked,
4447 * and we have free pre-allocated buffers, fill the ranks as much
4448 * as we can pulling from rx_free.
4449 *
4450 * This moves the 'write' index forward to catch up with 'processed', and
4451 * also updates the memory address in the firmware to reference the new
4452 * target buffer.
4453 */
4454static void ipw_rx_queue_restock(struct ipw_priv *priv)
4455{
4456 struct ipw_rx_queue *rxq = priv->rxq;
4457 struct list_head *element;
4458 struct ipw_rx_mem_buffer *rxb;
4459 unsigned long flags;
4460 int write;
4461
4462 spin_lock_irqsave(&rxq->lock, flags);
4463 write = rxq->write;
4464 while ((rxq->write != rxq->processed) && (rxq->free_count)) {
4465 element = rxq->rx_free.next;
4466 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
4467 list_del(element);
4468
4469 ipw_write32(priv, CX2_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
4470 rxb->dma_addr);
4471 rxq->queue[rxq->write] = rxb;
4472 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
4473 rxq->free_count--;
4474 }
4475 spin_unlock_irqrestore(&rxq->lock, flags);
4476
bf79451e 4477 /* If the pre-allocated buffer pool is dropping low, schedule to
43f66a6c
JK
4478 * refill it */
4479 if (rxq->free_count <= RX_LOW_WATERMARK)
4480 queue_work(priv->workqueue, &priv->rx_replenish);
4481
4482 /* If we've added more space for the firmware to place data, tell it */
bf79451e 4483 if (write != rxq->write)
43f66a6c
JK
4484 ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write);
4485}
4486
4487/*
4488 * Move all used packet from rx_used to rx_free, allocating a new SKB for each.
bf79451e
JG
4489 * Also restock the Rx queue via ipw_rx_queue_restock.
4490 *
43f66a6c
JK
4491 * This is called as a scheduled work item (except for during intialization)
4492 */
4493static void ipw_rx_queue_replenish(void *data)
4494{
4495 struct ipw_priv *priv = data;
4496 struct ipw_rx_queue *rxq = priv->rxq;
4497 struct list_head *element;
4498 struct ipw_rx_mem_buffer *rxb;
4499 unsigned long flags;
4500
4501 spin_lock_irqsave(&rxq->lock, flags);
4502 while (!list_empty(&rxq->rx_used)) {
4503 element = rxq->rx_used.next;
4504 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
4505 rxb->skb = alloc_skb(CX2_RX_BUF_SIZE, GFP_ATOMIC);
4506 if (!rxb->skb) {
4507 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
4508 priv->net_dev->name);
4509 /* We don't reschedule replenish work here -- we will
4510 * call the restock method and if it still needs
4511 * more buffers it will schedule replenish */
4512 break;
4513 }
4514 list_del(element);
bf79451e 4515
43f66a6c 4516 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
0edd5b44
JG
4517 rxb->dma_addr =
4518 pci_map_single(priv->pci_dev, rxb->skb->data,
4519 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
bf79451e 4520
43f66a6c
JK
4521 list_add_tail(&rxb->list, &rxq->rx_free);
4522 rxq->free_count++;
4523 }
4524 spin_unlock_irqrestore(&rxq->lock, flags);
4525
4526 ipw_rx_queue_restock(priv);
4527}
4528
c848d0af
JK
4529static void ipw_bg_rx_queue_replenish(void *data)
4530{
4531 struct ipw_priv *priv = data;
4532 down(&priv->sem);
4533 ipw_rx_queue_replenish(data);
4534 up(&priv->sem);
4535}
4536
43f66a6c
JK
4537/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4538 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
bf79451e 4539 * This free routine walks the list of POOL entries and if SKB is set to
43f66a6c
JK
4540 * non NULL it is unmapped and freed
4541 */
0edd5b44 4542static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
43f66a6c
JK
4543{
4544 int i;
4545
4546 if (!rxq)
4547 return;
bf79451e 4548
43f66a6c
JK
4549 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4550 if (rxq->pool[i].skb != NULL) {
4551 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
0edd5b44 4552 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c
JK
4553 dev_kfree_skb(rxq->pool[i].skb);
4554 }
4555 }
4556
4557 kfree(rxq);
4558}
4559
4560static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
4561{
4562 struct ipw_rx_queue *rxq;
4563 int i;
4564
4565 rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
ad18b0ea
PI
4566 if (unlikely(!rxq)) {
4567 IPW_ERROR("memory allocation failed\n");
4568 return NULL;
4569 }
43f66a6c
JK
4570 memset(rxq, 0, sizeof(*rxq));
4571 spin_lock_init(&rxq->lock);
4572 INIT_LIST_HEAD(&rxq->rx_free);
4573 INIT_LIST_HEAD(&rxq->rx_used);
4574
4575 /* Fill the rx_used queue with _all_ of the Rx buffers */
bf79451e 4576 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
43f66a6c
JK
4577 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
4578
4579 /* Set us so that we have processed and used all buffers, but have
4580 * not restocked the Rx queue with fresh buffers */
4581 rxq->read = rxq->write = 0;
4582 rxq->processed = RX_QUEUE_SIZE - 1;
4583 rxq->free_count = 0;
4584
4585 return rxq;
4586}
4587
4588static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
4589{
4590 rate &= ~IEEE80211_BASIC_RATE_MASK;
4591 if (ieee_mode == IEEE_A) {
4592 switch (rate) {
bf79451e
JG
4593 case IEEE80211_OFDM_RATE_6MB:
4594 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ?
0edd5b44 4595 1 : 0;
bf79451e
JG
4596 case IEEE80211_OFDM_RATE_9MB:
4597 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ?
0edd5b44 4598 1 : 0;
bf79451e 4599 case IEEE80211_OFDM_RATE_12MB:
0edd5b44
JG
4600 return priv->
4601 rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
bf79451e 4602 case IEEE80211_OFDM_RATE_18MB:
0edd5b44
JG
4603 return priv->
4604 rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
bf79451e 4605 case IEEE80211_OFDM_RATE_24MB:
0edd5b44
JG
4606 return priv->
4607 rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
bf79451e 4608 case IEEE80211_OFDM_RATE_36MB:
0edd5b44
JG
4609 return priv->
4610 rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
bf79451e 4611 case IEEE80211_OFDM_RATE_48MB:
0edd5b44
JG
4612 return priv->
4613 rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
bf79451e 4614 case IEEE80211_OFDM_RATE_54MB:
0edd5b44
JG
4615 return priv->
4616 rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
43f66a6c
JK
4617 default:
4618 return 0;
4619 }
4620 }
bf79451e 4621
43f66a6c
JK
4622 /* B and G mixed */
4623 switch (rate) {
bf79451e 4624 case IEEE80211_CCK_RATE_1MB:
43f66a6c 4625 return priv->rates_mask & IEEE80211_CCK_RATE_1MB_MASK ? 1 : 0;
bf79451e 4626 case IEEE80211_CCK_RATE_2MB:
43f66a6c 4627 return priv->rates_mask & IEEE80211_CCK_RATE_2MB_MASK ? 1 : 0;
bf79451e 4628 case IEEE80211_CCK_RATE_5MB:
43f66a6c 4629 return priv->rates_mask & IEEE80211_CCK_RATE_5MB_MASK ? 1 : 0;
bf79451e 4630 case IEEE80211_CCK_RATE_11MB:
43f66a6c
JK
4631 return priv->rates_mask & IEEE80211_CCK_RATE_11MB_MASK ? 1 : 0;
4632 }
4633
4634 /* If we are limited to B modulations, bail at this point */
4635 if (ieee_mode == IEEE_B)
4636 return 0;
4637
4638 /* G */
4639 switch (rate) {
bf79451e 4640 case IEEE80211_OFDM_RATE_6MB:
43f66a6c 4641 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? 1 : 0;
bf79451e 4642 case IEEE80211_OFDM_RATE_9MB:
43f66a6c 4643 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? 1 : 0;
bf79451e 4644 case IEEE80211_OFDM_RATE_12MB:
43f66a6c 4645 return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
bf79451e 4646 case IEEE80211_OFDM_RATE_18MB:
43f66a6c 4647 return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
bf79451e 4648 case IEEE80211_OFDM_RATE_24MB:
43f66a6c 4649 return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
bf79451e 4650 case IEEE80211_OFDM_RATE_36MB:
43f66a6c 4651 return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
bf79451e 4652 case IEEE80211_OFDM_RATE_48MB:
43f66a6c 4653 return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
bf79451e 4654 case IEEE80211_OFDM_RATE_54MB:
43f66a6c
JK
4655 return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
4656 }
4657
4658 return 0;
4659}
4660
bf79451e 4661static int ipw_compatible_rates(struct ipw_priv *priv,
43f66a6c
JK
4662 const struct ieee80211_network *network,
4663 struct ipw_supported_rates *rates)
4664{
4665 int num_rates, i;
4666
4667 memset(rates, 0, sizeof(*rates));
0edd5b44 4668 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
43f66a6c
JK
4669 rates->num_rates = 0;
4670 for (i = 0; i < num_rates; i++) {
a613bffd
JK
4671 if (!ipw_is_rate_in_mask(priv, network->mode,
4672 network->rates[i])) {
4673
ea2b26e0 4674 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
a613bffd
JK
4675 IPW_DEBUG_SCAN("Adding masked mandatory "
4676 "rate %02X\n",
4677 network->rates[i]);
4678 rates->supported_rates[rates->num_rates++] =
4679 network->rates[i];
4680 continue;
ea2b26e0
JK
4681 }
4682
43f66a6c
JK
4683 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4684 network->rates[i], priv->rates_mask);
4685 continue;
4686 }
bf79451e 4687
43f66a6c
JK
4688 rates->supported_rates[rates->num_rates++] = network->rates[i];
4689 }
4690
a613bffd
JK
4691 num_rates = min(network->rates_ex_len,
4692 (u8) (IPW_MAX_RATES - num_rates));
43f66a6c 4693 for (i = 0; i < num_rates; i++) {
a613bffd
JK
4694 if (!ipw_is_rate_in_mask(priv, network->mode,
4695 network->rates_ex[i])) {
ea2b26e0 4696 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
a613bffd
JK
4697 IPW_DEBUG_SCAN("Adding masked mandatory "
4698 "rate %02X\n",
4699 network->rates_ex[i]);
4700 rates->supported_rates[rates->num_rates++] =
4701 network->rates[i];
4702 continue;
ea2b26e0
JK
4703 }
4704
43f66a6c
JK
4705 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4706 network->rates_ex[i], priv->rates_mask);
4707 continue;
4708 }
bf79451e 4709
0edd5b44
JG
4710 rates->supported_rates[rates->num_rates++] =
4711 network->rates_ex[i];
43f66a6c
JK
4712 }
4713
ea2b26e0 4714 return 1;
43f66a6c
JK
4715}
4716
4717static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
4718 const struct ipw_supported_rates *src)
4719{
4720 u8 i;
4721 for (i = 0; i < src->num_rates; i++)
4722 dest->supported_rates[i] = src->supported_rates[i];
4723 dest->num_rates = src->num_rates;
4724}
4725
4726/* TODO: Look at sniffed packets in the air to determine if the basic rate
4727 * mask should ever be used -- right now all callers to add the scan rates are
4728 * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */
4729static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 4730 u8 modulation, u32 rate_mask)
43f66a6c 4731{
bf79451e 4732 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
0edd5b44 4733 IEEE80211_BASIC_RATE_MASK : 0;
bf79451e 4734
43f66a6c 4735 if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK)
bf79451e 4736 rates->supported_rates[rates->num_rates++] =
0edd5b44 4737 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
43f66a6c
JK
4738
4739 if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK)
bf79451e 4740 rates->supported_rates[rates->num_rates++] =
0edd5b44 4741 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
43f66a6c
JK
4742
4743 if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK)
bf79451e 4744 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4745 IEEE80211_CCK_RATE_5MB;
43f66a6c
JK
4746
4747 if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK)
bf79451e 4748 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4749 IEEE80211_CCK_RATE_11MB;
43f66a6c
JK
4750}
4751
4752static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 4753 u8 modulation, u32 rate_mask)
43f66a6c 4754{
bf79451e 4755 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
0edd5b44 4756 IEEE80211_BASIC_RATE_MASK : 0;
43f66a6c
JK
4757
4758 if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK)
bf79451e 4759 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4760 IEEE80211_OFDM_RATE_6MB;
43f66a6c
JK
4761
4762 if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK)
bf79451e 4763 rates->supported_rates[rates->num_rates++] =
0edd5b44 4764 IEEE80211_OFDM_RATE_9MB;
43f66a6c
JK
4765
4766 if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK)
bf79451e 4767 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4768 IEEE80211_OFDM_RATE_12MB;
43f66a6c
JK
4769
4770 if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK)
bf79451e 4771 rates->supported_rates[rates->num_rates++] =
0edd5b44 4772 IEEE80211_OFDM_RATE_18MB;
43f66a6c
JK
4773
4774 if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK)
bf79451e 4775 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4776 IEEE80211_OFDM_RATE_24MB;
43f66a6c
JK
4777
4778 if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK)
bf79451e 4779 rates->supported_rates[rates->num_rates++] =
0edd5b44 4780 IEEE80211_OFDM_RATE_36MB;
43f66a6c
JK
4781
4782 if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK)
bf79451e 4783 rates->supported_rates[rates->num_rates++] =
0edd5b44 4784 IEEE80211_OFDM_RATE_48MB;
43f66a6c
JK
4785
4786 if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK)
bf79451e 4787 rates->supported_rates[rates->num_rates++] =
0edd5b44 4788 IEEE80211_OFDM_RATE_54MB;
43f66a6c
JK
4789}
4790
4791struct ipw_network_match {
4792 struct ieee80211_network *network;
4793 struct ipw_supported_rates rates;
4794};
4795
c848d0af
JK
4796static int ipw_find_adhoc_network(struct ipw_priv *priv,
4797 struct ipw_network_match *match,
4798 struct ieee80211_network *network,
4799 int roaming)
4800{
4801 struct ipw_supported_rates rates;
4802
4803 /* Verify that this network's capability is compatible with the
4804 * current mode (AdHoc or Infrastructure) */
4805 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
4806 !(network->capability & WLAN_CAPABILITY_IBSS))) {
4807 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
4808 "capability mismatch.\n",
4809 escape_essid(network->ssid, network->ssid_len),
4810 MAC_ARG(network->bssid));
4811 return 0;
4812 }
4813
4814 /* If we do not have an ESSID for this AP, we can not associate with
4815 * it */
4816 if (network->flags & NETWORK_EMPTY_ESSID) {
4817 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4818 "because of hidden ESSID.\n",
4819 escape_essid(network->ssid, network->ssid_len),
4820 MAC_ARG(network->bssid));
4821 return 0;
4822 }
4823
4824 if (unlikely(roaming)) {
4825 /* If we are roaming, then ensure check if this is a valid
4826 * network to try and roam to */
4827 if ((network->ssid_len != match->network->ssid_len) ||
4828 memcmp(network->ssid, match->network->ssid,
4829 network->ssid_len)) {
4830 IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
4831 "because of non-network ESSID.\n",
4832 escape_essid(network->ssid,
4833 network->ssid_len),
4834 MAC_ARG(network->bssid));
4835 return 0;
4836 }
4837 } else {
4838 /* If an ESSID has been configured then compare the broadcast
4839 * ESSID to ours */
4840 if ((priv->config & CFG_STATIC_ESSID) &&
4841 ((network->ssid_len != priv->essid_len) ||
4842 memcmp(network->ssid, priv->essid,
4843 min(network->ssid_len, priv->essid_len)))) {
4844 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
4845 strncpy(escaped,
4846 escape_essid(network->ssid, network->ssid_len),
4847 sizeof(escaped));
4848 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4849 "because of ESSID mismatch: '%s'.\n",
4850 escaped, MAC_ARG(network->bssid),
4851 escape_essid(priv->essid,
4852 priv->essid_len));
4853 return 0;
4854 }
4855 }
4856
4857 /* If the old network rate is better than this one, don't bother
4858 * testing everything else. */
4859
4860 if (network->time_stamp[0] < match->network->time_stamp[0]) {
4861 IPW_DEBUG_MERGE
4862 ("Network '%s excluded because newer than current network.\n",
4863 escape_essid(match->network->ssid,
4864 match->network->ssid_len));
4865 return 0;
4866 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
4867 IPW_DEBUG_MERGE
4868 ("Network '%s excluded because newer than current network.\n",
4869 escape_essid(match->network->ssid,
4870 match->network->ssid_len));
4871 return 0;
4872 }
4873
4874 /* Now go through and see if the requested network is valid... */
4875 if (priv->ieee->scan_age != 0 &&
4876 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
4877 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4878 "because of age: %lums.\n",
4879 escape_essid(network->ssid, network->ssid_len),
4880 MAC_ARG(network->bssid),
4881 (jiffies - network->last_scanned) / (HZ / 100));
4882 return 0;
4883 }
4884
4885 if ((priv->config & CFG_STATIC_CHANNEL) &&
4886 (network->channel != priv->channel)) {
4887 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4888 "because of channel mismatch: %d != %d.\n",
4889 escape_essid(network->ssid, network->ssid_len),
4890 MAC_ARG(network->bssid),
4891 network->channel, priv->channel);
4892 return 0;
4893 }
4894
4895 /* Verify privacy compatability */
4896 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
4897 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
4898 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4899 "because of privacy mismatch: %s != %s.\n",
4900 escape_essid(network->ssid, network->ssid_len),
4901 MAC_ARG(network->bssid),
4902 priv->capability & CAP_PRIVACY_ON ? "on" :
4903 "off",
4904 network->capability &
4905 WLAN_CAPABILITY_PRIVACY ? "on" : "off");
4906 return 0;
4907 }
4908
4909 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
4910 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4911 "because of the same BSSID match: " MAC_FMT
4912 ".\n", escape_essid(network->ssid,
4913 network->ssid_len),
4914 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
4915 return 0;
4916 }
4917
4918 /* Filter out any incompatible freq / mode combinations */
4919 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
4920 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4921 "because of invalid frequency/mode "
4922 "combination.\n",
4923 escape_essid(network->ssid, network->ssid_len),
4924 MAC_ARG(network->bssid));
4925 return 0;
4926 }
4927
4928 /* Ensure that the rates supported by the driver are compatible with
4929 * this AP, including verification of basic rates (mandatory) */
4930 if (!ipw_compatible_rates(priv, network, &rates)) {
4931 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4932 "because configured rate mask excludes "
4933 "AP mandatory rate.\n",
4934 escape_essid(network->ssid, network->ssid_len),
4935 MAC_ARG(network->bssid));
4936 return 0;
4937 }
4938
4939 if (rates.num_rates == 0) {
4940 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
4941 "because of no compatible rates.\n",
4942 escape_essid(network->ssid, network->ssid_len),
4943 MAC_ARG(network->bssid));
4944 return 0;
4945 }
4946
4947 /* TODO: Perform any further minimal comparititive tests. We do not
4948 * want to put too much policy logic here; intelligent scan selection
4949 * should occur within a generic IEEE 802.11 user space tool. */
4950
4951 /* Set up 'new' AP to this network */
4952 ipw_copy_rates(&match->rates, &rates);
4953 match->network = network;
4954 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
4955 escape_essid(network->ssid, network->ssid_len),
4956 MAC_ARG(network->bssid));
4957
4958 return 1;
4959}
4960
4961static void ipw_merge_adhoc_network(void *data)
4962{
4963 struct ipw_priv *priv = data;
4964 struct ieee80211_network *network = NULL;
4965 struct ipw_network_match match = {
4966 .network = priv->assoc_network
4967 };
4968
4969 if ((priv->status & STATUS_ASSOCIATED)
4970 && (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
4971 /* First pass through ROAM process -- look for a better
4972 * network */
4973 unsigned long flags;
4974
4975 spin_lock_irqsave(&priv->ieee->lock, flags);
4976 list_for_each_entry(network, &priv->ieee->network_list, list) {
4977 if (network != priv->assoc_network)
4978 ipw_find_adhoc_network(priv, &match, network,
4979 1);
4980 }
4981 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4982
4983 if (match.network == priv->assoc_network) {
4984 IPW_DEBUG_MERGE("No better ADHOC in this network to "
4985 "merge to.\n");
4986 return;
4987 }
4988
4989 down(&priv->sem);
4990 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
4991 IPW_DEBUG_MERGE("remove network %s\n",
4992 escape_essid(priv->essid,
4993 priv->essid_len));
4994 ipw_remove_current_network(priv);
4995 }
4996
4997 ipw_disassociate(priv);
4998 priv->assoc_network = match.network;
4999 up(&priv->sem);
5000 return;
5001 }
5002
5003}
5004
0edd5b44
JG
5005static int ipw_best_network(struct ipw_priv *priv,
5006 struct ipw_network_match *match,
5007 struct ieee80211_network *network, int roaming)
43f66a6c
JK
5008{
5009 struct ipw_supported_rates rates;
5010
5011 /* Verify that this network's capability is compatible with the
5012 * current mode (AdHoc or Infrastructure) */
5013 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
2474385e 5014 !(network->capability & WLAN_CAPABILITY_ESS)) ||
43f66a6c
JK
5015 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
5016 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5017 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded due to "
bf79451e 5018 "capability mismatch.\n",
43f66a6c
JK
5019 escape_essid(network->ssid, network->ssid_len),
5020 MAC_ARG(network->bssid));
5021 return 0;
5022 }
5023
5024 /* If we do not have an ESSID for this AP, we can not associate with
5025 * it */
5026 if (network->flags & NETWORK_EMPTY_ESSID) {
5027 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5028 "because of hidden ESSID.\n",
5029 escape_essid(network->ssid, network->ssid_len),
5030 MAC_ARG(network->bssid));
5031 return 0;
5032 }
bf79451e 5033
43f66a6c
JK
5034 if (unlikely(roaming)) {
5035 /* If we are roaming, then ensure check if this is a valid
5036 * network to try and roam to */
5037 if ((network->ssid_len != match->network->ssid_len) ||
bf79451e 5038 memcmp(network->ssid, match->network->ssid,
43f66a6c
JK
5039 network->ssid_len)) {
5040 IPW_DEBUG_ASSOC("Netowrk '%s (" MAC_FMT ")' excluded "
5041 "because of non-network ESSID.\n",
bf79451e 5042 escape_essid(network->ssid,
43f66a6c
JK
5043 network->ssid_len),
5044 MAC_ARG(network->bssid));
5045 return 0;
5046 }
5047 } else {
bf79451e
JG
5048 /* If an ESSID has been configured then compare the broadcast
5049 * ESSID to ours */
5050 if ((priv->config & CFG_STATIC_ESSID) &&
43f66a6c 5051 ((network->ssid_len != priv->essid_len) ||
bf79451e 5052 memcmp(network->ssid, priv->essid,
43f66a6c
JK
5053 min(network->ssid_len, priv->essid_len)))) {
5054 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
0edd5b44
JG
5055 strncpy(escaped,
5056 escape_essid(network->ssid, network->ssid_len),
43f66a6c
JK
5057 sizeof(escaped));
5058 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
bf79451e 5059 "because of ESSID mismatch: '%s'.\n",
43f66a6c 5060 escaped, MAC_ARG(network->bssid),
0edd5b44
JG
5061 escape_essid(priv->essid,
5062 priv->essid_len));
43f66a6c
JK
5063 return 0;
5064 }
5065 }
5066
5067 /* If the old network rate is better than this one, don't bother
5068 * testing everything else. */
0edd5b44 5069 if (match->network && match->network->stats.rssi > network->stats.rssi) {
43f66a6c 5070 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
bf79451e
JG
5071 strncpy(escaped,
5072 escape_essid(network->ssid, network->ssid_len),
43f66a6c
JK
5073 sizeof(escaped));
5074 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded because "
5075 "'%s (" MAC_FMT ")' has a stronger signal.\n",
5076 escaped, MAC_ARG(network->bssid),
5077 escape_essid(match->network->ssid,
5078 match->network->ssid_len),
5079 MAC_ARG(match->network->bssid));
5080 return 0;
5081 }
bf79451e 5082
43f66a6c
JK
5083 /* If this network has already had an association attempt within the
5084 * last 3 seconds, do not try and associate again... */
5085 if (network->last_associate &&
ea2b26e0 5086 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
43f66a6c
JK
5087 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5088 "because of storming (%lu since last "
5089 "assoc attempt).\n",
5090 escape_essid(network->ssid, network->ssid_len),
5091 MAC_ARG(network->bssid),
5092 (jiffies - network->last_associate) / HZ);
5093 return 0;
5094 }
5095
5096 /* Now go through and see if the requested network is valid... */
bf79451e 5097 if (priv->ieee->scan_age != 0 &&
ea2b26e0 5098 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
43f66a6c
JK
5099 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5100 "because of age: %lums.\n",
5101 escape_essid(network->ssid, network->ssid_len),
5102 MAC_ARG(network->bssid),
5103 (jiffies - network->last_scanned) / (HZ / 100));
5104 return 0;
bf79451e 5105 }
43f66a6c 5106
bf79451e 5107 if ((priv->config & CFG_STATIC_CHANNEL) &&
43f66a6c
JK
5108 (network->channel != priv->channel)) {
5109 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5110 "because of channel mismatch: %d != %d.\n",
5111 escape_essid(network->ssid, network->ssid_len),
5112 MAC_ARG(network->bssid),
5113 network->channel, priv->channel);
5114 return 0;
5115 }
bf79451e 5116
43f66a6c 5117 /* Verify privacy compatability */
bf79451e 5118 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
43f66a6c
JK
5119 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5120 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5121 "because of privacy mismatch: %s != %s.\n",
5122 escape_essid(network->ssid, network->ssid_len),
5123 MAC_ARG(network->bssid),
bf79451e 5124 priv->capability & CAP_PRIVACY_ON ? "on" :
43f66a6c 5125 "off",
bf79451e 5126 network->capability &
0edd5b44 5127 WLAN_CAPABILITY_PRIVACY ? "on" : "off");
43f66a6c
JK
5128 return 0;
5129 }
bf79451e
JG
5130
5131 if ((priv->config & CFG_STATIC_BSSID) &&
43f66a6c
JK
5132 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5133 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5134 "because of BSSID mismatch: " MAC_FMT ".\n",
5135 escape_essid(network->ssid, network->ssid_len),
0edd5b44 5136 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
43f66a6c
JK
5137 return 0;
5138 }
bf79451e 5139
43f66a6c
JK
5140 /* Filter out any incompatible freq / mode combinations */
5141 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5142 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5143 "because of invalid frequency/mode "
5144 "combination.\n",
5145 escape_essid(network->ssid, network->ssid_len),
5146 MAC_ARG(network->bssid));
5147 return 0;
5148 }
bf79451e 5149
ea2b26e0
JK
5150 /* Ensure that the rates supported by the driver are compatible with
5151 * this AP, including verification of basic rates (mandatory) */
5152 if (!ipw_compatible_rates(priv, network, &rates)) {
5153 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5154 "because configured rate mask excludes "
5155 "AP mandatory rate.\n",
5156 escape_essid(network->ssid, network->ssid_len),
5157 MAC_ARG(network->bssid));
5158 return 0;
5159 }
5160
43f66a6c
JK
5161 if (rates.num_rates == 0) {
5162 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5163 "because of no compatible rates.\n",
5164 escape_essid(network->ssid, network->ssid_len),
5165 MAC_ARG(network->bssid));
5166 return 0;
5167 }
bf79451e 5168
43f66a6c
JK
5169 /* TODO: Perform any further minimal comparititive tests. We do not
5170 * want to put too much policy logic here; intelligent scan selection
5171 * should occur within a generic IEEE 802.11 user space tool. */
5172
5173 /* Set up 'new' AP to this network */
5174 ipw_copy_rates(&match->rates, &rates);
5175 match->network = network;
5176
5177 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' is a viable match.\n",
5178 escape_essid(network->ssid, network->ssid_len),
5179 MAC_ARG(network->bssid));
5180
5181 return 1;
5182}
5183
bf79451e 5184static void ipw_adhoc_create(struct ipw_priv *priv,
0edd5b44 5185 struct ieee80211_network *network)
43f66a6c
JK
5186{
5187 /*
5188 * For the purposes of scanning, we can set our wireless mode
5189 * to trigger scans across combinations of bands, but when it
5190 * comes to creating a new ad-hoc network, we have tell the FW
5191 * exactly which band to use.
5192 *
bf79451e 5193 * We also have the possibility of an invalid channel for the
43f66a6c
JK
5194 * chossen band. Attempting to create a new ad-hoc network
5195 * with an invalid channel for wireless mode will trigger a
5196 * FW fatal error.
5197 */
5198 network->mode = is_valid_channel(priv->ieee->mode, priv->channel);
a613bffd 5199 if (!network->mode) {
43f66a6c
JK
5200 IPW_WARNING("Overriding invalid channel\n");
5201 if (priv->ieee->mode & IEEE_A) {
5202 network->mode = IEEE_A;
5203 priv->channel = band_a_active_channel[0];
5204 } else if (priv->ieee->mode & IEEE_G) {
5205 network->mode = IEEE_G;
5206 priv->channel = band_b_active_channel[0];
5207 } else {
5208 network->mode = IEEE_B;
5209 priv->channel = band_b_active_channel[0];
5210 }
5211 }
5212
5213 network->channel = priv->channel;
5214 priv->config |= CFG_ADHOC_PERSIST;
5215 ipw_create_bssid(priv, network->bssid);
5216 network->ssid_len = priv->essid_len;
5217 memcpy(network->ssid, priv->essid, priv->essid_len);
5218 memset(&network->stats, 0, sizeof(network->stats));
5219 network->capability = WLAN_CAPABILITY_IBSS;
ea2b26e0
JK
5220 if (!(priv->config & CFG_PREAMBLE_LONG))
5221 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
43f66a6c
JK
5222 if (priv->capability & CAP_PRIVACY_ON)
5223 network->capability |= WLAN_CAPABILITY_PRIVACY;
5224 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
0edd5b44 5225 memcpy(network->rates, priv->rates.supported_rates, network->rates_len);
43f66a6c 5226 network->rates_ex_len = priv->rates.num_rates - network->rates_len;
bf79451e 5227 memcpy(network->rates_ex,
43f66a6c
JK
5228 &priv->rates.supported_rates[network->rates_len],
5229 network->rates_ex_len);
5230 network->last_scanned = 0;
5231 network->flags = 0;
5232 network->last_associate = 0;
5233 network->time_stamp[0] = 0;
5234 network->time_stamp[1] = 0;
0edd5b44
JG
5235 network->beacon_interval = 100; /* Default */
5236 network->listen_interval = 10; /* Default */
5237 network->atim_window = 0; /* Default */
43f66a6c
JK
5238 network->wpa_ie_len = 0;
5239 network->rsn_ie_len = 0;
43f66a6c
JK
5240}
5241
5242static void ipw_send_wep_keys(struct ipw_priv *priv)
5243{
5244 struct ipw_wep_key *key;
5245 int i;
5246 struct host_cmd cmd = {
5247 .cmd = IPW_CMD_WEP_KEY,
5248 .len = sizeof(*key)
5249 };
5250
5251 key = (struct ipw_wep_key *)&cmd.param;
5252 key->cmd_id = DINO_CMD_WEP_KEY;
5253 key->seq_num = 0;
5254
bf79451e 5255 for (i = 0; i < 4; i++) {
43f66a6c 5256 key->key_index = i;
a613bffd 5257 if (!(priv->sec.flags & (1 << i)))
43f66a6c 5258 key->key_size = 0;
a613bffd 5259 else {
43f66a6c
JK
5260 key->key_size = priv->sec.key_sizes[i];
5261 memcpy(key->key, priv->sec.keys[i], key->key_size);
5262 }
5263
5264 if (ipw_send_cmd(priv, &cmd)) {
5265 IPW_ERROR("failed to send WEP_KEY command\n");
5266 return;
5267 }
bf79451e 5268 }
43f66a6c
JK
5269}
5270
5271static void ipw_adhoc_check(void *data)
5272{
5273 struct ipw_priv *priv = data;
bf79451e 5274
43f66a6c
JK
5275 if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold &&
5276 !(priv->config & CFG_ADHOC_PERSIST)) {
5277 IPW_DEBUG_SCAN("Disassociating due to missed beacons\n");
5278 ipw_remove_current_network(priv);
5279 ipw_disassociate(priv);
5280 return;
5281 }
5282
bf79451e 5283 queue_delayed_work(priv->workqueue, &priv->adhoc_check,
43f66a6c
JK
5284 priv->assoc_request.beacon_interval);
5285}
5286
c848d0af
JK
5287static void ipw_bg_adhoc_check(void *data)
5288{
5289 struct ipw_priv *priv = data;
5290 down(&priv->sem);
5291 ipw_adhoc_check(data);
5292 up(&priv->sem);
5293}
5294
43f66a6c
JK
5295#ifdef CONFIG_IPW_DEBUG
5296static void ipw_debug_config(struct ipw_priv *priv)
5297{
5298 IPW_DEBUG_INFO("Scan completed, no valid APs matched "
5299 "[CFG 0x%08X]\n", priv->config);
5300 if (priv->config & CFG_STATIC_CHANNEL)
0edd5b44 5301 IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel);
43f66a6c
JK
5302 else
5303 IPW_DEBUG_INFO("Channel unlocked.\n");
5304 if (priv->config & CFG_STATIC_ESSID)
bf79451e 5305 IPW_DEBUG_INFO("ESSID locked to '%s'\n",
0edd5b44 5306 escape_essid(priv->essid, priv->essid_len));
43f66a6c
JK
5307 else
5308 IPW_DEBUG_INFO("ESSID unlocked.\n");
5309 if (priv->config & CFG_STATIC_BSSID)
ea2b26e0
JK
5310 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
5311 MAC_ARG(priv->bssid));
43f66a6c
JK
5312 else
5313 IPW_DEBUG_INFO("BSSID unlocked.\n");
5314 if (priv->capability & CAP_PRIVACY_ON)
5315 IPW_DEBUG_INFO("PRIVACY on\n");
5316 else
5317 IPW_DEBUG_INFO("PRIVACY off\n");
5318 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);
5319}
5320#else
8d45ff7d 5321#define ipw_debug_config(x) do {} while (0)
43f66a6c
JK
5322#endif
5323
5324static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
5325 struct ieee80211_network *network)
5326{
5327 /* TODO: Verify that this works... */
5328 struct ipw_fixed_rate fr = {
5329 .tx_rates = priv->rates_mask
5330 };
5331 u32 reg;
5332 u16 mask = 0;
5333
bf79451e 5334 /* Identify 'current FW band' and match it with the fixed
43f66a6c 5335 * Tx rates */
bf79451e 5336
43f66a6c 5337 switch (priv->ieee->freq_band) {
0edd5b44 5338 case IEEE80211_52GHZ_BAND: /* A only */
43f66a6c
JK
5339 /* IEEE_A */
5340 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
5341 /* Invalid fixed rate mask */
ea2b26e0
JK
5342 IPW_DEBUG_WX
5343 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5344 fr.tx_rates = 0;
5345 break;
5346 }
bf79451e 5347
43f66a6c
JK
5348 fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
5349 break;
5350
0edd5b44 5351 default: /* 2.4Ghz or Mixed */
43f66a6c
JK
5352 /* IEEE_B */
5353 if (network->mode == IEEE_B) {
5354 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
5355 /* Invalid fixed rate mask */
ea2b26e0
JK
5356 IPW_DEBUG_WX
5357 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5358 fr.tx_rates = 0;
5359 }
5360 break;
bf79451e 5361 }
43f66a6c
JK
5362
5363 /* IEEE_G */
5364 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
5365 IEEE80211_OFDM_RATES_MASK)) {
5366 /* Invalid fixed rate mask */
ea2b26e0
JK
5367 IPW_DEBUG_WX
5368 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5369 fr.tx_rates = 0;
5370 break;
5371 }
5372
5373 if (IEEE80211_OFDM_RATE_6MB_MASK & fr.tx_rates) {
5374 mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1);
5375 fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
5376 }
bf79451e 5377
43f66a6c
JK
5378 if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) {
5379 mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1);
5380 fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
5381 }
bf79451e 5382
43f66a6c
JK
5383 if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) {
5384 mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1);
5385 fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
5386 }
bf79451e 5387
43f66a6c
JK
5388 fr.tx_rates |= mask;
5389 break;
5390 }
5391
5392 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
0edd5b44 5393 ipw_write_reg32(priv, reg, *(u32 *) & fr);
43f66a6c
JK
5394}
5395
ea2b26e0 5396static void ipw_abort_scan(struct ipw_priv *priv)
43f66a6c
JK
5397{
5398 int err;
5399
ea2b26e0
JK
5400 if (priv->status & STATUS_SCAN_ABORTING) {
5401 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5402 return;
5403 }
5404 priv->status |= STATUS_SCAN_ABORTING;
43f66a6c 5405
ea2b26e0
JK
5406 err = ipw_send_scan_abort(priv);
5407 if (err)
5408 IPW_DEBUG_HC("Request to abort scan failed.\n");
5409}
5410
5411static int ipw_request_scan(struct ipw_priv *priv)
5412{
5413 struct ipw_scan_request_ext scan;
5414 int channel_index = 0;
5415 int i, err, scan_type;
5416
5417 if (priv->status & STATUS_EXIT_PENDING) {
5418 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n");
5419 priv->status |= STATUS_SCAN_PENDING;
5420 return 0;
43f66a6c
JK
5421 }
5422
ea2b26e0 5423 if (priv->status & STATUS_SCANNING) {
a613bffd
JK
5424 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
5425// IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n");
ea2b26e0 5426 priv->status |= STATUS_SCAN_PENDING;
a613bffd 5427// ipw_abort_scan(priv);
ea2b26e0
JK
5428 return 0;
5429 }
43f66a6c 5430
ea2b26e0
JK
5431 if (priv->status & STATUS_SCAN_ABORTING) {
5432 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
5433 priv->status |= STATUS_SCAN_PENDING;
5434 return 0;
43f66a6c
JK
5435 }
5436
ea2b26e0
JK
5437 if (priv->status & STATUS_RF_KILL_MASK) {
5438 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
5439 priv->status |= STATUS_SCAN_PENDING;
5440 return 0;
5441 }
43f66a6c 5442
ea2b26e0 5443 memset(&scan, 0, sizeof(scan));
43f66a6c 5444
a613bffd
JK
5445 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = cpu_to_le16(20);
5446 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
5447 cpu_to_le16(20);
5448 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(20);
43f66a6c 5449
a613bffd 5450 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
43f66a6c 5451
ea2b26e0
JK
5452#ifdef CONFIG_IPW_MONITOR
5453 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5454 u8 band = 0, channel = priv->channel;
43f66a6c 5455
ea2b26e0
JK
5456 if (is_valid_channel(IEEE_A, channel))
5457 band = (u8) (IPW_A_MODE << 6) | 1;
5458
5459 if (is_valid_channel(IEEE_B | IEEE_G, channel))
5460 band = (u8) (IPW_B_MODE << 6) | 1;
5461
5462 if (band == 0) {
5463 band = (u8) (IPW_B_MODE << 6) | 1;
5464 channel = 9;
5465 }
5466
5467 scan.channels_list[channel_index++] = band;
5468 scan.channels_list[channel_index] = channel;
5469 ipw_set_scan_type(&scan, channel_index,
5470 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
5471
a613bffd
JK
5472 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
5473 cpu_to_le16(2000);
43f66a6c 5474 } else {
ea2b26e0
JK
5475#endif /* CONFIG_IPW_MONITOR */
5476 /* If we are roaming, then make this a directed scan for the current
5477 * network. Otherwise, ensure that every other scan is a fast
5478 * channel hop scan */
c848d0af
JK
5479 if ((priv->status & STATUS_ROAMING) || (!(priv->status & STATUS_ASSOCIATED) && (priv->config & CFG_STATIC_ESSID) && (le32_to_cpu(scan.full_scan_index) % 2))) { /* || (
5480 (priv->status & STATUS_ASSOCIATED) &&
5481 (priv->ieee->iw_mode == IW_MODE_ADHOC))) { */
ea2b26e0
JK
5482 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5483 if (err) {
5484 IPW_DEBUG_HC
5485 ("Attempt to send SSID command failed.\n");
5486 return err;
5487 }
43f66a6c 5488
ea2b26e0
JK
5489 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
5490 } else {
5491 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
5492 }
bf79451e 5493
ea2b26e0
JK
5494 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5495 int start = channel_index;
5496 for (i = 0; i < MAX_A_CHANNELS; i++) {
5497 if (band_a_active_channel[i] == 0)
5498 break;
5499 if ((priv->status & STATUS_ASSOCIATED) &&
5500 band_a_active_channel[i] == priv->channel)
5501 continue;
5502 channel_index++;
5503 scan.channels_list[channel_index] =
5504 band_a_active_channel[i];
5505 ipw_set_scan_type(&scan, channel_index,
5506 scan_type);
5507 }
43f66a6c 5508
ea2b26e0
JK
5509 if (start != channel_index) {
5510 scan.channels_list[start] =
5511 (u8) (IPW_A_MODE << 6) | (channel_index -
5512 start);
5513 channel_index++;
5514 }
5515 }
bf79451e 5516
ea2b26e0
JK
5517 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5518 int start = channel_index;
5519 for (i = 0; i < MAX_B_CHANNELS; i++) {
5520 if (band_b_active_channel[i] == 0)
5521 break;
5522 if ((priv->status & STATUS_ASSOCIATED) &&
5523 band_b_active_channel[i] == priv->channel)
5524 continue;
5525 channel_index++;
5526 scan.channels_list[channel_index] =
5527 band_b_active_channel[i];
5528 ipw_set_scan_type(&scan, channel_index,
5529 scan_type);
5530 }
5531
5532 if (start != channel_index) {
5533 scan.channels_list[start] =
5534 (u8) (IPW_B_MODE << 6) | (channel_index -
5535 start);
5536 }
5537 }
5538#ifdef CONFIG_IPW_MONITOR
43f66a6c 5539 }
ea2b26e0 5540#endif
bf79451e 5541
ea2b26e0 5542 err = ipw_send_scan_request_ext(priv, &scan);
43f66a6c 5543 if (err) {
ea2b26e0
JK
5544 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
5545 return -EIO;
43f66a6c
JK
5546 }
5547
ea2b26e0
JK
5548 priv->status |= STATUS_SCANNING;
5549 priv->status &= ~STATUS_SCAN_PENDING;
43f66a6c 5550
ea2b26e0
JK
5551 return 0;
5552}
43f66a6c 5553
c848d0af
JK
5554static void ipw_bg_request_scan(void *data)
5555{
5556 struct ipw_priv *priv = data;
5557 down(&priv->sem);
5558 ipw_request_scan(data);
5559 up(&priv->sem);
5560}
5561
5562static void ipw_bg_abort_scan(void *data)
5563{
5564 struct ipw_priv *priv = data;
5565 down(&priv->sem);
5566 ipw_abort_scan(data);
5567 up(&priv->sem);
5568}
5569
ea2b26e0
JK
5570/* Support for wpa_supplicant. Will be replaced with WEXT once
5571 * they get WPA support. */
ea2b26e0
JK
5572
5573/* following definitions must match definitions in driver_ipw.c */
5574
5575#define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5576
5577#define IPW_CMD_SET_WPA_PARAM 1
5578#define IPW_CMD_SET_WPA_IE 2
5579#define IPW_CMD_SET_ENCRYPTION 3
5580#define IPW_CMD_MLME 4
5581
5582#define IPW_PARAM_WPA_ENABLED 1
5583#define IPW_PARAM_TKIP_COUNTERMEASURES 2
5584#define IPW_PARAM_DROP_UNENCRYPTED 3
5585#define IPW_PARAM_PRIVACY_INVOKED 4
5586#define IPW_PARAM_AUTH_ALGS 5
5587#define IPW_PARAM_IEEE_802_1X 6
5588
5589#define IPW_MLME_STA_DEAUTH 1
5590#define IPW_MLME_STA_DISASSOC 2
5591
5592#define IPW_CRYPT_ERR_UNKNOWN_ALG 2
5593#define IPW_CRYPT_ERR_UNKNOWN_ADDR 3
5594#define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4
5595#define IPW_CRYPT_ERR_KEY_SET_FAILED 5
5596#define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6
5597#define IPW_CRYPT_ERR_CARD_CONF_FAILED 7
5598
5599#define IPW_CRYPT_ALG_NAME_LEN 16
5600
5601struct ipw_param {
5602 u32 cmd;
5603 u8 sta_addr[ETH_ALEN];
5604 union {
5605 struct {
5606 u8 name;
5607 u32 value;
5608 } wpa_param;
5609 struct {
5610 u32 len;
5611 u8 *data;
5612 } wpa_ie;
5613 struct {
5614 int command;
5615 int reason_code;
5616 } mlme;
5617 struct {
5618 u8 alg[IPW_CRYPT_ALG_NAME_LEN];
5619 u8 set_tx;
5620 u32 err;
5621 u8 idx;
5622 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5623 u16 key_len;
5624 u8 key[0];
5625 } crypt;
5626
5627 } u;
5628};
5629
5630/* end of driver_ipw.c code */
5631
5632static int ipw_wpa_enable(struct ipw_priv *priv, int value)
5633{
5634 struct ieee80211_device *ieee = priv->ieee;
5635 struct ieee80211_security sec = {
5636 .flags = SEC_LEVEL | SEC_ENABLED,
5637 };
5638 int ret = 0;
5639
5640 ieee->wpa_enabled = value;
5641
5642 if (value) {
5643 sec.level = SEC_LEVEL_3;
5644 sec.enabled = 1;
5645 } else {
5646 sec.level = SEC_LEVEL_0;
5647 sec.enabled = 0;
a613bffd 5648 ieee->wpa_ie_len = 0;
ea2b26e0
JK
5649 }
5650
5651 if (ieee->set_security)
5652 ieee->set_security(ieee->dev, &sec);
5653 else
5654 ret = -EOPNOTSUPP;
5655
5656 return ret;
5657}
5658
5659#define AUTH_ALG_OPEN_SYSTEM 0x1
5660#define AUTH_ALG_SHARED_KEY 0x2
5661
5662static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
5663{
5664 struct ieee80211_device *ieee = priv->ieee;
5665 struct ieee80211_security sec = {
5666 .flags = SEC_AUTH_MODE,
5667 };
5668 int ret = 0;
5669
5670 if (value & AUTH_ALG_SHARED_KEY) {
5671 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5672 ieee->open_wep = 0;
5673 } else {
5674 sec.auth_mode = WLAN_AUTH_OPEN;
5675 ieee->open_wep = 1;
5676 }
5677
5678 if (ieee->set_security)
5679 ieee->set_security(ieee->dev, &sec);
5680 else
5681 ret = -EOPNOTSUPP;
5682
5683 return ret;
5684}
5685
5686static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5687{
5688 struct ipw_priv *priv = ieee80211_priv(dev);
a613bffd
JK
5689 struct ieee80211_crypt_data *crypt;
5690 unsigned long flags;
ea2b26e0
JK
5691 int ret = 0;
5692
5693 switch (name) {
5694 case IPW_PARAM_WPA_ENABLED:
5695 ret = ipw_wpa_enable(priv, value);
5696 break;
5697
5698 case IPW_PARAM_TKIP_COUNTERMEASURES:
a613bffd
JK
5699 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5700 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
5701 IPW_WARNING("Can't set TKIP countermeasures: "
5702 "crypt not set!\n");
5703 break;
5704 }
5705
5706 flags = crypt->ops->get_flags(crypt->priv);
5707
5708 if (value)
5709 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5710 else
5711 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5712
5713 crypt->ops->set_flags(flags, crypt->priv);
5714
ea2b26e0
JK
5715 break;
5716
5717 case IPW_PARAM_DROP_UNENCRYPTED:
5718 priv->ieee->drop_unencrypted = value;
5719 break;
5720
5721 case IPW_PARAM_PRIVACY_INVOKED:
5722 priv->ieee->privacy_invoked = value;
5723 break;
5724
5725 case IPW_PARAM_AUTH_ALGS:
5726 ret = ipw_wpa_set_auth_algs(priv, value);
5727 break;
5728
5729 case IPW_PARAM_IEEE_802_1X:
5730 priv->ieee->ieee802_1x = value;
5731 break;
5732
5733 default:
5734 IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name);
5735 ret = -EOPNOTSUPP;
5736 }
5737
5738 return ret;
5739}
5740
5741static int ipw_wpa_mlme(struct net_device *dev, int command, int reason)
5742{
5743 struct ipw_priv *priv = ieee80211_priv(dev);
5744 int ret = 0;
5745
5746 switch (command) {
5747 case IPW_MLME_STA_DEAUTH:
5748 // silently ignore
5749 break;
5750
5751 case IPW_MLME_STA_DISASSOC:
5752 ipw_disassociate(priv);
5753 break;
5754
5755 default:
5756 IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command);
5757 ret = -EOPNOTSUPP;
5758 }
5759
5760 return ret;
5761}
5762
5763static int ipw_set_rsn_capa(struct ipw_priv *priv,
5764 char *capabilities, int length)
5765{
5766 struct host_cmd cmd = {
5767 .cmd = IPW_CMD_RSN_CAPABILITIES,
5768 .len = length,
5769 };
5770
5771 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
5772
5773 memcpy(&cmd.param, capabilities, length);
5774 if (ipw_send_cmd(priv, &cmd)) {
5775 IPW_ERROR("failed to send HOST_CMD_RSN_CAPABILITIES command\n");
5776 return -1;
5777 }
5778 return 0;
5779}
5780
5781void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
5782{
5783 /* make sure WPA is enabled */
5784 ipw_wpa_enable(priv, 1);
5785
c848d0af 5786 ipw_disassociate(priv);
ea2b26e0
JK
5787}
5788
5789static int ipw_wpa_set_wpa_ie(struct net_device *dev,
5790 struct ipw_param *param, int plen)
5791{
5792 struct ipw_priv *priv = ieee80211_priv(dev);
5793 struct ieee80211_device *ieee = priv->ieee;
5794 u8 *buf;
5795
5796 if (!ieee->wpa_enabled)
5797 return -EOPNOTSUPP;
5798
5799 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5800 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
5801 return -EINVAL;
5802
5803 if (param->u.wpa_ie.len) {
5804 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5805 if (buf == NULL)
5806 return -ENOMEM;
5807
5808 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
5809 kfree(ieee->wpa_ie);
5810 ieee->wpa_ie = buf;
5811 ieee->wpa_ie_len = param->u.wpa_ie.len;
5812 } else {
5813 kfree(ieee->wpa_ie);
5814 ieee->wpa_ie = NULL;
5815 ieee->wpa_ie_len = 0;
5816 }
5817
5818 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
5819 return 0;
5820}
5821
5822/* implementation borrowed from hostap driver */
5823
5824static int ipw_wpa_set_encryption(struct net_device *dev,
5825 struct ipw_param *param, int param_len)
5826{
5827 int ret = 0;
5828 struct ipw_priv *priv = ieee80211_priv(dev);
5829 struct ieee80211_device *ieee = priv->ieee;
5830 struct ieee80211_crypto_ops *ops;
5831 struct ieee80211_crypt_data **crypt;
5832
5833 struct ieee80211_security sec = {
5834 .flags = 0,
5835 };
5836
5837 param->u.crypt.err = 0;
5838 param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0';
5839
5840 if (param_len !=
5841 (int)((char *)param->u.crypt.key - (char *)param) +
5842 param->u.crypt.key_len) {
5843 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
5844 param->u.crypt.key_len);
5845 return -EINVAL;
5846 }
5847 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
5848 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
5849 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
5850 if (param->u.crypt.idx >= WEP_KEYS)
5851 return -EINVAL;
5852 crypt = &ieee->crypt[param->u.crypt.idx];
5853 } else {
5854 return -EINVAL;
5855 }
5856
5857 if (strcmp(param->u.crypt.alg, "none") == 0) {
5858 if (crypt) {
5859 sec.enabled = 0;
5860 sec.level = SEC_LEVEL_0;
5861 sec.flags |= SEC_ENABLED | SEC_LEVEL;
5862 ieee80211_crypt_delayed_deinit(ieee, crypt);
5863 }
5864 goto done;
5865 }
5866 sec.enabled = 1;
5867 sec.flags |= SEC_ENABLED;
5868
5869 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5870 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
5871 request_module("ieee80211_crypt_wep");
5872 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5873 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
5874 request_module("ieee80211_crypt_tkip");
5875 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5876 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
5877 request_module("ieee80211_crypt_ccmp");
5878 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5879 }
5880 if (ops == NULL) {
5881 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
5882 dev->name, param->u.crypt.alg);
5883 param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_ALG;
5884 ret = -EINVAL;
5885 goto done;
5886 }
5887
5888 if (*crypt == NULL || (*crypt)->ops != ops) {
5889 struct ieee80211_crypt_data *new_crypt;
5890
5891 ieee80211_crypt_delayed_deinit(ieee, crypt);
5892
5893 new_crypt = (struct ieee80211_crypt_data *)
5894 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
5895 if (new_crypt == NULL) {
5896 ret = -ENOMEM;
5897 goto done;
5898 }
5899 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
5900 new_crypt->ops = ops;
5901 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
5902 new_crypt->priv =
5903 new_crypt->ops->init(param->u.crypt.idx);
5904
5905 if (new_crypt->priv == NULL) {
5906 kfree(new_crypt);
5907 param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED;
5908 ret = -EINVAL;
5909 goto done;
5910 }
5911
5912 *crypt = new_crypt;
5913 }
5914
5915 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
5916 (*crypt)->ops->set_key(param->u.crypt.key,
5917 param->u.crypt.key_len, param->u.crypt.seq,
5918 (*crypt)->priv) < 0) {
5919 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
5920 param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED;
5921 ret = -EINVAL;
5922 goto done;
5923 }
5924
5925 if (param->u.crypt.set_tx) {
5926 ieee->tx_keyidx = param->u.crypt.idx;
5927 sec.active_key = param->u.crypt.idx;
5928 sec.flags |= SEC_ACTIVE_KEY;
5929 }
5930
5931 if (ops->name != NULL) {
5932 if (strcmp(ops->name, "WEP") == 0) {
5933 memcpy(sec.keys[param->u.crypt.idx],
5934 param->u.crypt.key, param->u.crypt.key_len);
5935 sec.key_sizes[param->u.crypt.idx] =
5936 param->u.crypt.key_len;
5937 sec.flags |= (1 << param->u.crypt.idx);
5938 sec.flags |= SEC_LEVEL;
5939 sec.level = SEC_LEVEL_1;
5940 } else if (strcmp(ops->name, "TKIP") == 0) {
5941 sec.flags |= SEC_LEVEL;
5942 sec.level = SEC_LEVEL_2;
5943 } else if (strcmp(ops->name, "CCMP") == 0) {
5944 sec.flags |= SEC_LEVEL;
5945 sec.level = SEC_LEVEL_3;
5946 }
5947 }
5948 done:
5949 if (ieee->set_security)
5950 ieee->set_security(ieee->dev, &sec);
5951
5952 /* Do not reset port if card is in Managed mode since resetting will
5953 * generate new IEEE 802.11 authentication which may end up in looping
5954 * with IEEE 802.1X. If your hardware requires a reset after WEP
5955 * configuration (for example... Prism2), implement the reset_port in
5956 * the callbacks structures used to initialize the 802.11 stack. */
5957 if (ieee->reset_on_keychange &&
5958 ieee->iw_mode != IW_MODE_INFRA &&
5959 ieee->reset_port && ieee->reset_port(dev)) {
5960 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
5961 param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED;
5962 return -EINVAL;
5963 }
5964
5965 return ret;
5966}
5967
5968static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p)
5969{
5970 struct ipw_param *param;
5971 int ret = 0;
5972
5973 IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
5974
5975 if (p->length < sizeof(struct ipw_param) || !p->pointer)
5976 return -EINVAL;
5977
5978 param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL);
5979 if (param == NULL)
5980 return -ENOMEM;
5981
5982 if (copy_from_user(param, p->pointer, p->length)) {
5983 kfree(param);
5984 return -EFAULT;
5985 }
5986
5987 switch (param->cmd) {
5988
5989 case IPW_CMD_SET_WPA_PARAM:
5990 ret = ipw_wpa_set_param(dev, param->u.wpa_param.name,
5991 param->u.wpa_param.value);
5992 break;
5993
5994 case IPW_CMD_SET_WPA_IE:
5995 ret = ipw_wpa_set_wpa_ie(dev, param, p->length);
5996 break;
5997
5998 case IPW_CMD_SET_ENCRYPTION:
5999 ret = ipw_wpa_set_encryption(dev, param, p->length);
6000 break;
6001
6002 case IPW_CMD_MLME:
6003 ret = ipw_wpa_mlme(dev, param->u.mlme.command,
6004 param->u.mlme.reason_code);
6005 break;
6006
6007 default:
6008 IPW_ERROR("%s: Unknown WPA supplicant request: %d\n",
6009 dev->name, param->cmd);
6010 ret = -EOPNOTSUPP;
6011 }
6012
6013 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6014 ret = -EFAULT;
6015
6016 kfree(param);
6017 return ret;
6018}
ea2b26e0
JK
6019
6020static int ipw_associate_network(struct ipw_priv *priv,
6021 struct ieee80211_network *network,
6022 struct ipw_supported_rates *rates, int roaming)
6023{
6024 int err;
6025
6026 if (priv->config & CFG_FIXED_RATE)
6027 ipw_set_fixed_rate(priv, network);
6028
6029 if (!(priv->config & CFG_STATIC_ESSID)) {
6030 priv->essid_len = min(network->ssid_len,
6031 (u8) IW_ESSID_MAX_SIZE);
6032 memcpy(priv->essid, network->ssid, priv->essid_len);
6033 }
6034
6035 network->last_associate = jiffies;
6036
6037 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
6038 priv->assoc_request.channel = network->channel;
6039 if ((priv->capability & CAP_PRIVACY_ON) &&
6040 (priv->capability & CAP_SHARED_KEY)) {
6041 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
6042 priv->assoc_request.auth_key = priv->sec.active_key;
6043 } else {
6044 priv->assoc_request.auth_type = AUTH_OPEN;
6045 priv->assoc_request.auth_key = 0;
6046 }
6047
6048 if (priv->capability & CAP_PRIVACY_ON)
6049 ipw_send_wep_keys(priv);
6050
a613bffd 6051 if (priv->ieee->wpa_ie_len) {
ea2b26e0
JK
6052 priv->assoc_request.policy_support = 0x02; /* RSN active */
6053 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
6054 priv->ieee->wpa_ie_len);
6055 }
ea2b26e0
JK
6056
6057 /*
6058 * It is valid for our ieee device to support multiple modes, but
6059 * when it comes to associating to a given network we have to choose
6060 * just one mode.
6061 */
6062 if (network->mode & priv->ieee->mode & IEEE_A)
6063 priv->assoc_request.ieee_mode = IPW_A_MODE;
6064 else if (network->mode & priv->ieee->mode & IEEE_G)
6065 priv->assoc_request.ieee_mode = IPW_G_MODE;
6066 else if (network->mode & priv->ieee->mode & IEEE_B)
6067 priv->assoc_request.ieee_mode = IPW_B_MODE;
6068
6069 priv->assoc_request.capability = network->capability;
6070 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
6071 && !(priv->config & CFG_PREAMBLE_LONG)) {
6072 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
6073 } else {
6074 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
6075
6076 /* Clear the short preamble if we won't be supporting it */
6077 priv->assoc_request.capability &=
6078 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
6079 }
6080
6081 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
6082 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
6083 roaming ? "Rea" : "A",
6084 escape_essid(priv->essid, priv->essid_len),
6085 network->channel,
6086 ipw_modes[priv->assoc_request.ieee_mode],
6087 rates->num_rates,
6088 (priv->assoc_request.preamble_length ==
6089 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
6090 network->capability &
6091 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
6092 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
6093 priv->capability & CAP_PRIVACY_ON ?
6094 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
6095 "(open)") : "",
6096 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
6097 priv->capability & CAP_PRIVACY_ON ?
6098 '1' + priv->sec.active_key : '.',
6099 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
6100
6101 priv->assoc_request.beacon_interval = network->beacon_interval;
6102 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
6103 (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {
6104 priv->assoc_request.assoc_type = HC_IBSS_START;
6105 priv->assoc_request.assoc_tsf_msw = 0;
6106 priv->assoc_request.assoc_tsf_lsw = 0;
6107 } else {
6108 if (unlikely(roaming))
6109 priv->assoc_request.assoc_type = HC_REASSOCIATE;
6110 else
6111 priv->assoc_request.assoc_type = HC_ASSOCIATE;
6112 priv->assoc_request.assoc_tsf_msw = network->time_stamp[1];
6113 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
6114 }
6115
6116 memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN);
6117
6118 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6119 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
6120 priv->assoc_request.atim_window = network->atim_window;
6121 } else {
6122 memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN);
6123 priv->assoc_request.atim_window = 0;
6124 }
6125
6126 priv->assoc_request.listen_interval = network->listen_interval;
6127
6128 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6129 if (err) {
6130 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
6131 return err;
6132 }
6133
6134 rates->ieee_mode = priv->assoc_request.ieee_mode;
6135 rates->purpose = IPW_RATE_CONNECT;
6136 ipw_send_supported_rates(priv, rates);
6137
6138 if (priv->assoc_request.ieee_mode == IPW_G_MODE)
6139 priv->sys_config.dot11g_auto_detection = 1;
6140 else
6141 priv->sys_config.dot11g_auto_detection = 0;
c848d0af
JK
6142
6143 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
6144 priv->sys_config.answer_broadcast_ssid_probe = 1;
6145 else
6146 priv->sys_config.answer_broadcast_ssid_probe = 0;
6147
ea2b26e0
JK
6148 err = ipw_send_system_config(priv, &priv->sys_config);
6149 if (err) {
6150 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
6151 return err;
6152 }
6153
6154 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
6155 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
6156 if (err) {
6157 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
6158 return err;
6159 }
6160
6161 /*
6162 * If preemption is enabled, it is possible for the association
6163 * to complete before we return from ipw_send_associate. Therefore
6164 * we have to be sure and update our priviate data first.
6165 */
6166 priv->channel = network->channel;
6167 memcpy(priv->bssid, network->bssid, ETH_ALEN);
6168 priv->status |= STATUS_ASSOCIATING;
6169 priv->status &= ~STATUS_SECURITY_UPDATED;
6170
6171 priv->assoc_network = network;
6172
6173 err = ipw_send_associate(priv, &priv->assoc_request);
6174 if (err) {
43f66a6c
JK
6175 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
6176 return err;
6177 }
bf79451e
JG
6178
6179 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n",
43f66a6c
JK
6180 escape_essid(priv->essid, priv->essid_len),
6181 MAC_ARG(priv->bssid));
6182
6183 return 0;
6184}
6185
6186static void ipw_roam(void *data)
6187{
6188 struct ipw_priv *priv = data;
6189 struct ieee80211_network *network = NULL;
6190 struct ipw_network_match match = {
6191 .network = priv->assoc_network
6192 };
6193
6194 /* The roaming process is as follows:
bf79451e
JG
6195 *
6196 * 1. Missed beacon threshold triggers the roaming process by
43f66a6c
JK
6197 * setting the status ROAM bit and requesting a scan.
6198 * 2. When the scan completes, it schedules the ROAM work
6199 * 3. The ROAM work looks at all of the known networks for one that
6200 * is a better network than the currently associated. If none
6201 * found, the ROAM process is over (ROAM bit cleared)
6202 * 4. If a better network is found, a disassociation request is
6203 * sent.
6204 * 5. When the disassociation completes, the roam work is again
6205 * scheduled. The second time through, the driver is no longer
6206 * associated, and the newly selected network is sent an
bf79451e 6207 * association request.
43f66a6c
JK
6208 * 6. At this point ,the roaming process is complete and the ROAM
6209 * status bit is cleared.
6210 */
6211
6212 /* If we are no longer associated, and the roaming bit is no longer
6213 * set, then we are not actively roaming, so just return */
6214 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING)))
6215 return;
bf79451e 6216
43f66a6c 6217 if (priv->status & STATUS_ASSOCIATED) {
bf79451e 6218 /* First pass through ROAM process -- look for a better
43f66a6c 6219 * network */
a613bffd 6220 unsigned long flags;
43f66a6c
JK
6221 u8 rssi = priv->assoc_network->stats.rssi;
6222 priv->assoc_network->stats.rssi = -128;
a613bffd 6223 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c
JK
6224 list_for_each_entry(network, &priv->ieee->network_list, list) {
6225 if (network != priv->assoc_network)
6226 ipw_best_network(priv, &match, network, 1);
6227 }
a613bffd 6228 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c 6229 priv->assoc_network->stats.rssi = rssi;
bf79451e 6230
43f66a6c
JK
6231 if (match.network == priv->assoc_network) {
6232 IPW_DEBUG_ASSOC("No better APs in this network to "
6233 "roam to.\n");
6234 priv->status &= ~STATUS_ROAMING;
6235 ipw_debug_config(priv);
6236 return;
6237 }
bf79451e 6238
43f66a6c
JK
6239 ipw_send_disassociate(priv, 1);
6240 priv->assoc_network = match.network;
6241
6242 return;
bf79451e 6243 }
43f66a6c
JK
6244
6245 /* Second pass through ROAM process -- request association */
6246 ipw_compatible_rates(priv, priv->assoc_network, &match.rates);
6247 ipw_associate_network(priv, priv->assoc_network, &match.rates, 1);
6248 priv->status &= ~STATUS_ROAMING;
6249}
6250
c848d0af
JK
6251static void ipw_bg_roam(void *data)
6252{
6253 struct ipw_priv *priv = data;
6254 down(&priv->sem);
6255 ipw_roam(data);
6256 up(&priv->sem);
6257}
6258
6259static int ipw_associate(void *data)
43f66a6c
JK
6260{
6261 struct ipw_priv *priv = data;
6262
6263 struct ieee80211_network *network = NULL;
6264 struct ipw_network_match match = {
6265 .network = NULL
6266 };
6267 struct ipw_supported_rates *rates;
6268 struct list_head *element;
a613bffd 6269 unsigned long flags;
43f66a6c 6270
c848d0af
JK
6271 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6272 IPW_DEBUG_ASSOC
6273 ("Not attempting association (already in progress)\n");
6274 return 0;
6275 }
6276
6277 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
6278 IPW_DEBUG_ASSOC
6279 ("Not attempting association (scanning or not initialized)\n");
6280 return 0;
6281 }
6282
43f66a6c
JK
6283 if (!(priv->config & CFG_ASSOCIATE) &&
6284 !(priv->config & (CFG_STATIC_ESSID |
0edd5b44 6285 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
43f66a6c 6286 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
c848d0af 6287 return 0;
43f66a6c
JK
6288 }
6289
a613bffd
JK
6290 /* Protect our use of the network_list */
6291 spin_lock_irqsave(&priv->ieee->lock, flags);
bf79451e 6292 list_for_each_entry(network, &priv->ieee->network_list, list)
0edd5b44 6293 ipw_best_network(priv, &match, network, 0);
43f66a6c
JK
6294
6295 network = match.network;
6296 rates = &match.rates;
6297
6298 if (network == NULL &&
6299 priv->ieee->iw_mode == IW_MODE_ADHOC &&
6300 priv->config & CFG_ADHOC_CREATE &&
6301 priv->config & CFG_STATIC_ESSID &&
a613bffd 6302 priv->config & CFG_STATIC_CHANNEL &&
43f66a6c
JK
6303 !list_empty(&priv->ieee->network_free_list)) {
6304 element = priv->ieee->network_free_list.next;
0edd5b44 6305 network = list_entry(element, struct ieee80211_network, list);
43f66a6c
JK
6306 ipw_adhoc_create(priv, network);
6307 rates = &priv->rates;
6308 list_del(element);
6309 list_add_tail(&network->list, &priv->ieee->network_list);
6310 }
a613bffd 6311 spin_unlock_irqrestore(&priv->ieee->lock, flags);
bf79451e 6312
43f66a6c
JK
6313 /* If we reached the end of the list, then we don't have any valid
6314 * matching APs */
6315 if (!network) {
6316 ipw_debug_config(priv);
6317
a613bffd
JK
6318 if (!(priv->status & STATUS_SCANNING))
6319 queue_delayed_work(priv->workqueue, &priv->request_scan,
6320 SCAN_INTERVAL);
bf79451e 6321
c848d0af 6322 return 0;
43f66a6c
JK
6323 }
6324
6325 ipw_associate_network(priv, network, rates, 0);
c848d0af
JK
6326
6327 return 1;
6328}
6329
6330static void ipw_bg_associate(void *data)
6331{
6332 struct ipw_priv *priv = data;
6333 down(&priv->sem);
6334 ipw_associate(data);
6335 up(&priv->sem);
43f66a6c 6336}
bf79451e
JG
6337
6338static inline void ipw_handle_data_packet(struct ipw_priv *priv,
0edd5b44
JG
6339 struct ipw_rx_mem_buffer *rxb,
6340 struct ieee80211_rx_stats *stats)
43f66a6c
JK
6341{
6342 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
6343
6344 /* We received data from the HW, so stop the watchdog */
6345 priv->net_dev->trans_start = jiffies;
6346
bf79451e 6347 /* We only process data packets if the
43f66a6c 6348 * interface is open */
a613bffd 6349 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
43f66a6c
JK
6350 skb_tailroom(rxb->skb))) {
6351 priv->ieee->stats.rx_errors++;
6352 priv->wstats.discard.misc++;
6353 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
6354 return;
6355 } else if (unlikely(!netif_running(priv->net_dev))) {
6356 priv->ieee->stats.rx_dropped++;
6357 priv->wstats.discard.misc++;
6358 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
6359 return;
6360 }
6361
6362 /* Advance skb->data to the start of the actual payload */
aaa4d308 6363 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
43f66a6c
JK
6364
6365 /* Set the size of the skb to the size of the frame */
a613bffd 6366 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
43f66a6c
JK
6367
6368 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
6369
bf79451e 6370 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
43f66a6c 6371 priv->ieee->stats.rx_errors++;
a613bffd 6372 else { /* ieee80211_rx succeeded, so it now owns the SKB */
43f66a6c 6373 rxb->skb = NULL;
a613bffd
JK
6374 ipw_led_activity_on(priv);
6375 }
43f66a6c
JK
6376}
6377
ea2b26e0
JK
6378static inline int is_network_packet(struct ipw_priv *priv,
6379 struct ieee80211_hdr_4addr *header)
6380{
6381 /* Filter incoming packets to determine if they are targetted toward
6382 * this network, discarding packets coming from ourselves */
6383 switch (priv->ieee->iw_mode) {
a613bffd 6384 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
c848d0af
JK
6385 /* packets from our adapter are dropped (echo) */
6386 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
6387 return 0;
6388
a613bffd 6389 /* {broad,multi}cast packets to our IBSS go through */
ea2b26e0
JK
6390 if (is_broadcast_ether_addr(header->addr1) ||
6391 is_multicast_ether_addr(header->addr1))
6392 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
a613bffd
JK
6393
6394 /* packets to our adapter go through */
6395 return !memcmp(header->addr1, priv->net_dev->dev_addr,
6396 ETH_ALEN);
a613bffd
JK
6397
6398 case IW_MODE_INFRA: /* Header: Dest. | AP{BSSID} | Source */
c848d0af
JK
6399 /* packets from our adapter are dropped (echo) */
6400 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
6401 return 0;
6402
a613bffd
JK
6403 /* {broad,multi}cast packets to our IBSS go through */
6404 if (is_broadcast_ether_addr(header->addr1) ||
6405 is_multicast_ether_addr(header->addr1))
6406 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
6407
6408 /* packets to our adapter go through */
6409 return !memcmp(header->addr1, priv->net_dev->dev_addr,
6410 ETH_ALEN);
ea2b26e0 6411 }
a613bffd 6412
ea2b26e0
JK
6413 return 1;
6414}
6415
43f66a6c
JK
6416/*
6417 * Main entry function for recieving a packet with 80211 headers. This
6418 * should be called when ever the FW has notified us that there is a new
6419 * skb in the recieve queue.
6420 */
6421static void ipw_rx(struct ipw_priv *priv)
6422{
6423 struct ipw_rx_mem_buffer *rxb;
6424 struct ipw_rx_packet *pkt;
0dacca1f 6425 struct ieee80211_hdr_4addr *header;
43f66a6c
JK
6426 u32 r, w, i;
6427 u8 network_packet;
6428
6429 r = ipw_read32(priv, CX2_RX_READ_INDEX);
6430 w = ipw_read32(priv, CX2_RX_WRITE_INDEX);
6431 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
6432
6433 while (i != r) {
6434 rxb = priv->rxq->queue[i];
6435#ifdef CONFIG_IPW_DEBUG
6436 if (unlikely(rxb == NULL)) {
6437 printk(KERN_CRIT "Queue not allocated!\n");
6438 break;
6439 }
6440#endif
6441 priv->rxq->queue[i] = NULL;
6442
6443 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
bf79451e 6444 CX2_RX_BUF_SIZE,
43f66a6c
JK
6445 PCI_DMA_FROMDEVICE);
6446
6447 pkt = (struct ipw_rx_packet *)rxb->skb->data;
6448 IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",
6449 pkt->header.message_type,
0edd5b44 6450 pkt->header.rx_seq_num, pkt->header.control_bits);
43f66a6c
JK
6451
6452 switch (pkt->header.message_type) {
0edd5b44
JG
6453 case RX_FRAME_TYPE: /* 802.11 frame */ {
6454 struct ieee80211_rx_stats stats = {
c848d0af
JK
6455 .rssi =
6456 le16_to_cpu(pkt->u.frame.rssi_dbm) -
0edd5b44 6457 IPW_RSSI_TO_DBM,
c848d0af
JK
6458 .signal =
6459 le16_to_cpu(pkt->u.frame.signal),
6460 .noise =
6461 le16_to_cpu(pkt->u.frame.noise),
0edd5b44
JG
6462 .rate = pkt->u.frame.rate,
6463 .mac_time = jiffies,
6464 .received_channel =
6465 pkt->u.frame.received_channel,
6466 .freq =
6467 (pkt->u.frame.
6468 control & (1 << 0)) ?
6469 IEEE80211_24GHZ_BAND :
6470 IEEE80211_52GHZ_BAND,
a613bffd 6471 .len = le16_to_cpu(pkt->u.frame.length),
0edd5b44
JG
6472 };
6473
6474 if (stats.rssi != 0)
6475 stats.mask |= IEEE80211_STATMASK_RSSI;
6476 if (stats.signal != 0)
6477 stats.mask |= IEEE80211_STATMASK_SIGNAL;
c848d0af
JK
6478 if (stats.noise != 0)
6479 stats.mask |= IEEE80211_STATMASK_NOISE;
0edd5b44
JG
6480 if (stats.rate != 0)
6481 stats.mask |= IEEE80211_STATMASK_RATE;
6482
6483 priv->rx_packets++;
43f66a6c 6484
ea2b26e0 6485#ifdef CONFIG_IPW_MONITOR
0edd5b44
JG
6486 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
6487 ipw_handle_data_packet(priv, rxb,
6488 &stats);
6489 break;
6490 }
43f66a6c 6491#endif
bf79451e 6492
0edd5b44 6493 header =
0dacca1f
JK
6494 (struct ieee80211_hdr_4addr *)(rxb->skb->
6495 data +
6496 IPW_RX_FRAME_SIZE);
43f66a6c
JK
6497 /* TODO: Check Ad-Hoc dest/source and make sure
6498 * that we are actually parsing these packets
bf79451e 6499 * correctly -- we should probably use the
43f66a6c
JK
6500 * frame control of the packet and disregard
6501 * the current iw_mode */
0edd5b44 6502
ea2b26e0
JK
6503 network_packet =
6504 is_network_packet(priv, header);
0edd5b44
JG
6505 if (network_packet && priv->assoc_network) {
6506 priv->assoc_network->stats.rssi =
6507 stats.rssi;
6508 average_add(&priv->average_rssi,
6509 stats.rssi);
6510 priv->last_rx_rssi = stats.rssi;
6511 }
6512
6513 IPW_DEBUG_RX("Frame: len=%u\n",
a613bffd 6514 le16_to_cpu(pkt->u.frame.length));
0edd5b44 6515
a613bffd
JK
6516 if (le16_to_cpu(pkt->u.frame.length) <
6517 frame_hdr_len(header)) {
0edd5b44
JG
6518 IPW_DEBUG_DROP
6519 ("Received packet is too small. "
6520 "Dropping.\n");
6521 priv->ieee->stats.rx_errors++;
6522 priv->wstats.discard.misc++;
6523 break;
6524 }
6525
a613bffd
JK
6526 switch (WLAN_FC_GET_TYPE
6527 (le16_to_cpu(header->frame_ctl))) {
0edd5b44
JG
6528 case IEEE80211_FTYPE_MGMT:
6529 ieee80211_rx_mgt(priv->ieee, header,
6530 &stats);
6531 if (priv->ieee->iw_mode == IW_MODE_ADHOC
6532 &&
6533 ((WLAN_FC_GET_STYPE
a613bffd
JK
6534 (le16_to_cpu(header->frame_ctl))
6535 == IEEE80211_STYPE_PROBE_RESP)
0edd5b44
JG
6536 ||
6537 (WLAN_FC_GET_STYPE
a613bffd 6538 (le16_to_cpu(header->frame_ctl))
c848d0af
JK
6539 == IEEE80211_STYPE_BEACON))) {
6540 if (!memcmp
6541 (header->addr3, priv->bssid,
6542 ETH_ALEN))
6543 ipw_add_station(priv,
6544 header->
6545 addr2);
6546 else {
6547 struct
6548 ieee80211_probe_response
6549 *beacon;
6550 beacon =
6551 (struct
6552 ieee80211_probe_response
6553 *)header;
6554 if (le16_to_cpu
6555 (beacon->
6556 capability) &
6557 WLAN_CAPABILITY_IBSS)
6558 {
6559 queue_work
6560 (priv->
6561 workqueue,
6562 &priv->
6563 merge_networks);
6564 }
6565 }
6566 }
0edd5b44
JG
6567 break;
6568
6569 case IEEE80211_FTYPE_CTL:
6570 break;
6571
6572 case IEEE80211_FTYPE_DATA:
6573 if (network_packet)
6574 ipw_handle_data_packet(priv,
6575 rxb,
6576 &stats);
6577 else
6578 IPW_DEBUG_DROP("Dropping: "
6579 MAC_FMT ", "
6580 MAC_FMT ", "
6581 MAC_FMT "\n",
6582 MAC_ARG(header->
6583 addr1),
6584 MAC_ARG(header->
6585 addr2),
6586 MAC_ARG(header->
6587 addr3));
6588 break;
6589 }
43f66a6c
JK
6590 break;
6591 }
bf79451e 6592
0edd5b44
JG
6593 case RX_HOST_NOTIFICATION_TYPE:{
6594 IPW_DEBUG_RX
6595 ("Notification: subtype=%02X flags=%02X size=%d\n",
43f66a6c
JK
6596 pkt->u.notification.subtype,
6597 pkt->u.notification.flags,
6598 pkt->u.notification.size);
0edd5b44
JG
6599 ipw_rx_notification(priv, &pkt->u.notification);
6600 break;
6601 }
43f66a6c
JK
6602
6603 default:
6604 IPW_DEBUG_RX("Bad Rx packet of type %d\n",
6605 pkt->header.message_type);
6606 break;
6607 }
bf79451e
JG
6608
6609 /* For now we just don't re-use anything. We can tweak this
6610 * later to try and re-use notification packets and SKBs that
43f66a6c
JK
6611 * fail to Rx correctly */
6612 if (rxb->skb != NULL) {
6613 dev_kfree_skb_any(rxb->skb);
6614 rxb->skb = NULL;
6615 }
bf79451e 6616
43f66a6c
JK
6617 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
6618 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
6619 list_add_tail(&rxb->list, &priv->rxq->rx_used);
bf79451e 6620
43f66a6c
JK
6621 i = (i + 1) % RX_QUEUE_SIZE;
6622 }
6623
6624 /* Backtrack one entry */
6625 priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1;
6626
6627 ipw_rx_queue_restock(priv);
6628}
6629
43f66a6c
JK
6630/*
6631 * This file defines the Wireless Extension handlers. It does not
6632 * define any methods of hardware manipulation and relies on the
6633 * functions defined in ipw_main to provide the HW interaction.
bf79451e
JG
6634 *
6635 * The exception to this is the use of the ipw_get_ordinal()
43f66a6c
JK
6636 * function used to poll the hardware vs. making unecessary calls.
6637 *
6638 */
6639
bf79451e
JG
6640static int ipw_wx_get_name(struct net_device *dev,
6641 struct iw_request_info *info,
43f66a6c
JK
6642 union iwreq_data *wrqu, char *extra)
6643{
6644 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af
JK
6645 down(&priv->sem);
6646 if (priv->status & STATUS_RF_KILL_MASK)
a613bffd 6647 strcpy(wrqu->name, "radio off");
c848d0af 6648 else if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c 6649 strcpy(wrqu->name, "unassociated");
bf79451e 6650 else
43f66a6c
JK
6651 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
6652 ipw_modes[priv->assoc_request.ieee_mode]);
6653 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
c848d0af 6654 up(&priv->sem);
43f66a6c
JK
6655 return 0;
6656}
6657
6658static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
6659{
6660 if (channel == 0) {
6661 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
6662 priv->config &= ~CFG_STATIC_CHANNEL;
c848d0af
JK
6663 IPW_DEBUG_ASSOC("Attempting to associate with new "
6664 "parameters.\n");
6665 ipw_associate(priv);
43f66a6c
JK
6666 return 0;
6667 }
6668
6669 priv->config |= CFG_STATIC_CHANNEL;
6670
6671 if (priv->channel == channel) {
0edd5b44
JG
6672 IPW_DEBUG_INFO("Request to set channel to current value (%d)\n",
6673 channel);
43f66a6c
JK
6674 return 0;
6675 }
6676
6677 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
6678 priv->channel = channel;
6679
c848d0af
JK
6680 /* Network configuration changed -- force [re]association */
6681 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
6682 if (!ipw_disassociate(priv))
43f66a6c 6683 ipw_associate(priv);
43f66a6c
JK
6684
6685 return 0;
6686}
6687
bf79451e
JG
6688static int ipw_wx_set_freq(struct net_device *dev,
6689 struct iw_request_info *info,
6690 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
6691{
6692 struct ipw_priv *priv = ieee80211_priv(dev);
6693 struct iw_freq *fwrq = &wrqu->freq;
c848d0af 6694 int ret = 0;
bf79451e 6695
43f66a6c
JK
6696 /* if setting by freq convert to channel */
6697 if (fwrq->e == 1) {
0edd5b44 6698 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) {
43f66a6c
JK
6699 int f = fwrq->m / 100000;
6700 int c = 0;
bf79451e 6701
43f66a6c
JK
6702 while ((c < REG_MAX_CHANNEL) &&
6703 (f != ipw_frequencies[c]))
6704 c++;
bf79451e 6705
43f66a6c
JK
6706 /* hack to fall through */
6707 fwrq->e = 0;
6708 fwrq->m = c + 1;
6709 }
6710 }
bf79451e
JG
6711
6712 if (fwrq->e > 0 || fwrq->m > 1000)
43f66a6c
JK
6713 return -EOPNOTSUPP;
6714
6715 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
c848d0af
JK
6716 down(&priv->sem);
6717 ret = ipw_set_channel(priv, (u8) fwrq->m);
6718 up(&priv->sem);
6719 return ret;
43f66a6c
JK
6720}
6721
bf79451e
JG
6722static int ipw_wx_get_freq(struct net_device *dev,
6723 struct iw_request_info *info,
43f66a6c
JK
6724 union iwreq_data *wrqu, char *extra)
6725{
6726 struct ipw_priv *priv = ieee80211_priv(dev);
6727
6728 wrqu->freq.e = 0;
6729
6730 /* If we are associated, trying to associate, or have a statically
6731 * configured CHANNEL then return that; otherwise return ANY */
c848d0af 6732 down(&priv->sem);
43f66a6c
JK
6733 if (priv->config & CFG_STATIC_CHANNEL ||
6734 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
6735 wrqu->freq.m = priv->channel;
bf79451e 6736 else
43f66a6c
JK
6737 wrqu->freq.m = 0;
6738
c848d0af 6739 up(&priv->sem);
43f66a6c
JK
6740 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
6741 return 0;
6742}
6743
bf79451e
JG
6744static int ipw_wx_set_mode(struct net_device *dev,
6745 struct iw_request_info *info,
43f66a6c
JK
6746 union iwreq_data *wrqu, char *extra)
6747{
6748 struct ipw_priv *priv = ieee80211_priv(dev);
6749 int err = 0;
6750
6751 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
c848d0af
JK
6752 down(&priv->sem);
6753 if (wrqu->mode == priv->ieee->iw_mode) {
6754 up(&priv->sem);
43f66a6c 6755 return 0;
c848d0af 6756 }
43f66a6c
JK
6757
6758 switch (wrqu->mode) {
ea2b26e0 6759#ifdef CONFIG_IPW_MONITOR
43f66a6c
JK
6760 case IW_MODE_MONITOR:
6761#endif
6762 case IW_MODE_ADHOC:
6763 case IW_MODE_INFRA:
6764 break;
6765 case IW_MODE_AUTO:
6766 wrqu->mode = IW_MODE_INFRA;
6767 break;
6768 default:
c848d0af 6769 up(&priv->sem);
43f66a6c
JK
6770 return -EINVAL;
6771 }
6772
ea2b26e0 6773#ifdef CONFIG_IPW_MONITOR
bf79451e 6774 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
43f66a6c 6775 priv->net_dev->type = ARPHRD_ETHER;
bf79451e
JG
6776
6777 if (wrqu->mode == IW_MODE_MONITOR)
43f66a6c 6778 priv->net_dev->type = ARPHRD_IEEE80211;
ea2b26e0 6779#endif /* CONFIG_IPW_MONITOR */
bf79451e 6780
43f66a6c 6781#ifdef CONFIG_PM
bf79451e 6782 /* Free the existing firmware and reset the fw_loaded
43f66a6c 6783 * flag so ipw_load() will bring in the new firmawre */
a613bffd 6784 if (fw_loaded)
43f66a6c 6785 fw_loaded = 0;
43f66a6c
JK
6786
6787 release_firmware(bootfw);
6788 release_firmware(ucode);
6789 release_firmware(firmware);
6790 bootfw = ucode = firmware = NULL;
6791#endif
6792
6793 priv->ieee->iw_mode = wrqu->mode;
bf79451e 6794
c848d0af
JK
6795 queue_work(priv->workqueue, &priv->adapter_restart);
6796 up(&priv->sem);
0edd5b44 6797 return err;
43f66a6c
JK
6798}
6799
bf79451e 6800static int ipw_wx_get_mode(struct net_device *dev,
0edd5b44
JG
6801 struct iw_request_info *info,
6802 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
6803{
6804 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 6805 down(&priv->sem);
43f66a6c
JK
6806 wrqu->mode = priv->ieee->iw_mode;
6807 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
c848d0af 6808 up(&priv->sem);
43f66a6c
JK
6809 return 0;
6810}
6811
43f66a6c
JK
6812#define DEFAULT_RTS_THRESHOLD 2304U
6813#define MIN_RTS_THRESHOLD 1U
6814#define MAX_RTS_THRESHOLD 2304U
6815#define DEFAULT_BEACON_INTERVAL 100U
6816#define DEFAULT_SHORT_RETRY_LIMIT 7U
6817#define DEFAULT_LONG_RETRY_LIMIT 4U
6818
6819/* Values are in microsecond */
6820static const s32 timeout_duration[] = {
6821 350000,
6822 250000,
6823 75000,
6824 37000,
6825 25000,
6826};
6827
6828static const s32 period_duration[] = {
6829 400000,
6830 700000,
6831 1000000,
6832 1000000,
6833 1000000
6834};
6835
bf79451e
JG
6836static int ipw_wx_get_range(struct net_device *dev,
6837 struct iw_request_info *info,
43f66a6c
JK
6838 union iwreq_data *wrqu, char *extra)
6839{
6840 struct ipw_priv *priv = ieee80211_priv(dev);
6841 struct iw_range *range = (struct iw_range *)extra;
6842 u16 val;
6843 int i;
6844
6845 wrqu->data.length = sizeof(*range);
6846 memset(range, 0, sizeof(*range));
6847
6848 /* 54Mbs == ~27 Mb/s real (802.11g) */
bf79451e 6849 range->throughput = 27 * 1000 * 1000;
43f66a6c
JK
6850
6851 range->max_qual.qual = 100;
6852 /* TODO: Find real max RSSI and stick here */
6853 range->max_qual.level = 0;
c848d0af 6854 range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
0edd5b44 6855 range->max_qual.updated = 7; /* Updated all three */
43f66a6c
JK
6856
6857 range->avg_qual.qual = 70;
6858 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
0edd5b44 6859 range->avg_qual.level = 0; /* FIXME to real average level */
43f66a6c 6860 range->avg_qual.noise = 0;
0edd5b44 6861 range->avg_qual.updated = 7; /* Updated all three */
c848d0af 6862 down(&priv->sem);
0edd5b44 6863 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
43f66a6c 6864
bf79451e
JG
6865 for (i = 0; i < range->num_bitrates; i++)
6866 range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) *
0edd5b44 6867 500000;
bf79451e 6868
43f66a6c
JK
6869 range->max_rts = DEFAULT_RTS_THRESHOLD;
6870 range->min_frag = MIN_FRAG_THRESHOLD;
6871 range->max_frag = MAX_FRAG_THRESHOLD;
6872
6873 range->encoding_size[0] = 5;
bf79451e 6874 range->encoding_size[1] = 13;
43f66a6c
JK
6875 range->num_encoding_sizes = 2;
6876 range->max_encoding_tokens = WEP_KEYS;
6877
6878 /* Set the Wireless Extension versions */
6879 range->we_version_compiled = WIRELESS_EXT;
6880 range->we_version_source = 16;
6881
0edd5b44 6882 range->num_channels = FREQ_COUNT;
43f66a6c
JK
6883
6884 val = 0;
6885 for (i = 0; i < FREQ_COUNT; i++) {
6886 range->freq[val].i = i + 1;
6887 range->freq[val].m = ipw_frequencies[i] * 100000;
6888 range->freq[val].e = 1;
6889 val++;
6890
6891 if (val == IW_MAX_FREQUENCIES)
6892 break;
6893 }
6894 range->num_frequency = val;
c848d0af 6895 up(&priv->sem);
43f66a6c
JK
6896 IPW_DEBUG_WX("GET Range\n");
6897 return 0;
6898}
6899
bf79451e
JG
6900static int ipw_wx_set_wap(struct net_device *dev,
6901 struct iw_request_info *info,
43f66a6c
JK
6902 union iwreq_data *wrqu, char *extra)
6903{
6904 struct ipw_priv *priv = ieee80211_priv(dev);
6905
6906 static const unsigned char any[] = {
6907 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
6908 };
6909 static const unsigned char off[] = {
6910 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
6911 };
6912
bf79451e 6913 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
43f66a6c 6914 return -EINVAL;
c848d0af 6915 down(&priv->sem);
43f66a6c
JK
6916 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
6917 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
6918 /* we disable mandatory BSSID association */
6919 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
6920 priv->config &= ~CFG_STATIC_BSSID;
c848d0af
JK
6921 IPW_DEBUG_ASSOC("Attempting to associate with new "
6922 "parameters.\n");
6923 ipw_associate(priv);
6924 up(&priv->sem);
43f66a6c
JK
6925 return 0;
6926 }
6927
6928 priv->config |= CFG_STATIC_BSSID;
6929 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
6930 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
c848d0af 6931 up(&priv->sem);
43f66a6c
JK
6932 return 0;
6933 }
6934
6935 IPW_DEBUG_WX("Setting mandatory BSSID to " MAC_FMT "\n",
6936 MAC_ARG(wrqu->ap_addr.sa_data));
6937
6938 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
6939
c848d0af
JK
6940 /* Network configuration changed -- force [re]association */
6941 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
6942 if (!ipw_disassociate(priv))
43f66a6c 6943 ipw_associate(priv);
43f66a6c 6944
c848d0af 6945 up(&priv->sem);
43f66a6c
JK
6946 return 0;
6947}
6948
bf79451e
JG
6949static int ipw_wx_get_wap(struct net_device *dev,
6950 struct iw_request_info *info,
43f66a6c
JK
6951 union iwreq_data *wrqu, char *extra)
6952{
6953 struct ipw_priv *priv = ieee80211_priv(dev);
6954 /* If we are associated, trying to associate, or have a statically
6955 * configured BSSID then return that; otherwise return ANY */
c848d0af 6956 down(&priv->sem);
bf79451e 6957 if (priv->config & CFG_STATIC_BSSID ||
43f66a6c
JK
6958 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6959 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
6960 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
6961 } else
6962 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
6963
6964 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
6965 MAC_ARG(wrqu->ap_addr.sa_data));
c848d0af 6966 up(&priv->sem);
43f66a6c
JK
6967 return 0;
6968}
6969
bf79451e
JG
6970static int ipw_wx_set_essid(struct net_device *dev,
6971 struct iw_request_info *info,
43f66a6c
JK
6972 union iwreq_data *wrqu, char *extra)
6973{
6974 struct ipw_priv *priv = ieee80211_priv(dev);
0edd5b44 6975 char *essid = ""; /* ANY */
43f66a6c 6976 int length = 0;
c848d0af 6977 down(&priv->sem);
43f66a6c
JK
6978 if (wrqu->essid.flags && wrqu->essid.length) {
6979 length = wrqu->essid.length - 1;
6980 essid = extra;
6981 }
6982 if (length == 0) {
6983 IPW_DEBUG_WX("Setting ESSID to ANY\n");
6984 priv->config &= ~CFG_STATIC_ESSID;
c848d0af 6985 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
43f66a6c
JK
6986 IPW_DEBUG_ASSOC("Attempting to associate with new "
6987 "parameters.\n");
6988 ipw_associate(priv);
6989 }
c848d0af 6990 up(&priv->sem);
43f66a6c
JK
6991 return 0;
6992 }
6993
6994 length = min(length, IW_ESSID_MAX_SIZE);
6995
6996 priv->config |= CFG_STATIC_ESSID;
6997
6998 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
6999 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
c848d0af 7000 up(&priv->sem);
43f66a6c
JK
7001 return 0;
7002 }
7003
7004 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
7005 length);
7006
7007 priv->essid_len = length;
7008 memcpy(priv->essid, essid, priv->essid_len);
bf79451e 7009
c848d0af
JK
7010 /* Network configuration changed -- force [re]association */
7011 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
7012 if (!ipw_disassociate(priv))
43f66a6c 7013 ipw_associate(priv);
43f66a6c 7014
c848d0af 7015 up(&priv->sem);
43f66a6c
JK
7016 return 0;
7017}
7018
bf79451e
JG
7019static int ipw_wx_get_essid(struct net_device *dev,
7020 struct iw_request_info *info,
43f66a6c
JK
7021 union iwreq_data *wrqu, char *extra)
7022{
7023 struct ipw_priv *priv = ieee80211_priv(dev);
7024
7025 /* If we are associated, trying to associate, or have a statically
7026 * configured ESSID then return that; otherwise return ANY */
c848d0af 7027 down(&priv->sem);
43f66a6c 7028 if (priv->config & CFG_STATIC_ESSID ||
bf79451e
JG
7029 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7030 IPW_DEBUG_WX("Getting essid: '%s'\n",
43f66a6c 7031 escape_essid(priv->essid, priv->essid_len));
bf79451e 7032 memcpy(extra, priv->essid, priv->essid_len);
43f66a6c 7033 wrqu->essid.length = priv->essid_len;
0edd5b44 7034 wrqu->essid.flags = 1; /* active */
43f66a6c
JK
7035 } else {
7036 IPW_DEBUG_WX("Getting essid: ANY\n");
7037 wrqu->essid.length = 0;
0edd5b44 7038 wrqu->essid.flags = 0; /* active */
43f66a6c 7039 }
c848d0af 7040 up(&priv->sem);
43f66a6c
JK
7041 return 0;
7042}
7043
bf79451e
JG
7044static int ipw_wx_set_nick(struct net_device *dev,
7045 struct iw_request_info *info,
43f66a6c 7046 union iwreq_data *wrqu, char *extra)
bf79451e 7047{
43f66a6c
JK
7048 struct ipw_priv *priv = ieee80211_priv(dev);
7049
7050 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
7051 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7052 return -E2BIG;
c848d0af 7053 down(&priv->sem);
0edd5b44 7054 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
43f66a6c 7055 memset(priv->nick, 0, sizeof(priv->nick));
0edd5b44 7056 memcpy(priv->nick, extra, wrqu->data.length);
43f66a6c 7057 IPW_DEBUG_TRACE("<<\n");
c848d0af 7058 up(&priv->sem);
43f66a6c
JK
7059 return 0;
7060
7061}
7062
bf79451e
JG
7063static int ipw_wx_get_nick(struct net_device *dev,
7064 struct iw_request_info *info,
43f66a6c 7065 union iwreq_data *wrqu, char *extra)
bf79451e 7066{
43f66a6c
JK
7067 struct ipw_priv *priv = ieee80211_priv(dev);
7068 IPW_DEBUG_WX("Getting nick\n");
c848d0af 7069 down(&priv->sem);
43f66a6c
JK
7070 wrqu->data.length = strlen(priv->nick) + 1;
7071 memcpy(extra, priv->nick, wrqu->data.length);
0edd5b44 7072 wrqu->data.flags = 1; /* active */
c848d0af 7073 up(&priv->sem);
43f66a6c
JK
7074 return 0;
7075}
7076
43f66a6c
JK
7077static int ipw_wx_set_rate(struct net_device *dev,
7078 struct iw_request_info *info,
7079 union iwreq_data *wrqu, char *extra)
bf79451e 7080{
ea2b26e0
JK
7081 /* TODO: We should use semaphores or locks for access to priv */
7082 struct ipw_priv *priv = ieee80211_priv(dev);
7083 u32 target_rate = wrqu->bitrate.value;
7084 u32 fixed, mask;
7085
7086 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
7087 /* value = X, fixed = 1 means only rate X */
7088 /* value = X, fixed = 0 means all rates lower equal X */
7089
7090 if (target_rate == -1) {
7091 fixed = 0;
7092 mask = IEEE80211_DEFAULT_RATES_MASK;
7093 /* Now we should reassociate */
7094 goto apply;
7095 }
7096
7097 mask = 0;
7098 fixed = wrqu->bitrate.fixed;
7099
7100 if (target_rate == 1000000 || !fixed)
7101 mask |= IEEE80211_CCK_RATE_1MB_MASK;
7102 if (target_rate == 1000000)
7103 goto apply;
7104
7105 if (target_rate == 2000000 || !fixed)
7106 mask |= IEEE80211_CCK_RATE_2MB_MASK;
7107 if (target_rate == 2000000)
7108 goto apply;
7109
7110 if (target_rate == 5500000 || !fixed)
7111 mask |= IEEE80211_CCK_RATE_5MB_MASK;
7112 if (target_rate == 5500000)
7113 goto apply;
7114
7115 if (target_rate == 6000000 || !fixed)
7116 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
7117 if (target_rate == 6000000)
7118 goto apply;
7119
7120 if (target_rate == 9000000 || !fixed)
7121 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
7122 if (target_rate == 9000000)
7123 goto apply;
7124
7125 if (target_rate == 11000000 || !fixed)
7126 mask |= IEEE80211_CCK_RATE_11MB_MASK;
7127 if (target_rate == 11000000)
7128 goto apply;
7129
7130 if (target_rate == 12000000 || !fixed)
7131 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
7132 if (target_rate == 12000000)
7133 goto apply;
7134
7135 if (target_rate == 18000000 || !fixed)
7136 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
7137 if (target_rate == 18000000)
7138 goto apply;
7139
7140 if (target_rate == 24000000 || !fixed)
7141 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
7142 if (target_rate == 24000000)
7143 goto apply;
7144
7145 if (target_rate == 36000000 || !fixed)
7146 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
7147 if (target_rate == 36000000)
7148 goto apply;
7149
7150 if (target_rate == 48000000 || !fixed)
7151 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
7152 if (target_rate == 48000000)
7153 goto apply;
7154
7155 if (target_rate == 54000000 || !fixed)
7156 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
7157 if (target_rate == 54000000)
7158 goto apply;
7159
7160 IPW_DEBUG_WX("invalid rate specified, returning error\n");
7161 return -EINVAL;
7162
7163 apply:
7164 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
7165 mask, fixed ? "fixed" : "sub-rates");
c848d0af 7166 down(&priv->sem);
ea2b26e0
JK
7167 if (mask == IEEE80211_DEFAULT_RATES_MASK)
7168 priv->config &= ~CFG_FIXED_RATE;
7169 else
7170 priv->config |= CFG_FIXED_RATE;
7171
c848d0af
JK
7172 if (priv->rates_mask == mask) {
7173 IPW_DEBUG_WX("Mask set to current mask.\n");
7174 up(&priv->sem);
7175 return 0;
ea2b26e0
JK
7176 }
7177
c848d0af
JK
7178 priv->rates_mask = mask;
7179
7180 /* Network configuration changed -- force [re]association */
7181 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
7182 if (!ipw_disassociate(priv))
7183 ipw_associate(priv);
7184
7185 up(&priv->sem);
ea2b26e0 7186 return 0;
43f66a6c
JK
7187}
7188
bf79451e
JG
7189static int ipw_wx_get_rate(struct net_device *dev,
7190 struct iw_request_info *info,
43f66a6c 7191 union iwreq_data *wrqu, char *extra)
bf79451e 7192{
0edd5b44 7193 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7194 down(&priv->sem);
43f66a6c 7195 wrqu->bitrate.value = priv->last_rate;
c848d0af 7196 up(&priv->sem);
43f66a6c
JK
7197 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7198 return 0;
7199}
7200
bf79451e
JG
7201static int ipw_wx_set_rts(struct net_device *dev,
7202 struct iw_request_info *info,
43f66a6c 7203 union iwreq_data *wrqu, char *extra)
bf79451e 7204{
43f66a6c 7205 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7206 down(&priv->sem);
43f66a6c
JK
7207 if (wrqu->rts.disabled)
7208 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
7209 else {
7210 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
c848d0af
JK
7211 wrqu->rts.value > MAX_RTS_THRESHOLD) {
7212 up(&priv->sem);
43f66a6c 7213 return -EINVAL;
c848d0af 7214 }
43f66a6c
JK
7215 priv->rts_threshold = wrqu->rts.value;
7216 }
7217
7218 ipw_send_rts_threshold(priv, priv->rts_threshold);
c848d0af 7219 up(&priv->sem);
43f66a6c
JK
7220 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
7221 return 0;
7222}
7223
bf79451e
JG
7224static int ipw_wx_get_rts(struct net_device *dev,
7225 struct iw_request_info *info,
43f66a6c 7226 union iwreq_data *wrqu, char *extra)
bf79451e 7227{
43f66a6c 7228 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7229 down(&priv->sem);
43f66a6c
JK
7230 wrqu->rts.value = priv->rts_threshold;
7231 wrqu->rts.fixed = 0; /* no auto select */
0edd5b44 7232 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
c848d0af 7233 up(&priv->sem);
43f66a6c
JK
7234 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
7235 return 0;
7236}
7237
bf79451e
JG
7238static int ipw_wx_set_txpow(struct net_device *dev,
7239 struct iw_request_info *info,
43f66a6c 7240 union iwreq_data *wrqu, char *extra)
bf79451e 7241{
43f66a6c
JK
7242 struct ipw_priv *priv = ieee80211_priv(dev);
7243 struct ipw_tx_power tx_power;
7244 int i;
c848d0af
JK
7245 down(&priv->sem);
7246 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
7247 up(&priv->sem);
43f66a6c 7248 return -EINPROGRESS;
c848d0af 7249 }
43f66a6c 7250
c848d0af
JK
7251 if (wrqu->power.flags != IW_TXPOW_DBM) {
7252 up(&priv->sem);
43f66a6c 7253 return -EINVAL;
c848d0af 7254 }
43f66a6c 7255
c848d0af
JK
7256 if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) {
7257 up(&priv->sem);
43f66a6c 7258 return -EINVAL;
c848d0af 7259 }
43f66a6c
JK
7260
7261 priv->tx_power = wrqu->power.value;
7262
7263 memset(&tx_power, 0, sizeof(tx_power));
7264
7265 /* configure device for 'G' band */
7266 tx_power.ieee_mode = IPW_G_MODE;
7267 tx_power.num_channels = 11;
7268 for (i = 0; i < 11; i++) {
7269 tx_power.channels_tx_power[i].channel_number = i + 1;
7270 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
7271 }
7272 if (ipw_send_tx_power(priv, &tx_power))
7273 goto error;
7274
7275 /* configure device to also handle 'B' band */
7276 tx_power.ieee_mode = IPW_B_MODE;
7277 if (ipw_send_tx_power(priv, &tx_power))
7278 goto error;
7279
c848d0af 7280 up(&priv->sem);
43f66a6c
JK
7281 return 0;
7282
0edd5b44 7283 error:
c848d0af 7284 up(&priv->sem);
43f66a6c
JK
7285 return -EIO;
7286}
7287
bf79451e
JG
7288static int ipw_wx_get_txpow(struct net_device *dev,
7289 struct iw_request_info *info,
43f66a6c 7290 union iwreq_data *wrqu, char *extra)
bf79451e 7291{
43f66a6c 7292 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7293 down(&priv->sem);
43f66a6c
JK
7294 wrqu->power.value = priv->tx_power;
7295 wrqu->power.fixed = 1;
7296 wrqu->power.flags = IW_TXPOW_DBM;
7297 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
c848d0af 7298 up(&priv->sem);
43f66a6c 7299
bf79451e 7300 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
0edd5b44 7301 wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value);
43f66a6c
JK
7302
7303 return 0;
7304}
7305
bf79451e 7306static int ipw_wx_set_frag(struct net_device *dev,
0edd5b44
JG
7307 struct iw_request_info *info,
7308 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7309{
7310 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7311 down(&priv->sem);
43f66a6c
JK
7312 if (wrqu->frag.disabled)
7313 priv->ieee->fts = DEFAULT_FTS;
7314 else {
7315 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
7316 wrqu->frag.value > MAX_FRAG_THRESHOLD)
7317 return -EINVAL;
bf79451e 7318
43f66a6c
JK
7319 priv->ieee->fts = wrqu->frag.value & ~0x1;
7320 }
7321
7322 ipw_send_frag_threshold(priv, wrqu->frag.value);
c848d0af 7323 up(&priv->sem);
43f66a6c
JK
7324 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
7325 return 0;
7326}
7327
bf79451e 7328static int ipw_wx_get_frag(struct net_device *dev,
0edd5b44
JG
7329 struct iw_request_info *info,
7330 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7331{
7332 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7333 down(&priv->sem);
43f66a6c
JK
7334 wrqu->frag.value = priv->ieee->fts;
7335 wrqu->frag.fixed = 0; /* no auto select */
0edd5b44 7336 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
c848d0af 7337 up(&priv->sem);
43f66a6c
JK
7338 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
7339
7340 return 0;
7341}
7342
bf79451e
JG
7343static int ipw_wx_set_retry(struct net_device *dev,
7344 struct iw_request_info *info,
43f66a6c 7345 union iwreq_data *wrqu, char *extra)
bf79451e 7346{
43f66a6c 7347 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
bf79451e 7348 return -EOPNOTSUPP;
43f66a6c
JK
7349}
7350
bf79451e
JG
7351static int ipw_wx_get_retry(struct net_device *dev,
7352 struct iw_request_info *info,
43f66a6c 7353 union iwreq_data *wrqu, char *extra)
bf79451e 7354{
43f66a6c 7355 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
bf79451e 7356 return -EOPNOTSUPP;
43f66a6c
JK
7357}
7358
bf79451e
JG
7359static int ipw_wx_set_scan(struct net_device *dev,
7360 struct iw_request_info *info,
43f66a6c
JK
7361 union iwreq_data *wrqu, char *extra)
7362{
7363 struct ipw_priv *priv = ieee80211_priv(dev);
7364 IPW_DEBUG_WX("Start scan\n");
c848d0af
JK
7365 down(&priv->sem);
7366 if (ipw_request_scan(priv)) {
7367 up(&priv->sem);
43f66a6c 7368 return -EIO;
c848d0af
JK
7369 }
7370 up(&priv->sem);
43f66a6c
JK
7371 return 0;
7372}
7373
bf79451e
JG
7374static int ipw_wx_get_scan(struct net_device *dev,
7375 struct iw_request_info *info,
43f66a6c 7376 union iwreq_data *wrqu, char *extra)
bf79451e 7377{
43f66a6c
JK
7378 struct ipw_priv *priv = ieee80211_priv(dev);
7379 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7380}
7381
bf79451e 7382static int ipw_wx_set_encode(struct net_device *dev,
0edd5b44
JG
7383 struct iw_request_info *info,
7384 union iwreq_data *wrqu, char *key)
43f66a6c
JK
7385{
7386 struct ipw_priv *priv = ieee80211_priv(dev);
7387 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
7388}
7389
bf79451e 7390static int ipw_wx_get_encode(struct net_device *dev,
0edd5b44
JG
7391 struct iw_request_info *info,
7392 union iwreq_data *wrqu, char *key)
43f66a6c
JK
7393{
7394 struct ipw_priv *priv = ieee80211_priv(dev);
7395 return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
7396}
7397
bf79451e 7398static int ipw_wx_set_power(struct net_device *dev,
0edd5b44
JG
7399 struct iw_request_info *info,
7400 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7401{
7402 struct ipw_priv *priv = ieee80211_priv(dev);
7403 int err;
c848d0af 7404 down(&priv->sem);
43f66a6c
JK
7405 if (wrqu->power.disabled) {
7406 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
7407 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
7408 if (err) {
7409 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 7410 up(&priv->sem);
43f66a6c
JK
7411 return err;
7412 }
43f66a6c 7413 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
c848d0af 7414 up(&priv->sem);
43f66a6c 7415 return 0;
bf79451e 7416 }
43f66a6c
JK
7417
7418 switch (wrqu->power.flags & IW_POWER_MODE) {
0edd5b44
JG
7419 case IW_POWER_ON: /* If not specified */
7420 case IW_POWER_MODE: /* If set all mask */
7421 case IW_POWER_ALL_R: /* If explicitely state all */
43f66a6c 7422 break;
0edd5b44 7423 default: /* Otherwise we don't support it */
43f66a6c
JK
7424 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7425 wrqu->power.flags);
c848d0af 7426 up(&priv->sem);
bf79451e 7427 return -EOPNOTSUPP;
43f66a6c 7428 }
bf79451e 7429
43f66a6c
JK
7430 /* If the user hasn't specified a power management mode yet, default
7431 * to BATTERY */
0edd5b44 7432 if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)
43f66a6c 7433 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
bf79451e 7434 else
43f66a6c
JK
7435 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7436 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7437 if (err) {
7438 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 7439 up(&priv->sem);
43f66a6c
JK
7440 return err;
7441 }
7442
0edd5b44 7443 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
c848d0af 7444 up(&priv->sem);
43f66a6c
JK
7445 return 0;
7446}
7447
bf79451e 7448static int ipw_wx_get_power(struct net_device *dev,
0edd5b44
JG
7449 struct iw_request_info *info,
7450 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7451{
7452 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7453 down(&priv->sem);
a613bffd 7454 if (!(priv->power_mode & IPW_POWER_ENABLED))
43f66a6c 7455 wrqu->power.disabled = 1;
a613bffd 7456 else
43f66a6c 7457 wrqu->power.disabled = 0;
43f66a6c 7458
c848d0af 7459 up(&priv->sem);
43f66a6c 7460 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
bf79451e 7461
43f66a6c
JK
7462 return 0;
7463}
7464
bf79451e 7465static int ipw_wx_set_powermode(struct net_device *dev,
0edd5b44
JG
7466 struct iw_request_info *info,
7467 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7468{
7469 struct ipw_priv *priv = ieee80211_priv(dev);
7470 int mode = *(int *)extra;
7471 int err;
c848d0af 7472 down(&priv->sem);
43f66a6c
JK
7473 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
7474 mode = IPW_POWER_AC;
7475 priv->power_mode = mode;
7476 } else {
7477 priv->power_mode = IPW_POWER_ENABLED | mode;
7478 }
bf79451e 7479
43f66a6c
JK
7480 if (priv->power_mode != mode) {
7481 err = ipw_send_power_mode(priv, mode);
bf79451e 7482
43f66a6c
JK
7483 if (err) {
7484 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 7485 up(&priv->sem);
43f66a6c
JK
7486 return err;
7487 }
7488 }
c848d0af 7489 up(&priv->sem);
43f66a6c
JK
7490 return 0;
7491}
7492
7493#define MAX_WX_STRING 80
bf79451e 7494static int ipw_wx_get_powermode(struct net_device *dev,
0edd5b44
JG
7495 struct iw_request_info *info,
7496 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7497{
7498 struct ipw_priv *priv = ieee80211_priv(dev);
7499 int level = IPW_POWER_LEVEL(priv->power_mode);
7500 char *p = extra;
7501
7502 p += snprintf(p, MAX_WX_STRING, "Power save level: %d ", level);
7503
7504 switch (level) {
7505 case IPW_POWER_AC:
7506 p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
7507 break;
7508 case IPW_POWER_BATTERY:
7509 p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
7510 break;
7511 default:
7512 p += snprintf(p, MAX_WX_STRING - (p - extra),
bf79451e 7513 "(Timeout %dms, Period %dms)",
43f66a6c
JK
7514 timeout_duration[level - 1] / 1000,
7515 period_duration[level - 1] / 1000);
7516 }
7517
7518 if (!(priv->power_mode & IPW_POWER_ENABLED))
0edd5b44 7519 p += snprintf(p, MAX_WX_STRING - (p - extra), " OFF");
43f66a6c
JK
7520
7521 wrqu->data.length = p - extra + 1;
7522
7523 return 0;
7524}
7525
7526static int ipw_wx_set_wireless_mode(struct net_device *dev,
0edd5b44
JG
7527 struct iw_request_info *info,
7528 union iwreq_data *wrqu, char *extra)
43f66a6c 7529{
0edd5b44 7530 struct ipw_priv *priv = ieee80211_priv(dev);
43f66a6c
JK
7531 int mode = *(int *)extra;
7532 u8 band = 0, modulation = 0;
7533
7534 if (mode == 0 || mode & ~IEEE_MODE_MASK) {
0edd5b44 7535 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
43f66a6c
JK
7536 return -EINVAL;
7537 }
c848d0af 7538 down(&priv->sem);
43f66a6c 7539 if (priv->adapter == IPW_2915ABG) {
a33a1982 7540 priv->ieee->abg_true = 1;
43f66a6c
JK
7541 if (mode & IEEE_A) {
7542 band |= IEEE80211_52GHZ_BAND;
7543 modulation |= IEEE80211_OFDM_MODULATION;
7544 } else
a33a1982 7545 priv->ieee->abg_true = 0;
43f66a6c
JK
7546 } else {
7547 if (mode & IEEE_A) {
7548 IPW_WARNING("Attempt to set 2200BG into "
7549 "802.11a mode\n");
c848d0af 7550 up(&priv->sem);
43f66a6c
JK
7551 return -EINVAL;
7552 }
7553
a33a1982 7554 priv->ieee->abg_true = 0;
43f66a6c
JK
7555 }
7556
7557 if (mode & IEEE_B) {
7558 band |= IEEE80211_24GHZ_BAND;
7559 modulation |= IEEE80211_CCK_MODULATION;
7560 } else
a33a1982 7561 priv->ieee->abg_true = 0;
bf79451e 7562
43f66a6c
JK
7563 if (mode & IEEE_G) {
7564 band |= IEEE80211_24GHZ_BAND;
7565 modulation |= IEEE80211_OFDM_MODULATION;
7566 } else
a33a1982 7567 priv->ieee->abg_true = 0;
43f66a6c
JK
7568
7569 priv->ieee->mode = mode;
7570 priv->ieee->freq_band = band;
7571 priv->ieee->modulation = modulation;
0edd5b44 7572 init_supported_rates(priv, &priv->rates);
43f66a6c 7573
c848d0af
JK
7574 /* Network configuration changed -- force [re]association */
7575 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
7576 if (!ipw_disassociate(priv)) {
43f66a6c 7577 ipw_send_supported_rates(priv, &priv->rates);
c848d0af
JK
7578 ipw_associate(priv);
7579 }
43f66a6c 7580
a613bffd
JK
7581 /* Update the band LEDs */
7582 ipw_led_band_on(priv);
7583
bf79451e 7584 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
43f66a6c 7585 mode & IEEE_A ? 'a' : '.',
0edd5b44 7586 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
c848d0af 7587 up(&priv->sem);
43f66a6c
JK
7588 return 0;
7589}
7590
7591static int ipw_wx_get_wireless_mode(struct net_device *dev,
0edd5b44
JG
7592 struct iw_request_info *info,
7593 union iwreq_data *wrqu, char *extra)
43f66a6c 7594{
0edd5b44 7595 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7596 down(&priv->sem);
ea2b26e0
JK
7597 switch (priv->ieee->mode) {
7598 case IEEE_A:
43f66a6c
JK
7599 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
7600 break;
ea2b26e0
JK
7601 case IEEE_B:
7602 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
7603 break;
7604 case IEEE_A | IEEE_B:
7605 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
7606 break;
7607 case IEEE_G:
7608 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
7609 break;
7610 case IEEE_A | IEEE_G:
7611 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
7612 break;
7613 case IEEE_B | IEEE_G:
7614 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
7615 break;
7616 case IEEE_A | IEEE_B | IEEE_G:
7617 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
7618 break;
7619 default:
7620 strncpy(extra, "unknown", MAX_WX_STRING);
43f66a6c 7621 break;
bf79451e
JG
7622 }
7623
43f66a6c
JK
7624 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
7625
0edd5b44 7626 wrqu->data.length = strlen(extra) + 1;
c848d0af 7627 up(&priv->sem);
43f66a6c 7628
0edd5b44 7629 return 0;
43f66a6c
JK
7630}
7631
ea2b26e0
JK
7632static int ipw_wx_set_preamble(struct net_device *dev,
7633 struct iw_request_info *info,
7634 union iwreq_data *wrqu, char *extra)
7635{
7636 struct ipw_priv *priv = ieee80211_priv(dev);
7637 int mode = *(int *)extra;
c848d0af 7638 down(&priv->sem);
ea2b26e0
JK
7639 /* Switching from SHORT -> LONG requires a disassociation */
7640 if (mode == 1) {
7641 if (!(priv->config & CFG_PREAMBLE_LONG)) {
7642 priv->config |= CFG_PREAMBLE_LONG;
c848d0af
JK
7643
7644 /* Network configuration changed -- force [re]association */
7645 IPW_DEBUG_ASSOC
7646 ("[re]association triggered due to preamble change.\n");
7647 if (!ipw_disassociate(priv))
7648 ipw_associate(priv);
ea2b26e0
JK
7649 }
7650 goto done;
7651 }
7652
7653 if (mode == 0) {
7654 priv->config &= ~CFG_PREAMBLE_LONG;
7655 goto done;
7656 }
c848d0af 7657 up(&priv->sem);
ea2b26e0
JK
7658 return -EINVAL;
7659
7660 done:
c848d0af 7661 up(&priv->sem);
ea2b26e0
JK
7662 return 0;
7663}
7664
7665static int ipw_wx_get_preamble(struct net_device *dev,
7666 struct iw_request_info *info,
7667 union iwreq_data *wrqu, char *extra)
7668{
7669 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7670 down(&priv->sem);
ea2b26e0
JK
7671 if (priv->config & CFG_PREAMBLE_LONG)
7672 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
7673 else
7674 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
c848d0af 7675 up(&priv->sem);
ea2b26e0
JK
7676 return 0;
7677}
7678
7679#ifdef CONFIG_IPW_MONITOR
7680static int ipw_wx_set_monitor(struct net_device *dev,
bf79451e 7681 struct iw_request_info *info,
43f66a6c 7682 union iwreq_data *wrqu, char *extra)
bf79451e 7683{
43f66a6c
JK
7684 struct ipw_priv *priv = ieee80211_priv(dev);
7685 int *parms = (int *)extra;
7686 int enable = (parms[0] > 0);
c848d0af 7687 down(&priv->sem);
ea2b26e0 7688 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
43f66a6c
JK
7689 if (enable) {
7690 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
7691 priv->net_dev->type = ARPHRD_IEEE80211;
a613bffd 7692 queue_work(priv->workqueue, &priv->adapter_restart);
43f66a6c 7693 }
bf79451e 7694
43f66a6c
JK
7695 ipw_set_channel(priv, parms[1]);
7696 } else {
c848d0af
JK
7697 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
7698 up(&priv->sem);
43f66a6c 7699 return 0;
c848d0af 7700 }
43f66a6c 7701 priv->net_dev->type = ARPHRD_ETHER;
a613bffd 7702 queue_work(priv->workqueue, &priv->adapter_restart);
43f66a6c 7703 }
c848d0af 7704 up(&priv->sem);
43f66a6c
JK
7705 return 0;
7706}
7707
bf79451e
JG
7708static int ipw_wx_reset(struct net_device *dev,
7709 struct iw_request_info *info,
43f66a6c 7710 union iwreq_data *wrqu, char *extra)
bf79451e 7711{
43f66a6c
JK
7712 struct ipw_priv *priv = ieee80211_priv(dev);
7713 IPW_DEBUG_WX("RESET\n");
a613bffd 7714 queue_work(priv->workqueue, &priv->adapter_restart);
43f66a6c
JK
7715 return 0;
7716}
ea2b26e0 7717#endif // CONFIG_IPW_MONITOR
43f66a6c
JK
7718
7719/* Rebase the WE IOCTLs to zero for the handler array */
7720#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
0edd5b44 7721static iw_handler ipw_wx_handlers[] = {
ea2b26e0
JK
7722 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
7723 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
7724 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
7725 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
7726 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
7727 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
7728 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
7729 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
7730 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
7731 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
7732 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
7733 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
7734 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
7735 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
7736 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
7737 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
7738 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
7739 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
7740 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
7741 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
7742 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
7743 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
7744 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
7745 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
7746 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
7747 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
7748 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
7749 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
a613bffd
JK
7750 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
7751 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
7752 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
7753 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
43f66a6c
JK
7754};
7755
7756#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV
7757#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1
7758#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2
7759#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3
ea2b26e0
JK
7760#define IPW_PRIV_SET_PREAMBLE SIOCIWFIRSTPRIV+4
7761#define IPW_PRIV_GET_PREAMBLE SIOCIWFIRSTPRIV+5
7762#define IPW_PRIV_SET_MONITOR SIOCIWFIRSTPRIV+6
7763#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+7
43f66a6c 7764
bf79451e 7765static struct iw_priv_args ipw_priv_args[] = {
43f66a6c 7766 {
0edd5b44
JG
7767 .cmd = IPW_PRIV_SET_POWER,
7768 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
7769 .name = "set_power"},
43f66a6c 7770 {
0edd5b44
JG
7771 .cmd = IPW_PRIV_GET_POWER,
7772 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
7773 .name = "get_power"},
43f66a6c 7774 {
0edd5b44
JG
7775 .cmd = IPW_PRIV_SET_MODE,
7776 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
7777 .name = "set_mode"},
43f66a6c 7778 {
0edd5b44
JG
7779 .cmd = IPW_PRIV_GET_MODE,
7780 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
7781 .name = "get_mode"},
43f66a6c 7782 {
ea2b26e0
JK
7783 .cmd = IPW_PRIV_SET_PREAMBLE,
7784 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
7785 .name = "set_preamble"},
7786 {
7787 .cmd = IPW_PRIV_GET_PREAMBLE,
7788 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
7789 .name = "get_preamble"},
7790#ifdef CONFIG_IPW_MONITOR
7791 {
7792 IPW_PRIV_SET_MONITOR,
0edd5b44 7793 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
43f66a6c 7794 {
0edd5b44
JG
7795 IPW_PRIV_RESET,
7796 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
ea2b26e0 7797#endif /* CONFIG_IPW_MONITOR */
43f66a6c
JK
7798};
7799
7800static iw_handler ipw_priv_handler[] = {
7801 ipw_wx_set_powermode,
7802 ipw_wx_get_powermode,
7803 ipw_wx_set_wireless_mode,
7804 ipw_wx_get_wireless_mode,
ea2b26e0
JK
7805 ipw_wx_set_preamble,
7806 ipw_wx_get_preamble,
7807#ifdef CONFIG_IPW_MONITOR
7808 ipw_wx_set_monitor,
bf79451e 7809 ipw_wx_reset,
43f66a6c
JK
7810#endif
7811};
7812
0edd5b44 7813static struct iw_handler_def ipw_wx_handler_def = {
ea2b26e0
JK
7814 .standard = ipw_wx_handlers,
7815 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
7816 .num_private = ARRAY_SIZE(ipw_priv_handler),
7817 .num_private_args = ARRAY_SIZE(ipw_priv_args),
7818 .private = ipw_priv_handler,
7819 .private_args = ipw_priv_args,
43f66a6c
JK
7820};
7821
a613bffd
JK
7822static struct iw_public_data ipw_wx_data;
7823
43f66a6c
JK
7824/*
7825 * Get wireless statistics.
7826 * Called by /proc/net/wireless
7827 * Also called by SIOCGIWSTATS
7828 */
0edd5b44 7829static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
43f66a6c
JK
7830{
7831 struct ipw_priv *priv = ieee80211_priv(dev);
7832 struct iw_statistics *wstats;
bf79451e 7833
43f66a6c
JK
7834 wstats = &priv->wstats;
7835
ea2b26e0 7836 /* if hw is disabled, then ipw_get_ordinal() can't be called.
bf79451e 7837 * ipw2100_wx_wireless_stats seems to be called before fw is
43f66a6c
JK
7838 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
7839 * and associated; if not associcated, the values are all meaningless
7840 * anyway, so set them all to NULL and INVALID */
7841 if (!(priv->status & STATUS_ASSOCIATED)) {
7842 wstats->miss.beacon = 0;
7843 wstats->discard.retries = 0;
7844 wstats->qual.qual = 0;
7845 wstats->qual.level = 0;
7846 wstats->qual.noise = 0;
7847 wstats->qual.updated = 7;
7848 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
0edd5b44 7849 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
43f66a6c 7850 return wstats;
bf79451e 7851 }
43f66a6c
JK
7852
7853 wstats->qual.qual = priv->quality;
7854 wstats->qual.level = average_value(&priv->average_rssi);
7855 wstats->qual.noise = average_value(&priv->average_noise);
7856 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
0edd5b44 7857 IW_QUAL_NOISE_UPDATED;
43f66a6c
JK
7858
7859 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
7860 wstats->discard.retries = priv->last_tx_failures;
7861 wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable;
bf79451e 7862
43f66a6c
JK
7863/* if (ipw_get_ordinal(priv, IPW_ORD_STAT_TX_RETRY, &tx_retry, &len))
7864 goto fail_get_ordinal;
7865 wstats->discard.retries += tx_retry; */
bf79451e 7866
43f66a6c
JK
7867 return wstats;
7868}
7869
43f66a6c
JK
7870/* net device stuff */
7871
7872static inline void init_sys_config(struct ipw_sys_config *sys_config)
7873{
0edd5b44
JG
7874 memset(sys_config, 0, sizeof(struct ipw_sys_config));
7875 sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */
43f66a6c
JK
7876 sys_config->answer_broadcast_ssid_probe = 0;
7877 sys_config->accept_all_data_frames = 0;
7878 sys_config->accept_non_directed_frames = 1;
7879 sys_config->exclude_unicast_unencrypted = 0;
7880 sys_config->disable_unicast_decryption = 1;
7881 sys_config->exclude_multicast_unencrypted = 0;
7882 sys_config->disable_multicast_decryption = 1;
7883 sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH;
0edd5b44 7884 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */
43f66a6c 7885 sys_config->dot11g_auto_detection = 0;
bf79451e 7886 sys_config->enable_cts_to_self = 0;
43f66a6c 7887 sys_config->bt_coexist_collision_thr = 0;
c848d0af 7888 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
43f66a6c
JK
7889}
7890
7891static int ipw_net_open(struct net_device *dev)
7892{
7893 struct ipw_priv *priv = ieee80211_priv(dev);
7894 IPW_DEBUG_INFO("dev->open\n");
7895 /* we should be verifying the device is ready to be opened */
c848d0af 7896 down(&priv->sem);
bf79451e
JG
7897 if (!(priv->status & STATUS_RF_KILL_MASK) &&
7898 (priv->status & STATUS_ASSOCIATED))
43f66a6c 7899 netif_start_queue(dev);
c848d0af 7900 up(&priv->sem);
43f66a6c
JK
7901 return 0;
7902}
7903
7904static int ipw_net_stop(struct net_device *dev)
7905{
7906 IPW_DEBUG_INFO("dev->close\n");
7907 netif_stop_queue(dev);
7908 return 0;
7909}
7910
7911/*
7912todo:
7913
7914modify to send one tfd per fragment instead of using chunking. otherwise
7915we need to heavily modify the ieee80211_skb_to_txb.
7916*/
7917
7918static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
7919{
0dacca1f 7920 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
0edd5b44 7921 txb->fragments[0]->data;
43f66a6c
JK
7922 int i = 0;
7923 struct tfd_frame *tfd;
7924 struct clx2_tx_queue *txq = &priv->txq[0];
7925 struct clx2_queue *q = &txq->q;
7926 u8 id, hdr_len, unicast;
7927 u16 remaining_bytes;
c848d0af 7928 int fc;
43f66a6c
JK
7929
7930 switch (priv->ieee->iw_mode) {
7931 case IW_MODE_ADHOC:
7932 hdr_len = IEEE80211_3ADDR_LEN;
7933 unicast = !is_broadcast_ether_addr(hdr->addr1) &&
0edd5b44 7934 !is_multicast_ether_addr(hdr->addr1);
43f66a6c
JK
7935 id = ipw_find_station(priv, hdr->addr1);
7936 if (id == IPW_INVALID_STATION) {
7937 id = ipw_add_station(priv, hdr->addr1);
7938 if (id == IPW_INVALID_STATION) {
7939 IPW_WARNING("Attempt to send data to "
bf79451e 7940 "invalid cell: " MAC_FMT "\n",
43f66a6c
JK
7941 MAC_ARG(hdr->addr1));
7942 goto drop;
7943 }
7944 }
7945 break;
7946
7947 case IW_MODE_INFRA:
7948 default:
7949 unicast = !is_broadcast_ether_addr(hdr->addr3) &&
0edd5b44 7950 !is_multicast_ether_addr(hdr->addr3);
43f66a6c
JK
7951 hdr_len = IEEE80211_3ADDR_LEN;
7952 id = 0;
7953 break;
7954 }
7955
7956 tfd = &txq->bd[q->first_empty];
7957 txq->txb[q->first_empty] = txb;
7958 memset(tfd, 0, sizeof(*tfd));
7959 tfd->u.data.station_number = id;
7960
7961 tfd->control_flags.message_type = TX_FRAME_TYPE;
7962 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
7963
7964 tfd->u.data.cmd_id = DINO_CMD_TX;
a613bffd 7965 tfd->u.data.len = cpu_to_le16(txb->payload_size);
43f66a6c
JK
7966 remaining_bytes = txb->payload_size;
7967 if (unlikely(!unicast))
7968 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
7969 else
7970 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD;
bf79451e 7971
43f66a6c
JK
7972 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
7973 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK;
7974 else
7975 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM;
7976
ea2b26e0
JK
7977 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
7978 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
43f66a6c 7979
c848d0af
JK
7980 fc = le16_to_cpu(hdr->frame_ctl);
7981 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
7982
43f66a6c
JK
7983 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
7984
7985 /* payload */
a613bffd
JK
7986 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
7987 txb->nr_frags));
7988 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
7989 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
7990 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
7991 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
7992 i, le32_to_cpu(tfd->u.data.num_chunks),
7993 txb->fragments[i]->len - hdr_len);
bf79451e 7994 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
43f66a6c
JK
7995 i, tfd->u.data.num_chunks,
7996 txb->fragments[i]->len - hdr_len);
bf79451e 7997 printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len,
43f66a6c
JK
7998 txb->fragments[i]->len - hdr_len);
7999
0edd5b44 8000 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
8001 cpu_to_le32(pci_map_single
8002 (priv->pci_dev,
8003 txb->fragments[i]->data + hdr_len,
8004 txb->fragments[i]->len - hdr_len,
8005 PCI_DMA_TODEVICE));
8006 tfd->u.data.chunk_len[i] =
8007 cpu_to_le16(txb->fragments[i]->len - hdr_len);
43f66a6c
JK
8008 }
8009
8010 if (i != txb->nr_frags) {
8011 struct sk_buff *skb;
8012 u16 remaining_bytes = 0;
8013 int j;
8014
8015 for (j = i; j < txb->nr_frags; j++)
8016 remaining_bytes += txb->fragments[j]->len - hdr_len;
8017
8018 printk(KERN_INFO "Trying to reallocate for %d bytes\n",
8019 remaining_bytes);
8020 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
8021 if (skb != NULL) {
a613bffd 8022 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
43f66a6c
JK
8023 for (j = i; j < txb->nr_frags; j++) {
8024 int size = txb->fragments[j]->len - hdr_len;
8025 printk(KERN_INFO "Adding frag %d %d...\n",
0edd5b44 8026 j, size);
43f66a6c 8027 memcpy(skb_put(skb, size),
0edd5b44 8028 txb->fragments[j]->data + hdr_len, size);
43f66a6c
JK
8029 }
8030 dev_kfree_skb_any(txb->fragments[i]);
8031 txb->fragments[i] = skb;
0edd5b44 8032 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
8033 cpu_to_le32(pci_map_single
8034 (priv->pci_dev, skb->data,
8035 tfd->u.data.chunk_len[i],
8036 PCI_DMA_TODEVICE));
8037
8038 tfd->u.data.num_chunks =
8039 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
8040 1);
bf79451e 8041 }
43f66a6c
JK
8042 }
8043
8044 /* kick DMA */
8045 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
8046 ipw_write32(priv, q->reg_w, q->first_empty);
8047
bf79451e 8048 if (ipw_queue_space(q) < q->high_mark)
43f66a6c
JK
8049 netif_stop_queue(priv->net_dev);
8050
8051 return;
8052
0edd5b44 8053 drop:
43f66a6c
JK
8054 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
8055 ieee80211_txb_free(txb);
8056}
8057
8058static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
c8d42d1a 8059 struct net_device *dev, int pri)
43f66a6c
JK
8060{
8061 struct ipw_priv *priv = ieee80211_priv(dev);
8062 unsigned long flags;
8063
8064 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
43f66a6c
JK
8065 spin_lock_irqsave(&priv->lock, flags);
8066
8067 if (!(priv->status & STATUS_ASSOCIATED)) {
8068 IPW_DEBUG_INFO("Tx attempt while not associated.\n");
8069 priv->ieee->stats.tx_carrier_errors++;
8070 netif_stop_queue(dev);
8071 goto fail_unlock;
8072 }
8073
8074 ipw_tx_skb(priv, txb);
c848d0af 8075 spin_unlock_irqrestore(&priv->lock, flags);
a613bffd 8076 ipw_led_activity_on(priv);
43f66a6c 8077
c848d0af 8078// up(&priv->sem);
43f66a6c
JK
8079 return 0;
8080
0edd5b44 8081 fail_unlock:
43f66a6c 8082 spin_unlock_irqrestore(&priv->lock, flags);
c848d0af 8083// up(&priv->sem);
43f66a6c
JK
8084 return 1;
8085}
8086
8087static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
8088{
8089 struct ipw_priv *priv = ieee80211_priv(dev);
bf79451e 8090
43f66a6c
JK
8091 priv->ieee->stats.tx_packets = priv->tx_packets;
8092 priv->ieee->stats.rx_packets = priv->rx_packets;
8093 return &priv->ieee->stats;
8094}
8095
8096static void ipw_net_set_multicast_list(struct net_device *dev)
8097{
8098
8099}
8100
8101static int ipw_net_set_mac_address(struct net_device *dev, void *p)
8102{
8103 struct ipw_priv *priv = ieee80211_priv(dev);
8104 struct sockaddr *addr = p;
8105 if (!is_valid_ether_addr(addr->sa_data))
8106 return -EADDRNOTAVAIL;
c848d0af 8107 down(&priv->sem);
43f66a6c
JK
8108 priv->config |= CFG_CUSTOM_MAC;
8109 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
8110 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
8111 priv->net_dev->name, MAC_ARG(priv->mac_addr));
a613bffd 8112 queue_work(priv->workqueue, &priv->adapter_restart);
c848d0af 8113 up(&priv->sem);
43f66a6c
JK
8114 return 0;
8115}
8116
bf79451e 8117static void ipw_ethtool_get_drvinfo(struct net_device *dev,
43f66a6c
JK
8118 struct ethtool_drvinfo *info)
8119{
8120 struct ipw_priv *p = ieee80211_priv(dev);
8121 char vers[64];
8122 char date[32];
8123 u32 len;
8124
8125 strcpy(info->driver, DRV_NAME);
8126 strcpy(info->version, DRV_VERSION);
8127
8128 len = sizeof(vers);
8129 ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
8130 len = sizeof(date);
8131 ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len);
8132
0edd5b44 8133 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
43f66a6c
JK
8134 vers, date);
8135 strcpy(info->bus_info, pci_name(p->pci_dev));
8136 info->eedump_len = CX2_EEPROM_IMAGE_SIZE;
8137}
8138
8139static u32 ipw_ethtool_get_link(struct net_device *dev)
8140{
8141 struct ipw_priv *priv = ieee80211_priv(dev);
8142 return (priv->status & STATUS_ASSOCIATED) != 0;
8143}
8144
8145static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
8146{
8147 return CX2_EEPROM_IMAGE_SIZE;
8148}
8149
8150static int ipw_ethtool_get_eeprom(struct net_device *dev,
0edd5b44 8151 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c
JK
8152{
8153 struct ipw_priv *p = ieee80211_priv(dev);
8154
8155 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
8156 return -EINVAL;
c848d0af 8157 down(&p->sem);
0edd5b44 8158 memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len);
c848d0af 8159 up(&p->sem);
43f66a6c
JK
8160 return 0;
8161}
8162
8163static int ipw_ethtool_set_eeprom(struct net_device *dev,
0edd5b44 8164 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c
JK
8165{
8166 struct ipw_priv *p = ieee80211_priv(dev);
8167 int i;
8168
8169 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
8170 return -EINVAL;
c848d0af 8171 down(&p->sem);
0edd5b44 8172 memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len);
bf79451e 8173 for (i = IPW_EEPROM_DATA;
0edd5b44 8174 i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++)
43f66a6c 8175 ipw_write8(p, i, p->eeprom[i]);
c848d0af 8176 up(&p->sem);
43f66a6c
JK
8177 return 0;
8178}
8179
8180static struct ethtool_ops ipw_ethtool_ops = {
ea2b26e0
JK
8181 .get_link = ipw_ethtool_get_link,
8182 .get_drvinfo = ipw_ethtool_get_drvinfo,
8183 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
8184 .get_eeprom = ipw_ethtool_get_eeprom,
8185 .set_eeprom = ipw_ethtool_set_eeprom,
43f66a6c
JK
8186};
8187
8188static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
8189{
8190 struct ipw_priv *priv = data;
8191 u32 inta, inta_mask;
bf79451e 8192
43f66a6c
JK
8193 if (!priv)
8194 return IRQ_NONE;
8195
8196 spin_lock(&priv->lock);
8197
8198 if (!(priv->status & STATUS_INT_ENABLED)) {
8199 /* Shared IRQ */
c848d0af
JK
8200// ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
8201// return IRQ_HANDLED;
43f66a6c
JK
8202 goto none;
8203 }
8204
8205 inta = ipw_read32(priv, CX2_INTA_RW);
8206 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R);
bf79451e 8207
43f66a6c
JK
8208 if (inta == 0xFFFFFFFF) {
8209 /* Hardware disappeared */
8210 IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n");
8211 goto none;
8212 }
8213
8214 if (!(inta & (CX2_INTA_MASK_ALL & inta_mask))) {
8215 /* Shared interrupt */
8216 goto none;
8217 }
8218
8219 /* tell the device to stop sending interrupts */
8220 ipw_disable_interrupts(priv);
bf79451e 8221
43f66a6c
JK
8222 /* ack current interrupts */
8223 inta &= (CX2_INTA_MASK_ALL & inta_mask);
8224 ipw_write32(priv, CX2_INTA_RW, inta);
bf79451e 8225
43f66a6c
JK
8226 /* Cache INTA value for our tasklet */
8227 priv->isr_inta = inta;
8228
8229 tasklet_schedule(&priv->irq_tasklet);
8230
0edd5b44 8231 spin_unlock(&priv->lock);
43f66a6c
JK
8232
8233 return IRQ_HANDLED;
0edd5b44 8234 none:
43f66a6c
JK
8235 spin_unlock(&priv->lock);
8236 return IRQ_NONE;
8237}
8238
8239static void ipw_rf_kill(void *adapter)
8240{
8241 struct ipw_priv *priv = adapter;
8242 unsigned long flags;
bf79451e 8243
43f66a6c
JK
8244 spin_lock_irqsave(&priv->lock, flags);
8245
8246 if (rf_kill_active(priv)) {
8247 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
8248 if (priv->workqueue)
8249 queue_delayed_work(priv->workqueue,
8250 &priv->rf_kill, 2 * HZ);
8251 goto exit_unlock;
8252 }
8253
8254 /* RF Kill is now disabled, so bring the device back up */
8255
8256 if (!(priv->status & STATUS_RF_KILL_MASK)) {
8257 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
8258 "device\n");
8259
8260 /* we can not do an adapter restart while inside an irq lock */
8261 queue_work(priv->workqueue, &priv->adapter_restart);
bf79451e 8262 } else
43f66a6c
JK
8263 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
8264 "enabled\n");
8265
0edd5b44 8266 exit_unlock:
43f66a6c
JK
8267 spin_unlock_irqrestore(&priv->lock, flags);
8268}
8269
c848d0af
JK
8270static void ipw_bg_rf_kill(void *data)
8271{
8272 struct ipw_priv *priv = data;
8273 down(&priv->sem);
8274 ipw_rf_kill(data);
8275 up(&priv->sem);
8276}
8277
a613bffd
JK
8278void ipw_link_up(struct ipw_priv *priv)
8279{
8280 netif_carrier_on(priv->net_dev);
8281 if (netif_queue_stopped(priv->net_dev)) {
8282 IPW_DEBUG_NOTIF("waking queue\n");
8283 netif_wake_queue(priv->net_dev);
8284 } else {
8285 IPW_DEBUG_NOTIF("starting queue\n");
8286 netif_start_queue(priv->net_dev);
8287 }
8288
c848d0af 8289 cancel_delayed_work(&priv->request_scan);
a613bffd
JK
8290 ipw_reset_stats(priv);
8291 /* Ensure the rate is updated immediately */
8292 priv->last_rate = ipw_get_current_rate(priv);
8293 ipw_gather_stats(priv);
8294 ipw_led_link_up(priv);
8295 notify_wx_assoc_event(priv);
8296
8297 if (priv->config & CFG_BACKGROUND_SCAN)
8298 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
8299}
8300
c848d0af
JK
8301static void ipw_bg_link_up(void *data)
8302{
8303 struct ipw_priv *priv = data;
8304 down(&priv->sem);
8305 ipw_link_up(data);
8306 up(&priv->sem);
8307}
8308
a613bffd
JK
8309void ipw_link_down(struct ipw_priv *priv)
8310{
8311 ipw_led_link_down(priv);
8312 netif_carrier_off(priv->net_dev);
8313 netif_stop_queue(priv->net_dev);
8314 notify_wx_assoc_event(priv);
8315
8316 /* Cancel any queued work ... */
8317 cancel_delayed_work(&priv->request_scan);
8318 cancel_delayed_work(&priv->adhoc_check);
8319 cancel_delayed_work(&priv->gather_stats);
8320
8321 ipw_reset_stats(priv);
8322
8323 /* Queue up another scan... */
8324 queue_work(priv->workqueue, &priv->request_scan);
8325}
8326
c848d0af
JK
8327static void ipw_bg_link_down(void *data)
8328{
8329 struct ipw_priv *priv = data;
8330 down(&priv->sem);
8331 ipw_link_down(data);
8332 up(&priv->sem);
8333}
8334
43f66a6c
JK
8335static int ipw_setup_deferred_work(struct ipw_priv *priv)
8336{
8337 int ret = 0;
8338
43f66a6c 8339 priv->workqueue = create_workqueue(DRV_NAME);
43f66a6c
JK
8340 init_waitqueue_head(&priv->wait_command_queue);
8341
c848d0af
JK
8342 INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
8343 INIT_WORK(&priv->associate, ipw_bg_associate, priv);
8344 INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
8345 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
8346 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
8347 INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
8348 INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
8349 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
bf79451e 8350 INIT_WORK(&priv->request_scan,
c848d0af 8351 (void (*)(void *))ipw_bg_request_scan, priv);
bf79451e 8352 INIT_WORK(&priv->gather_stats,
c848d0af
JK
8353 (void (*)(void *))ipw_bg_gather_stats, priv);
8354 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
8355 INIT_WORK(&priv->roam, ipw_bg_roam, priv);
8356 INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
8357 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
8358 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
8359 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
8360 priv);
8361 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
a613bffd 8362 priv);
c848d0af 8363 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
a613bffd 8364 priv);
c848d0af
JK
8365 INIT_WORK(&priv->merge_networks,
8366 (void (*)(void *))ipw_merge_adhoc_network, priv);
43f66a6c
JK
8367
8368 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
8369 ipw_irq_tasklet, (unsigned long)priv);
8370
8371 return ret;
8372}
8373
43f66a6c
JK
8374static void shim__set_security(struct net_device *dev,
8375 struct ieee80211_security *sec)
8376{
8377 struct ipw_priv *priv = ieee80211_priv(dev);
8378 int i;
c848d0af 8379 down(&priv->sem);
bf79451e 8380 for (i = 0; i < 4; i++) {
43f66a6c
JK
8381 if (sec->flags & (1 << i)) {
8382 priv->sec.key_sizes[i] = sec->key_sizes[i];
8383 if (sec->key_sizes[i] == 0)
8384 priv->sec.flags &= ~(1 << i);
8385 else
bf79451e 8386 memcpy(priv->sec.keys[i], sec->keys[i],
43f66a6c
JK
8387 sec->key_sizes[i]);
8388 priv->sec.flags |= (1 << i);
8389 priv->status |= STATUS_SECURITY_UPDATED;
bf79451e 8390 }
43f66a6c
JK
8391 }
8392
8393 if ((sec->flags & SEC_ACTIVE_KEY) &&
8394 priv->sec.active_key != sec->active_key) {
8395 if (sec->active_key <= 3) {
8396 priv->sec.active_key = sec->active_key;
8397 priv->sec.flags |= SEC_ACTIVE_KEY;
bf79451e 8398 } else
43f66a6c
JK
8399 priv->sec.flags &= ~SEC_ACTIVE_KEY;
8400 priv->status |= STATUS_SECURITY_UPDATED;
8401 }
8402
8403 if ((sec->flags & SEC_AUTH_MODE) &&
8404 (priv->sec.auth_mode != sec->auth_mode)) {
8405 priv->sec.auth_mode = sec->auth_mode;
8406 priv->sec.flags |= SEC_AUTH_MODE;
8407 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
8408 priv->capability |= CAP_SHARED_KEY;
8409 else
8410 priv->capability &= ~CAP_SHARED_KEY;
8411 priv->status |= STATUS_SECURITY_UPDATED;
8412 }
bf79451e 8413
0edd5b44 8414 if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) {
43f66a6c
JK
8415 priv->sec.flags |= SEC_ENABLED;
8416 priv->sec.enabled = sec->enabled;
8417 priv->status |= STATUS_SECURITY_UPDATED;
bf79451e 8418 if (sec->enabled)
43f66a6c
JK
8419 priv->capability |= CAP_PRIVACY_ON;
8420 else
8421 priv->capability &= ~CAP_PRIVACY_ON;
8422 }
bf79451e 8423
0edd5b44 8424 if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) {
43f66a6c
JK
8425 priv->sec.level = sec->level;
8426 priv->sec.flags |= SEC_LEVEL;
8427 priv->status |= STATUS_SECURITY_UPDATED;
8428 }
8429
bf79451e
JG
8430 /* To match current functionality of ipw2100 (which works well w/
8431 * various supplicants, we don't force a disassociate if the
43f66a6c
JK
8432 * privacy capability changes ... */
8433#if 0
8434 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
bf79451e 8435 (((priv->assoc_request.capability &
43f66a6c 8436 WLAN_CAPABILITY_PRIVACY) && !sec->enabled) ||
bf79451e 8437 (!(priv->assoc_request.capability &
0edd5b44 8438 WLAN_CAPABILITY_PRIVACY) && sec->enabled))) {
43f66a6c
JK
8439 IPW_DEBUG_ASSOC("Disassociating due to capability "
8440 "change.\n");
8441 ipw_disassociate(priv);
8442 }
8443#endif
c848d0af 8444 up(&priv->sem);
43f66a6c
JK
8445}
8446
bf79451e 8447static int init_supported_rates(struct ipw_priv *priv,
43f66a6c
JK
8448 struct ipw_supported_rates *rates)
8449{
8450 /* TODO: Mask out rates based on priv->rates_mask */
8451
8452 memset(rates, 0, sizeof(*rates));
0edd5b44 8453 /* configure supported rates */
43f66a6c
JK
8454 switch (priv->ieee->freq_band) {
8455 case IEEE80211_52GHZ_BAND:
8456 rates->ieee_mode = IPW_A_MODE;
8457 rates->purpose = IPW_RATE_CAPABILITIES;
8458 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
8459 IEEE80211_OFDM_DEFAULT_RATES_MASK);
8460 break;
8461
0edd5b44 8462 default: /* Mixed or 2.4Ghz */
43f66a6c
JK
8463 rates->ieee_mode = IPW_G_MODE;
8464 rates->purpose = IPW_RATE_CAPABILITIES;
8465 ipw_add_cck_scan_rates(rates, IEEE80211_CCK_MODULATION,
8466 IEEE80211_CCK_DEFAULT_RATES_MASK);
8467 if (priv->ieee->modulation & IEEE80211_OFDM_MODULATION) {
8468 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
8469 IEEE80211_OFDM_DEFAULT_RATES_MASK);
8470 }
8471 break;
8472 }
8473
8474 return 0;
8475}
8476
bf79451e 8477static int ipw_config(struct ipw_priv *priv)
43f66a6c
JK
8478{
8479 int i;
8480 struct ipw_tx_power tx_power;
8481
8482 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
8483 memset(&tx_power, 0, sizeof(tx_power));
8484
8485 /* This is only called from ipw_up, which resets/reloads the firmware
8486 so, we don't need to first disable the card before we configure
8487 it */
8488
8489 /* configure device for 'G' band */
8490 tx_power.ieee_mode = IPW_G_MODE;
8491 tx_power.num_channels = 11;
8492 for (i = 0; i < 11; i++) {
8493 tx_power.channels_tx_power[i].channel_number = i + 1;
8494 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
8495 }
8496 if (ipw_send_tx_power(priv, &tx_power))
8497 goto error;
8498
8499 /* configure device to also handle 'B' band */
8500 tx_power.ieee_mode = IPW_B_MODE;
8501 if (ipw_send_tx_power(priv, &tx_power))
8502 goto error;
8503
8504 /* initialize adapter address */
8505 if (ipw_send_adapter_address(priv, priv->net_dev->dev_addr))
8506 goto error;
8507
8508 /* set basic system config settings */
8509 init_sys_config(&priv->sys_config);
c848d0af
JK
8510 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
8511 priv->sys_config.answer_broadcast_ssid_probe = 1;
8512 else
8513 priv->sys_config.answer_broadcast_ssid_probe = 0;
8514
43f66a6c
JK
8515 if (ipw_send_system_config(priv, &priv->sys_config))
8516 goto error;
8517
0edd5b44
JG
8518 init_supported_rates(priv, &priv->rates);
8519 if (ipw_send_supported_rates(priv, &priv->rates))
43f66a6c
JK
8520 goto error;
8521
8522 /* Set request-to-send threshold */
8523 if (priv->rts_threshold) {
8524 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
8525 goto error;
8526 }
8527
8528 if (ipw_set_random_seed(priv))
8529 goto error;
bf79451e 8530
43f66a6c
JK
8531 /* final state transition to the RUN state */
8532 if (ipw_send_host_complete(priv))
8533 goto error;
8534
8535 /* If configured to try and auto-associate, kick off a scan */
c848d0af
JK
8536 if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv)) {
8537 IPW_WARNING("error sending scan request\n");
43f66a6c 8538 goto error;
c848d0af 8539 }
43f66a6c
JK
8540
8541 return 0;
bf79451e 8542
0edd5b44 8543 error:
43f66a6c
JK
8544 return -EIO;
8545}
8546
8547#define MAX_HW_RESTARTS 5
8548static int ipw_up(struct ipw_priv *priv)
8549{
8550 int rc, i;
8551
8552 if (priv->status & STATUS_EXIT_PENDING)
8553 return -EIO;
8554
0edd5b44 8555 for (i = 0; i < MAX_HW_RESTARTS; i++) {
bf79451e 8556 /* Load the microcode, firmware, and eeprom.
43f66a6c
JK
8557 * Also start the clocks. */
8558 rc = ipw_load(priv);
8559 if (rc) {
0edd5b44 8560 IPW_ERROR("Unable to load firmware: 0x%08X\n", rc);
43f66a6c
JK
8561 return rc;
8562 }
8563
8564 ipw_init_ordinals(priv);
8565 if (!(priv->config & CFG_CUSTOM_MAC))
8566 eeprom_parse_mac(priv, priv->mac_addr);
8567 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
8568
c848d0af 8569 if (priv->status & STATUS_RF_KILL_MASK) {
43f66a6c 8570 return 0;
c848d0af 8571 }
43f66a6c
JK
8572
8573 rc = ipw_config(priv);
8574 if (!rc) {
8575 IPW_DEBUG_INFO("Configured device on count %i\n", i);
a613bffd
JK
8576 ipw_led_init(priv);
8577 ipw_led_radio_on(priv);
43f66a6c 8578 priv->notif_missed_beacons = 0;
c848d0af 8579 priv->status |= STATUS_INIT;
43f66a6c 8580 return 0;
43f66a6c 8581 }
bf79451e 8582
c848d0af 8583 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
43f66a6c
JK
8584 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
8585 i, MAX_HW_RESTARTS);
8586
8587 /* We had an error bringing up the hardware, so take it
8588 * all the way back down so we can try again */
8589 ipw_down(priv);
8590 }
8591
bf79451e 8592 /* tried to restart and config the device for as long as our
43f66a6c 8593 * patience could withstand */
0edd5b44 8594 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
c848d0af 8595
43f66a6c
JK
8596 return -EIO;
8597}
8598
c848d0af
JK
8599static void ipw_bg_up(void *data)
8600{
8601 struct ipw_priv *priv = data;
8602 down(&priv->sem);
8603 ipw_up(data);
8604 up(&priv->sem);
8605}
8606
43f66a6c
JK
8607static void ipw_down(struct ipw_priv *priv)
8608{
43f66a6c 8609#if 0
c848d0af 8610 /* Attempt to disable the card */
43f66a6c
JK
8611 ipw_send_card_disable(priv, 0);
8612#endif
8613
8614 /* tell the device to stop sending interrupts */
8615 ipw_disable_interrupts(priv);
8616
8617 /* Clear all bits but the RF Kill */
8618 priv->status &= STATUS_RF_KILL_MASK;
43f66a6c
JK
8619 netif_carrier_off(priv->net_dev);
8620 netif_stop_queue(priv->net_dev);
8621
8622 ipw_stop_nic(priv);
a613bffd
JK
8623
8624 ipw_led_radio_off(priv);
43f66a6c
JK
8625}
8626
c848d0af
JK
8627static void ipw_bg_down(void *data)
8628{
8629 struct ipw_priv *priv = data;
8630 down(&priv->sem);
8631 ipw_down(data);
8632 up(&priv->sem);
8633}
8634
ea2b26e0
JK
8635static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
8636{
ea2b26e0
JK
8637 struct iwreq *wrq = (struct iwreq *)rq;
8638 int ret = -1;
8639 switch (cmd) {
8640 case IPW_IOCTL_WPA_SUPPLICANT:
8641 ret = ipw_wpa_supplicant(dev, &wrq->u.data);
8642 return ret;
8643
8644 default:
8645 return -EOPNOTSUPP;
8646 }
8647
ea2b26e0
JK
8648 return -EOPNOTSUPP;
8649}
8650
43f66a6c
JK
8651/* Called by register_netdev() */
8652static int ipw_net_init(struct net_device *dev)
8653{
8654 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8655 down(&priv->sem);
43f66a6c
JK
8656 if (priv->status & STATUS_RF_KILL_SW) {
8657 IPW_WARNING("Radio disabled by module parameter.\n");
c848d0af 8658 up(&priv->sem);
43f66a6c
JK
8659 return 0;
8660 } else if (rf_kill_active(priv)) {
8661 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
8662 "Kill switch must be turned off for "
8663 "wireless networking to work.\n");
8664 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
c848d0af 8665 up(&priv->sem);
43f66a6c
JK
8666 return 0;
8667 }
8668
c848d0af
JK
8669 if (ipw_up(priv)) {
8670 up(&priv->sem);
43f66a6c 8671 return -EIO;
c848d0af 8672 }
43f66a6c 8673
c848d0af 8674 up(&priv->sem);
43f66a6c
JK
8675 return 0;
8676}
8677
8678/* PCI driver stuff */
8679static struct pci_device_id card_ids[] = {
8680 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
8681 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
8682 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
8683 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2712, 0, 0, 0},
8684 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2721, 0, 0, 0},
8685 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2722, 0, 0, 0},
8686 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2731, 0, 0, 0},
8687 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2732, 0, 0, 0},
8688 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2741, 0, 0, 0},
8689 {PCI_VENDOR_ID_INTEL, 0x1043, 0x103c, 0x2741, 0, 0, 0},
8690 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2742, 0, 0, 0},
8691 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2751, 0, 0, 0},
8692 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2752, 0, 0, 0},
8693 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2753, 0, 0, 0},
8694 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},
8695 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},
8696 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
8697 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
0edd5b44 8698 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
a613bffd 8699 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
0edd5b44
JG
8700 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
8701 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
bf79451e 8702
43f66a6c
JK
8703 /* required last entry */
8704 {0,}
8705};
8706
8707MODULE_DEVICE_TABLE(pci, card_ids);
8708
8709static struct attribute *ipw_sysfs_entries[] = {
8710 &dev_attr_rf_kill.attr,
8711 &dev_attr_direct_dword.attr,
8712 &dev_attr_indirect_byte.attr,
8713 &dev_attr_indirect_dword.attr,
8714 &dev_attr_mem_gpio_reg.attr,
8715 &dev_attr_command_event_reg.attr,
8716 &dev_attr_nic_type.attr,
8717 &dev_attr_status.attr,
8718 &dev_attr_cfg.attr,
8719 &dev_attr_dump_errors.attr,
8720 &dev_attr_dump_events.attr,
8721 &dev_attr_eeprom_delay.attr,
8722 &dev_attr_ucode_version.attr,
8723 &dev_attr_rtc.attr,
a613bffd
JK
8724 &dev_attr_scan_age.attr,
8725 &dev_attr_led.attr,
43f66a6c
JK
8726 NULL
8727};
8728
8729static struct attribute_group ipw_attribute_group = {
8730 .name = NULL, /* put in device directory */
0edd5b44 8731 .attrs = ipw_sysfs_entries,
43f66a6c
JK
8732};
8733
0edd5b44 8734static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
43f66a6c
JK
8735{
8736 int err = 0;
8737 struct net_device *net_dev;
8738 void __iomem *base;
8739 u32 length, val;
8740 struct ipw_priv *priv;
8741 int band, modulation;
8742
8743 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
8744 if (net_dev == NULL) {
8745 err = -ENOMEM;
8746 goto out;
8747 }
8748
8749 priv = ieee80211_priv(net_dev);
8750 priv->ieee = netdev_priv(net_dev);
a613bffd 8751
43f66a6c
JK
8752 priv->net_dev = net_dev;
8753 priv->pci_dev = pdev;
8754#ifdef CONFIG_IPW_DEBUG
8755 ipw_debug_level = debug;
8756#endif
8757 spin_lock_init(&priv->lock);
8758
c848d0af 8759 init_MUTEX(&priv->sem);
43f66a6c
JK
8760 if (pci_enable_device(pdev)) {
8761 err = -ENODEV;
8762 goto out_free_ieee80211;
8763 }
8764
8765 pci_set_master(pdev);
8766
0e08b44e 8767 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
bf79451e 8768 if (!err)
0e08b44e 8769 err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
43f66a6c
JK
8770 if (err) {
8771 printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
8772 goto out_pci_disable_device;
8773 }
8774
8775 pci_set_drvdata(pdev, priv);
8776
8777 err = pci_request_regions(pdev, DRV_NAME);
bf79451e 8778 if (err)
43f66a6c
JK
8779 goto out_pci_disable_device;
8780
bf79451e 8781 /* We disable the RETRY_TIMEOUT register (0x41) to keep
43f66a6c 8782 * PCI Tx retries from interfering with C3 CPU state */
bf79451e
JG
8783 pci_read_config_dword(pdev, 0x40, &val);
8784 if ((val & 0x0000ff00) != 0)
43f66a6c 8785 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
bf79451e 8786
43f66a6c
JK
8787 length = pci_resource_len(pdev, 0);
8788 priv->hw_len = length;
bf79451e 8789
43f66a6c
JK
8790 base = ioremap_nocache(pci_resource_start(pdev, 0), length);
8791 if (!base) {
8792 err = -ENODEV;
8793 goto out_pci_release_regions;
8794 }
8795
8796 priv->hw_base = base;
8797 IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);
8798 IPW_DEBUG_INFO("pci_resource_base = %p\n", base);
8799
8800 err = ipw_setup_deferred_work(priv);
8801 if (err) {
8802 IPW_ERROR("Unable to setup deferred work\n");
8803 goto out_iounmap;
8804 }
8805
8806 /* Initialize module parameter values here */
a613bffd
JK
8807
8808 /* We default to disabling the LED code as right now it causes
8809 * too many systems to lock up... */
8810 if (!led)
8811 priv->config |= CFG_NO_LED;
8812
bf79451e 8813 if (associate)
43f66a6c
JK
8814 priv->config |= CFG_ASSOCIATE;
8815 else
8816 IPW_DEBUG_INFO("Auto associate disabled.\n");
bf79451e
JG
8817
8818 if (auto_create)
43f66a6c
JK
8819 priv->config |= CFG_ADHOC_CREATE;
8820 else
8821 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
bf79451e 8822
43f66a6c
JK
8823 if (disable) {
8824 priv->status |= STATUS_RF_KILL_SW;
8825 IPW_DEBUG_INFO("Radio disabled.\n");
8826 }
8827
8828 if (channel != 0) {
8829 priv->config |= CFG_STATIC_CHANNEL;
8830 priv->channel = channel;
8831 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
0edd5b44 8832 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
43f66a6c
JK
8833 /* TODO: Validate that provided channel is in range */
8834 }
8835
8836 switch (mode) {
8837 case 1:
8838 priv->ieee->iw_mode = IW_MODE_ADHOC;
8839 break;
ea2b26e0 8840#ifdef CONFIG_IPW_MONITOR
43f66a6c
JK
8841 case 2:
8842 priv->ieee->iw_mode = IW_MODE_MONITOR;
8843 break;
8844#endif
8845 default:
8846 case 0:
8847 priv->ieee->iw_mode = IW_MODE_INFRA;
8848 break;
8849 }
8850
8851 if ((priv->pci_dev->device == 0x4223) ||
8852 (priv->pci_dev->device == 0x4224)) {
bf79451e 8853 printk(KERN_INFO DRV_NAME
43f66a6c
JK
8854 ": Detected Intel PRO/Wireless 2915ABG Network "
8855 "Connection\n");
a33a1982 8856 priv->ieee->abg_true = 1;
43f66a6c
JK
8857 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
8858 modulation = IEEE80211_OFDM_MODULATION |
0edd5b44 8859 IEEE80211_CCK_MODULATION;
43f66a6c 8860 priv->adapter = IPW_2915ABG;
0edd5b44 8861 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
43f66a6c 8862 } else {
a613bffd
JK
8863 printk(KERN_INFO DRV_NAME
8864 ": Detected Intel PRO/Wireless 2200BG Network "
8865 "Connection\n");
bf79451e 8866
a33a1982 8867 priv->ieee->abg_true = 0;
43f66a6c
JK
8868 band = IEEE80211_24GHZ_BAND;
8869 modulation = IEEE80211_OFDM_MODULATION |
0edd5b44 8870 IEEE80211_CCK_MODULATION;
43f66a6c 8871 priv->adapter = IPW_2200BG;
0edd5b44 8872 priv->ieee->mode = IEEE_G | IEEE_B;
43f66a6c
JK
8873 }
8874
8875 priv->ieee->freq_band = band;
8876 priv->ieee->modulation = modulation;
8877
8878 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
8879
8880 priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
8881 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
8882
8883 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8884
8885 /* If power management is turned on, default to AC mode */
0edd5b44 8886 priv->power_mode = IPW_POWER_AC;
43f66a6c
JK
8887 priv->tx_power = IPW_DEFAULT_TX_POWER;
8888
0edd5b44 8889 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
43f66a6c
JK
8890 if (err) {
8891 IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
8892 goto out_destroy_workqueue;
8893 }
8894
8895 SET_MODULE_OWNER(net_dev);
8896 SET_NETDEV_DEV(net_dev, &pdev->dev);
8897
a613bffd
JK
8898 ipw_wx_data.spy_data = &priv->ieee->spy_data;
8899 ipw_wx_data.ieee80211 = priv->ieee;
8900
c848d0af
JK
8901 down(&priv->sem);
8902
43f66a6c
JK
8903 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
8904 priv->ieee->set_security = shim__set_security;
8905
c848d0af
JK
8906 priv->ieee->perfect_rssi = -20;
8907 priv->ieee->worst_rssi = -85;
8908
43f66a6c
JK
8909 net_dev->open = ipw_net_open;
8910 net_dev->stop = ipw_net_stop;
8911 net_dev->init = ipw_net_init;
ea2b26e0 8912 net_dev->do_ioctl = ipw_ioctl;
43f66a6c
JK
8913 net_dev->get_stats = ipw_net_get_stats;
8914 net_dev->set_multicast_list = ipw_net_set_multicast_list;
8915 net_dev->set_mac_address = ipw_net_set_mac_address;
8916 net_dev->get_wireless_stats = ipw_get_wireless_stats;
a613bffd 8917 net_dev->wireless_data = &ipw_wx_data;
43f66a6c
JK
8918 net_dev->wireless_handlers = &ipw_wx_handler_def;
8919 net_dev->ethtool_ops = &ipw_ethtool_ops;
8920 net_dev->irq = pdev->irq;
0edd5b44 8921 net_dev->base_addr = (unsigned long)priv->hw_base;
43f66a6c
JK
8922 net_dev->mem_start = pci_resource_start(pdev, 0);
8923 net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1;
8924
8925 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
8926 if (err) {
8927 IPW_ERROR("failed to create sysfs device attributes\n");
c848d0af 8928 up(&priv->sem);
43f66a6c
JK
8929 goto out_release_irq;
8930 }
8931
c848d0af 8932 up(&priv->sem);
43f66a6c
JK
8933 err = register_netdev(net_dev);
8934 if (err) {
8935 IPW_ERROR("failed to register network device\n");
a613bffd 8936 goto out_remove_sysfs;
43f66a6c 8937 }
43f66a6c
JK
8938 return 0;
8939
a613bffd 8940 out_remove_sysfs:
43f66a6c 8941 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
0edd5b44 8942 out_release_irq:
43f66a6c 8943 free_irq(pdev->irq, priv);
0edd5b44 8944 out_destroy_workqueue:
43f66a6c
JK
8945 destroy_workqueue(priv->workqueue);
8946 priv->workqueue = NULL;
0edd5b44 8947 out_iounmap:
43f66a6c 8948 iounmap(priv->hw_base);
0edd5b44 8949 out_pci_release_regions:
43f66a6c 8950 pci_release_regions(pdev);
0edd5b44 8951 out_pci_disable_device:
43f66a6c
JK
8952 pci_disable_device(pdev);
8953 pci_set_drvdata(pdev, NULL);
0edd5b44 8954 out_free_ieee80211:
43f66a6c 8955 free_ieee80211(priv->net_dev);
0edd5b44 8956 out:
43f66a6c
JK
8957 return err;
8958}
8959
8960static void ipw_pci_remove(struct pci_dev *pdev)
8961{
8962 struct ipw_priv *priv = pci_get_drvdata(pdev);
8963 if (!priv)
8964 return;
8965
8966 priv->status |= STATUS_EXIT_PENDING;
8967
8968 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
8969
8970 ipw_down(priv);
8971
8972 unregister_netdev(priv->net_dev);
8973
8974 if (priv->rxq) {
8975 ipw_rx_queue_free(priv, priv->rxq);
8976 priv->rxq = NULL;
8977 }
8978 ipw_tx_queue_free(priv);
8979
a613bffd
JK
8980 ipw_led_shutdown(priv);
8981
43f66a6c
JK
8982 /* ipw_down will ensure that there is no more pending work
8983 * in the workqueue's, so we can safely remove them now. */
a613bffd
JK
8984 cancel_delayed_work(&priv->adhoc_check);
8985 cancel_delayed_work(&priv->gather_stats);
8986 cancel_delayed_work(&priv->request_scan);
8987 cancel_delayed_work(&priv->rf_kill);
8988 cancel_delayed_work(&priv->scan_check);
8989 destroy_workqueue(priv->workqueue);
8990 priv->workqueue = NULL;
43f66a6c
JK
8991
8992 free_irq(pdev->irq, priv);
8993 iounmap(priv->hw_base);
8994 pci_release_regions(pdev);
8995 pci_disable_device(pdev);
8996 pci_set_drvdata(pdev, NULL);
8997 free_ieee80211(priv->net_dev);
8998
8999#ifdef CONFIG_PM
9000 if (fw_loaded) {
9001 release_firmware(bootfw);
9002 release_firmware(ucode);
9003 release_firmware(firmware);
9004 fw_loaded = 0;
9005 }
9006#endif
9007}
9008
43f66a6c 9009#ifdef CONFIG_PM
583a4e88 9010static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
43f66a6c
JK
9011{
9012 struct ipw_priv *priv = pci_get_drvdata(pdev);
9013 struct net_device *dev = priv->net_dev;
9014
9015 printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
9016
0edd5b44 9017 /* Take down the device; powers it off, etc. */
43f66a6c
JK
9018 ipw_down(priv);
9019
9020 /* Remove the PRESENT state of the device */
9021 netif_device_detach(dev);
9022
43f66a6c 9023 pci_save_state(pdev);
43f66a6c 9024 pci_disable_device(pdev);
583a4e88 9025 pci_set_power_state(pdev, pci_choose_state(pdev, state));
bf79451e 9026
43f66a6c
JK
9027 return 0;
9028}
9029
9030static int ipw_pci_resume(struct pci_dev *pdev)
9031{
9032 struct ipw_priv *priv = pci_get_drvdata(pdev);
9033 struct net_device *dev = priv->net_dev;
9034 u32 val;
bf79451e 9035
43f66a6c
JK
9036 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
9037
ea2b26e0 9038 pci_set_power_state(pdev, PCI_D0);
43f66a6c 9039 pci_enable_device(pdev);
43f66a6c 9040 pci_restore_state(pdev);
ea2b26e0 9041
43f66a6c
JK
9042 /*
9043 * Suspend/Resume resets the PCI configuration space, so we have to
9044 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
9045 * from interfering with C3 CPU state. pci_restore_state won't help
9046 * here since it only restores the first 64 bytes pci config header.
9047 */
bf79451e
JG
9048 pci_read_config_dword(pdev, 0x40, &val);
9049 if ((val & 0x0000ff00) != 0)
43f66a6c
JK
9050 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
9051
9052 /* Set the device back into the PRESENT state; this will also wake
9053 * the queue of needed */
9054 netif_device_attach(dev);
9055
9056 /* Bring the device back up */
9057 queue_work(priv->workqueue, &priv->up);
bf79451e 9058
43f66a6c
JK
9059 return 0;
9060}
9061#endif
9062
9063/* driver initialization stuff */
9064static struct pci_driver ipw_driver = {
9065 .name = DRV_NAME,
9066 .id_table = card_ids,
9067 .probe = ipw_pci_probe,
9068 .remove = __devexit_p(ipw_pci_remove),
9069#ifdef CONFIG_PM
9070 .suspend = ipw_pci_suspend,
9071 .resume = ipw_pci_resume,
9072#endif
9073};
9074
9075static int __init ipw_init(void)
9076{
9077 int ret;
9078
9079 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
9080 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
9081
9082 ret = pci_module_init(&ipw_driver);
9083 if (ret) {
9084 IPW_ERROR("Unable to initialize PCI module\n");
9085 return ret;
9086 }
9087
0edd5b44 9088 ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level);
43f66a6c
JK
9089 if (ret) {
9090 IPW_ERROR("Unable to create driver sysfs file\n");
9091 pci_unregister_driver(&ipw_driver);
9092 return ret;
9093 }
9094
9095 return ret;
9096}
9097
9098static void __exit ipw_exit(void)
9099{
9100 driver_remove_file(&ipw_driver.driver, &driver_attr_debug_level);
9101 pci_unregister_driver(&ipw_driver);
9102}
9103
9104module_param(disable, int, 0444);
9105MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
9106
9107module_param(associate, int, 0444);
9108MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
9109
9110module_param(auto_create, int, 0444);
9111MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
9112
a613bffd 9113module_param(led, int, 0444);
c848d0af 9114MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
a613bffd 9115
43f66a6c
JK
9116module_param(debug, int, 0444);
9117MODULE_PARM_DESC(debug, "debug output mask");
9118
9119module_param(channel, int, 0444);
bf79451e 9120MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
43f66a6c 9121
ea2b26e0 9122#ifdef CONFIG_IPW_MONITOR
43f66a6c
JK
9123module_param(mode, int, 0444);
9124MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
9125#else
9126module_param(mode, int, 0444);
9127MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
9128#endif
9129
9130module_exit(ipw_exit);
9131module_init(ipw_init);