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