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