aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2200.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r--drivers/net/wireless/ipw2200.c1239
1 files changed, 596 insertions, 643 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 287676ad80df..9dce522526c5 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
4 4
5 802.11 status code portion of this file from ethereal-0.10.6: 5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB 6 Copyright 2000, Axis Communications AB
@@ -33,9 +33,9 @@
33#include "ipw2200.h" 33#include "ipw2200.h"
34#include <linux/version.h> 34#include <linux/version.h>
35 35
36#define IPW2200_VERSION "git-1.0.8" 36#define IPW2200_VERSION "git-1.1.1"
37#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 37#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
38#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation" 38#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
39#define DRV_VERSION IPW2200_VERSION 39#define DRV_VERSION IPW2200_VERSION
40 40
41#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1) 41#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
@@ -55,7 +55,9 @@ static int associate = 1;
55static int auto_create = 1; 55static int auto_create = 1;
56static int led = 0; 56static int led = 0;
57static int disable = 0; 57static int disable = 0;
58static int hwcrypto = 1; 58static int bt_coexist = 0;
59static int hwcrypto = 0;
60static int roaming = 1;
59static const char ipw_modes[] = { 61static const char ipw_modes[] = {
60 'a', 'b', 'g', '?' 62 'a', 'b', 'g', '?'
61}; 63};
@@ -151,12 +153,6 @@ static int init_supported_rates(struct ipw_priv *priv,
151static void ipw_set_hwcrypto_keys(struct ipw_priv *); 153static void ipw_set_hwcrypto_keys(struct ipw_priv *);
152static void ipw_send_wep_keys(struct ipw_priv *, int); 154static void ipw_send_wep_keys(struct ipw_priv *, int);
153 155
154static int ipw_is_valid_channel(struct ieee80211_device *, u8);
155static int ipw_channel_to_index(struct ieee80211_device *, u8);
156static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
157static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
158static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
159
160static int snprint_line(char *buf, size_t count, 156static int snprint_line(char *buf, size_t count,
161 const u8 * data, u32 len, u32 ofs) 157 const u8 * data, u32 len, u32 ofs)
162{ 158{
@@ -227,12 +223,15 @@ static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
227 return total; 223 return total;
228} 224}
229 225
226/* alias for 32-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
230static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg); 227static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
231#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b) 228#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
232 229
230/* alias for 8-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
233static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg); 231static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
234#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b) 232#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
235 233
234/* 8-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
236static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value); 235static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
237static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) 236static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
238{ 237{
@@ -241,6 +240,7 @@ static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
241 _ipw_write_reg8(a, b, c); 240 _ipw_write_reg8(a, b, c);
242} 241}
243 242
243/* 16-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
244static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value); 244static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
245static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) 245static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
246{ 246{
@@ -249,6 +249,7 @@ static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
249 _ipw_write_reg16(a, b, c); 249 _ipw_write_reg16(a, b, c);
250} 250}
251 251
252/* 32-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
252static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value); 253static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
253static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) 254static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
254{ 255{
@@ -257,48 +258,70 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
257 _ipw_write_reg32(a, b, c); 258 _ipw_write_reg32(a, b, c);
258} 259}
259 260
261/* 8-bit direct write (low 4K) */
260#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs)) 262#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
263
264/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
261#define ipw_write8(ipw, ofs, val) \ 265#define ipw_write8(ipw, ofs, val) \
262 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ 266 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
263 _ipw_write8(ipw, ofs, val) 267 _ipw_write8(ipw, ofs, val)
264 268
269/* 16-bit direct write (low 4K) */
265#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs)) 270#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
271
272/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
266#define ipw_write16(ipw, ofs, val) \ 273#define ipw_write16(ipw, ofs, val) \
267 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ 274 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
268 _ipw_write16(ipw, ofs, val) 275 _ipw_write16(ipw, ofs, val)
269 276
277/* 32-bit direct write (low 4K) */
270#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs)) 278#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
279
280/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
271#define ipw_write32(ipw, ofs, val) \ 281#define ipw_write32(ipw, ofs, val) \
272 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ 282 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
273 _ipw_write32(ipw, ofs, val) 283 _ipw_write32(ipw, ofs, val)
274 284
285/* 8-bit direct read (low 4K) */
275#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs)) 286#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
287
288/* 8-bit direct read (low 4K), with debug wrapper */
276static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) 289static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
277{ 290{
278 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs)); 291 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
279 return _ipw_read8(ipw, ofs); 292 return _ipw_read8(ipw, ofs);
280} 293}
281 294
295/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
282#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs) 296#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
283 297
298/* 16-bit direct read (low 4K) */
284#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs)) 299#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
300
301/* 16-bit direct read (low 4K), with debug wrapper */
285static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) 302static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
286{ 303{
287 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs)); 304 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
288 return _ipw_read16(ipw, ofs); 305 return _ipw_read16(ipw, ofs);
289} 306}
290 307
308/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
291#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs) 309#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
292 310
311/* 32-bit direct read (low 4K) */
293#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs)) 312#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
313
314/* 32-bit direct read (low 4K), with debug wrapper */
294static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) 315static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
295{ 316{
296 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs)); 317 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
297 return _ipw_read32(ipw, ofs); 318 return _ipw_read32(ipw, ofs);
298} 319}
299 320
321/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
300#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) 322#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
301 323
324/* multi-byte read (above 4K), with debug wrapper */
302static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); 325static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
303static inline void __ipw_read_indirect(const char *f, int l, 326static inline void __ipw_read_indirect(const char *f, int l,
304 struct ipw_priv *a, u32 b, u8 * c, int d) 327 struct ipw_priv *a, u32 b, u8 * c, int d)
@@ -308,15 +331,17 @@ static inline void __ipw_read_indirect(const char *f, int l,
308 _ipw_read_indirect(a, b, c, d); 331 _ipw_read_indirect(a, b, c, d);
309} 332}
310 333
334/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
311#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d) 335#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
312 336
337/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
313static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, 338static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
314 int num); 339 int num);
315#define ipw_write_indirect(a, b, c, d) \ 340#define ipw_write_indirect(a, b, c, d) \
316 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 341 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
317 _ipw_write_indirect(a, b, c, d) 342 _ipw_write_indirect(a, b, c, d)
318 343
319/* indirect write s */ 344/* 32-bit indirect write (above 4K) */
320static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) 345static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
321{ 346{
322 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); 347 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
@@ -324,22 +349,29 @@ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
324 _ipw_write32(priv, IPW_INDIRECT_DATA, value); 349 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
325} 350}
326 351
352/* 8-bit indirect write (above 4K) */
327static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) 353static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
328{ 354{
355 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */
356 u32 dif_len = reg - aligned_addr;
357
329 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 358 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
330 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); 359 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
331 _ipw_write8(priv, IPW_INDIRECT_DATA, value); 360 _ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value);
332} 361}
333 362
363/* 16-bit indirect write (above 4K) */
334static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) 364static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
335{ 365{
366 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */
367 u32 dif_len = (reg - aligned_addr) & (~0x1ul);
368
336 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 369 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
337 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); 370 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
338 _ipw_write16(priv, IPW_INDIRECT_DATA, value); 371 _ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value);
339} 372}
340 373
341/* indirect read s */ 374/* 8-bit indirect read (above 4K) */
342
343static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) 375static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
344{ 376{
345 u32 word; 377 u32 word;
@@ -349,6 +381,7 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
349 return (word >> ((reg & 0x3) * 8)) & 0xff; 381 return (word >> ((reg & 0x3) * 8)) & 0xff;
350} 382}
351 383
384/* 32-bit indirect read (above 4K) */
352static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg) 385static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
353{ 386{
354 u32 value; 387 u32 value;
@@ -361,11 +394,12 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
361 return value; 394 return value;
362} 395}
363 396
364/* iterative/auto-increment 32 bit reads and writes */ 397/* General purpose, no alignment requirement, iterative (multi-byte) read, */
398/* for area above 1st 4K of SRAM/reg space */
365static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 399static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
366 int num) 400 int num)
367{ 401{
368 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; 402 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */
369 u32 dif_len = addr - aligned_addr; 403 u32 dif_len = addr - aligned_addr;
370 u32 i; 404 u32 i;
371 405
@@ -375,7 +409,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
375 return; 409 return;
376 } 410 }
377 411
378 /* Read the first nibble byte by byte */ 412 /* Read the first dword (or portion) byte by byte */
379 if (unlikely(dif_len)) { 413 if (unlikely(dif_len)) {
380 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); 414 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
381 /* Start reading at aligned_addr + dif_len */ 415 /* Start reading at aligned_addr + dif_len */
@@ -384,11 +418,12 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
384 aligned_addr += 4; 418 aligned_addr += 4;
385 } 419 }
386 420
421 /* Read all of the middle dwords as dwords, with auto-increment */
387 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr); 422 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
388 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4) 423 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
389 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA); 424 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
390 425
391 /* Copy the last nibble */ 426 /* Read the last dword (or portion) byte by byte */
392 if (unlikely(num)) { 427 if (unlikely(num)) {
393 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); 428 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
394 for (i = 0; num > 0; i++, num--) 429 for (i = 0; num > 0; i++, num--)
@@ -396,10 +431,12 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
396 } 431 }
397} 432}
398 433
434/* General purpose, no alignment requirement, iterative (multi-byte) write, */
435/* for area above 1st 4K of SRAM/reg space */
399static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 436static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
400 int num) 437 int num)
401{ 438{
402 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; 439 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */
403 u32 dif_len = addr - aligned_addr; 440 u32 dif_len = addr - aligned_addr;
404 u32 i; 441 u32 i;
405 442
@@ -409,20 +446,21 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
409 return; 446 return;
410 } 447 }
411 448
412 /* Write the first nibble byte by byte */ 449 /* Write the first dword (or portion) byte by byte */
413 if (unlikely(dif_len)) { 450 if (unlikely(dif_len)) {
414 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); 451 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
415 /* Start reading at aligned_addr + dif_len */ 452 /* Start writing at aligned_addr + dif_len */
416 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++) 453 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
417 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf); 454 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
418 aligned_addr += 4; 455 aligned_addr += 4;
419 } 456 }
420 457
458 /* Write all of the middle dwords as dwords, with auto-increment */
421 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr); 459 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
422 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4) 460 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
423 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf); 461 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
424 462
425 /* Copy the last nibble */ 463 /* Write the last dword (or portion) byte by byte */
426 if (unlikely(num)) { 464 if (unlikely(num)) {
427 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); 465 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
428 for (i = 0; num > 0; i++, num--, buf++) 466 for (i = 0; num > 0; i++, num--, buf++)
@@ -430,17 +468,21 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
430 } 468 }
431} 469}
432 470
471/* General purpose, no alignment requirement, iterative (multi-byte) write, */
472/* for 1st 4K of SRAM/regs space */
433static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, 473static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
434 int num) 474 int num)
435{ 475{
436 memcpy_toio((priv->hw_base + addr), buf, num); 476 memcpy_toio((priv->hw_base + addr), buf, num);
437} 477}
438 478
479/* Set bit(s) in low 4K of SRAM/regs */
439static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask) 480static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
440{ 481{
441 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask); 482 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
442} 483}
443 484
485/* Clear bit(s) in low 4K of SRAM/regs */
444static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask) 486static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
445{ 487{
446 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); 488 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
@@ -701,7 +743,7 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
701 743
702} 744}
703 745
704u32 ipw_register_toggle(u32 reg) 746static u32 ipw_register_toggle(u32 reg)
705{ 747{
706 reg &= ~IPW_START_STANDBY; 748 reg &= ~IPW_START_STANDBY;
707 if (reg & IPW_GATE_ODMA) 749 if (reg & IPW_GATE_ODMA)
@@ -722,11 +764,11 @@ u32 ipw_register_toggle(u32 reg)
722 * - On radio OFF, turn off any LEDs started during radio on 764 * - On radio OFF, turn off any LEDs started during radio on
723 * 765 *
724 */ 766 */
725#define LD_TIME_LINK_ON 300 767#define LD_TIME_LINK_ON msecs_to_jiffies(300)
726#define LD_TIME_LINK_OFF 2700 768#define LD_TIME_LINK_OFF msecs_to_jiffies(2700)
727#define LD_TIME_ACT_ON 250 769#define LD_TIME_ACT_ON msecs_to_jiffies(250)
728 770
729void ipw_led_link_on(struct ipw_priv *priv) 771static void ipw_led_link_on(struct ipw_priv *priv)
730{ 772{
731 unsigned long flags; 773 unsigned long flags;
732 u32 led; 774 u32 led;
@@ -764,12 +806,12 @@ void ipw_led_link_on(struct ipw_priv *priv)
764static void ipw_bg_led_link_on(void *data) 806static void ipw_bg_led_link_on(void *data)
765{ 807{
766 struct ipw_priv *priv = data; 808 struct ipw_priv *priv = data;
767 down(&priv->sem); 809 mutex_lock(&priv->mutex);
768 ipw_led_link_on(data); 810 ipw_led_link_on(data);
769 up(&priv->sem); 811 mutex_unlock(&priv->mutex);
770} 812}
771 813
772void ipw_led_link_off(struct ipw_priv *priv) 814static void ipw_led_link_off(struct ipw_priv *priv)
773{ 815{
774 unsigned long flags; 816 unsigned long flags;
775 u32 led; 817 u32 led;
@@ -808,9 +850,9 @@ void ipw_led_link_off(struct ipw_priv *priv)
808static void ipw_bg_led_link_off(void *data) 850static void ipw_bg_led_link_off(void *data)
809{ 851{
810 struct ipw_priv *priv = data; 852 struct ipw_priv *priv = data;
811 down(&priv->sem); 853 mutex_lock(&priv->mutex);
812 ipw_led_link_off(data); 854 ipw_led_link_off(data);
813 up(&priv->sem); 855 mutex_unlock(&priv->mutex);
814} 856}
815 857
816static void __ipw_led_activity_on(struct ipw_priv *priv) 858static void __ipw_led_activity_on(struct ipw_priv *priv)
@@ -847,6 +889,7 @@ static void __ipw_led_activity_on(struct ipw_priv *priv)
847 } 889 }
848} 890}
849 891
892#if 0
850void ipw_led_activity_on(struct ipw_priv *priv) 893void ipw_led_activity_on(struct ipw_priv *priv)
851{ 894{
852 unsigned long flags; 895 unsigned long flags;
@@ -854,8 +897,9 @@ void ipw_led_activity_on(struct ipw_priv *priv)
854 __ipw_led_activity_on(priv); 897 __ipw_led_activity_on(priv);
855 spin_unlock_irqrestore(&priv->lock, flags); 898 spin_unlock_irqrestore(&priv->lock, flags);
856} 899}
900#endif /* 0 */
857 901
858void ipw_led_activity_off(struct ipw_priv *priv) 902static void ipw_led_activity_off(struct ipw_priv *priv)
859{ 903{
860 unsigned long flags; 904 unsigned long flags;
861 u32 led; 905 u32 led;
@@ -885,12 +929,12 @@ void ipw_led_activity_off(struct ipw_priv *priv)
885static void ipw_bg_led_activity_off(void *data) 929static void ipw_bg_led_activity_off(void *data)
886{ 930{
887 struct ipw_priv *priv = data; 931 struct ipw_priv *priv = data;
888 down(&priv->sem); 932 mutex_lock(&priv->mutex);
889 ipw_led_activity_off(data); 933 ipw_led_activity_off(data);
890 up(&priv->sem); 934 mutex_unlock(&priv->mutex);
891} 935}
892 936
893void ipw_led_band_on(struct ipw_priv *priv) 937static void ipw_led_band_on(struct ipw_priv *priv)
894{ 938{
895 unsigned long flags; 939 unsigned long flags;
896 u32 led; 940 u32 led;
@@ -925,7 +969,7 @@ void ipw_led_band_on(struct ipw_priv *priv)
925 spin_unlock_irqrestore(&priv->lock, flags); 969 spin_unlock_irqrestore(&priv->lock, flags);
926} 970}
927 971
928void ipw_led_band_off(struct ipw_priv *priv) 972static void ipw_led_band_off(struct ipw_priv *priv)
929{ 973{
930 unsigned long flags; 974 unsigned long flags;
931 u32 led; 975 u32 led;
@@ -948,24 +992,24 @@ void ipw_led_band_off(struct ipw_priv *priv)
948 spin_unlock_irqrestore(&priv->lock, flags); 992 spin_unlock_irqrestore(&priv->lock, flags);
949} 993}
950 994
951void ipw_led_radio_on(struct ipw_priv *priv) 995static void ipw_led_radio_on(struct ipw_priv *priv)
952{ 996{
953 ipw_led_link_on(priv); 997 ipw_led_link_on(priv);
954} 998}
955 999
956void ipw_led_radio_off(struct ipw_priv *priv) 1000static void ipw_led_radio_off(struct ipw_priv *priv)
957{ 1001{
958 ipw_led_activity_off(priv); 1002 ipw_led_activity_off(priv);
959 ipw_led_link_off(priv); 1003 ipw_led_link_off(priv);
960} 1004}
961 1005
962void ipw_led_link_up(struct ipw_priv *priv) 1006static void ipw_led_link_up(struct ipw_priv *priv)
963{ 1007{
964 /* Set the Link Led on for all nic types */ 1008 /* Set the Link Led on for all nic types */
965 ipw_led_link_on(priv); 1009 ipw_led_link_on(priv);
966} 1010}
967 1011
968void ipw_led_link_down(struct ipw_priv *priv) 1012static void ipw_led_link_down(struct ipw_priv *priv)
969{ 1013{
970 ipw_led_activity_off(priv); 1014 ipw_led_activity_off(priv);
971 ipw_led_link_off(priv); 1015 ipw_led_link_off(priv);
@@ -974,7 +1018,7 @@ void ipw_led_link_down(struct ipw_priv *priv)
974 ipw_led_radio_off(priv); 1018 ipw_led_radio_off(priv);
975} 1019}
976 1020
977void ipw_led_init(struct ipw_priv *priv) 1021static void ipw_led_init(struct ipw_priv *priv)
978{ 1022{
979 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE]; 1023 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
980 1024
@@ -1025,7 +1069,7 @@ void ipw_led_init(struct ipw_priv *priv)
1025 } 1069 }
1026} 1070}
1027 1071
1028void ipw_led_shutdown(struct ipw_priv *priv) 1072static void ipw_led_shutdown(struct ipw_priv *priv)
1029{ 1073{
1030 ipw_led_activity_off(priv); 1074 ipw_led_activity_off(priv);
1031 ipw_led_link_off(priv); 1075 ipw_led_link_off(priv);
@@ -1074,6 +1118,7 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
1074 1118
1075static inline u32 ipw_get_event_log_len(struct ipw_priv *priv) 1119static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
1076{ 1120{
1121 /* length = 1st dword in log */
1077 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG)); 1122 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
1078} 1123}
1079 1124
@@ -1603,7 +1648,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1603 break; 1648 break;
1604 } 1649 }
1605 1650
1606 if (ipw_is_valid_channel(priv->ieee, channel)) 1651 if (ieee80211_is_valid_channel(priv->ieee, channel))
1607 priv->speed_scan[pos++] = channel; 1652 priv->speed_scan[pos++] = channel;
1608 else 1653 else
1609 IPW_WARNING("Skipping invalid channel request: %d\n", 1654 IPW_WARNING("Skipping invalid channel request: %d\n",
@@ -1751,9 +1796,9 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1751 } 1796 }
1752 1797
1753 if (inta & IPW_INTA_BIT_FATAL_ERROR) { 1798 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
1754 IPW_ERROR("Firmware error detected. Restarting.\n"); 1799 IPW_WARNING("Firmware error detected. Restarting.\n");
1755 if (priv->error) { 1800 if (priv->error) {
1756 IPW_ERROR("Sysfs 'error' log already exists.\n"); 1801 IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");
1757#ifdef CONFIG_IPW2200_DEBUG 1802#ifdef CONFIG_IPW2200_DEBUG
1758 if (ipw_debug_level & IPW_DL_FW_ERRORS) { 1803 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1759 struct ipw_fw_error *error = 1804 struct ipw_fw_error *error =
@@ -1766,10 +1811,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1766 } else { 1811 } else {
1767 priv->error = ipw_alloc_error_log(priv); 1812 priv->error = ipw_alloc_error_log(priv);
1768 if (priv->error) 1813 if (priv->error)
1769 IPW_ERROR("Sysfs 'error' log captured.\n"); 1814 IPW_DEBUG_FW("Sysfs 'error' log captured.\n");
1770 else 1815 else
1771 IPW_ERROR("Error allocating sysfs 'error' " 1816 IPW_DEBUG_FW("Error allocating sysfs 'error' "
1772 "log.\n"); 1817 "log.\n");
1773#ifdef CONFIG_IPW2200_DEBUG 1818#ifdef CONFIG_IPW2200_DEBUG
1774 if (ipw_debug_level & IPW_DL_FW_ERRORS) 1819 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1775 ipw_dump_error_log(priv, priv->error); 1820 ipw_dump_error_log(priv, priv->error);
@@ -1870,7 +1915,8 @@ static char *get_cmd_string(u8 cmd)
1870} 1915}
1871 1916
1872#define HOST_COMPLETE_TIMEOUT HZ 1917#define HOST_COMPLETE_TIMEOUT HZ
1873static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) 1918
1919static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1874{ 1920{
1875 int rc = 0; 1921 int rc = 0;
1876 unsigned long flags; 1922 unsigned long flags;
@@ -1897,9 +1943,15 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1897 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n", 1943 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
1898 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len, 1944 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
1899 priv->status); 1945 priv->status);
1900 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
1901 1946
1902 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); 1947#ifndef DEBUG_CMD_WEP_KEY
1948 if (cmd->cmd == IPW_CMD_WEP_KEY)
1949 IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n");
1950 else
1951#endif
1952 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
1953
1954 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0);
1903 if (rc) { 1955 if (rc) {
1904 priv->status &= ~STATUS_HCMD_ACTIVE; 1956 priv->status &= ~STATUS_HCMD_ACTIVE;
1905 IPW_ERROR("Failed to send %s: Reason %d\n", 1957 IPW_ERROR("Failed to send %s: Reason %d\n",
@@ -1942,61 +1994,62 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1942 return rc; 1994 return rc;
1943} 1995}
1944 1996
1945static int ipw_send_host_complete(struct ipw_priv *priv) 1997static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command)
1998{
1999 struct host_cmd cmd = {
2000 .cmd = command,
2001 };
2002
2003 return __ipw_send_cmd(priv, &cmd);
2004}
2005
2006static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len,
2007 void *data)
1946{ 2008{
1947 struct host_cmd cmd = { 2009 struct host_cmd cmd = {
1948 .cmd = IPW_CMD_HOST_COMPLETE, 2010 .cmd = command,
1949 .len = 0 2011 .len = len,
2012 .param = data,
1950 }; 2013 };
1951 2014
2015 return __ipw_send_cmd(priv, &cmd);
2016}
2017
2018static int ipw_send_host_complete(struct ipw_priv *priv)
2019{
1952 if (!priv) { 2020 if (!priv) {
1953 IPW_ERROR("Invalid args\n"); 2021 IPW_ERROR("Invalid args\n");
1954 return -1; 2022 return -1;
1955 } 2023 }
1956 2024
1957 return ipw_send_cmd(priv, &cmd); 2025 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
1958} 2026}
1959 2027
1960static int ipw_send_system_config(struct ipw_priv *priv, 2028static int ipw_send_system_config(struct ipw_priv *priv,
1961 struct ipw_sys_config *config) 2029 struct ipw_sys_config *config)
1962{ 2030{
1963 struct host_cmd cmd = {
1964 .cmd = IPW_CMD_SYSTEM_CONFIG,
1965 .len = sizeof(*config)
1966 };
1967
1968 if (!priv || !config) { 2031 if (!priv || !config) {
1969 IPW_ERROR("Invalid args\n"); 2032 IPW_ERROR("Invalid args\n");
1970 return -1; 2033 return -1;
1971 } 2034 }
1972 2035
1973 memcpy(cmd.param, config, sizeof(*config)); 2036 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config),
1974 return ipw_send_cmd(priv, &cmd); 2037 config);
1975} 2038}
1976 2039
1977static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) 2040static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
1978{ 2041{
1979 struct host_cmd cmd = {
1980 .cmd = IPW_CMD_SSID,
1981 .len = min(len, IW_ESSID_MAX_SIZE)
1982 };
1983
1984 if (!priv || !ssid) { 2042 if (!priv || !ssid) {
1985 IPW_ERROR("Invalid args\n"); 2043 IPW_ERROR("Invalid args\n");
1986 return -1; 2044 return -1;
1987 } 2045 }
1988 2046
1989 memcpy(cmd.param, ssid, cmd.len); 2047 return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE),
1990 return ipw_send_cmd(priv, &cmd); 2048 ssid);
1991} 2049}
1992 2050
1993static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) 2051static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
1994{ 2052{
1995 struct host_cmd cmd = {
1996 .cmd = IPW_CMD_ADAPTER_ADDRESS,
1997 .len = ETH_ALEN
1998 };
1999
2000 if (!priv || !mac) { 2053 if (!priv || !mac) {
2001 IPW_ERROR("Invalid args\n"); 2054 IPW_ERROR("Invalid args\n");
2002 return -1; 2055 return -1;
@@ -2005,8 +2058,7 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
2005 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", 2058 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
2006 priv->net_dev->name, MAC_ARG(mac)); 2059 priv->net_dev->name, MAC_ARG(mac));
2007 2060
2008 memcpy(cmd.param, mac, ETH_ALEN); 2061 return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
2009 return ipw_send_cmd(priv, &cmd);
2010} 2062}
2011 2063
2012/* 2064/*
@@ -2036,9 +2088,9 @@ static void ipw_adapter_restart(void *adapter)
2036static void ipw_bg_adapter_restart(void *data) 2088static void ipw_bg_adapter_restart(void *data)
2037{ 2089{
2038 struct ipw_priv *priv = data; 2090 struct ipw_priv *priv = data;
2039 down(&priv->sem); 2091 mutex_lock(&priv->mutex);
2040 ipw_adapter_restart(data); 2092 ipw_adapter_restart(data);
2041 up(&priv->sem); 2093 mutex_unlock(&priv->mutex);
2042} 2094}
2043 2095
2044#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) 2096#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
@@ -2048,8 +2100,8 @@ static void ipw_scan_check(void *data)
2048 struct ipw_priv *priv = data; 2100 struct ipw_priv *priv = data;
2049 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { 2101 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
2050 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 2102 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
2051 "adapter (%dms).\n", 2103 "adapter after (%dms).\n",
2052 IPW_SCAN_CHECK_WATCHDOG / 100); 2104 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2053 queue_work(priv->workqueue, &priv->adapter_restart); 2105 queue_work(priv->workqueue, &priv->adapter_restart);
2054 } 2106 }
2055} 2107}
@@ -2057,59 +2109,48 @@ static void ipw_scan_check(void *data)
2057static void ipw_bg_scan_check(void *data) 2109static void ipw_bg_scan_check(void *data)
2058{ 2110{
2059 struct ipw_priv *priv = data; 2111 struct ipw_priv *priv = data;
2060 down(&priv->sem); 2112 mutex_lock(&priv->mutex);
2061 ipw_scan_check(data); 2113 ipw_scan_check(data);
2062 up(&priv->sem); 2114 mutex_unlock(&priv->mutex);
2063} 2115}
2064 2116
2065static int ipw_send_scan_request_ext(struct ipw_priv *priv, 2117static int ipw_send_scan_request_ext(struct ipw_priv *priv,
2066 struct ipw_scan_request_ext *request) 2118 struct ipw_scan_request_ext *request)
2067{ 2119{
2068 struct host_cmd cmd = { 2120 return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT,
2069 .cmd = IPW_CMD_SCAN_REQUEST_EXT, 2121 sizeof(*request), request);
2070 .len = sizeof(*request)
2071 };
2072
2073 memcpy(cmd.param, request, sizeof(*request));
2074 return ipw_send_cmd(priv, &cmd);
2075} 2122}
2076 2123
2077static int ipw_send_scan_abort(struct ipw_priv *priv) 2124static int ipw_send_scan_abort(struct ipw_priv *priv)
2078{ 2125{
2079 struct host_cmd cmd = {
2080 .cmd = IPW_CMD_SCAN_ABORT,
2081 .len = 0
2082 };
2083
2084 if (!priv) { 2126 if (!priv) {
2085 IPW_ERROR("Invalid args\n"); 2127 IPW_ERROR("Invalid args\n");
2086 return -1; 2128 return -1;
2087 } 2129 }
2088 2130
2089 return ipw_send_cmd(priv, &cmd); 2131 return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT);
2090} 2132}
2091 2133
2092static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) 2134static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
2093{ 2135{
2094 struct host_cmd cmd = { 2136 struct ipw_sensitivity_calib calib = {
2095 .cmd = IPW_CMD_SENSITIVITY_CALIB, 2137 .beacon_rssi_raw = sens,
2096 .len = sizeof(struct ipw_sensitivity_calib)
2097 }; 2138 };
2098 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) 2139
2099 &cmd.param; 2140 return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),
2100 calib->beacon_rssi_raw = sens; 2141 &calib);
2101 return ipw_send_cmd(priv, &cmd);
2102} 2142}
2103 2143
2104static int ipw_send_associate(struct ipw_priv *priv, 2144static int ipw_send_associate(struct ipw_priv *priv,
2105 struct ipw_associate *associate) 2145 struct ipw_associate *associate)
2106{ 2146{
2107 struct host_cmd cmd = {
2108 .cmd = IPW_CMD_ASSOCIATE,
2109 .len = sizeof(*associate)
2110 };
2111
2112 struct ipw_associate tmp_associate; 2147 struct ipw_associate tmp_associate;
2148
2149 if (!priv || !associate) {
2150 IPW_ERROR("Invalid args\n");
2151 return -1;
2152 }
2153
2113 memcpy(&tmp_associate, associate, sizeof(*associate)); 2154 memcpy(&tmp_associate, associate, sizeof(*associate));
2114 tmp_associate.policy_support = 2155 tmp_associate.policy_support =
2115 cpu_to_le16(tmp_associate.policy_support); 2156 cpu_to_le16(tmp_associate.policy_support);
@@ -2122,85 +2163,60 @@ static int ipw_send_associate(struct ipw_priv *priv,
2122 cpu_to_le16(tmp_associate.beacon_interval); 2163 cpu_to_le16(tmp_associate.beacon_interval);
2123 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window); 2164 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
2124 2165
2125 if (!priv || !associate) { 2166 return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate),
2126 IPW_ERROR("Invalid args\n"); 2167 &tmp_associate);
2127 return -1;
2128 }
2129
2130 memcpy(cmd.param, &tmp_associate, sizeof(*associate));
2131 return ipw_send_cmd(priv, &cmd);
2132} 2168}
2133 2169
2134static int ipw_send_supported_rates(struct ipw_priv *priv, 2170static int ipw_send_supported_rates(struct ipw_priv *priv,
2135 struct ipw_supported_rates *rates) 2171 struct ipw_supported_rates *rates)
2136{ 2172{
2137 struct host_cmd cmd = {
2138 .cmd = IPW_CMD_SUPPORTED_RATES,
2139 .len = sizeof(*rates)
2140 };
2141
2142 if (!priv || !rates) { 2173 if (!priv || !rates) {
2143 IPW_ERROR("Invalid args\n"); 2174 IPW_ERROR("Invalid args\n");
2144 return -1; 2175 return -1;
2145 } 2176 }
2146 2177
2147 memcpy(cmd.param, rates, sizeof(*rates)); 2178 return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates),
2148 return ipw_send_cmd(priv, &cmd); 2179 rates);
2149} 2180}
2150 2181
2151static int ipw_set_random_seed(struct ipw_priv *priv) 2182static int ipw_set_random_seed(struct ipw_priv *priv)
2152{ 2183{
2153 struct host_cmd cmd = { 2184 u32 val;
2154 .cmd = IPW_CMD_SEED_NUMBER,
2155 .len = sizeof(u32)
2156 };
2157 2185
2158 if (!priv) { 2186 if (!priv) {
2159 IPW_ERROR("Invalid args\n"); 2187 IPW_ERROR("Invalid args\n");
2160 return -1; 2188 return -1;
2161 } 2189 }
2162 2190
2163 get_random_bytes(&cmd.param, sizeof(u32)); 2191 get_random_bytes(&val, sizeof(val));
2164 2192
2165 return ipw_send_cmd(priv, &cmd); 2193 return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val);
2166} 2194}
2167 2195
2168static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) 2196static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
2169{ 2197{
2170 struct host_cmd cmd = {
2171 .cmd = IPW_CMD_CARD_DISABLE,
2172 .len = sizeof(u32)
2173 };
2174
2175 if (!priv) { 2198 if (!priv) {
2176 IPW_ERROR("Invalid args\n"); 2199 IPW_ERROR("Invalid args\n");
2177 return -1; 2200 return -1;
2178 } 2201 }
2179 2202
2180 *((u32 *) & cmd.param) = phy_off; 2203 return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off),
2181 2204 &phy_off);
2182 return ipw_send_cmd(priv, &cmd);
2183} 2205}
2184 2206
2185static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) 2207static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
2186{ 2208{
2187 struct host_cmd cmd = {
2188 .cmd = IPW_CMD_TX_POWER,
2189 .len = sizeof(*power)
2190 };
2191
2192 if (!priv || !power) { 2209 if (!priv || !power) {
2193 IPW_ERROR("Invalid args\n"); 2210 IPW_ERROR("Invalid args\n");
2194 return -1; 2211 return -1;
2195 } 2212 }
2196 2213
2197 memcpy(cmd.param, power, sizeof(*power)); 2214 return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power);
2198 return ipw_send_cmd(priv, &cmd);
2199} 2215}
2200 2216
2201static int ipw_set_tx_power(struct ipw_priv *priv) 2217static int ipw_set_tx_power(struct ipw_priv *priv)
2202{ 2218{
2203 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 2219 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
2204 struct ipw_tx_power tx_power; 2220 struct ipw_tx_power tx_power;
2205 s8 max_power; 2221 s8 max_power;
2206 int i; 2222 int i;
@@ -2247,18 +2263,14 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2247 struct ipw_rts_threshold rts_threshold = { 2263 struct ipw_rts_threshold rts_threshold = {
2248 .rts_threshold = rts, 2264 .rts_threshold = rts,
2249 }; 2265 };
2250 struct host_cmd cmd = {
2251 .cmd = IPW_CMD_RTS_THRESHOLD,
2252 .len = sizeof(rts_threshold)
2253 };
2254 2266
2255 if (!priv) { 2267 if (!priv) {
2256 IPW_ERROR("Invalid args\n"); 2268 IPW_ERROR("Invalid args\n");
2257 return -1; 2269 return -1;
2258 } 2270 }
2259 2271
2260 memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold)); 2272 return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD,
2261 return ipw_send_cmd(priv, &cmd); 2273 sizeof(rts_threshold), &rts_threshold);
2262} 2274}
2263 2275
2264static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) 2276static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -2266,27 +2278,19 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
2266 struct ipw_frag_threshold frag_threshold = { 2278 struct ipw_frag_threshold frag_threshold = {
2267 .frag_threshold = frag, 2279 .frag_threshold = frag,
2268 }; 2280 };
2269 struct host_cmd cmd = {
2270 .cmd = IPW_CMD_FRAG_THRESHOLD,
2271 .len = sizeof(frag_threshold)
2272 };
2273 2281
2274 if (!priv) { 2282 if (!priv) {
2275 IPW_ERROR("Invalid args\n"); 2283 IPW_ERROR("Invalid args\n");
2276 return -1; 2284 return -1;
2277 } 2285 }
2278 2286
2279 memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold)); 2287 return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD,
2280 return ipw_send_cmd(priv, &cmd); 2288 sizeof(frag_threshold), &frag_threshold);
2281} 2289}
2282 2290
2283static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) 2291static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2284{ 2292{
2285 struct host_cmd cmd = { 2293 u32 param;
2286 .cmd = IPW_CMD_POWER_MODE,
2287 .len = sizeof(u32)
2288 };
2289 u32 *param = (u32 *) (&cmd.param);
2290 2294
2291 if (!priv) { 2295 if (!priv) {
2292 IPW_ERROR("Invalid args\n"); 2296 IPW_ERROR("Invalid args\n");
@@ -2297,17 +2301,18 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2297 * level */ 2301 * level */
2298 switch (mode) { 2302 switch (mode) {
2299 case IPW_POWER_BATTERY: 2303 case IPW_POWER_BATTERY:
2300 *param = IPW_POWER_INDEX_3; 2304 param = IPW_POWER_INDEX_3;
2301 break; 2305 break;
2302 case IPW_POWER_AC: 2306 case IPW_POWER_AC:
2303 *param = IPW_POWER_MODE_CAM; 2307 param = IPW_POWER_MODE_CAM;
2304 break; 2308 break;
2305 default: 2309 default:
2306 *param = mode; 2310 param = mode;
2307 break; 2311 break;
2308 } 2312 }
2309 2313
2310 return ipw_send_cmd(priv, &cmd); 2314 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
2315 &param);
2311} 2316}
2312 2317
2313static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit) 2318static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
@@ -2316,18 +2321,14 @@ static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2316 .short_retry_limit = slimit, 2321 .short_retry_limit = slimit,
2317 .long_retry_limit = llimit 2322 .long_retry_limit = llimit
2318 }; 2323 };
2319 struct host_cmd cmd = {
2320 .cmd = IPW_CMD_RETRY_LIMIT,
2321 .len = sizeof(retry_limit)
2322 };
2323 2324
2324 if (!priv) { 2325 if (!priv) {
2325 IPW_ERROR("Invalid args\n"); 2326 IPW_ERROR("Invalid args\n");
2326 return -1; 2327 return -1;
2327 } 2328 }
2328 2329
2329 memcpy(cmd.param, &retry_limit, sizeof(retry_limit)); 2330 return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit),
2330 return ipw_send_cmd(priv, &cmd); 2331 &retry_limit);
2331} 2332}
2332 2333
2333/* 2334/*
@@ -2454,7 +2455,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
2454 /* 2455 /*
2455 If the data looks correct, then copy it to our private 2456 If the data looks correct, then copy it to our private
2456 copy. Otherwise let the firmware know to perform the operation 2457 copy. Otherwise let the firmware know to perform the operation
2457 on it's own 2458 on its own.
2458 */ 2459 */
2459 if (priv->eeprom[EEPROM_VERSION] != 0) { 2460 if (priv->eeprom[EEPROM_VERSION] != 0) {
2460 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); 2461 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
@@ -2707,22 +2708,25 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv,
2707 2708
2708static int ipw_fw_dma_wait(struct ipw_priv *priv) 2709static int ipw_fw_dma_wait(struct ipw_priv *priv)
2709{ 2710{
2710 u32 current_index = 0; 2711 u32 current_index = 0, previous_index;
2711 u32 watchdog = 0; 2712 u32 watchdog = 0;
2712 2713
2713 IPW_DEBUG_FW(">> : \n"); 2714 IPW_DEBUG_FW(">> : \n");
2714 2715
2715 current_index = ipw_fw_dma_command_block_index(priv); 2716 current_index = ipw_fw_dma_command_block_index(priv);
2716 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", 2717 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
2717 (int)priv->sram_desc.last_cb_index); 2718 (int)priv->sram_desc.last_cb_index);
2718 2719
2719 while (current_index < priv->sram_desc.last_cb_index) { 2720 while (current_index < priv->sram_desc.last_cb_index) {
2720 udelay(50); 2721 udelay(50);
2722 previous_index = current_index;
2721 current_index = ipw_fw_dma_command_block_index(priv); 2723 current_index = ipw_fw_dma_command_block_index(priv);
2722 2724
2723 watchdog++; 2725 if (previous_index < current_index) {
2724 2726 watchdog = 0;
2725 if (watchdog > 400) { 2727 continue;
2728 }
2729 if (++watchdog > 400) {
2726 IPW_DEBUG_FW_INFO("Timeout\n"); 2730 IPW_DEBUG_FW_INFO("Timeout\n");
2727 ipw_fw_dma_dump_command_block(priv); 2731 ipw_fw_dma_dump_command_block(priv);
2728 ipw_fw_dma_abort(priv); 2732 ipw_fw_dma_abort(priv);
@@ -2772,6 +2776,7 @@ static inline int ipw_alive(struct ipw_priv *priv)
2772 return ipw_read32(priv, 0x90) == 0xd55555d5; 2776 return ipw_read32(priv, 0x90) == 0xd55555d5;
2773} 2777}
2774 2778
2779/* timeout in msec, attempted in 10-msec quanta */
2775static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, 2780static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
2776 int timeout) 2781 int timeout)
2777{ 2782{
@@ -2800,10 +2805,11 @@ static int ipw_stop_master(struct ipw_priv *priv)
2800 /* stop master. typical delay - 0 */ 2805 /* stop master. typical delay - 0 */
2801 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER); 2806 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2802 2807
2808 /* timeout is in msec, polled in 10-msec quanta */
2803 rc = ipw_poll_bit(priv, IPW_RESET_REG, 2809 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2804 IPW_RESET_REG_MASTER_DISABLED, 100); 2810 IPW_RESET_REG_MASTER_DISABLED, 100);
2805 if (rc < 0) { 2811 if (rc < 0) {
2806 IPW_ERROR("stop master failed in 10ms\n"); 2812 IPW_ERROR("wait for stop master failed after 100ms\n");
2807 return -1; 2813 return -1;
2808 } 2814 }
2809 2815
@@ -2823,33 +2829,11 @@ static void ipw_arc_release(struct ipw_priv *priv)
2823 mdelay(5); 2829 mdelay(5);
2824} 2830}
2825 2831
2826struct fw_header {
2827 u32 version;
2828 u32 mode;
2829};
2830
2831struct fw_chunk { 2832struct fw_chunk {
2832 u32 address; 2833 u32 address;
2833 u32 length; 2834 u32 length;
2834}; 2835};
2835 2836
2836#define IPW_FW_MAJOR_VERSION 2
2837#define IPW_FW_MINOR_VERSION 4
2838
2839#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2840#define IPW_FW_MAJOR(x) (x & 0xff)
2841
2842#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
2843
2844#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2845"." __stringify(IPW_FW_MINOR_VERSION) "-"
2846
2847#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
2848#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
2849#else
2850#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
2851#endif
2852
2853static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) 2837static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2854{ 2838{
2855 int rc = 0, i, addr; 2839 int rc = 0, i, addr;
@@ -2890,8 +2874,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2890 mdelay(1); 2874 mdelay(1);
2891 2875
2892 /* enable ucode store */ 2876 /* enable ucode store */
2893 ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0); 2877 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0);
2894 ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS); 2878 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS);
2895 mdelay(1); 2879 mdelay(1);
2896 2880
2897 /* write ucode */ 2881 /* write ucode */
@@ -3036,7 +3020,7 @@ static int ipw_stop_nic(struct ipw_priv *priv)
3036 rc = ipw_poll_bit(priv, IPW_RESET_REG, 3020 rc = ipw_poll_bit(priv, IPW_RESET_REG,
3037 IPW_RESET_REG_MASTER_DISABLED, 500); 3021 IPW_RESET_REG_MASTER_DISABLED, 500);
3038 if (rc < 0) { 3022 if (rc < 0) {
3039 IPW_ERROR("wait for reg master disabled failed\n"); 3023 IPW_ERROR("wait for reg master disabled failed after 500ms\n");
3040 return rc; 3024 return rc;
3041 } 3025 }
3042 3026
@@ -3118,33 +3102,47 @@ static int ipw_reset_nic(struct ipw_priv *priv)
3118 return rc; 3102 return rc;
3119} 3103}
3120 3104
3105
3106struct ipw_fw {
3107 u32 ver;
3108 u32 boot_size;
3109 u32 ucode_size;
3110 u32 fw_size;
3111 u8 data[0];
3112};
3113
3121static int ipw_get_fw(struct ipw_priv *priv, 3114static int ipw_get_fw(struct ipw_priv *priv,
3122 const struct firmware **fw, const char *name) 3115 const struct firmware **raw, const char *name)
3123{ 3116{
3124 struct fw_header *header; 3117 struct ipw_fw *fw;
3125 int rc; 3118 int rc;
3126 3119
3127 /* ask firmware_class module to get the boot firmware off disk */ 3120 /* ask firmware_class module to get the boot firmware off disk */
3128 rc = request_firmware(fw, name, &priv->pci_dev->dev); 3121 rc = request_firmware(raw, name, &priv->pci_dev->dev);
3129 if (rc < 0) { 3122 if (rc < 0) {
3130 IPW_ERROR("%s load failed: Reason %d\n", name, rc); 3123 IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc);
3131 return rc; 3124 return rc;
3132 } 3125 }
3133 3126
3134 header = (struct fw_header *)(*fw)->data; 3127 if ((*raw)->size < sizeof(*fw)) {
3135 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) { 3128 IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size);
3136 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", 3129 return -EINVAL;
3137 name, 3130 }
3138 IPW_FW_MAJOR(le32_to_cpu(header->version)), 3131
3139 IPW_FW_MAJOR_VERSION); 3132 fw = (void *)(*raw)->data;
3133
3134 if ((*raw)->size < sizeof(*fw) +
3135 fw->boot_size + fw->ucode_size + fw->fw_size) {
3136 IPW_ERROR("%s is too small or corrupt (%zd)\n",
3137 name, (*raw)->size);
3140 return -EINVAL; 3138 return -EINVAL;
3141 } 3139 }
3142 3140
3143 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", 3141 IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n",
3144 name, 3142 name,
3145 IPW_FW_MAJOR(le32_to_cpu(header->version)), 3143 le32_to_cpu(fw->ver) >> 16,
3146 IPW_FW_MINOR(le32_to_cpu(header->version)), 3144 le32_to_cpu(fw->ver) & 0xff,
3147 (*fw)->size - sizeof(struct fw_header)); 3145 (*raw)->size - sizeof(*fw));
3148 return 0; 3146 return 0;
3149} 3147}
3150 3148
@@ -3184,17 +3182,13 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
3184 3182
3185#ifdef CONFIG_PM 3183#ifdef CONFIG_PM
3186static int fw_loaded = 0; 3184static int fw_loaded = 0;
3187static const struct firmware *bootfw = NULL; 3185static const struct firmware *raw = NULL;
3188static const struct firmware *firmware = NULL;
3189static const struct firmware *ucode = NULL;
3190 3186
3191static void free_firmware(void) 3187static void free_firmware(void)
3192{ 3188{
3193 if (fw_loaded) { 3189 if (fw_loaded) {
3194 release_firmware(bootfw); 3190 release_firmware(raw);
3195 release_firmware(ucode); 3191 raw = NULL;
3196 release_firmware(firmware);
3197 bootfw = ucode = firmware = NULL;
3198 fw_loaded = 0; 3192 fw_loaded = 0;
3199 } 3193 }
3200} 3194}
@@ -3205,60 +3199,50 @@ static void free_firmware(void)
3205static int ipw_load(struct ipw_priv *priv) 3199static int ipw_load(struct ipw_priv *priv)
3206{ 3200{
3207#ifndef CONFIG_PM 3201#ifndef CONFIG_PM
3208 const struct firmware *bootfw = NULL; 3202 const struct firmware *raw = NULL;
3209 const struct firmware *firmware = NULL;
3210 const struct firmware *ucode = NULL;
3211#endif 3203#endif
3204 struct ipw_fw *fw;
3205 u8 *boot_img, *ucode_img, *fw_img;
3206 u8 *name = NULL;
3212 int rc = 0, retries = 3; 3207 int rc = 0, retries = 3;
3213 3208
3214#ifdef CONFIG_PM 3209 switch (priv->ieee->iw_mode) {
3215 if (!fw_loaded) { 3210 case IW_MODE_ADHOC:
3216#endif 3211 name = "ipw2200-ibss.fw";
3217 rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); 3212 break;
3218 if (rc)
3219 goto error;
3220
3221 switch (priv->ieee->iw_mode) {
3222 case IW_MODE_ADHOC:
3223 rc = ipw_get_fw(priv, &ucode,
3224 IPW_FW_NAME("ibss_ucode"));
3225 if (rc)
3226 goto error;
3227
3228 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
3229 break;
3230
3231#ifdef CONFIG_IPW2200_MONITOR 3213#ifdef CONFIG_IPW2200_MONITOR
3232 case IW_MODE_MONITOR: 3214 case IW_MODE_MONITOR:
3233 rc = ipw_get_fw(priv, &ucode, 3215 name = "ipw2200-sniffer.fw";
3234 IPW_FW_NAME("sniffer_ucode")); 3216 break;
3235 if (rc)
3236 goto error;
3237
3238 rc = ipw_get_fw(priv, &firmware,
3239 IPW_FW_NAME("sniffer"));
3240 break;
3241#endif 3217#endif
3242 case IW_MODE_INFRA: 3218 case IW_MODE_INFRA:
3243 rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode")); 3219 name = "ipw2200-bss.fw";
3244 if (rc) 3220 break;
3245 goto error; 3221 }
3246
3247 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss"));
3248 break;
3249 3222
3250 default: 3223 if (!name) {
3251 rc = -EINVAL; 3224 rc = -EINVAL;
3252 } 3225 goto error;
3226 }
3253 3227
3254 if (rc) 3228#ifdef CONFIG_PM
3229 if (!fw_loaded) {
3230#endif
3231 rc = ipw_get_fw(priv, &raw, name);
3232 if (rc < 0)
3255 goto error; 3233 goto error;
3256
3257#ifdef CONFIG_PM 3234#ifdef CONFIG_PM
3258 fw_loaded = 1;
3259 } 3235 }
3260#endif 3236#endif
3261 3237
3238 fw = (void *)raw->data;
3239 boot_img = &fw->data[0];
3240 ucode_img = &fw->data[fw->boot_size];
3241 fw_img = &fw->data[fw->boot_size + fw->ucode_size];
3242
3243 if (rc < 0)
3244 goto error;
3245
3262 if (!priv->rxq) 3246 if (!priv->rxq)
3263 priv->rxq = ipw_rx_queue_alloc(priv); 3247 priv->rxq = ipw_rx_queue_alloc(priv);
3264 else 3248 else
@@ -3279,7 +3263,7 @@ static int ipw_load(struct ipw_priv *priv)
3279 ipw_stop_nic(priv); 3263 ipw_stop_nic(priv);
3280 3264
3281 rc = ipw_reset_nic(priv); 3265 rc = ipw_reset_nic(priv);
3282 if (rc) { 3266 if (rc < 0) {
3283 IPW_ERROR("Unable to reset NIC\n"); 3267 IPW_ERROR("Unable to reset NIC\n");
3284 goto error; 3268 goto error;
3285 } 3269 }
@@ -3288,8 +3272,7 @@ static int ipw_load(struct ipw_priv *priv)
3288 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); 3272 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
3289 3273
3290 /* DMA the initial boot firmware into the device */ 3274 /* DMA the initial boot firmware into the device */
3291 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), 3275 rc = ipw_load_firmware(priv, boot_img, fw->boot_size);
3292 bootfw->size - sizeof(struct fw_header));
3293 if (rc < 0) { 3276 if (rc < 0) {
3294 IPW_ERROR("Unable to load boot firmware: %d\n", rc); 3277 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
3295 goto error; 3278 goto error;
@@ -3298,7 +3281,7 @@ static int ipw_load(struct ipw_priv *priv)
3298 /* kick start the device */ 3281 /* kick start the device */
3299 ipw_start_nic(priv); 3282 ipw_start_nic(priv);
3300 3283
3301 /* wait for the device to finish it's initial startup sequence */ 3284 /* wait for the device to finish its initial startup sequence */
3302 rc = ipw_poll_bit(priv, IPW_INTA_RW, 3285 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3303 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3286 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
3304 if (rc < 0) { 3287 if (rc < 0) {
@@ -3311,8 +3294,7 @@ static int ipw_load(struct ipw_priv *priv)
3311 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); 3294 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
3312 3295
3313 /* DMA the ucode into the device */ 3296 /* DMA the ucode into the device */
3314 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), 3297 rc = ipw_load_ucode(priv, ucode_img, fw->ucode_size);
3315 ucode->size - sizeof(struct fw_header));
3316 if (rc < 0) { 3298 if (rc < 0) {
3317 IPW_ERROR("Unable to load ucode: %d\n", rc); 3299 IPW_ERROR("Unable to load ucode: %d\n", rc);
3318 goto error; 3300 goto error;
@@ -3322,18 +3304,19 @@ static int ipw_load(struct ipw_priv *priv)
3322 ipw_stop_nic(priv); 3304 ipw_stop_nic(priv);
3323 3305
3324 /* DMA bss firmware into the device */ 3306 /* DMA bss firmware into the device */
3325 rc = ipw_load_firmware(priv, firmware->data + 3307 rc = ipw_load_firmware(priv, fw_img, fw->fw_size);
3326 sizeof(struct fw_header),
3327 firmware->size - sizeof(struct fw_header));
3328 if (rc < 0) { 3308 if (rc < 0) {
3329 IPW_ERROR("Unable to load firmware: %d\n", rc); 3309 IPW_ERROR("Unable to load firmware: %d\n", rc);
3330 goto error; 3310 goto error;
3331 } 3311 }
3312#ifdef CONFIG_PM
3313 fw_loaded = 1;
3314#endif
3332 3315
3333 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0); 3316 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
3334 3317
3335 rc = ipw_queue_reset(priv); 3318 rc = ipw_queue_reset(priv);
3336 if (rc) { 3319 if (rc < 0) {
3337 IPW_ERROR("Unable to initialize queues\n"); 3320 IPW_ERROR("Unable to initialize queues\n");
3338 goto error; 3321 goto error;
3339 } 3322 }
@@ -3362,7 +3345,7 @@ static int ipw_load(struct ipw_priv *priv)
3362 rc = ipw_poll_bit(priv, IPW_INTA_RW, 3345 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3363 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3346 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
3364 if (rc < 0) { 3347 if (rc < 0) {
3365 IPW_ERROR("device failed to start after 500ms\n"); 3348 IPW_ERROR("device failed to start within 500ms\n");
3366 goto error; 3349 goto error;
3367 } 3350 }
3368 IPW_DEBUG_INFO("device response after %dms\n", rc); 3351 IPW_DEBUG_INFO("device response after %dms\n", rc);
@@ -3386,9 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
3386 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL); 3369 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3387 3370
3388#ifndef CONFIG_PM 3371#ifndef CONFIG_PM
3389 release_firmware(bootfw); 3372 release_firmware(raw);
3390 release_firmware(ucode);
3391 release_firmware(firmware);
3392#endif 3373#endif
3393 return 0; 3374 return 0;
3394 3375
@@ -3398,15 +3379,11 @@ static int ipw_load(struct ipw_priv *priv)
3398 priv->rxq = NULL; 3379 priv->rxq = NULL;
3399 } 3380 }
3400 ipw_tx_queue_free(priv); 3381 ipw_tx_queue_free(priv);
3401 if (bootfw) 3382 if (raw)
3402 release_firmware(bootfw); 3383 release_firmware(raw);
3403 if (ucode)
3404 release_firmware(ucode);
3405 if (firmware)
3406 release_firmware(firmware);
3407#ifdef CONFIG_PM 3384#ifdef CONFIG_PM
3408 fw_loaded = 0; 3385 fw_loaded = 0;
3409 bootfw = ucode = firmware = NULL; 3386 raw = NULL;
3410#endif 3387#endif
3411 3388
3412 return rc; 3389 return rc;
@@ -3715,9 +3692,9 @@ static int ipw_disassociate(void *data)
3715static void ipw_bg_disassociate(void *data) 3692static void ipw_bg_disassociate(void *data)
3716{ 3693{
3717 struct ipw_priv *priv = data; 3694 struct ipw_priv *priv = data;
3718 down(&priv->sem); 3695 mutex_lock(&priv->mutex);
3719 ipw_disassociate(data); 3696 ipw_disassociate(data);
3720 up(&priv->sem); 3697 mutex_unlock(&priv->mutex);
3721} 3698}
3722 3699
3723static void ipw_system_config(void *data) 3700static void ipw_system_config(void *data)
@@ -4077,9 +4054,9 @@ static void ipw_gather_stats(struct ipw_priv *priv)
4077static void ipw_bg_gather_stats(void *data) 4054static void ipw_bg_gather_stats(void *data)
4078{ 4055{
4079 struct ipw_priv *priv = data; 4056 struct ipw_priv *priv = data;
4080 down(&priv->sem); 4057 mutex_lock(&priv->mutex);
4081 ipw_gather_stats(data); 4058 ipw_gather_stats(data);
4082 up(&priv->sem); 4059 mutex_unlock(&priv->mutex);
4083} 4060}
4084 4061
4085/* Missed beacon behavior: 4062/* Missed beacon behavior:
@@ -4121,8 +4098,9 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
4121 return; 4098 return;
4122 } 4099 }
4123 4100
4124 if (missed_count > priv->roaming_threshold && 4101 if (roaming &&
4125 missed_count <= priv->disassociate_threshold) { 4102 (missed_count > priv->roaming_threshold &&
4103 missed_count <= priv->disassociate_threshold)) {
4126 /* If we are not already roaming, set the ROAM 4104 /* If we are not already roaming, set the ROAM
4127 * bit in the status and kick off a scan. 4105 * bit in the status and kick off a scan.
4128 * This can happen several times before we reach 4106 * This can happen several times before we reach
@@ -4150,7 +4128,6 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
4150 } 4128 }
4151 4129
4152 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count); 4130 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4153
4154} 4131}
4155 4132
4156/** 4133/**
@@ -4527,10 +4504,9 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4527 4504
4528 if (notif->size == sizeof(*x)) { 4505 if (notif->size == sizeof(*x)) {
4529 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4506 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4530 "link deterioration: '%s' " MAC_FMT 4507 "link deterioration: type %d, cnt %d\n",
4531 " \n", escape_essid(priv->essid, 4508 x->silence_notification_type,
4532 priv->essid_len), 4509 x->silence_count);
4533 MAC_ARG(priv->bssid));
4534 memcpy(&priv->last_link_deterioration, x, 4510 memcpy(&priv->last_link_deterioration, x,
4535 sizeof(*x)); 4511 sizeof(*x));
4536 } else { 4512 } else {
@@ -4911,13 +4887,13 @@ static void ipw_rx_queue_replenish(void *data)
4911static void ipw_bg_rx_queue_replenish(void *data) 4887static void ipw_bg_rx_queue_replenish(void *data)
4912{ 4888{
4913 struct ipw_priv *priv = data; 4889 struct ipw_priv *priv = data;
4914 down(&priv->sem); 4890 mutex_lock(&priv->mutex);
4915 ipw_rx_queue_replenish(data); 4891 ipw_rx_queue_replenish(data);
4916 up(&priv->sem); 4892 mutex_unlock(&priv->mutex);
4917} 4893}
4918 4894
4919/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 4895/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4920 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL 4896 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
4921 * This free routine walks the list of POOL entries and if SKB is set to 4897 * This free routine walks the list of POOL entries and if SKB is set to
4922 * non NULL it is unmapped and freed 4898 * non NULL it is unmapped and freed
4923 */ 4899 */
@@ -5257,10 +5233,11 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
5257 if (priv->ieee->scan_age != 0 && 5233 if (priv->ieee->scan_age != 0 &&
5258 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { 5234 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5259 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " 5235 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5260 "because of age: %lums.\n", 5236 "because of age: %ums.\n",
5261 escape_essid(network->ssid, network->ssid_len), 5237 escape_essid(network->ssid, network->ssid_len),
5262 MAC_ARG(network->bssid), 5238 MAC_ARG(network->bssid),
5263 1000 * (jiffies - network->last_scanned) / HZ); 5239 jiffies_to_msecs(jiffies -
5240 network->last_scanned));
5264 return 0; 5241 return 0;
5265 } 5242 }
5266 5243
@@ -5369,7 +5346,7 @@ static void ipw_merge_adhoc_network(void *data)
5369 return; 5346 return;
5370 } 5347 }
5371 5348
5372 down(&priv->sem); 5349 mutex_lock(&priv->mutex);
5373 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { 5350 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5374 IPW_DEBUG_MERGE("remove network %s\n", 5351 IPW_DEBUG_MERGE("remove network %s\n",
5375 escape_essid(priv->essid, 5352 escape_essid(priv->essid,
@@ -5379,7 +5356,7 @@ static void ipw_merge_adhoc_network(void *data)
5379 5356
5380 ipw_disassociate(priv); 5357 ipw_disassociate(priv);
5381 priv->assoc_network = match.network; 5358 priv->assoc_network = match.network;
5382 up(&priv->sem); 5359 mutex_unlock(&priv->mutex);
5383 return; 5360 return;
5384 } 5361 }
5385} 5362}
@@ -5467,11 +5444,12 @@ static int ipw_best_network(struct ipw_priv *priv,
5467 if (network->last_associate && 5444 if (network->last_associate &&
5468 time_after(network->last_associate + (HZ * 3UL), jiffies)) { 5445 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
5469 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5446 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5470 "because of storming (%lus since last " 5447 "because of storming (%ums since last "
5471 "assoc attempt).\n", 5448 "assoc attempt).\n",
5472 escape_essid(network->ssid, network->ssid_len), 5449 escape_essid(network->ssid, network->ssid_len),
5473 MAC_ARG(network->bssid), 5450 MAC_ARG(network->bssid),
5474 (jiffies - network->last_associate) / HZ); 5451 jiffies_to_msecs(jiffies -
5452 network->last_associate));
5475 return 0; 5453 return 0;
5476 } 5454 }
5477 5455
@@ -5479,10 +5457,11 @@ static int ipw_best_network(struct ipw_priv *priv,
5479 if (priv->ieee->scan_age != 0 && 5457 if (priv->ieee->scan_age != 0 &&
5480 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { 5458 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5481 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5459 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5482 "because of age: %lums.\n", 5460 "because of age: %ums.\n",
5483 escape_essid(network->ssid, network->ssid_len), 5461 escape_essid(network->ssid, network->ssid_len),
5484 MAC_ARG(network->bssid), 5462 MAC_ARG(network->bssid),
5485 1000 * (jiffies - network->last_scanned) / HZ); 5463 jiffies_to_msecs(jiffies -
5464 network->last_scanned));
5486 return 0; 5465 return 0;
5487 } 5466 }
5488 5467
@@ -5510,15 +5489,6 @@ static int ipw_best_network(struct ipw_priv *priv,
5510 return 0; 5489 return 0;
5511 } 5490 }
5512 5491
5513 if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
5514 network->rsn_ie_len > 0)) {
5515 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5516 "because of WPA capability mismatch.\n",
5517 escape_essid(network->ssid, network->ssid_len),
5518 MAC_ARG(network->bssid));
5519 return 0;
5520 }
5521
5522 if ((priv->config & CFG_STATIC_BSSID) && 5492 if ((priv->config & CFG_STATIC_BSSID) &&
5523 memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5493 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5524 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5494 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -5539,7 +5509,7 @@ static int ipw_best_network(struct ipw_priv *priv,
5539 } 5509 }
5540 5510
5541 /* Filter out invalid channel in current GEO */ 5511 /* Filter out invalid channel in current GEO */
5542 if (!ipw_is_valid_channel(priv->ieee, network->channel)) { 5512 if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) {
5543 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5513 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5544 "because of invalid channel in current GEO\n", 5514 "because of invalid channel in current GEO\n",
5545 escape_essid(network->ssid, network->ssid_len), 5515 escape_essid(network->ssid, network->ssid_len),
@@ -5584,7 +5554,7 @@ static int ipw_best_network(struct ipw_priv *priv,
5584static void ipw_adhoc_create(struct ipw_priv *priv, 5554static void ipw_adhoc_create(struct ipw_priv *priv,
5585 struct ieee80211_network *network) 5555 struct ieee80211_network *network)
5586{ 5556{
5587 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 5557 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
5588 int i; 5558 int i;
5589 5559
5590 /* 5560 /*
@@ -5599,10 +5569,10 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
5599 * FW fatal error. 5569 * FW fatal error.
5600 * 5570 *
5601 */ 5571 */
5602 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { 5572 switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
5603 case IEEE80211_52GHZ_BAND: 5573 case IEEE80211_52GHZ_BAND:
5604 network->mode = IEEE_A; 5574 network->mode = IEEE_A;
5605 i = ipw_channel_to_index(priv->ieee, priv->channel); 5575 i = ieee80211_channel_to_index(priv->ieee, priv->channel);
5606 if (i == -1) 5576 if (i == -1)
5607 BUG(); 5577 BUG();
5608 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) { 5578 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
@@ -5616,7 +5586,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
5616 network->mode = IEEE_G; 5586 network->mode = IEEE_G;
5617 else 5587 else
5618 network->mode = IEEE_B; 5588 network->mode = IEEE_B;
5619 i = ipw_channel_to_index(priv->ieee, priv->channel); 5589 i = ieee80211_channel_to_index(priv->ieee, priv->channel);
5620 if (i == -1) 5590 if (i == -1)
5621 BUG(); 5591 BUG();
5622 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) { 5592 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
@@ -5671,54 +5641,44 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
5671 5641
5672static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index) 5642static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5673{ 5643{
5674 struct ipw_tgi_tx_key *key; 5644 struct ipw_tgi_tx_key key;
5675 struct host_cmd cmd = {
5676 .cmd = IPW_CMD_TGI_TX_KEY,
5677 .len = sizeof(*key)
5678 };
5679 5645
5680 if (!(priv->ieee->sec.flags & (1 << index))) 5646 if (!(priv->ieee->sec.flags & (1 << index)))
5681 return; 5647 return;
5682 5648
5683 key = (struct ipw_tgi_tx_key *)&cmd.param; 5649 key.key_id = index;
5684 key->key_id = index; 5650 memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5685 memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH); 5651 key.security_type = type;
5686 key->security_type = type; 5652 key.station_index = 0; /* always 0 for BSS */
5687 key->station_index = 0; /* always 0 for BSS */ 5653 key.flags = 0;
5688 key->flags = 0;
5689 /* 0 for new key; previous value of counter (after fatal error) */ 5654 /* 0 for new key; previous value of counter (after fatal error) */
5690 key->tx_counter[0] = 0; 5655 key.tx_counter[0] = 0;
5691 key->tx_counter[1] = 0; 5656 key.tx_counter[1] = 0;
5692 5657
5693 ipw_send_cmd(priv, &cmd); 5658 ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key);
5694} 5659}
5695 5660
5696static void ipw_send_wep_keys(struct ipw_priv *priv, int type) 5661static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
5697{ 5662{
5698 struct ipw_wep_key *key; 5663 struct ipw_wep_key key;
5699 int i; 5664 int i;
5700 struct host_cmd cmd = {
5701 .cmd = IPW_CMD_WEP_KEY,
5702 .len = sizeof(*key)
5703 };
5704 5665
5705 key = (struct ipw_wep_key *)&cmd.param; 5666 key.cmd_id = DINO_CMD_WEP_KEY;
5706 key->cmd_id = DINO_CMD_WEP_KEY; 5667 key.seq_num = 0;
5707 key->seq_num = 0;
5708 5668
5709 /* Note: AES keys cannot be set for multiple times. 5669 /* Note: AES keys cannot be set for multiple times.
5710 * Only set it at the first time. */ 5670 * Only set it at the first time. */
5711 for (i = 0; i < 4; i++) { 5671 for (i = 0; i < 4; i++) {
5712 key->key_index = i | type; 5672 key.key_index = i | type;
5713 if (!(priv->ieee->sec.flags & (1 << i))) { 5673 if (!(priv->ieee->sec.flags & (1 << i))) {
5714 key->key_size = 0; 5674 key.key_size = 0;
5715 continue; 5675 continue;
5716 } 5676 }
5717 5677
5718 key->key_size = priv->ieee->sec.key_sizes[i]; 5678 key.key_size = priv->ieee->sec.key_sizes[i];
5719 memcpy(key->key, priv->ieee->sec.keys[i], key->key_size); 5679 memcpy(key.key, priv->ieee->sec.keys[i], key.key_size);
5720 5680
5721 ipw_send_cmd(priv, &cmd); 5681 ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key);
5722 } 5682 }
5723} 5683}
5724 5684
@@ -5822,9 +5782,9 @@ static void ipw_adhoc_check(void *data)
5822static void ipw_bg_adhoc_check(void *data) 5782static void ipw_bg_adhoc_check(void *data)
5823{ 5783{
5824 struct ipw_priv *priv = data; 5784 struct ipw_priv *priv = data;
5825 down(&priv->sem); 5785 mutex_lock(&priv->mutex);
5826 ipw_adhoc_check(data); 5786 ipw_adhoc_check(data);
5827 up(&priv->sem); 5787 mutex_unlock(&priv->mutex);
5828} 5788}
5829 5789
5830#ifdef CONFIG_IPW2200_DEBUG 5790#ifdef CONFIG_IPW2200_DEBUG
@@ -5950,7 +5910,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
5950 const struct ieee80211_geo *geo; 5910 const struct ieee80211_geo *geo;
5951 int i; 5911 int i;
5952 5912
5953 geo = ipw_get_geo(priv->ieee); 5913 geo = ieee80211_get_geo(priv->ieee);
5954 5914
5955 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { 5915 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5956 int start = channel_index; 5916 int start = channel_index;
@@ -6010,7 +5970,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
6010 channel_index++; 5970 channel_index++;
6011 scan->channels_list[channel_index] = channel; 5971 scan->channels_list[channel_index] = channel;
6012 index = 5972 index =
6013 ipw_channel_to_index(priv->ieee, channel); 5973 ieee80211_channel_to_index(priv->ieee, channel);
6014 ipw_set_scan_type(scan, channel_index, 5974 ipw_set_scan_type(scan, channel_index,
6015 geo->bg[index]. 5975 geo->bg[index].
6016 flags & 5976 flags &
@@ -6051,7 +6011,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
6051 (priv->status & STATUS_EXIT_PENDING)) 6011 (priv->status & STATUS_EXIT_PENDING))
6052 return 0; 6012 return 0;
6053 6013
6054 down(&priv->sem); 6014 mutex_lock(&priv->mutex);
6055 6015
6056 if (priv->status & STATUS_SCANNING) { 6016 if (priv->status & STATUS_SCANNING) {
6057 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n"); 6017 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
@@ -6092,7 +6052,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
6092 u8 channel; 6052 u8 channel;
6093 u8 band = 0; 6053 u8 band = 0;
6094 6054
6095 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { 6055 switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
6096 case IEEE80211_52GHZ_BAND: 6056 case IEEE80211_52GHZ_BAND:
6097 band = (u8) (IPW_A_MODE << 6) | 1; 6057 band = (u8) (IPW_A_MODE << 6) | 1;
6098 channel = priv->channel; 6058 channel = priv->channel;
@@ -6159,16 +6119,16 @@ static int ipw_request_scan(struct ipw_priv *priv)
6159 queue_delayed_work(priv->workqueue, &priv->scan_check, 6119 queue_delayed_work(priv->workqueue, &priv->scan_check,
6160 IPW_SCAN_CHECK_WATCHDOG); 6120 IPW_SCAN_CHECK_WATCHDOG);
6161 done: 6121 done:
6162 up(&priv->sem); 6122 mutex_unlock(&priv->mutex);
6163 return err; 6123 return err;
6164} 6124}
6165 6125
6166static void ipw_bg_abort_scan(void *data) 6126static void ipw_bg_abort_scan(void *data)
6167{ 6127{
6168 struct ipw_priv *priv = data; 6128 struct ipw_priv *priv = data;
6169 down(&priv->sem); 6129 mutex_lock(&priv->mutex);
6170 ipw_abort_scan(data); 6130 ipw_abort_scan(data);
6171 up(&priv->sem); 6131 mutex_unlock(&priv->mutex);
6172} 6132}
6173 6133
6174static int ipw_wpa_enable(struct ipw_priv *priv, int value) 6134static int ipw_wpa_enable(struct ipw_priv *priv, int value)
@@ -6193,6 +6153,9 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6193 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) { 6153 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
6194 sec.auth_mode = WLAN_AUTH_OPEN; 6154 sec.auth_mode = WLAN_AUTH_OPEN;
6195 ieee->open_wep = 1; 6155 ieee->open_wep = 1;
6156 } else if (value & IW_AUTH_ALG_LEAP) {
6157 sec.auth_mode = WLAN_AUTH_LEAP;
6158 ieee->open_wep = 1;
6196 } else 6159 } else
6197 return -EINVAL; 6160 return -EINVAL;
6198 6161
@@ -6204,7 +6167,8 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6204 return ret; 6167 return ret;
6205} 6168}
6206 6169
6207void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len) 6170static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie,
6171 int wpa_ie_len)
6208{ 6172{
6209 /* make sure WPA is enabled */ 6173 /* make sure WPA is enabled */
6210 ipw_wpa_enable(priv, 1); 6174 ipw_wpa_enable(priv, 1);
@@ -6215,15 +6179,10 @@ void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
6215static int ipw_set_rsn_capa(struct ipw_priv *priv, 6179static int ipw_set_rsn_capa(struct ipw_priv *priv,
6216 char *capabilities, int length) 6180 char *capabilities, int length)
6217{ 6181{
6218 struct host_cmd cmd = {
6219 .cmd = IPW_CMD_RSN_CAPABILITIES,
6220 .len = length,
6221 };
6222
6223 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n"); 6182 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6224 6183
6225 memcpy(cmd.param, capabilities, length); 6184 return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length,
6226 return ipw_send_cmd(priv, &cmd); 6185 capabilities);
6227} 6186}
6228 6187
6229/* 6188/*
@@ -6244,7 +6203,7 @@ static int ipw_wx_set_genie(struct net_device *dev,
6244 (wrqu->data.length && extra == NULL)) 6203 (wrqu->data.length && extra == NULL))
6245 return -EINVAL; 6204 return -EINVAL;
6246 6205
6247 //down(&priv->sem); 6206 //mutex_lock(&priv->mutex);
6248 6207
6249 //if (!ieee->wpa_enabled) { 6208 //if (!ieee->wpa_enabled) {
6250 // err = -EOPNOTSUPP; 6209 // err = -EOPNOTSUPP;
@@ -6270,7 +6229,7 @@ static int ipw_wx_set_genie(struct net_device *dev,
6270 6229
6271 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); 6230 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6272 out: 6231 out:
6273 //up(&priv->sem); 6232 //mutex_unlock(&priv->mutex);
6274 return err; 6233 return err;
6275} 6234}
6276 6235
@@ -6283,7 +6242,7 @@ static int ipw_wx_get_genie(struct net_device *dev,
6283 struct ieee80211_device *ieee = priv->ieee; 6242 struct ieee80211_device *ieee = priv->ieee;
6284 int err = 0; 6243 int err = 0;
6285 6244
6286 //down(&priv->sem); 6245 //mutex_lock(&priv->mutex);
6287 6246
6288 //if (!ieee->wpa_enabled) { 6247 //if (!ieee->wpa_enabled) {
6289 // err = -EOPNOTSUPP; 6248 // err = -EOPNOTSUPP;
@@ -6304,7 +6263,7 @@ static int ipw_wx_get_genie(struct net_device *dev,
6304 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); 6263 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6305 6264
6306 out: 6265 out:
6307 //up(&priv->sem); 6266 //mutex_unlock(&priv->mutex);
6308 return err; 6267 return err;
6309} 6268}
6310 6269
@@ -6556,7 +6515,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,
6556* get the modulation type of the current network or 6515* get the modulation type of the current network or
6557* the card current mode 6516* the card current mode
6558*/ 6517*/
6559u8 ipw_qos_current_mode(struct ipw_priv * priv) 6518static u8 ipw_qos_current_mode(struct ipw_priv * priv)
6560{ 6519{
6561 u8 mode = 0; 6520 u8 mode = 0;
6562 6521
@@ -6964,12 +6923,12 @@ static void ipw_bg_qos_activate(void *data)
6964 if (priv == NULL) 6923 if (priv == NULL)
6965 return; 6924 return;
6966 6925
6967 down(&priv->sem); 6926 mutex_lock(&priv->mutex);
6968 6927
6969 if (priv->status & STATUS_ASSOCIATED) 6928 if (priv->status & STATUS_ASSOCIATED)
6970 ipw_qos_activate(priv, &(priv->assoc_network->qos_data)); 6929 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
6971 6930
6972 up(&priv->sem); 6931 mutex_unlock(&priv->mutex);
6973} 6932}
6974 6933
6975static int ipw_handle_probe_response(struct net_device *dev, 6934static int ipw_handle_probe_response(struct net_device *dev,
@@ -7010,25 +6969,15 @@ static int ipw_handle_assoc_response(struct net_device *dev,
7010static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters 6969static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
7011 *qos_param) 6970 *qos_param)
7012{ 6971{
7013 struct host_cmd cmd = { 6972 return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS,
7014 .cmd = IPW_CMD_QOS_PARAMETERS, 6973 sizeof(*qos_param) * 3, qos_param);
7015 .len = (sizeof(struct ieee80211_qos_parameters) * 3)
7016 };
7017
7018 memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
7019 return ipw_send_cmd(priv, &cmd);
7020} 6974}
7021 6975
7022static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element 6976static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
7023 *qos_param) 6977 *qos_param)
7024{ 6978{
7025 struct host_cmd cmd = { 6979 return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param),
7026 .cmd = IPW_CMD_WME_INFO, 6980 qos_param);
7027 .len = sizeof(*qos_param)
7028 };
7029
7030 memcpy(cmd.param, qos_param, sizeof(*qos_param));
7031 return ipw_send_cmd(priv, &cmd);
7032} 6981}
7033 6982
7034#endif /* CONFIG_IPW_QOS */ 6983#endif /* CONFIG_IPW_QOS */
@@ -7052,19 +7001,21 @@ static int ipw_associate_network(struct ipw_priv *priv,
7052 7001
7053 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request)); 7002 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
7054 priv->assoc_request.channel = network->channel; 7003 priv->assoc_request.channel = network->channel;
7004 priv->assoc_request.auth_key = 0;
7005
7055 if ((priv->capability & CAP_PRIVACY_ON) && 7006 if ((priv->capability & CAP_PRIVACY_ON) &&
7056 (priv->capability & CAP_SHARED_KEY)) { 7007 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) {
7057 priv->assoc_request.auth_type = AUTH_SHARED_KEY; 7008 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
7058 priv->assoc_request.auth_key = priv->ieee->sec.active_key; 7009 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7059 7010
7060 if ((priv->capability & CAP_PRIVACY_ON) && 7011 if (priv->ieee->sec.level == SEC_LEVEL_1)
7061 (priv->ieee->sec.level == SEC_LEVEL_1) &&
7062 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
7063 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP); 7012 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
7064 } else { 7013
7014 } else if ((priv->capability & CAP_PRIVACY_ON) &&
7015 (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP))
7016 priv->assoc_request.auth_type = AUTH_LEAP;
7017 else
7065 priv->assoc_request.auth_type = AUTH_OPEN; 7018 priv->assoc_request.auth_type = AUTH_OPEN;
7066 priv->assoc_request.auth_key = 0;
7067 }
7068 7019
7069 if (priv->ieee->wpa_ie_len) { 7020 if (priv->ieee->wpa_ie_len) {
7070 priv->assoc_request.policy_support = 0x02; /* RSN active */ 7021 priv->assoc_request.policy_support = 0x02; /* RSN active */
@@ -7278,9 +7229,9 @@ static void ipw_roam(void *data)
7278static void ipw_bg_roam(void *data) 7229static void ipw_bg_roam(void *data)
7279{ 7230{
7280 struct ipw_priv *priv = data; 7231 struct ipw_priv *priv = data;
7281 down(&priv->sem); 7232 mutex_lock(&priv->mutex);
7282 ipw_roam(data); 7233 ipw_roam(data);
7283 up(&priv->sem); 7234 mutex_unlock(&priv->mutex);
7284} 7235}
7285 7236
7286static int ipw_associate(void *data) 7237static int ipw_associate(void *data)
@@ -7375,9 +7326,9 @@ static int ipw_associate(void *data)
7375static void ipw_bg_associate(void *data) 7326static void ipw_bg_associate(void *data)
7376{ 7327{
7377 struct ipw_priv *priv = data; 7328 struct ipw_priv *priv = data;
7378 down(&priv->sem); 7329 mutex_lock(&priv->mutex);
7379 ipw_associate(data); 7330 ipw_associate(data);
7380 up(&priv->sem); 7331 mutex_unlock(&priv->mutex);
7381} 7332}
7382 7333
7383static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv, 7334static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
@@ -7811,12 +7762,10 @@ static void ipw_rx(struct ipw_priv *priv)
7811 7762
7812 while (i != r) { 7763 while (i != r) {
7813 rxb = priv->rxq->queue[i]; 7764 rxb = priv->rxq->queue[i];
7814#ifdef CONFIG_IPW2200_DEBUG
7815 if (unlikely(rxb == NULL)) { 7765 if (unlikely(rxb == NULL)) {
7816 printk(KERN_CRIT "Queue not allocated!\n"); 7766 printk(KERN_CRIT "Queue not allocated!\n");
7817 break; 7767 break;
7818 } 7768 }
7819#endif
7820 priv->rxq->queue[i] = NULL; 7769 priv->rxq->queue[i] = NULL;
7821 7770
7822 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, 7771 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
@@ -7835,7 +7784,8 @@ static void ipw_rx(struct ipw_priv *priv)
7835 le16_to_cpu(pkt->u.frame.rssi_dbm) - 7784 le16_to_cpu(pkt->u.frame.rssi_dbm) -
7836 IPW_RSSI_TO_DBM, 7785 IPW_RSSI_TO_DBM,
7837 .signal = 7786 .signal =
7838 le16_to_cpu(pkt->u.frame.signal), 7787 le16_to_cpu(pkt->u.frame.rssi_dbm) -
7788 IPW_RSSI_TO_DBM + 0x100,
7839 .noise = 7789 .noise =
7840 le16_to_cpu(pkt->u.frame.noise), 7790 le16_to_cpu(pkt->u.frame.noise),
7841 .rate = pkt->u.frame.rate, 7791 .rate = pkt->u.frame.rate,
@@ -7899,7 +7849,8 @@ static void ipw_rx(struct ipw_priv *priv)
7899 le16_to_cpu(pkt->u.frame.length)); 7849 le16_to_cpu(pkt->u.frame.length));
7900 7850
7901 if (le16_to_cpu(pkt->u.frame.length) < 7851 if (le16_to_cpu(pkt->u.frame.length) <
7902 frame_hdr_len(header)) { 7852 ieee80211_get_hdrlen(le16_to_cpu(
7853 header->frame_ctl))) {
7903 IPW_DEBUG_DROP 7854 IPW_DEBUG_DROP
7904 ("Received packet is too small. " 7855 ("Received packet is too small. "
7905 "Dropping.\n"); 7856 "Dropping.\n");
@@ -7989,7 +7940,14 @@ static void ipw_rx(struct ipw_priv *priv)
7989#define DEFAULT_SHORT_RETRY_LIMIT 7U 7940#define DEFAULT_SHORT_RETRY_LIMIT 7U
7990#define DEFAULT_LONG_RETRY_LIMIT 4U 7941#define DEFAULT_LONG_RETRY_LIMIT 4U
7991 7942
7992static int ipw_sw_reset(struct ipw_priv *priv, int init) 7943/**
7944 * ipw_sw_reset
7945 * @option: options to control different reset behaviour
7946 * 0 = reset everything except the 'disable' module_param
7947 * 1 = reset everything and print out driver info (for probe only)
7948 * 2 = reset everything
7949 */
7950static int ipw_sw_reset(struct ipw_priv *priv, int option)
7993{ 7951{
7994 int band, modulation; 7952 int band, modulation;
7995 int old_mode = priv->ieee->iw_mode; 7953 int old_mode = priv->ieee->iw_mode;
@@ -8016,7 +7974,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
8016 priv->essid_len = 0; 7974 priv->essid_len = 0;
8017 memset(priv->essid, 0, IW_ESSID_MAX_SIZE); 7975 memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
8018 7976
8019 if (disable) { 7977 if (disable && option) {
8020 priv->status |= STATUS_RF_KILL_SW; 7978 priv->status |= STATUS_RF_KILL_SW;
8021 IPW_DEBUG_INFO("Radio disabled.\n"); 7979 IPW_DEBUG_INFO("Radio disabled.\n");
8022 } 7980 }
@@ -8068,7 +8026,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
8068 8026
8069 if ((priv->pci_dev->device == 0x4223) || 8027 if ((priv->pci_dev->device == 0x4223) ||
8070 (priv->pci_dev->device == 0x4224)) { 8028 (priv->pci_dev->device == 0x4224)) {
8071 if (init) 8029 if (option == 1)
8072 printk(KERN_INFO DRV_NAME 8030 printk(KERN_INFO DRV_NAME
8073 ": Detected Intel PRO/Wireless 2915ABG Network " 8031 ": Detected Intel PRO/Wireless 2915ABG Network "
8074 "Connection\n"); 8032 "Connection\n");
@@ -8079,7 +8037,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
8079 priv->adapter = IPW_2915ABG; 8037 priv->adapter = IPW_2915ABG;
8080 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B; 8038 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
8081 } else { 8039 } else {
8082 if (init) 8040 if (option == 1)
8083 printk(KERN_INFO DRV_NAME 8041 printk(KERN_INFO DRV_NAME
8084 ": Detected Intel PRO/Wireless 2200BG Network " 8042 ": Detected Intel PRO/Wireless 2200BG Network "
8085 "Connection\n"); 8043 "Connection\n");
@@ -8126,7 +8084,7 @@ static int ipw_wx_get_name(struct net_device *dev,
8126 union iwreq_data *wrqu, char *extra) 8084 union iwreq_data *wrqu, char *extra)
8127{ 8085{
8128 struct ipw_priv *priv = ieee80211_priv(dev); 8086 struct ipw_priv *priv = ieee80211_priv(dev);
8129 down(&priv->sem); 8087 mutex_lock(&priv->mutex);
8130 if (priv->status & STATUS_RF_KILL_MASK) 8088 if (priv->status & STATUS_RF_KILL_MASK)
8131 strcpy(wrqu->name, "radio off"); 8089 strcpy(wrqu->name, "radio off");
8132 else if (!(priv->status & STATUS_ASSOCIATED)) 8090 else if (!(priv->status & STATUS_ASSOCIATED))
@@ -8135,7 +8093,7 @@ static int ipw_wx_get_name(struct net_device *dev,
8135 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", 8093 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
8136 ipw_modes[priv->assoc_request.ieee_mode]); 8094 ipw_modes[priv->assoc_request.ieee_mode]);
8137 IPW_DEBUG_WX("Name: %s\n", wrqu->name); 8095 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
8138 up(&priv->sem); 8096 mutex_unlock(&priv->mutex);
8139 return 0; 8097 return 0;
8140} 8098}
8141 8099
@@ -8196,7 +8154,7 @@ static int ipw_wx_set_freq(struct net_device *dev,
8196 union iwreq_data *wrqu, char *extra) 8154 union iwreq_data *wrqu, char *extra)
8197{ 8155{
8198 struct ipw_priv *priv = ieee80211_priv(dev); 8156 struct ipw_priv *priv = ieee80211_priv(dev);
8199 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 8157 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
8200 struct iw_freq *fwrq = &wrqu->freq; 8158 struct iw_freq *fwrq = &wrqu->freq;
8201 int ret = 0, i; 8159 int ret = 0, i;
8202 u8 channel, flags; 8160 u8 channel, flags;
@@ -8204,24 +8162,24 @@ static int ipw_wx_set_freq(struct net_device *dev,
8204 8162
8205 if (fwrq->m == 0) { 8163 if (fwrq->m == 0) {
8206 IPW_DEBUG_WX("SET Freq/Channel -> any\n"); 8164 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
8207 down(&priv->sem); 8165 mutex_lock(&priv->mutex);
8208 ret = ipw_set_channel(priv, 0); 8166 ret = ipw_set_channel(priv, 0);
8209 up(&priv->sem); 8167 mutex_unlock(&priv->mutex);
8210 return ret; 8168 return ret;
8211 } 8169 }
8212 /* if setting by freq convert to channel */ 8170 /* if setting by freq convert to channel */
8213 if (fwrq->e == 1) { 8171 if (fwrq->e == 1) {
8214 channel = ipw_freq_to_channel(priv->ieee, fwrq->m); 8172 channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m);
8215 if (channel == 0) 8173 if (channel == 0)
8216 return -EINVAL; 8174 return -EINVAL;
8217 } else 8175 } else
8218 channel = fwrq->m; 8176 channel = fwrq->m;
8219 8177
8220 if (!(band = ipw_is_valid_channel(priv->ieee, channel))) 8178 if (!(band = ieee80211_is_valid_channel(priv->ieee, channel)))
8221 return -EINVAL; 8179 return -EINVAL;
8222 8180
8223 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 8181 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
8224 i = ipw_channel_to_index(priv->ieee, channel); 8182 i = ieee80211_channel_to_index(priv->ieee, channel);
8225 if (i == -1) 8183 if (i == -1)
8226 return -EINVAL; 8184 return -EINVAL;
8227 8185
@@ -8234,9 +8192,9 @@ static int ipw_wx_set_freq(struct net_device *dev,
8234 } 8192 }
8235 8193
8236 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 8194 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
8237 down(&priv->sem); 8195 mutex_lock(&priv->mutex);
8238 ret = ipw_set_channel(priv, channel); 8196 ret = ipw_set_channel(priv, channel);
8239 up(&priv->sem); 8197 mutex_unlock(&priv->mutex);
8240 return ret; 8198 return ret;
8241} 8199}
8242 8200
@@ -8250,14 +8208,14 @@ static int ipw_wx_get_freq(struct net_device *dev,
8250 8208
8251 /* If we are associated, trying to associate, or have a statically 8209 /* If we are associated, trying to associate, or have a statically
8252 * configured CHANNEL then return that; otherwise return ANY */ 8210 * configured CHANNEL then return that; otherwise return ANY */
8253 down(&priv->sem); 8211 mutex_lock(&priv->mutex);
8254 if (priv->config & CFG_STATIC_CHANNEL || 8212 if (priv->config & CFG_STATIC_CHANNEL ||
8255 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) 8213 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
8256 wrqu->freq.m = priv->channel; 8214 wrqu->freq.m = priv->channel;
8257 else 8215 else
8258 wrqu->freq.m = 0; 8216 wrqu->freq.m = 0;
8259 8217
8260 up(&priv->sem); 8218 mutex_unlock(&priv->mutex);
8261 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 8219 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
8262 return 0; 8220 return 0;
8263} 8221}
@@ -8287,7 +8245,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
8287 if (wrqu->mode == priv->ieee->iw_mode) 8245 if (wrqu->mode == priv->ieee->iw_mode)
8288 return 0; 8246 return 0;
8289 8247
8290 down(&priv->sem); 8248 mutex_lock(&priv->mutex);
8291 8249
8292 ipw_sw_reset(priv, 0); 8250 ipw_sw_reset(priv, 0);
8293 8251
@@ -8310,7 +8268,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
8310 priv->ieee->iw_mode = wrqu->mode; 8268 priv->ieee->iw_mode = wrqu->mode;
8311 8269
8312 queue_work(priv->workqueue, &priv->adapter_restart); 8270 queue_work(priv->workqueue, &priv->adapter_restart);
8313 up(&priv->sem); 8271 mutex_unlock(&priv->mutex);
8314 return err; 8272 return err;
8315} 8273}
8316 8274
@@ -8319,10 +8277,10 @@ static int ipw_wx_get_mode(struct net_device *dev,
8319 union iwreq_data *wrqu, char *extra) 8277 union iwreq_data *wrqu, char *extra)
8320{ 8278{
8321 struct ipw_priv *priv = ieee80211_priv(dev); 8279 struct ipw_priv *priv = ieee80211_priv(dev);
8322 down(&priv->sem); 8280 mutex_lock(&priv->mutex);
8323 wrqu->mode = priv->ieee->iw_mode; 8281 wrqu->mode = priv->ieee->iw_mode;
8324 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode); 8282 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
8325 up(&priv->sem); 8283 mutex_unlock(&priv->mutex);
8326 return 0; 8284 return 0;
8327} 8285}
8328 8286
@@ -8349,7 +8307,7 @@ static int ipw_wx_get_range(struct net_device *dev,
8349{ 8307{
8350 struct ipw_priv *priv = ieee80211_priv(dev); 8308 struct ipw_priv *priv = ieee80211_priv(dev);
8351 struct iw_range *range = (struct iw_range *)extra; 8309 struct iw_range *range = (struct iw_range *)extra;
8352 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 8310 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
8353 int i = 0, j; 8311 int i = 0, j;
8354 8312
8355 wrqu->data.length = sizeof(*range); 8313 wrqu->data.length = sizeof(*range);
@@ -8361,7 +8319,7 @@ static int ipw_wx_get_range(struct net_device *dev,
8361 range->max_qual.qual = 100; 8319 range->max_qual.qual = 100;
8362 /* TODO: Find real max RSSI and stick here */ 8320 /* TODO: Find real max RSSI and stick here */
8363 range->max_qual.level = 0; 8321 range->max_qual.level = 0;
8364 range->max_qual.noise = priv->ieee->worst_rssi + 0x100; 8322 range->max_qual.noise = 0;
8365 range->max_qual.updated = 7; /* Updated all three */ 8323 range->max_qual.updated = 7; /* Updated all three */
8366 8324
8367 range->avg_qual.qual = 70; 8325 range->avg_qual.qual = 70;
@@ -8369,7 +8327,7 @@ static int ipw_wx_get_range(struct net_device *dev,
8369 range->avg_qual.level = 0; /* FIXME to real average level */ 8327 range->avg_qual.level = 0; /* FIXME to real average level */
8370 range->avg_qual.noise = 0; 8328 range->avg_qual.noise = 0;
8371 range->avg_qual.updated = 7; /* Updated all three */ 8329 range->avg_qual.updated = 7; /* Updated all three */
8372 down(&priv->sem); 8330 mutex_lock(&priv->mutex);
8373 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); 8331 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
8374 8332
8375 for (i = 0; i < range->num_bitrates; i++) 8333 for (i = 0; i < range->num_bitrates; i++)
@@ -8387,31 +8345,39 @@ static int ipw_wx_get_range(struct net_device *dev,
8387 8345
8388 /* Set the Wireless Extension versions */ 8346 /* Set the Wireless Extension versions */
8389 range->we_version_compiled = WIRELESS_EXT; 8347 range->we_version_compiled = WIRELESS_EXT;
8390 range->we_version_source = 16; 8348 range->we_version_source = 18;
8391 8349
8392 i = 0; 8350 i = 0;
8393 if (priv->ieee->mode & (IEEE_B | IEEE_G)) { 8351 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
8394 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; 8352 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {
8395 i++, j++) { 8353 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
8354 (geo->bg[j].flags & IEEE80211_CH_PASSIVE_ONLY))
8355 continue;
8356
8396 range->freq[i].i = geo->bg[j].channel; 8357 range->freq[i].i = geo->bg[j].channel;
8397 range->freq[i].m = geo->bg[j].freq * 100000; 8358 range->freq[i].m = geo->bg[j].freq * 100000;
8398 range->freq[i].e = 1; 8359 range->freq[i].e = 1;
8360 i++;
8399 } 8361 }
8400 } 8362 }
8401 8363
8402 if (priv->ieee->mode & IEEE_A) { 8364 if (priv->ieee->mode & IEEE_A) {
8403 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; 8365 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {
8404 i++, j++) { 8366 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
8367 (geo->a[j].flags & IEEE80211_CH_PASSIVE_ONLY))
8368 continue;
8369
8405 range->freq[i].i = geo->a[j].channel; 8370 range->freq[i].i = geo->a[j].channel;
8406 range->freq[i].m = geo->a[j].freq * 100000; 8371 range->freq[i].m = geo->a[j].freq * 100000;
8407 range->freq[i].e = 1; 8372 range->freq[i].e = 1;
8373 i++;
8408 } 8374 }
8409 } 8375 }
8410 8376
8411 range->num_channels = i; 8377 range->num_channels = i;
8412 range->num_frequency = i; 8378 range->num_frequency = i;
8413 8379
8414 up(&priv->sem); 8380 mutex_unlock(&priv->mutex);
8415 8381
8416 /* Event capability (kernel + driver) */ 8382 /* Event capability (kernel + driver) */
8417 range->event_capa[0] = (IW_EVENT_CAPA_K_0 | 8383 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
@@ -8419,6 +8385,9 @@ static int ipw_wx_get_range(struct net_device *dev,
8419 IW_EVENT_CAPA_MASK(SIOCGIWAP)); 8385 IW_EVENT_CAPA_MASK(SIOCGIWAP));
8420 range->event_capa[1] = IW_EVENT_CAPA_K_1; 8386 range->event_capa[1] = IW_EVENT_CAPA_K_1;
8421 8387
8388 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
8389 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
8390
8422 IPW_DEBUG_WX("GET Range\n"); 8391 IPW_DEBUG_WX("GET Range\n");
8423 return 0; 8392 return 0;
8424} 8393}
@@ -8438,7 +8407,7 @@ static int ipw_wx_set_wap(struct net_device *dev,
8438 8407
8439 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) 8408 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
8440 return -EINVAL; 8409 return -EINVAL;
8441 down(&priv->sem); 8410 mutex_lock(&priv->mutex);
8442 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || 8411 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
8443 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8412 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
8444 /* we disable mandatory BSSID association */ 8413 /* we disable mandatory BSSID association */
@@ -8447,14 +8416,14 @@ static int ipw_wx_set_wap(struct net_device *dev,
8447 IPW_DEBUG_ASSOC("Attempting to associate with new " 8416 IPW_DEBUG_ASSOC("Attempting to associate with new "
8448 "parameters.\n"); 8417 "parameters.\n");
8449 ipw_associate(priv); 8418 ipw_associate(priv);
8450 up(&priv->sem); 8419 mutex_unlock(&priv->mutex);
8451 return 0; 8420 return 0;
8452 } 8421 }
8453 8422
8454 priv->config |= CFG_STATIC_BSSID; 8423 priv->config |= CFG_STATIC_BSSID;
8455 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8424 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
8456 IPW_DEBUG_WX("BSSID set to current BSSID.\n"); 8425 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
8457 up(&priv->sem); 8426 mutex_unlock(&priv->mutex);
8458 return 0; 8427 return 0;
8459 } 8428 }
8460 8429
@@ -8468,7 +8437,7 @@ static int ipw_wx_set_wap(struct net_device *dev,
8468 if (!ipw_disassociate(priv)) 8437 if (!ipw_disassociate(priv))
8469 ipw_associate(priv); 8438 ipw_associate(priv);
8470 8439
8471 up(&priv->sem); 8440 mutex_unlock(&priv->mutex);
8472 return 0; 8441 return 0;
8473} 8442}
8474 8443
@@ -8479,7 +8448,7 @@ static int ipw_wx_get_wap(struct net_device *dev,
8479 struct ipw_priv *priv = ieee80211_priv(dev); 8448 struct ipw_priv *priv = ieee80211_priv(dev);
8480 /* If we are associated, trying to associate, or have a statically 8449 /* If we are associated, trying to associate, or have a statically
8481 * configured BSSID then return that; otherwise return ANY */ 8450 * configured BSSID then return that; otherwise return ANY */
8482 down(&priv->sem); 8451 mutex_lock(&priv->mutex);
8483 if (priv->config & CFG_STATIC_BSSID || 8452 if (priv->config & CFG_STATIC_BSSID ||
8484 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8453 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
8485 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 8454 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
@@ -8489,7 +8458,7 @@ static int ipw_wx_get_wap(struct net_device *dev,
8489 8458
8490 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", 8459 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
8491 MAC_ARG(wrqu->ap_addr.sa_data)); 8460 MAC_ARG(wrqu->ap_addr.sa_data));
8492 up(&priv->sem); 8461 mutex_unlock(&priv->mutex);
8493 return 0; 8462 return 0;
8494} 8463}
8495 8464
@@ -8500,7 +8469,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
8500 struct ipw_priv *priv = ieee80211_priv(dev); 8469 struct ipw_priv *priv = ieee80211_priv(dev);
8501 char *essid = ""; /* ANY */ 8470 char *essid = ""; /* ANY */
8502 int length = 0; 8471 int length = 0;
8503 down(&priv->sem); 8472 mutex_lock(&priv->mutex);
8504 if (wrqu->essid.flags && wrqu->essid.length) { 8473 if (wrqu->essid.flags && wrqu->essid.length) {
8505 length = wrqu->essid.length - 1; 8474 length = wrqu->essid.length - 1;
8506 essid = extra; 8475 essid = extra;
@@ -8515,7 +8484,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
8515 priv->config &= ~CFG_STATIC_ESSID; 8484 priv->config &= ~CFG_STATIC_ESSID;
8516 ipw_associate(priv); 8485 ipw_associate(priv);
8517 } 8486 }
8518 up(&priv->sem); 8487 mutex_unlock(&priv->mutex);
8519 return 0; 8488 return 0;
8520 } 8489 }
8521 8490
@@ -8525,7 +8494,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
8525 8494
8526 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { 8495 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
8527 IPW_DEBUG_WX("ESSID set to current ESSID.\n"); 8496 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
8528 up(&priv->sem); 8497 mutex_unlock(&priv->mutex);
8529 return 0; 8498 return 0;
8530 } 8499 }
8531 8500
@@ -8540,7 +8509,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
8540 if (!ipw_disassociate(priv)) 8509 if (!ipw_disassociate(priv))
8541 ipw_associate(priv); 8510 ipw_associate(priv);
8542 8511
8543 up(&priv->sem); 8512 mutex_unlock(&priv->mutex);
8544 return 0; 8513 return 0;
8545} 8514}
8546 8515
@@ -8552,7 +8521,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
8552 8521
8553 /* If we are associated, trying to associate, or have a statically 8522 /* If we are associated, trying to associate, or have a statically
8554 * configured ESSID then return that; otherwise return ANY */ 8523 * configured ESSID then return that; otherwise return ANY */
8555 down(&priv->sem); 8524 mutex_lock(&priv->mutex);
8556 if (priv->config & CFG_STATIC_ESSID || 8525 if (priv->config & CFG_STATIC_ESSID ||
8557 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8526 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
8558 IPW_DEBUG_WX("Getting essid: '%s'\n", 8527 IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -8565,7 +8534,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
8565 wrqu->essid.length = 0; 8534 wrqu->essid.length = 0;
8566 wrqu->essid.flags = 0; /* active */ 8535 wrqu->essid.flags = 0; /* active */
8567 } 8536 }
8568 up(&priv->sem); 8537 mutex_unlock(&priv->mutex);
8569 return 0; 8538 return 0;
8570} 8539}
8571 8540
@@ -8578,12 +8547,12 @@ static int ipw_wx_set_nick(struct net_device *dev,
8578 IPW_DEBUG_WX("Setting nick to '%s'\n", extra); 8547 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
8579 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 8548 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
8580 return -E2BIG; 8549 return -E2BIG;
8581 down(&priv->sem); 8550 mutex_lock(&priv->mutex);
8582 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 8551 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
8583 memset(priv->nick, 0, sizeof(priv->nick)); 8552 memset(priv->nick, 0, sizeof(priv->nick));
8584 memcpy(priv->nick, extra, wrqu->data.length); 8553 memcpy(priv->nick, extra, wrqu->data.length);
8585 IPW_DEBUG_TRACE("<<\n"); 8554 IPW_DEBUG_TRACE("<<\n");
8586 up(&priv->sem); 8555 mutex_unlock(&priv->mutex);
8587 return 0; 8556 return 0;
8588 8557
8589} 8558}
@@ -8594,11 +8563,57 @@ static int ipw_wx_get_nick(struct net_device *dev,
8594{ 8563{
8595 struct ipw_priv *priv = ieee80211_priv(dev); 8564 struct ipw_priv *priv = ieee80211_priv(dev);
8596 IPW_DEBUG_WX("Getting nick\n"); 8565 IPW_DEBUG_WX("Getting nick\n");
8597 down(&priv->sem); 8566 mutex_lock(&priv->mutex);
8598 wrqu->data.length = strlen(priv->nick) + 1; 8567 wrqu->data.length = strlen(priv->nick) + 1;
8599 memcpy(extra, priv->nick, wrqu->data.length); 8568 memcpy(extra, priv->nick, wrqu->data.length);
8600 wrqu->data.flags = 1; /* active */ 8569 wrqu->data.flags = 1; /* active */
8601 up(&priv->sem); 8570 mutex_unlock(&priv->mutex);
8571 return 0;
8572}
8573
8574static int ipw_wx_set_sens(struct net_device *dev,
8575 struct iw_request_info *info,
8576 union iwreq_data *wrqu, char *extra)
8577{
8578 struct ipw_priv *priv = ieee80211_priv(dev);
8579 int err = 0;
8580
8581 IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value);
8582 IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value);
8583 mutex_lock(&priv->mutex);
8584
8585 if (wrqu->sens.fixed == 0)
8586 {
8587 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
8588 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
8589 goto out;
8590 }
8591 if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) ||
8592 (wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) {
8593 err = -EINVAL;
8594 goto out;
8595 }
8596
8597 priv->roaming_threshold = wrqu->sens.value;
8598 priv->disassociate_threshold = 3*wrqu->sens.value;
8599 out:
8600 mutex_unlock(&priv->mutex);
8601 return err;
8602}
8603
8604static int ipw_wx_get_sens(struct net_device *dev,
8605 struct iw_request_info *info,
8606 union iwreq_data *wrqu, char *extra)
8607{
8608 struct ipw_priv *priv = ieee80211_priv(dev);
8609 mutex_lock(&priv->mutex);
8610 wrqu->sens.fixed = 1;
8611 wrqu->sens.value = priv->roaming_threshold;
8612 mutex_unlock(&priv->mutex);
8613
8614 IPW_DEBUG_WX("GET roaming threshold -> %s %d \n",
8615 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
8616
8602 return 0; 8617 return 0;
8603} 8618}
8604 8619
@@ -8691,7 +8706,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
8691 apply: 8706 apply:
8692 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n", 8707 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
8693 mask, fixed ? "fixed" : "sub-rates"); 8708 mask, fixed ? "fixed" : "sub-rates");
8694 down(&priv->sem); 8709 mutex_lock(&priv->mutex);
8695 if (mask == IEEE80211_DEFAULT_RATES_MASK) { 8710 if (mask == IEEE80211_DEFAULT_RATES_MASK) {
8696 priv->config &= ~CFG_FIXED_RATE; 8711 priv->config &= ~CFG_FIXED_RATE;
8697 ipw_set_fixed_rate(priv, priv->ieee->mode); 8712 ipw_set_fixed_rate(priv, priv->ieee->mode);
@@ -8700,7 +8715,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
8700 8715
8701 if (priv->rates_mask == mask) { 8716 if (priv->rates_mask == mask) {
8702 IPW_DEBUG_WX("Mask set to current mask.\n"); 8717 IPW_DEBUG_WX("Mask set to current mask.\n");
8703 up(&priv->sem); 8718 mutex_unlock(&priv->mutex);
8704 return 0; 8719 return 0;
8705 } 8720 }
8706 8721
@@ -8711,7 +8726,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
8711 if (!ipw_disassociate(priv)) 8726 if (!ipw_disassociate(priv))
8712 ipw_associate(priv); 8727 ipw_associate(priv);
8713 8728
8714 up(&priv->sem); 8729 mutex_unlock(&priv->mutex);
8715 return 0; 8730 return 0;
8716} 8731}
8717 8732
@@ -8720,9 +8735,9 @@ static int ipw_wx_get_rate(struct net_device *dev,
8720 union iwreq_data *wrqu, char *extra) 8735 union iwreq_data *wrqu, char *extra)
8721{ 8736{
8722 struct ipw_priv *priv = ieee80211_priv(dev); 8737 struct ipw_priv *priv = ieee80211_priv(dev);
8723 down(&priv->sem); 8738 mutex_lock(&priv->mutex);
8724 wrqu->bitrate.value = priv->last_rate; 8739 wrqu->bitrate.value = priv->last_rate;
8725 up(&priv->sem); 8740 mutex_unlock(&priv->mutex);
8726 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 8741 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
8727 return 0; 8742 return 0;
8728} 8743}
@@ -8732,20 +8747,20 @@ static int ipw_wx_set_rts(struct net_device *dev,
8732 union iwreq_data *wrqu, char *extra) 8747 union iwreq_data *wrqu, char *extra)
8733{ 8748{
8734 struct ipw_priv *priv = ieee80211_priv(dev); 8749 struct ipw_priv *priv = ieee80211_priv(dev);
8735 down(&priv->sem); 8750 mutex_lock(&priv->mutex);
8736 if (wrqu->rts.disabled) 8751 if (wrqu->rts.disabled)
8737 priv->rts_threshold = DEFAULT_RTS_THRESHOLD; 8752 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8738 else { 8753 else {
8739 if (wrqu->rts.value < MIN_RTS_THRESHOLD || 8754 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
8740 wrqu->rts.value > MAX_RTS_THRESHOLD) { 8755 wrqu->rts.value > MAX_RTS_THRESHOLD) {
8741 up(&priv->sem); 8756 mutex_unlock(&priv->mutex);
8742 return -EINVAL; 8757 return -EINVAL;
8743 } 8758 }
8744 priv->rts_threshold = wrqu->rts.value; 8759 priv->rts_threshold = wrqu->rts.value;
8745 } 8760 }
8746 8761
8747 ipw_send_rts_threshold(priv, priv->rts_threshold); 8762 ipw_send_rts_threshold(priv, priv->rts_threshold);
8748 up(&priv->sem); 8763 mutex_unlock(&priv->mutex);
8749 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); 8764 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
8750 return 0; 8765 return 0;
8751} 8766}
@@ -8755,11 +8770,11 @@ static int ipw_wx_get_rts(struct net_device *dev,
8755 union iwreq_data *wrqu, char *extra) 8770 union iwreq_data *wrqu, char *extra)
8756{ 8771{
8757 struct ipw_priv *priv = ieee80211_priv(dev); 8772 struct ipw_priv *priv = ieee80211_priv(dev);
8758 down(&priv->sem); 8773 mutex_lock(&priv->mutex);
8759 wrqu->rts.value = priv->rts_threshold; 8774 wrqu->rts.value = priv->rts_threshold;
8760 wrqu->rts.fixed = 0; /* no auto select */ 8775 wrqu->rts.fixed = 0; /* no auto select */
8761 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 8776 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
8762 up(&priv->sem); 8777 mutex_unlock(&priv->mutex);
8763 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); 8778 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
8764 return 0; 8779 return 0;
8765} 8780}
@@ -8771,7 +8786,7 @@ static int ipw_wx_set_txpow(struct net_device *dev,
8771 struct ipw_priv *priv = ieee80211_priv(dev); 8786 struct ipw_priv *priv = ieee80211_priv(dev);
8772 int err = 0; 8787 int err = 0;
8773 8788
8774 down(&priv->sem); 8789 mutex_lock(&priv->mutex);
8775 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) { 8790 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
8776 err = -EINPROGRESS; 8791 err = -EINPROGRESS;
8777 goto out; 8792 goto out;
@@ -8794,7 +8809,7 @@ static int ipw_wx_set_txpow(struct net_device *dev,
8794 priv->tx_power = wrqu->power.value; 8809 priv->tx_power = wrqu->power.value;
8795 err = ipw_set_tx_power(priv); 8810 err = ipw_set_tx_power(priv);
8796 out: 8811 out:
8797 up(&priv->sem); 8812 mutex_unlock(&priv->mutex);
8798 return err; 8813 return err;
8799} 8814}
8800 8815
@@ -8803,12 +8818,12 @@ static int ipw_wx_get_txpow(struct net_device *dev,
8803 union iwreq_data *wrqu, char *extra) 8818 union iwreq_data *wrqu, char *extra)
8804{ 8819{
8805 struct ipw_priv *priv = ieee80211_priv(dev); 8820 struct ipw_priv *priv = ieee80211_priv(dev);
8806 down(&priv->sem); 8821 mutex_lock(&priv->mutex);
8807 wrqu->power.value = priv->tx_power; 8822 wrqu->power.value = priv->tx_power;
8808 wrqu->power.fixed = 1; 8823 wrqu->power.fixed = 1;
8809 wrqu->power.flags = IW_TXPOW_DBM; 8824 wrqu->power.flags = IW_TXPOW_DBM;
8810 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; 8825 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
8811 up(&priv->sem); 8826 mutex_unlock(&priv->mutex);
8812 8827
8813 IPW_DEBUG_WX("GET TX Power -> %s %d \n", 8828 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
8814 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); 8829 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
@@ -8821,13 +8836,13 @@ static int ipw_wx_set_frag(struct net_device *dev,
8821 union iwreq_data *wrqu, char *extra) 8836 union iwreq_data *wrqu, char *extra)
8822{ 8837{
8823 struct ipw_priv *priv = ieee80211_priv(dev); 8838 struct ipw_priv *priv = ieee80211_priv(dev);
8824 down(&priv->sem); 8839 mutex_lock(&priv->mutex);
8825 if (wrqu->frag.disabled) 8840 if (wrqu->frag.disabled)
8826 priv->ieee->fts = DEFAULT_FTS; 8841 priv->ieee->fts = DEFAULT_FTS;
8827 else { 8842 else {
8828 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 8843 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
8829 wrqu->frag.value > MAX_FRAG_THRESHOLD) { 8844 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
8830 up(&priv->sem); 8845 mutex_unlock(&priv->mutex);
8831 return -EINVAL; 8846 return -EINVAL;
8832 } 8847 }
8833 8848
@@ -8835,7 +8850,7 @@ static int ipw_wx_set_frag(struct net_device *dev,
8835 } 8850 }
8836 8851
8837 ipw_send_frag_threshold(priv, wrqu->frag.value); 8852 ipw_send_frag_threshold(priv, wrqu->frag.value);
8838 up(&priv->sem); 8853 mutex_unlock(&priv->mutex);
8839 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); 8854 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
8840 return 0; 8855 return 0;
8841} 8856}
@@ -8845,11 +8860,11 @@ static int ipw_wx_get_frag(struct net_device *dev,
8845 union iwreq_data *wrqu, char *extra) 8860 union iwreq_data *wrqu, char *extra)
8846{ 8861{
8847 struct ipw_priv *priv = ieee80211_priv(dev); 8862 struct ipw_priv *priv = ieee80211_priv(dev);
8848 down(&priv->sem); 8863 mutex_lock(&priv->mutex);
8849 wrqu->frag.value = priv->ieee->fts; 8864 wrqu->frag.value = priv->ieee->fts;
8850 wrqu->frag.fixed = 0; /* no auto select */ 8865 wrqu->frag.fixed = 0; /* no auto select */
8851 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); 8866 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
8852 up(&priv->sem); 8867 mutex_unlock(&priv->mutex);
8853 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 8868 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
8854 8869
8855 return 0; 8870 return 0;
@@ -8870,7 +8885,7 @@ static int ipw_wx_set_retry(struct net_device *dev,
8870 if (wrqu->retry.value < 0 || wrqu->retry.value > 255) 8885 if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
8871 return -EINVAL; 8886 return -EINVAL;
8872 8887
8873 down(&priv->sem); 8888 mutex_lock(&priv->mutex);
8874 if (wrqu->retry.flags & IW_RETRY_MIN) 8889 if (wrqu->retry.flags & IW_RETRY_MIN)
8875 priv->short_retry_limit = (u8) wrqu->retry.value; 8890 priv->short_retry_limit = (u8) wrqu->retry.value;
8876 else if (wrqu->retry.flags & IW_RETRY_MAX) 8891 else if (wrqu->retry.flags & IW_RETRY_MAX)
@@ -8882,7 +8897,7 @@ static int ipw_wx_set_retry(struct net_device *dev,
8882 8897
8883 ipw_send_retry_limit(priv, priv->short_retry_limit, 8898 ipw_send_retry_limit(priv, priv->short_retry_limit,
8884 priv->long_retry_limit); 8899 priv->long_retry_limit);
8885 up(&priv->sem); 8900 mutex_unlock(&priv->mutex);
8886 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n", 8901 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
8887 priv->short_retry_limit, priv->long_retry_limit); 8902 priv->short_retry_limit, priv->long_retry_limit);
8888 return 0; 8903 return 0;
@@ -8894,11 +8909,11 @@ static int ipw_wx_get_retry(struct net_device *dev,
8894{ 8909{
8895 struct ipw_priv *priv = ieee80211_priv(dev); 8910 struct ipw_priv *priv = ieee80211_priv(dev);
8896 8911
8897 down(&priv->sem); 8912 mutex_lock(&priv->mutex);
8898 wrqu->retry.disabled = 0; 8913 wrqu->retry.disabled = 0;
8899 8914
8900 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { 8915 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
8901 up(&priv->sem); 8916 mutex_unlock(&priv->mutex);
8902 return -EINVAL; 8917 return -EINVAL;
8903 } 8918 }
8904 8919
@@ -8912,7 +8927,7 @@ static int ipw_wx_get_retry(struct net_device *dev,
8912 wrqu->retry.flags = IW_RETRY_LIMIT; 8927 wrqu->retry.flags = IW_RETRY_LIMIT;
8913 wrqu->retry.value = priv->short_retry_limit; 8928 wrqu->retry.value = priv->short_retry_limit;
8914 } 8929 }
8915 up(&priv->sem); 8930 mutex_unlock(&priv->mutex);
8916 8931
8917 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value); 8932 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
8918 8933
@@ -8929,7 +8944,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
8929 (priv->status & STATUS_EXIT_PENDING)) 8944 (priv->status & STATUS_EXIT_PENDING))
8930 return 0; 8945 return 0;
8931 8946
8932 down(&priv->sem); 8947 mutex_lock(&priv->mutex);
8933 8948
8934 if (priv->status & STATUS_RF_KILL_MASK) { 8949 if (priv->status & STATUS_RF_KILL_MASK) {
8935 IPW_DEBUG_HC("Aborting scan due to RF kill activation\n"); 8950 IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
@@ -8981,7 +8996,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
8981 priv->status |= STATUS_SCANNING; 8996 priv->status |= STATUS_SCANNING;
8982 8997
8983 done: 8998 done:
8984 up(&priv->sem); 8999 mutex_unlock(&priv->mutex);
8985 return err; 9000 return err;
8986} 9001}
8987 9002
@@ -9024,7 +9039,7 @@ static int ipw_wx_set_encode(struct net_device *dev,
9024 int ret; 9039 int ret;
9025 u32 cap = priv->capability; 9040 u32 cap = priv->capability;
9026 9041
9027 down(&priv->sem); 9042 mutex_lock(&priv->mutex);
9028 ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); 9043 ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
9029 9044
9030 /* In IBSS mode, we need to notify the firmware to update 9045 /* In IBSS mode, we need to notify the firmware to update
@@ -9034,7 +9049,7 @@ static int ipw_wx_set_encode(struct net_device *dev,
9034 priv->status & STATUS_ASSOCIATED) 9049 priv->status & STATUS_ASSOCIATED)
9035 ipw_disassociate(priv); 9050 ipw_disassociate(priv);
9036 9051
9037 up(&priv->sem); 9052 mutex_unlock(&priv->mutex);
9038 return ret; 9053 return ret;
9039} 9054}
9040 9055
@@ -9052,17 +9067,17 @@ static int ipw_wx_set_power(struct net_device *dev,
9052{ 9067{
9053 struct ipw_priv *priv = ieee80211_priv(dev); 9068 struct ipw_priv *priv = ieee80211_priv(dev);
9054 int err; 9069 int err;
9055 down(&priv->sem); 9070 mutex_lock(&priv->mutex);
9056 if (wrqu->power.disabled) { 9071 if (wrqu->power.disabled) {
9057 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode); 9072 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
9058 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM); 9073 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
9059 if (err) { 9074 if (err) {
9060 IPW_DEBUG_WX("failed setting power mode.\n"); 9075 IPW_DEBUG_WX("failed setting power mode.\n");
9061 up(&priv->sem); 9076 mutex_unlock(&priv->mutex);
9062 return err; 9077 return err;
9063 } 9078 }
9064 IPW_DEBUG_WX("SET Power Management Mode -> off\n"); 9079 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
9065 up(&priv->sem); 9080 mutex_unlock(&priv->mutex);
9066 return 0; 9081 return 0;
9067 } 9082 }
9068 9083
@@ -9074,7 +9089,7 @@ static int ipw_wx_set_power(struct net_device *dev,
9074 default: /* Otherwise we don't support it */ 9089 default: /* Otherwise we don't support it */
9075 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 9090 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
9076 wrqu->power.flags); 9091 wrqu->power.flags);
9077 up(&priv->sem); 9092 mutex_unlock(&priv->mutex);
9078 return -EOPNOTSUPP; 9093 return -EOPNOTSUPP;
9079 } 9094 }
9080 9095
@@ -9087,12 +9102,12 @@ static int ipw_wx_set_power(struct net_device *dev,
9087 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 9102 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
9088 if (err) { 9103 if (err) {
9089 IPW_DEBUG_WX("failed setting power mode.\n"); 9104 IPW_DEBUG_WX("failed setting power mode.\n");
9090 up(&priv->sem); 9105 mutex_unlock(&priv->mutex);
9091 return err; 9106 return err;
9092 } 9107 }
9093 9108
9094 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); 9109 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
9095 up(&priv->sem); 9110 mutex_unlock(&priv->mutex);
9096 return 0; 9111 return 0;
9097} 9112}
9098 9113
@@ -9101,13 +9116,13 @@ static int ipw_wx_get_power(struct net_device *dev,
9101 union iwreq_data *wrqu, char *extra) 9116 union iwreq_data *wrqu, char *extra)
9102{ 9117{
9103 struct ipw_priv *priv = ieee80211_priv(dev); 9118 struct ipw_priv *priv = ieee80211_priv(dev);
9104 down(&priv->sem); 9119 mutex_lock(&priv->mutex);
9105 if (!(priv->power_mode & IPW_POWER_ENABLED)) 9120 if (!(priv->power_mode & IPW_POWER_ENABLED))
9106 wrqu->power.disabled = 1; 9121 wrqu->power.disabled = 1;
9107 else 9122 else
9108 wrqu->power.disabled = 0; 9123 wrqu->power.disabled = 0;
9109 9124
9110 up(&priv->sem); 9125 mutex_unlock(&priv->mutex);
9111 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); 9126 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
9112 9127
9113 return 0; 9128 return 0;
@@ -9120,7 +9135,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
9120 struct ipw_priv *priv = ieee80211_priv(dev); 9135 struct ipw_priv *priv = ieee80211_priv(dev);
9121 int mode = *(int *)extra; 9136 int mode = *(int *)extra;
9122 int err; 9137 int err;
9123 down(&priv->sem); 9138 mutex_lock(&priv->mutex);
9124 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { 9139 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
9125 mode = IPW_POWER_AC; 9140 mode = IPW_POWER_AC;
9126 priv->power_mode = mode; 9141 priv->power_mode = mode;
@@ -9133,11 +9148,11 @@ static int ipw_wx_set_powermode(struct net_device *dev,
9133 9148
9134 if (err) { 9149 if (err) {
9135 IPW_DEBUG_WX("failed setting power mode.\n"); 9150 IPW_DEBUG_WX("failed setting power mode.\n");
9136 up(&priv->sem); 9151 mutex_unlock(&priv->mutex);
9137 return err; 9152 return err;
9138 } 9153 }
9139 } 9154 }
9140 up(&priv->sem); 9155 mutex_unlock(&priv->mutex);
9141 return 0; 9156 return 0;
9142} 9157}
9143 9158
@@ -9186,7 +9201,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
9186 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); 9201 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
9187 return -EINVAL; 9202 return -EINVAL;
9188 } 9203 }
9189 down(&priv->sem); 9204 mutex_lock(&priv->mutex);
9190 if (priv->adapter == IPW_2915ABG) { 9205 if (priv->adapter == IPW_2915ABG) {
9191 priv->ieee->abg_true = 1; 9206 priv->ieee->abg_true = 1;
9192 if (mode & IEEE_A) { 9207 if (mode & IEEE_A) {
@@ -9198,7 +9213,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
9198 if (mode & IEEE_A) { 9213 if (mode & IEEE_A) {
9199 IPW_WARNING("Attempt to set 2200BG into " 9214 IPW_WARNING("Attempt to set 2200BG into "
9200 "802.11a mode\n"); 9215 "802.11a mode\n");
9201 up(&priv->sem); 9216 mutex_unlock(&priv->mutex);
9202 return -EINVAL; 9217 return -EINVAL;
9203 } 9218 }
9204 9219
@@ -9235,7 +9250,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
9235 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", 9250 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
9236 mode & IEEE_A ? 'a' : '.', 9251 mode & IEEE_A ? 'a' : '.',
9237 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); 9252 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
9238 up(&priv->sem); 9253 mutex_unlock(&priv->mutex);
9239 return 0; 9254 return 0;
9240} 9255}
9241 9256
@@ -9244,7 +9259,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
9244 union iwreq_data *wrqu, char *extra) 9259 union iwreq_data *wrqu, char *extra)
9245{ 9260{
9246 struct ipw_priv *priv = ieee80211_priv(dev); 9261 struct ipw_priv *priv = ieee80211_priv(dev);
9247 down(&priv->sem); 9262 mutex_lock(&priv->mutex);
9248 switch (priv->ieee->mode) { 9263 switch (priv->ieee->mode) {
9249 case IEEE_A: 9264 case IEEE_A:
9250 strncpy(extra, "802.11a (1)", MAX_WX_STRING); 9265 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
@@ -9275,7 +9290,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
9275 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); 9290 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
9276 9291
9277 wrqu->data.length = strlen(extra) + 1; 9292 wrqu->data.length = strlen(extra) + 1;
9278 up(&priv->sem); 9293 mutex_unlock(&priv->mutex);
9279 9294
9280 return 0; 9295 return 0;
9281} 9296}
@@ -9286,7 +9301,7 @@ static int ipw_wx_set_preamble(struct net_device *dev,
9286{ 9301{
9287 struct ipw_priv *priv = ieee80211_priv(dev); 9302 struct ipw_priv *priv = ieee80211_priv(dev);
9288 int mode = *(int *)extra; 9303 int mode = *(int *)extra;
9289 down(&priv->sem); 9304 mutex_lock(&priv->mutex);
9290 /* Switching from SHORT -> LONG requires a disassociation */ 9305 /* Switching from SHORT -> LONG requires a disassociation */
9291 if (mode == 1) { 9306 if (mode == 1) {
9292 if (!(priv->config & CFG_PREAMBLE_LONG)) { 9307 if (!(priv->config & CFG_PREAMBLE_LONG)) {
@@ -9305,11 +9320,11 @@ static int ipw_wx_set_preamble(struct net_device *dev,
9305 priv->config &= ~CFG_PREAMBLE_LONG; 9320 priv->config &= ~CFG_PREAMBLE_LONG;
9306 goto done; 9321 goto done;
9307 } 9322 }
9308 up(&priv->sem); 9323 mutex_unlock(&priv->mutex);
9309 return -EINVAL; 9324 return -EINVAL;
9310 9325
9311 done: 9326 done:
9312 up(&priv->sem); 9327 mutex_unlock(&priv->mutex);
9313 return 0; 9328 return 0;
9314} 9329}
9315 9330
@@ -9318,12 +9333,12 @@ static int ipw_wx_get_preamble(struct net_device *dev,
9318 union iwreq_data *wrqu, char *extra) 9333 union iwreq_data *wrqu, char *extra)
9319{ 9334{
9320 struct ipw_priv *priv = ieee80211_priv(dev); 9335 struct ipw_priv *priv = ieee80211_priv(dev);
9321 down(&priv->sem); 9336 mutex_lock(&priv->mutex);
9322 if (priv->config & CFG_PREAMBLE_LONG) 9337 if (priv->config & CFG_PREAMBLE_LONG)
9323 snprintf(wrqu->name, IFNAMSIZ, "long (1)"); 9338 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9324 else 9339 else
9325 snprintf(wrqu->name, IFNAMSIZ, "auto (0)"); 9340 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
9326 up(&priv->sem); 9341 mutex_unlock(&priv->mutex);
9327 return 0; 9342 return 0;
9328} 9343}
9329 9344
@@ -9335,7 +9350,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
9335 struct ipw_priv *priv = ieee80211_priv(dev); 9350 struct ipw_priv *priv = ieee80211_priv(dev);
9336 int *parms = (int *)extra; 9351 int *parms = (int *)extra;
9337 int enable = (parms[0] > 0); 9352 int enable = (parms[0] > 0);
9338 down(&priv->sem); 9353 mutex_lock(&priv->mutex);
9339 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]); 9354 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
9340 if (enable) { 9355 if (enable) {
9341 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 9356 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
@@ -9350,13 +9365,13 @@ static int ipw_wx_set_monitor(struct net_device *dev,
9350 ipw_set_channel(priv, parms[1]); 9365 ipw_set_channel(priv, parms[1]);
9351 } else { 9366 } else {
9352 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 9367 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9353 up(&priv->sem); 9368 mutex_unlock(&priv->mutex);
9354 return 0; 9369 return 0;
9355 } 9370 }
9356 priv->net_dev->type = ARPHRD_ETHER; 9371 priv->net_dev->type = ARPHRD_ETHER;
9357 queue_work(priv->workqueue, &priv->adapter_restart); 9372 queue_work(priv->workqueue, &priv->adapter_restart);
9358 } 9373 }
9359 up(&priv->sem); 9374 mutex_unlock(&priv->mutex);
9360 return 0; 9375 return 0;
9361} 9376}
9362 9377
@@ -9386,9 +9401,9 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9386 9401
9387 IPW_DEBUG_WX("SW_RESET\n"); 9402 IPW_DEBUG_WX("SW_RESET\n");
9388 9403
9389 down(&priv->sem); 9404 mutex_lock(&priv->mutex);
9390 9405
9391 ret = ipw_sw_reset(priv, 0); 9406 ret = ipw_sw_reset(priv, 2);
9392 if (!ret) { 9407 if (!ret) {
9393 free_firmware(); 9408 free_firmware();
9394 ipw_adapter_restart(priv); 9409 ipw_adapter_restart(priv);
@@ -9398,9 +9413,9 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9398 * module parameter, so take appropriate action */ 9413 * module parameter, so take appropriate action */
9399 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW); 9414 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
9400 9415
9401 up(&priv->sem); 9416 mutex_unlock(&priv->mutex);
9402 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL); 9417 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
9403 down(&priv->sem); 9418 mutex_lock(&priv->mutex);
9404 9419
9405 if (!(priv->status & STATUS_RF_KILL_MASK)) { 9420 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9406 /* Configuration likely changed -- force [re]association */ 9421 /* Configuration likely changed -- force [re]association */
@@ -9410,7 +9425,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9410 ipw_associate(priv); 9425 ipw_associate(priv);
9411 } 9426 }
9412 9427
9413 up(&priv->sem); 9428 mutex_unlock(&priv->mutex);
9414 9429
9415 return 0; 9430 return 0;
9416} 9431}
@@ -9423,6 +9438,8 @@ static iw_handler ipw_wx_handlers[] = {
9423 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 9438 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
9424 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 9439 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
9425 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 9440 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
9441 IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens,
9442 IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens,
9426 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 9443 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
9427 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 9444 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
9428 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 9445 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
@@ -9568,7 +9585,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
9568 wstats->qual.level = average_value(&priv->average_rssi); 9585 wstats->qual.level = average_value(&priv->average_rssi);
9569 wstats->qual.noise = average_value(&priv->average_noise); 9586 wstats->qual.noise = average_value(&priv->average_noise);
9570 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | 9587 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
9571 IW_QUAL_NOISE_UPDATED; 9588 IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
9572 9589
9573 wstats->miss.beacon = average_value(&priv->average_missed_beacons); 9590 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
9574 wstats->discard.retries = priv->last_tx_failures; 9591 wstats->discard.retries = priv->last_tx_failures;
@@ -9586,7 +9603,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
9586static void init_sys_config(struct ipw_sys_config *sys_config) 9603static void init_sys_config(struct ipw_sys_config *sys_config)
9587{ 9604{
9588 memset(sys_config, 0, sizeof(struct ipw_sys_config)); 9605 memset(sys_config, 0, sizeof(struct ipw_sys_config));
9589 sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */ 9606 sys_config->bt_coexistence = 0;
9590 sys_config->answer_broadcast_ssid_probe = 0; 9607 sys_config->answer_broadcast_ssid_probe = 0;
9591 sys_config->accept_all_data_frames = 0; 9608 sys_config->accept_all_data_frames = 0;
9592 sys_config->accept_non_directed_frames = 1; 9609 sys_config->accept_non_directed_frames = 1;
@@ -9594,12 +9611,13 @@ static void init_sys_config(struct ipw_sys_config *sys_config)
9594 sys_config->disable_unicast_decryption = 1; 9611 sys_config->disable_unicast_decryption = 1;
9595 sys_config->exclude_multicast_unencrypted = 0; 9612 sys_config->exclude_multicast_unencrypted = 0;
9596 sys_config->disable_multicast_decryption = 1; 9613 sys_config->disable_multicast_decryption = 1;
9597 sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH; 9614 sys_config->antenna_diversity = CFG_SYS_ANTENNA_SLOW_DIV;
9598 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */ 9615 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */
9599 sys_config->dot11g_auto_detection = 0; 9616 sys_config->dot11g_auto_detection = 0;
9600 sys_config->enable_cts_to_self = 0; 9617 sys_config->enable_cts_to_self = 0;
9601 sys_config->bt_coexist_collision_thr = 0; 9618 sys_config->bt_coexist_collision_thr = 0;
9602 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256 9619 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
9620 sys_config->silence_threshold = 0x1e;
9603} 9621}
9604 9622
9605static int ipw_net_open(struct net_device *dev) 9623static int ipw_net_open(struct net_device *dev)
@@ -9607,11 +9625,11 @@ static int ipw_net_open(struct net_device *dev)
9607 struct ipw_priv *priv = ieee80211_priv(dev); 9625 struct ipw_priv *priv = ieee80211_priv(dev);
9608 IPW_DEBUG_INFO("dev->open\n"); 9626 IPW_DEBUG_INFO("dev->open\n");
9609 /* we should be verifying the device is ready to be opened */ 9627 /* we should be verifying the device is ready to be opened */
9610 down(&priv->sem); 9628 mutex_lock(&priv->mutex);
9611 if (!(priv->status & STATUS_RF_KILL_MASK) && 9629 if (!(priv->status & STATUS_RF_KILL_MASK) &&
9612 (priv->status & STATUS_ASSOCIATED)) 9630 (priv->status & STATUS_ASSOCIATED))
9613 netif_start_queue(dev); 9631 netif_start_queue(dev);
9614 up(&priv->sem); 9632 mutex_unlock(&priv->mutex);
9615 return 0; 9633 return 0;
9616} 9634}
9617 9635
@@ -9647,11 +9665,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9647 u16 remaining_bytes; 9665 u16 remaining_bytes;
9648 int fc; 9666 int fc;
9649 9667
9650 /* If there isn't room in the queue, we return busy and let the
9651 * network stack requeue the packet for us */
9652 if (ipw_queue_space(q) < q->high_mark)
9653 return NETDEV_TX_BUSY;
9654
9655 switch (priv->ieee->iw_mode) { 9668 switch (priv->ieee->iw_mode) {
9656 case IW_MODE_ADHOC: 9669 case IW_MODE_ADHOC:
9657 hdr_len = IEEE80211_3ADDR_LEN; 9670 hdr_len = IEEE80211_3ADDR_LEN;
@@ -9817,6 +9830,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9817 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); 9830 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
9818 ipw_write32(priv, q->reg_w, q->first_empty); 9831 ipw_write32(priv, q->reg_w, q->first_empty);
9819 9832
9833 if (ipw_queue_space(q) < q->high_mark)
9834 netif_stop_queue(priv->net_dev);
9835
9820 return NETDEV_TX_OK; 9836 return NETDEV_TX_OK;
9821 9837
9822 drop: 9838 drop:
@@ -9890,13 +9906,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
9890 struct sockaddr *addr = p; 9906 struct sockaddr *addr = p;
9891 if (!is_valid_ether_addr(addr->sa_data)) 9907 if (!is_valid_ether_addr(addr->sa_data))
9892 return -EADDRNOTAVAIL; 9908 return -EADDRNOTAVAIL;
9893 down(&priv->sem); 9909 mutex_lock(&priv->mutex);
9894 priv->config |= CFG_CUSTOM_MAC; 9910 priv->config |= CFG_CUSTOM_MAC;
9895 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); 9911 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
9896 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", 9912 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
9897 priv->net_dev->name, MAC_ARG(priv->mac_addr)); 9913 priv->net_dev->name, MAC_ARG(priv->mac_addr));
9898 queue_work(priv->workqueue, &priv->adapter_restart); 9914 queue_work(priv->workqueue, &priv->adapter_restart);
9899 up(&priv->sem); 9915 mutex_unlock(&priv->mutex);
9900 return 0; 9916 return 0;
9901} 9917}
9902 9918
@@ -9940,9 +9956,9 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
9940 9956
9941 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE) 9957 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
9942 return -EINVAL; 9958 return -EINVAL;
9943 down(&p->sem); 9959 mutex_lock(&p->mutex);
9944 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len); 9960 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
9945 up(&p->sem); 9961 mutex_unlock(&p->mutex);
9946 return 0; 9962 return 0;
9947} 9963}
9948 9964
@@ -9954,12 +9970,11 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
9954 9970
9955 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE) 9971 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
9956 return -EINVAL; 9972 return -EINVAL;
9957 down(&p->sem); 9973 mutex_lock(&p->mutex);
9958 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); 9974 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
9959 for (i = IPW_EEPROM_DATA; 9975 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
9960 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++) 9976 ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]);
9961 ipw_write8(p, i, p->eeprom[i]); 9977 mutex_unlock(&p->mutex);
9962 up(&p->sem);
9963 return 0; 9978 return 0;
9964} 9979}
9965 9980
@@ -10054,12 +10069,12 @@ static void ipw_rf_kill(void *adapter)
10054static void ipw_bg_rf_kill(void *data) 10069static void ipw_bg_rf_kill(void *data)
10055{ 10070{
10056 struct ipw_priv *priv = data; 10071 struct ipw_priv *priv = data;
10057 down(&priv->sem); 10072 mutex_lock(&priv->mutex);
10058 ipw_rf_kill(data); 10073 ipw_rf_kill(data);
10059 up(&priv->sem); 10074 mutex_unlock(&priv->mutex);
10060} 10075}
10061 10076
10062void ipw_link_up(struct ipw_priv *priv) 10077static void ipw_link_up(struct ipw_priv *priv)
10063{ 10078{
10064 priv->last_seq_num = -1; 10079 priv->last_seq_num = -1;
10065 priv->last_frag_num = -1; 10080 priv->last_frag_num = -1;
@@ -10089,12 +10104,12 @@ void ipw_link_up(struct ipw_priv *priv)
10089static void ipw_bg_link_up(void *data) 10104static void ipw_bg_link_up(void *data)
10090{ 10105{
10091 struct ipw_priv *priv = data; 10106 struct ipw_priv *priv = data;
10092 down(&priv->sem); 10107 mutex_lock(&priv->mutex);
10093 ipw_link_up(data); 10108 ipw_link_up(data);
10094 up(&priv->sem); 10109 mutex_unlock(&priv->mutex);
10095} 10110}
10096 10111
10097void ipw_link_down(struct ipw_priv *priv) 10112static void ipw_link_down(struct ipw_priv *priv)
10098{ 10113{
10099 ipw_led_link_down(priv); 10114 ipw_led_link_down(priv);
10100 netif_carrier_off(priv->net_dev); 10115 netif_carrier_off(priv->net_dev);
@@ -10117,9 +10132,9 @@ void ipw_link_down(struct ipw_priv *priv)
10117static void ipw_bg_link_down(void *data) 10132static void ipw_bg_link_down(void *data)
10118{ 10133{
10119 struct ipw_priv *priv = data; 10134 struct ipw_priv *priv = data;
10120 down(&priv->sem); 10135 mutex_lock(&priv->mutex);
10121 ipw_link_down(data); 10136 ipw_link_down(data);
10122 up(&priv->sem); 10137 mutex_unlock(&priv->mutex);
10123} 10138}
10124 10139
10125static int ipw_setup_deferred_work(struct ipw_priv *priv) 10140static int ipw_setup_deferred_work(struct ipw_priv *priv)
@@ -10292,6 +10307,20 @@ static int ipw_config(struct ipw_priv *priv)
10292 10307
10293 /* set basic system config settings */ 10308 /* set basic system config settings */
10294 init_sys_config(&priv->sys_config); 10309 init_sys_config(&priv->sys_config);
10310
10311 /* Support Bluetooth if we have BT h/w on board, and user wants to.
10312 * Does not support BT priority yet (don't abort or defer our Tx) */
10313 if (bt_coexist) {
10314 unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY];
10315
10316 if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG)
10317 priv->sys_config.bt_coexistence
10318 |= CFG_BT_COEXISTENCE_SIGNAL_CHNL;
10319 if (bt_caps & EEPROM_SKU_CAP_BT_OOB)
10320 priv->sys_config.bt_coexistence
10321 |= CFG_BT_COEXISTENCE_OOB;
10322 }
10323
10295 if (priv->ieee->iw_mode == IW_MODE_ADHOC) 10324 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10296 priv->sys_config.answer_broadcast_ssid_probe = 1; 10325 priv->sys_config.answer_broadcast_ssid_probe = 1;
10297 else 10326 else
@@ -10349,6 +10378,9 @@ static int ipw_config(struct ipw_priv *priv)
10349 * not intended for resale of the above mentioned Intel adapters has 10378 * not intended for resale of the above mentioned Intel adapters has
10350 * not been tested. 10379 * not been tested.
10351 * 10380 *
10381 * Remember to update the table in README.ipw2200 when changing this
10382 * table.
10383 *
10352 */ 10384 */
10353static const struct ieee80211_geo ipw_geos[] = { 10385static const struct ieee80211_geo ipw_geos[] = {
10354 { /* Restricted */ 10386 { /* Restricted */
@@ -10596,96 +10628,6 @@ static const struct ieee80211_geo ipw_geos[] = {
10596 } 10628 }
10597}; 10629};
10598 10630
10599/* GEO code borrowed from ieee80211_geo.c */
10600static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
10601{
10602 int i;
10603
10604 /* Driver needs to initialize the geography map before using
10605 * these helper functions */
10606 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10607
10608 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10609 for (i = 0; i < ieee->geo.bg_channels; i++)
10610 /* NOTE: If G mode is currently supported but
10611 * this is a B only channel, we don't see it
10612 * as valid. */
10613 if ((ieee->geo.bg[i].channel == channel) &&
10614 (!(ieee->mode & IEEE_G) ||
10615 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
10616 return IEEE80211_24GHZ_BAND;
10617
10618 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10619 for (i = 0; i < ieee->geo.a_channels; i++)
10620 if (ieee->geo.a[i].channel == channel)
10621 return IEEE80211_52GHZ_BAND;
10622
10623 return 0;
10624}
10625
10626static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
10627{
10628 int i;
10629
10630 /* Driver needs to initialize the geography map before using
10631 * these helper functions */
10632 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10633
10634 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10635 for (i = 0; i < ieee->geo.bg_channels; i++)
10636 if (ieee->geo.bg[i].channel == channel)
10637 return i;
10638
10639 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10640 for (i = 0; i < ieee->geo.a_channels; i++)
10641 if (ieee->geo.a[i].channel == channel)
10642 return i;
10643
10644 return -1;
10645}
10646
10647static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
10648{
10649 int i;
10650
10651 /* Driver needs to initialize the geography map before using
10652 * these helper functions */
10653 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10654
10655 freq /= 100000;
10656
10657 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10658 for (i = 0; i < ieee->geo.bg_channels; i++)
10659 if (ieee->geo.bg[i].freq == freq)
10660 return ieee->geo.bg[i].channel;
10661
10662 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10663 for (i = 0; i < ieee->geo.a_channels; i++)
10664 if (ieee->geo.a[i].freq == freq)
10665 return ieee->geo.a[i].channel;
10666
10667 return 0;
10668}
10669
10670static int ipw_set_geo(struct ieee80211_device *ieee,
10671 const struct ieee80211_geo *geo)
10672{
10673 memcpy(ieee->geo.name, geo->name, 3);
10674 ieee->geo.name[3] = '\0';
10675 ieee->geo.bg_channels = geo->bg_channels;
10676 ieee->geo.a_channels = geo->a_channels;
10677 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
10678 sizeof(struct ieee80211_channel));
10679 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
10680 sizeof(struct ieee80211_channel));
10681 return 0;
10682}
10683
10684static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
10685{
10686 return &ieee->geo;
10687}
10688
10689#define MAX_HW_RESTARTS 5 10631#define MAX_HW_RESTARTS 5
10690static int ipw_up(struct ipw_priv *priv) 10632static int ipw_up(struct ipw_priv *priv)
10691{ 10633{
@@ -10732,14 +10674,11 @@ static int ipw_up(struct ipw_priv *priv)
10732 priv->eeprom[EEPROM_COUNTRY_CODE + 2]); 10674 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
10733 j = 0; 10675 j = 0;
10734 } 10676 }
10735 if (ipw_set_geo(priv->ieee, &ipw_geos[j])) { 10677 if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) {
10736 IPW_WARNING("Could not set geography."); 10678 IPW_WARNING("Could not set geography.");
10737 return 0; 10679 return 0;
10738 } 10680 }
10739 10681
10740 IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
10741 j, priv->ieee->geo.name);
10742
10743 if (priv->status & STATUS_RF_KILL_SW) { 10682 if (priv->status & STATUS_RF_KILL_SW) {
10744 IPW_WARNING("Radio disabled by module parameter.\n"); 10683 IPW_WARNING("Radio disabled by module parameter.\n");
10745 return 0; 10684 return 0;
@@ -10782,9 +10721,9 @@ static int ipw_up(struct ipw_priv *priv)
10782static void ipw_bg_up(void *data) 10721static void ipw_bg_up(void *data)
10783{ 10722{
10784 struct ipw_priv *priv = data; 10723 struct ipw_priv *priv = data;
10785 down(&priv->sem); 10724 mutex_lock(&priv->mutex);
10786 ipw_up(data); 10725 ipw_up(data);
10787 up(&priv->sem); 10726 mutex_unlock(&priv->mutex);
10788} 10727}
10789 10728
10790static void ipw_deinit(struct ipw_priv *priv) 10729static void ipw_deinit(struct ipw_priv *priv)
@@ -10853,23 +10792,23 @@ static void ipw_down(struct ipw_priv *priv)
10853static void ipw_bg_down(void *data) 10792static void ipw_bg_down(void *data)
10854{ 10793{
10855 struct ipw_priv *priv = data; 10794 struct ipw_priv *priv = data;
10856 down(&priv->sem); 10795 mutex_lock(&priv->mutex);
10857 ipw_down(data); 10796 ipw_down(data);
10858 up(&priv->sem); 10797 mutex_unlock(&priv->mutex);
10859} 10798}
10860 10799
10861/* Called by register_netdev() */ 10800/* Called by register_netdev() */
10862static int ipw_net_init(struct net_device *dev) 10801static int ipw_net_init(struct net_device *dev)
10863{ 10802{
10864 struct ipw_priv *priv = ieee80211_priv(dev); 10803 struct ipw_priv *priv = ieee80211_priv(dev);
10865 down(&priv->sem); 10804 mutex_lock(&priv->mutex);
10866 10805
10867 if (ipw_up(priv)) { 10806 if (ipw_up(priv)) {
10868 up(&priv->sem); 10807 mutex_unlock(&priv->mutex);
10869 return -EIO; 10808 return -EIO;
10870 } 10809 }
10871 10810
10872 up(&priv->sem); 10811 mutex_unlock(&priv->mutex);
10873 return 0; 10812 return 0;
10874} 10813}
10875 10814
@@ -10959,7 +10898,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
10959 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) 10898 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
10960 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); 10899 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
10961 10900
10962 init_MUTEX(&priv->sem); 10901 mutex_init(&priv->mutex);
10963 if (pci_enable_device(pdev)) { 10902 if (pci_enable_device(pdev)) {
10964 err = -ENODEV; 10903 err = -ENODEV;
10965 goto out_free_ieee80211; 10904 goto out_free_ieee80211;
@@ -11017,7 +10956,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11017 SET_MODULE_OWNER(net_dev); 10956 SET_MODULE_OWNER(net_dev);
11018 SET_NETDEV_DEV(net_dev, &pdev->dev); 10957 SET_NETDEV_DEV(net_dev, &pdev->dev);
11019 10958
11020 down(&priv->sem); 10959 mutex_lock(&priv->mutex);
11021 10960
11022 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; 10961 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
11023 priv->ieee->set_security = shim__set_security; 10962 priv->ieee->set_security = shim__set_security;
@@ -11050,16 +10989,22 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11050 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); 10989 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
11051 if (err) { 10990 if (err) {
11052 IPW_ERROR("failed to create sysfs device attributes\n"); 10991 IPW_ERROR("failed to create sysfs device attributes\n");
11053 up(&priv->sem); 10992 mutex_unlock(&priv->mutex);
11054 goto out_release_irq; 10993 goto out_release_irq;
11055 } 10994 }
11056 10995
11057 up(&priv->sem); 10996 mutex_unlock(&priv->mutex);
11058 err = register_netdev(net_dev); 10997 err = register_netdev(net_dev);
11059 if (err) { 10998 if (err) {
11060 IPW_ERROR("failed to register network device\n"); 10999 IPW_ERROR("failed to register network device\n");
11061 goto out_remove_sysfs; 11000 goto out_remove_sysfs;
11062 } 11001 }
11002
11003 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "
11004 "channels, %d 802.11a channels)\n",
11005 priv->ieee->geo.name, priv->ieee->geo.bg_channels,
11006 priv->ieee->geo.a_channels);
11007
11063 return 0; 11008 return 0;
11064 11009
11065 out_remove_sysfs: 11010 out_remove_sysfs:
@@ -11091,13 +11036,13 @@ static void ipw_pci_remove(struct pci_dev *pdev)
11091 if (!priv) 11036 if (!priv)
11092 return; 11037 return;
11093 11038
11094 down(&priv->sem); 11039 mutex_lock(&priv->mutex);
11095 11040
11096 priv->status |= STATUS_EXIT_PENDING; 11041 priv->status |= STATUS_EXIT_PENDING;
11097 ipw_down(priv); 11042 ipw_down(priv);
11098 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11043 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
11099 11044
11100 up(&priv->sem); 11045 mutex_unlock(&priv->mutex);
11101 11046
11102 unregister_netdev(priv->net_dev); 11047 unregister_netdev(priv->net_dev);
11103 11048
@@ -11250,8 +11195,10 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
11250module_param(led, int, 0444); 11195module_param(led, int, 0444);
11251MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); 11196MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
11252 11197
11198#ifdef CONFIG_IPW2200_DEBUG
11253module_param(debug, int, 0444); 11199module_param(debug, int, 0444);
11254MODULE_PARM_DESC(debug, "debug output mask"); 11200MODULE_PARM_DESC(debug, "debug output mask");
11201#endif
11255 11202
11256module_param(channel, int, 0444); 11203module_param(channel, int, 0444);
11257MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11204MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
@@ -11281,12 +11228,18 @@ module_param(mode, int, 0444);
11281MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); 11228MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
11282#endif 11229#endif
11283 11230
11231module_param(bt_coexist, int, 0444);
11232MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)");
11233
11284module_param(hwcrypto, int, 0444); 11234module_param(hwcrypto, int, 0444);
11285MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)"); 11235MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)");
11286 11236
11287module_param(cmdlog, int, 0444); 11237module_param(cmdlog, int, 0444);
11288MODULE_PARM_DESC(cmdlog, 11238MODULE_PARM_DESC(cmdlog,
11289 "allocate a ring buffer for logging firmware commands"); 11239 "allocate a ring buffer for logging firmware commands");
11290 11240
11241module_param(roaming, int, 0444);
11242MODULE_PARM_DESC(roaming, "enable roaming support (default on)");
11243
11291module_exit(ipw_exit); 11244module_exit(ipw_exit);
11292module_init(ipw_init); 11245module_init(ipw_init);