Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
This commit is contained in:
commit
2e9ff56efb
7 changed files with 416 additions and 376 deletions
|
@ -3,18 +3,18 @@ Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
|
|||
|
||||
Intel(R) PRO/Wireless 2100 Network Connection
|
||||
|
||||
Copyright (C) 2003-2005, Intel Corporation
|
||||
Copyright (C) 2003-2006, Intel Corporation
|
||||
|
||||
README.ipw2100
|
||||
|
||||
Version: 1.1.3
|
||||
Date : October 17, 2005
|
||||
Version: git-1.1.5
|
||||
Date : January 25, 2006
|
||||
|
||||
Index
|
||||
-----------------------------------------------
|
||||
0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
|
||||
1. Introduction
|
||||
2. Release 1.1.3 Current Features
|
||||
2. Release git-1.1.5 Current Features
|
||||
3. Command Line Parameters
|
||||
4. Sysfs Helper Files
|
||||
5. Radio Kill Switch
|
||||
|
@ -89,7 +89,7 @@ potential fixes and patches, as well as links to the development mailing list
|
|||
for the driver project.
|
||||
|
||||
|
||||
2. Release 1.1.3 Current Supported Features
|
||||
2. Release git-1.1.5 Current Supported Features
|
||||
-----------------------------------------------
|
||||
- Managed (BSS) and Ad-Hoc (IBSS)
|
||||
- WEP (shared key and open)
|
||||
|
@ -270,7 +270,7 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
|
|||
9. License
|
||||
-----------------------------------------------
|
||||
|
||||
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
|
||||
Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License (version 2) as
|
||||
|
|
|
@ -10,7 +10,7 @@ both hardware adapters listed above. In this document the Intel(R)
|
|||
PRO/Wireless 2915ABG Driver for Linux will be used to reference the
|
||||
unified driver.
|
||||
|
||||
Copyright (C) 2004-2005, Intel Corporation
|
||||
Copyright (C) 2004-2006, Intel Corporation
|
||||
|
||||
README.ipw2200
|
||||
|
||||
|
@ -26,9 +26,11 @@ Index
|
|||
1.2. Module parameters
|
||||
1.3. Wireless Extension Private Methods
|
||||
1.4. Sysfs Helper Files
|
||||
1.5. Supported channels
|
||||
2. Ad-Hoc Networking
|
||||
3. Interacting with Wireless Tools
|
||||
3.1. iwconfig mode
|
||||
3.2. iwconfig sens
|
||||
4. About the Version Numbers
|
||||
5. Firmware installation
|
||||
6. Support
|
||||
|
@ -314,6 +316,35 @@ For the device level files, see /sys/bus/pci/drivers/ipw2200:
|
|||
running ifconfig and is therefore disabled by default.
|
||||
|
||||
|
||||
1.5. Supported channels
|
||||
-----------------------------------------------
|
||||
|
||||
Upon loading the Intel(R) PRO/Wireless 2915ABG Driver for Linux, a
|
||||
message stating the detected geography code and the number of 802.11
|
||||
channels supported by the card will be displayed in the log.
|
||||
|
||||
The geography code corresponds to a regulatory domain as shown in the
|
||||
table below.
|
||||
|
||||
Supported channels
|
||||
Code Geography 802.11bg 802.11a
|
||||
|
||||
--- Restricted 11 0
|
||||
ZZF Custom US/Canada 11 8
|
||||
ZZD Rest of World 13 0
|
||||
ZZA Custom USA & Europe & High 11 13
|
||||
ZZB Custom NA & Europe 11 13
|
||||
ZZC Custom Japan 11 4
|
||||
ZZM Custom 11 0
|
||||
ZZE Europe 13 19
|
||||
ZZJ Custom Japan 14 4
|
||||
ZZR Rest of World 14 0
|
||||
ZZH High Band 13 4
|
||||
ZZG Custom Europe 13 4
|
||||
ZZK Europe 13 24
|
||||
ZZL Europe 11 13
|
||||
|
||||
|
||||
2. Ad-Hoc Networking
|
||||
-----------------------------------------------
|
||||
|
||||
|
@ -353,6 +384,15 @@ When configuring the mode of the adapter, all run-time configured parameters
|
|||
are reset to the value used when the module was loaded. This includes
|
||||
channels, rates, ESSID, etc.
|
||||
|
||||
3.2 iwconfig sens
|
||||
-----------------------------------------------
|
||||
|
||||
The 'iwconfig ethX sens XX' command will not set the signal sensitivity
|
||||
threshold, as described in iwconfig documentation, but rather the number
|
||||
of consecutive missed beacons that will trigger handover, i.e. roaming
|
||||
to another access point. At the same time, it will set the disassociation
|
||||
threshold to 3 times the given value.
|
||||
|
||||
|
||||
4. About the Version Numbers
|
||||
-----------------------------------------------
|
||||
|
@ -408,7 +448,7 @@ For general information and support, go to:
|
|||
7. License
|
||||
-----------------------------------------------
|
||||
|
||||
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
|
||||
Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
|
||||
Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
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.
|
|||
|
||||
#include "ipw2100.h"
|
||||
|
||||
#define IPW2100_VERSION "git-1.1.4"
|
||||
#define IPW2100_VERSION "git-1.2.2"
|
||||
|
||||
#define DRV_NAME "ipw2100"
|
||||
#define DRV_VERSION IPW2100_VERSION
|
||||
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
|
||||
|
||||
/* Debugging stuff */
|
||||
#ifdef CONFIG_IPW2100_DEBUG
|
||||
|
@ -1418,7 +1418,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
|
|||
if (priv->status & STATUS_ENABLED)
|
||||
return 0;
|
||||
|
||||
down(&priv->adapter_sem);
|
||||
mutex_lock(&priv->adapter_mutex);
|
||||
|
||||
if (rf_kill_active(priv)) {
|
||||
IPW_DEBUG_HC("Command aborted due to RF kill active.\n");
|
||||
|
@ -1444,7 +1444,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
|
|||
}
|
||||
|
||||
fail_up:
|
||||
up(&priv->adapter_sem);
|
||||
mutex_unlock(&priv->adapter_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1576,7 +1576,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
|
|||
cancel_delayed_work(&priv->hang_check);
|
||||
}
|
||||
|
||||
down(&priv->adapter_sem);
|
||||
mutex_lock(&priv->adapter_mutex);
|
||||
|
||||
err = ipw2100_hw_send_command(priv, &cmd);
|
||||
if (err) {
|
||||
|
@ -1595,7 +1595,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
|
|||
IPW_DEBUG_INFO("TODO: implement scan state machine\n");
|
||||
|
||||
fail_up:
|
||||
up(&priv->adapter_sem);
|
||||
mutex_unlock(&priv->adapter_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1888,7 +1888,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
|
|||
priv->status |= STATUS_RESET_PENDING;
|
||||
spin_unlock_irqrestore(&priv->low_lock, flags);
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
/* stop timed checks so that they don't interfere with reset */
|
||||
priv->stop_hang_check = 1;
|
||||
cancel_delayed_work(&priv->hang_check);
|
||||
|
@ -1898,7 +1898,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
|
|||
wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
|
||||
|
||||
ipw2100_up(priv, 0);
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
|
||||
}
|
||||
|
||||
|
@ -2390,15 +2390,6 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
|
|||
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_IPW2100_MONITOR
|
||||
if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
|
||||
priv->config & CFG_CRC_CHECK &&
|
||||
status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
|
||||
IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
|
||||
priv->ieee->stats.rx_errors++;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
|
||||
!(priv->status & STATUS_ASSOCIATED))) {
|
||||
|
@ -2446,6 +2437,89 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
|
|||
priv->rx_queue.drv[i].host_addr = packet->dma_addr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPW2100_MONITOR
|
||||
|
||||
static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
|
||||
struct ieee80211_rx_stats *stats)
|
||||
{
|
||||
struct ipw2100_status *status = &priv->status_queue.drv[i];
|
||||
struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
|
||||
|
||||
/* Magic struct that slots into the radiotap header -- no reason
|
||||
* to build this manually element by element, we can write it much
|
||||
* more efficiently than we can parse it. ORDER MATTERS HERE */
|
||||
struct ipw_rt_hdr {
|
||||
struct ieee80211_radiotap_header rt_hdr;
|
||||
s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
|
||||
} *ipw_rt;
|
||||
|
||||
IPW_DEBUG_RX("Handler...\n");
|
||||
|
||||
if (unlikely(status->frame_size > skb_tailroom(packet->skb) -
|
||||
sizeof(struct ipw_rt_hdr))) {
|
||||
IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
|
||||
" Dropping.\n",
|
||||
priv->net_dev->name,
|
||||
status->frame_size,
|
||||
skb_tailroom(packet->skb));
|
||||
priv->ieee->stats.rx_errors++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(!netif_running(priv->net_dev))) {
|
||||
priv->ieee->stats.rx_errors++;
|
||||
priv->wstats.discard.misc++;
|
||||
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(priv->config & CFG_CRC_CHECK &&
|
||||
status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
|
||||
IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
|
||||
priv->ieee->stats.rx_errors++;
|
||||
return;
|
||||
}
|
||||
|
||||
pci_unmap_single(priv->pci_dev, packet->dma_addr,
|
||||
sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
|
||||
memmove(packet->skb->data + sizeof(struct ipw_rt_hdr),
|
||||
packet->skb->data, status->frame_size);
|
||||
|
||||
ipw_rt = (struct ipw_rt_hdr *) packet->skb->data;
|
||||
|
||||
ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
|
||||
ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
|
||||
ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total hdr+data */
|
||||
|
||||
ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL;
|
||||
|
||||
ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM;
|
||||
|
||||
skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
|
||||
|
||||
if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
|
||||
priv->ieee->stats.rx_errors++;
|
||||
|
||||
/* ieee80211_rx failed, so it didn't free the SKB */
|
||||
dev_kfree_skb_any(packet->skb);
|
||||
packet->skb = NULL;
|
||||
}
|
||||
|
||||
/* We need to allocate a new SKB and attach it to the RDB. */
|
||||
if (unlikely(ipw2100_alloc_skb(priv, packet))) {
|
||||
IPW_DEBUG_WARNING(
|
||||
"%s: Unable to allocate SKB onto RBD ring - disabling "
|
||||
"adapter.\n", priv->net_dev->name);
|
||||
/* TODO: schedule adapter shutdown */
|
||||
IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
|
||||
}
|
||||
|
||||
/* Update the RDB entry */
|
||||
priv->rx_queue.drv[i].host_addr = packet->dma_addr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
|
||||
{
|
||||
struct ipw2100_status *status = &priv->status_queue.drv[i];
|
||||
|
@ -2577,7 +2651,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
|
|||
case P8023_DATA_VAL:
|
||||
#ifdef CONFIG_IPW2100_MONITOR
|
||||
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
|
||||
isr_rx(priv, i, &stats);
|
||||
isr_rx_monitor(priv, i, &stats);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -3882,7 +3956,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
|
|||
#ifdef CONFIG_IPW2100_MONITOR
|
||||
case IW_MODE_MONITOR:
|
||||
priv->last_mode = priv->ieee->iw_mode;
|
||||
priv->net_dev->type = ARPHRD_IEEE80211;
|
||||
priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
|
||||
break;
|
||||
#endif /* CONFIG_IPW2100_MONITOR */
|
||||
}
|
||||
|
@ -4138,7 +4212,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
|
|||
IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
|
||||
disable_radio ? "OFF" : "ON");
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
|
||||
if (disable_radio) {
|
||||
priv->status |= STATUS_RF_KILL_SW;
|
||||
|
@ -4156,7 +4230,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
|
|||
schedule_reset(priv);
|
||||
}
|
||||
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -5460,7 +5534,7 @@ static void shim__set_security(struct net_device *dev,
|
|||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
int i, force_update = 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED))
|
||||
goto done;
|
||||
|
||||
|
@ -5533,7 +5607,7 @@ static void shim__set_security(struct net_device *dev,
|
|||
if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
|
||||
ipw2100_configure_security(priv, 0);
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
}
|
||||
|
||||
static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
|
||||
|
@ -5657,7 +5731,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
|
|||
if (!is_valid_ether_addr(addr->sa_data))
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
|
||||
priv->config |= CFG_CUSTOM_MAC;
|
||||
memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
|
||||
|
@ -5667,12 +5741,12 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
|
|||
goto done;
|
||||
|
||||
priv->reset_backoff = 0;
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
ipw2100_reset_adapter(priv);
|
||||
return 0;
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -6015,8 +6089,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
|
|||
strcpy(priv->nick, "ipw2100");
|
||||
|
||||
spin_lock_init(&priv->low_lock);
|
||||
sema_init(&priv->action_sem, 1);
|
||||
sema_init(&priv->adapter_sem, 1);
|
||||
mutex_init(&priv->action_mutex);
|
||||
mutex_init(&priv->adapter_mutex);
|
||||
|
||||
init_waitqueue_head(&priv->wait_command_queue);
|
||||
|
||||
|
@ -6181,7 +6255,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
|
|||
* member to call a function that then just turns and calls ipw2100_up.
|
||||
* net_dev->init is called after name allocation but before the
|
||||
* notifier chain is called */
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
err = register_netdev(dev);
|
||||
if (err) {
|
||||
printk(KERN_WARNING DRV_NAME
|
||||
|
@ -6217,12 +6291,12 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
|
|||
|
||||
priv->status |= STATUS_INITIALIZED;
|
||||
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_unlock:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
|
||||
fail:
|
||||
if (dev) {
|
||||
|
@ -6262,7 +6336,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
|
|||
struct net_device *dev;
|
||||
|
||||
if (priv) {
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
|
||||
priv->status &= ~STATUS_INITIALIZED;
|
||||
|
||||
|
@ -6277,9 +6351,9 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
|
|||
/* Take down the hardware */
|
||||
ipw2100_down(priv);
|
||||
|
||||
/* Release the semaphore so that the network subsystem can
|
||||
/* Release the mutex so that the network subsystem can
|
||||
* complete any needed calls into the driver... */
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
|
||||
/* Unregister the device first - this results in close()
|
||||
* 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)
|
|||
|
||||
IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (priv->status & STATUS_INITIALIZED) {
|
||||
/* Take down the device; powers it off, etc. */
|
||||
ipw2100_down(priv);
|
||||
|
@ -6331,7 +6405,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
|
|||
pci_disable_device(pci_dev);
|
||||
pci_set_power_state(pci_dev, PCI_D3hot);
|
||||
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -6345,7 +6419,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
|
|||
if (IPW2100_PM_DISABLED)
|
||||
return 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
|
||||
IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
|
||||
|
||||
|
@ -6371,7 +6445,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
|
|||
if (!(priv->status & STATUS_RF_KILL_SW))
|
||||
ipw2100_up(priv, 0);
|
||||
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -6535,7 +6609,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
|
|||
if (priv->ieee->iw_mode == IW_MODE_INFRA)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -6566,7 +6640,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
|
|||
}
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -6607,7 +6681,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
|
|||
if (wrqu->mode == priv->ieee->iw_mode)
|
||||
return 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -6630,7 +6704,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
|
|||
}
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -6812,7 +6886,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
|
|||
if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
|
||||
return -EINVAL;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -6841,7 +6915,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
|
|||
wrqu->ap_addr.sa_data[5] & 0xff);
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -6877,7 +6951,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
|
|||
int length = 0;
|
||||
int err = 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -6914,7 +6988,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
|
|||
err = ipw2100_set_essid(priv, essid, length, 0);
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -6995,7 +7069,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
|
|||
u32 rate;
|
||||
int err = 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7022,7 +7096,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
|
|||
|
||||
IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7042,7 +7116,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7074,7 +7148,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
|
|||
IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7089,7 +7163,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
|
|||
if (wrqu->rts.fixed == 0)
|
||||
return -EINVAL;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7109,7 +7183,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
|
|||
|
||||
IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7160,7 +7234,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
|
|||
value = wrqu->txpower.value;
|
||||
}
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7171,7 +7245,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
|
|||
IPW_DEBUG_WX("SET TX Power -> %d \n", value);
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7263,7 +7337,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
|
|||
if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
|
||||
return 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7290,7 +7364,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
|
|||
IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7333,7 +7407,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
|
|||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
int err = 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7348,7 +7422,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
|
|||
}
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7398,7 +7472,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
|
|||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
int err = 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7431,7 +7505,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
|
|||
IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
|
||||
}
|
||||
|
@ -7735,7 +7809,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
|
|||
int enable = (parms[0] > 0);
|
||||
int err = 0;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7753,7 +7827,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
|
|||
err = ipw2100_switch_mode(priv, priv->last_mode);
|
||||
}
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7776,7 +7850,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
|
|||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
int err = 0, mode = *(int *)extra;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7788,7 +7862,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
|
|||
if (priv->power_mode != mode)
|
||||
err = ipw2100_set_power_mode(priv, mode);
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7840,7 +7914,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
|
|||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
int err, mode = *(int *)extra;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7858,7 +7932,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
|
|||
err = ipw2100_system_config(priv, 0);
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -7888,7 +7962,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
|
|||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
int err, mode = *(int *)extra;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
if (!(priv->status & STATUS_INITIALIZED)) {
|
||||
err = -EIO;
|
||||
goto done;
|
||||
|
@ -7905,7 +7979,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
|
|||
err = 0;
|
||||
|
||||
done:
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -8210,11 +8284,11 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
|
|||
if (priv->status & STATUS_STOPPING)
|
||||
return;
|
||||
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
|
||||
IPW_DEBUG_WX("enter\n");
|
||||
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
|
||||
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
|
@ -8237,7 +8311,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
|
|||
|
||||
if (!(priv->status & STATUS_ASSOCIATED)) {
|
||||
IPW_DEBUG_WX("Configuring ESSID\n");
|
||||
down(&priv->action_sem);
|
||||
mutex_lock(&priv->action_mutex);
|
||||
/* This is a disassociation event, so kick the firmware to
|
||||
* look for another AP */
|
||||
if (priv->config & CFG_STATIC_ESSID)
|
||||
|
@ -8245,7 +8319,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
|
|||
0);
|
||||
else
|
||||
ipw2100_set_essid(priv, NULL, 0, 0);
|
||||
up(&priv->action_sem);
|
||||
mutex_unlock(&priv->action_mutex);
|
||||
}
|
||||
|
||||
wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
|
||||
Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -41,7 +41,12 @@
|
|||
|
||||
#include <net/ieee80211.h>
|
||||
|
||||
#ifdef CONFIG_IPW2100_MONITOR
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
#endif
|
||||
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
struct ipw2100_priv;
|
||||
struct ipw2100_tx_packet;
|
||||
|
@ -590,8 +595,8 @@ struct ipw2100_priv {
|
|||
int inta_other;
|
||||
|
||||
spinlock_t low_lock;
|
||||
struct semaphore action_sem;
|
||||
struct semaphore adapter_sem;
|
||||
struct mutex action_mutex;
|
||||
struct mutex adapter_mutex;
|
||||
|
||||
wait_queue_head_t wait_command_queue;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
|
||||
Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
|
||||
|
||||
802.11 status code portion of this file from ethereal-0.10.6:
|
||||
Copyright 2000, Axis Communications AB
|
||||
|
@ -33,9 +33,9 @@
|
|||
#include "ipw2200.h"
|
||||
#include <linux/version.h>
|
||||
|
||||
#define IPW2200_VERSION "git-1.0.10"
|
||||
#define IPW2200_VERSION "git-1.1.1"
|
||||
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
|
||||
#define DRV_VERSION IPW2200_VERSION
|
||||
|
||||
#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
|
||||
|
@ -153,12 +153,6 @@ static int init_supported_rates(struct ipw_priv *priv,
|
|||
static void ipw_set_hwcrypto_keys(struct ipw_priv *);
|
||||
static void ipw_send_wep_keys(struct ipw_priv *, int);
|
||||
|
||||
static int ipw_is_valid_channel(struct ieee80211_device *, u8);
|
||||
static int ipw_channel_to_index(struct ieee80211_device *, u8);
|
||||
static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
|
||||
static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
|
||||
static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
|
||||
|
||||
static int snprint_line(char *buf, size_t count,
|
||||
const u8 * data, u32 len, u32 ofs)
|
||||
{
|
||||
|
@ -1654,7 +1648,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
|
|||
break;
|
||||
}
|
||||
|
||||
if (ipw_is_valid_channel(priv->ieee, channel))
|
||||
if (ieee80211_is_valid_channel(priv->ieee, channel))
|
||||
priv->speed_scan[pos++] = channel;
|
||||
else
|
||||
IPW_WARNING("Skipping invalid channel request: %d\n",
|
||||
|
@ -1802,9 +1796,9 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
|
|||
}
|
||||
|
||||
if (inta & IPW_INTA_BIT_FATAL_ERROR) {
|
||||
IPW_ERROR("Firmware error detected. Restarting.\n");
|
||||
IPW_WARNING("Firmware error detected. Restarting.\n");
|
||||
if (priv->error) {
|
||||
IPW_ERROR("Sysfs 'error' log already exists.\n");
|
||||
IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");
|
||||
#ifdef CONFIG_IPW2200_DEBUG
|
||||
if (ipw_debug_level & IPW_DL_FW_ERRORS) {
|
||||
struct ipw_fw_error *error =
|
||||
|
@ -1817,10 +1811,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
|
|||
} else {
|
||||
priv->error = ipw_alloc_error_log(priv);
|
||||
if (priv->error)
|
||||
IPW_ERROR("Sysfs 'error' log captured.\n");
|
||||
IPW_DEBUG_FW("Sysfs 'error' log captured.\n");
|
||||
else
|
||||
IPW_ERROR("Error allocating sysfs 'error' "
|
||||
"log.\n");
|
||||
IPW_DEBUG_FW("Error allocating sysfs 'error' "
|
||||
"log.\n");
|
||||
#ifdef CONFIG_IPW2200_DEBUG
|
||||
if (ipw_debug_level & IPW_DL_FW_ERRORS)
|
||||
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)
|
|||
|
||||
static int ipw_set_tx_power(struct ipw_priv *priv)
|
||||
{
|
||||
const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
|
||||
const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
|
||||
struct ipw_tx_power tx_power;
|
||||
s8 max_power;
|
||||
int i;
|
||||
|
@ -2835,33 +2829,11 @@ static void ipw_arc_release(struct ipw_priv *priv)
|
|||
mdelay(5);
|
||||
}
|
||||
|
||||
struct fw_header {
|
||||
u32 version;
|
||||
u32 mode;
|
||||
};
|
||||
|
||||
struct fw_chunk {
|
||||
u32 address;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
#define IPW_FW_MAJOR_VERSION 2
|
||||
#define IPW_FW_MINOR_VERSION 4
|
||||
|
||||
#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
|
||||
#define IPW_FW_MAJOR(x) (x & 0xff)
|
||||
|
||||
#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
|
||||
|
||||
#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
|
||||
"." __stringify(IPW_FW_MINOR_VERSION) "-"
|
||||
|
||||
#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
|
||||
#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
|
||||
#else
|
||||
#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
|
||||
#endif
|
||||
|
||||
static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
|
||||
{
|
||||
int rc = 0, i, addr;
|
||||
|
@ -3130,33 +3102,47 @@ static int ipw_reset_nic(struct ipw_priv *priv)
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
struct ipw_fw {
|
||||
u32 ver;
|
||||
u32 boot_size;
|
||||
u32 ucode_size;
|
||||
u32 fw_size;
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
static int ipw_get_fw(struct ipw_priv *priv,
|
||||
const struct firmware **fw, const char *name)
|
||||
const struct firmware **raw, const char *name)
|
||||
{
|
||||
struct fw_header *header;
|
||||
struct ipw_fw *fw;
|
||||
int rc;
|
||||
|
||||
/* ask firmware_class module to get the boot firmware off disk */
|
||||
rc = request_firmware(fw, name, &priv->pci_dev->dev);
|
||||
rc = request_firmware(raw, name, &priv->pci_dev->dev);
|
||||
if (rc < 0) {
|
||||
IPW_ERROR("%s load failed: Reason %d\n", name, rc);
|
||||
IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
header = (struct fw_header *)(*fw)->data;
|
||||
if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
|
||||
IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
|
||||
name,
|
||||
IPW_FW_MAJOR(le32_to_cpu(header->version)),
|
||||
IPW_FW_MAJOR_VERSION);
|
||||
if ((*raw)->size < sizeof(*fw)) {
|
||||
IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
|
||||
fw = (void *)(*raw)->data;
|
||||
|
||||
if ((*raw)->size < sizeof(*fw) +
|
||||
fw->boot_size + fw->ucode_size + fw->fw_size) {
|
||||
IPW_ERROR("%s is too small or corrupt (%zd)\n",
|
||||
name, (*raw)->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n",
|
||||
name,
|
||||
IPW_FW_MAJOR(le32_to_cpu(header->version)),
|
||||
IPW_FW_MINOR(le32_to_cpu(header->version)),
|
||||
(*fw)->size - sizeof(struct fw_header));
|
||||
le32_to_cpu(fw->ver) >> 16,
|
||||
le32_to_cpu(fw->ver) & 0xff,
|
||||
(*raw)->size - sizeof(*fw));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3196,17 +3182,13 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
static int fw_loaded = 0;
|
||||
static const struct firmware *bootfw = NULL;
|
||||
static const struct firmware *firmware = NULL;
|
||||
static const struct firmware *ucode = NULL;
|
||||
static const struct firmware *raw = NULL;
|
||||
|
||||
static void free_firmware(void)
|
||||
{
|
||||
if (fw_loaded) {
|
||||
release_firmware(bootfw);
|
||||
release_firmware(ucode);
|
||||
release_firmware(firmware);
|
||||
bootfw = ucode = firmware = NULL;
|
||||
release_firmware(raw);
|
||||
raw = NULL;
|
||||
fw_loaded = 0;
|
||||
}
|
||||
}
|
||||
|
@ -3217,33 +3199,47 @@ static void free_firmware(void)
|
|||
static int ipw_load(struct ipw_priv *priv)
|
||||
{
|
||||
#ifndef CONFIG_PM
|
||||
const struct firmware *bootfw = NULL;
|
||||
const struct firmware *firmware = NULL;
|
||||
const struct firmware *ucode = NULL;
|
||||
const struct firmware *raw = NULL;
|
||||
#endif
|
||||
char *ucode_name;
|
||||
char *fw_name;
|
||||
struct ipw_fw *fw;
|
||||
u8 *boot_img, *ucode_img, *fw_img;
|
||||
u8 *name = NULL;
|
||||
int rc = 0, retries = 3;
|
||||
|
||||
switch (priv->ieee->iw_mode) {
|
||||
case IW_MODE_ADHOC:
|
||||
ucode_name = IPW_FW_NAME("ibss_ucode");
|
||||
fw_name = IPW_FW_NAME("ibss");
|
||||
name = "ipw2200-ibss.fw";
|
||||
break;
|
||||
#ifdef CONFIG_IPW2200_MONITOR
|
||||
case IW_MODE_MONITOR:
|
||||
ucode_name = IPW_FW_NAME("sniffer_ucode");
|
||||
fw_name = IPW_FW_NAME("sniffer");
|
||||
name = "ipw2200-sniffer.fw";
|
||||
break;
|
||||
#endif
|
||||
case IW_MODE_INFRA:
|
||||
ucode_name = IPW_FW_NAME("bss_ucode");
|
||||
fw_name = IPW_FW_NAME("bss");
|
||||
name = "ipw2200-bss.fw";
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
rc = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (!fw_loaded) {
|
||||
#endif
|
||||
rc = ipw_get_fw(priv, &raw, name);
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
#ifdef CONFIG_PM
|
||||
}
|
||||
#endif
|
||||
|
||||
fw = (void *)raw->data;
|
||||
boot_img = &fw->data[0];
|
||||
ucode_img = &fw->data[fw->boot_size];
|
||||
fw_img = &fw->data[fw->boot_size + fw->ucode_size];
|
||||
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
|
||||
|
@ -3275,18 +3271,8 @@ static int ipw_load(struct ipw_priv *priv)
|
|||
ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
|
||||
IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (!fw_loaded) {
|
||||
#endif
|
||||
rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
#ifdef CONFIG_PM
|
||||
}
|
||||
#endif
|
||||
/* DMA the initial boot firmware into the device */
|
||||
rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
|
||||
bootfw->size - sizeof(struct fw_header));
|
||||
rc = ipw_load_firmware(priv, boot_img, fw->boot_size);
|
||||
if (rc < 0) {
|
||||
IPW_ERROR("Unable to load boot firmware: %d\n", rc);
|
||||
goto error;
|
||||
|
@ -3307,19 +3293,8 @@ static int ipw_load(struct ipw_priv *priv)
|
|||
/* ack fw init done interrupt */
|
||||
ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (!fw_loaded) {
|
||||
#endif
|
||||
rc = ipw_get_fw(priv, &ucode, ucode_name);
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
#ifdef CONFIG_PM
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DMA the ucode into the device */
|
||||
rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
|
||||
ucode->size - sizeof(struct fw_header));
|
||||
rc = ipw_load_ucode(priv, ucode_img, fw->ucode_size);
|
||||
if (rc < 0) {
|
||||
IPW_ERROR("Unable to load ucode: %d\n", rc);
|
||||
goto error;
|
||||
|
@ -3328,20 +3303,8 @@ static int ipw_load(struct ipw_priv *priv)
|
|||
/* stop nic */
|
||||
ipw_stop_nic(priv);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (!fw_loaded) {
|
||||
#endif
|
||||
rc = ipw_get_fw(priv, &firmware, fw_name);
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
#ifdef CONFIG_PM
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DMA bss firmware into the device */
|
||||
rc = ipw_load_firmware(priv, firmware->data +
|
||||
sizeof(struct fw_header),
|
||||
firmware->size - sizeof(struct fw_header));
|
||||
rc = ipw_load_firmware(priv, fw_img, fw->fw_size);
|
||||
if (rc < 0) {
|
||||
IPW_ERROR("Unable to load firmware: %d\n", rc);
|
||||
goto error;
|
||||
|
@ -3406,9 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
|
|||
ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
|
||||
|
||||
#ifndef CONFIG_PM
|
||||
release_firmware(bootfw);
|
||||
release_firmware(ucode);
|
||||
release_firmware(firmware);
|
||||
release_firmware(raw);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
|
@ -3418,15 +3379,11 @@ static int ipw_load(struct ipw_priv *priv)
|
|||
priv->rxq = NULL;
|
||||
}
|
||||
ipw_tx_queue_free(priv);
|
||||
if (bootfw)
|
||||
release_firmware(bootfw);
|
||||
if (ucode)
|
||||
release_firmware(ucode);
|
||||
if (firmware)
|
||||
release_firmware(firmware);
|
||||
if (raw)
|
||||
release_firmware(raw);
|
||||
#ifdef CONFIG_PM
|
||||
fw_loaded = 0;
|
||||
bootfw = ucode = firmware = NULL;
|
||||
raw = NULL;
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
|
@ -4547,10 +4504,9 @@ static void ipw_rx_notification(struct ipw_priv *priv,
|
|||
|
||||
if (notif->size == sizeof(*x)) {
|
||||
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
|
||||
"link deterioration: '%s' " MAC_FMT
|
||||
" \n", escape_essid(priv->essid,
|
||||
priv->essid_len),
|
||||
MAC_ARG(priv->bssid));
|
||||
"link deterioration: type %d, cnt %d\n",
|
||||
x->silence_notification_type,
|
||||
x->silence_count);
|
||||
memcpy(&priv->last_link_deterioration, x,
|
||||
sizeof(*x));
|
||||
} else {
|
||||
|
@ -5533,15 +5489,6 @@ static int ipw_best_network(struct ipw_priv *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (priv->ieee->wpa_enabled &&
|
||||
network->wpa_ie_len == 0 && network->rsn_ie_len == 0) {
|
||||
IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
|
||||
"because of WPA capability mismatch.\n",
|
||||
escape_essid(network->ssid, network->ssid_len),
|
||||
MAC_ARG(network->bssid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((priv->config & CFG_STATIC_BSSID) &&
|
||||
memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
|
||||
IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
|
||||
|
@ -5562,7 +5509,7 @@ static int ipw_best_network(struct ipw_priv *priv,
|
|||
}
|
||||
|
||||
/* Filter out invalid channel in current GEO */
|
||||
if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
|
||||
if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) {
|
||||
IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
|
||||
"because of invalid channel in current GEO\n",
|
||||
escape_essid(network->ssid, network->ssid_len),
|
||||
|
@ -5607,7 +5554,7 @@ static int ipw_best_network(struct ipw_priv *priv,
|
|||
static void ipw_adhoc_create(struct ipw_priv *priv,
|
||||
struct ieee80211_network *network)
|
||||
{
|
||||
const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
|
||||
const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
|
||||
int i;
|
||||
|
||||
/*
|
||||
|
@ -5622,10 +5569,10 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
|
|||
* FW fatal error.
|
||||
*
|
||||
*/
|
||||
switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
|
||||
switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
|
||||
case IEEE80211_52GHZ_BAND:
|
||||
network->mode = IEEE_A;
|
||||
i = ipw_channel_to_index(priv->ieee, priv->channel);
|
||||
i = ieee80211_channel_to_index(priv->ieee, priv->channel);
|
||||
if (i == -1)
|
||||
BUG();
|
||||
if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
|
||||
|
@ -5639,7 +5586,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
|
|||
network->mode = IEEE_G;
|
||||
else
|
||||
network->mode = IEEE_B;
|
||||
i = ipw_channel_to_index(priv->ieee, priv->channel);
|
||||
i = ieee80211_channel_to_index(priv->ieee, priv->channel);
|
||||
if (i == -1)
|
||||
BUG();
|
||||
if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
|
||||
|
@ -5963,7 +5910,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
|
|||
const struct ieee80211_geo *geo;
|
||||
int i;
|
||||
|
||||
geo = ipw_get_geo(priv->ieee);
|
||||
geo = ieee80211_get_geo(priv->ieee);
|
||||
|
||||
if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
|
||||
int start = channel_index;
|
||||
|
@ -6023,7 +5970,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
|
|||
channel_index++;
|
||||
scan->channels_list[channel_index] = channel;
|
||||
index =
|
||||
ipw_channel_to_index(priv->ieee, channel);
|
||||
ieee80211_channel_to_index(priv->ieee, channel);
|
||||
ipw_set_scan_type(scan, channel_index,
|
||||
geo->bg[index].
|
||||
flags &
|
||||
|
@ -6105,7 +6052,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
|
|||
u8 channel;
|
||||
u8 band = 0;
|
||||
|
||||
switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
|
||||
switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
|
||||
case IEEE80211_52GHZ_BAND:
|
||||
band = (u8) (IPW_A_MODE << 6) | 1;
|
||||
channel = priv->channel;
|
||||
|
@ -6568,7 +6515,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,
|
|||
* get the modulation type of the current network or
|
||||
* the card current mode
|
||||
*/
|
||||
u8 ipw_qos_current_mode(struct ipw_priv * priv)
|
||||
static u8 ipw_qos_current_mode(struct ipw_priv * priv)
|
||||
{
|
||||
u8 mode = 0;
|
||||
|
||||
|
@ -7815,12 +7762,10 @@ static void ipw_rx(struct ipw_priv *priv)
|
|||
|
||||
while (i != r) {
|
||||
rxb = priv->rxq->queue[i];
|
||||
#ifdef CONFIG_IPW2200_DEBUG
|
||||
if (unlikely(rxb == NULL)) {
|
||||
printk(KERN_CRIT "Queue not allocated!\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
priv->rxq->queue[i] = NULL;
|
||||
|
||||
pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
|
||||
|
@ -7839,7 +7784,8 @@ static void ipw_rx(struct ipw_priv *priv)
|
|||
le16_to_cpu(pkt->u.frame.rssi_dbm) -
|
||||
IPW_RSSI_TO_DBM,
|
||||
.signal =
|
||||
le16_to_cpu(pkt->u.frame.signal),
|
||||
le16_to_cpu(pkt->u.frame.rssi_dbm) -
|
||||
IPW_RSSI_TO_DBM + 0x100,
|
||||
.noise =
|
||||
le16_to_cpu(pkt->u.frame.noise),
|
||||
.rate = pkt->u.frame.rate,
|
||||
|
@ -7903,7 +7849,8 @@ static void ipw_rx(struct ipw_priv *priv)
|
|||
le16_to_cpu(pkt->u.frame.length));
|
||||
|
||||
if (le16_to_cpu(pkt->u.frame.length) <
|
||||
frame_hdr_len(header)) {
|
||||
ieee80211_get_hdrlen(le16_to_cpu(
|
||||
header->frame_ctl))) {
|
||||
IPW_DEBUG_DROP
|
||||
("Received packet is too small. "
|
||||
"Dropping.\n");
|
||||
|
@ -7993,7 +7940,14 @@ static void ipw_rx(struct ipw_priv *priv)
|
|||
#define DEFAULT_SHORT_RETRY_LIMIT 7U
|
||||
#define DEFAULT_LONG_RETRY_LIMIT 4U
|
||||
|
||||
static int ipw_sw_reset(struct ipw_priv *priv, int init)
|
||||
/**
|
||||
* ipw_sw_reset
|
||||
* @option: options to control different reset behaviour
|
||||
* 0 = reset everything except the 'disable' module_param
|
||||
* 1 = reset everything and print out driver info (for probe only)
|
||||
* 2 = reset everything
|
||||
*/
|
||||
static int ipw_sw_reset(struct ipw_priv *priv, int option)
|
||||
{
|
||||
int band, modulation;
|
||||
int old_mode = priv->ieee->iw_mode;
|
||||
|
@ -8020,7 +7974,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
|
|||
priv->essid_len = 0;
|
||||
memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
|
||||
|
||||
if (disable) {
|
||||
if (disable && option) {
|
||||
priv->status |= STATUS_RF_KILL_SW;
|
||||
IPW_DEBUG_INFO("Radio disabled.\n");
|
||||
}
|
||||
|
@ -8072,7 +8026,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
|
|||
|
||||
if ((priv->pci_dev->device == 0x4223) ||
|
||||
(priv->pci_dev->device == 0x4224)) {
|
||||
if (init)
|
||||
if (option == 1)
|
||||
printk(KERN_INFO DRV_NAME
|
||||
": Detected Intel PRO/Wireless 2915ABG Network "
|
||||
"Connection\n");
|
||||
|
@ -8083,7 +8037,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
|
|||
priv->adapter = IPW_2915ABG;
|
||||
priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
|
||||
} else {
|
||||
if (init)
|
||||
if (option == 1)
|
||||
printk(KERN_INFO DRV_NAME
|
||||
": Detected Intel PRO/Wireless 2200BG Network "
|
||||
"Connection\n");
|
||||
|
@ -8200,7 +8154,7 @@ static int ipw_wx_set_freq(struct net_device *dev,
|
|||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
struct ipw_priv *priv = ieee80211_priv(dev);
|
||||
const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
|
||||
const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
|
||||
struct iw_freq *fwrq = &wrqu->freq;
|
||||
int ret = 0, i;
|
||||
u8 channel, flags;
|
||||
|
@ -8215,17 +8169,17 @@ static int ipw_wx_set_freq(struct net_device *dev,
|
|||
}
|
||||
/* if setting by freq convert to channel */
|
||||
if (fwrq->e == 1) {
|
||||
channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
|
||||
channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m);
|
||||
if (channel == 0)
|
||||
return -EINVAL;
|
||||
} else
|
||||
channel = fwrq->m;
|
||||
|
||||
if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
|
||||
if (!(band = ieee80211_is_valid_channel(priv->ieee, channel)))
|
||||
return -EINVAL;
|
||||
|
||||
if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
|
||||
i = ipw_channel_to_index(priv->ieee, channel);
|
||||
i = ieee80211_channel_to_index(priv->ieee, channel);
|
||||
if (i == -1)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -8353,7 +8307,7 @@ static int ipw_wx_get_range(struct net_device *dev,
|
|||
{
|
||||
struct ipw_priv *priv = ieee80211_priv(dev);
|
||||
struct iw_range *range = (struct iw_range *)extra;
|
||||
const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
|
||||
const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
|
||||
int i = 0, j;
|
||||
|
||||
wrqu->data.length = sizeof(*range);
|
||||
|
@ -8365,7 +8319,7 @@ static int ipw_wx_get_range(struct net_device *dev,
|
|||
range->max_qual.qual = 100;
|
||||
/* TODO: Find real max RSSI and stick here */
|
||||
range->max_qual.level = 0;
|
||||
range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
|
||||
range->max_qual.noise = 0;
|
||||
range->max_qual.updated = 7; /* Updated all three */
|
||||
|
||||
range->avg_qual.qual = 70;
|
||||
|
@ -8395,20 +8349,28 @@ static int ipw_wx_get_range(struct net_device *dev,
|
|||
|
||||
i = 0;
|
||||
if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
|
||||
for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
|
||||
i++, j++) {
|
||||
for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {
|
||||
if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
|
||||
(geo->bg[j].flags & IEEE80211_CH_PASSIVE_ONLY))
|
||||
continue;
|
||||
|
||||
range->freq[i].i = geo->bg[j].channel;
|
||||
range->freq[i].m = geo->bg[j].freq * 100000;
|
||||
range->freq[i].e = 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->ieee->mode & IEEE_A) {
|
||||
for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
|
||||
i++, j++) {
|
||||
for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {
|
||||
if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
|
||||
(geo->a[j].flags & IEEE80211_CH_PASSIVE_ONLY))
|
||||
continue;
|
||||
|
||||
range->freq[i].i = geo->a[j].channel;
|
||||
range->freq[i].m = geo->a[j].freq * 100000;
|
||||
range->freq[i].e = 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8609,6 +8571,52 @@ static int ipw_wx_get_nick(struct net_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ipw_wx_set_sens(struct net_device *dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
struct ipw_priv *priv = ieee80211_priv(dev);
|
||||
int err = 0;
|
||||
|
||||
IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value);
|
||||
IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value);
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (wrqu->sens.fixed == 0)
|
||||
{
|
||||
priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
|
||||
priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
|
||||
goto out;
|
||||
}
|
||||
if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) ||
|
||||
(wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
priv->roaming_threshold = wrqu->sens.value;
|
||||
priv->disassociate_threshold = 3*wrqu->sens.value;
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ipw_wx_get_sens(struct net_device *dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
struct ipw_priv *priv = ieee80211_priv(dev);
|
||||
mutex_lock(&priv->mutex);
|
||||
wrqu->sens.fixed = 1;
|
||||
wrqu->sens.value = priv->roaming_threshold;
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
IPW_DEBUG_WX("GET roaming threshold -> %s %d \n",
|
||||
wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipw_wx_set_rate(struct net_device *dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
|
@ -9395,7 +9403,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
|
|||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
ret = ipw_sw_reset(priv, 0);
|
||||
ret = ipw_sw_reset(priv, 2);
|
||||
if (!ret) {
|
||||
free_firmware();
|
||||
ipw_adapter_restart(priv);
|
||||
|
@ -9430,6 +9438,8 @@ static iw_handler ipw_wx_handlers[] = {
|
|||
IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
|
||||
IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
|
||||
IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
|
||||
IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens,
|
||||
IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens,
|
||||
IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
|
||||
IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
|
||||
IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
|
||||
|
@ -9575,7 +9585,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
|
|||
wstats->qual.level = average_value(&priv->average_rssi);
|
||||
wstats->qual.noise = average_value(&priv->average_noise);
|
||||
wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
|
||||
IW_QUAL_NOISE_UPDATED;
|
||||
IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
|
||||
|
||||
wstats->miss.beacon = average_value(&priv->average_missed_beacons);
|
||||
wstats->discard.retries = priv->last_tx_failures;
|
||||
|
@ -9601,12 +9611,13 @@ static void init_sys_config(struct ipw_sys_config *sys_config)
|
|||
sys_config->disable_unicast_decryption = 1;
|
||||
sys_config->exclude_multicast_unencrypted = 0;
|
||||
sys_config->disable_multicast_decryption = 1;
|
||||
sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH;
|
||||
sys_config->antenna_diversity = CFG_SYS_ANTENNA_SLOW_DIV;
|
||||
sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */
|
||||
sys_config->dot11g_auto_detection = 0;
|
||||
sys_config->enable_cts_to_self = 0;
|
||||
sys_config->bt_coexist_collision_thr = 0;
|
||||
sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
|
||||
sys_config->silence_threshold = 0x1e;
|
||||
}
|
||||
|
||||
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,
|
|||
u16 remaining_bytes;
|
||||
int fc;
|
||||
|
||||
/* If there isn't room in the queue, we return busy and let the
|
||||
* network stack requeue the packet for us */
|
||||
if (ipw_queue_space(q) < q->high_mark)
|
||||
return NETDEV_TX_BUSY;
|
||||
|
||||
switch (priv->ieee->iw_mode) {
|
||||
case IW_MODE_ADHOC:
|
||||
hdr_len = IEEE80211_3ADDR_LEN;
|
||||
|
@ -9824,6 +9830,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
|
|||
q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
|
||||
ipw_write32(priv, q->reg_w, q->first_empty);
|
||||
|
||||
if (ipw_queue_space(q) < q->high_mark)
|
||||
netif_stop_queue(priv->net_dev);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
drop:
|
||||
|
@ -9963,9 +9972,8 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
|
|||
return -EINVAL;
|
||||
mutex_lock(&p->mutex);
|
||||
memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
|
||||
for (i = IPW_EEPROM_DATA;
|
||||
i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
|
||||
ipw_write8(p, i, p->eeprom[i]);
|
||||
for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
|
||||
ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]);
|
||||
mutex_unlock(&p->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
@ -10370,6 +10378,9 @@ static int ipw_config(struct ipw_priv *priv)
|
|||
* not intended for resale of the above mentioned Intel adapters has
|
||||
* not been tested.
|
||||
*
|
||||
* Remember to update the table in README.ipw2200 when changing this
|
||||
* table.
|
||||
*
|
||||
*/
|
||||
static const struct ieee80211_geo ipw_geos[] = {
|
||||
{ /* Restricted */
|
||||
|
@ -10617,96 +10628,6 @@ static const struct ieee80211_geo ipw_geos[] = {
|
|||
}
|
||||
};
|
||||
|
||||
/* GEO code borrowed from ieee80211_geo.c */
|
||||
static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Driver needs to initialize the geography map before using
|
||||
* these helper functions */
|
||||
BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
|
||||
|
||||
if (ieee->freq_band & IEEE80211_24GHZ_BAND)
|
||||
for (i = 0; i < ieee->geo.bg_channels; i++)
|
||||
/* NOTE: If G mode is currently supported but
|
||||
* this is a B only channel, we don't see it
|
||||
* as valid. */
|
||||
if ((ieee->geo.bg[i].channel == channel) &&
|
||||
(!(ieee->mode & IEEE_G) ||
|
||||
!(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
|
||||
return IEEE80211_24GHZ_BAND;
|
||||
|
||||
if (ieee->freq_band & IEEE80211_52GHZ_BAND)
|
||||
for (i = 0; i < ieee->geo.a_channels; i++)
|
||||
if (ieee->geo.a[i].channel == channel)
|
||||
return IEEE80211_52GHZ_BAND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Driver needs to initialize the geography map before using
|
||||
* these helper functions */
|
||||
BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
|
||||
|
||||
if (ieee->freq_band & IEEE80211_24GHZ_BAND)
|
||||
for (i = 0; i < ieee->geo.bg_channels; i++)
|
||||
if (ieee->geo.bg[i].channel == channel)
|
||||
return i;
|
||||
|
||||
if (ieee->freq_band & IEEE80211_52GHZ_BAND)
|
||||
for (i = 0; i < ieee->geo.a_channels; i++)
|
||||
if (ieee->geo.a[i].channel == channel)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Driver needs to initialize the geography map before using
|
||||
* these helper functions */
|
||||
BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
|
||||
|
||||
freq /= 100000;
|
||||
|
||||
if (ieee->freq_band & IEEE80211_24GHZ_BAND)
|
||||
for (i = 0; i < ieee->geo.bg_channels; i++)
|
||||
if (ieee->geo.bg[i].freq == freq)
|
||||
return ieee->geo.bg[i].channel;
|
||||
|
||||
if (ieee->freq_band & IEEE80211_52GHZ_BAND)
|
||||
for (i = 0; i < ieee->geo.a_channels; i++)
|
||||
if (ieee->geo.a[i].freq == freq)
|
||||
return ieee->geo.a[i].channel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipw_set_geo(struct ieee80211_device *ieee,
|
||||
const struct ieee80211_geo *geo)
|
||||
{
|
||||
memcpy(ieee->geo.name, geo->name, 3);
|
||||
ieee->geo.name[3] = '\0';
|
||||
ieee->geo.bg_channels = geo->bg_channels;
|
||||
ieee->geo.a_channels = geo->a_channels;
|
||||
memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
|
||||
sizeof(struct ieee80211_channel));
|
||||
memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
|
||||
sizeof(struct ieee80211_channel));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
|
||||
{
|
||||
return &ieee->geo;
|
||||
}
|
||||
|
||||
#define MAX_HW_RESTARTS 5
|
||||
static int ipw_up(struct ipw_priv *priv)
|
||||
{
|
||||
|
@ -10753,14 +10674,11 @@ static int ipw_up(struct ipw_priv *priv)
|
|||
priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
|
||||
j = 0;
|
||||
}
|
||||
if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
|
||||
if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) {
|
||||
IPW_WARNING("Could not set geography.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
|
||||
j, priv->ieee->geo.name);
|
||||
|
||||
if (priv->status & STATUS_RF_KILL_SW) {
|
||||
IPW_WARNING("Radio disabled by module parameter.\n");
|
||||
return 0;
|
||||
|
@ -11081,6 +10999,12 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
IPW_ERROR("failed to register network device\n");
|
||||
goto out_remove_sysfs;
|
||||
}
|
||||
|
||||
printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "
|
||||
"channels, %d 802.11a channels)\n",
|
||||
priv->ieee->geo.name, priv->ieee->geo.bg_channels,
|
||||
priv->ieee->geo.a_channels);
|
||||
|
||||
return 0;
|
||||
|
||||
out_remove_sysfs:
|
||||
|
@ -11271,8 +11195,10 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
|
|||
module_param(led, int, 0444);
|
||||
MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
|
||||
|
||||
#ifdef CONFIG_IPW2200_DEBUG
|
||||
module_param(debug, int, 0444);
|
||||
MODULE_PARM_DESC(debug, "debug output mask");
|
||||
#endif
|
||||
|
||||
module_param(channel, int, 0444);
|
||||
MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
|
||||
Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -246,8 +246,10 @@ enum connection_manager_assoc_states {
|
|||
#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31
|
||||
|
||||
#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1
|
||||
#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 24
|
||||
#define IPW_MB_ROAMING_THRESHOLD_MIN 1
|
||||
#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8
|
||||
#define IPW_MB_ROAMING_THRESHOLD_MAX 30
|
||||
#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 3*IPW_MB_ROAMING_THRESHOLD_DEFAULT
|
||||
#define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300
|
||||
|
||||
#define MACADRR_BYTE_LEN 6
|
||||
|
@ -618,13 +620,16 @@ struct notif_tgi_tx_key {
|
|||
u8 reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define SILENCE_OVER_THRESH (1)
|
||||
#define SILENCE_UNDER_THRESH (2)
|
||||
|
||||
struct notif_link_deterioration {
|
||||
struct ipw_cmd_stats stats;
|
||||
u8 rate;
|
||||
u8 modulation;
|
||||
struct rate_histogram histogram;
|
||||
u8 reserved1;
|
||||
u16 reserved2;
|
||||
u8 silence_notification_type; /* SILENCE_OVER/UNDER_THRESH */
|
||||
u16 silence_count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct notif_association {
|
||||
|
@ -782,7 +787,7 @@ struct ipw_sys_config {
|
|||
u8 enable_cts_to_self;
|
||||
u8 enable_multicast_filtering;
|
||||
u8 bt_coexist_collision_thr;
|
||||
u8 reserved2;
|
||||
u8 silence_threshold;
|
||||
u8 accept_all_mgmt_bcpr;
|
||||
u8 accept_all_mgtm_frames;
|
||||
u8 pass_noise_stats_to_host;
|
||||
|
@ -1892,6 +1897,7 @@ struct ipw_cmd_log {
|
|||
#define CFG_SYS_ANTENNA_BOTH 0x00 /* NIC selects best antenna */
|
||||
#define CFG_SYS_ANTENNA_A 0x01 /* force antenna A */
|
||||
#define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */
|
||||
#define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */
|
||||
|
||||
/*
|
||||
* The definitions below were lifted off the ipw2100 driver, which only
|
||||
|
@ -1907,27 +1913,4 @@ struct ipw_cmd_log {
|
|||
|
||||
#define IPW_MAX_CONFIG_RETRIES 10
|
||||
|
||||
static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
|
||||
{
|
||||
u32 retval;
|
||||
u16 fc;
|
||||
|
||||
retval = sizeof(struct ieee80211_hdr_3addr);
|
||||
fc = le16_to_cpu(hdr->frame_ctl);
|
||||
|
||||
/*
|
||||
* Function ToDS FromDS
|
||||
* IBSS 0 0
|
||||
* To AP 1 0
|
||||
* From AP 0 1
|
||||
* WDS (bridge) 1 1
|
||||
*
|
||||
* Only WDS frames use Address4 among them. --YZ
|
||||
*/
|
||||
if (!(fc & IEEE80211_FCTL_TODS) || !(fc & IEEE80211_FCTL_FROMDS))
|
||||
retval -= ETH_ALEN;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* __ipw2200_h__ */
|
||||
|
|
|
@ -1345,7 +1345,19 @@ static void update_network(struct ieee80211_network *dst,
|
|||
ieee80211_network_reset(dst);
|
||||
dst->ibss_dfs = src->ibss_dfs;
|
||||
|
||||
memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
|
||||
/* We only update the statistics if they were created by receiving
|
||||
* the network information on the actual channel the network is on.
|
||||
*
|
||||
* This keeps beacons received on neighbor channels from bringing
|
||||
* down the signal level of an AP. */
|
||||
if (dst->channel == src->stats.received_channel)
|
||||
memcpy(&dst->stats, &src->stats,
|
||||
sizeof(struct ieee80211_rx_stats));
|
||||
else
|
||||
IEEE80211_DEBUG_SCAN("Network " MAC_FMT " info received "
|
||||
"off channel (%d vs. %d)\n", MAC_ARG(src->bssid),
|
||||
dst->channel, src->stats.received_channel);
|
||||
|
||||
dst->capability = src->capability;
|
||||
memcpy(dst->rates, src->rates, src->rates_len);
|
||||
dst->rates_len = src->rates_len;
|
||||
|
|
Loading…
Reference in a new issue