aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-12-05 09:37:56 -0500
committerDavid Howells <dhowells@warthog.cambridge.redhat.com>2006-12-05 09:37:56 -0500
commit4c1ac1b49122b805adfa4efc620592f68dccf5db (patch)
tree87557f4bc2fd4fe65b7570489c2f610c45c0adcd /drivers/net/wireless
parentc4028958b6ecad064b1a6303a6a5906d4fe48d73 (diff)
parentd916faace3efc0bf19fe9a615a1ab8fa1a24cd93 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/infiniband/core/iwcm.c drivers/net/chelsio/cxgb2.c drivers/net/wireless/bcm43xx/bcm43xx_main.c drivers/net/wireless/prism54/islpci_eth.c drivers/usb/core/hub.h drivers/usb/input/hid-core.c net/core/netpoll.c Fix up merge failures with Linus's head and fix new compilation failures. Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/atmel.c36
-rw-r--r--drivers/net/wireless/atmel_cs.c74
-rw-r--r--drivers/net/wireless/atmel_pci.c10
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h32
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c207
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.c28
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.c18
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c8
-rw-r--r--drivers/net/wireless/ipw2100.c25
-rw-r--r--drivers/net/wireless/ipw2200.c12
-rw-r--r--drivers/net/wireless/orinoco_pci.h7
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c17
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h7
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c61
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.h1
-rw-r--r--drivers/net/wireless/prism54/isl_oid.h48
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c13
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h11
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c28
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.h1
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c43
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c3
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h5
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c6
-rw-r--r--drivers/net/wireless/prism54/prismcompat.h4
-rw-r--r--drivers/net/wireless/zd1201.c6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c38
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h104
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_ieee80211.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_ieee80211.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c404
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h38
-rw-r--r--drivers/net/wireless/zd1211rw/zd_netdev.c13
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c45
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h14
37 files changed, 806 insertions, 579 deletions
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 0c07b8b7250d..10bcb48e80d0 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -595,7 +595,7 @@ static void atmel_join_bss(struct atmel_private *priv, int bss_index);
595static void atmel_smooth_qual(struct atmel_private *priv); 595static void atmel_smooth_qual(struct atmel_private *priv);
596static void atmel_writeAR(struct net_device *dev, u16 data); 596static void atmel_writeAR(struct net_device *dev, u16 data);
597static int probe_atmel_card(struct net_device *dev); 597static int probe_atmel_card(struct net_device *dev);
598static int reset_atmel_card(struct net_device *dev ); 598static int reset_atmel_card(struct net_device *dev);
599static void atmel_enter_state(struct atmel_private *priv, int new_state); 599static void atmel_enter_state(struct atmel_private *priv, int new_state);
600int atmel_open (struct net_device *dev); 600int atmel_open (struct net_device *dev);
601 601
@@ -784,11 +784,11 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
784 784
785static int start_tx(struct sk_buff *skb, struct net_device *dev) 785static int start_tx(struct sk_buff *skb, struct net_device *dev)
786{ 786{
787 static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
787 struct atmel_private *priv = netdev_priv(dev); 788 struct atmel_private *priv = netdev_priv(dev);
788 struct ieee80211_hdr_4addr header; 789 struct ieee80211_hdr_4addr header;
789 unsigned long flags; 790 unsigned long flags;
790 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; 791 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
791 u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
792 792
793 if (priv->card && priv->present_callback && 793 if (priv->card && priv->present_callback &&
794 !(*priv->present_callback)(priv->card)) { 794 !(*priv->present_callback)(priv->card)) {
@@ -1193,7 +1193,7 @@ static irqreturn_t service_interrupt(int irq, void *dev_id)
1193 1193
1194 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */ 1194 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1195 1195
1196 for (i = 0; i < sizeof(irq_order)/sizeof(u8); i++) 1196 for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1197 if (isr & irq_order[i]) 1197 if (isr & irq_order[i])
1198 break; 1198 break;
1199 1199
@@ -1345,10 +1345,10 @@ int atmel_open(struct net_device *dev)
1345 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain); 1345 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1346 } else { 1346 } else {
1347 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS); 1347 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1348 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) 1348 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1349 if (priv->reg_domain == channel_table[i].reg_domain) 1349 if (priv->reg_domain == channel_table[i].reg_domain)
1350 break; 1350 break;
1351 if (i == sizeof(channel_table)/sizeof(channel_table[0])) { 1351 if (i == ARRAY_SIZE(channel_table)) {
1352 priv->reg_domain = REG_DOMAIN_MKK1; 1352 priv->reg_domain = REG_DOMAIN_MKK1;
1353 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name); 1353 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1354 } 1354 }
@@ -1393,7 +1393,7 @@ static int atmel_validate_channel(struct atmel_private *priv, int channel)
1393 else return suitable default channel */ 1393 else return suitable default channel */
1394 int i; 1394 int i;
1395 1395
1396 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) 1396 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1397 if (priv->reg_domain == channel_table[i].reg_domain) { 1397 if (priv->reg_domain == channel_table[i].reg_domain) {
1398 if (channel >= channel_table[i].min && 1398 if (channel >= channel_table[i].min &&
1399 channel <= channel_table[i].max) 1399 channel <= channel_table[i].max)
@@ -1437,7 +1437,7 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
1437 } 1437 }
1438 1438
1439 r = "<unknown>"; 1439 r = "<unknown>";
1440 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) 1440 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1441 if (priv->reg_domain == channel_table[i].reg_domain) 1441 if (priv->reg_domain == channel_table[i].reg_domain)
1442 r = channel_table[i].name; 1442 r = channel_table[i].name;
1443 1443
@@ -1736,7 +1736,7 @@ static int atmel_set_encode(struct net_device *dev,
1736 /* Disable the key */ 1736 /* Disable the key */
1737 priv->wep_key_len[index] = 0; 1737 priv->wep_key_len[index] = 0;
1738 /* Check if the key is not marked as invalid */ 1738 /* Check if the key is not marked as invalid */
1739 if(!(dwrq->flags & IW_ENCODE_NOKEY)) { 1739 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1740 /* Cleanup */ 1740 /* Cleanup */
1741 memset(priv->wep_keys[index], 0, 13); 1741 memset(priv->wep_keys[index], 0, 13);
1742 /* Copy the key in the driver */ 1742 /* Copy the key in the driver */
@@ -1907,7 +1907,7 @@ static int atmel_get_encodeext(struct net_device *dev,
1907 1907
1908 encoding->flags = idx + 1; 1908 encoding->flags = idx + 1;
1909 memset(ext, 0, sizeof(*ext)); 1909 memset(ext, 0, sizeof(*ext));
1910 1910
1911 if (!priv->wep_is_on) { 1911 if (!priv->wep_is_on) {
1912 ext->alg = IW_ENCODE_ALG_NONE; 1912 ext->alg = IW_ENCODE_ALG_NONE;
1913 ext->key_len = 0; 1913 ext->key_len = 0;
@@ -2343,6 +2343,14 @@ static int atmel_get_scan(struct net_device *dev,
2343 iwe.u.freq.e = 0; 2343 iwe.u.freq.e = 0;
2344 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN); 2344 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
2345 2345
2346 /* Add quality statistics */
2347 iwe.cmd = IWEVQUAL;
2348 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2349 iwe.u.qual.qual = iwe.u.qual.level;
2350 /* iwe.u.qual.noise = SOMETHING */
2351 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
2352
2353
2346 iwe.cmd = SIOCGIWENCODE; 2354 iwe.cmd = SIOCGIWENCODE;
2347 if (priv->BSSinfo[i].UsingWEP) 2355 if (priv->BSSinfo[i].UsingWEP)
2348 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 2356 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
@@ -2373,7 +2381,7 @@ static int atmel_get_range(struct net_device *dev,
2373 range->min_nwid = 0x0000; 2381 range->min_nwid = 0x0000;
2374 range->max_nwid = 0x0000; 2382 range->max_nwid = 0x0000;
2375 range->num_channels = 0; 2383 range->num_channels = 0;
2376 for (j = 0; j < sizeof(channel_table)/sizeof(channel_table[0]); j++) 2384 for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2377 if (priv->reg_domain == channel_table[j].reg_domain) { 2385 if (priv->reg_domain == channel_table[j].reg_domain) {
2378 range->num_channels = channel_table[j].max - channel_table[j].min + 1; 2386 range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2379 break; 2387 break;
@@ -2579,9 +2587,9 @@ static const struct iw_priv_args atmel_private_args[] = {
2579 2587
2580static const struct iw_handler_def atmel_handler_def = 2588static const struct iw_handler_def atmel_handler_def =
2581{ 2589{
2582 .num_standard = sizeof(atmel_handler)/sizeof(iw_handler), 2590 .num_standard = ARRAY_SIZE(atmel_handler),
2583 .num_private = sizeof(atmel_private_handler)/sizeof(iw_handler), 2591 .num_private = ARRAY_SIZE(atmel_private_handler),
2584 .num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args), 2592 .num_private_args = ARRAY_SIZE(atmel_private_args),
2585 .standard = (iw_handler *) atmel_handler, 2593 .standard = (iw_handler *) atmel_handler,
2586 .private = (iw_handler *) atmel_private_handler, 2594 .private = (iw_handler *) atmel_private_handler,
2587 .private_args = (struct iw_priv_args *) atmel_private_args, 2595 .private_args = (struct iw_priv_args *) atmel_private_args,
@@ -2645,7 +2653,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2645 2653
2646 domain[REGDOMAINSZ] = 0; 2654 domain[REGDOMAINSZ] = 0;
2647 rc = -EINVAL; 2655 rc = -EINVAL;
2648 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) { 2656 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2649 /* strcasecmp doesn't exist in the library */ 2657 /* strcasecmp doesn't exist in the library */
2650 char *a = channel_table[i].name; 2658 char *a = channel_table[i].name;
2651 char *b = domain; 2659 char *b = domain;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 785664090bb4..5c410989c4d7 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -5,12 +5,12 @@
5 Copyright 2000-2001 ATMEL Corporation. 5 Copyright 2000-2001 ATMEL Corporation.
6 Copyright 2003 Simon Kelley. 6 Copyright 2003 Simon Kelley.
7 7
8 This code was developed from version 2.1.1 of the Atmel drivers, 8 This code was developed from version 2.1.1 of the Atmel drivers,
9 released by Atmel corp. under the GPL in December 2002. It also 9 released by Atmel corp. under the GPL in December 2002. It also
10 includes code from the Linux aironet drivers (C) Benjamin Reed, 10 includes code from the Linux aironet drivers (C) Benjamin Reed,
11 and the Linux PCMCIA package, (C) David Hinds. 11 and the Linux PCMCIA package, (C) David Hinds.
12 12
13 For all queries about this code, please contact the current author, 13 For all queries about this code, please contact the current author,
14 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation. 14 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
15 15
16 This program is free software; you can redistribute it and/or modify 16 This program is free software; you can redistribute it and/or modify
@@ -87,7 +87,7 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
87 event is received. The config() and release() entry points are 87 event is received. The config() and release() entry points are
88 used to configure or release a socket, in response to card 88 used to configure or release a socket, in response to card
89 insertion and ejection events. They are invoked from the atmel_cs 89 insertion and ejection events. They are invoked from the atmel_cs
90 event handler. 90 event handler.
91*/ 91*/
92 92
93static int atmel_config(struct pcmcia_device *link); 93static int atmel_config(struct pcmcia_device *link);
@@ -133,22 +133,22 @@ static void atmel_detach(struct pcmcia_device *p_dev);
133 device IO routines can use a flag like this to throttle IO to a 133 device IO routines can use a flag like this to throttle IO to a
134 card that is not ready to accept it. 134 card that is not ready to accept it.
135*/ 135*/
136 136
137typedef struct local_info_t { 137typedef struct local_info_t {
138 dev_node_t node; 138 dev_node_t node;
139 struct net_device *eth_dev; 139 struct net_device *eth_dev;
140} local_info_t; 140} local_info_t;
141 141
142/*====================================================================== 142/*======================================================================
143 143
144 atmel_attach() creates an "instance" of the driver, allocating 144 atmel_attach() creates an "instance" of the driver, allocating
145 local data structures for one device. The device is registered 145 local data structures for one device. The device is registered
146 with Card Services. 146 with Card Services.
147 147
148 The dev_link structure is initialized, but we don't actually 148 The dev_link structure is initialized, but we don't actually
149 configure the card at this point -- we wait until we receive a 149 configure the card at this point -- we wait until we receive a
150 card insertion event. 150 card insertion event.
151 151
152 ======================================================================*/ 152 ======================================================================*/
153 153
154static int atmel_probe(struct pcmcia_device *p_dev) 154static int atmel_probe(struct pcmcia_device *p_dev)
@@ -184,12 +184,12 @@ static int atmel_probe(struct pcmcia_device *p_dev)
184} /* atmel_attach */ 184} /* atmel_attach */
185 185
186/*====================================================================== 186/*======================================================================
187 187
188 This deletes a driver "instance". The device is de-registered 188 This deletes a driver "instance". The device is de-registered
189 with Card Services. If it has been released, all local data 189 with Card Services. If it has been released, all local data
190 structures are freed. Otherwise, the structures will be freed 190 structures are freed. Otherwise, the structures will be freed
191 when the device is released. 191 when the device is released.
192 192
193 ======================================================================*/ 193 ======================================================================*/
194 194
195static void atmel_detach(struct pcmcia_device *link) 195static void atmel_detach(struct pcmcia_device *link)
@@ -202,11 +202,11 @@ static void atmel_detach(struct pcmcia_device *link)
202} 202}
203 203
204/*====================================================================== 204/*======================================================================
205 205
206 atmel_config() is scheduled to run after a CARD_INSERTION event 206 atmel_config() is scheduled to run after a CARD_INSERTION event
207 is received, to configure the PCMCIA socket, and to make the 207 is received, to configure the PCMCIA socket, and to make the
208 device available to the system. 208 device available to the system.
209 209
210 ======================================================================*/ 210 ======================================================================*/
211 211
212#define CS_CHECK(fn, ret) \ 212#define CS_CHECK(fn, ret) \
@@ -237,12 +237,12 @@ static int atmel_config(struct pcmcia_device *link)
237 did = handle_to_dev(link).driver_data; 237 did = handle_to_dev(link).driver_data;
238 238
239 DEBUG(0, "atmel_config(0x%p)\n", link); 239 DEBUG(0, "atmel_config(0x%p)\n", link);
240 240
241 tuple.Attributes = 0; 241 tuple.Attributes = 0;
242 tuple.TupleData = buf; 242 tuple.TupleData = buf;
243 tuple.TupleDataMax = sizeof(buf); 243 tuple.TupleDataMax = sizeof(buf);
244 tuple.TupleOffset = 0; 244 tuple.TupleOffset = 0;
245 245
246 /* 246 /*
247 This reads the card's CONFIG tuple to find its configuration 247 This reads the card's CONFIG tuple to find its configuration
248 registers. 248 registers.
@@ -258,7 +258,7 @@ static int atmel_config(struct pcmcia_device *link)
258 In this loop, we scan the CIS for configuration table entries, 258 In this loop, we scan the CIS for configuration table entries,
259 each of which describes a valid card configuration, including 259 each of which describes a valid card configuration, including
260 voltage, IO window, memory window, and interrupt settings. 260 voltage, IO window, memory window, and interrupt settings.
261 261
262 We make no assumptions about the card to be configured: we use 262 We make no assumptions about the card to be configured: we use
263 just the information available in the CIS. In an ideal world, 263 just the information available in the CIS. In an ideal world,
264 this would work for any PCMCIA card, but it requires a complete 264 this would work for any PCMCIA card, but it requires a complete
@@ -274,17 +274,17 @@ static int atmel_config(struct pcmcia_device *link)
274 if (pcmcia_get_tuple_data(link, &tuple) != 0 || 274 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
275 pcmcia_parse_tuple(link, &tuple, &parse) != 0) 275 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
276 goto next_entry; 276 goto next_entry;
277 277
278 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; 278 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
279 if (cfg->index == 0) goto next_entry; 279 if (cfg->index == 0) goto next_entry;
280 link->conf.ConfigIndex = cfg->index; 280 link->conf.ConfigIndex = cfg->index;
281 281
282 /* Does this card need audio output? */ 282 /* Does this card need audio output? */
283 if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 283 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
284 link->conf.Attributes |= CONF_ENABLE_SPKR; 284 link->conf.Attributes |= CONF_ENABLE_SPKR;
285 link->conf.Status = CCSR_AUDIO_ENA; 285 link->conf.Status = CCSR_AUDIO_ENA;
286 } 286 }
287 287
288 /* Use power settings for Vcc and Vpp if present */ 288 /* Use power settings for Vcc and Vpp if present */
289 /* Note that the CIS values need to be rescaled */ 289 /* Note that the CIS values need to be rescaled */
290 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 290 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
@@ -293,11 +293,11 @@ static int atmel_config(struct pcmcia_device *link)
293 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) 293 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
294 link->conf.Vpp = 294 link->conf.Vpp =
295 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; 295 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
296 296
297 /* Do we need to allocate an interrupt? */ 297 /* Do we need to allocate an interrupt? */
298 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) 298 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
299 link->conf.Attributes |= CONF_ENABLE_IRQ; 299 link->conf.Attributes |= CONF_ENABLE_IRQ;
300 300
301 /* IO window settings */ 301 /* IO window settings */
302 link->io.NumPorts1 = link->io.NumPorts2 = 0; 302 link->io.NumPorts1 = link->io.NumPorts2 = 0;
303 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 303 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
@@ -315,18 +315,18 @@ static int atmel_config(struct pcmcia_device *link)
315 link->io.NumPorts2 = io->win[1].len; 315 link->io.NumPorts2 = io->win[1].len;
316 } 316 }
317 } 317 }
318 318
319 /* This reserves IO space but doesn't actually enable it */ 319 /* This reserves IO space but doesn't actually enable it */
320 if (pcmcia_request_io(link, &link->io) != 0) 320 if (pcmcia_request_io(link, &link->io) != 0)
321 goto next_entry; 321 goto next_entry;
322 322
323 /* If we got this far, we're cool! */ 323 /* If we got this far, we're cool! */
324 break; 324 break;
325 325
326 next_entry: 326 next_entry:
327 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); 327 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
328 } 328 }
329 329
330 /* 330 /*
331 Allocate an interrupt line. Note that this does not assign a 331 Allocate an interrupt line. Note that this does not assign a
332 handler to the interrupt, unless the 'Handler' member of the 332 handler to the interrupt, unless the 'Handler' member of the
@@ -334,31 +334,31 @@ static int atmel_config(struct pcmcia_device *link)
334 */ 334 */
335 if (link->conf.Attributes & CONF_ENABLE_IRQ) 335 if (link->conf.Attributes & CONF_ENABLE_IRQ)
336 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 336 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
337 337
338 /* 338 /*
339 This actually configures the PCMCIA socket -- setting up 339 This actually configures the PCMCIA socket -- setting up
340 the I/O windows and the interrupt mapping, and putting the 340 the I/O windows and the interrupt mapping, and putting the
341 card and host interface into "Memory and IO" mode. 341 card and host interface into "Memory and IO" mode.
342 */ 342 */
343 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 343 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
344 344
345 if (link->irq.AssignedIRQ == 0) { 345 if (link->irq.AssignedIRQ == 0) {
346 printk(KERN_ALERT 346 printk(KERN_ALERT
347 "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config."); 347 "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
348 goto cs_failed; 348 goto cs_failed;
349 } 349 }
350 350
351 ((local_info_t*)link->priv)->eth_dev = 351 ((local_info_t*)link->priv)->eth_dev =
352 init_atmel_card(link->irq.AssignedIRQ, 352 init_atmel_card(link->irq.AssignedIRQ,
353 link->io.BasePort1, 353 link->io.BasePort1,
354 did ? did->driver_info : ATMEL_FW_TYPE_NONE, 354 did ? did->driver_info : ATMEL_FW_TYPE_NONE,
355 &handle_to_dev(link), 355 &handle_to_dev(link),
356 card_present, 356 card_present,
357 link); 357 link);
358 if (!((local_info_t*)link->priv)->eth_dev) 358 if (!((local_info_t*)link->priv)->eth_dev)
359 goto cs_failed; 359 goto cs_failed;
360 360
361 361
362 /* 362 /*
363 At this point, the dev_node_t structure(s) need to be 363 At this point, the dev_node_t structure(s) need to be
364 initialized and arranged in a linked list at link->dev_node. 364 initialized and arranged in a linked list at link->dev_node.
@@ -376,11 +376,11 @@ static int atmel_config(struct pcmcia_device *link)
376} 376}
377 377
378/*====================================================================== 378/*======================================================================
379 379
380 After a card is removed, atmel_release() will unregister the 380 After a card is removed, atmel_release() will unregister the
381 device, and release the PCMCIA configuration. If the device is 381 device, and release the PCMCIA configuration. If the device is
382 still open, this will be postponed until it is closed. 382 still open, this will be postponed until it is closed.
383 383
384 ======================================================================*/ 384 ======================================================================*/
385 385
386static void atmel_release(struct pcmcia_device *link) 386static void atmel_release(struct pcmcia_device *link)
@@ -517,7 +517,7 @@ static void atmel_cs_cleanup(void)
517 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 517 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
518 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 518 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
519 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 519 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
520 POSSIBILITY OF SUCH DAMAGE. 520 POSSIBILITY OF SUCH DAMAGE.
521*/ 521*/
522 522
523module_init(atmel_cs_init); 523module_init(atmel_cs_init);
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
index 3bfa791c323d..92f87fbe750f 100644
--- a/drivers/net/wireless/atmel_pci.c
+++ b/drivers/net/wireless/atmel_pci.c
@@ -53,18 +53,18 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev,
53 const struct pci_device_id *pent) 53 const struct pci_device_id *pent)
54{ 54{
55 struct net_device *dev; 55 struct net_device *dev;
56 56
57 if (pci_enable_device(pdev)) 57 if (pci_enable_device(pdev))
58 return -ENODEV; 58 return -ENODEV;
59 59
60 pci_set_master(pdev); 60 pci_set_master(pdev);
61 61
62 dev = init_atmel_card(pdev->irq, pdev->resource[1].start, 62 dev = init_atmel_card(pdev->irq, pdev->resource[1].start,
63 ATMEL_FW_TYPE_506, 63 ATMEL_FW_TYPE_506,
64 &pdev->dev, NULL, NULL); 64 &pdev->dev, NULL, NULL);
65 if (!dev) 65 if (!dev)
66 return -ENODEV; 66 return -ENODEV;
67 67
68 pci_set_drvdata(pdev, dev); 68 pci_set_drvdata(pdev, dev);
69 return 0; 69 return 0;
70} 70}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index fbc0c087f53c..8286678513b9 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -159,6 +159,7 @@
159 159
160/* Chipcommon registers. */ 160/* Chipcommon registers. */
161#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 161#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
162#define BCM43xx_CHIPCOMMON_CTL 0x28
162#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 163#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
163#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 164#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
164#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 165#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
@@ -172,6 +173,33 @@
172/* SBTOPCI2 values. */ 173/* SBTOPCI2 values. */
173#define BCM43xx_SBTOPCI2_PREFETCH 0x4 174#define BCM43xx_SBTOPCI2_PREFETCH 0x4
174#define BCM43xx_SBTOPCI2_BURST 0x8 175#define BCM43xx_SBTOPCI2_BURST 0x8
176#define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20
177
178/* PCI-E core registers. */
179#define BCM43xx_PCIECORE_REG_ADDR 0x0130
180#define BCM43xx_PCIECORE_REG_DATA 0x0134
181#define BCM43xx_PCIECORE_MDIO_CTL 0x0128
182#define BCM43xx_PCIECORE_MDIO_DATA 0x012C
183
184/* PCI-E registers. */
185#define BCM43xx_PCIE_TLP_WORKAROUND 0x0004
186#define BCM43xx_PCIE_DLLP_LINKCTL 0x0100
187
188/* PCI-E MDIO bits. */
189#define BCM43xx_PCIE_MDIO_ST 0x40000000
190#define BCM43xx_PCIE_MDIO_WT 0x10000000
191#define BCM43xx_PCIE_MDIO_DEV 22
192#define BCM43xx_PCIE_MDIO_REG 18
193#define BCM43xx_PCIE_MDIO_TA 0x00020000
194#define BCM43xx_PCIE_MDIO_TC 0x0100
195
196/* MDIO devices. */
197#define BCM43xx_MDIO_SERDES_RX 0x1F
198
199/* SERDES RX registers. */
200#define BCM43xx_SERDES_RXTIMER 0x2
201#define BCM43xx_SERDES_CDR 0x6
202#define BCM43xx_SERDES_CDR_BW 0x7
175 203
176/* Chipcommon capabilities. */ 204/* Chipcommon capabilities. */
177#define BCM43xx_CAPABILITIES_PCTL 0x00040000 205#define BCM43xx_CAPABILITIES_PCTL 0x00040000
@@ -221,6 +249,7 @@
221#define BCM43xx_COREID_USB20_HOST 0x819 249#define BCM43xx_COREID_USB20_HOST 0x819
222#define BCM43xx_COREID_USB20_DEV 0x81a 250#define BCM43xx_COREID_USB20_DEV 0x81a
223#define BCM43xx_COREID_SDIO_HOST 0x81b 251#define BCM43xx_COREID_SDIO_HOST 0x81b
252#define BCM43xx_COREID_PCIE 0x820
224 253
225/* Core Information Registers */ 254/* Core Information Registers */
226#define BCM43xx_CIR_BASE 0xf00 255#define BCM43xx_CIR_BASE 0xf00
@@ -365,6 +394,9 @@
365#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7 394#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
366#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4 395#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
367 396
397/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
398#define RX_RSSI_MAX 60
399
368/* Max size of a security key */ 400/* Max size of a security key */
369#define BCM43xx_SEC_KEYSIZE 16 401#define BCM43xx_SEC_KEYSIZE 16
370/* Security algorithms. */ 402/* Security algorithms. */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 728a9b789fdf..2ec2e5afce67 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -130,6 +130,10 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
130 { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 130 { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
131 /* Broadcom 4307 802.11b */ 131 /* Broadcom 4307 802.11b */
132 { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 132 { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
133 /* Broadcom 4311 802.11(a)/b/g */
134 { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
135 /* Broadcom 4312 802.11a/b/g */
136 { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
133 /* Broadcom 4318 802.11b/g */ 137 /* Broadcom 4318 802.11b/g */
134 { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 138 { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
135 /* Broadcom 4319 802.11a/b/g */ 139 /* Broadcom 4319 802.11a/b/g */
@@ -2600,8 +2604,9 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2600 /* fetch sb_id_hi from core information registers */ 2604 /* fetch sb_id_hi from core information registers */
2601 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); 2605 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2602 2606
2603 core_id = (sb_id_hi & 0xFFF0) >> 4; 2607 core_id = (sb_id_hi & 0x8FF0) >> 4;
2604 core_rev = (sb_id_hi & 0xF); 2608 core_rev = (sb_id_hi & 0x7000) >> 8;
2609 core_rev |= (sb_id_hi & 0xF);
2605 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; 2610 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2606 2611
2607 /* if present, chipcommon is always core 0; read the chipid from it */ 2612 /* if present, chipcommon is always core 0; read the chipid from it */
@@ -2679,14 +2684,10 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2679 bcm->chip_id, bcm->chip_rev); 2684 bcm->chip_id, bcm->chip_rev);
2680 dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count); 2685 dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
2681 if (bcm->core_chipcommon.available) { 2686 if (bcm->core_chipcommon.available) {
2682 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", 2687 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x\n",
2683 core_id, core_rev, core_vendor, 2688 core_id, core_rev, core_vendor);
2684 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled");
2685 }
2686
2687 if (bcm->core_chipcommon.available)
2688 current_core = 1; 2689 current_core = 1;
2689 else 2690 } else
2690 current_core = 0; 2691 current_core = 0;
2691 for ( ; current_core < core_count; current_core++) { 2692 for ( ; current_core < core_count; current_core++) {
2692 struct bcm43xx_coreinfo *core; 2693 struct bcm43xx_coreinfo *core;
@@ -2704,13 +2705,13 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2704 core_rev = (sb_id_hi & 0xF); 2705 core_rev = (sb_id_hi & 0xF);
2705 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; 2706 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2706 2707
2707 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", 2708 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x\n",
2708 current_core, core_id, core_rev, core_vendor, 2709 current_core, core_id, core_rev, core_vendor);
2709 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" );
2710 2710
2711 core = NULL; 2711 core = NULL;
2712 switch (core_id) { 2712 switch (core_id) {
2713 case BCM43xx_COREID_PCI: 2713 case BCM43xx_COREID_PCI:
2714 case BCM43xx_COREID_PCIE:
2714 core = &bcm->core_pci; 2715 core = &bcm->core_pci;
2715 if (core->available) { 2716 if (core->available) {
2716 printk(KERN_WARNING PFX "Multiple PCI cores found.\n"); 2717 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
@@ -2749,12 +2750,12 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2749 case 6: 2750 case 6:
2750 case 7: 2751 case 7:
2751 case 9: 2752 case 9:
2753 case 10:
2752 break; 2754 break;
2753 default: 2755 default:
2754 printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n", 2756 printk(KERN_WARNING PFX
2757 "Unsupported 80211 core revision %u\n",
2755 core_rev); 2758 core_rev);
2756 err = -ENODEV;
2757 goto out;
2758 } 2759 }
2759 bcm->nr_80211_available++; 2760 bcm->nr_80211_available++;
2760 core->priv = ext_80211; 2761 core->priv = ext_80211;
@@ -2868,16 +2869,11 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2868 u32 sbimconfiglow; 2869 u32 sbimconfiglow;
2869 u8 limit; 2870 u8 limit;
2870 2871
2871 if (bcm->chip_rev < 5) { 2872 if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) {
2872 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); 2873 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
2873 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; 2874 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
2874 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; 2875 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
2875 if (bcm->bustype == BCM43xx_BUSTYPE_PCI) 2876 sbimconfiglow |= 0x32;
2876 sbimconfiglow |= 0x32;
2877 else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
2878 sbimconfiglow |= 0x53;
2879 else
2880 assert(0);
2881 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); 2877 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
2882 } 2878 }
2883 2879
@@ -3004,22 +3000,64 @@ static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
3004 3000
3005static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) 3001static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
3006{ 3002{
3007 int err; 3003 int err = 0;
3008 struct bcm43xx_coreinfo *old_core;
3009 3004
3010 old_core = bcm->current_core; 3005 bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3011 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3012 if (err)
3013 goto out;
3014 3006
3015 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); 3007 if (bcm->core_chipcommon.available) {
3008 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
3009 if (err)
3010 goto out;
3011
3012 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
3013
3014 /* this function is always called when a PCI core is mapped */
3015 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3016 if (err)
3017 goto out;
3018 } else
3019 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
3020
3021 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3016 3022
3017 bcm43xx_switch_core(bcm, old_core);
3018 assert(err == 0);
3019out: 3023out:
3020 return err; 3024 return err;
3021} 3025}
3022 3026
3027static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address)
3028{
3029 bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
3030 return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA);
3031}
3032
3033static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address,
3034 u32 data)
3035{
3036 bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
3037 bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data);
3038}
3039
3040static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg,
3041 u16 data)
3042{
3043 int i;
3044
3045 bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082);
3046 bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST |
3047 BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) |
3048 (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA |
3049 data);
3050 udelay(10);
3051
3052 for (i = 0; i < 10; i++) {
3053 if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
3054 BCM43xx_PCIE_MDIO_TC)
3055 break;
3056 msleep(1);
3057 }
3058 bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0);
3059}
3060
3023/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable. 3061/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
3024 * To enable core 0, pass a core_mask of 1<<0 3062 * To enable core 0, pass a core_mask of 1<<0
3025 */ 3063 */
@@ -3039,7 +3077,8 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
3039 if (err) 3077 if (err)
3040 goto out; 3078 goto out;
3041 3079
3042 if (bcm->core_pci.rev < 6) { 3080 if (bcm->current_core->rev < 6 ||
3081 bcm->current_core->id == BCM43xx_COREID_PCI) {
3043 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); 3082 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
3044 value |= (1 << backplane_flag_nr); 3083 value |= (1 << backplane_flag_nr);
3045 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value); 3084 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
@@ -3057,21 +3096,46 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
3057 } 3096 }
3058 } 3097 }
3059 3098
3060 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); 3099 if (bcm->current_core->id == BCM43xx_COREID_PCI) {
3061 value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; 3100 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3062 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); 3101 value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
3063 3102 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3064 if (bcm->core_pci.rev < 5) { 3103
3065 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); 3104 if (bcm->current_core->rev < 5) {
3066 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) 3105 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3067 & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; 3106 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
3068 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) 3107 & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3069 & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; 3108 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
3070 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); 3109 & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3071 err = bcm43xx_pcicore_commit_settings(bcm); 3110 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
3072 assert(err == 0); 3111 err = bcm43xx_pcicore_commit_settings(bcm);
3112 assert(err == 0);
3113 } else if (bcm->current_core->rev >= 11) {
3114 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3115 value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI;
3116 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3117 }
3118 } else {
3119 if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) {
3120 value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND);
3121 value |= 0x8;
3122 bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND,
3123 value);
3124 }
3125 if (bcm->current_core->rev == 0) {
3126 bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3127 BCM43xx_SERDES_RXTIMER, 0x8128);
3128 bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3129 BCM43xx_SERDES_CDR, 0x0100);
3130 bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3131 BCM43xx_SERDES_CDR_BW, 0x1466);
3132 } else if (bcm->current_core->rev == 1) {
3133 value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL);
3134 value |= 0x40;
3135 bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL,
3136 value);
3137 }
3073 } 3138 }
3074
3075out_switch_back: 3139out_switch_back:
3076 err = bcm43xx_switch_core(bcm, old_core); 3140 err = bcm43xx_switch_core(bcm, old_core);
3077out: 3141out:
@@ -3140,43 +3204,17 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3140 3204
3141static void do_periodic_work(struct bcm43xx_private *bcm) 3205static void do_periodic_work(struct bcm43xx_private *bcm)
3142{ 3206{
3143 unsigned int state; 3207 if (bcm->periodic_state % 8 == 0)
3144
3145 state = bcm->periodic_state;
3146 if (state % 8 == 0)
3147 bcm43xx_periodic_every120sec(bcm); 3208 bcm43xx_periodic_every120sec(bcm);
3148 if (state % 4 == 0) 3209 if (bcm->periodic_state % 4 == 0)
3149 bcm43xx_periodic_every60sec(bcm); 3210 bcm43xx_periodic_every60sec(bcm);
3150 if (state % 2 == 0) 3211 if (bcm->periodic_state % 2 == 0)
3151 bcm43xx_periodic_every30sec(bcm); 3212 bcm43xx_periodic_every30sec(bcm);
3152 if (state % 1 == 0) 3213 bcm43xx_periodic_every15sec(bcm);
3153 bcm43xx_periodic_every15sec(bcm);
3154 bcm->periodic_state = state + 1;
3155 3214
3156 schedule_delayed_work(&bcm->periodic_work, HZ * 15); 3215 schedule_delayed_work(&bcm->periodic_work, HZ * 15);
3157} 3216}
3158 3217
3159/* Estimate a "Badness" value based on the periodic work
3160 * state-machine state. "Badness" is worse (bigger), if the
3161 * periodic work will take longer.
3162 */
3163static int estimate_periodic_work_badness(unsigned int state)
3164{
3165 int badness = 0;
3166
3167 if (state % 8 == 0) /* every 120 sec */
3168 badness += 10;
3169 if (state % 4 == 0) /* every 60 sec */
3170 badness += 5;
3171 if (state % 2 == 0) /* every 30 sec */
3172 badness += 1;
3173 if (state % 1 == 0) /* every 15 sec */
3174 badness += 1;
3175
3176#define BADNESS_LIMIT 4
3177 return badness;
3178}
3179
3180static void bcm43xx_periodic_work_handler(struct work_struct *work) 3218static void bcm43xx_periodic_work_handler(struct work_struct *work)
3181{ 3219{
3182 struct bcm43xx_private *bcm = 3220 struct bcm43xx_private *bcm =
@@ -3184,12 +3222,10 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work)
3184 struct net_device *net_dev = bcm->net_dev; 3222 struct net_device *net_dev = bcm->net_dev;
3185 unsigned long flags; 3223 unsigned long flags;
3186 u32 savedirqs = 0; 3224 u32 savedirqs = 0;
3187 int badness;
3188 unsigned long orig_trans_start = 0; 3225 unsigned long orig_trans_start = 0;
3189 3226
3190 mutex_lock(&bcm->mutex); 3227 mutex_lock(&bcm->mutex);
3191 badness = estimate_periodic_work_badness(bcm->periodic_state); 3228 if (unlikely(bcm->periodic_state % 4 == 0)) {
3192 if (badness > BADNESS_LIMIT) {
3193 /* Periodic work will take a long time, so we want it to 3229 /* Periodic work will take a long time, so we want it to
3194 * be preemtible. 3230 * be preemtible.
3195 */ 3231 */
@@ -3221,7 +3257,7 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work)
3221 3257
3222 do_periodic_work(bcm); 3258 do_periodic_work(bcm);
3223 3259
3224 if (badness > BADNESS_LIMIT) { 3260 if (unlikely(bcm->periodic_state % 4 == 0)) {
3225 spin_lock_irqsave(&bcm->irq_lock, flags); 3261 spin_lock_irqsave(&bcm->irq_lock, flags);
3226 tasklet_enable(&bcm->isr_tasklet); 3262 tasklet_enable(&bcm->isr_tasklet);
3227 bcm43xx_interrupt_enable(bcm, savedirqs); 3263 bcm43xx_interrupt_enable(bcm, savedirqs);
@@ -3232,6 +3268,7 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work)
3232 net_dev->trans_start = orig_trans_start; 3268 net_dev->trans_start = orig_trans_start;
3233 } 3269 }
3234 mmiowb(); 3270 mmiowb();
3271 bcm->periodic_state++;
3235 spin_unlock_irqrestore(&bcm->irq_lock, flags); 3272 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3236 mutex_unlock(&bcm->mutex); 3273 mutex_unlock(&bcm->mutex);
3237} 3274}
@@ -3677,7 +3714,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3677 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; 3714 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3678 break; 3715 break;
3679 case BCM43xx_PHYTYPE_G: 3716 case BCM43xx_PHYTYPE_G:
3680 if (phy_rev > 7) 3717 if (phy_rev > 8)
3681 phy_rev_ok = 0; 3718 phy_rev_ok = 0;
3682 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION | 3719 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3683 IEEE80211_CCK_MODULATION; 3720 IEEE80211_CCK_MODULATION;
@@ -3689,6 +3726,8 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3689 phy_type); 3726 phy_type);
3690 return -ENODEV; 3727 return -ENODEV;
3691 }; 3728 };
3729 bcm->ieee->perfect_rssi = RX_RSSI_MAX;
3730 bcm->ieee->worst_rssi = 0;
3692 if (!phy_rev_ok) { 3731 if (!phy_rev_ok) {
3693 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n", 3732 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3694 phy_rev); 3733 phy_rev);
@@ -3975,11 +4014,6 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3975 return NETDEV_TX_OK; 4014 return NETDEV_TX_OK;
3976} 4015}
3977 4016
3978static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
3979{
3980 return &(bcm43xx_priv(net_dev)->ieee->stats);
3981}
3982
3983static void bcm43xx_net_tx_timeout(struct net_device *net_dev) 4017static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3984{ 4018{
3985 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 4019 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
@@ -4093,7 +4127,6 @@ static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
4093 4127
4094 net_dev->open = bcm43xx_net_open; 4128 net_dev->open = bcm43xx_net_open;
4095 net_dev->stop = bcm43xx_net_stop; 4129 net_dev->stop = bcm43xx_net_stop;
4096 net_dev->get_stats = bcm43xx_net_get_stats;
4097 net_dev->tx_timeout = bcm43xx_net_tx_timeout; 4130 net_dev->tx_timeout = bcm43xx_net_tx_timeout;
4098#ifdef CONFIG_NET_POLL_CONTROLLER 4131#ifdef CONFIG_NET_POLL_CONTROLLER
4099 net_dev->poll_controller = bcm43xx_net_poll_controller; 4132 net_dev->poll_controller = bcm43xx_net_poll_controller;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
index 6569da3a7a39..7e774f410953 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
@@ -153,8 +153,6 @@ int bcm43xx_pctl_init(struct bcm43xx_private *bcm)
153 int err, maxfreq; 153 int err, maxfreq;
154 struct bcm43xx_coreinfo *old_core; 154 struct bcm43xx_coreinfo *old_core;
155 155
156 if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
157 return 0;
158 old_core = bcm->current_core; 156 old_core = bcm->current_core;
159 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); 157 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
160 if (err == -ENODEV) 158 if (err == -ENODEV)
@@ -162,11 +160,27 @@ int bcm43xx_pctl_init(struct bcm43xx_private *bcm)
162 if (err) 160 if (err)
163 goto out; 161 goto out;
164 162
165 maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); 163 if (bcm->chip_id == 0x4321) {
166 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, 164 if (bcm->chip_rev == 0)
167 (maxfreq * 150 + 999999) / 1000000); 165 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4);
168 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, 166 if (bcm->chip_rev == 1)
169 (maxfreq * 15 + 999999) / 1000000); 167 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4);
168 }
169
170 if (bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) {
171 if (bcm->current_core->rev >= 10) {
172 /* Set Idle Power clock rate to 1Mhz */
173 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL,
174 (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL)
175 & 0x0000FFFF) | 0x40000);
176 } else {
177 maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
178 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
179 (maxfreq * 150 + 999999) / 1000000);
180 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY,
181 (maxfreq * 15 + 999999) / 1000000);
182 }
183 }
170 184
171 err = bcm43xx_switch_core(bcm, old_core); 185 err = bcm43xx_switch_core(bcm, old_core);
172 assert(err == 0); 186 assert(err == 0);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index d27016f8c736..a659442b9c15 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -47,9 +47,6 @@
47#define BCM43xx_WX_VERSION 18 47#define BCM43xx_WX_VERSION 18
48 48
49#define MAX_WX_STRING 80 49#define MAX_WX_STRING 80
50/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
51#define RX_RSSI_MAX 60
52
53 50
54static int bcm43xx_wx_get_name(struct net_device *net_dev, 51static int bcm43xx_wx_get_name(struct net_device *net_dev,
55 struct iw_request_info *info, 52 struct iw_request_info *info,
@@ -693,6 +690,7 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
693 bcm->ieee->host_encrypt = !!on; 690 bcm->ieee->host_encrypt = !!on;
694 bcm->ieee->host_decrypt = !!on; 691 bcm->ieee->host_decrypt = !!on;
695 bcm->ieee->host_build_iv = !on; 692 bcm->ieee->host_build_iv = !on;
693 bcm->ieee->host_strip_iv_icv = !on;
696 spin_unlock_irqrestore(&bcm->irq_lock, flags); 694 spin_unlock_irqrestore(&bcm->irq_lock, flags);
697 mutex_unlock(&bcm->mutex); 695 mutex_unlock(&bcm->mutex);
698 696
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
index 0159e4e93201..3e2462671690 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
@@ -544,24 +544,6 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
544 } 544 }
545 545
546 frame_ctl = le16_to_cpu(wlhdr->frame_ctl); 546 frame_ctl = le16_to_cpu(wlhdr->frame_ctl);
547 if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) {
548 frame_ctl &= ~IEEE80211_FCTL_PROTECTED;
549 wlhdr->frame_ctl = cpu_to_le16(frame_ctl);
550 /* trim IV and ICV */
551 /* FIXME: this must be done only for WEP encrypted packets */
552 if (skb->len < 32) {
553 dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag "
554 "set and length < 32)\n");
555 return -EINVAL;
556 } else {
557 memmove(skb->data + 4, skb->data, 24);
558 skb_pull(skb, 4);
559 skb_trim(skb, skb->len - 4);
560 stats.len -= 8;
561 }
562 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
563 }
564
565 switch (WLAN_FC_GET_TYPE(frame_ctl)) { 547 switch (WLAN_FC_GET_TYPE(frame_ctl)) {
566 case IEEE80211_FTYPE_MGMT: 548 case IEEE80211_FTYPE_MGMT:
567 ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats); 549 ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index c2fa011be291..d1de9766c831 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -425,8 +425,14 @@ static int prism2_pci_suspend(struct pci_dev *pdev, pm_message_t state)
425static int prism2_pci_resume(struct pci_dev *pdev) 425static int prism2_pci_resume(struct pci_dev *pdev)
426{ 426{
427 struct net_device *dev = pci_get_drvdata(pdev); 427 struct net_device *dev = pci_get_drvdata(pdev);
428 int err;
428 429
429 pci_enable_device(pdev); 430 err = pci_enable_device(pdev);
431 if (err) {
432 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
433 dev->name);
434 return err;
435 }
430 pci_restore_state(pdev); 436 pci_restore_state(pdev);
431 prism2_hw_config(dev, 0); 437 prism2_hw_config(dev, 0);
432 if (netif_running(dev)) { 438 if (netif_running(dev)) {
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 0f554373a60d..1bcd352a813b 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -5833,19 +5833,6 @@ static void ipw2100_tx_timeout(struct net_device *dev)
5833 schedule_reset(priv); 5833 schedule_reset(priv);
5834} 5834}
5835 5835
5836/*
5837 * TODO: reimplement it so that it reads statistics
5838 * from the adapter using ordinal tables
5839 * instead of/in addition to collecting them
5840 * in the driver
5841 */
5842static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5843{
5844 struct ipw2100_priv *priv = ieee80211_priv(dev);
5845
5846 return &priv->ieee->stats;
5847}
5848
5849static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) 5836static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5850{ 5837{
5851 /* This is called when wpa_supplicant loads and closes the driver 5838 /* This is called when wpa_supplicant loads and closes the driver
@@ -6030,7 +6017,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6030 dev->open = ipw2100_open; 6017 dev->open = ipw2100_open;
6031 dev->stop = ipw2100_close; 6018 dev->stop = ipw2100_close;
6032 dev->init = ipw2100_net_init; 6019 dev->init = ipw2100_net_init;
6033 dev->get_stats = ipw2100_stats;
6034 dev->ethtool_ops = &ipw2100_ethtool_ops; 6020 dev->ethtool_ops = &ipw2100_ethtool_ops;
6035 dev->tx_timeout = ipw2100_tx_timeout; 6021 dev->tx_timeout = ipw2100_tx_timeout;
6036 dev->wireless_handlers = &ipw2100_wx_handler_def; 6022 dev->wireless_handlers = &ipw2100_wx_handler_def;
@@ -6428,6 +6414,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6428{ 6414{
6429 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); 6415 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6430 struct net_device *dev = priv->net_dev; 6416 struct net_device *dev = priv->net_dev;
6417 int err;
6431 u32 val; 6418 u32 val;
6432 6419
6433 if (IPW2100_PM_DISABLED) 6420 if (IPW2100_PM_DISABLED)
@@ -6438,7 +6425,12 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6438 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name); 6425 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
6439 6426
6440 pci_set_power_state(pci_dev, PCI_D0); 6427 pci_set_power_state(pci_dev, PCI_D0);
6441 pci_enable_device(pci_dev); 6428 err = pci_enable_device(pci_dev);
6429 if (err) {
6430 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
6431 dev->name);
6432 return err;
6433 }
6442 pci_restore_state(pci_dev); 6434 pci_restore_state(pci_dev);
6443 6435
6444 /* 6436 /*
@@ -7573,11 +7565,10 @@ static int ipw2100_wx_set_genie(struct net_device *dev,
7573 return -EINVAL; 7565 return -EINVAL;
7574 7566
7575 if (wrqu->data.length) { 7567 if (wrqu->data.length) {
7576 buf = kmalloc(wrqu->data.length, GFP_KERNEL); 7568 buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);
7577 if (buf == NULL) 7569 if (buf == NULL)
7578 return -ENOMEM; 7570 return -ENOMEM;
7579 7571
7580 memcpy(buf, extra, wrqu->data.length);
7581 kfree(ieee->wpa_ie); 7572 kfree(ieee->wpa_ie);
7582 ieee->wpa_ie = buf; 7573 ieee->wpa_ie = buf;
7583 ieee->wpa_ie_len = wrqu->data.length; 7574 ieee->wpa_ie_len = wrqu->data.length;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 587a0918fa52..e82e56bb85e1 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -6938,8 +6938,8 @@ static int ipw_qos_association(struct ipw_priv *priv,
6938} 6938}
6939 6939
6940/* 6940/*
6941* handling the beaconing responces. if we get different QoS setting 6941* handling the beaconing responses. if we get different QoS setting
6942* of the network from the the associated setting adjust the QoS 6942* off the network from the associated setting, adjust the QoS
6943* setting 6943* setting
6944*/ 6944*/
6945static int ipw_qos_association_resp(struct ipw_priv *priv, 6945static int ipw_qos_association_resp(struct ipw_priv *priv,
@@ -11746,12 +11746,18 @@ static int ipw_pci_resume(struct pci_dev *pdev)
11746{ 11746{
11747 struct ipw_priv *priv = pci_get_drvdata(pdev); 11747 struct ipw_priv *priv = pci_get_drvdata(pdev);
11748 struct net_device *dev = priv->net_dev; 11748 struct net_device *dev = priv->net_dev;
11749 int err;
11749 u32 val; 11750 u32 val;
11750 11751
11751 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); 11752 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
11752 11753
11753 pci_set_power_state(pdev, PCI_D0); 11754 pci_set_power_state(pdev, PCI_D0);
11754 pci_enable_device(pdev); 11755 err = pci_enable_device(pdev);
11756 if (err) {
11757 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
11758 dev->name);
11759 return err;
11760 }
11755 pci_restore_state(pdev); 11761 pci_restore_state(pdev);
11756 11762
11757 /* 11763 /*
diff --git a/drivers/net/wireless/orinoco_pci.h b/drivers/net/wireless/orinoco_pci.h
index be1abea4b64f..f4e5e06760c1 100644
--- a/drivers/net/wireless/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco_pci.h
@@ -60,7 +60,12 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
60 int err; 60 int err;
61 61
62 pci_set_power_state(pdev, 0); 62 pci_set_power_state(pdev, 0);
63 pci_enable_device(pdev); 63 err = pci_enable_device(pdev);
64 if (err) {
65 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
66 dev->name);
67 return err;
68 }
64 pci_restore_state(pdev); 69 pci_restore_state(pdev);
65 70
66 err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, 71 err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 23deee69974b..02fc67bccbd0 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_ 3 * Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_
5 * 4 *
@@ -38,7 +37,7 @@
38 * isl38xx_disable_interrupts - disable all interrupts 37 * isl38xx_disable_interrupts - disable all interrupts
39 * @device: pci memory base address 38 * @device: pci memory base address
40 * 39 *
41 * Instructs the device to disable all interrupt reporting by asserting 40 * Instructs the device to disable all interrupt reporting by asserting
42 * the IRQ line. New events may still show up in the interrupt identification 41 * the IRQ line. New events may still show up in the interrupt identification
43 * register located at offset %ISL38XX_INT_IDENT_REG. 42 * register located at offset %ISL38XX_INT_IDENT_REG.
44 */ 43 */
@@ -204,17 +203,19 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
204 /* enable the interrupt for detecting initialization */ 203 /* enable the interrupt for detecting initialization */
205 204
206 /* Note: Do not enable other interrupts here. We want the 205 /* Note: Do not enable other interrupts here. We want the
207 * device to have come up first 100% before allowing any other 206 * device to have come up first 100% before allowing any other
208 * interrupts. */ 207 * interrupts. */
209 isl38xx_w32_flush(device_base, ISL38XX_INT_IDENT_INIT, ISL38XX_INT_EN_REG); 208 isl38xx_w32_flush(device_base, ISL38XX_INT_IDENT_INIT, ISL38XX_INT_EN_REG);
210 udelay(ISL38XX_WRITEIO_DELAY); /* allow complete full reset */ 209 udelay(ISL38XX_WRITEIO_DELAY); /* allow complete full reset */
211} 210}
212 211
213void 212void
214isl38xx_enable_common_interrupts(void __iomem *device_base) { 213isl38xx_enable_common_interrupts(void __iomem *device_base)
214{
215 u32 reg; 215 u32 reg;
216 reg = ( ISL38XX_INT_IDENT_UPDATE | 216
217 ISL38XX_INT_IDENT_SLEEP | ISL38XX_INT_IDENT_WAKEUP); 217 reg = ISL38XX_INT_IDENT_UPDATE | ISL38XX_INT_IDENT_SLEEP |
218 ISL38XX_INT_IDENT_WAKEUP;
218 isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG); 219 isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG);
219 udelay(ISL38XX_WRITEIO_DELAY); 220 udelay(ISL38XX_WRITEIO_DELAY);
220} 221}
@@ -234,23 +235,21 @@ isl38xx_in_queue(isl38xx_control_block *cb, int queue)
234 /* send queues */ 235 /* send queues */
235 case ISL38XX_CB_TX_MGMTQ: 236 case ISL38XX_CB_TX_MGMTQ:
236 BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE); 237 BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
238
237 case ISL38XX_CB_TX_DATA_LQ: 239 case ISL38XX_CB_TX_DATA_LQ:
238 case ISL38XX_CB_TX_DATA_HQ: 240 case ISL38XX_CB_TX_DATA_HQ:
239 BUG_ON(delta > ISL38XX_CB_TX_QSIZE); 241 BUG_ON(delta > ISL38XX_CB_TX_QSIZE);
240 return delta; 242 return delta;
241 break;
242 243
243 /* receive queues */ 244 /* receive queues */
244 case ISL38XX_CB_RX_MGMTQ: 245 case ISL38XX_CB_RX_MGMTQ:
245 BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE); 246 BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
246 return ISL38XX_CB_MGMT_QSIZE - delta; 247 return ISL38XX_CB_MGMT_QSIZE - delta;
247 break;
248 248
249 case ISL38XX_CB_RX_DATA_LQ: 249 case ISL38XX_CB_RX_DATA_LQ:
250 case ISL38XX_CB_RX_DATA_HQ: 250 case ISL38XX_CB_RX_DATA_HQ:
251 BUG_ON(delta > ISL38XX_CB_RX_QSIZE); 251 BUG_ON(delta > ISL38XX_CB_RX_QSIZE);
252 return ISL38XX_CB_RX_QSIZE - delta; 252 return ISL38XX_CB_RX_QSIZE - delta;
253 break;
254 } 253 }
255 BUG(); 254 BUG();
256 return 0; 255 return 0;
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index 8af20980af8d..3fadcb6f5297 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
@@ -67,10 +66,10 @@
67 * @base: (host) memory base address of the device 66 * @base: (host) memory base address of the device
68 * @val: 32bit value (host order) to write 67 * @val: 32bit value (host order) to write
69 * @offset: byte offset into @base to write value to 68 * @offset: byte offset into @base to write value to
70 * 69 *
71 * This helper takes care of writing a 32bit datum to the 70 * This helper takes care of writing a 32bit datum to the
72 * specified offset into the device's pci memory space, and making sure 71 * specified offset into the device's pci memory space, and making sure
73 * the pci memory buffers get flushed by performing one harmless read 72 * the pci memory buffers get flushed by performing one harmless read
74 * from the %ISL38XX_PCI_POSTING_FLUSH offset. 73 * from the %ISL38XX_PCI_POSTING_FLUSH offset.
75 */ 74 */
76static inline void 75static inline void
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index e7700b4257eb..a87eb51886c8 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * (C) 2003,2004 Aurelien Alleaume <slts@free.fr> 3 * (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
5 * (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> 4 * (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -55,12 +54,12 @@ static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
55 * prism54_mib_mode_helper - MIB change mode helper function 54 * prism54_mib_mode_helper - MIB change mode helper function
56 * @mib: the &struct islpci_mib object to modify 55 * @mib: the &struct islpci_mib object to modify
57 * @iw_mode: new mode (%IW_MODE_*) 56 * @iw_mode: new mode (%IW_MODE_*)
58 * 57 *
59 * This is a helper function, hence it does not lock. Make sure 58 * This is a helper function, hence it does not lock. Make sure
60 * caller deals with locking *if* necessary. This function sets the 59 * caller deals with locking *if* necessary. This function sets the
61 * mode-dependent mib values and does the mapping of the Linux 60 * mode-dependent mib values and does the mapping of the Linux
62 * Wireless API modes to Device firmware modes. It also checks for 61 * Wireless API modes to Device firmware modes. It also checks for
63 * correct valid Linux wireless modes. 62 * correct valid Linux wireless modes.
64 */ 63 */
65static int 64static int
66prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode) 65prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
@@ -118,7 +117,7 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
118 * 117 *
119 * this function initializes the struct given as @mib with defaults, 118 * this function initializes the struct given as @mib with defaults,
120 * of which many are retrieved from the global module parameter 119 * of which many are retrieved from the global module parameter
121 * variables. 120 * variables.
122 */ 121 */
123 122
124void 123void
@@ -134,7 +133,7 @@ prism54_mib_init(islpci_private *priv)
134 authen = CARD_DEFAULT_AUTHEN; 133 authen = CARD_DEFAULT_AUTHEN;
135 wep = CARD_DEFAULT_WEP; 134 wep = CARD_DEFAULT_WEP;
136 filter = CARD_DEFAULT_FILTER; /* (0) Do not filter un-encrypted data */ 135 filter = CARD_DEFAULT_FILTER; /* (0) Do not filter un-encrypted data */
137 dot1x = CARD_DEFAULT_DOT1X; 136 dot1x = CARD_DEFAULT_DOT1X;
138 mlme = CARD_DEFAULT_MLME_MODE; 137 mlme = CARD_DEFAULT_MLME_MODE;
139 conformance = CARD_DEFAULT_CONFORMANCE; 138 conformance = CARD_DEFAULT_CONFORMANCE;
140 power = 127; 139 power = 127;
@@ -229,7 +228,7 @@ prism54_get_wireless_stats(struct net_device *ndev)
229 } else 228 } else
230 priv->iwstatistics.qual.updated = 0; 229 priv->iwstatistics.qual.updated = 0;
231 230
232 /* Update our wireless stats, but do not schedule to often 231 /* Update our wireless stats, but do not schedule to often
233 * (max 1 HZ) */ 232 * (max 1 HZ) */
234 if ((priv->stats_timestamp == 0) || 233 if ((priv->stats_timestamp == 0) ||
235 time_after(jiffies, priv->stats_timestamp + 1 * HZ)) { 234 time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
@@ -706,7 +705,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
706 * Starting with WE-17, the buffer can be as big as needed. 705 * Starting with WE-17, the buffer can be as big as needed.
707 * But the device won't repport anything if you change the value 706 * But the device won't repport anything if you change the value
708 * of IWMAX_BSS=24. */ 707 * of IWMAX_BSS=24. */
709 708
710 rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r); 709 rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
711 bsslist = r.ptr; 710 bsslist = r.ptr;
712 711
@@ -786,7 +785,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
786 return rvalue; 785 return rvalue;
787} 786}
788 787
789/* Provides no functionality, just completes the ioctl. In essence this is a 788/* Provides no functionality, just completes the ioctl. In essence this is a
790 * just a cosmetic ioctl. 789 * just a cosmetic ioctl.
791 */ 790 */
792static int 791static int
@@ -1105,7 +1104,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
1105 &key); 1104 &key);
1106 } 1105 }
1107 /* 1106 /*
1108 * If a valid key is set, encryption should be enabled 1107 * If a valid key is set, encryption should be enabled
1109 * (user may turn it off later). 1108 * (user may turn it off later).
1110 * This is also how "iwconfig ethX key on" works 1109 * This is also how "iwconfig ethX key on" works
1111 */ 1110 */
@@ -1127,7 +1126,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
1127 } 1126 }
1128 /* now read the flags */ 1127 /* now read the flags */
1129 if (dwrq->flags & IW_ENCODE_DISABLED) { 1128 if (dwrq->flags & IW_ENCODE_DISABLED) {
1130 /* Encoding disabled, 1129 /* Encoding disabled,
1131 * authen = DOT11_AUTH_OS; 1130 * authen = DOT11_AUTH_OS;
1132 * invoke = 0; 1131 * invoke = 0;
1133 * exunencrypt = 0; */ 1132 * exunencrypt = 0; */
@@ -1215,7 +1214,7 @@ prism54_get_txpower(struct net_device *ndev, struct iw_request_info *info,
1215 vwrq->value = (s32) r.u / 4; 1214 vwrq->value = (s32) r.u / 4;
1216 vwrq->fixed = 1; 1215 vwrq->fixed = 1;
1217 /* radio is not turned of 1216 /* radio is not turned of
1218 * btw: how is possible to turn off only the radio 1217 * btw: how is possible to turn off only the radio
1219 */ 1218 */
1220 vwrq->disabled = 0; 1219 vwrq->disabled = 0;
1221 1220
@@ -2355,17 +2354,17 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
2355 handle_request(priv, mlme, oid); 2354 handle_request(priv, mlme, oid);
2356 send_formatted_event(priv, "Authenticate request (ex)", mlme, 1); 2355 send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
2357 2356
2358 if (priv->iw_mode != IW_MODE_MASTER 2357 if (priv->iw_mode != IW_MODE_MASTER
2359 && mlmeex->state != DOT11_STATE_AUTHING) 2358 && mlmeex->state != DOT11_STATE_AUTHING)
2360 break; 2359 break;
2361 2360
2362 confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC); 2361 confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
2363 2362
2364 if (!confirm) 2363 if (!confirm)
2365 break; 2364 break;
2366 2365
2367 memcpy(&confirm->address, mlmeex->address, ETH_ALEN); 2366 memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
2368 printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 2367 printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
2369 mlmeex->address[0], 2368 mlmeex->address[0],
2370 mlmeex->address[1], 2369 mlmeex->address[1],
2371 mlmeex->address[2], 2370 mlmeex->address[2],
@@ -2399,10 +2398,10 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
2399 handle_request(priv, mlme, oid); 2398 handle_request(priv, mlme, oid);
2400 send_formatted_event(priv, "Associate request (ex)", mlme, 1); 2399 send_formatted_event(priv, "Associate request (ex)", mlme, 1);
2401 2400
2402 if (priv->iw_mode != IW_MODE_MASTER 2401 if (priv->iw_mode != IW_MODE_MASTER
2403 && mlmeex->state != DOT11_STATE_ASSOCING) 2402 && mlmeex->state != DOT11_STATE_ASSOCING)
2404 break; 2403 break;
2405 2404
2406 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC); 2405 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
2407 2406
2408 if (!confirm) 2407 if (!confirm)
@@ -2418,7 +2417,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
2418 2417
2419 if (!wpa_ie_len) { 2418 if (!wpa_ie_len) {
2420 printk(KERN_DEBUG "No WPA IE found from " 2419 printk(KERN_DEBUG "No WPA IE found from "
2421 "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 2420 "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
2422 mlmeex->address[0], 2421 mlmeex->address[0],
2423 mlmeex->address[1], 2422 mlmeex->address[1],
2424 mlmeex->address[2], 2423 mlmeex->address[2],
@@ -2436,14 +2435,14 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
2436 mgt_set_varlen(priv, oid, confirm, wpa_ie_len); 2435 mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
2437 2436
2438 kfree(confirm); 2437 kfree(confirm);
2439 2438
2440 break; 2439 break;
2441 2440
2442 case DOT11_OID_REASSOCIATEEX: 2441 case DOT11_OID_REASSOCIATEEX:
2443 handle_request(priv, mlme, oid); 2442 handle_request(priv, mlme, oid);
2444 send_formatted_event(priv, "Reassociate request (ex)", mlme, 1); 2443 send_formatted_event(priv, "Reassociate request (ex)", mlme, 1);
2445 2444
2446 if (priv->iw_mode != IW_MODE_MASTER 2445 if (priv->iw_mode != IW_MODE_MASTER
2447 && mlmeex->state != DOT11_STATE_ASSOCING) 2446 && mlmeex->state != DOT11_STATE_ASSOCING)
2448 break; 2447 break;
2449 2448
@@ -2462,7 +2461,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
2462 2461
2463 if (!wpa_ie_len) { 2462 if (!wpa_ie_len) {
2464 printk(KERN_DEBUG "No WPA IE found from " 2463 printk(KERN_DEBUG "No WPA IE found from "
2465 "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 2464 "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
2466 mlmeex->address[0], 2465 mlmeex->address[0],
2467 mlmeex->address[1], 2466 mlmeex->address[1],
2468 mlmeex->address[2], 2467 mlmeex->address[2],
@@ -2474,13 +2473,13 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
2474 break; 2473 break;
2475 } 2474 }
2476 2475
2477 confirm->size = wpa_ie_len; 2476 confirm->size = wpa_ie_len;
2478 memcpy(&confirm->data, wpa_ie, wpa_ie_len); 2477 memcpy(&confirm->data, wpa_ie, wpa_ie_len);
2479 2478
2480 mgt_set_varlen(priv, oid, confirm, wpa_ie_len); 2479 mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
2481 2480
2482 kfree(confirm); 2481 kfree(confirm);
2483 2482
2484 break; 2483 break;
2485 2484
2486 default: 2485 default:
@@ -2547,10 +2546,10 @@ enum {
2547#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ 2546#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
2548((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data)) 2547((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
2549 2548
2550/* Maximum length for algorithm names (-1 for nul termination) 2549/* Maximum length for algorithm names (-1 for nul termination)
2551 * used in ioctl() */ 2550 * used in ioctl() */
2552#define HOSTAP_CRYPT_ALG_NAME_LEN 16 2551#define HOSTAP_CRYPT_ALG_NAME_LEN 16
2553 2552
2554struct prism2_hostapd_param { 2553struct prism2_hostapd_param {
2555 u32 cmd; 2554 u32 cmd;
2556 u8 sta_addr[ETH_ALEN]; 2555 u8 sta_addr[ETH_ALEN];
@@ -2623,7 +2622,7 @@ prism2_ioctl_set_encryption(struct net_device *dev,
2623 &key); 2622 &key);
2624 } 2623 }
2625 /* 2624 /*
2626 * If a valid key is set, encryption should be enabled 2625 * If a valid key is set, encryption should be enabled
2627 * (user may turn it off later). 2626 * (user may turn it off later).
2628 * This is also how "iwconfig ethX key on" works 2627 * This is also how "iwconfig ethX key on" works
2629 */ 2628 */
@@ -2645,7 +2644,7 @@ prism2_ioctl_set_encryption(struct net_device *dev,
2645 } 2644 }
2646 /* now read the flags */ 2645 /* now read the flags */
2647 if (param->u.crypt.flags & IW_ENCODE_DISABLED) { 2646 if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
2648 /* Encoding disabled, 2647 /* Encoding disabled,
2649 * authen = DOT11_AUTH_OS; 2648 * authen = DOT11_AUTH_OS;
2650 * invoke = 0; 2649 * invoke = 0;
2651 * exunencrypt = 0; */ 2650 * exunencrypt = 0; */
@@ -2712,7 +2711,7 @@ prism2_ioctl_set_generic_element(struct net_device *ndev,
2712 2711
2713 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len); 2712 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
2714 2713
2715 if (ret == 0) 2714 if (ret == 0)
2716 printk(KERN_DEBUG "%s: WPA IE Attachment was set\n", 2715 printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
2717 ndev->name); 2716 ndev->name);
2718 } 2717 }
@@ -2872,7 +2871,7 @@ prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
2872 mlme = DOT11_MLME_AUTO; 2871 mlme = DOT11_MLME_AUTO;
2873 printk("%s: Disabling WPA\n", ndev->name); 2872 printk("%s: Disabling WPA\n", ndev->name);
2874 break; 2873 break;
2875 case 2: 2874 case 2:
2876 case 1: /* WPA */ 2875 case 1: /* WPA */
2877 printk("%s: Enabling WPA\n", ndev->name); 2876 printk("%s: Enabling WPA\n", ndev->name);
2878 break; 2877 break;
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index 0802fa64996f..bcfbfb9281d2 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * (C) 2003 Aurelien Alleaume <slts@free.fr> 3 * (C) 2003 Aurelien Alleaume <slts@free.fr>
5 * (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> 4 * (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index 419edf7ccf1a..b7534c2869c8 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -1,6 +1,4 @@
1/* 1/*
2 *
3 *
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> 2 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 * Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> 3 * Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> 4 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
@@ -23,7 +21,7 @@
23#if !defined(_ISL_OID_H) 21#if !defined(_ISL_OID_H)
24#define _ISL_OID_H 22#define _ISL_OID_H
25 23
26/* 24/*
27 * MIB related constant and structure definitions for communicating 25 * MIB related constant and structure definitions for communicating
28 * with the device firmware 26 * with the device firmware
29 */ 27 */
@@ -99,21 +97,21 @@ struct obj_attachment {
99 char data[0]; 97 char data[0];
100} __attribute__((packed)); 98} __attribute__((packed));
101 99
102/* 100/*
103 * in case everything's ok, the inlined function below will be 101 * in case everything's ok, the inlined function below will be
104 * optimized away by the compiler... 102 * optimized away by the compiler...
105 */ 103 */
106static inline void 104static inline void
107__bug_on_wrong_struct_sizes(void) 105__bug_on_wrong_struct_sizes(void)
108{ 106{
109 BUG_ON(sizeof (struct obj_ssid) != 34); 107 BUILD_BUG_ON(sizeof (struct obj_ssid) != 34);
110 BUG_ON(sizeof (struct obj_key) != 34); 108 BUILD_BUG_ON(sizeof (struct obj_key) != 34);
111 BUG_ON(sizeof (struct obj_mlme) != 12); 109 BUILD_BUG_ON(sizeof (struct obj_mlme) != 12);
112 BUG_ON(sizeof (struct obj_mlmeex) != 14); 110 BUILD_BUG_ON(sizeof (struct obj_mlmeex) != 14);
113 BUG_ON(sizeof (struct obj_buffer) != 8); 111 BUILD_BUG_ON(sizeof (struct obj_buffer) != 8);
114 BUG_ON(sizeof (struct obj_bss) != 60); 112 BUILD_BUG_ON(sizeof (struct obj_bss) != 60);
115 BUG_ON(sizeof (struct obj_bsslist) != 4); 113 BUILD_BUG_ON(sizeof (struct obj_bsslist) != 4);
116 BUG_ON(sizeof (struct obj_frequencies) != 2); 114 BUILD_BUG_ON(sizeof (struct obj_frequencies) != 2);
117} 115}
118 116
119enum dot11_state_t { 117enum dot11_state_t {
@@ -154,13 +152,13 @@ enum dot11_priv_t {
154 152
155/* Prism "Nitro" / Frameburst / "Packet Frame Grouping" 153/* Prism "Nitro" / Frameburst / "Packet Frame Grouping"
156 * Value is in microseconds. Represents the # microseconds 154 * Value is in microseconds. Represents the # microseconds
157 * the firmware will take to group frames before sending out then out 155 * the firmware will take to group frames before sending out then out
158 * together with a CSMA contention. Without this all frames are 156 * together with a CSMA contention. Without this all frames are
159 * sent with a CSMA contention. 157 * sent with a CSMA contention.
160 * Bibliography: 158 * Bibliography:
161 * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Papers/Packet.Frame.Grouping.html 159 * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Papers/Packet.Frame.Grouping.html
162 */ 160 */
163enum dot11_maxframeburst_t { 161enum dot11_maxframeburst_t {
164 /* Values for DOT11_OID_MAXFRAMEBURST */ 162 /* Values for DOT11_OID_MAXFRAMEBURST */
165 DOT11_MAXFRAMEBURST_OFF = 0, /* Card firmware default */ 163 DOT11_MAXFRAMEBURST_OFF = 0, /* Card firmware default */
166 DOT11_MAXFRAMEBURST_MIXED_SAFE = 650, /* 802.11 a,b,g safe */ 164 DOT11_MAXFRAMEBURST_MIXED_SAFE = 650, /* 802.11 a,b,g safe */
@@ -176,9 +174,9 @@ enum dot11_maxframeburst_t {
176/* Support for 802.11 long and short frame preambles. 174/* Support for 802.11 long and short frame preambles.
177 * Long preamble uses 128-bit sync field, 8-bit CRC 175 * Long preamble uses 128-bit sync field, 8-bit CRC
178 * Short preamble uses 56-bit sync field, 16-bit CRC 176 * Short preamble uses 56-bit sync field, 16-bit CRC
179 * 177 *
180 * 802.11a -- not sure, both optionally ? 178 * 802.11a -- not sure, both optionally ?
181 * 802.11b supports long and optionally short 179 * 802.11b supports long and optionally short
182 * 802.11g supports both */ 180 * 802.11g supports both */
183enum dot11_preamblesettings_t { 181enum dot11_preamblesettings_t {
184 DOT11_PREAMBLESETTING_LONG = 0, 182 DOT11_PREAMBLESETTING_LONG = 0,
@@ -194,7 +192,7 @@ enum dot11_preamblesettings_t {
194 * Long uses 802.11a slot timing (9 usec ?) 192 * Long uses 802.11a slot timing (9 usec ?)
195 * Short uses 802.11b slot timing (20 use ?) */ 193 * Short uses 802.11b slot timing (20 use ?) */
196enum dot11_slotsettings_t { 194enum dot11_slotsettings_t {
197 DOT11_SLOTSETTINGS_LONG = 0, 195 DOT11_SLOTSETTINGS_LONG = 0,
198 /* Allows *only* long 802.11b slot timing */ 196 /* Allows *only* long 802.11b slot timing */
199 DOT11_SLOTSETTINGS_SHORT = 1, 197 DOT11_SLOTSETTINGS_SHORT = 1,
200 /* Allows *only* long 802.11a slot timing */ 198 /* Allows *only* long 802.11a slot timing */
@@ -203,7 +201,7 @@ enum dot11_slotsettings_t {
203}; 201};
204 202
205/* All you need to know, ERP is "Extended Rate PHY". 203/* All you need to know, ERP is "Extended Rate PHY".
206 * An Extended Rate PHY (ERP) STA or AP shall support three different 204 * An Extended Rate PHY (ERP) STA or AP shall support three different
207 * preamble and header formats: 205 * preamble and header formats:
208 * Long preamble (refer to above) 206 * Long preamble (refer to above)
209 * Short preamble (refer to above) 207 * Short preamble (refer to above)
@@ -221,7 +219,7 @@ enum do11_nonerpstatus_t {
221/* (ERP is "Extended Rate PHY") Way to read NONERP is NON-ERP-* 219/* (ERP is "Extended Rate PHY") Way to read NONERP is NON-ERP-*
222 * The key here is DOT11 NON ERP NEVER protects against 220 * The key here is DOT11 NON ERP NEVER protects against
223 * NON ERP STA's. You *don't* want this unless 221 * NON ERP STA's. You *don't* want this unless
224 * you know what you are doing. It means you will only 222 * you know what you are doing. It means you will only
225 * get Extended Rate capabilities */ 223 * get Extended Rate capabilities */
226enum dot11_nonerpprotection_t { 224enum dot11_nonerpprotection_t {
227 DOT11_NONERP_NEVER = 0, 225 DOT11_NONERP_NEVER = 0,
@@ -229,13 +227,13 @@ enum dot11_nonerpprotection_t {
229 DOT11_NONERP_DYNAMIC = 2 227 DOT11_NONERP_DYNAMIC = 2
230}; 228};
231 229
232/* Preset OID configuration for 802.11 modes 230/* Preset OID configuration for 802.11 modes
233 * Note: DOT11_OID_CW[MIN|MAX] hold the values of the 231 * Note: DOT11_OID_CW[MIN|MAX] hold the values of the
234 * DCS MIN|MAX backoff used */ 232 * DCS MIN|MAX backoff used */
235enum dot11_profile_t { /* And set/allowed values */ 233enum dot11_profile_t { /* And set/allowed values */
236 /* Allowed values for DOT11_OID_PROFILES */ 234 /* Allowed values for DOT11_OID_PROFILES */
237 DOT11_PROFILE_B_ONLY = 0, 235 DOT11_PROFILE_B_ONLY = 0,
238 /* DOT11_OID_RATES: 1, 2, 5.5, 11Mbps 236 /* DOT11_OID_RATES: 1, 2, 5.5, 11Mbps
239 * DOT11_OID_PREAMBLESETTINGS: DOT11_PREAMBLESETTING_DYNAMIC 237 * DOT11_OID_PREAMBLESETTINGS: DOT11_PREAMBLESETTING_DYNAMIC
240 * DOT11_OID_CWMIN: 31 238 * DOT11_OID_CWMIN: 31
241 * DOT11_OID_NONEPROTECTION: DOT11_NOERP_DYNAMIC 239 * DOT11_OID_NONEPROTECTION: DOT11_NOERP_DYNAMIC
@@ -275,7 +273,7 @@ enum oid_inl_conformance_t {
275 OID_INL_CONFORMANCE_NONE = 0, /* Perform active scanning */ 273 OID_INL_CONFORMANCE_NONE = 0, /* Perform active scanning */
276 OID_INL_CONFORMANCE_STRICT = 1, /* Strictly adhere to 802.11d */ 274 OID_INL_CONFORMANCE_STRICT = 1, /* Strictly adhere to 802.11d */
277 OID_INL_CONFORMANCE_FLEXIBLE = 2, /* Use passed 802.11d info to 275 OID_INL_CONFORMANCE_FLEXIBLE = 2, /* Use passed 802.11d info to
278 * determine channel AND/OR just make assumption that active 276 * determine channel AND/OR just make assumption that active
279 * channels are valid channels */ 277 * channels are valid channels */
280}; 278};
281 279
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index e35fcb2543c4..f057fd9fcd79 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> 3 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> 4 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -413,7 +412,7 @@ prism54_bring_down(islpci_private *priv)
413 islpci_set_state(priv, PRV_STATE_PREBOOT); 412 islpci_set_state(priv, PRV_STATE_PREBOOT);
414 413
415 /* disable all device interrupts in case they weren't */ 414 /* disable all device interrupts in case they weren't */
416 isl38xx_disable_interrupts(priv->device_base); 415 isl38xx_disable_interrupts(priv->device_base);
417 416
418 /* For safety reasons, we may want to ensure that no DMA transfer is 417 /* For safety reasons, we may want to ensure that no DMA transfer is
419 * currently in progress by emptying the TX and RX queues. */ 418 * currently in progress by emptying the TX and RX queues. */
@@ -480,7 +479,7 @@ islpci_reset_if(islpci_private *priv)
480 479
481 DEFINE_WAIT(wait); 480 DEFINE_WAIT(wait);
482 prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE); 481 prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE);
483 482
484 /* now the last step is to reset the interface */ 483 /* now the last step is to reset the interface */
485 isl38xx_interface_reset(priv->device_base, priv->device_host_address); 484 isl38xx_interface_reset(priv->device_base, priv->device_host_address);
486 islpci_set_state(priv, PRV_STATE_PREINIT); 485 islpci_set_state(priv, PRV_STATE_PREINIT);
@@ -488,7 +487,7 @@ islpci_reset_if(islpci_private *priv)
488 for(count = 0; count < 2 && result; count++) { 487 for(count = 0; count < 2 && result; count++) {
489 /* The software reset acknowledge needs about 220 msec here. 488 /* The software reset acknowledge needs about 220 msec here.
490 * Be conservative and wait for up to one second. */ 489 * Be conservative and wait for up to one second. */
491 490
492 remaining = schedule_timeout_uninterruptible(HZ); 491 remaining = schedule_timeout_uninterruptible(HZ);
493 492
494 if(remaining > 0) { 493 if(remaining > 0) {
@@ -496,7 +495,7 @@ islpci_reset_if(islpci_private *priv)
496 break; 495 break;
497 } 496 }
498 497
499 /* If we're here it's because our IRQ hasn't yet gone through. 498 /* If we're here it's because our IRQ hasn't yet gone through.
500 * Retry a bit more... 499 * Retry a bit more...
501 */ 500 */
502 printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n", 501 printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n",
@@ -514,7 +513,7 @@ islpci_reset_if(islpci_private *priv)
514 513
515 /* Now that the device is 100% up, let's allow 514 /* Now that the device is 100% up, let's allow
516 * for the other interrupts -- 515 * for the other interrupts --
517 * NOTE: this is not *yet* true since we've only allowed the 516 * NOTE: this is not *yet* true since we've only allowed the
518 * INIT interrupt on the IRQ line. We can perhaps poll 517 * INIT interrupt on the IRQ line. We can perhaps poll
519 * the IRQ line until we know for sure the reset went through */ 518 * the IRQ line until we know for sure the reset went through */
520 isl38xx_enable_common_interrupts(priv->device_base); 519 isl38xx_enable_common_interrupts(priv->device_base);
@@ -716,7 +715,7 @@ islpci_alloc_memory(islpci_private *priv)
716 715
717 prism54_acl_init(&priv->acl); 716 prism54_acl_init(&priv->acl);
718 prism54_wpa_bss_ie_init(priv); 717 prism54_wpa_bss_ie_init(priv);
719 if (mgt_init(priv)) 718 if (mgt_init(priv))
720 goto out_free; 719 goto out_free;
721 720
722 return 0; 721 return 0;
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 2f7e525d0cf6..a9aa1662eaa4 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * 2 * Copyright (C) 2002 Intersil Americas Inc.
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> 3 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> 4 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
6 * Copyright (C) 2003 Aurelien Alleaume <slts@free.fr> 5 * Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
@@ -72,12 +71,12 @@ struct islpci_bss_wpa_ie {
72 u8 bssid[ETH_ALEN]; 71 u8 bssid[ETH_ALEN];
73 u8 wpa_ie[MAX_WPA_IE_LEN]; 72 u8 wpa_ie[MAX_WPA_IE_LEN];
74 size_t wpa_ie_len; 73 size_t wpa_ie_len;
75 74
76}; 75};
77 76
78typedef struct { 77typedef struct {
79 spinlock_t slock; /* generic spinlock; */ 78 spinlock_t slock; /* generic spinlock; */
80 79
81 u32 priv_oid; 80 u32 priv_oid;
82 81
83 /* our mib cache */ 82 /* our mib cache */
@@ -85,7 +84,7 @@ typedef struct {
85 struct rw_semaphore mib_sem; 84 struct rw_semaphore mib_sem;
86 void **mib; 85 void **mib;
87 char nickname[IW_ESSID_MAX_SIZE+1]; 86 char nickname[IW_ESSID_MAX_SIZE+1];
88 87
89 /* Take care of the wireless stats */ 88 /* Take care of the wireless stats */
90 struct work_struct stats_work; 89 struct work_struct stats_work;
91 struct semaphore stats_sem; 90 struct semaphore stats_sem;
@@ -120,7 +119,7 @@ typedef struct {
120 struct net_device *ndev; 119 struct net_device *ndev;
121 120
122 /* device queue interface members */ 121 /* device queue interface members */
123 struct isl38xx_cb *control_block; /* device control block 122 struct isl38xx_cb *control_block; /* device control block
124 (== driver_mem_address!) */ 123 (== driver_mem_address!) */
125 124
126 /* Each queue has three indexes: 125 /* Each queue has three indexes:
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 103a37877733..b1122912ee2d 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> 3 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
@@ -48,7 +47,7 @@ islpci_eth_cleanup_transmit(islpci_private *priv,
48 /* read the index of the first fragment to be freed */ 47 /* read the index of the first fragment to be freed */
49 index = priv->free_data_tx % ISL38XX_CB_TX_QSIZE; 48 index = priv->free_data_tx % ISL38XX_CB_TX_QSIZE;
50 49
51 /* check for holes in the arrays caused by multi fragment frames 50 /* check for holes in the arrays caused by multi fragment frames
52 * searching for the last fragment of a frame */ 51 * searching for the last fragment of a frame */
53 if (priv->pci_map_tx_address[index] != (dma_addr_t) NULL) { 52 if (priv->pci_map_tx_address[index] != (dma_addr_t) NULL) {
54 /* entry is the last fragment of a frame 53 /* entry is the last fragment of a frame
@@ -253,6 +252,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
253 * header and without the FCS. But there a is a bit that 252 * header and without the FCS. But there a is a bit that
254 * indicates if the packet is corrupted :-) */ 253 * indicates if the packet is corrupted :-) */
255 struct rfmon_header *hdr = (struct rfmon_header *) (*skb)->data; 254 struct rfmon_header *hdr = (struct rfmon_header *) (*skb)->data;
255
256 if (hdr->flags & 0x01) 256 if (hdr->flags & 0x01)
257 /* This one is bad. Drop it ! */ 257 /* This one is bad. Drop it ! */
258 return -1; 258 return -1;
@@ -284,7 +284,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
284 (struct avs_80211_1_header *) skb_push(*skb, 284 (struct avs_80211_1_header *) skb_push(*skb,
285 sizeof (struct 285 sizeof (struct
286 avs_80211_1_header)); 286 avs_80211_1_header));
287 287
288 avs->version = cpu_to_be32(P80211CAPTURE_VERSION); 288 avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
289 avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); 289 avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
290 avs->mactime = cpu_to_be64(le64_to_cpu(clock)); 290 avs->mactime = cpu_to_be64(le64_to_cpu(clock));
@@ -390,7 +390,7 @@ islpci_eth_receive(islpci_private *priv)
390 struct rx_annex_header *annex = 390 struct rx_annex_header *annex =
391 (struct rx_annex_header *) skb->data; 391 (struct rx_annex_header *) skb->data;
392 wstats.level = annex->rfmon.rssi; 392 wstats.level = annex->rfmon.rssi;
393 /* The noise value can be a bit outdated if nobody's 393 /* The noise value can be a bit outdated if nobody's
394 * reading wireless stats... */ 394 * reading wireless stats... */
395 wstats.noise = priv->local_iwstatistics.qual.noise; 395 wstats.noise = priv->local_iwstatistics.qual.noise;
396 wstats.qual = wstats.level - wstats.noise; 396 wstats.qual = wstats.level - wstats.noise;
@@ -464,10 +464,8 @@ islpci_eth_receive(islpci_private *priv)
464 break; 464 break;
465 } 465 }
466 /* update the fragment address */ 466 /* update the fragment address */
467 control_block->rx_data_low[index].address = cpu_to_le32((u32) 467 control_block->rx_data_low[index].address =
468 priv-> 468 cpu_to_le32((u32)priv->pci_map_rx_address[index]);
469 pci_map_rx_address
470 [index]);
471 wmb(); 469 wmb();
472 470
473 /* increment the driver read pointer */ 471 /* increment the driver read pointer */
@@ -485,9 +483,11 @@ void
485islpci_do_reset_and_wake(struct work_struct *work) 483islpci_do_reset_and_wake(struct work_struct *work)
486{ 484{
487 islpci_private *priv = container_of(work, islpci_private, reset_task); 485 islpci_private *priv = container_of(work, islpci_private, reset_task);
486
488 islpci_reset(priv, 1); 487 islpci_reset(priv, 1);
489 netif_wake_queue(priv->ndev);
490 priv->reset_task_pending = 0; 488 priv->reset_task_pending = 0;
489 smp_wmb();
490 netif_wake_queue(priv->ndev);
491} 491}
492 492
493void 493void
@@ -499,12 +499,14 @@ islpci_eth_tx_timeout(struct net_device *ndev)
499 /* increment the transmit error counter */ 499 /* increment the transmit error counter */
500 statistics->tx_errors++; 500 statistics->tx_errors++;
501 501
502 printk(KERN_WARNING "%s: tx_timeout", ndev->name);
503 if (!priv->reset_task_pending) { 502 if (!priv->reset_task_pending) {
504 priv->reset_task_pending = 1; 503 printk(KERN_WARNING
505 printk(", scheduling a reset"); 504 "%s: tx_timeout, scheduling reset", ndev->name);
506 netif_stop_queue(ndev); 505 netif_stop_queue(ndev);
506 priv->reset_task_pending = 1;
507 schedule_work(&priv->reset_task); 507 schedule_work(&priv->reset_task);
508 } else {
509 printk(KERN_WARNING
510 "%s: tx_timeout, waiting for reset", ndev->name);
508 } 511 }
509 printk("\n");
510} 512}
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
index 99d37eda9f01..5bf820defbd0 100644
--- a/drivers/net/wireless/prism54/islpci_eth.h
+++ b/drivers/net/wireless/prism54/islpci_eth.h
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index f692dccf0d07..58257b40c043 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> 3 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 * 4 *
@@ -40,8 +39,8 @@ static int init_pcitm = 0;
40module_param(init_pcitm, int, 0); 39module_param(init_pcitm, int, 0);
41 40
42/* In this order: vendor, device, subvendor, subdevice, class, class_mask, 41/* In this order: vendor, device, subvendor, subdevice, class, class_mask,
43 * driver_data 42 * driver_data
44 * If you have an update for this please contact prism54-devel@prism54.org 43 * If you have an update for this please contact prism54-devel@prism54.org
45 * The latest list can be found at http://prism54.org/supported_cards.php */ 44 * The latest list can be found at http://prism54.org/supported_cards.php */
46static const struct pci_device_id prism54_id_tbl[] = { 45static const struct pci_device_id prism54_id_tbl[] = {
47 /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */ 46 /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
@@ -132,15 +131,15 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
132 131
133 /* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT) 132 /* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT)
134 * 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT) 133 * 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT)
135 * The RETRY_TIMEOUT is used to set the number of retries that the core, as a 134 * The RETRY_TIMEOUT is used to set the number of retries that the core, as a
136 * Master, will perform before abandoning a cycle. The default value for 135 * Master, will perform before abandoning a cycle. The default value for
137 * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new 136 * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new
138 * devices. A write of zero to the RETRY_TIMEOUT register disables this 137 * devices. A write of zero to the RETRY_TIMEOUT register disables this
139 * function to allow use with any non-compliant legacy devices that may 138 * function to allow use with any non-compliant legacy devices that may
140 * execute more retries. 139 * execute more retries.
141 * 140 *
142 * Writing zero to both these two registers will disable both timeouts and 141 * Writing zero to both these two registers will disable both timeouts and
143 * *can* solve problems caused by devices that are slow to respond. 142 * *can* solve problems caused by devices that are slow to respond.
144 * Make this configurable - MSW 143 * Make this configurable - MSW
145 */ 144 */
146 if ( init_pcitm >= 0 ) { 145 if ( init_pcitm >= 0 ) {
@@ -171,14 +170,15 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
171 pci_set_master(pdev); 170 pci_set_master(pdev);
172 171
173 /* enable MWI */ 172 /* enable MWI */
174 pci_set_mwi(pdev); 173 if (!pci_set_mwi(pdev))
174 printk(KERN_INFO "%s: pci_set_mwi(pdev) succeeded\n", DRV_NAME);
175 175
176 /* setup the network device interface and its structure */ 176 /* setup the network device interface and its structure */
177 if (!(ndev = islpci_setup(pdev))) { 177 if (!(ndev = islpci_setup(pdev))) {
178 /* error configuring the driver as a network device */ 178 /* error configuring the driver as a network device */
179 printk(KERN_ERR "%s: could not configure network device\n", 179 printk(KERN_ERR "%s: could not configure network device\n",
180 DRV_NAME); 180 DRV_NAME);
181 goto do_pci_release_regions; 181 goto do_pci_clear_mwi;
182 } 182 }
183 183
184 priv = netdev_priv(ndev); 184 priv = netdev_priv(ndev);
@@ -208,6 +208,8 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
208 pci_set_drvdata(pdev, NULL); 208 pci_set_drvdata(pdev, NULL);
209 free_netdev(ndev); 209 free_netdev(ndev);
210 priv = NULL; 210 priv = NULL;
211 do_pci_clear_mwi:
212 pci_clear_mwi(pdev);
211 do_pci_release_regions: 213 do_pci_release_regions:
212 pci_release_regions(pdev); 214 pci_release_regions(pdev);
213 do_pci_disable_device: 215 do_pci_disable_device:
@@ -241,7 +243,7 @@ prism54_remove(struct pci_dev *pdev)
241 isl38xx_disable_interrupts(priv->device_base); 243 isl38xx_disable_interrupts(priv->device_base);
242 islpci_set_state(priv, PRV_STATE_OFF); 244 islpci_set_state(priv, PRV_STATE_OFF);
243 /* This bellow causes a lockup at rmmod time. It might be 245 /* This bellow causes a lockup at rmmod time. It might be
244 * because some interrupts still linger after rmmod time, 246 * because some interrupts still linger after rmmod time,
245 * see bug #17 */ 247 * see bug #17 */
246 /* pci_set_power_state(pdev, 3);*/ /* try to power-off */ 248 /* pci_set_power_state(pdev, 3);*/ /* try to power-off */
247 } 249 }
@@ -255,6 +257,8 @@ prism54_remove(struct pci_dev *pdev)
255 free_netdev(ndev); 257 free_netdev(ndev);
256 priv = NULL; 258 priv = NULL;
257 259
260 pci_clear_mwi(pdev);
261
258 pci_release_regions(pdev); 262 pci_release_regions(pdev);
259 263
260 pci_disable_device(pdev); 264 pci_disable_device(pdev);
@@ -288,12 +292,19 @@ prism54_resume(struct pci_dev *pdev)
288{ 292{
289 struct net_device *ndev = pci_get_drvdata(pdev); 293 struct net_device *ndev = pci_get_drvdata(pdev);
290 islpci_private *priv = ndev ? netdev_priv(ndev) : NULL; 294 islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
291 BUG_ON(!priv); 295 int err;
292 296
293 pci_enable_device(pdev); 297 BUG_ON(!priv);
294 298
295 printk(KERN_NOTICE "%s: got resume request\n", ndev->name); 299 printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
296 300
301 err = pci_enable_device(pdev);
302 if (err) {
303 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
304 ndev->name);
305 return err;
306 }
307
297 pci_restore_state(pdev); 308 pci_restore_state(pdev);
298 309
299 /* alright let's go into the PREBOOT state */ 310 /* alright let's go into the PREBOOT state */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 656ec9fa7128..2246f7930b4e 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net> 3 * Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net>
5 * 4 *
@@ -502,7 +501,7 @@ islpci_mgt_transaction(struct net_device *ndev,
502 printk(KERN_WARNING "%s: timeout waiting for mgmt response\n", 501 printk(KERN_WARNING "%s: timeout waiting for mgmt response\n",
503 ndev->name); 502 ndev->name);
504 503
505 /* TODO: we should reset the device here */ 504 /* TODO: we should reset the device here */
506 out: 505 out:
507 finish_wait(&priv->mgmt_wqueue, &wait); 506 finish_wait(&priv->mgmt_wqueue, &wait);
508 up(&priv->mgmt_sem); 507 up(&priv->mgmt_sem);
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
index 2982be3363ef..fc53b587b722 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.h
+++ b/drivers/net/wireless/prism54/islpci_mgt.h
@@ -1,5 +1,4 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc. 2 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> 3 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
5 * 4 *
@@ -36,8 +35,8 @@ extern int pc_debug;
36 35
37 36
38/* General driver definitions */ 37/* General driver definitions */
39#define PCIDEVICE_LATENCY_TIMER_MIN 0x40 38#define PCIDEVICE_LATENCY_TIMER_MIN 0x40
40#define PCIDEVICE_LATENCY_TIMER_VAL 0x50 39#define PCIDEVICE_LATENCY_TIMER_VAL 0x50
41 40
42/* Debugging verbose definitions */ 41/* Debugging verbose definitions */
43#define SHOW_NOTHING 0x00 /* overrules everything */ 42#define SHOW_NOTHING 0x00 /* overrules everything */
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index ebb238785839..fbc52b6a3024 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2003,2004 Aurelien Alleaume <slts@free.fr> 2 * Copyright (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
@@ -503,7 +503,7 @@ mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len
503 } 503 }
504 if (ret || response_op == PIMFOR_OP_ERROR) 504 if (ret || response_op == PIMFOR_OP_ERROR)
505 ret = -EIO; 505 ret = -EIO;
506 } else 506 } else
507 ret = -EIO; 507 ret = -EIO;
508 508
509 /* re-set given data to what it was */ 509 /* re-set given data to what it was */
@@ -727,7 +727,7 @@ mgt_commit(islpci_private *priv)
727 * MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL 727 * MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL
728 * FREQUENCY,EXTENDEDRATES. 728 * FREQUENCY,EXTENDEDRATES.
729 * 729 *
730 * The way to do this is to set ESSID. Note though that they may get 730 * The way to do this is to set ESSID. Note though that they may get
731 * unlatch before though by setting another OID. */ 731 * unlatch before though by setting another OID. */
732#if 0 732#if 0
733void 733void
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
index d71eca55a302..aa1d1747784f 100644
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ b/drivers/net/wireless/prism54/prismcompat.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * (C) 2004 Margit Schubert-While <margitsw@t-online.de> 2 * (C) 2004 Margit Schubert-While <margitsw@t-online.de>
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
@@ -16,7 +16,7 @@
16 * 16 *
17 */ 17 */
18 18
19/* 19/*
20 * Compatibility header file to aid support of different kernel versions 20 * Compatibility header file to aid support of different kernel versions
21 */ 21 */
22 22
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 36b29ff05814..6cb66a356c96 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1828,10 +1828,8 @@ err_start:
1828 /* Leave the device in reset state */ 1828 /* Leave the device in reset state */
1829 zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0); 1829 zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
1830err_zd: 1830err_zd:
1831 if (zd->tx_urb) 1831 usb_free_urb(zd->tx_urb);
1832 usb_free_urb(zd->tx_urb); 1832 usb_free_urb(zd->rx_urb);
1833 if (zd->rx_urb)
1834 usb_free_urb(zd->rx_urb);
1835 kfree(zd); 1833 kfree(zd);
1836 return err; 1834 return err;
1837} 1835}
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index aa661b2b76c7..8be99ebbe1cd 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1076,6 +1076,31 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
1076 return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); 1076 return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
1077} 1077}
1078 1078
1079int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
1080 u8 rts_rate, int preamble)
1081{
1082 int rts_mod = ZD_RX_CCK;
1083 u32 value = 0;
1084
1085 /* Modulation bit */
1086 if (ZD_CS_TYPE(rts_rate) == ZD_CS_OFDM)
1087 rts_mod = ZD_RX_OFDM;
1088
1089 dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n",
1090 rts_rate, preamble);
1091
1092 value |= rts_rate << RTSCTS_SH_RTS_RATE;
1093 value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE;
1094 value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
1095 value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;
1096
1097 /* We always send 11M self-CTS messages, like the vendor driver. */
1098 value |= ZD_CCK_RATE_11M << RTSCTS_SH_CTS_RATE;
1099 value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;
1100
1101 return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE);
1102}
1103
1079int zd_chip_enable_hwint(struct zd_chip *chip) 1104int zd_chip_enable_hwint(struct zd_chip *chip)
1080{ 1105{
1081 int r; 1106 int r;
@@ -1355,17 +1380,12 @@ out:
1355 return r; 1380 return r;
1356} 1381}
1357 1382
1358int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) 1383int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates)
1359{ 1384{
1360 int r; 1385 ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
1361 1386 dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
1362 if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
1363 return -EINVAL;
1364 1387
1365 mutex_lock(&chip->mutex); 1388 return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
1366 r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
1367 mutex_unlock(&chip->mutex);
1368 return r;
1369} 1389}
1370 1390
1371static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) 1391static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index ae59597ce4e1..ca892b9a6448 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -337,24 +337,24 @@
337#define CR_MAC_PS_STATE CTL_REG(0x050C) 337#define CR_MAC_PS_STATE CTL_REG(0x050C)
338 338
339#define CR_INTERRUPT CTL_REG(0x0510) 339#define CR_INTERRUPT CTL_REG(0x0510)
340#define INT_TX_COMPLETE 0x00000001 340#define INT_TX_COMPLETE (1 << 0)
341#define INT_RX_COMPLETE 0x00000002 341#define INT_RX_COMPLETE (1 << 1)
342#define INT_RETRY_FAIL 0x00000004 342#define INT_RETRY_FAIL (1 << 2)
343#define INT_WAKEUP 0x00000008 343#define INT_WAKEUP (1 << 3)
344#define INT_DTIM_NOTIFY 0x00000020 344#define INT_DTIM_NOTIFY (1 << 5)
345#define INT_CFG_NEXT_BCN 0x00000040 345#define INT_CFG_NEXT_BCN (1 << 6)
346#define INT_BUS_ABORT 0x00000080 346#define INT_BUS_ABORT (1 << 7)
347#define INT_TX_FIFO_READY 0x00000100 347#define INT_TX_FIFO_READY (1 << 8)
348#define INT_UART 0x00000200 348#define INT_UART (1 << 9)
349#define INT_TX_COMPLETE_EN 0x00010000 349#define INT_TX_COMPLETE_EN (1 << 16)
350#define INT_RX_COMPLETE_EN 0x00020000 350#define INT_RX_COMPLETE_EN (1 << 17)
351#define INT_RETRY_FAIL_EN 0x00040000 351#define INT_RETRY_FAIL_EN (1 << 18)
352#define INT_WAKEUP_EN 0x00080000 352#define INT_WAKEUP_EN (1 << 19)
353#define INT_DTIM_NOTIFY_EN 0x00200000 353#define INT_DTIM_NOTIFY_EN (1 << 21)
354#define INT_CFG_NEXT_BCN_EN 0x00400000 354#define INT_CFG_NEXT_BCN_EN (1 << 22)
355#define INT_BUS_ABORT_EN 0x00800000 355#define INT_BUS_ABORT_EN (1 << 23)
356#define INT_TX_FIFO_READY_EN 0x01000000 356#define INT_TX_FIFO_READY_EN (1 << 24)
357#define INT_UART_EN 0x02000000 357#define INT_UART_EN (1 << 25)
358 358
359#define CR_TSF_LOW_PART CTL_REG(0x0514) 359#define CR_TSF_LOW_PART CTL_REG(0x0514)
360#define CR_TSF_HIGH_PART CTL_REG(0x0518) 360#define CR_TSF_HIGH_PART CTL_REG(0x0518)
@@ -398,18 +398,18 @@
398 * device will use a rate in this table that is less than or equal to the rate 398 * device will use a rate in this table that is less than or equal to the rate
399 * of the incoming frame which prompted the response */ 399 * of the incoming frame which prompted the response */
400#define CR_BASIC_RATE_TBL CTL_REG(0x0630) 400#define CR_BASIC_RATE_TBL CTL_REG(0x0630)
401#define CR_RATE_1M 0x0001 /* 802.11b */ 401#define CR_RATE_1M (1 << 0) /* 802.11b */
402#define CR_RATE_2M 0x0002 /* 802.11b */ 402#define CR_RATE_2M (1 << 1) /* 802.11b */
403#define CR_RATE_5_5M 0x0004 /* 802.11b */ 403#define CR_RATE_5_5M (1 << 2) /* 802.11b */
404#define CR_RATE_11M 0x0008 /* 802.11b */ 404#define CR_RATE_11M (1 << 3) /* 802.11b */
405#define CR_RATE_6M 0x0100 /* 802.11g */ 405#define CR_RATE_6M (1 << 8) /* 802.11g */
406#define CR_RATE_9M 0x0200 /* 802.11g */ 406#define CR_RATE_9M (1 << 9) /* 802.11g */
407#define CR_RATE_12M 0x0400 /* 802.11g */ 407#define CR_RATE_12M (1 << 10) /* 802.11g */
408#define CR_RATE_18M 0x0800 /* 802.11g */ 408#define CR_RATE_18M (1 << 11) /* 802.11g */
409#define CR_RATE_24M 0x1000 /* 802.11g */ 409#define CR_RATE_24M (1 << 12) /* 802.11g */
410#define CR_RATE_36M 0x2000 /* 802.11g */ 410#define CR_RATE_36M (1 << 13) /* 802.11g */
411#define CR_RATE_48M 0x4000 /* 802.11g */ 411#define CR_RATE_48M (1 << 14) /* 802.11g */
412#define CR_RATE_54M 0x8000 /* 802.11g */ 412#define CR_RATE_54M (1 << 15) /* 802.11g */
413#define CR_RATES_80211G 0xff00 413#define CR_RATES_80211G 0xff00
414#define CR_RATES_80211B 0x000f 414#define CR_RATES_80211B 0x000f
415 415
@@ -420,15 +420,24 @@
420#define CR_MANDATORY_RATE_TBL CTL_REG(0x0634) 420#define CR_MANDATORY_RATE_TBL CTL_REG(0x0634)
421#define CR_RTS_CTS_RATE CTL_REG(0x0638) 421#define CR_RTS_CTS_RATE CTL_REG(0x0638)
422 422
423/* These are all bit indexes in CR_RTS_CTS_RATE, so remember to shift. */
424#define RTSCTS_SH_RTS_RATE 0
425#define RTSCTS_SH_EXP_CTS_RATE 4
426#define RTSCTS_SH_RTS_MOD_TYPE 8
427#define RTSCTS_SH_RTS_PMB_TYPE 9
428#define RTSCTS_SH_CTS_RATE 16
429#define RTSCTS_SH_CTS_MOD_TYPE 24
430#define RTSCTS_SH_CTS_PMB_TYPE 25
431
423#define CR_WEP_PROTECT CTL_REG(0x063C) 432#define CR_WEP_PROTECT CTL_REG(0x063C)
424#define CR_RX_THRESHOLD CTL_REG(0x0640) 433#define CR_RX_THRESHOLD CTL_REG(0x0640)
425 434
426/* register for controlling the LEDS */ 435/* register for controlling the LEDS */
427#define CR_LED CTL_REG(0x0644) 436#define CR_LED CTL_REG(0x0644)
428/* masks for controlling LEDs */ 437/* masks for controlling LEDs */
429#define LED1 0x0100 438#define LED1 (1 << 8)
430#define LED2 0x0200 439#define LED2 (1 << 9)
431#define LED_SW 0x0400 440#define LED_SW (1 << 10)
432 441
433/* Seems to indicate that the configuration is over. 442/* Seems to indicate that the configuration is over.
434 */ 443 */
@@ -455,18 +464,18 @@
455 * registers, so one could argue it is a LOCK bit. But calling it 464 * registers, so one could argue it is a LOCK bit. But calling it
456 * LOCK_PHY_REGS makes it confusing. 465 * LOCK_PHY_REGS makes it confusing.
457 */ 466 */
458#define UNLOCK_PHY_REGS 0x0080 467#define UNLOCK_PHY_REGS (1 << 7)
459 468
460#define CR_DEVICE_STATE CTL_REG(0x0684) 469#define CR_DEVICE_STATE CTL_REG(0x0684)
461#define CR_UNDERRUN_CNT CTL_REG(0x0688) 470#define CR_UNDERRUN_CNT CTL_REG(0x0688)
462 471
463#define CR_RX_FILTER CTL_REG(0x068c) 472#define CR_RX_FILTER CTL_REG(0x068c)
464#define RX_FILTER_ASSOC_RESPONSE 0x0002 473#define RX_FILTER_ASSOC_RESPONSE (1 << 1)
465#define RX_FILTER_REASSOC_RESPONSE 0x0008 474#define RX_FILTER_REASSOC_RESPONSE (1 << 3)
466#define RX_FILTER_PROBE_RESPONSE 0x0020 475#define RX_FILTER_PROBE_RESPONSE (1 << 5)
467#define RX_FILTER_BEACON 0x0100 476#define RX_FILTER_BEACON (1 << 8)
468#define RX_FILTER_DISASSOC 0x0400 477#define RX_FILTER_DISASSOC (1 << 10)
469#define RX_FILTER_AUTH 0x0800 478#define RX_FILTER_AUTH (1 << 11)
470#define AP_RX_FILTER 0x0400feff 479#define AP_RX_FILTER 0x0400feff
471#define STA_RX_FILTER 0x0000ffff 480#define STA_RX_FILTER 0x0000ffff
472 481
@@ -794,6 +803,9 @@ void zd_chip_disable_rx(struct zd_chip *chip);
794int zd_chip_enable_hwint(struct zd_chip *chip); 803int zd_chip_enable_hwint(struct zd_chip *chip);
795int zd_chip_disable_hwint(struct zd_chip *chip); 804int zd_chip_disable_hwint(struct zd_chip *chip);
796 805
806int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
807 u8 rts_rate, int preamble);
808
797static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) 809static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type)
798{ 810{
799 return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type); 811 return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type);
@@ -809,7 +821,17 @@ static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates)
809 return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates); 821 return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates);
810} 822}
811 823
812int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates); 824int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates);
825
826static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
827{
828 int r;
829
830 mutex_lock(&chip->mutex);
831 r = zd_chip_set_basic_rates_locked(chip, cr_rates);
832 mutex_unlock(&chip->mutex);
833 return r;
834}
813 835
814static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter) 836static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter)
815{ 837{
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index a13ec72eb304..fb22f62cf1f3 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -39,6 +39,7 @@ do { \
39 if (!(x)) { \ 39 if (!(x)) { \
40 pr_debug("%s:%d ASSERT %s VIOLATED!\n", \ 40 pr_debug("%s:%d ASSERT %s VIOLATED!\n", \
41 __FILE__, __LINE__, __stringify(x)); \ 41 __FILE__, __LINE__, __stringify(x)); \
42 dump_stack(); \
42 } \ 43 } \
43} while (0) 44} while (0)
44#else 45#else
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.c b/drivers/net/wireless/zd1211rw/zd_ieee80211.c
index 66905f7b61ff..189160efd2ae 100644
--- a/drivers/net/wireless/zd1211rw/zd_ieee80211.c
+++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.c
@@ -37,7 +37,12 @@ static const struct channel_range channel_ranges[] = {
37 [ZD_REGDOMAIN_JAPAN] = { 1, 14}, 37 [ZD_REGDOMAIN_JAPAN] = { 1, 14},
38 [ZD_REGDOMAIN_SPAIN] = { 1, 14}, 38 [ZD_REGDOMAIN_SPAIN] = { 1, 14},
39 [ZD_REGDOMAIN_FRANCE] = { 1, 14}, 39 [ZD_REGDOMAIN_FRANCE] = { 1, 14},
40 [ZD_REGDOMAIN_JAPAN_ADD] = {14, 15}, 40
41 /* Japan originally only had channel 14 available (see CHNL_ID 0x40 in
42 * 802.11). However, in 2001 the range was extended to include channels
43 * 1-13. The ZyDAS devices still use the old region code but are
44 * designed to allow the extra channel access in Japan. */
45 [ZD_REGDOMAIN_JAPAN_ADD] = { 1, 15},
41}; 46};
42 47
43const struct channel_range *zd_channel_range(u8 regdomain) 48const struct channel_range *zd_channel_range(u8 regdomain)
@@ -133,9 +138,6 @@ int zd_find_channel(u8 *channel, const struct iw_freq *freq)
133 int i, r; 138 int i, r;
134 u32 mhz; 139 u32 mhz;
135 140
136 if (!(freq->flags & IW_FREQ_FIXED))
137 return 0;
138
139 if (freq->m < 1000) { 141 if (freq->m < 1000) {
140 if (freq->m > NUM_CHANNELS || freq->m == 0) 142 if (freq->m > NUM_CHANNELS || freq->m == 0)
141 return -EINVAL; 143 return -EINVAL;
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.h b/drivers/net/wireless/zd1211rw/zd_ieee80211.h
index f63245b0d966..26b8298dff8c 100644
--- a/drivers/net/wireless/zd1211rw/zd_ieee80211.h
+++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.h
@@ -50,6 +50,7 @@ static inline u8 zd_ofdm_plcp_header_rate(
50 return header->prefix[0] & 0xf; 50 return header->prefix[0] & 0xf;
51} 51}
52 52
53/* These are referred to as zd_rates */
53#define ZD_OFDM_RATE_6M 0xb 54#define ZD_OFDM_RATE_6M 0xb
54#define ZD_OFDM_RATE_9M 0xf 55#define ZD_OFDM_RATE_9M 0xf
55#define ZD_OFDM_RATE_12M 0xa 56#define ZD_OFDM_RATE_12M 0xa
@@ -64,7 +65,7 @@ struct cck_plcp_header {
64 u8 service; 65 u8 service;
65 __le16 length; 66 __le16 length;
66 __le16 crc16; 67 __le16 crc16;
67}; 68} __attribute__((packed));
68 69
69static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header) 70static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header)
70{ 71{
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 5e4f4b707375..44f3cfd4cc1d 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -32,6 +32,8 @@
32 32
33static void ieee_init(struct ieee80211_device *ieee); 33static void ieee_init(struct ieee80211_device *ieee);
34static void softmac_init(struct ieee80211softmac_device *sm); 34static void softmac_init(struct ieee80211softmac_device *sm);
35static void set_rts_cts_work(void *d);
36static void set_basic_rates_work(void *d);
35 37
36static void housekeeping_init(struct zd_mac *mac); 38static void housekeeping_init(struct zd_mac *mac);
37static void housekeeping_enable(struct zd_mac *mac); 39static void housekeeping_enable(struct zd_mac *mac);
@@ -46,6 +48,8 @@ int zd_mac_init(struct zd_mac *mac,
46 memset(mac, 0, sizeof(*mac)); 48 memset(mac, 0, sizeof(*mac));
47 spin_lock_init(&mac->lock); 49 spin_lock_init(&mac->lock);
48 mac->netdev = netdev; 50 mac->netdev = netdev;
51 INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work, mac);
52 INIT_WORK(&mac->set_basic_rates_work, set_basic_rates_work, mac);
49 53
50 ieee_init(ieee); 54 ieee_init(ieee);
51 softmac_init(ieee80211_priv(netdev)); 55 softmac_init(ieee80211_priv(netdev));
@@ -213,6 +217,13 @@ int zd_mac_stop(struct net_device *netdev)
213 housekeeping_disable(mac); 217 housekeeping_disable(mac);
214 ieee80211softmac_stop(netdev); 218 ieee80211softmac_stop(netdev);
215 219
220 /* Ensure no work items are running or queued from this point */
221 cancel_delayed_work(&mac->set_rts_cts_work);
222 cancel_delayed_work(&mac->set_basic_rates_work);
223 flush_workqueue(zd_workqueue);
224 mac->updating_rts_rate = 0;
225 mac->updating_basic_rates = 0;
226
216 zd_chip_disable_hwint(chip); 227 zd_chip_disable_hwint(chip);
217 zd_chip_switch_radio_off(chip); 228 zd_chip_switch_radio_off(chip);
218 zd_chip_disable_int(chip); 229 zd_chip_disable_int(chip);
@@ -286,6 +297,186 @@ u8 zd_mac_get_regdomain(struct zd_mac *mac)
286 return regdomain; 297 return regdomain;
287} 298}
288 299
300/* Fallback to lowest rate, if rate is unknown. */
301static u8 rate_to_zd_rate(u8 rate)
302{
303 switch (rate) {
304 case IEEE80211_CCK_RATE_2MB:
305 return ZD_CCK_RATE_2M;
306 case IEEE80211_CCK_RATE_5MB:
307 return ZD_CCK_RATE_5_5M;
308 case IEEE80211_CCK_RATE_11MB:
309 return ZD_CCK_RATE_11M;
310 case IEEE80211_OFDM_RATE_6MB:
311 return ZD_OFDM_RATE_6M;
312 case IEEE80211_OFDM_RATE_9MB:
313 return ZD_OFDM_RATE_9M;
314 case IEEE80211_OFDM_RATE_12MB:
315 return ZD_OFDM_RATE_12M;
316 case IEEE80211_OFDM_RATE_18MB:
317 return ZD_OFDM_RATE_18M;
318 case IEEE80211_OFDM_RATE_24MB:
319 return ZD_OFDM_RATE_24M;
320 case IEEE80211_OFDM_RATE_36MB:
321 return ZD_OFDM_RATE_36M;
322 case IEEE80211_OFDM_RATE_48MB:
323 return ZD_OFDM_RATE_48M;
324 case IEEE80211_OFDM_RATE_54MB:
325 return ZD_OFDM_RATE_54M;
326 }
327 return ZD_CCK_RATE_1M;
328}
329
330static u16 rate_to_cr_rate(u8 rate)
331{
332 switch (rate) {
333 case IEEE80211_CCK_RATE_2MB:
334 return CR_RATE_1M;
335 case IEEE80211_CCK_RATE_5MB:
336 return CR_RATE_5_5M;
337 case IEEE80211_CCK_RATE_11MB:
338 return CR_RATE_11M;
339 case IEEE80211_OFDM_RATE_6MB:
340 return CR_RATE_6M;
341 case IEEE80211_OFDM_RATE_9MB:
342 return CR_RATE_9M;
343 case IEEE80211_OFDM_RATE_12MB:
344 return CR_RATE_12M;
345 case IEEE80211_OFDM_RATE_18MB:
346 return CR_RATE_18M;
347 case IEEE80211_OFDM_RATE_24MB:
348 return CR_RATE_24M;
349 case IEEE80211_OFDM_RATE_36MB:
350 return CR_RATE_36M;
351 case IEEE80211_OFDM_RATE_48MB:
352 return CR_RATE_48M;
353 case IEEE80211_OFDM_RATE_54MB:
354 return CR_RATE_54M;
355 }
356 return CR_RATE_1M;
357}
358
359static void try_enable_tx(struct zd_mac *mac)
360{
361 unsigned long flags;
362
363 spin_lock_irqsave(&mac->lock, flags);
364 if (mac->updating_rts_rate == 0 && mac->updating_basic_rates == 0)
365 netif_wake_queue(mac->netdev);
366 spin_unlock_irqrestore(&mac->lock, flags);
367}
368
369static void set_rts_cts_work(void *d)
370{
371 struct zd_mac *mac = d;
372 unsigned long flags;
373 u8 rts_rate;
374 unsigned int short_preamble;
375
376 mutex_lock(&mac->chip.mutex);
377
378 spin_lock_irqsave(&mac->lock, flags);
379 mac->updating_rts_rate = 0;
380 rts_rate = mac->rts_rate;
381 short_preamble = mac->short_preamble;
382 spin_unlock_irqrestore(&mac->lock, flags);
383
384 zd_chip_set_rts_cts_rate_locked(&mac->chip, rts_rate, short_preamble);
385 mutex_unlock(&mac->chip.mutex);
386
387 try_enable_tx(mac);
388}
389
390static void set_basic_rates_work(void *d)
391{
392 struct zd_mac *mac = d;
393 unsigned long flags;
394 u16 basic_rates;
395
396 mutex_lock(&mac->chip.mutex);
397
398 spin_lock_irqsave(&mac->lock, flags);
399 mac->updating_basic_rates = 0;
400 basic_rates = mac->basic_rates;
401 spin_unlock_irqrestore(&mac->lock, flags);
402
403 zd_chip_set_basic_rates_locked(&mac->chip, basic_rates);
404 mutex_unlock(&mac->chip.mutex);
405
406 try_enable_tx(mac);
407}
408
409static void bssinfo_change(struct net_device *netdev, u32 changes)
410{
411 struct zd_mac *mac = zd_netdev_mac(netdev);
412 struct ieee80211softmac_device *softmac = ieee80211_priv(netdev);
413 struct ieee80211softmac_bss_info *bssinfo = &softmac->bssinfo;
414 int need_set_rts_cts = 0;
415 int need_set_rates = 0;
416 u16 basic_rates;
417 unsigned long flags;
418
419 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
420
421 if (changes & IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE) {
422 spin_lock_irqsave(&mac->lock, flags);
423 mac->short_preamble = bssinfo->short_preamble;
424 spin_unlock_irqrestore(&mac->lock, flags);
425 need_set_rts_cts = 1;
426 }
427
428 if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) {
429 /* Set RTS rate to highest available basic rate */
430 u8 rate = ieee80211softmac_highest_supported_rate(softmac,
431 &bssinfo->supported_rates, 1);
432 rate = rate_to_zd_rate(rate);
433
434 spin_lock_irqsave(&mac->lock, flags);
435 if (rate != mac->rts_rate) {
436 mac->rts_rate = rate;
437 need_set_rts_cts = 1;
438 }
439 spin_unlock_irqrestore(&mac->lock, flags);
440
441 /* Set basic rates */
442 need_set_rates = 1;
443 if (bssinfo->supported_rates.count == 0) {
444 /* Allow the device to be flexible */
445 basic_rates = CR_RATES_80211B | CR_RATES_80211G;
446 } else {
447 int i = 0;
448 basic_rates = 0;
449
450 for (i = 0; i < bssinfo->supported_rates.count; i++) {
451 u16 rate = bssinfo->supported_rates.rates[i];
452 if ((rate & IEEE80211_BASIC_RATE_MASK) == 0)
453 continue;
454
455 rate &= ~IEEE80211_BASIC_RATE_MASK;
456 basic_rates |= rate_to_cr_rate(rate);
457 }
458 }
459 spin_lock_irqsave(&mac->lock, flags);
460 mac->basic_rates = basic_rates;
461 spin_unlock_irqrestore(&mac->lock, flags);
462 }
463
464 /* Schedule any changes we made above */
465
466 spin_lock_irqsave(&mac->lock, flags);
467 if (need_set_rts_cts && !mac->updating_rts_rate) {
468 mac->updating_rts_rate = 1;
469 netif_stop_queue(mac->netdev);
470 queue_work(zd_workqueue, &mac->set_rts_cts_work);
471 }
472 if (need_set_rates && !mac->updating_basic_rates) {
473 mac->updating_basic_rates = 1;
474 netif_stop_queue(mac->netdev);
475 queue_work(zd_workqueue, &mac->set_basic_rates_work);
476 }
477 spin_unlock_irqrestore(&mac->lock, flags);
478}
479
289static void set_channel(struct net_device *netdev, u8 channel) 480static void set_channel(struct net_device *netdev, u8 channel)
290{ 481{
291 struct zd_mac *mac = zd_netdev_mac(netdev); 482 struct zd_mac *mac = zd_netdev_mac(netdev);
@@ -295,7 +486,6 @@ static void set_channel(struct net_device *netdev, u8 channel)
295 zd_chip_set_channel(&mac->chip, channel); 486 zd_chip_set_channel(&mac->chip, channel);
296} 487}
297 488
298/* TODO: Should not work in Managed mode. */
299int zd_mac_request_channel(struct zd_mac *mac, u8 channel) 489int zd_mac_request_channel(struct zd_mac *mac, u8 channel)
300{ 490{
301 unsigned long lock_flags; 491 unsigned long lock_flags;
@@ -317,31 +507,22 @@ int zd_mac_request_channel(struct zd_mac *mac, u8 channel)
317 return 0; 507 return 0;
318} 508}
319 509
320int zd_mac_get_channel(struct zd_mac *mac, u8 *channel, u8 *flags) 510u8 zd_mac_get_channel(struct zd_mac *mac)
321{ 511{
322 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); 512 u8 channel = zd_chip_get_channel(&mac->chip);
323 513
324 *channel = zd_chip_get_channel(&mac->chip); 514 dev_dbg_f(zd_mac_dev(mac), "channel %u\n", channel);
325 if (ieee->iw_mode != IW_MODE_INFRA) { 515 return channel;
326 spin_lock_irq(&mac->lock);
327 *flags = *channel == mac->requested_channel ?
328 MAC_FIXED_CHANNEL : 0;
329 spin_unlock(&mac->lock);
330 } else {
331 *flags = 0;
332 }
333 dev_dbg_f(zd_mac_dev(mac), "channel %u flags %u\n", *channel, *flags);
334 return 0;
335} 516}
336 517
337/* If wrong rate is given, we are falling back to the slowest rate: 1MBit/s */ 518/* If wrong rate is given, we are falling back to the slowest rate: 1MBit/s */
338static u8 cs_typed_rate(u8 cs_rate) 519static u8 zd_rate_typed(u8 zd_rate)
339{ 520{
340 static const u8 typed_rates[16] = { 521 static const u8 typed_rates[16] = {
341 [ZD_CS_CCK_RATE_1M] = ZD_CS_CCK|ZD_CS_CCK_RATE_1M, 522 [ZD_CCK_RATE_1M] = ZD_CS_CCK|ZD_CCK_RATE_1M,
342 [ZD_CS_CCK_RATE_2M] = ZD_CS_CCK|ZD_CS_CCK_RATE_2M, 523 [ZD_CCK_RATE_2M] = ZD_CS_CCK|ZD_CCK_RATE_2M,
343 [ZD_CS_CCK_RATE_5_5M] = ZD_CS_CCK|ZD_CS_CCK_RATE_5_5M, 524 [ZD_CCK_RATE_5_5M] = ZD_CS_CCK|ZD_CCK_RATE_5_5M,
344 [ZD_CS_CCK_RATE_11M] = ZD_CS_CCK|ZD_CS_CCK_RATE_11M, 525 [ZD_CCK_RATE_11M] = ZD_CS_CCK|ZD_CCK_RATE_11M,
345 [ZD_OFDM_RATE_6M] = ZD_CS_OFDM|ZD_OFDM_RATE_6M, 526 [ZD_OFDM_RATE_6M] = ZD_CS_OFDM|ZD_OFDM_RATE_6M,
346 [ZD_OFDM_RATE_9M] = ZD_CS_OFDM|ZD_OFDM_RATE_9M, 527 [ZD_OFDM_RATE_9M] = ZD_CS_OFDM|ZD_OFDM_RATE_9M,
347 [ZD_OFDM_RATE_12M] = ZD_CS_OFDM|ZD_OFDM_RATE_12M, 528 [ZD_OFDM_RATE_12M] = ZD_CS_OFDM|ZD_OFDM_RATE_12M,
@@ -353,37 +534,7 @@ static u8 cs_typed_rate(u8 cs_rate)
353 }; 534 };
354 535
355 ZD_ASSERT(ZD_CS_RATE_MASK == 0x0f); 536 ZD_ASSERT(ZD_CS_RATE_MASK == 0x0f);
356 return typed_rates[cs_rate & ZD_CS_RATE_MASK]; 537 return typed_rates[zd_rate & ZD_CS_RATE_MASK];
357}
358
359/* Fallback to lowest rate, if rate is unknown. */
360static u8 rate_to_cs_rate(u8 rate)
361{
362 switch (rate) {
363 case IEEE80211_CCK_RATE_2MB:
364 return ZD_CS_CCK_RATE_2M;
365 case IEEE80211_CCK_RATE_5MB:
366 return ZD_CS_CCK_RATE_5_5M;
367 case IEEE80211_CCK_RATE_11MB:
368 return ZD_CS_CCK_RATE_11M;
369 case IEEE80211_OFDM_RATE_6MB:
370 return ZD_OFDM_RATE_6M;
371 case IEEE80211_OFDM_RATE_9MB:
372 return ZD_OFDM_RATE_9M;
373 case IEEE80211_OFDM_RATE_12MB:
374 return ZD_OFDM_RATE_12M;
375 case IEEE80211_OFDM_RATE_18MB:
376 return ZD_OFDM_RATE_18M;
377 case IEEE80211_OFDM_RATE_24MB:
378 return ZD_OFDM_RATE_24M;
379 case IEEE80211_OFDM_RATE_36MB:
380 return ZD_OFDM_RATE_36M;
381 case IEEE80211_OFDM_RATE_48MB:
382 return ZD_OFDM_RATE_48M;
383 case IEEE80211_OFDM_RATE_54MB:
384 return ZD_OFDM_RATE_54M;
385 }
386 return ZD_CS_CCK_RATE_1M;
387} 538}
388 539
389int zd_mac_set_mode(struct zd_mac *mac, u32 mode) 540int zd_mac_set_mode(struct zd_mac *mac, u32 mode)
@@ -484,13 +635,13 @@ int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range)
484 return 0; 635 return 0;
485} 636}
486 637
487static int zd_calc_tx_length_us(u8 *service, u8 cs_rate, u16 tx_length) 638static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length)
488{ 639{
489 static const u8 rate_divisor[] = { 640 static const u8 rate_divisor[] = {
490 [ZD_CS_CCK_RATE_1M] = 1, 641 [ZD_CCK_RATE_1M] = 1,
491 [ZD_CS_CCK_RATE_2M] = 2, 642 [ZD_CCK_RATE_2M] = 2,
492 [ZD_CS_CCK_RATE_5_5M] = 11, /* bits must be doubled */ 643 [ZD_CCK_RATE_5_5M] = 11, /* bits must be doubled */
493 [ZD_CS_CCK_RATE_11M] = 11, 644 [ZD_CCK_RATE_11M] = 11,
494 [ZD_OFDM_RATE_6M] = 6, 645 [ZD_OFDM_RATE_6M] = 6,
495 [ZD_OFDM_RATE_9M] = 9, 646 [ZD_OFDM_RATE_9M] = 9,
496 [ZD_OFDM_RATE_12M] = 12, 647 [ZD_OFDM_RATE_12M] = 12,
@@ -504,15 +655,15 @@ static int zd_calc_tx_length_us(u8 *service, u8 cs_rate, u16 tx_length)
504 u32 bits = (u32)tx_length * 8; 655 u32 bits = (u32)tx_length * 8;
505 u32 divisor; 656 u32 divisor;
506 657
507 divisor = rate_divisor[cs_rate]; 658 divisor = rate_divisor[zd_rate];
508 if (divisor == 0) 659 if (divisor == 0)
509 return -EINVAL; 660 return -EINVAL;
510 661
511 switch (cs_rate) { 662 switch (zd_rate) {
512 case ZD_CS_CCK_RATE_5_5M: 663 case ZD_CCK_RATE_5_5M:
513 bits = (2*bits) + 10; /* round up to the next integer */ 664 bits = (2*bits) + 10; /* round up to the next integer */
514 break; 665 break;
515 case ZD_CS_CCK_RATE_11M: 666 case ZD_CCK_RATE_11M:
516 if (service) { 667 if (service) {
517 u32 t = bits % 11; 668 u32 t = bits % 11;
518 *service &= ~ZD_PLCP_SERVICE_LENGTH_EXTENSION; 669 *service &= ~ZD_PLCP_SERVICE_LENGTH_EXTENSION;
@@ -532,16 +683,16 @@ enum {
532 R2M_11A = 0x02, 683 R2M_11A = 0x02,
533}; 684};
534 685
535static u8 cs_rate_to_modulation(u8 cs_rate, int flags) 686static u8 zd_rate_to_modulation(u8 zd_rate, int flags)
536{ 687{
537 u8 modulation; 688 u8 modulation;
538 689
539 modulation = cs_typed_rate(cs_rate); 690 modulation = zd_rate_typed(zd_rate);
540 if (flags & R2M_SHORT_PREAMBLE) { 691 if (flags & R2M_SHORT_PREAMBLE) {
541 switch (ZD_CS_RATE(modulation)) { 692 switch (ZD_CS_RATE(modulation)) {
542 case ZD_CS_CCK_RATE_2M: 693 case ZD_CCK_RATE_2M:
543 case ZD_CS_CCK_RATE_5_5M: 694 case ZD_CCK_RATE_5_5M:
544 case ZD_CS_CCK_RATE_11M: 695 case ZD_CCK_RATE_11M:
545 modulation |= ZD_CS_CCK_PREA_SHORT; 696 modulation |= ZD_CS_CCK_PREA_SHORT;
546 return modulation; 697 return modulation;
547 } 698 }
@@ -558,39 +709,36 @@ static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs,
558{ 709{
559 struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); 710 struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev);
560 u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl)); 711 u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl));
561 u8 rate, cs_rate; 712 u8 rate, zd_rate;
562 int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0; 713 int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0;
714 int is_multicast = is_multicast_ether_addr(hdr->addr1);
715 int short_preamble = ieee80211softmac_short_preamble_ok(softmac,
716 is_multicast, is_mgt);
717 int flags = 0;
718
719 /* FIXME: 802.11a? */
720 rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt);
563 721
564 /* FIXME: 802.11a? short preamble? */ 722 if (short_preamble)
565 rate = ieee80211softmac_suggest_txrate(softmac, 723 flags |= R2M_SHORT_PREAMBLE;
566 is_multicast_ether_addr(hdr->addr1), is_mgt);
567 724
568 cs_rate = rate_to_cs_rate(rate); 725 zd_rate = rate_to_zd_rate(rate);
569 cs->modulation = cs_rate_to_modulation(cs_rate, 0); 726 cs->modulation = zd_rate_to_modulation(zd_rate, flags);
570} 727}
571 728
572static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, 729static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
573 struct ieee80211_hdr_4addr *header) 730 struct ieee80211_hdr_4addr *header)
574{ 731{
732 struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev);
575 unsigned int tx_length = le16_to_cpu(cs->tx_length); 733 unsigned int tx_length = le16_to_cpu(cs->tx_length);
576 u16 fctl = le16_to_cpu(header->frame_ctl); 734 u16 fctl = le16_to_cpu(header->frame_ctl);
577 u16 ftype = WLAN_FC_GET_TYPE(fctl); 735 u16 ftype = WLAN_FC_GET_TYPE(fctl);
578 u16 stype = WLAN_FC_GET_STYPE(fctl); 736 u16 stype = WLAN_FC_GET_STYPE(fctl);
579 737
580 /* 738 /*
581 * CONTROL: 739 * CONTROL TODO:
582 * - start at 0x00
583 * - if fragment 0, enable bit 0
584 * - if backoff needed, enable bit 0 740 * - if backoff needed, enable bit 0
585 * - if burst (backoff not needed) disable bit 0 741 * - if burst (backoff not needed) disable bit 0
586 * - if multicast, enable bit 1
587 * - if PS-POLL frame, enable bit 2
588 * - if in INDEPENDENT_BSS mode and zd1205_DestPowerSave, then enable
589 * bit 4 (FIXME: wtf)
590 * - if frag_len > RTS threshold, set bit 5 as long if it isnt
591 * multicast or mgt
592 * - if bit 5 is set, and we are in OFDM mode, unset bit 5 and set bit
593 * 7
594 */ 742 */
595 743
596 cs->control = 0; 744 cs->control = 0;
@@ -607,17 +755,18 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
607 if (stype == IEEE80211_STYPE_PSPOLL) 755 if (stype == IEEE80211_STYPE_PSPOLL)
608 cs->control |= ZD_CS_PS_POLL_FRAME; 756 cs->control |= ZD_CS_PS_POLL_FRAME;
609 757
758 /* Unicast data frames over the threshold should have RTS */
610 if (!is_multicast_ether_addr(header->addr1) && 759 if (!is_multicast_ether_addr(header->addr1) &&
611 ftype != IEEE80211_FTYPE_MGMT && 760 ftype != IEEE80211_FTYPE_MGMT &&
612 tx_length > zd_netdev_ieee80211(mac->netdev)->rts) 761 tx_length > zd_netdev_ieee80211(mac->netdev)->rts)
613 { 762 cs->control |= ZD_CS_RTS;
614 /* FIXME: check the logic */ 763
615 if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM) { 764 /* Use CTS-to-self protection if required */
616 /* 802.11g */ 765 if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM &&
617 cs->control |= ZD_CS_SELF_CTS; 766 ieee80211softmac_protection_needed(softmac)) {
618 } else { /* 802.11b */ 767 /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */
619 cs->control |= ZD_CS_RTS; 768 cs->control &= ~ZD_CS_RTS;
620 } 769 cs->control |= ZD_CS_SELF_CTS;
621 } 770 }
622 771
623 /* FIXME: Management frame? */ 772 /* FIXME: Management frame? */
@@ -721,7 +870,7 @@ struct zd_rt_hdr {
721 u8 rt_rate; 870 u8 rt_rate;
722 u16 rt_channel; 871 u16 rt_channel;
723 u16 rt_chbitmask; 872 u16 rt_chbitmask;
724}; 873} __attribute__((packed));
725 874
726static void fill_rt_header(void *buffer, struct zd_mac *mac, 875static void fill_rt_header(void *buffer, struct zd_mac *mac,
727 const struct ieee80211_rx_stats *stats, 876 const struct ieee80211_rx_stats *stats,
@@ -782,9 +931,11 @@ static int is_data_packet_for_us(struct ieee80211_device *ieee,
782 (netdev->flags & IFF_PROMISC); 931 (netdev->flags & IFF_PROMISC);
783} 932}
784 933
785/* Filters receiving packets. If it returns 1 send it to ieee80211_rx, if 0 934/* Filters received packets. The function returns 1 if the packet should be
786 * return. If an error is detected -EINVAL is returned. ieee80211_rx_mgt() is 935 * forwarded to ieee80211_rx(). If the packet should be ignored the function
787 * called here. 936 * returns 0. If an invalid packet is found the function returns -EINVAL.
937 *
938 * The function calls ieee80211_rx_mgt() directly.
788 * 939 *
789 * It has been based on ieee80211_rx_any. 940 * It has been based on ieee80211_rx_any.
790 */ 941 */
@@ -810,9 +961,9 @@ static int filter_rx(struct ieee80211_device *ieee,
810 ieee80211_rx_mgt(ieee, hdr, stats); 961 ieee80211_rx_mgt(ieee, hdr, stats);
811 return 0; 962 return 0;
812 case IEEE80211_FTYPE_CTL: 963 case IEEE80211_FTYPE_CTL:
813 /* Ignore invalid short buffers */
814 return 0; 964 return 0;
815 case IEEE80211_FTYPE_DATA: 965 case IEEE80211_FTYPE_DATA:
966 /* Ignore invalid short buffers */
816 if (length < sizeof(struct ieee80211_hdr_3addr)) 967 if (length < sizeof(struct ieee80211_hdr_3addr))
817 return -EINVAL; 968 return -EINVAL;
818 return is_data_packet_for_us(ieee, hdr); 969 return is_data_packet_for_us(ieee, hdr);
@@ -993,6 +1144,7 @@ static void ieee_init(struct ieee80211_device *ieee)
993static void softmac_init(struct ieee80211softmac_device *sm) 1144static void softmac_init(struct ieee80211softmac_device *sm)
994{ 1145{
995 sm->set_channel = set_channel; 1146 sm->set_channel = set_channel;
1147 sm->bssinfo_change = bssinfo_change;
996} 1148}
997 1149
998struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) 1150struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
@@ -1028,66 +1180,6 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
1028 return iw_stats; 1180 return iw_stats;
1029} 1181}
1030 1182
1031#ifdef DEBUG
1032static const char* decryption_types[] = {
1033 [ZD_RX_NO_WEP] = "none",
1034 [ZD_RX_WEP64] = "WEP64",
1035 [ZD_RX_TKIP] = "TKIP",
1036 [ZD_RX_AES] = "AES",
1037 [ZD_RX_WEP128] = "WEP128",
1038 [ZD_RX_WEP256] = "WEP256",
1039};
1040
1041static const char *decryption_type_string(u8 type)
1042{
1043 const char *s;
1044
1045 if (type < ARRAY_SIZE(decryption_types)) {
1046 s = decryption_types[type];
1047 } else {
1048 s = NULL;
1049 }
1050 return s ? s : "unknown";
1051}
1052
1053static int is_ofdm(u8 frame_status)
1054{
1055 return (frame_status & ZD_RX_OFDM);
1056}
1057
1058void zd_dump_rx_status(const struct rx_status *status)
1059{
1060 const char* modulation;
1061 u8 quality;
1062
1063 if (is_ofdm(status->frame_status)) {
1064 modulation = "ofdm";
1065 quality = status->signal_quality_ofdm;
1066 } else {
1067 modulation = "cck";
1068 quality = status->signal_quality_cck;
1069 }
1070 pr_debug("rx status %s strength %#04x qual %#04x decryption %s\n",
1071 modulation, status->signal_strength, quality,
1072 decryption_type_string(status->decryption_type));
1073 if (status->frame_status & ZD_RX_ERROR) {
1074 pr_debug("rx error %s%s%s%s%s%s\n",
1075 (status->frame_status & ZD_RX_TIMEOUT_ERROR) ?
1076 "timeout " : "",
1077 (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR) ?
1078 "fifo " : "",
1079 (status->frame_status & ZD_RX_DECRYPTION_ERROR) ?
1080 "decryption " : "",
1081 (status->frame_status & ZD_RX_CRC32_ERROR) ?
1082 "crc32 " : "",
1083 (status->frame_status & ZD_RX_NO_ADDR1_MATCH_ERROR) ?
1084 "addr1 " : "",
1085 (status->frame_status & ZD_RX_CRC16_ERROR) ?
1086 "crc16" : "");
1087 }
1088}
1089#endif /* DEBUG */
1090
1091#define LINK_LED_WORK_DELAY HZ 1183#define LINK_LED_WORK_DELAY HZ
1092 1184
1093static void link_led_handler(struct work_struct *work) 1185static void link_led_handler(struct work_struct *work)
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 7957cac3de25..08d6b8c08e75 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -20,6 +20,7 @@
20 20
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/workqueue.h>
23#include <net/ieee80211.h> 24#include <net/ieee80211.h>
24#include <net/ieee80211softmac.h> 25#include <net/ieee80211softmac.h>
25 26
@@ -48,10 +49,11 @@ struct zd_ctrlset {
48#define ZD_CS_CCK 0x00 49#define ZD_CS_CCK 0x00
49#define ZD_CS_OFDM 0x10 50#define ZD_CS_OFDM 0x10
50 51
51#define ZD_CS_CCK_RATE_1M 0x00 52/* These are referred to as zd_rates */
52#define ZD_CS_CCK_RATE_2M 0x01 53#define ZD_CCK_RATE_1M 0x00
53#define ZD_CS_CCK_RATE_5_5M 0x02 54#define ZD_CCK_RATE_2M 0x01
54#define ZD_CS_CCK_RATE_11M 0x03 55#define ZD_CCK_RATE_5_5M 0x02
56#define ZD_CCK_RATE_11M 0x03
55/* The rates for OFDM are encoded as in the PLCP header. Use ZD_OFDM_RATE_*. 57/* The rates for OFDM are encoded as in the PLCP header. Use ZD_OFDM_RATE_*.
56 */ 58 */
57 59
@@ -82,7 +84,7 @@ struct zd_ctrlset {
82struct rx_length_info { 84struct rx_length_info {
83 __le16 length[3]; 85 __le16 length[3];
84 __le16 tag; 86 __le16 tag;
85}; 87} __attribute__((packed));
86 88
87#define RX_LENGTH_INFO_TAG 0x697e 89#define RX_LENGTH_INFO_TAG 0x697e
88 90
@@ -93,7 +95,7 @@ struct rx_status {
93 u8 signal_quality_ofdm; 95 u8 signal_quality_ofdm;
94 u8 decryption_type; 96 u8 decryption_type;
95 u8 frame_status; 97 u8 frame_status;
96}; 98} __attribute__((packed));
97 99
98/* rx_status field decryption_type */ 100/* rx_status field decryption_type */
99#define ZD_RX_NO_WEP 0 101#define ZD_RX_NO_WEP 0
@@ -116,10 +118,6 @@ struct rx_status {
116#define ZD_RX_CRC16_ERROR 0x40 118#define ZD_RX_CRC16_ERROR 0x40
117#define ZD_RX_ERROR 0x80 119#define ZD_RX_ERROR 0x80
118 120
119enum mac_flags {
120 MAC_FIXED_CHANNEL = 0x01,
121};
122
123struct housekeeping { 121struct housekeeping {
124 struct delayed_work link_led_work; 122 struct delayed_work link_led_work;
125}; 123};
@@ -130,15 +128,33 @@ struct zd_mac {
130 struct zd_chip chip; 128 struct zd_chip chip;
131 spinlock_t lock; 129 spinlock_t lock;
132 struct net_device *netdev; 130 struct net_device *netdev;
131
133 /* Unlocked reading possible */ 132 /* Unlocked reading possible */
134 struct iw_statistics iw_stats; 133 struct iw_statistics iw_stats;
134
135 struct housekeeping housekeeping; 135 struct housekeeping housekeeping;
136 struct work_struct set_rts_cts_work;
137 struct work_struct set_basic_rates_work;
138
136 unsigned int stats_count; 139 unsigned int stats_count;
137 u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; 140 u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
138 u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; 141 u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
139 u8 regdomain; 142 u8 regdomain;
140 u8 default_regdomain; 143 u8 default_regdomain;
141 u8 requested_channel; 144 u8 requested_channel;
145
146 /* A bitpattern of cr_rates */
147 u16 basic_rates;
148
149 /* A zd_rate */
150 u8 rts_rate;
151
152 /* Short preamble (used for RTS/CTS) */
153 unsigned int short_preamble:1;
154
155 /* flags to indicate update in progress */
156 unsigned int updating_rts_rate:1;
157 unsigned int updating_basic_rates:1;
142}; 158};
143 159
144static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac) 160static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac)
@@ -180,7 +196,7 @@ int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain);
180u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); 196u8 zd_mac_get_regdomain(struct zd_mac *zd_mac);
181 197
182int zd_mac_request_channel(struct zd_mac *mac, u8 channel); 198int zd_mac_request_channel(struct zd_mac *mac, u8 channel);
183int zd_mac_get_channel(struct zd_mac *mac, u8 *channel, u8 *flags); 199u8 zd_mac_get_channel(struct zd_mac *mac);
184 200
185int zd_mac_set_mode(struct zd_mac *mac, u32 mode); 201int zd_mac_set_mode(struct zd_mac *mac, u32 mode);
186int zd_mac_get_mode(struct zd_mac *mac, u32 *mode); 202int zd_mac_get_mode(struct zd_mac *mac, u32 *mode);
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c
index af3a7b36d078..60f1b0f6d45b 100644
--- a/drivers/net/wireless/zd1211rw/zd_netdev.c
+++ b/drivers/net/wireless/zd1211rw/zd_netdev.c
@@ -107,21 +107,10 @@ static int iw_get_freq(struct net_device *netdev,
107 struct iw_request_info *info, 107 struct iw_request_info *info,
108 union iwreq_data *req, char *extra) 108 union iwreq_data *req, char *extra)
109{ 109{
110 int r;
111 struct zd_mac *mac = zd_netdev_mac(netdev); 110 struct zd_mac *mac = zd_netdev_mac(netdev);
112 struct iw_freq *freq = &req->freq; 111 struct iw_freq *freq = &req->freq;
113 u8 channel;
114 u8 flags;
115
116 r = zd_mac_get_channel(mac, &channel, &flags);
117 if (r)
118 return r;
119 112
120 freq->flags = (flags & MAC_FIXED_CHANNEL) ? 113 return zd_channel_to_freq(freq, zd_mac_get_channel(mac));
121 IW_FREQ_FIXED : IW_FREQ_AUTO;
122 dev_dbg_f(zd_mac_dev(mac), "channel %s\n",
123 (flags & MAC_FIXED_CHANNEL) ? "fixed" : "auto");
124 return zd_channel_to_freq(freq, channel);
125} 114}
126 115
127static int iw_set_mode(struct net_device *netdev, 116static int iw_set_mode(struct net_device *netdev,
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 3faaeb2b7c89..aa782e88754b 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -47,11 +47,17 @@ static struct usb_device_id usb_ids[] = {
47 { USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 }, 47 { USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 },
48 { USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 }, 48 { USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 },
49 { USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 }, 49 { USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 },
50 { USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 },
51 { USB_DEVICE(0x0586, 0x3409), .driver_info = DEVICE_ZD1211 },
52 { USB_DEVICE(0x0b3b, 0x1630), .driver_info = DEVICE_ZD1211 },
53 { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
54 { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
50 /* ZD1211B */ 55 /* ZD1211B */
51 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, 56 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
52 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, 57 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
53 { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, 58 { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
54 { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, 59 { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
60 { USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B },
55 /* "Driverless" devices that need ejecting */ 61 /* "Driverless" devices that need ejecting */
56 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, 62 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
57 {} 63 {}
@@ -366,15 +372,6 @@ error:
366 return r; 372 return r;
367} 373}
368 374
369static void disable_read_regs_int(struct zd_usb *usb)
370{
371 struct zd_usb_interrupt *intr = &usb->intr;
372
373 spin_lock(&intr->lock);
374 intr->read_regs_enabled = 0;
375 spin_unlock(&intr->lock);
376}
377
378#define urb_dev(urb) (&(urb)->dev->dev) 375#define urb_dev(urb) (&(urb)->dev->dev)
379 376
380static inline void handle_regs_int(struct urb *urb) 377static inline void handle_regs_int(struct urb *urb)
@@ -596,6 +593,8 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
596 unsigned int l, k, n; 593 unsigned int l, k, n;
597 for (i = 0, l = 0;; i++) { 594 for (i = 0, l = 0;; i++) {
598 k = le16_to_cpu(get_unaligned(&length_info->length[i])); 595 k = le16_to_cpu(get_unaligned(&length_info->length[i]));
596 if (k == 0)
597 return;
599 n = l+k; 598 n = l+k;
600 if (n > length) 599 if (n > length)
601 return; 600 return;
@@ -1119,27 +1118,28 @@ static int __init usb_init(void)
1119{ 1118{
1120 int r; 1119 int r;
1121 1120
1122 pr_debug("usb_init()\n"); 1121 pr_debug("%s usb_init()\n", driver.name);
1123 1122
1124 zd_workqueue = create_singlethread_workqueue(driver.name); 1123 zd_workqueue = create_singlethread_workqueue(driver.name);
1125 if (zd_workqueue == NULL) { 1124 if (zd_workqueue == NULL) {
1126 printk(KERN_ERR "%s: couldn't create workqueue\n", driver.name); 1125 printk(KERN_ERR "%s couldn't create workqueue\n", driver.name);
1127 return -ENOMEM; 1126 return -ENOMEM;
1128 } 1127 }
1129 1128
1130 r = usb_register(&driver); 1129 r = usb_register(&driver);
1131 if (r) { 1130 if (r) {
1132 printk(KERN_ERR "usb_register() failed. Error number %d\n", r); 1131 printk(KERN_ERR "%s usb_register() failed. Error number %d\n",
1132 driver.name, r);
1133 return r; 1133 return r;
1134 } 1134 }
1135 1135
1136 pr_debug("zd1211rw initialized\n"); 1136 pr_debug("%s initialized\n", driver.name);
1137 return 0; 1137 return 0;
1138} 1138}
1139 1139
1140static void __exit usb_exit(void) 1140static void __exit usb_exit(void)
1141{ 1141{
1142 pr_debug("usb_exit()\n"); 1142 pr_debug("%s usb_exit()\n", driver.name);
1143 usb_deregister(&driver); 1143 usb_deregister(&driver);
1144 destroy_workqueue(zd_workqueue); 1144 destroy_workqueue(zd_workqueue);
1145} 1145}
@@ -1156,10 +1156,19 @@ static void prepare_read_regs_int(struct zd_usb *usb)
1156{ 1156{
1157 struct zd_usb_interrupt *intr = &usb->intr; 1157 struct zd_usb_interrupt *intr = &usb->intr;
1158 1158
1159 spin_lock(&intr->lock); 1159 spin_lock_irq(&intr->lock);
1160 intr->read_regs_enabled = 1; 1160 intr->read_regs_enabled = 1;
1161 INIT_COMPLETION(intr->read_regs.completion); 1161 INIT_COMPLETION(intr->read_regs.completion);
1162 spin_unlock(&intr->lock); 1162 spin_unlock_irq(&intr->lock);
1163}
1164
1165static void disable_read_regs_int(struct zd_usb *usb)
1166{
1167 struct zd_usb_interrupt *intr = &usb->intr;
1168
1169 spin_lock_irq(&intr->lock);
1170 intr->read_regs_enabled = 0;
1171 spin_unlock_irq(&intr->lock);
1163} 1172}
1164 1173
1165static int get_results(struct zd_usb *usb, u16 *values, 1174static int get_results(struct zd_usb *usb, u16 *values,
@@ -1171,7 +1180,7 @@ static int get_results(struct zd_usb *usb, u16 *values,
1171 struct read_regs_int *rr = &intr->read_regs; 1180 struct read_regs_int *rr = &intr->read_regs;
1172 struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; 1181 struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer;
1173 1182
1174 spin_lock(&intr->lock); 1183 spin_lock_irq(&intr->lock);
1175 1184
1176 r = -EIO; 1185 r = -EIO;
1177 /* The created block size seems to be larger than expected. 1186 /* The created block size seems to be larger than expected.
@@ -1204,7 +1213,7 @@ static int get_results(struct zd_usb *usb, u16 *values,
1204 1213
1205 r = 0; 1214 r = 0;
1206error_unlock: 1215error_unlock:
1207 spin_unlock(&intr->lock); 1216 spin_unlock_irq(&intr->lock);
1208 return r; 1217 return r;
1209} 1218}
1210 1219
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index e81a2d3cfffd..317d37c36679 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -74,17 +74,17 @@ enum control_requests {
74struct usb_req_read_regs { 74struct usb_req_read_regs {
75 __le16 id; 75 __le16 id;
76 __le16 addr[0]; 76 __le16 addr[0];
77}; 77} __attribute__((packed));
78 78
79struct reg_data { 79struct reg_data {
80 __le16 addr; 80 __le16 addr;
81 __le16 value; 81 __le16 value;
82}; 82} __attribute__((packed));
83 83
84struct usb_req_write_regs { 84struct usb_req_write_regs {
85 __le16 id; 85 __le16 id;
86 struct reg_data reg_writes[0]; 86 struct reg_data reg_writes[0];
87}; 87} __attribute__((packed));
88 88
89enum { 89enum {
90 RF_IF_LE = 0x02, 90 RF_IF_LE = 0x02,
@@ -101,7 +101,7 @@ struct usb_req_rfwrite {
101 /* RF2595: 24 */ 101 /* RF2595: 24 */
102 __le16 bit_values[0]; 102 __le16 bit_values[0];
103 /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ 103 /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
104}; 104} __attribute__((packed));
105 105
106/* USB interrupt */ 106/* USB interrupt */
107 107
@@ -118,12 +118,12 @@ enum usb_int_flags {
118struct usb_int_header { 118struct usb_int_header {
119 u8 type; /* must always be 1 */ 119 u8 type; /* must always be 1 */
120 u8 id; 120 u8 id;
121}; 121} __attribute__((packed));
122 122
123struct usb_int_regs { 123struct usb_int_regs {
124 struct usb_int_header hdr; 124 struct usb_int_header hdr;
125 struct reg_data regs[0]; 125 struct reg_data regs[0];
126}; 126} __attribute__((packed));
127 127
128struct usb_int_retry_fail { 128struct usb_int_retry_fail {
129 struct usb_int_header hdr; 129 struct usb_int_header hdr;
@@ -131,7 +131,7 @@ struct usb_int_retry_fail {
131 u8 _dummy; 131 u8 _dummy;
132 u8 addr[ETH_ALEN]; 132 u8 addr[ETH_ALEN];
133 u8 ibss_wakeup_dest; 133 u8 ibss_wakeup_dest;
134}; 134} __attribute__((packed));
135 135
136struct read_regs_int { 136struct read_regs_int {
137 struct completion completion; 137 struct completion completion;