aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/README.ipw210012
-rw-r--r--Documentation/networking/README.ipw220044
-rw-r--r--drivers/net/wireless/ipw2100.c220
-rw-r--r--drivers/net/wireless/ipw2100.h11
-rw-r--r--drivers/net/wireless/ipw2200.c450
-rw-r--r--drivers/net/wireless/ipw2200.h39
-rw-r--r--net/ieee80211/ieee80211_rx.c14
7 files changed, 415 insertions, 375 deletions
diff --git a/Documentation/networking/README.ipw2100 b/Documentation/networking/README.ipw2100
index 3ab40379d1c..f3fcaa41f77 100644
--- a/Documentation/networking/README.ipw2100
+++ b/Documentation/networking/README.ipw2100
@@ -3,18 +3,18 @@ Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
3 3
4Intel(R) PRO/Wireless 2100 Network Connection 4Intel(R) PRO/Wireless 2100 Network Connection
5 5
6Copyright (C) 2003-2005, Intel Corporation 6Copyright (C) 2003-2006, Intel Corporation
7 7
8README.ipw2100 8README.ipw2100
9 9
10Version: 1.1.3 10Version: git-1.1.5
11Date : October 17, 2005 11Date : January 25, 2006
12 12
13Index 13Index
14----------------------------------------------- 14-----------------------------------------------
150. IMPORTANT INFORMATION BEFORE USING THIS DRIVER 150. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
161. Introduction 161. Introduction
172. Release 1.1.3 Current Features 172. Release git-1.1.5 Current Features
183. Command Line Parameters 183. Command Line Parameters
194. Sysfs Helper Files 194. Sysfs Helper Files
205. Radio Kill Switch 205. Radio Kill Switch
@@ -89,7 +89,7 @@ potential fixes and patches, as well as links to the development mailing list
89for the driver project. 89for the driver project.
90 90
91 91
922. Release 1.1.3 Current Supported Features 922. Release git-1.1.5 Current Supported Features
93----------------------------------------------- 93-----------------------------------------------
94- Managed (BSS) and Ad-Hoc (IBSS) 94- Managed (BSS) and Ad-Hoc (IBSS)
95- WEP (shared key and open) 95- WEP (shared key and open)
@@ -270,7 +270,7 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
2709. License 2709. License
271----------------------------------------------- 271-----------------------------------------------
272 272
273 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 273 Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
274 274
275 This program is free software; you can redistribute it and/or modify it 275 This program is free software; you can redistribute it and/or modify it
276 under the terms of the GNU General Public License (version 2) as 276 under the terms of the GNU General Public License (version 2) as
diff --git a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200
index c6492d3839f..acb30c5dcff 100644
--- a/Documentation/networking/README.ipw2200
+++ b/Documentation/networking/README.ipw2200
@@ -10,7 +10,7 @@ both hardware adapters listed above. In this document the Intel(R)
10PRO/Wireless 2915ABG Driver for Linux will be used to reference the 10PRO/Wireless 2915ABG Driver for Linux will be used to reference the
11unified driver. 11unified driver.
12 12
13Copyright (C) 2004-2005, Intel Corporation 13Copyright (C) 2004-2006, Intel Corporation
14 14
15README.ipw2200 15README.ipw2200
16 16
@@ -26,9 +26,11 @@ Index
261.2. Module parameters 261.2. Module parameters
271.3. Wireless Extension Private Methods 271.3. Wireless Extension Private Methods
281.4. Sysfs Helper Files 281.4. Sysfs Helper Files
291.5. Supported channels
292. Ad-Hoc Networking 302. Ad-Hoc Networking
303. Interacting with Wireless Tools 313. Interacting with Wireless Tools
313.1. iwconfig mode 323.1. iwconfig mode
333.2. iwconfig sens
324. About the Version Numbers 344. About the Version Numbers
335. Firmware installation 355. Firmware installation
346. Support 366. Support
@@ -314,6 +316,35 @@ For the device level files, see /sys/bus/pci/drivers/ipw2200:
314 running ifconfig and is therefore disabled by default. 316 running ifconfig and is therefore disabled by default.
315 317
316 318
3191.5. Supported channels
320-----------------------------------------------
321
322Upon loading the Intel(R) PRO/Wireless 2915ABG Driver for Linux, a
323message stating the detected geography code and the number of 802.11
324channels supported by the card will be displayed in the log.
325
326The geography code corresponds to a regulatory domain as shown in the
327table below.
328
329 Supported channels
330Code Geography 802.11bg 802.11a
331
332--- Restricted 11 0
333ZZF Custom US/Canada 11 8
334ZZD Rest of World 13 0
335ZZA Custom USA & Europe & High 11 13
336ZZB Custom NA & Europe 11 13
337ZZC Custom Japan 11 4
338ZZM Custom 11 0
339ZZE Europe 13 19
340ZZJ Custom Japan 14 4
341ZZR Rest of World 14 0
342ZZH High Band 13 4
343ZZG Custom Europe 13 4
344ZZK Europe 13 24
345ZZL Europe 11 13
346
347
3172. Ad-Hoc Networking 3482. Ad-Hoc Networking
318----------------------------------------------- 349-----------------------------------------------
319 350
@@ -353,6 +384,15 @@ When configuring the mode of the adapter, all run-time configured parameters
353are reset to the value used when the module was loaded. This includes 384are reset to the value used when the module was loaded. This includes
354channels, rates, ESSID, etc. 385channels, rates, ESSID, etc.
355 386
3873.2 iwconfig sens
388-----------------------------------------------
389
390The 'iwconfig ethX sens XX' command will not set the signal sensitivity
391threshold, as described in iwconfig documentation, but rather the number
392of consecutive missed beacons that will trigger handover, i.e. roaming
393to another access point. At the same time, it will set the disassociation
394threshold to 3 times the given value.
395
356 396
3574. About the Version Numbers 3974. About the Version Numbers
358----------------------------------------------- 398-----------------------------------------------
@@ -408,7 +448,7 @@ For general information and support, go to:
4087. License 4487. License
409----------------------------------------------- 449-----------------------------------------------
410 450
411 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 451 Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
412 452
413 This program is free software; you can redistribute it and/or modify it 453 This program is free software; you can redistribute it and/or modify it
414 under the terms of the GNU General Public License version 2 as 454 under the terms of the GNU General Public License version 2 as
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index eb79198ac45..72335c8eb97 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.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 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -167,12 +167,12 @@ that only one external action is invoked at a time.
167 167
168#include "ipw2100.h" 168#include "ipw2100.h"
169 169
170#define IPW2100_VERSION "git-1.1.4" 170#define IPW2100_VERSION "git-1.2.2"
171 171
172#define DRV_NAME "ipw2100" 172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION 173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
176 176
177/* Debugging stuff */ 177/* Debugging stuff */
178#ifdef CONFIG_IPW2100_DEBUG 178#ifdef CONFIG_IPW2100_DEBUG
@@ -1418,7 +1418,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1418 if (priv->status & STATUS_ENABLED) 1418 if (priv->status & STATUS_ENABLED)
1419 return 0; 1419 return 0;
1420 1420
1421 down(&priv->adapter_sem); 1421 mutex_lock(&priv->adapter_mutex);
1422 1422
1423 if (rf_kill_active(priv)) { 1423 if (rf_kill_active(priv)) {
1424 IPW_DEBUG_HC("Command aborted due to RF kill active.\n"); 1424 IPW_DEBUG_HC("Command aborted due to RF kill active.\n");
@@ -1444,7 +1444,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1444 } 1444 }
1445 1445
1446 fail_up: 1446 fail_up:
1447 up(&priv->adapter_sem); 1447 mutex_unlock(&priv->adapter_mutex);
1448 return err; 1448 return err;
1449} 1449}
1450 1450
@@ -1576,7 +1576,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1576 cancel_delayed_work(&priv->hang_check); 1576 cancel_delayed_work(&priv->hang_check);
1577 } 1577 }
1578 1578
1579 down(&priv->adapter_sem); 1579 mutex_lock(&priv->adapter_mutex);
1580 1580
1581 err = ipw2100_hw_send_command(priv, &cmd); 1581 err = ipw2100_hw_send_command(priv, &cmd);
1582 if (err) { 1582 if (err) {
@@ -1595,7 +1595,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1595 IPW_DEBUG_INFO("TODO: implement scan state machine\n"); 1595 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1596 1596
1597 fail_up: 1597 fail_up:
1598 up(&priv->adapter_sem); 1598 mutex_unlock(&priv->adapter_mutex);
1599 return err; 1599 return err;
1600} 1600}
1601 1601
@@ -1888,7 +1888,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1888 priv->status |= STATUS_RESET_PENDING; 1888 priv->status |= STATUS_RESET_PENDING;
1889 spin_unlock_irqrestore(&priv->low_lock, flags); 1889 spin_unlock_irqrestore(&priv->low_lock, flags);
1890 1890
1891 down(&priv->action_sem); 1891 mutex_lock(&priv->action_mutex);
1892 /* stop timed checks so that they don't interfere with reset */ 1892 /* stop timed checks so that they don't interfere with reset */
1893 priv->stop_hang_check = 1; 1893 priv->stop_hang_check = 1;
1894 cancel_delayed_work(&priv->hang_check); 1894 cancel_delayed_work(&priv->hang_check);
@@ -1898,7 +1898,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1898 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); 1898 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1899 1899
1900 ipw2100_up(priv, 0); 1900 ipw2100_up(priv, 0);
1901 up(&priv->action_sem); 1901 mutex_unlock(&priv->action_mutex);
1902 1902
1903} 1903}
1904 1904
@@ -2390,15 +2390,6 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
2390 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); 2390 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2391 return; 2391 return;
2392 } 2392 }
2393#ifdef CONFIG_IPW2100_MONITOR
2394 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2395 priv->config & CFG_CRC_CHECK &&
2396 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2397 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2398 priv->ieee->stats.rx_errors++;
2399 return;
2400 }
2401#endif
2402 2393
2403 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && 2394 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2404 !(priv->status & STATUS_ASSOCIATED))) { 2395 !(priv->status & STATUS_ASSOCIATED))) {
@@ -2446,6 +2437,89 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
2446 priv->rx_queue.drv[i].host_addr = packet->dma_addr; 2437 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
2447} 2438}
2448 2439
2440#ifdef CONFIG_IPW2100_MONITOR
2441
2442static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
2443 struct ieee80211_rx_stats *stats)
2444{
2445 struct ipw2100_status *status = &priv->status_queue.drv[i];
2446 struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
2447
2448 /* Magic struct that slots into the radiotap header -- no reason
2449 * to build this manually element by element, we can write it much
2450 * more efficiently than we can parse it. ORDER MATTERS HERE */
2451 struct ipw_rt_hdr {
2452 struct ieee80211_radiotap_header rt_hdr;
2453 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
2454 } *ipw_rt;
2455
2456 IPW_DEBUG_RX("Handler...\n");
2457
2458 if (unlikely(status->frame_size > skb_tailroom(packet->skb) -
2459 sizeof(struct ipw_rt_hdr))) {
2460 IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
2461 " Dropping.\n",
2462 priv->net_dev->name,
2463 status->frame_size,
2464 skb_tailroom(packet->skb));
2465 priv->ieee->stats.rx_errors++;
2466 return;
2467 }
2468
2469 if (unlikely(!netif_running(priv->net_dev))) {
2470 priv->ieee->stats.rx_errors++;
2471 priv->wstats.discard.misc++;
2472 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2473 return;
2474 }
2475
2476 if (unlikely(priv->config & CFG_CRC_CHECK &&
2477 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2478 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2479 priv->ieee->stats.rx_errors++;
2480 return;
2481 }
2482
2483 pci_unmap_single(priv->pci_dev, packet->dma_addr,
2484 sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
2485 memmove(packet->skb->data + sizeof(struct ipw_rt_hdr),
2486 packet->skb->data, status->frame_size);
2487
2488 ipw_rt = (struct ipw_rt_hdr *) packet->skb->data;
2489
2490 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
2491 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
2492 ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total hdr+data */
2493
2494 ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL;
2495
2496 ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM;
2497
2498 skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
2499
2500 if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
2501 priv->ieee->stats.rx_errors++;
2502
2503 /* ieee80211_rx failed, so it didn't free the SKB */
2504 dev_kfree_skb_any(packet->skb);
2505 packet->skb = NULL;
2506 }
2507
2508 /* We need to allocate a new SKB and attach it to the RDB. */
2509 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
2510 IPW_DEBUG_WARNING(
2511 "%s: Unable to allocate SKB onto RBD ring - disabling "
2512 "adapter.\n", priv->net_dev->name);
2513 /* TODO: schedule adapter shutdown */
2514 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2515 }
2516
2517 /* Update the RDB entry */
2518 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
2519}
2520
2521#endif
2522
2449static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i) 2523static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
2450{ 2524{
2451 struct ipw2100_status *status = &priv->status_queue.drv[i]; 2525 struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2577,7 +2651,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
2577 case P8023_DATA_VAL: 2651 case P8023_DATA_VAL:
2578#ifdef CONFIG_IPW2100_MONITOR 2652#ifdef CONFIG_IPW2100_MONITOR
2579 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 2653 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
2580 isr_rx(priv, i, &stats); 2654 isr_rx_monitor(priv, i, &stats);
2581 break; 2655 break;
2582 } 2656 }
2583#endif 2657#endif
@@ -3882,7 +3956,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3882#ifdef CONFIG_IPW2100_MONITOR 3956#ifdef CONFIG_IPW2100_MONITOR
3883 case IW_MODE_MONITOR: 3957 case IW_MODE_MONITOR:
3884 priv->last_mode = priv->ieee->iw_mode; 3958 priv->last_mode = priv->ieee->iw_mode;
3885 priv->net_dev->type = ARPHRD_IEEE80211; 3959 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
3886 break; 3960 break;
3887#endif /* CONFIG_IPW2100_MONITOR */ 3961#endif /* CONFIG_IPW2100_MONITOR */
3888 } 3962 }
@@ -4138,7 +4212,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4138 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 4212 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4139 disable_radio ? "OFF" : "ON"); 4213 disable_radio ? "OFF" : "ON");
4140 4214
4141 down(&priv->action_sem); 4215 mutex_lock(&priv->action_mutex);
4142 4216
4143 if (disable_radio) { 4217 if (disable_radio) {
4144 priv->status |= STATUS_RF_KILL_SW; 4218 priv->status |= STATUS_RF_KILL_SW;
@@ -4156,7 +4230,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4156 schedule_reset(priv); 4230 schedule_reset(priv);
4157 } 4231 }
4158 4232
4159 up(&priv->action_sem); 4233 mutex_unlock(&priv->action_mutex);
4160 return 1; 4234 return 1;
4161} 4235}
4162 4236
@@ -5460,7 +5534,7 @@ static void shim__set_security(struct net_device *dev,
5460 struct ipw2100_priv *priv = ieee80211_priv(dev); 5534 struct ipw2100_priv *priv = ieee80211_priv(dev);
5461 int i, force_update = 0; 5535 int i, force_update = 0;
5462 5536
5463 down(&priv->action_sem); 5537 mutex_lock(&priv->action_mutex);
5464 if (!(priv->status & STATUS_INITIALIZED)) 5538 if (!(priv->status & STATUS_INITIALIZED))
5465 goto done; 5539 goto done;
5466 5540
@@ -5533,7 +5607,7 @@ static void shim__set_security(struct net_device *dev,
5533 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) 5607 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5534 ipw2100_configure_security(priv, 0); 5608 ipw2100_configure_security(priv, 0);
5535 done: 5609 done:
5536 up(&priv->action_sem); 5610 mutex_unlock(&priv->action_mutex);
5537} 5611}
5538 5612
5539static int ipw2100_adapter_setup(struct ipw2100_priv *priv) 5613static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
@@ -5657,7 +5731,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
5657 if (!is_valid_ether_addr(addr->sa_data)) 5731 if (!is_valid_ether_addr(addr->sa_data))
5658 return -EADDRNOTAVAIL; 5732 return -EADDRNOTAVAIL;
5659 5733
5660 down(&priv->action_sem); 5734 mutex_lock(&priv->action_mutex);
5661 5735
5662 priv->config |= CFG_CUSTOM_MAC; 5736 priv->config |= CFG_CUSTOM_MAC;
5663 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); 5737 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
@@ -5667,12 +5741,12 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
5667 goto done; 5741 goto done;
5668 5742
5669 priv->reset_backoff = 0; 5743 priv->reset_backoff = 0;
5670 up(&priv->action_sem); 5744 mutex_unlock(&priv->action_mutex);
5671 ipw2100_reset_adapter(priv); 5745 ipw2100_reset_adapter(priv);
5672 return 0; 5746 return 0;
5673 5747
5674 done: 5748 done:
5675 up(&priv->action_sem); 5749 mutex_unlock(&priv->action_mutex);
5676 return err; 5750 return err;
5677} 5751}
5678 5752
@@ -6015,8 +6089,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6015 strcpy(priv->nick, "ipw2100"); 6089 strcpy(priv->nick, "ipw2100");
6016 6090
6017 spin_lock_init(&priv->low_lock); 6091 spin_lock_init(&priv->low_lock);
6018 sema_init(&priv->action_sem, 1); 6092 mutex_init(&priv->action_mutex);
6019 sema_init(&priv->adapter_sem, 1); 6093 mutex_init(&priv->adapter_mutex);
6020 6094
6021 init_waitqueue_head(&priv->wait_command_queue); 6095 init_waitqueue_head(&priv->wait_command_queue);
6022 6096
@@ -6181,7 +6255,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6181 * member to call a function that then just turns and calls ipw2100_up. 6255 * member to call a function that then just turns and calls ipw2100_up.
6182 * net_dev->init is called after name allocation but before the 6256 * net_dev->init is called after name allocation but before the
6183 * notifier chain is called */ 6257 * notifier chain is called */
6184 down(&priv->action_sem); 6258 mutex_lock(&priv->action_mutex);
6185 err = register_netdev(dev); 6259 err = register_netdev(dev);
6186 if (err) { 6260 if (err) {
6187 printk(KERN_WARNING DRV_NAME 6261 printk(KERN_WARNING DRV_NAME
@@ -6217,12 +6291,12 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6217 6291
6218 priv->status |= STATUS_INITIALIZED; 6292 priv->status |= STATUS_INITIALIZED;
6219 6293
6220 up(&priv->action_sem); 6294 mutex_unlock(&priv->action_mutex);
6221 6295
6222 return 0; 6296 return 0;
6223 6297
6224 fail_unlock: 6298 fail_unlock:
6225 up(&priv->action_sem); 6299 mutex_unlock(&priv->action_mutex);
6226 6300
6227 fail: 6301 fail:
6228 if (dev) { 6302 if (dev) {
@@ -6262,7 +6336,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6262 struct net_device *dev; 6336 struct net_device *dev;
6263 6337
6264 if (priv) { 6338 if (priv) {
6265 down(&priv->action_sem); 6339 mutex_lock(&priv->action_mutex);
6266 6340
6267 priv->status &= ~STATUS_INITIALIZED; 6341 priv->status &= ~STATUS_INITIALIZED;
6268 6342
@@ -6277,9 +6351,9 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6277 /* Take down the hardware */ 6351 /* Take down the hardware */
6278 ipw2100_down(priv); 6352 ipw2100_down(priv);
6279 6353
6280 /* Release the semaphore so that the network subsystem can 6354 /* Release the mutex so that the network subsystem can
6281 * complete any needed calls into the driver... */ 6355 * complete any needed calls into the driver... */
6282 up(&priv->action_sem); 6356 mutex_unlock(&priv->action_mutex);
6283 6357
6284 /* Unregister the device first - this results in close() 6358 /* Unregister the device first - this results in close()
6285 * being called if the device is open. If we free storage 6359 * being called if the device is open. If we free storage
@@ -6318,7 +6392,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6318 6392
6319 IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name); 6393 IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
6320 6394
6321 down(&priv->action_sem); 6395 mutex_lock(&priv->action_mutex);
6322 if (priv->status & STATUS_INITIALIZED) { 6396 if (priv->status & STATUS_INITIALIZED) {
6323 /* Take down the device; powers it off, etc. */ 6397 /* Take down the device; powers it off, etc. */
6324 ipw2100_down(priv); 6398 ipw2100_down(priv);
@@ -6331,7 +6405,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6331 pci_disable_device(pci_dev); 6405 pci_disable_device(pci_dev);
6332 pci_set_power_state(pci_dev, PCI_D3hot); 6406 pci_set_power_state(pci_dev, PCI_D3hot);
6333 6407
6334 up(&priv->action_sem); 6408 mutex_unlock(&priv->action_mutex);
6335 6409
6336 return 0; 6410 return 0;
6337} 6411}
@@ -6345,7 +6419,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6345 if (IPW2100_PM_DISABLED) 6419 if (IPW2100_PM_DISABLED)
6346 return 0; 6420 return 0;
6347 6421
6348 down(&priv->action_sem); 6422 mutex_lock(&priv->action_mutex);
6349 6423
6350 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name); 6424 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
6351 6425
@@ -6371,7 +6445,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6371 if (!(priv->status & STATUS_RF_KILL_SW)) 6445 if (!(priv->status & STATUS_RF_KILL_SW))
6372 ipw2100_up(priv, 0); 6446 ipw2100_up(priv, 0);
6373 6447
6374 up(&priv->action_sem); 6448 mutex_unlock(&priv->action_mutex);
6375 6449
6376 return 0; 6450 return 0;
6377} 6451}
@@ -6535,7 +6609,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6535 if (priv->ieee->iw_mode == IW_MODE_INFRA) 6609 if (priv->ieee->iw_mode == IW_MODE_INFRA)
6536 return -EOPNOTSUPP; 6610 return -EOPNOTSUPP;
6537 6611
6538 down(&priv->action_sem); 6612 mutex_lock(&priv->action_mutex);
6539 if (!(priv->status & STATUS_INITIALIZED)) { 6613 if (!(priv->status & STATUS_INITIALIZED)) {
6540 err = -EIO; 6614 err = -EIO;
6541 goto done; 6615 goto done;
@@ -6566,7 +6640,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6566 } 6640 }
6567 6641
6568 done: 6642 done:
6569 up(&priv->action_sem); 6643 mutex_unlock(&priv->action_mutex);
6570 return err; 6644 return err;
6571} 6645}
6572 6646
@@ -6607,7 +6681,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
6607 if (wrqu->mode == priv->ieee->iw_mode) 6681 if (wrqu->mode == priv->ieee->iw_mode)
6608 return 0; 6682 return 0;
6609 6683
6610 down(&priv->action_sem); 6684 mutex_lock(&priv->action_mutex);
6611 if (!(priv->status & STATUS_INITIALIZED)) { 6685 if (!(priv->status & STATUS_INITIALIZED)) {
6612 err = -EIO; 6686 err = -EIO;
6613 goto done; 6687 goto done;
@@ -6630,7 +6704,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
6630 } 6704 }
6631 6705
6632 done: 6706 done:
6633 up(&priv->action_sem); 6707 mutex_unlock(&priv->action_mutex);
6634 return err; 6708 return err;
6635} 6709}
6636 6710
@@ -6812,7 +6886,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
6812 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) 6886 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
6813 return -EINVAL; 6887 return -EINVAL;
6814 6888
6815 down(&priv->action_sem); 6889 mutex_lock(&priv->action_mutex);
6816 if (!(priv->status & STATUS_INITIALIZED)) { 6890 if (!(priv->status & STATUS_INITIALIZED)) {
6817 err = -EIO; 6891 err = -EIO;
6818 goto done; 6892 goto done;
@@ -6841,7 +6915,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
6841 wrqu->ap_addr.sa_data[5] & 0xff); 6915 wrqu->ap_addr.sa_data[5] & 0xff);
6842 6916
6843 done: 6917 done:
6844 up(&priv->action_sem); 6918 mutex_unlock(&priv->action_mutex);
6845 return err; 6919 return err;
6846} 6920}
6847 6921
@@ -6877,7 +6951,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
6877 int length = 0; 6951 int length = 0;
6878 int err = 0; 6952 int err = 0;
6879 6953
6880 down(&priv->action_sem); 6954 mutex_lock(&priv->action_mutex);
6881 if (!(priv->status & STATUS_INITIALIZED)) { 6955 if (!(priv->status & STATUS_INITIALIZED)) {
6882 err = -EIO; 6956 err = -EIO;
6883 goto done; 6957 goto done;
@@ -6914,7 +6988,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
6914 err = ipw2100_set_essid(priv, essid, length, 0); 6988 err = ipw2100_set_essid(priv, essid, length, 0);
6915 6989
6916 done: 6990 done:
6917 up(&priv->action_sem); 6991 mutex_unlock(&priv->action_mutex);
6918 return err; 6992 return err;
6919} 6993}
6920 6994
@@ -6995,7 +7069,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
6995 u32 rate; 7069 u32 rate;
6996 int err = 0; 7070 int err = 0;
6997 7071
6998 down(&priv->action_sem); 7072 mutex_lock(&priv->action_mutex);
6999 if (!(priv->status & STATUS_INITIALIZED)) { 7073 if (!(priv->status & STATUS_INITIALIZED)) {
7000 err = -EIO; 7074 err = -EIO;
7001 goto done; 7075 goto done;
@@ -7022,7 +7096,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
7022 7096
7023 IPW_DEBUG_WX("SET Rate -> %04X \n", rate); 7097 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7024 done: 7098 done:
7025 up(&priv->action_sem); 7099 mutex_unlock(&priv->action_mutex);
7026 return err; 7100 return err;
7027} 7101}
7028 7102
@@ -7042,7 +7116,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7042 return 0; 7116 return 0;
7043 } 7117 }
7044 7118
7045 down(&priv->action_sem); 7119 mutex_lock(&priv->action_mutex);
7046 if (!(priv->status & STATUS_INITIALIZED)) { 7120 if (!(priv->status & STATUS_INITIALIZED)) {
7047 err = -EIO; 7121 err = -EIO;
7048 goto done; 7122 goto done;
@@ -7074,7 +7148,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7074 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 7148 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7075 7149
7076 done: 7150 done:
7077 up(&priv->action_sem); 7151 mutex_unlock(&priv->action_mutex);
7078 return err; 7152 return err;
7079} 7153}
7080 7154
@@ -7089,7 +7163,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7089 if (wrqu->rts.fixed == 0) 7163 if (wrqu->rts.fixed == 0)
7090 return -EINVAL; 7164 return -EINVAL;
7091 7165
7092 down(&priv->action_sem); 7166 mutex_lock(&priv->action_mutex);
7093 if (!(priv->status & STATUS_INITIALIZED)) { 7167 if (!(priv->status & STATUS_INITIALIZED)) {
7094 err = -EIO; 7168 err = -EIO;
7095 goto done; 7169 goto done;
@@ -7109,7 +7183,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7109 7183
7110 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); 7184 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7111 done: 7185 done:
7112 up(&priv->action_sem); 7186 mutex_unlock(&priv->action_mutex);
7113 return err; 7187 return err;
7114} 7188}
7115 7189
@@ -7160,7 +7234,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7160 value = wrqu->txpower.value; 7234 value = wrqu->txpower.value;
7161 } 7235 }
7162 7236
7163 down(&priv->action_sem); 7237 mutex_lock(&priv->action_mutex);
7164 if (!(priv->status & STATUS_INITIALIZED)) { 7238 if (!(priv->status & STATUS_INITIALIZED)) {
7165 err = -EIO; 7239 err = -EIO;
7166 goto done; 7240 goto done;
@@ -7171,7 +7245,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7171 IPW_DEBUG_WX("SET TX Power -> %d \n", value); 7245 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7172 7246
7173 done: 7247 done:
7174 up(&priv->action_sem); 7248 mutex_unlock(&priv->action_mutex);
7175 return err; 7249 return err;
7176} 7250}
7177 7251
@@ -7263,7 +7337,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7263 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) 7337 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
7264 return 0; 7338 return 0;
7265 7339
7266 down(&priv->action_sem); 7340 mutex_lock(&priv->action_mutex);
7267 if (!(priv->status & STATUS_INITIALIZED)) { 7341 if (!(priv->status & STATUS_INITIALIZED)) {
7268 err = -EIO; 7342 err = -EIO;
7269 goto done; 7343 goto done;
@@ -7290,7 +7364,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7290 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); 7364 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7291 7365
7292 done: 7366 done:
7293 up(&priv->action_sem); 7367 mutex_unlock(&priv->action_mutex);
7294 return err; 7368 return err;
7295} 7369}
7296 7370
@@ -7333,7 +7407,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7333 struct ipw2100_priv *priv = ieee80211_priv(dev); 7407 struct ipw2100_priv *priv = ieee80211_priv(dev);
7334 int err = 0; 7408 int err = 0;
7335 7409
7336 down(&priv->action_sem); 7410 mutex_lock(&priv->action_mutex);
7337 if (!(priv->status & STATUS_INITIALIZED)) { 7411 if (!(priv->status & STATUS_INITIALIZED)) {
7338 err = -EIO; 7412 err = -EIO;
7339 goto done; 7413 goto done;
@@ -7348,7 +7422,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7348 } 7422 }
7349 7423
7350 done: 7424 done:
7351 up(&priv->action_sem); 7425 mutex_unlock(&priv->action_mutex);
7352 return err; 7426 return err;
7353} 7427}
7354 7428
@@ -7398,7 +7472,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7398 struct ipw2100_priv *priv = ieee80211_priv(dev); 7472 struct ipw2100_priv *priv = ieee80211_priv(dev);
7399 int err = 0; 7473 int err = 0;
7400 7474
7401 down(&priv->action_sem); 7475 mutex_lock(&priv->action_mutex);
7402 if (!(priv->status & STATUS_INITIALIZED)) { 7476 if (!(priv->status & STATUS_INITIALIZED)) {
7403 err = -EIO; 7477 err = -EIO;
7404 goto done; 7478 goto done;
@@ -7431,7 +7505,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7431 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); 7505 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
7432 7506
7433 done: 7507 done:
7434 up(&priv->action_sem); 7508 mutex_unlock(&priv->action_mutex);
7435 return err; 7509 return err;
7436 7510
7437} 7511}
@@ -7735,7 +7809,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
7735 int enable = (parms[0] > 0); 7809 int enable = (parms[0] > 0);
7736 int err = 0; 7810 int err = 0;
7737 7811
7738 down(&priv->action_sem); 7812 mutex_lock(&priv->action_mutex);
7739 if (!(priv->status & STATUS_INITIALIZED)) { 7813 if (!(priv->status & STATUS_INITIALIZED)) {
7740 err = -EIO; 7814 err = -EIO;
7741 goto done; 7815 goto done;
@@ -7753,7 +7827,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
7753 err = ipw2100_switch_mode(priv, priv->last_mode); 7827 err = ipw2100_switch_mode(priv, priv->last_mode);
7754 } 7828 }
7755 done: 7829 done:
7756 up(&priv->action_sem); 7830 mutex_unlock(&priv->action_mutex);
7757 return err; 7831 return err;
7758} 7832}
7759 7833
@@ -7776,7 +7850,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
7776 struct ipw2100_priv *priv = ieee80211_priv(dev); 7850 struct ipw2100_priv *priv = ieee80211_priv(dev);
7777 int err = 0, mode = *(int *)extra; 7851 int err = 0, mode = *(int *)extra;
7778 7852
7779 down(&priv->action_sem); 7853 mutex_lock(&priv->action_mutex);
7780 if (!(priv->status & STATUS_INITIALIZED)) { 7854 if (!(priv->status & STATUS_INITIALIZED)) {
7781 err = -EIO; 7855 err = -EIO;
7782 goto done; 7856 goto done;
@@ -7788,7 +7862,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
7788 if (priv->power_mode != mode) 7862 if (priv->power_mode != mode)
7789 err = ipw2100_set_power_mode(priv, mode); 7863 err = ipw2100_set_power_mode(priv, mode);
7790 done: 7864 done:
7791 up(&priv->action_sem); 7865 mutex_unlock(&priv->action_mutex);
7792 return err; 7866 return err;
7793} 7867}
7794 7868
@@ -7840,7 +7914,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
7840 struct ipw2100_priv *priv = ieee80211_priv(dev); 7914 struct ipw2100_priv *priv = ieee80211_priv(dev);
7841 int err, mode = *(int *)extra; 7915 int err, mode = *(int *)extra;
7842 7916
7843 down(&priv->action_sem); 7917 mutex_lock(&priv->action_mutex);
7844 if (!(priv->status & STATUS_INITIALIZED)) { 7918 if (!(priv->status & STATUS_INITIALIZED)) {
7845 err = -EIO; 7919 err = -EIO;
7846 goto done; 7920 goto done;
@@ -7858,7 +7932,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
7858 err = ipw2100_system_config(priv, 0); 7932 err = ipw2100_system_config(priv, 0);
7859 7933
7860 done: 7934 done:
7861 up(&priv->action_sem); 7935 mutex_unlock(&priv->action_mutex);
7862 return err; 7936 return err;
7863} 7937}
7864 7938
@@ -7888,7 +7962,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
7888 struct ipw2100_priv *priv = ieee80211_priv(dev); 7962 struct ipw2100_priv *priv = ieee80211_priv(dev);
7889 int err, mode = *(int *)extra; 7963 int err, mode = *(int *)extra;
7890 7964
7891 down(&priv->action_sem); 7965 mutex_lock(&priv->action_mutex);
7892 if (!(priv->status & STATUS_INITIALIZED)) { 7966 if (!(priv->status & STATUS_INITIALIZED)) {
7893 err = -EIO; 7967 err = -EIO;
7894 goto done; 7968 goto done;
@@ -7905,7 +7979,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
7905 err = 0; 7979 err = 0;
7906 7980
7907 done: 7981 done:
7908 up(&priv->action_sem); 7982 mutex_unlock(&priv->action_mutex);
7909 return err; 7983 return err;
7910} 7984}
7911 7985
@@ -8210,11 +8284,11 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8210 if (priv->status & STATUS_STOPPING) 8284 if (priv->status & STATUS_STOPPING)
8211 return; 8285 return;
8212 8286
8213 down(&priv->action_sem); 8287 mutex_lock(&priv->action_mutex);
8214 8288
8215 IPW_DEBUG_WX("enter\n"); 8289 IPW_DEBUG_WX("enter\n");
8216 8290
8217 up(&priv->action_sem); 8291 mutex_unlock(&priv->action_mutex);
8218 8292
8219 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 8293 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
8220 8294
@@ -8237,7 +8311,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8237 8311
8238 if (!(priv->status & STATUS_ASSOCIATED)) { 8312 if (!(priv->status & STATUS_ASSOCIATED)) {
8239 IPW_DEBUG_WX("Configuring ESSID\n"); 8313 IPW_DEBUG_WX("Configuring ESSID\n");
8240 down(&priv->action_sem); 8314 mutex_lock(&priv->action_mutex);
8241 /* This is a disassociation event, so kick the firmware to 8315 /* This is a disassociation event, so kick the firmware to
8242 * look for another AP */ 8316 * look for another AP */
8243 if (priv->config & CFG_STATIC_ESSID) 8317 if (priv->config & CFG_STATIC_ESSID)
@@ -8245,7 +8319,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8245 0); 8319 0);
8246 else 8320 else
8247 ipw2100_set_essid(priv, NULL, 0, 0); 8321 ipw2100_set_essid(priv, NULL, 0, 0);
8248 up(&priv->action_sem); 8322 mutex_unlock(&priv->action_mutex);
8249 } 8323 }
8250 8324
8251 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); 8325 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 51360910d22..55b7227198d 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -41,7 +41,12 @@
41 41
42#include <net/ieee80211.h> 42#include <net/ieee80211.h>
43 43
44#ifdef CONFIG_IPW2100_MONITOR
45#include <net/ieee80211_radiotap.h>
46#endif
47
44#include <linux/workqueue.h> 48#include <linux/workqueue.h>
49#include <linux/mutex.h>
45 50
46struct ipw2100_priv; 51struct ipw2100_priv;
47struct ipw2100_tx_packet; 52struct ipw2100_tx_packet;
@@ -590,8 +595,8 @@ struct ipw2100_priv {
590 int inta_other; 595 int inta_other;
591 596
592 spinlock_t low_lock; 597 spinlock_t low_lock;
593 struct semaphore action_sem; 598 struct mutex action_mutex;
594 struct semaphore adapter_sem; 599 struct mutex adapter_mutex;
595 600
596 wait_queue_head_t wait_command_queue; 601 wait_queue_head_t wait_command_queue;
597}; 602};
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index ed37141319e..9dce522526c 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.10" 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)
@@ -153,12 +153,6 @@ static int init_supported_rates(struct ipw_priv *priv,
153static void ipw_set_hwcrypto_keys(struct ipw_priv *); 153static void ipw_set_hwcrypto_keys(struct ipw_priv *);
154static void ipw_send_wep_keys(struct ipw_priv *, int); 154static void ipw_send_wep_keys(struct ipw_priv *, int);
155 155
156static int ipw_is_valid_channel(struct ieee80211_device *, u8);
157static int ipw_channel_to_index(struct ieee80211_device *, u8);
158static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
159static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
160static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
161
162static int snprint_line(char *buf, size_t count, 156static int snprint_line(char *buf, size_t count,
163 const u8 * data, u32 len, u32 ofs) 157 const u8 * data, u32 len, u32 ofs)
164{ 158{
@@ -1654,7 +1648,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1654 break; 1648 break;
1655 } 1649 }
1656 1650
1657 if (ipw_is_valid_channel(priv->ieee, channel)) 1651 if (ieee80211_is_valid_channel(priv->ieee, channel))
1658 priv->speed_scan[pos++] = channel; 1652 priv->speed_scan[pos++] = channel;
1659 else 1653 else
1660 IPW_WARNING("Skipping invalid channel request: %d\n", 1654 IPW_WARNING("Skipping invalid channel request: %d\n",
@@ -1802,9 +1796,9 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1802 } 1796 }
1803 1797
1804 if (inta & IPW_INTA_BIT_FATAL_ERROR) { 1798 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
1805 IPW_ERROR("Firmware error detected. Restarting.\n"); 1799 IPW_WARNING("Firmware error detected. Restarting.\n");
1806 if (priv->error) { 1800 if (priv->error) {
1807 IPW_ERROR("Sysfs 'error' log already exists.\n"); 1801 IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");
1808#ifdef CONFIG_IPW2200_DEBUG 1802#ifdef CONFIG_IPW2200_DEBUG
1809 if (ipw_debug_level & IPW_DL_FW_ERRORS) { 1803 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1810 struct ipw_fw_error *error = 1804 struct ipw_fw_error *error =
@@ -1817,10 +1811,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1817 } else { 1811 } else {
1818 priv->error = ipw_alloc_error_log(priv); 1812 priv->error = ipw_alloc_error_log(priv);
1819 if (priv->error) 1813 if (priv->error)
1820 IPW_ERROR("Sysfs 'error' log captured.\n"); 1814 IPW_DEBUG_FW("Sysfs 'error' log captured.\n");
1821 else 1815 else
1822 IPW_ERROR("Error allocating sysfs 'error' " 1816 IPW_DEBUG_FW("Error allocating sysfs 'error' "
1823 "log.\n"); 1817 "log.\n");
1824#ifdef CONFIG_IPW2200_DEBUG 1818#ifdef CONFIG_IPW2200_DEBUG
1825 if (ipw_debug_level & IPW_DL_FW_ERRORS) 1819 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1826 ipw_dump_error_log(priv, priv->error); 1820 ipw_dump_error_log(priv, priv->error);
@@ -2222,7 +2216,7 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
2222 2216
2223static int ipw_set_tx_power(struct ipw_priv *priv) 2217static int ipw_set_tx_power(struct ipw_priv *priv)
2224{ 2218{
2225 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 2219 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
2226 struct ipw_tx_power tx_power; 2220 struct ipw_tx_power tx_power;
2227 s8 max_power; 2221 s8 max_power;
2228 int i; 2222 int i;
@@ -2835,33 +2829,11 @@ static void ipw_arc_release(struct ipw_priv *priv)
2835 mdelay(5); 2829 mdelay(5);
2836} 2830}
2837 2831
2838struct fw_header {
2839 u32 version;
2840 u32 mode;
2841};
2842
2843struct fw_chunk { 2832struct fw_chunk {
2844 u32 address; 2833 u32 address;
2845 u32 length; 2834 u32 length;
2846}; 2835};
2847 2836
2848#define IPW_FW_MAJOR_VERSION 2
2849#define IPW_FW_MINOR_VERSION 4
2850
2851#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2852#define IPW_FW_MAJOR(x) (x & 0xff)
2853
2854#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
2855
2856#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2857"." __stringify(IPW_FW_MINOR_VERSION) "-"
2858
2859#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
2860#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
2861#else
2862#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
2863#endif
2864
2865static 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)
2866{ 2838{
2867 int rc = 0, i, addr; 2839 int rc = 0, i, addr;
@@ -3130,33 +3102,47 @@ static int ipw_reset_nic(struct ipw_priv *priv)
3130 return rc; 3102 return rc;
3131} 3103}
3132 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
3133static int ipw_get_fw(struct ipw_priv *priv, 3114static int ipw_get_fw(struct ipw_priv *priv,
3134 const struct firmware **fw, const char *name) 3115 const struct firmware **raw, const char *name)
3135{ 3116{
3136 struct fw_header *header; 3117 struct ipw_fw *fw;
3137 int rc; 3118 int rc;
3138 3119
3139 /* ask firmware_class module to get the boot firmware off disk */ 3120 /* ask firmware_class module to get the boot firmware off disk */
3140 rc = request_firmware(fw, name, &priv->pci_dev->dev); 3121 rc = request_firmware(raw, name, &priv->pci_dev->dev);
3141 if (rc < 0) { 3122 if (rc < 0) {
3142 IPW_ERROR("%s load failed: Reason %d\n", name, rc); 3123 IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc);
3143 return rc; 3124 return rc;
3144 } 3125 }
3145 3126
3146 header = (struct fw_header *)(*fw)->data; 3127 if ((*raw)->size < sizeof(*fw)) {
3147 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);
3148 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
3149 name,
3150 IPW_FW_MAJOR(le32_to_cpu(header->version)),
3151 IPW_FW_MAJOR_VERSION);
3152 return -EINVAL; 3129 return -EINVAL;
3153 } 3130 }
3154 3131
3155 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", 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);
3138 return -EINVAL;
3139 }
3140
3141 IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n",
3156 name, 3142 name,
3157 IPW_FW_MAJOR(le32_to_cpu(header->version)), 3143 le32_to_cpu(fw->ver) >> 16,
3158 IPW_FW_MINOR(le32_to_cpu(header->version)), 3144 le32_to_cpu(fw->ver) & 0xff,
3159 (*fw)->size - sizeof(struct fw_header)); 3145 (*raw)->size - sizeof(*fw));
3160 return 0; 3146 return 0;
3161} 3147}
3162 3148
@@ -3196,17 +3182,13 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
3196 3182
3197#ifdef CONFIG_PM 3183#ifdef CONFIG_PM
3198static int fw_loaded = 0; 3184static int fw_loaded = 0;
3199static const struct firmware *bootfw = NULL; 3185static const struct firmware *raw = NULL;
3200static const struct firmware *firmware = NULL;
3201static const struct firmware *ucode = NULL;
3202 3186
3203static void free_firmware(void) 3187static void free_firmware(void)
3204{ 3188{
3205 if (fw_loaded) { 3189 if (fw_loaded) {
3206 release_firmware(bootfw); 3190 release_firmware(raw);
3207 release_firmware(ucode); 3191 raw = NULL;
3208 release_firmware(firmware);
3209 bootfw = ucode = firmware = NULL;
3210 fw_loaded = 0; 3192 fw_loaded = 0;
3211 } 3193 }
3212} 3194}
@@ -3217,32 +3199,46 @@ static void free_firmware(void)
3217static int ipw_load(struct ipw_priv *priv) 3199static int ipw_load(struct ipw_priv *priv)
3218{ 3200{
3219#ifndef CONFIG_PM 3201#ifndef CONFIG_PM
3220 const struct firmware *bootfw = NULL; 3202 const struct firmware *raw = NULL;
3221 const struct firmware *firmware = NULL;
3222 const struct firmware *ucode = NULL;
3223#endif 3203#endif
3224 char *ucode_name; 3204 struct ipw_fw *fw;
3225 char *fw_name; 3205 u8 *boot_img, *ucode_img, *fw_img;
3206 u8 *name = NULL;
3226 int rc = 0, retries = 3; 3207 int rc = 0, retries = 3;
3227 3208
3228 switch (priv->ieee->iw_mode) { 3209 switch (priv->ieee->iw_mode) {
3229 case IW_MODE_ADHOC: 3210 case IW_MODE_ADHOC:
3230 ucode_name = IPW_FW_NAME("ibss_ucode"); 3211 name = "ipw2200-ibss.fw";
3231 fw_name = IPW_FW_NAME("ibss");
3232 break; 3212 break;
3233#ifdef CONFIG_IPW2200_MONITOR 3213#ifdef CONFIG_IPW2200_MONITOR
3234 case IW_MODE_MONITOR: 3214 case IW_MODE_MONITOR:
3235 ucode_name = IPW_FW_NAME("sniffer_ucode"); 3215 name = "ipw2200-sniffer.fw";
3236 fw_name = IPW_FW_NAME("sniffer");
3237 break; 3216 break;
3238#endif 3217#endif
3239 case IW_MODE_INFRA: 3218 case IW_MODE_INFRA:
3240 ucode_name = IPW_FW_NAME("bss_ucode"); 3219 name = "ipw2200-bss.fw";
3241 fw_name = IPW_FW_NAME("bss");
3242 break; 3220 break;
3243 default: 3221 }
3222
3223 if (!name) {
3244 rc = -EINVAL; 3224 rc = -EINVAL;
3225 goto error;
3226 }
3227
3228#ifdef CONFIG_PM
3229 if (!fw_loaded) {
3230#endif
3231 rc = ipw_get_fw(priv, &raw, name);
3232 if (rc < 0)
3233 goto error;
3234#ifdef CONFIG_PM
3245 } 3235 }
3236#endif
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];
3246 3242
3247 if (rc < 0) 3243 if (rc < 0)
3248 goto error; 3244 goto error;
@@ -3275,18 +3271,8 @@ static int ipw_load(struct ipw_priv *priv)
3275 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND, 3271 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
3276 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); 3272 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
3277 3273
3278#ifdef CONFIG_PM
3279 if (!fw_loaded) {
3280#endif
3281 rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
3282 if (rc < 0)
3283 goto error;
3284#ifdef CONFIG_PM
3285 }
3286#endif
3287 /* DMA the initial boot firmware into the device */ 3274 /* DMA the initial boot firmware into the device */
3288 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), 3275 rc = ipw_load_firmware(priv, boot_img, fw->boot_size);
3289 bootfw->size - sizeof(struct fw_header));
3290 if (rc < 0) { 3276 if (rc < 0) {
3291 IPW_ERROR("Unable to load boot firmware: %d\n", rc); 3277 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
3292 goto error; 3278 goto error;
@@ -3307,19 +3293,8 @@ static int ipw_load(struct ipw_priv *priv)
3307 /* ack fw init done interrupt */ 3293 /* ack fw init done interrupt */
3308 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);
3309 3295
3310#ifdef CONFIG_PM
3311 if (!fw_loaded) {
3312#endif
3313 rc = ipw_get_fw(priv, &ucode, ucode_name);
3314 if (rc < 0)
3315 goto error;
3316#ifdef CONFIG_PM
3317 }
3318#endif
3319
3320 /* DMA the ucode into the device */ 3296 /* DMA the ucode into the device */
3321 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), 3297 rc = ipw_load_ucode(priv, ucode_img, fw->ucode_size);
3322 ucode->size - sizeof(struct fw_header));
3323 if (rc < 0) { 3298 if (rc < 0) {
3324 IPW_ERROR("Unable to load ucode: %d\n", rc); 3299 IPW_ERROR("Unable to load ucode: %d\n", rc);
3325 goto error; 3300 goto error;
@@ -3328,20 +3303,8 @@ static int ipw_load(struct ipw_priv *priv)
3328 /* stop nic */ 3303 /* stop nic */
3329 ipw_stop_nic(priv); 3304 ipw_stop_nic(priv);
3330 3305
3331#ifdef CONFIG_PM
3332 if (!fw_loaded) {
3333#endif
3334 rc = ipw_get_fw(priv, &firmware, fw_name);
3335 if (rc < 0)
3336 goto error;
3337#ifdef CONFIG_PM
3338 }
3339#endif
3340
3341 /* DMA bss firmware into the device */ 3306 /* DMA bss firmware into the device */
3342 rc = ipw_load_firmware(priv, firmware->data + 3307 rc = ipw_load_firmware(priv, fw_img, fw->fw_size);
3343 sizeof(struct fw_header),
3344 firmware->size - sizeof(struct fw_header));
3345 if (rc < 0) { 3308 if (rc < 0) {
3346 IPW_ERROR("Unable to load firmware: %d\n", rc); 3309 IPW_ERROR("Unable to load firmware: %d\n", rc);
3347 goto error; 3310 goto error;
@@ -3406,9 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
3406 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL); 3369 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3407 3370
3408#ifndef CONFIG_PM 3371#ifndef CONFIG_PM
3409 release_firmware(bootfw); 3372 release_firmware(raw);
3410 release_firmware(ucode);
3411 release_firmware(firmware);
3412#endif 3373#endif
3413 return 0; 3374 return 0;
3414 3375
@@ -3418,15 +3379,11 @@ static int ipw_load(struct ipw_priv *priv)
3418 priv->rxq = NULL; 3379 priv->rxq = NULL;
3419 } 3380 }
3420 ipw_tx_queue_free(priv); 3381 ipw_tx_queue_free(priv);
3421 if (bootfw) 3382 if (raw)
3422 release_firmware(bootfw); 3383 release_firmware(raw);
3423 if (ucode)
3424 release_firmware(ucode);
3425 if (firmware)
3426 release_firmware(firmware);
3427#ifdef CONFIG_PM 3384#ifdef CONFIG_PM
3428 fw_loaded = 0; 3385 fw_loaded = 0;
3429 bootfw = ucode = firmware = NULL; 3386 raw = NULL;
3430#endif 3387#endif
3431 3388
3432 return rc; 3389 return rc;
@@ -4547,10 +4504,9 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4547 4504
4548 if (notif->size == sizeof(*x)) { 4505 if (notif->size == sizeof(*x)) {
4549 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4506 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4550 "link deterioration: '%s' " MAC_FMT 4507 "link deterioration: type %d, cnt %d\n",
4551 " \n", escape_essid(priv->essid, 4508 x->silence_notification_type,
4552 priv->essid_len), 4509 x->silence_count);
4553 MAC_ARG(priv->bssid));
4554 memcpy(&priv->last_link_deterioration, x, 4510 memcpy(&priv->last_link_deterioration, x,
4555 sizeof(*x)); 4511 sizeof(*x));
4556 } else { 4512 } else {
@@ -5533,15 +5489,6 @@ static int ipw_best_network(struct ipw_priv *priv,
5533 return 0; 5489 return 0;
5534 } 5490 }
5535 5491
5536 if (priv->ieee->wpa_enabled &&
5537 network->wpa_ie_len == 0 && network->rsn_ie_len == 0) {
5538 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5539 "because of WPA capability mismatch.\n",
5540 escape_essid(network->ssid, network->ssid_len),
5541 MAC_ARG(network->bssid));
5542 return 0;
5543 }
5544
5545 if ((priv->config & CFG_STATIC_BSSID) && 5492 if ((priv->config & CFG_STATIC_BSSID) &&
5546 memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5493 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5547 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5494 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -5562,7 +5509,7 @@ static int ipw_best_network(struct ipw_priv *priv,
5562 } 5509 }
5563 5510
5564 /* Filter out invalid channel in current GEO */ 5511 /* Filter out invalid channel in current GEO */
5565 if (!ipw_is_valid_channel(priv->ieee, network->channel)) { 5512 if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) {
5566 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5513 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5567 "because of invalid channel in current GEO\n", 5514 "because of invalid channel in current GEO\n",
5568 escape_essid(network->ssid, network->ssid_len), 5515 escape_essid(network->ssid, network->ssid_len),
@@ -5607,7 +5554,7 @@ static int ipw_best_network(struct ipw_priv *priv,
5607static void ipw_adhoc_create(struct ipw_priv *priv, 5554static void ipw_adhoc_create(struct ipw_priv *priv,
5608 struct ieee80211_network *network) 5555 struct ieee80211_network *network)
5609{ 5556{
5610 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 5557 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
5611 int i; 5558 int i;
5612 5559
5613 /* 5560 /*
@@ -5622,10 +5569,10 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
5622 * FW fatal error. 5569 * FW fatal error.
5623 * 5570 *
5624 */ 5571 */
5625 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { 5572 switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
5626 case IEEE80211_52GHZ_BAND: 5573 case IEEE80211_52GHZ_BAND:
5627 network->mode = IEEE_A; 5574 network->mode = IEEE_A;
5628 i = ipw_channel_to_index(priv->ieee, priv->channel); 5575 i = ieee80211_channel_to_index(priv->ieee, priv->channel);
5629 if (i == -1) 5576 if (i == -1)
5630 BUG(); 5577 BUG();
5631 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) { 5578 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
@@ -5639,7 +5586,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
5639 network->mode = IEEE_G; 5586 network->mode = IEEE_G;
5640 else 5587 else
5641 network->mode = IEEE_B; 5588 network->mode = IEEE_B;
5642 i = ipw_channel_to_index(priv->ieee, priv->channel); 5589 i = ieee80211_channel_to_index(priv->ieee, priv->channel);
5643 if (i == -1) 5590 if (i == -1)
5644 BUG(); 5591 BUG();
5645 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) { 5592 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
@@ -5963,7 +5910,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
5963 const struct ieee80211_geo *geo; 5910 const struct ieee80211_geo *geo;
5964 int i; 5911 int i;
5965 5912
5966 geo = ipw_get_geo(priv->ieee); 5913 geo = ieee80211_get_geo(priv->ieee);
5967 5914
5968 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { 5915 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5969 int start = channel_index; 5916 int start = channel_index;
@@ -6023,7 +5970,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
6023 channel_index++; 5970 channel_index++;
6024 scan->channels_list[channel_index] = channel; 5971 scan->channels_list[channel_index] = channel;
6025 index = 5972 index =
6026 ipw_channel_to_index(priv->ieee, channel); 5973 ieee80211_channel_to_index(priv->ieee, channel);
6027 ipw_set_scan_type(scan, channel_index, 5974 ipw_set_scan_type(scan, channel_index,
6028 geo->bg[index]. 5975 geo->bg[index].
6029 flags & 5976 flags &
@@ -6105,7 +6052,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
6105 u8 channel; 6052 u8 channel;
6106 u8 band = 0; 6053 u8 band = 0;
6107 6054
6108 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { 6055 switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
6109 case IEEE80211_52GHZ_BAND: 6056 case IEEE80211_52GHZ_BAND:
6110 band = (u8) (IPW_A_MODE << 6) | 1; 6057 band = (u8) (IPW_A_MODE << 6) | 1;
6111 channel = priv->channel; 6058 channel = priv->channel;
@@ -6568,7 +6515,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,
6568* get the modulation type of the current network or 6515* get the modulation type of the current network or
6569* the card current mode 6516* the card current mode
6570*/ 6517*/
6571u8 ipw_qos_current_mode(struct ipw_priv * priv) 6518static u8 ipw_qos_current_mode(struct ipw_priv * priv)
6572{ 6519{
6573 u8 mode = 0; 6520 u8 mode = 0;
6574 6521
@@ -7815,12 +7762,10 @@ static void ipw_rx(struct ipw_priv *priv)
7815 7762
7816 while (i != r) { 7763 while (i != r) {
7817 rxb = priv->rxq->queue[i]; 7764 rxb = priv->rxq->queue[i];
7818#ifdef CONFIG_IPW2200_DEBUG
7819 if (unlikely(rxb == NULL)) { 7765 if (unlikely(rxb == NULL)) {
7820 printk(KERN_CRIT "Queue not allocated!\n"); 7766 printk(KERN_CRIT "Queue not allocated!\n");
7821 break; 7767 break;
7822 } 7768 }
7823#endif
7824 priv->rxq->queue[i] = NULL; 7769 priv->rxq->queue[i] = NULL;
7825 7770
7826 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,
@@ -7839,7 +7784,8 @@ static void ipw_rx(struct ipw_priv *priv)
7839 le16_to_cpu(pkt->u.frame.rssi_dbm) - 7784 le16_to_cpu(pkt->u.frame.rssi_dbm) -
7840 IPW_RSSI_TO_DBM, 7785 IPW_RSSI_TO_DBM,
7841 .signal = 7786 .signal =
7842 le16_to_cpu(pkt->u.frame.signal), 7787 le16_to_cpu(pkt->u.frame.rssi_dbm) -
7788 IPW_RSSI_TO_DBM + 0x100,
7843 .noise = 7789 .noise =
7844 le16_to_cpu(pkt->u.frame.noise), 7790 le16_to_cpu(pkt->u.frame.noise),
7845 .rate = pkt->u.frame.rate, 7791 .rate = pkt->u.frame.rate,
@@ -7903,7 +7849,8 @@ static void ipw_rx(struct ipw_priv *priv)
7903 le16_to_cpu(pkt->u.frame.length)); 7849 le16_to_cpu(pkt->u.frame.length));
7904 7850
7905 if (le16_to_cpu(pkt->u.frame.length) < 7851 if (le16_to_cpu(pkt->u.frame.length) <
7906 frame_hdr_len(header)) { 7852 ieee80211_get_hdrlen(le16_to_cpu(
7853 header->frame_ctl))) {
7907 IPW_DEBUG_DROP 7854 IPW_DEBUG_DROP
7908 ("Received packet is too small. " 7855 ("Received packet is too small. "
7909 "Dropping.\n"); 7856 "Dropping.\n");
@@ -7993,7 +7940,14 @@ static void ipw_rx(struct ipw_priv *priv)
7993#define DEFAULT_SHORT_RETRY_LIMIT 7U 7940#define DEFAULT_SHORT_RETRY_LIMIT 7U
7994#define DEFAULT_LONG_RETRY_LIMIT 4U 7941#define DEFAULT_LONG_RETRY_LIMIT 4U
7995 7942
7996static 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)
7997{ 7951{
7998 int band, modulation; 7952 int band, modulation;
7999 int old_mode = priv->ieee->iw_mode; 7953 int old_mode = priv->ieee->iw_mode;
@@ -8020,7 +7974,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
8020 priv->essid_len = 0; 7974 priv->essid_len = 0;
8021 memset(priv->essid, 0, IW_ESSID_MAX_SIZE); 7975 memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
8022 7976
8023 if (disable) { 7977 if (disable && option) {
8024 priv->status |= STATUS_RF_KILL_SW; 7978 priv->status |= STATUS_RF_KILL_SW;
8025 IPW_DEBUG_INFO("Radio disabled.\n"); 7979 IPW_DEBUG_INFO("Radio disabled.\n");
8026 } 7980 }
@@ -8072,7 +8026,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
8072 8026
8073 if ((priv->pci_dev->device == 0x4223) || 8027 if ((priv->pci_dev->device == 0x4223) ||
8074 (priv->pci_dev->device == 0x4224)) { 8028 (priv->pci_dev->device == 0x4224)) {
8075 if (init) 8029 if (option == 1)
8076 printk(KERN_INFO DRV_NAME 8030 printk(KERN_INFO DRV_NAME
8077 ": Detected Intel PRO/Wireless 2915ABG Network " 8031 ": Detected Intel PRO/Wireless 2915ABG Network "
8078 "Connection\n"); 8032 "Connection\n");
@@ -8083,7 +8037,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
8083 priv->adapter = IPW_2915ABG; 8037 priv->adapter = IPW_2915ABG;
8084 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B; 8038 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
8085 } else { 8039 } else {
8086 if (init) 8040 if (option == 1)
8087 printk(KERN_INFO DRV_NAME 8041 printk(KERN_INFO DRV_NAME
8088 ": Detected Intel PRO/Wireless 2200BG Network " 8042 ": Detected Intel PRO/Wireless 2200BG Network "
8089 "Connection\n"); 8043 "Connection\n");
@@ -8200,7 +8154,7 @@ static int ipw_wx_set_freq(struct net_device *dev,
8200 union iwreq_data *wrqu, char *extra) 8154 union iwreq_data *wrqu, char *extra)
8201{ 8155{
8202 struct ipw_priv *priv = ieee80211_priv(dev); 8156 struct ipw_priv *priv = ieee80211_priv(dev);
8203 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 8157 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
8204 struct iw_freq *fwrq = &wrqu->freq; 8158 struct iw_freq *fwrq = &wrqu->freq;
8205 int ret = 0, i; 8159 int ret = 0, i;
8206 u8 channel, flags; 8160 u8 channel, flags;
@@ -8215,17 +8169,17 @@ static int ipw_wx_set_freq(struct net_device *dev,
8215 } 8169 }
8216 /* if setting by freq convert to channel */ 8170 /* if setting by freq convert to channel */
8217 if (fwrq->e == 1) { 8171 if (fwrq->e == 1) {
8218 channel = ipw_freq_to_channel(priv->ieee, fwrq->m); 8172 channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m);
8219 if (channel == 0) 8173 if (channel == 0)
8220 return -EINVAL; 8174 return -EINVAL;
8221 } else 8175 } else
8222 channel = fwrq->m; 8176 channel = fwrq->m;
8223 8177
8224 if (!(band = ipw_is_valid_channel(priv->ieee, channel))) 8178 if (!(band = ieee80211_is_valid_channel(priv->ieee, channel)))
8225 return -EINVAL; 8179 return -EINVAL;
8226 8180
8227 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 8181 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
8228 i = ipw_channel_to_index(priv->ieee, channel); 8182 i = ieee80211_channel_to_index(priv->ieee, channel);
8229 if (i == -1) 8183 if (i == -1)
8230 return -EINVAL; 8184 return -EINVAL;
8231 8185
@@ -8353,7 +8307,7 @@ static int ipw_wx_get_range(struct net_device *dev,
8353{ 8307{
8354 struct ipw_priv *priv = ieee80211_priv(dev); 8308 struct ipw_priv *priv = ieee80211_priv(dev);
8355 struct iw_range *range = (struct iw_range *)extra; 8309 struct iw_range *range = (struct iw_range *)extra;
8356 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); 8310 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
8357 int i = 0, j; 8311 int i = 0, j;
8358 8312
8359 wrqu->data.length = sizeof(*range); 8313 wrqu->data.length = sizeof(*range);
@@ -8365,7 +8319,7 @@ static int ipw_wx_get_range(struct net_device *dev,
8365 range->max_qual.qual = 100; 8319 range->max_qual.qual = 100;
8366 /* TODO: Find real max RSSI and stick here */ 8320 /* TODO: Find real max RSSI and stick here */
8367 range->max_qual.level = 0; 8321 range->max_qual.level = 0;
8368 range->max_qual.noise = priv->ieee->worst_rssi + 0x100; 8322 range->max_qual.noise = 0;
8369 range->max_qual.updated = 7; /* Updated all three */ 8323 range->max_qual.updated = 7; /* Updated all three */
8370 8324
8371 range->avg_qual.qual = 70; 8325 range->avg_qual.qual = 70;
@@ -8395,20 +8349,28 @@ static int ipw_wx_get_range(struct net_device *dev,
8395 8349
8396 i = 0; 8350 i = 0;
8397 if (priv->ieee->mode & (IEEE_B | IEEE_G)) { 8351 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
8398 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; 8352 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {
8399 i++, j++) { 8353 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
8354 (geo->bg[j].flags & IEEE80211_CH_PASSIVE_ONLY))
8355 continue;
8356
8400 range->freq[i].i = geo->bg[j].channel; 8357 range->freq[i].i = geo->bg[j].channel;
8401 range->freq[i].m = geo->bg[j].freq * 100000; 8358 range->freq[i].m = geo->bg[j].freq * 100000;
8402 range->freq[i].e = 1; 8359 range->freq[i].e = 1;
8360 i++;
8403 } 8361 }
8404 } 8362 }
8405 8363
8406 if (priv->ieee->mode & IEEE_A) { 8364 if (priv->ieee->mode & IEEE_A) {
8407 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; 8365 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {
8408 i++, j++) { 8366 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
8367 (geo->a[j].flags & IEEE80211_CH_PASSIVE_ONLY))
8368 continue;
8369
8409 range->freq[i].i = geo->a[j].channel; 8370 range->freq[i].i = geo->a[j].channel;
8410 range->freq[i].m = geo->a[j].freq * 100000; 8371 range->freq[i].m = geo->a[j].freq * 100000;
8411 range->freq[i].e = 1; 8372 range->freq[i].e = 1;
8373 i++;
8412 } 8374 }
8413 } 8375 }
8414 8376
@@ -8609,6 +8571,52 @@ static int ipw_wx_get_nick(struct net_device *dev,
8609 return 0; 8571 return 0;
8610} 8572}
8611 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
8617 return 0;
8618}
8619
8612static int ipw_wx_set_rate(struct net_device *dev, 8620static int ipw_wx_set_rate(struct net_device *dev,
8613 struct iw_request_info *info, 8621 struct iw_request_info *info,
8614 union iwreq_data *wrqu, char *extra) 8622 union iwreq_data *wrqu, char *extra)
@@ -9395,7 +9403,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9395 9403
9396 mutex_lock(&priv->mutex); 9404 mutex_lock(&priv->mutex);
9397 9405
9398 ret = ipw_sw_reset(priv, 0); 9406 ret = ipw_sw_reset(priv, 2);
9399 if (!ret) { 9407 if (!ret) {
9400 free_firmware(); 9408 free_firmware();
9401 ipw_adapter_restart(priv); 9409 ipw_adapter_restart(priv);
@@ -9430,6 +9438,8 @@ static iw_handler ipw_wx_handlers[] = {
9430 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 9438 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
9431 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 9439 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
9432 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,
9433 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 9443 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
9434 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 9444 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
9435 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 9445 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
@@ -9575,7 +9585,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
9575 wstats->qual.level = average_value(&priv->average_rssi); 9585 wstats->qual.level = average_value(&priv->average_rssi);
9576 wstats->qual.noise = average_value(&priv->average_noise); 9586 wstats->qual.noise = average_value(&priv->average_noise);
9577 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | 9587 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
9578 IW_QUAL_NOISE_UPDATED; 9588 IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
9579 9589
9580 wstats->miss.beacon = average_value(&priv->average_missed_beacons); 9590 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
9581 wstats->discard.retries = priv->last_tx_failures; 9591 wstats->discard.retries = priv->last_tx_failures;
@@ -9601,12 +9611,13 @@ static void init_sys_config(struct ipw_sys_config *sys_config)
9601 sys_config->disable_unicast_decryption = 1; 9611 sys_config->disable_unicast_decryption = 1;
9602 sys_config->exclude_multicast_unencrypted = 0; 9612 sys_config->exclude_multicast_unencrypted = 0;
9603 sys_config->disable_multicast_decryption = 1; 9613 sys_config->disable_multicast_decryption = 1;
9604 sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH; 9614 sys_config->antenna_diversity = CFG_SYS_ANTENNA_SLOW_DIV;
9605 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 */
9606 sys_config->dot11g_auto_detection = 0; 9616 sys_config->dot11g_auto_detection = 0;
9607 sys_config->enable_cts_to_self = 0; 9617 sys_config->enable_cts_to_self = 0;
9608 sys_config->bt_coexist_collision_thr = 0; 9618 sys_config->bt_coexist_collision_thr = 0;
9609 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;
9610} 9621}
9611 9622
9612static int ipw_net_open(struct net_device *dev) 9623static int ipw_net_open(struct net_device *dev)
@@ -9654,11 +9665,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9654 u16 remaining_bytes; 9665 u16 remaining_bytes;
9655 int fc; 9666 int fc;
9656 9667
9657 /* If there isn't room in the queue, we return busy and let the
9658 * network stack requeue the packet for us */
9659 if (ipw_queue_space(q) < q->high_mark)
9660 return NETDEV_TX_BUSY;
9661
9662 switch (priv->ieee->iw_mode) { 9668 switch (priv->ieee->iw_mode) {
9663 case IW_MODE_ADHOC: 9669 case IW_MODE_ADHOC:
9664 hdr_len = IEEE80211_3ADDR_LEN; 9670 hdr_len = IEEE80211_3ADDR_LEN;
@@ -9824,6 +9830,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9824 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);
9825 ipw_write32(priv, q->reg_w, q->first_empty); 9831 ipw_write32(priv, q->reg_w, q->first_empty);
9826 9832
9833 if (ipw_queue_space(q) < q->high_mark)
9834 netif_stop_queue(priv->net_dev);
9835
9827 return NETDEV_TX_OK; 9836 return NETDEV_TX_OK;
9828 9837
9829 drop: 9838 drop:
@@ -9963,9 +9972,8 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
9963 return -EINVAL; 9972 return -EINVAL;
9964 mutex_lock(&p->mutex); 9973 mutex_lock(&p->mutex);
9965 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); 9974 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
9966 for (i = IPW_EEPROM_DATA; 9975 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
9967 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++) 9976 ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]);
9968 ipw_write8(p, i, p->eeprom[i]);
9969 mutex_unlock(&p->mutex); 9977 mutex_unlock(&p->mutex);
9970 return 0; 9978 return 0;
9971} 9979}
@@ -10370,6 +10378,9 @@ static int ipw_config(struct ipw_priv *priv)
10370 * not intended for resale of the above mentioned Intel adapters has 10378 * not intended for resale of the above mentioned Intel adapters has
10371 * not been tested. 10379 * not been tested.
10372 * 10380 *
10381 * Remember to update the table in README.ipw2200 when changing this
10382 * table.
10383 *
10373 */ 10384 */
10374static const struct ieee80211_geo ipw_geos[] = { 10385static const struct ieee80211_geo ipw_geos[] = {
10375 { /* Restricted */ 10386 { /* Restricted */
@@ -10617,96 +10628,6 @@ static const struct ieee80211_geo ipw_geos[] = {
10617 } 10628 }
10618}; 10629};
10619 10630
10620/* GEO code borrowed from ieee80211_geo.c */
10621static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
10622{
10623 int i;
10624
10625 /* Driver needs to initialize the geography map before using
10626 * these helper functions */
10627 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10628
10629 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10630 for (i = 0; i < ieee->geo.bg_channels; i++)
10631 /* NOTE: If G mode is currently supported but
10632 * this is a B only channel, we don't see it
10633 * as valid. */
10634 if ((ieee->geo.bg[i].channel == channel) &&
10635 (!(ieee->mode & IEEE_G) ||
10636 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
10637 return IEEE80211_24GHZ_BAND;
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 IEEE80211_52GHZ_BAND;
10643
10644 return 0;
10645}
10646
10647static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
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 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10656 for (i = 0; i < ieee->geo.bg_channels; i++)
10657 if (ieee->geo.bg[i].channel == channel)
10658 return i;
10659
10660 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10661 for (i = 0; i < ieee->geo.a_channels; i++)
10662 if (ieee->geo.a[i].channel == channel)
10663 return i;
10664
10665 return -1;
10666}
10667
10668static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
10669{
10670 int i;
10671
10672 /* Driver needs to initialize the geography map before using
10673 * these helper functions */
10674 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10675
10676 freq /= 100000;
10677
10678 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10679 for (i = 0; i < ieee->geo.bg_channels; i++)
10680 if (ieee->geo.bg[i].freq == freq)
10681 return ieee->geo.bg[i].channel;
10682
10683 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10684 for (i = 0; i < ieee->geo.a_channels; i++)
10685 if (ieee->geo.a[i].freq == freq)
10686 return ieee->geo.a[i].channel;
10687
10688 return 0;
10689}
10690
10691static int ipw_set_geo(struct ieee80211_device *ieee,
10692 const struct ieee80211_geo *geo)
10693{
10694 memcpy(ieee->geo.name, geo->name, 3);
10695 ieee->geo.name[3] = '\0';
10696 ieee->geo.bg_channels = geo->bg_channels;
10697 ieee->geo.a_channels = geo->a_channels;
10698 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
10699 sizeof(struct ieee80211_channel));
10700 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
10701 sizeof(struct ieee80211_channel));
10702 return 0;
10703}
10704
10705static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
10706{
10707 return &ieee->geo;
10708}
10709
10710#define MAX_HW_RESTARTS 5 10631#define MAX_HW_RESTARTS 5
10711static int ipw_up(struct ipw_priv *priv) 10632static int ipw_up(struct ipw_priv *priv)
10712{ 10633{
@@ -10753,14 +10674,11 @@ static int ipw_up(struct ipw_priv *priv)
10753 priv->eeprom[EEPROM_COUNTRY_CODE + 2]); 10674 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
10754 j = 0; 10675 j = 0;
10755 } 10676 }
10756 if (ipw_set_geo(priv->ieee, &ipw_geos[j])) { 10677 if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) {
10757 IPW_WARNING("Could not set geography."); 10678 IPW_WARNING("Could not set geography.");
10758 return 0; 10679 return 0;
10759 } 10680 }
10760 10681
10761 IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
10762 j, priv->ieee->geo.name);
10763
10764 if (priv->status & STATUS_RF_KILL_SW) { 10682 if (priv->status & STATUS_RF_KILL_SW) {
10765 IPW_WARNING("Radio disabled by module parameter.\n"); 10683 IPW_WARNING("Radio disabled by module parameter.\n");
10766 return 0; 10684 return 0;
@@ -11081,6 +10999,12 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11081 IPW_ERROR("failed to register network device\n"); 10999 IPW_ERROR("failed to register network device\n");
11082 goto out_remove_sysfs; 11000 goto out_remove_sysfs;
11083 } 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
11084 return 0; 11008 return 0;
11085 11009
11086 out_remove_sysfs: 11010 out_remove_sysfs:
@@ -11271,8 +11195,10 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
11271module_param(led, int, 0444); 11195module_param(led, int, 0444);
11272MODULE_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");
11273 11197
11198#ifdef CONFIG_IPW2200_DEBUG
11274module_param(debug, int, 0444); 11199module_param(debug, int, 0444);
11275MODULE_PARM_DESC(debug, "debug output mask"); 11200MODULE_PARM_DESC(debug, "debug output mask");
11201#endif
11276 11202
11277module_param(channel, int, 0444); 11203module_param(channel, int, 0444);
11278MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11204MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 5405ba105ab..4b980490070 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -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 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -246,8 +246,10 @@ enum connection_manager_assoc_states {
246#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31 246#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31
247 247
248#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1 248#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1
249#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 24 249#define IPW_MB_ROAMING_THRESHOLD_MIN 1
250#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8 250#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8
251#define IPW_MB_ROAMING_THRESHOLD_MAX 30
252#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 3*IPW_MB_ROAMING_THRESHOLD_DEFAULT
251#define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300 253#define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300
252 254
253#define MACADRR_BYTE_LEN 6 255#define MACADRR_BYTE_LEN 6
@@ -618,13 +620,16 @@ struct notif_tgi_tx_key {
618 u8 reserved; 620 u8 reserved;
619} __attribute__ ((packed)); 621} __attribute__ ((packed));
620 622
623#define SILENCE_OVER_THRESH (1)
624#define SILENCE_UNDER_THRESH (2)
625
621struct notif_link_deterioration { 626struct notif_link_deterioration {
622 struct ipw_cmd_stats stats; 627 struct ipw_cmd_stats stats;
623 u8 rate; 628 u8 rate;
624 u8 modulation; 629 u8 modulation;
625 struct rate_histogram histogram; 630 struct rate_histogram histogram;
626 u8 reserved1; 631 u8 silence_notification_type; /* SILENCE_OVER/UNDER_THRESH */
627 u16 reserved2; 632 u16 silence_count;
628} __attribute__ ((packed)); 633} __attribute__ ((packed));
629 634
630struct notif_association { 635struct notif_association {
@@ -782,7 +787,7 @@ struct ipw_sys_config {
782 u8 enable_cts_to_self; 787 u8 enable_cts_to_self;
783 u8 enable_multicast_filtering; 788 u8 enable_multicast_filtering;
784 u8 bt_coexist_collision_thr; 789 u8 bt_coexist_collision_thr;
785 u8 reserved2; 790 u8 silence_threshold;
786 u8 accept_all_mgmt_bcpr; 791 u8 accept_all_mgmt_bcpr;
787 u8 accept_all_mgtm_frames; 792 u8 accept_all_mgtm_frames;
788 u8 pass_noise_stats_to_host; 793 u8 pass_noise_stats_to_host;
@@ -1892,6 +1897,7 @@ struct ipw_cmd_log {
1892#define CFG_SYS_ANTENNA_BOTH 0x00 /* NIC selects best antenna */ 1897#define CFG_SYS_ANTENNA_BOTH 0x00 /* NIC selects best antenna */
1893#define CFG_SYS_ANTENNA_A 0x01 /* force antenna A */ 1898#define CFG_SYS_ANTENNA_A 0x01 /* force antenna A */
1894#define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ 1899#define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */
1900#define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */
1895 1901
1896/* 1902/*
1897 * The definitions below were lifted off the ipw2100 driver, which only 1903 * The definitions below were lifted off the ipw2100 driver, which only
@@ -1907,27 +1913,4 @@ struct ipw_cmd_log {
1907 1913
1908#define IPW_MAX_CONFIG_RETRIES 10 1914#define IPW_MAX_CONFIG_RETRIES 10
1909 1915
1910static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
1911{
1912 u32 retval;
1913 u16 fc;
1914
1915 retval = sizeof(struct ieee80211_hdr_3addr);
1916 fc = le16_to_cpu(hdr->frame_ctl);
1917
1918 /*
1919 * Function ToDS FromDS
1920 * IBSS 0 0
1921 * To AP 1 0
1922 * From AP 0 1
1923 * WDS (bridge) 1 1
1924 *
1925 * Only WDS frames use Address4 among them. --YZ
1926 */
1927 if (!(fc & IEEE80211_FCTL_TODS) || !(fc & IEEE80211_FCTL_FROMDS))
1928 retval -= ETH_ALEN;
1929
1930 return retval;
1931}
1932
1933#endif /* __ipw2200_h__ */ 1916#endif /* __ipw2200_h__ */
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 785d5a170a7..a7f2a642a51 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -1345,7 +1345,19 @@ static void update_network(struct ieee80211_network *dst,
1345 ieee80211_network_reset(dst); 1345 ieee80211_network_reset(dst);
1346 dst->ibss_dfs = src->ibss_dfs; 1346 dst->ibss_dfs = src->ibss_dfs;
1347 1347
1348 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); 1348 /* We only update the statistics if they were created by receiving
1349 * the network information on the actual channel the network is on.
1350 *
1351 * This keeps beacons received on neighbor channels from bringing
1352 * down the signal level of an AP. */
1353 if (dst->channel == src->stats.received_channel)
1354 memcpy(&dst->stats, &src->stats,
1355 sizeof(struct ieee80211_rx_stats));
1356 else
1357 IEEE80211_DEBUG_SCAN("Network " MAC_FMT " info received "
1358 "off channel (%d vs. %d)\n", MAC_ARG(src->bssid),
1359 dst->channel, src->stats.received_channel);
1360
1349 dst->capability = src->capability; 1361 dst->capability = src->capability;
1350 memcpy(dst->rates, src->rates, src->rates_len); 1362 memcpy(dst->rates, src->rates, src->rates_len);
1351 dst->rates_len = src->rates_len; 1363 dst->rates_len = src->rates_len;