diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-03-20 04:38:50 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-20 04:38:50 -0500 |
commit | 2e9ff56efbc005ab2b92b68df65940c7459446c6 (patch) | |
tree | 8844a54f2b205bb5dceb6391d05df9a9f8bc62d2 /drivers | |
parent | d378aca6ec708bfb24df5c47801b1f2399efc481 (diff) | |
parent | cc8279f68c34c3f32b3a85f3103b0ad755c57846 (diff) |
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ipw2100.c | 220 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2100.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 450 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2200.h | 39 |
4 files changed, 354 insertions, 366 deletions
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index eb79198ac450..72335c8eb97f 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 | |||
2442 | static 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 | |||
2449 | static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i) | 2523 | static 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 | ||
5539 | static int ipw2100_adapter_setup(struct ipw2100_priv *priv) | 5613 | static 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 51360910d222..55b7227198df 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 | ||
46 | struct ipw2100_priv; | 51 | struct ipw2100_priv; |
47 | struct ipw2100_tx_packet; | 52 | struct 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 ed37141319ea..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.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, | |||
153 | static void ipw_set_hwcrypto_keys(struct ipw_priv *); | 153 | static void ipw_set_hwcrypto_keys(struct ipw_priv *); |
154 | static void ipw_send_wep_keys(struct ipw_priv *, int); | 154 | static void ipw_send_wep_keys(struct ipw_priv *, int); |
155 | 155 | ||
156 | static int ipw_is_valid_channel(struct ieee80211_device *, u8); | ||
157 | static int ipw_channel_to_index(struct ieee80211_device *, u8); | ||
158 | static u8 ipw_freq_to_channel(struct ieee80211_device *, u32); | ||
159 | static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *); | ||
160 | static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *); | ||
161 | |||
162 | static int snprint_line(char *buf, size_t count, | 156 | static 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 | ||
2223 | static int ipw_set_tx_power(struct ipw_priv *priv) | 2217 | static 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 | ||
2838 | struct fw_header { | ||
2839 | u32 version; | ||
2840 | u32 mode; | ||
2841 | }; | ||
2842 | |||
2843 | struct fw_chunk { | 2832 | struct 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 | |||
2865 | static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) | 2837 | static 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 | |||
3106 | struct ipw_fw { | ||
3107 | u32 ver; | ||
3108 | u32 boot_size; | ||
3109 | u32 ucode_size; | ||
3110 | u32 fw_size; | ||
3111 | u8 data[0]; | ||
3112 | }; | ||
3113 | |||
3133 | static int ipw_get_fw(struct ipw_priv *priv, | 3114 | static 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 |
3198 | static int fw_loaded = 0; | 3184 | static int fw_loaded = 0; |
3199 | static const struct firmware *bootfw = NULL; | 3185 | static const struct firmware *raw = NULL; |
3200 | static const struct firmware *firmware = NULL; | ||
3201 | static const struct firmware *ucode = NULL; | ||
3202 | 3186 | ||
3203 | static void free_firmware(void) | 3187 | static 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) | |||
3217 | static int ipw_load(struct ipw_priv *priv) | 3199 | static 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, | |||
5607 | static void ipw_adhoc_create(struct ipw_priv *priv, | 5554 | static 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 | */ |
6571 | u8 ipw_qos_current_mode(struct ipw_priv * priv) | 6518 | static 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 | ||
7996 | static 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 | */ | ||
7950 | static 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 | ||
8574 | static 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 | |||
8604 | static 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 | |||
8612 | static int ipw_wx_set_rate(struct net_device *dev, | 8620 | static 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 | ||
9612 | static int ipw_net_open(struct net_device *dev) | 9623 | static 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 | */ |
10374 | static const struct ieee80211_geo ipw_geos[] = { | 10385 | static 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 */ | ||
10621 | static 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 | |||
10647 | static 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 | |||
10668 | static 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 | |||
10691 | static 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 | |||
10705 | static 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 |
10711 | static int ipw_up(struct ipw_priv *priv) | 10632 | static 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)"); | |||
11271 | module_param(led, int, 0444); | 11195 | module_param(led, int, 0444); |
11272 | MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); | 11196 | MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); |
11273 | 11197 | ||
11198 | #ifdef CONFIG_IPW2200_DEBUG | ||
11274 | module_param(debug, int, 0444); | 11199 | module_param(debug, int, 0444); |
11275 | MODULE_PARM_DESC(debug, "debug output mask"); | 11200 | MODULE_PARM_DESC(debug, "debug output mask"); |
11201 | #endif | ||
11276 | 11202 | ||
11277 | module_param(channel, int, 0444); | 11203 | module_param(channel, int, 0444); |
11278 | MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); | 11204 | MODULE_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 5405ba105abf..4b9804900702 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 | |||
621 | struct notif_link_deterioration { | 626 | struct 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 | ||
630 | struct notif_association { | 635 | struct 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 | ||
1910 | static 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__ */ |