aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ipw2x00/ipw2200.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ipw2x00/ipw2200.c')
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c702
1 files changed, 370 insertions, 332 deletions
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 09ddd3e6bed..c5aa404069f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -31,7 +31,10 @@
******************************************************************************/
#include <linux/sched.h>
+#include <linux/slab.h>
+#include <net/cfg80211-wext.h>
#include "ipw2200.h"
+#include "ipw.h"
#ifndef KBUILD_EXTMOD
@@ -95,7 +98,7 @@ static int network_mode = 0;
static u32 ipw_debug_level;
static int associate;
static int auto_create = 1;
-static int led_support = 0;
+static int led_support = 1;
static int disable = 0;
static int bt_coexist = 0;
static int hwcrypto = 0;
@@ -129,6 +132,14 @@ static struct ieee80211_rate ipw2200_rates[] = {
#define ipw2200_bg_rates (ipw2200_rates + 0)
#define ipw2200_num_bg_rates 12
+/* Ugly macro to convert literal channel numbers into their mhz equivalents
+ * There are certianly some conditions that will break this (like feeding it '30')
+ * but they shouldn't arise since nothing talks on channel 30. */
+#define ieee80211chan2mhz(x) \
+ (((x) <= 14) ? \
+ (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
+ ((x) + 1000) * 5)
+
#ifdef CONFIG_IPW2200_QOS
static int qos_enable = 0;
static int qos_burst_enable = 0;
@@ -458,7 +469,7 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
{
u32 word;
_ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
- IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
+ IPW_DEBUG_IO(" reg = 0x%8X :\n", reg);
word = _ipw_read32(priv, IPW_INDIRECT_DATA);
return (word >> ((reg & 0x3) * 8)) & 0xff;
}
@@ -472,7 +483,7 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
_ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
value = _ipw_read32(priv, IPW_INDIRECT_DATA);
- IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
+ IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x\n", reg, value);
return value;
}
@@ -893,9 +904,8 @@ static void ipw_led_link_on(struct ipw_priv *priv)
/* If we aren't associated, schedule turning the LED off */
if (!(priv->status & STATUS_ASSOCIATED))
- queue_delayed_work(priv->workqueue,
- &priv->led_link_off,
- LD_TIME_LINK_ON);
+ schedule_delayed_work(&priv->led_link_off,
+ LD_TIME_LINK_ON);
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -938,8 +948,8 @@ static void ipw_led_link_off(struct ipw_priv *priv)
* turning the LED on (blink while unassociated) */
if (!(priv->status & STATUS_RF_KILL_MASK) &&
!(priv->status & STATUS_ASSOCIATED))
- queue_delayed_work(priv->workqueue, &priv->led_link_on,
- LD_TIME_LINK_OFF);
+ schedule_delayed_work(&priv->led_link_on,
+ LD_TIME_LINK_OFF);
}
@@ -979,13 +989,11 @@ static void __ipw_led_activity_on(struct ipw_priv *priv)
priv->status |= STATUS_LED_ACT_ON;
cancel_delayed_work(&priv->led_act_off);
- queue_delayed_work(priv->workqueue, &priv->led_act_off,
- LD_TIME_ACT_ON);
+ schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
} else {
/* Reschedule LED off for full time period */
cancel_delayed_work(&priv->led_act_off);
- queue_delayed_work(priv->workqueue, &priv->led_act_off,
- LD_TIME_ACT_ON);
+ schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
}
}
@@ -1183,7 +1191,7 @@ static void ipw_led_shutdown(struct ipw_priv *priv)
/*
* The following adds a new attribute to the sysfs representation
* of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
- * used for controling the debug level.
+ * used for controlling the debug level.
*
* See the level definitions in ipw for details.
*/
@@ -1794,13 +1802,11 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
if (disable_radio) {
priv->status |= STATUS_RF_KILL_SW;
- if (priv->workqueue) {
- cancel_delayed_work(&priv->request_scan);
- cancel_delayed_work(&priv->request_direct_scan);
- cancel_delayed_work(&priv->request_passive_scan);
- cancel_delayed_work(&priv->scan_event);
- }
- queue_work(priv->workqueue, &priv->down);
+ cancel_delayed_work(&priv->request_scan);
+ cancel_delayed_work(&priv->request_direct_scan);
+ cancel_delayed_work(&priv->request_passive_scan);
+ cancel_delayed_work(&priv->scan_event);
+ schedule_work(&priv->down);
} else {
priv->status &= ~STATUS_RF_KILL_SW;
if (rf_kill_active(priv)) {
@@ -1808,10 +1814,10 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
"disabled by HW switch\n");
/* Make sure the RF_KILL check timer is running */
cancel_delayed_work(&priv->rf_kill);
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies_relative(2 * HZ));
+ schedule_delayed_work(&priv->rf_kill,
+ round_jiffies_relative(2 * HZ));
} else
- queue_work(priv->workqueue, &priv->up);
+ schedule_work(&priv->up);
}
return 1;
@@ -1972,6 +1978,13 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
inta = ipw_read32(priv, IPW_INTA_RW);
inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
+
+ if (inta == 0xFFFFFFFF) {
+ /* Hardware disappeared */
+ IPW_WARNING("TASKLET INTA == 0xFFFFFFFF\n");
+ /* Only handle the cached INTA values */
+ inta = 0;
+ }
inta &= (IPW_INTA_MASK_ALL & inta_mask);
/* Add any cached INTA values that need to be handled */
@@ -2055,7 +2068,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->scan_event);
schedule_work(&priv->link_down);
- queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
+ schedule_delayed_work(&priv->rf_kill, 2 * HZ);
handled |= IPW_INTA_BIT_RF_KILL_DONE;
}
@@ -2095,7 +2108,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
priv->status &= ~STATUS_HCMD_ACTIVE;
wake_up_interruptible(&priv->wait_command_queue);
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
handled |= IPW_INTA_BIT_FATAL_ERROR;
}
@@ -2179,6 +2192,7 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
{
int rc = 0;
unsigned long flags;
+ unsigned long now, end;
spin_lock_irqsave(&priv->lock, flags);
if (priv->status & STATUS_HCMD_ACTIVE) {
@@ -2220,10 +2234,20 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
}
spin_unlock_irqrestore(&priv->lock, flags);
+ now = jiffies;
+ end = now + HOST_COMPLETE_TIMEOUT;
+again:
rc = wait_event_interruptible_timeout(priv->wait_command_queue,
!(priv->
status & STATUS_HCMD_ACTIVE),
- HOST_COMPLETE_TIMEOUT);
+ end - now);
+ if (rc < 0) {
+ now = jiffies;
+ if (time_before(now, end))
+ goto again;
+ rc = 0;
+ }
+
if (rc == 0) {
spin_lock_irqsave(&priv->lock, flags);
if (priv->status & STATUS_HCMD_ACTIVE) {
@@ -2315,11 +2339,6 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
}
-/*
- * NOTE: This must be executed from our workqueue as it results in udelay
- * being called which may corrupt the keyboard if executed on default
- * workqueue
- */
static void ipw_adapter_restart(void *adapter)
{
struct ipw_priv *priv = adapter;
@@ -2348,16 +2367,25 @@ static void ipw_bg_adapter_restart(struct work_struct *work)
mutex_unlock(&priv->mutex);
}
-#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
+static void ipw_abort_scan(struct ipw_priv *priv);
+
+#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
static void ipw_scan_check(void *data)
{
struct ipw_priv *priv = data;
- if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
+
+ if (priv->status & STATUS_SCAN_ABORTING) {
IPW_DEBUG_SCAN("Scan completion watchdog resetting "
"adapter after (%dms).\n",
jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
+ } else if (priv->status & STATUS_SCANNING) {
+ IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "
+ "after (%dms).\n",
+ jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
+ ipw_abort_scan(priv);
+ schedule_delayed_work(&priv->scan_check, HZ);
}
}
@@ -2597,8 +2625,6 @@ static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
/* the eeprom requires some time to complete the operation */
udelay(p->eeprom_delay);
-
- return;
}
/* perform a chip select operation */
@@ -2672,7 +2698,21 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
/* data's copy of the eeprom data */
static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
{
- memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
+ memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], ETH_ALEN);
+}
+
+static void ipw_read_eeprom(struct ipw_priv *priv)
+{
+ int i;
+ __le16 *eeprom = (__le16 *) priv->eeprom;
+
+ IPW_DEBUG_TRACE(">>\n");
+
+ /* read entire contents of eeprom into private buffer */
+ for (i = 0; i < 128; i++)
+ eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i));
+
+ IPW_DEBUG_TRACE("<<\n");
}
/*
@@ -2686,14 +2726,9 @@ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
static void ipw_eeprom_init_sram(struct ipw_priv *priv)
{
int i;
- __le16 *eeprom = (__le16 *) priv->eeprom;
IPW_DEBUG_TRACE(">>\n");
- /* read entire contents of eeprom into private buffer */
- for (i = 0; i < 128; i++)
- eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i));
-
/*
If the data looks correct, then copy it to our private
copy. Otherwise let the firmware know to perform the operation
@@ -2738,7 +2773,7 @@ static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
static int ipw_fw_dma_enable(struct ipw_priv *priv)
{ /* start dma engine but no transfers yet */
- IPW_DEBUG_FW(">> : \n");
+ IPW_DEBUG_FW(">> :\n");
/* Start the dma */
ipw_fw_dma_reset_command_blocks(priv);
@@ -2746,7 +2781,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
/* Write CB base address */
ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
- IPW_DEBUG_FW("<< : \n");
+ IPW_DEBUG_FW("<< :\n");
return 0;
}
@@ -2761,7 +2796,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
priv->sram_desc.last_cb_index = 0;
- IPW_DEBUG_FW("<< \n");
+ IPW_DEBUG_FW("<<\n");
}
static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
@@ -2812,29 +2847,29 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
IPW_DEBUG_FW(">> :\n");
address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
- IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
+ IPW_DEBUG_FW_INFO("Current CB is 0x%x\n", address);
/* Read the DMA Controlor register */
register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
- IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
+ IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x\n", register_value);
/* Print the CB values */
cb_fields_address = address;
register_value = ipw_read_reg32(priv, cb_fields_address);
- IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n", register_value);
+ IPW_DEBUG_FW_INFO("Current CB Control Field is 0x%x\n", register_value);
cb_fields_address += sizeof(u32);
register_value = ipw_read_reg32(priv, cb_fields_address);
- IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n", register_value);
+ IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x\n", register_value);
cb_fields_address += sizeof(u32);
register_value = ipw_read_reg32(priv, cb_fields_address);
- IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x \n",
+ IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x\n",
register_value);
cb_fields_address += sizeof(u32);
register_value = ipw_read_reg32(priv, cb_fields_address);
- IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n", register_value);
+ IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x\n", register_value);
IPW_DEBUG_FW(">> :\n");
}
@@ -2850,7 +2885,7 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
sizeof(struct command_block);
- IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
+ IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X\n",
current_cb_index, current_cb_address);
IPW_DEBUG_FW(">> :\n");
@@ -2909,7 +2944,7 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
int ret, i;
u32 size;
- IPW_DEBUG_FW(">> \n");
+ IPW_DEBUG_FW(">>\n");
IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",
nr, dest_address, len);
@@ -2926,7 +2961,7 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
IPW_DEBUG_FW_INFO(": Added new cb\n");
}
- IPW_DEBUG_FW("<< \n");
+ IPW_DEBUG_FW("<<\n");
return 0;
}
@@ -2935,7 +2970,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
u32 current_index = 0, previous_index;
u32 watchdog = 0;
- IPW_DEBUG_FW(">> : \n");
+ IPW_DEBUG_FW(">> :\n");
current_index = ipw_fw_dma_command_block_index(priv);
IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
@@ -2964,7 +2999,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
ipw_set_bit(priv, IPW_RESET_REG,
IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
- IPW_DEBUG_FW("<< dmaWaitSync \n");
+ IPW_DEBUG_FW("<< dmaWaitSync\n");
return 0;
}
@@ -2977,7 +3012,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
spin_lock_irqsave(&priv->ieee->lock, flags);
list_for_each_safe(element, safe, &priv->ieee->network_list) {
network = list_entry(element, struct libipw_network, list);
- if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
+ if (ether_addr_equal(network->bssid, priv->bssid)) {
list_del(element);
list_add_tail(&network->list,
&priv->ieee->network_free_list);
@@ -3025,7 +3060,7 @@ static int ipw_stop_master(struct ipw_priv *priv)
{
int rc;
- IPW_DEBUG_TRACE(">> \n");
+ IPW_DEBUG_TRACE(">>\n");
/* stop master. typical delay - 0 */
ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
@@ -3044,7 +3079,7 @@ static int ipw_stop_master(struct ipw_priv *priv)
static void ipw_arc_release(struct ipw_priv *priv)
{
- IPW_DEBUG_TRACE(">> \n");
+ IPW_DEBUG_TRACE(">>\n");
mdelay(5);
ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
@@ -3066,7 +3101,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
image = (__le16 *) data;
- IPW_DEBUG_TRACE(">> \n");
+ IPW_DEBUG_TRACE(">>\n");
rc = ipw_stop_master(priv);
@@ -3177,14 +3212,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
int total_nr = 0;
int i;
struct pci_pool *pool;
- u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL];
- dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL];
+ void **virts;
+ dma_addr_t *phys;
- IPW_DEBUG_TRACE("<< : \n");
+ IPW_DEBUG_TRACE("<< :\n");
+ virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
+ GFP_KERNEL);
+ if (!virts)
+ return -ENOMEM;
+
+ phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
+ GFP_KERNEL);
+ if (!phys) {
+ kfree(virts);
+ return -ENOMEM;
+ }
pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
if (!pool) {
IPW_ERROR("pci_pool_create failed\n");
+ kfree(phys);
+ kfree(virts);
return -ENOMEM;
}
@@ -3254,6 +3302,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
pci_pool_free(pool, virts[i], phys[i]);
pci_pool_destroy(pool);
+ kfree(phys);
+ kfree(virts);
return ret;
}
@@ -3498,6 +3548,7 @@ static int ipw_load(struct ipw_priv *priv)
ipw_rx_queue_reset(priv, priv->rxq);
if (!priv->rxq) {
IPW_ERROR("Unable to initialize Rx queue\n");
+ rc = -ENOMEM;
goto error;
}
@@ -3602,8 +3653,10 @@ 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);
- /* read eeprom data and initialize the eeprom region of sram */
+ /* read eeprom data */
priv->eeprom_delay = 1;
+ ipw_read_eeprom(priv);
+ /* initialize the eeprom region of sram */
ipw_eeprom_init_sram(priv);
/* enable interrupts */
@@ -3628,8 +3681,7 @@ static int ipw_load(struct ipw_priv *priv)
priv->rxq = NULL;
}
ipw_tx_queue_free(priv);
- if (raw)
- release_firmware(raw);
+ release_firmware(raw);
#ifdef CONFIG_PM
fw_loaded = 0;
raw = NULL;
@@ -3743,7 +3795,7 @@ static int ipw_queue_tx_init(struct ipw_priv *priv,
q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL);
if (!q->txb) {
- IPW_ERROR("vmalloc for auxilary BD structures failed\n");
+ IPW_ERROR("vmalloc for auxiliary BD structures failed\n");
return -ENOMEM;
}
@@ -3869,7 +3921,7 @@ static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
int i;
for (i = 0; i < priv->num_stations; i++) {
- if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
+ if (ether_addr_equal(priv->stations[i], bssid)) {
/* Another node is active in network */
priv->missed_adhoc_beacons = 0;
if (!(priv->config & CFG_STATIC_CHANNEL))
@@ -3901,7 +3953,7 @@ static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
int i;
for (i = 0; i < priv->num_stations; i++)
- if (!memcmp(priv->stations[i], bssid, ETH_ALEN))
+ if (ether_addr_equal(priv->stations[i], bssid))
return i;
return IPW_INVALID_STATION;
@@ -3913,7 +3965,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
if (priv->status & STATUS_ASSOCIATING) {
IPW_DEBUG_ASSOC("Disassociating while associating.\n");
- queue_work(priv->workqueue, &priv->disassociate);
+ schedule_work(&priv->disassociate);
return;
}
@@ -4330,8 +4382,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
priv->quality = quality;
- queue_delayed_work(priv->workqueue, &priv->gather_stats,
- IPW_STATS_INTERVAL);
+ schedule_delayed_work(&priv->gather_stats, IPW_STATS_INTERVAL);
}
static void ipw_bg_gather_stats(struct work_struct *work)
@@ -4366,10 +4417,10 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
IPW_DL_STATE,
"Aborting scan with missed beacon.\n");
- queue_work(priv->workqueue, &priv->abort_scan);
+ schedule_work(&priv->abort_scan);
}
- queue_work(priv->workqueue, &priv->disassociate);
+ schedule_work(&priv->disassociate);
return;
}
@@ -4395,8 +4446,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
if (!(priv->status & STATUS_ROAMING)) {
priv->status |= STATUS_ROAMING;
if (!(priv->status & STATUS_SCANNING))
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
}
return;
}
@@ -4409,7 +4459,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
* channels..) */
IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
"Aborting scan with missed beacon.\n");
- queue_work(priv->workqueue, &priv->abort_scan);
+ schedule_work(&priv->abort_scan);
}
IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
@@ -4431,18 +4481,11 @@ static void handle_scan_event(struct ipw_priv *priv)
{
/* Only userspace-requested scan completion events go out immediately */
if (!priv->user_requested_scan) {
- if (!delayed_work_pending(&priv->scan_event))
- queue_delayed_work(priv->workqueue, &priv->scan_event,
- round_jiffies_relative(msecs_to_jiffies(4000)));
+ schedule_delayed_work(&priv->scan_event,
+ round_jiffies_relative(msecs_to_jiffies(4000)));
} else {
- union iwreq_data wrqu;
-
priv->user_requested_scan = 0;
- cancel_delayed_work(&priv->scan_event);
-
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
+ mod_delayed_work(system_wq, &priv->scan_event, 0);
}
}
@@ -4466,7 +4509,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
case CMAS_ASSOCIATED:{
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
- "associated: '%s' %pM \n",
+ "associated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
priv->bssid);
@@ -4486,20 +4529,17 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DEBUG_ASSOC
("queueing adhoc check\n");
- queue_delayed_work(priv->
- workqueue,
- &priv->
- adhoc_check,
- le16_to_cpu(priv->
- assoc_request.
- beacon_interval));
+ schedule_delayed_work(
+ &priv->adhoc_check,
+ le16_to_cpu(priv->
+ assoc_request.
+ beacon_interval));
break;
}
priv->status &= ~STATUS_ASSOCIATING;
priv->status |= STATUS_ASSOCIATED;
- queue_work(priv->workqueue,
- &priv->system_config);
+ schedule_work(&priv->system_config);
#ifdef CONFIG_IPW2200_QOS
#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
@@ -4547,7 +4587,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DL_ASSOC,
"deauthenticated: '%s' "
"%pM"
- ": (0x%04X) - %s \n",
+ ": (0x%04X) - %s\n",
print_ssid(ssid,
priv->
essid,
@@ -4598,7 +4638,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
- "disassociated: '%s' %pM \n",
+ "disassociated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
priv->bssid);
@@ -4636,7 +4676,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
switch (auth->state) {
case CMAS_AUTHENTICATED:
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
- "authenticated: '%s' %pM \n",
+ "authenticated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
priv->bssid);
@@ -4762,43 +4802,37 @@ static void ipw_rx_notification(struct ipw_priv *priv,
#ifdef CONFIG_IPW2200_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
priv->status |= STATUS_SCAN_FORCED;
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
break;
}
priv->status &= ~STATUS_SCAN_FORCED;
#endif /* CONFIG_IPW2200_MONITOR */
/* Do queued direct scans first */
- if (priv->status & STATUS_DIRECT_SCAN_PENDING) {
- queue_delayed_work(priv->workqueue,
- &priv->request_direct_scan, 0);
- }
+ if (priv->status & STATUS_DIRECT_SCAN_PENDING)
+ schedule_delayed_work(&priv->request_direct_scan, 0);
if (!(priv->status & (STATUS_ASSOCIATED |
STATUS_ASSOCIATING |
STATUS_ROAMING |
STATUS_DISASSOCIATING)))
- queue_work(priv->workqueue, &priv->associate);
+ schedule_work(&priv->associate);
else if (priv->status & STATUS_ROAMING) {
if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
/* If a scan completed and we are in roam mode, then
* the scan that completed was the one requested as a
* result of entering roam... so, schedule the
* roam work */
- queue_work(priv->workqueue,
- &priv->roam);
+ schedule_work(&priv->roam);
else
/* Don't schedule if we aborted the scan */
priv->status &= ~STATUS_ROAMING;
} else if (priv->status & STATUS_SCAN_PENDING)
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
else if (priv->config & CFG_BACKGROUND_SCAN
&& priv->status & STATUS_ASSOCIATED)
- queue_delayed_work(priv->workqueue,
- &priv->request_scan,
- round_jiffies_relative(HZ));
+ schedule_delayed_work(&priv->request_scan,
+ round_jiffies_relative(HZ));
/* Send an empty event to user space.
* We don't send the received data on the event because
@@ -5162,7 +5196,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
/* If the pre-allocated buffer pool is dropping low, schedule to
* refill it */
if (rxq->free_count <= RX_LOW_WATERMARK)
- queue_work(priv->workqueue, &priv->rx_replenish);
+ schedule_work(&priv->rx_replenish);
/* If we've added more space for the firmware to place data, tell it */
if (write != rxq->write)
@@ -5572,7 +5606,7 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
return 0;
}
- /* Verify privacy compatability */
+ /* Verify privacy compatibility */
if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
@@ -5588,7 +5622,7 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
return 0;
}
- if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
+ if (ether_addr_equal(network->bssid, priv->bssid)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of the same BSSID match: %pM"
".\n", print_ssid(ssid, network->ssid,
@@ -5799,7 +5833,7 @@ static int ipw_best_network(struct ipw_priv *priv,
return 0;
}
- /* Verify privacy compatability */
+ /* Verify privacy compatibility */
if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
@@ -5815,7 +5849,7 @@ static int ipw_best_network(struct ipw_priv *priv,
}
if ((priv->config & CFG_STATIC_BSSID) &&
- memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
+ !ether_addr_equal(network->bssid, priv->bssid)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of BSSID mismatch: %pM.\n",
print_ssid(ssid, network->ssid,
@@ -6103,8 +6137,8 @@ static void ipw_adhoc_check(void *data)
return;
}
- queue_delayed_work(priv->workqueue, &priv->adhoc_check,
- le16_to_cpu(priv->assoc_request.beacon_interval));
+ schedule_delayed_work(&priv->adhoc_check,
+ le16_to_cpu(priv->assoc_request.beacon_interval));
}
static void ipw_bg_adhoc_check(struct work_struct *work)
@@ -6493,8 +6527,7 @@ send_request:
} else
priv->status &= ~STATUS_SCAN_PENDING;
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IPW_SCAN_CHECK_WATCHDOG);
+ schedule_delayed_work(&priv->scan_check, IPW_SCAN_CHECK_WATCHDOG);
done:
mutex_unlock(&priv->mutex);
return err;
@@ -6601,13 +6634,12 @@ static int ipw_wx_set_genie(struct net_device *dev,
return -EINVAL;
if (wrqu->data.length) {
- buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+ buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);
if (buf == NULL) {
err = -ENOMEM;
goto out;
}
- memcpy(buf, extra, wrqu->data.length);
kfree(ieee->wpa_ie);
ieee->wpa_ie = buf;
ieee->wpa_ie_len = wrqu->data.length;
@@ -6774,7 +6806,6 @@ static int ipw_wx_get_auth(struct net_device *dev,
struct libipw_device *ieee = priv->ieee;
struct lib80211_crypt_data *crypt;
struct iw_param *param = &wrqu->param;
- int ret = 0;
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
@@ -6784,8 +6815,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
/*
* wpa_supplicant will control these internally
*/
- ret = -EOPNOTSUPP;
- break;
+ return -EOPNOTSUPP;
case IW_AUTH_TKIP_COUNTERMEASURES:
crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
@@ -6909,7 +6939,7 @@ static u8 ipw_qos_current_mode(struct ipw_priv * priv)
} else {
mode = priv->ieee->mode;
}
- IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
+ IPW_DEBUG_QOS("QoS network/card mode %d\n", mode);
return mode;
}
@@ -6949,7 +6979,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
&def_parameters_OFDM, size);
if ((network->qos_data.active == 1) && (active_network == 1)) {
- IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
+ IPW_DEBUG_QOS("QoS was disabled call qos_activate\n");
schedule_work(&priv->qos_activate);
}
@@ -6958,15 +6988,14 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
}
if ((priv->status & STATUS_ASSOCIATED) &&
(priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
- if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
+ if (!ether_addr_equal(network->bssid, priv->bssid))
if (network->capability & WLAN_CAPABILITY_IBSS)
if ((network->ssid_len ==
priv->assoc_network->ssid_len) &&
!memcmp(network->ssid,
priv->assoc_network->ssid,
network->ssid_len)) {
- queue_work(priv->workqueue,
- &priv->merge_networks);
+ schedule_work(&priv->merge_networks);
}
}
@@ -7009,7 +7038,7 @@ static int ipw_qos_activate(struct ipw_priv *priv,
cpu_to_le16(burst_duration);
} else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
if (type == IEEE_B) {
- IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
+ IPW_DEBUG_QOS("QoS activate IBSS network mode %d\n",
type);
if (priv->qos_data.qos_enable == 0)
active_one = &def_parameters_CCK;
@@ -7043,9 +7072,7 @@ static int ipw_qos_activate(struct ipw_priv *priv,
}
IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
- err = ipw_send_qos_params_command(priv,
- (struct libipw_qos_parameters *)
- &(qos_parameters[0]));
+ err = ipw_send_qos_params_command(priv, &qos_parameters[0]);
if (err)
IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
@@ -7424,7 +7451,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
priv->assoc_request.capability &=
~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
- IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
+ IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, "
"802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
roaming ? "Rea" : "A",
print_ssid(ssid, priv->essid, priv->essid_len),
@@ -7526,7 +7553,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
return err;
}
- IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM \n",
+ IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n",
print_ssid(ssid, priv->essid, priv->essid_len),
priv->bssid);
@@ -7634,7 +7661,7 @@ static int ipw_associate(void *data)
if (priv->status & STATUS_DISASSOCIATING) {
IPW_DEBUG_ASSOC("Not attempting association (in "
"disassociating)\n ");
- queue_work(priv->workqueue, &priv->associate);
+ schedule_work(&priv->associate);
return 0;
}
@@ -7702,12 +7729,10 @@ static int ipw_associate(void *data)
if (!(priv->status & STATUS_SCANNING)) {
if (!(priv->config & CFG_SPEED_SCAN))
- queue_delayed_work(priv->workqueue,
- &priv->request_scan,
- SCAN_INTERVAL);
+ schedule_delayed_work(&priv->request_scan,
+ SCAN_INTERVAL);
else
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
}
return 0;
@@ -7835,7 +7860,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
* more efficiently than we can parse it. ORDER MATTERS HERE */
struct ipw_rt_hdr *ipw_rt;
- short len = le16_to_cpu(pkt->u.frame.length);
+ unsigned short len = le16_to_cpu(pkt->u.frame.length);
/* We received data from the HW, so stop the watchdog */
dev->trans_start = jiffies;
@@ -8010,7 +8035,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
s8 noise = (s8) le16_to_cpu(frame->noise);
u8 rate = frame->rate;
- short len = le16_to_cpu(pkt->u.frame.length);
+ unsigned short len = le16_to_cpu(pkt->u.frame.length);
struct sk_buff *skb;
int hdr_only = 0;
u16 filter = priv->prom_priv->filter;
@@ -8180,34 +8205,34 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
static int is_network_packet(struct ipw_priv *priv,
struct libipw_hdr_4addr *header)
{
- /* Filter incoming packets to determine if they are targetted toward
+ /* Filter incoming packets to determine if they are targeted toward
* this network, discarding packets coming from ourselves */
switch (priv->ieee->iw_mode) {
case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
/* packets from our adapter are dropped (echo) */
- if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
+ if (ether_addr_equal(header->addr2, priv->net_dev->dev_addr))
return 0;
/* {broad,multi}cast packets to our BSSID go through */
if (is_multicast_ether_addr(header->addr1))
- return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
+ return ether_addr_equal(header->addr3, priv->bssid);
/* packets to our adapter go through */
- return !memcmp(header->addr1, priv->net_dev->dev_addr,
- ETH_ALEN);
+ return ether_addr_equal(header->addr1,
+ priv->net_dev->dev_addr);
case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
/* packets from our adapter are dropped (echo) */
- if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
+ if (ether_addr_equal(header->addr3, priv->net_dev->dev_addr))
return 0;
/* {broad,multi}cast packets to our BSS go through */
if (is_multicast_ether_addr(header->addr1))
- return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
+ return ether_addr_equal(header->addr2, priv->bssid);
/* packets to our adapter go through */
- return !memcmp(header->addr1, priv->net_dev->dev_addr,
- ETH_ALEN);
+ return ether_addr_equal(header->addr1,
+ priv->net_dev->dev_addr);
}
return 1;
@@ -8232,10 +8257,10 @@ static int is_duplicate_packet(struct ipw_priv *priv,
u8 *mac = header->addr2;
int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
- __list_for_each(p, &priv->ibss_mac_hash[index]) {
+ list_for_each(p, &priv->ibss_mac_hash[index]) {
entry =
list_entry(p, struct ipw_ibss_seq, list);
- if (!memcmp(entry->mac, mac, ETH_ALEN))
+ if (ether_addr_equal(entry->mac, mac))
break;
}
if (p == &priv->ibss_mac_hash[index]) {
@@ -8304,7 +8329,7 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
IEEE80211_STYPE_PROBE_RESP) ||
(WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
IEEE80211_STYPE_BEACON))) {
- if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
+ if (ether_addr_equal(header->addr3, priv->bssid))
ipw_add_station(priv, header->addr2);
}
@@ -8336,9 +8361,9 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
}
/*
- * Main entry function for recieving a packet with 80211 headers. This
+ * Main entry function for receiving a packet with 80211 headers. This
* should be called when ever the FW has notified us that there is a new
- * skb in the recieve queue.
+ * skb in the receive queue.
*/
static void ipw_rx(struct ipw_priv *priv)
{
@@ -8679,7 +8704,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
* functions defined in ipw_main to provide the HW interaction.
*
* The exception to this is the use of the ipw_get_ordinal()
- * function used to poll the hardware vs. making unecessary calls.
+ * function used to poll the hardware vs. making unnecessary calls.
*
*/
@@ -8777,7 +8802,7 @@ static int ipw_wx_set_freq(struct net_device *dev,
}
}
- IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
+ IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
mutex_lock(&priv->mutex);
ret = ipw_set_channel(priv, channel);
mutex_unlock(&priv->mutex);
@@ -8819,7 +8844,7 @@ static int ipw_wx_get_freq(struct net_device *dev,
wrqu->freq.m = 0;
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
+ IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
return 0;
}
@@ -8870,7 +8895,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
priv->ieee->iw_mode = wrqu->mode;
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
mutex_unlock(&priv->mutex);
return err;
}
@@ -9004,18 +9029,11 @@ static int ipw_wx_set_wap(struct net_device *dev,
{
struct ipw_priv *priv = libipw_priv(dev);
- static const unsigned char any[] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
- static const unsigned char off[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
return -EINVAL;
mutex_lock(&priv->mutex);
- if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
- !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
+ if (is_broadcast_ether_addr(wrqu->ap_addr.sa_data) ||
+ is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
/* we disable mandatory BSSID association */
IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
priv->config &= ~CFG_STATIC_BSSID;
@@ -9027,7 +9045,7 @@ static int ipw_wx_set_wap(struct net_device *dev,
}
priv->config |= CFG_STATIC_BSSID;
- if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
+ if (ether_addr_equal(priv->bssid, wrqu->ap_addr.sa_data)) {
IPW_DEBUG_WX("BSSID set to current BSSID.\n");
mutex_unlock(&priv->mutex);
return 0;
@@ -9151,7 +9169,7 @@ static int ipw_wx_set_nick(struct net_device *dev,
if (wrqu->data.length > IW_ESSID_MAX_SIZE)
return -E2BIG;
mutex_lock(&priv->mutex);
- wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
+ wrqu->data.length = min_t(size_t, wrqu->data.length, sizeof(priv->nick));
memset(priv->nick, 0, sizeof(priv->nick));
memcpy(priv->nick, extra, wrqu->data.length);
IPW_DEBUG_TRACE("<<\n");
@@ -9214,7 +9232,7 @@ static int ipw_wx_get_sens(struct net_device *dev,
wrqu->sens.value = priv->roaming_threshold;
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("GET roaming threshold -> %s %d \n",
+ IPW_DEBUG_WX("GET roaming threshold -> %s %d\n",
wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
return 0;
@@ -9342,7 +9360,7 @@ static int ipw_wx_get_rate(struct net_device *dev,
wrqu->bitrate.value = priv->last_rate;
wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
+ IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
return 0;
}
@@ -9365,7 +9383,7 @@ static int ipw_wx_set_rts(struct net_device *dev,
ipw_send_rts_threshold(priv, priv->rts_threshold);
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
+ IPW_DEBUG_WX("SET RTS Threshold -> %d\n", priv->rts_threshold);
return 0;
}
@@ -9379,7 +9397,7 @@ static int ipw_wx_get_rts(struct net_device *dev,
wrqu->rts.fixed = 0; /* no auto select */
wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
+ IPW_DEBUG_WX("GET RTS Threshold -> %d\n", wrqu->rts.value);
return 0;
}
@@ -9429,7 +9447,7 @@ static int ipw_wx_get_txpow(struct net_device *dev,
wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("GET TX Power -> %s %d \n",
+ IPW_DEBUG_WX("GET TX Power -> %s %d\n",
wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
return 0;
@@ -9455,7 +9473,7 @@ static int ipw_wx_set_frag(struct net_device *dev,
ipw_send_frag_threshold(priv, wrqu->frag.value);
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
+ IPW_DEBUG_WX("SET Frag Threshold -> %d\n", wrqu->frag.value);
return 0;
}
@@ -9469,7 +9487,7 @@ static int ipw_wx_get_frag(struct net_device *dev,
wrqu->frag.fixed = 0; /* no auto select */
wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
+ IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
return 0;
}
@@ -9533,7 +9551,7 @@ static int ipw_wx_get_retry(struct net_device *dev,
}
mutex_unlock(&priv->mutex);
- IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
+ IPW_DEBUG_WX("GET retry -> %d\n", wrqu->retry.value);
return 0;
}
@@ -9569,7 +9587,7 @@ static int ipw_wx_set_scan(struct net_device *dev,
IPW_DEBUG_WX("Start scan\n");
- queue_delayed_work(priv->workqueue, work, 0);
+ schedule_delayed_work(work, 0);
return 0;
}
@@ -9908,7 +9926,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
#else
priv->net_dev->type = ARPHRD_IEEE80211;
#endif
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
}
ipw_set_channel(priv, parms[1]);
@@ -9918,7 +9936,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
return 0;
}
priv->net_dev->type = ARPHRD_ETHER;
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
}
mutex_unlock(&priv->mutex);
return 0;
@@ -9932,7 +9950,7 @@ static int ipw_wx_reset(struct net_device *dev,
{
struct ipw_priv *priv = libipw_priv(dev);
IPW_DEBUG_WX("RESET\n");
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
return 0;
}
@@ -9980,49 +9998,48 @@ static int ipw_wx_sw_reset(struct net_device *dev,
}
/* Rebase the WE IOCTLs to zero for the handler array */
-#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
static iw_handler ipw_wx_handlers[] = {
- IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
- IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
- 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,
- IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
- IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
- IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
- IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
- IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
- IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
- IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
- IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
- IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
- IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
- IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
- IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
- IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
- IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
- IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
- IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
- IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
- IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
- IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
- IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
- IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
- IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
- IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
- IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
- IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
- IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
- IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
- IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
- IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
- IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
- IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
+ IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
+ IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
+ IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
+ IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
+ IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),
+ IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),
+ IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),
+ IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),
+ IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),
+ IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),
+ IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),
+ IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),
+ IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),
+ IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),
+ IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),
+ IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),
+ IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),
+ IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),
+ IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),
+ IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),
+ IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),
+ IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),
+ IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),
+ IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),
+ IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),
+ IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),
+ IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),
+ IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
+ IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
+ IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
+ IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
+ IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
+ IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
+ IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
+ IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
+ IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
+ IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
+ IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),
+ IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),
+ IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),
+ IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),
};
enum {
@@ -10416,7 +10433,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
memset(&dummystats, 0, sizeof(dummystats));
- /* Filtering of fragment chains is done agains the first fragment */
+ /* Filtering of fragment chains is done against the first fragment */
hdr = (void *)txb->fragments[0]->data;
if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {
if (filter & IPW_PROM_NO_MGMT)
@@ -10447,7 +10464,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
} else
len = src->len;
- dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC);
+ dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC);
if (!dst)
continue;
@@ -10523,7 +10540,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
printk(KERN_INFO "%s: Setting MAC to %pM\n",
priv->net_dev->name, priv->mac_addr);
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
mutex_unlock(&priv->mutex);
return 0;
}
@@ -10536,8 +10553,8 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
char date[32];
u32 len;
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
len = sizeof(vers);
ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
@@ -10546,7 +10563,8 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
vers, date);
- strcpy(info->bus_info, pci_name(p->pci_dev));
+ strlcpy(info->bus_info, pci_name(p->pci_dev),
+ sizeof(info->bus_info));
info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
}
@@ -10656,9 +10674,7 @@ static void ipw_rf_kill(void *adapter)
if (rf_kill_active(priv)) {
IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
- if (priv->workqueue)
- queue_delayed_work(priv->workqueue,
- &priv->rf_kill, 2 * HZ);
+ schedule_delayed_work(&priv->rf_kill, 2 * HZ);
goto exit_unlock;
}
@@ -10669,7 +10685,7 @@ static void ipw_rf_kill(void *adapter)
"device\n");
/* we can not do an adapter restart while inside an irq lock */
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
} else
IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
"enabled\n");
@@ -10707,7 +10723,7 @@ static void ipw_link_up(struct ipw_priv *priv)
notify_wx_assoc_event(priv);
if (priv->config & CFG_BACKGROUND_SCAN)
- queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
+ schedule_delayed_work(&priv->request_scan, HZ);
}
static void ipw_bg_link_up(struct work_struct *work)
@@ -10736,7 +10752,7 @@ static void ipw_link_down(struct ipw_priv *priv)
if (!(priv->status & STATUS_EXIT_PENDING)) {
/* Queue up another scan... */
- queue_delayed_work(priv->workqueue, &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
} else
cancel_delayed_work(&priv->scan_event);
}
@@ -10750,11 +10766,10 @@ static void ipw_bg_link_down(struct work_struct *work)
mutex_unlock(&priv->mutex);
}
-static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv)
+static int ipw_setup_deferred_work(struct ipw_priv *priv)
{
int ret = 0;
- priv->workqueue = create_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue);
init_waitqueue_head(&priv->wait_state);
@@ -11246,10 +11261,31 @@ static const struct libipw_geo ipw_geos[] = {
}
};
+static void ipw_set_geo(struct ipw_priv *priv)
+{
+ int j;
+
+ for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
+ if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
+ ipw_geos[j].name, 3))
+ break;
+ }
+
+ if (j == ARRAY_SIZE(ipw_geos)) {
+ IPW_WARNING("SKU [%c%c%c] not recognized.\n",
+ priv->eeprom[EEPROM_COUNTRY_CODE + 0],
+ priv->eeprom[EEPROM_COUNTRY_CODE + 1],
+ priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
+ j = 0;
+ }
+
+ libipw_set_geo(priv->ieee, &ipw_geos[j]);
+}
+
#define MAX_HW_RESTARTS 5
static int ipw_up(struct ipw_priv *priv)
{
- int rc, i, j;
+ int rc, i;
/* Age scan list entries found before suspend */
if (priv->suspend_time) {
@@ -11285,24 +11321,8 @@ static int ipw_up(struct ipw_priv *priv)
if (!(priv->config & CFG_CUSTOM_MAC))
eeprom_parse_mac(priv, priv->mac_addr);
memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
- memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN);
- for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
- if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
- ipw_geos[j].name, 3))
- break;
- }
- if (j == ARRAY_SIZE(ipw_geos)) {
- IPW_WARNING("SKU [%c%c%c] not recognized.\n",
- priv->eeprom[EEPROM_COUNTRY_CODE + 0],
- priv->eeprom[EEPROM_COUNTRY_CODE + 1],
- priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
- j = 0;
- }
- if (libipw_set_geo(priv->ieee, &ipw_geos[j])) {
- IPW_WARNING("Could not set geography.");
- return 0;
- }
+ ipw_set_geo(priv);
if (priv->status & STATUS_RF_KILL_SW) {
IPW_WARNING("Radio disabled by module parameter.\n");
@@ -11311,8 +11331,7 @@ static int ipw_up(struct ipw_priv *priv)
IPW_WARNING("Radio Frequency Kill Switch is On:\n"
"Kill switch must be turned off for "
"wireless networking to work.\n");
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- 2 * HZ);
+ schedule_delayed_work(&priv->rf_kill, 2 * HZ);
return 0;
}
@@ -11322,8 +11341,7 @@ static int ipw_up(struct ipw_priv *priv)
/* If configure to try and auto-associate, kick
* off a scan. */
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
return 0;
}
@@ -11424,19 +11442,12 @@ static void ipw_bg_down(struct work_struct *work)
mutex_unlock(&priv->mutex);
}
-/* Called by register_netdev() */
-static int ipw_net_init(struct net_device *dev)
+static int ipw_wdev_init(struct net_device *dev)
{
int i, rc = 0;
struct ipw_priv *priv = libipw_priv(dev);
const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
struct wireless_dev *wdev = &priv->ieee->wdev;
- mutex_lock(&priv->mutex);
-
- if (ipw_up(priv)) {
- rc = -EIO;
- goto out;
- }
memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
@@ -11446,9 +11457,13 @@ static int ipw_net_init(struct net_device *dev)
bg_band->band = IEEE80211_BAND_2GHZ;
bg_band->n_channels = geo->bg_channels;
- bg_band->channels =
- kzalloc(geo->bg_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ bg_band->channels = kcalloc(geo->bg_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
+ if (!bg_band->channels) {
+ rc = -ENOMEM;
+ goto out;
+ }
/* translate geo->bg to bg_band.channels */
for (i = 0; i < geo->bg_channels; i++) {
bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
@@ -11457,10 +11472,10 @@ static int ipw_net_init(struct net_device *dev)
bg_band->channels[i].max_power = geo->bg[i].max_power;
if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
bg_band->channels[i].flags |=
- IEEE80211_CHAN_PASSIVE_SCAN;
+ IEEE80211_CHAN_NO_IR;
if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
bg_band->channels[i].flags |=
- IEEE80211_CHAN_NO_IBSS;
+ IEEE80211_CHAN_NO_IR;
if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
bg_band->channels[i].flags |=
IEEE80211_CHAN_RADAR;
@@ -11481,21 +11496,25 @@ static int ipw_net_init(struct net_device *dev)
a_band->band = IEEE80211_BAND_5GHZ;
a_band->n_channels = geo->a_channels;
- a_band->channels =
- kzalloc(geo->a_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
- /* translate geo->bg to a_band.channels */
+ a_band->channels = kcalloc(geo->a_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
+ if (!a_band->channels) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ /* translate geo->a to a_band.channels */
for (i = 0; i < geo->a_channels; i++) {
- a_band->channels[i].band = IEEE80211_BAND_2GHZ;
+ a_band->channels[i].band = IEEE80211_BAND_5GHZ;
a_band->channels[i].center_freq = geo->a[i].freq;
a_band->channels[i].hw_value = geo->a[i].channel;
a_band->channels[i].max_power = geo->a[i].max_power;
if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
a_band->channels[i].flags |=
- IEEE80211_CHAN_PASSIVE_SCAN;
+ IEEE80211_CHAN_NO_IR;
if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
a_band->channels[i].flags |=
- IEEE80211_CHAN_NO_IBSS;
+ IEEE80211_CHAN_NO_IR;
if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
a_band->channels[i].flags |=
IEEE80211_CHAN_RADAR;
@@ -11510,21 +11529,20 @@ static int ipw_net_init(struct net_device *dev)
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
}
+ wdev->wiphy->cipher_suites = ipw_cipher_suites;
+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);
+
set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
/* With that information in place, we can now register the wiphy... */
- if (wiphy_register(wdev->wiphy)) {
+ if (wiphy_register(wdev->wiphy))
rc = -EIO;
- goto out;
- }
-
out:
- mutex_unlock(&priv->mutex);
return rc;
}
/* PCI driver stuff */
-static struct pci_device_id card_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(card_ids) = {
{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
@@ -11651,7 +11669,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
if (priv->prom_net_dev)
return -EPERM;
- priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
+ priv->prom_net_dev = alloc_libipw(sizeof(struct ipw_prom_priv), 1);
if (priv->prom_net_dev == NULL)
return -ENOMEM;
@@ -11670,7 +11688,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
rc = register_netdev(priv->prom_net_dev);
if (rc) {
- free_ieee80211(priv->prom_net_dev, 1);
+ free_libipw(priv->prom_net_dev, 1);
priv->prom_net_dev = NULL;
return rc;
}
@@ -11684,7 +11702,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
return;
unregister_netdev(priv->prom_net_dev);
- free_ieee80211(priv->prom_net_dev, 1);
+ free_libipw(priv->prom_net_dev, 1);
priv->prom_net_dev = NULL;
}
@@ -11692,17 +11710,16 @@ static void ipw_prom_free(struct ipw_priv *priv)
#endif
static const struct net_device_ops ipw_netdev_ops = {
- .ndo_init = ipw_net_init,
.ndo_open = ipw_net_open,
.ndo_stop = ipw_net_stop,
- .ndo_set_multicast_list = ipw_net_set_multicast_list,
+ .ndo_set_rx_mode = ipw_net_set_multicast_list,
.ndo_set_mac_address = ipw_net_set_mac_address,
.ndo_start_xmit = libipw_xmit,
.ndo_change_mtu = libipw_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};
-static int __devinit ipw_pci_probe(struct pci_dev *pdev,
+static int ipw_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int err = 0;
@@ -11712,7 +11729,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
struct ipw_priv *priv;
int i;
- net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
+ net_dev = alloc_libipw(sizeof(struct ipw_priv), 0);
if (net_dev == NULL) {
err = -ENOMEM;
goto out;
@@ -11732,7 +11749,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
mutex_init(&priv->mutex);
if (pci_enable_device(pdev)) {
err = -ENODEV;
- goto out_free_ieee80211;
+ goto out_free_libipw;
}
pci_set_master(pdev);
@@ -11781,7 +11798,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv);
if (err) {
IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
- goto out_destroy_workqueue;
+ goto out_iounmap;
}
SET_NETDEV_DEV(net_dev, &pdev->dev);
@@ -11807,10 +11824,6 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
net_dev->wireless_data = &priv->wireless_data;
net_dev->wireless_handlers = &ipw_wx_handler_def;
net_dev->ethtool_ops = &ipw_ethtool_ops;
- net_dev->irq = pdev->irq;
- net_dev->base_addr = (unsigned long)priv->hw_base;
- net_dev->mem_start = pci_resource_start(pdev, 0);
- net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1;
err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
if (err) {
@@ -11819,11 +11832,24 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
goto out_release_irq;
}
+ if (ipw_up(priv)) {
+ mutex_unlock(&priv->mutex);
+ err = -EIO;
+ goto out_remove_sysfs;
+ }
+
mutex_unlock(&priv->mutex);
+
+ err = ipw_wdev_init(net_dev);
+ if (err) {
+ IPW_ERROR("failed to register wireless device\n");
+ goto out_remove_sysfs;
+ }
+
err = register_netdev(net_dev);
if (err) {
IPW_ERROR("failed to register network device\n");
- goto out_remove_sysfs;
+ goto out_unregister_wiphy;
}
#ifdef CONFIG_IPW2200_PROMISCUOUS
@@ -11833,7 +11859,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
IPW_ERROR("Failed to register promiscuous network "
"device (error %d).\n", err);
unregister_netdev(priv->net_dev);
- goto out_remove_sysfs;
+ goto out_unregister_wiphy;
}
}
#endif
@@ -11845,27 +11871,27 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
return 0;
+ out_unregister_wiphy:
+ wiphy_unregister(priv->ieee->wdev.wiphy);
+ kfree(priv->ieee->a_band.channels);
+ kfree(priv->ieee->bg_band.channels);
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
out_release_irq:
free_irq(pdev->irq, priv);
- out_destroy_workqueue:
- destroy_workqueue(priv->workqueue);
- priv->workqueue = NULL;
out_iounmap:
iounmap(priv->hw_base);
out_pci_release_regions:
pci_release_regions(pdev);
out_pci_disable_device:
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- out_free_ieee80211:
- free_ieee80211(priv->net_dev, 0);
+ out_free_libipw:
+ free_libipw(priv->net_dev, 0);
out:
return err;
}
-static void __devexit ipw_pci_remove(struct pci_dev *pdev)
+static void ipw_pci_remove(struct pci_dev *pdev)
{
struct ipw_priv *priv = pci_get_drvdata(pdev);
struct list_head *p, *q;
@@ -11894,18 +11920,31 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
kfree(priv->cmdlog);
priv->cmdlog = NULL;
}
- /* ipw_down will ensure that there is no more pending work
- * in the workqueue's, so we can safely remove them now. */
- cancel_delayed_work(&priv->adhoc_check);
- cancel_delayed_work(&priv->gather_stats);
- cancel_delayed_work(&priv->request_scan);
- cancel_delayed_work(&priv->request_direct_scan);
- cancel_delayed_work(&priv->request_passive_scan);
- cancel_delayed_work(&priv->scan_event);
- cancel_delayed_work(&priv->rf_kill);
- cancel_delayed_work(&priv->scan_check);
- destroy_workqueue(priv->workqueue);
- priv->workqueue = NULL;
+
+ /* make sure all works are inactive */
+ cancel_delayed_work_sync(&priv->adhoc_check);
+ cancel_work_sync(&priv->associate);
+ cancel_work_sync(&priv->disassociate);
+ cancel_work_sync(&priv->system_config);
+ cancel_work_sync(&priv->rx_replenish);
+ cancel_work_sync(&priv->adapter_restart);
+ cancel_delayed_work_sync(&priv->rf_kill);
+ cancel_work_sync(&priv->up);
+ cancel_work_sync(&priv->down);
+ cancel_delayed_work_sync(&priv->request_scan);
+ cancel_delayed_work_sync(&priv->request_direct_scan);
+ cancel_delayed_work_sync(&priv->request_passive_scan);
+ cancel_delayed_work_sync(&priv->scan_event);
+ cancel_delayed_work_sync(&priv->gather_stats);
+ cancel_work_sync(&priv->abort_scan);
+ cancel_work_sync(&priv->roam);
+ cancel_delayed_work_sync(&priv->scan_check);
+ cancel_work_sync(&priv->link_up);
+ cancel_work_sync(&priv->link_down);
+ cancel_delayed_work_sync(&priv->led_link_on);
+ cancel_delayed_work_sync(&priv->led_link_off);
+ cancel_delayed_work_sync(&priv->led_act_off);
+ cancel_work_sync(&priv->merge_networks);
/* Free MAC hash list for ADHOC */
for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
@@ -11926,12 +11965,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
iounmap(priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- /* wiphy_unregister needs to be here, before free_ieee80211 */
+ /* wiphy_unregister needs to be here, before free_libipw */
wiphy_unregister(priv->ieee->wdev.wiphy);
kfree(priv->ieee->a_band.channels);
kfree(priv->ieee->bg_band.channels);
- free_ieee80211(priv->net_dev, 0);
+ free_libipw(priv->net_dev, 0);
free_firmware();
}
@@ -11993,7 +12031,7 @@ static int ipw_pci_resume(struct pci_dev *pdev)
priv->suspend_time = get_seconds() - priv->suspend_at;
/* Bring the device back up */
- queue_work(priv->workqueue, &priv->up);
+ schedule_work(&priv->up);
return 0;
}
@@ -12014,7 +12052,7 @@ static struct pci_driver ipw_driver = {
.name = DRV_NAME,
.id_table = card_ids,
.probe = ipw_pci_probe,
- .remove = __devexit_p(ipw_pci_remove),
+ .remove = ipw_pci_remove,
#ifdef CONFIG_PM
.suspend = ipw_pci_suspend,
.resume = ipw_pci_resume,
@@ -12061,7 +12099,7 @@ module_param(auto_create, int, 0444);
MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
module_param_named(led, led_support, int, 0444);
-MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)");
+MODULE_PARM_DESC(led, "enable led control on some systems (default 1 on)");
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");