diff options
Diffstat (limited to 'drivers/net/wireless')
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); | |||
595 | static void atmel_smooth_qual(struct atmel_private *priv); | 595 | static void atmel_smooth_qual(struct atmel_private *priv); |
596 | static void atmel_writeAR(struct net_device *dev, u16 data); | 596 | static void atmel_writeAR(struct net_device *dev, u16 data); |
597 | static int probe_atmel_card(struct net_device *dev); | 597 | static int probe_atmel_card(struct net_device *dev); |
598 | static int reset_atmel_card(struct net_device *dev ); | 598 | static int reset_atmel_card(struct net_device *dev); |
599 | static void atmel_enter_state(struct atmel_private *priv, int new_state); | 599 | static void atmel_enter_state(struct atmel_private *priv, int new_state); |
600 | int atmel_open (struct net_device *dev); | 600 | int 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 | ||
785 | static int start_tx(struct sk_buff *skb, struct net_device *dev) | 785 | static 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 | ||
2580 | static const struct iw_handler_def atmel_handler_def = | 2588 | static 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 | ||
93 | static int atmel_config(struct pcmcia_device *link); | 93 | static 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 | ||
137 | typedef struct local_info_t { | 137 | typedef 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 | ||
154 | static int atmel_probe(struct pcmcia_device *p_dev) | 154 | static 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 | ||
195 | static void atmel_detach(struct pcmcia_device *link) | 195 | static 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 | ||
386 | static void atmel_release(struct pcmcia_device *link) | 386 | static 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 | ||
523 | module_init(atmel_cs_init); | 523 | module_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 | ||
3005 | static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) | 3001 | static 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); | ||
3019 | out: | 3023 | out: |
3020 | return err; | 3024 | return err; |
3021 | } | 3025 | } |
3022 | 3026 | ||
3027 | static 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 | |||
3033 | static 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 | |||
3040 | static 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 | |||
3075 | out_switch_back: | 3139 | out_switch_back: |
3076 | err = bcm43xx_switch_core(bcm, old_core); | 3140 | err = bcm43xx_switch_core(bcm, old_core); |
3077 | out: | 3141 | out: |
@@ -3140,43 +3204,17 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) | |||
3140 | 3204 | ||
3141 | static void do_periodic_work(struct bcm43xx_private *bcm) | 3205 | static 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 | */ | ||
3163 | static 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 | |||
3180 | static void bcm43xx_periodic_work_handler(struct work_struct *work) | 3218 | static 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 | ||
3978 | static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev) | ||
3979 | { | ||
3980 | return &(bcm43xx_priv(net_dev)->ieee->stats); | ||
3981 | } | ||
3982 | |||
3983 | static void bcm43xx_net_tx_timeout(struct net_device *net_dev) | 4017 | static 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 | ||
54 | static int bcm43xx_wx_get_name(struct net_device *net_dev, | 51 | static 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) | |||
425 | static int prism2_pci_resume(struct pci_dev *pdev) | 425 | static 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 | */ | ||
5842 | static 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 | |||
5849 | static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) | 5836 | static 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 | */ |
6945 | static int ipw_qos_association_resp(struct ipw_priv *priv, | 6945 | static 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 | ||
213 | void | 212 | void |
214 | isl38xx_enable_common_interrupts(void __iomem *device_base) { | 213 | isl38xx_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 | */ |
76 | static inline void | 75 | static 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 | */ |
65 | static int | 64 | static int |
66 | prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode) | 65 | prism54_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 | ||
124 | void | 123 | void |
@@ -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 | */ |
792 | static int | 791 | static 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 | ||
2554 | struct prism2_hostapd_param { | 2553 | struct 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 | */ |
106 | static inline void | 104 | static 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 | ||
119 | enum dot11_state_t { | 117 | enum 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 | */ |
163 | enum dot11_maxframeburst_t { | 161 | enum 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 */ |
183 | enum dot11_preamblesettings_t { | 181 | enum 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 ?) */ |
196 | enum dot11_slotsettings_t { | 194 | enum 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 */ |
226 | enum dot11_nonerpprotection_t { | 224 | enum 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 */ |
235 | enum dot11_profile_t { /* And set/allowed values */ | 233 | enum 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 | ||
78 | typedef struct { | 77 | typedef 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 | |||
485 | islpci_do_reset_and_wake(struct work_struct *work) | 483 | islpci_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 | ||
493 | void | 493 | void |
@@ -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; | |||
40 | module_param(init_pcitm, int, 0); | 39 | module_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 */ |
46 | static const struct pci_device_id prism54_id_tbl[] = { | 45 | static 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 |
733 | void | 733 | void |
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); |
1830 | err_zd: | 1830 | err_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 | ||
1079 | int 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 | |||
1079 | int zd_chip_enable_hwint(struct zd_chip *chip) | 1104 | int 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 | ||
1358 | int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) | 1383 | int 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 | ||
1371 | static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) | 1391 | static 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); | |||
794 | int zd_chip_enable_hwint(struct zd_chip *chip); | 803 | int zd_chip_enable_hwint(struct zd_chip *chip); |
795 | int zd_chip_disable_hwint(struct zd_chip *chip); | 804 | int zd_chip_disable_hwint(struct zd_chip *chip); |
796 | 805 | ||
806 | int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, | ||
807 | u8 rts_rate, int preamble); | ||
808 | |||
797 | static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) | 809 | static 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 | ||
812 | int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates); | 824 | int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates); |
825 | |||
826 | static 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 | ||
814 | static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter) | 836 | static 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 | ||
43 | const struct channel_range *zd_channel_range(u8 regdomain) | 48 | const 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 | ||
69 | static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header) | 70 | static 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 | ||
33 | static void ieee_init(struct ieee80211_device *ieee); | 33 | static void ieee_init(struct ieee80211_device *ieee); |
34 | static void softmac_init(struct ieee80211softmac_device *sm); | 34 | static void softmac_init(struct ieee80211softmac_device *sm); |
35 | static void set_rts_cts_work(void *d); | ||
36 | static void set_basic_rates_work(void *d); | ||
35 | 37 | ||
36 | static void housekeeping_init(struct zd_mac *mac); | 38 | static void housekeeping_init(struct zd_mac *mac); |
37 | static void housekeeping_enable(struct zd_mac *mac); | 39 | static 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. */ | ||
301 | static 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 | |||
330 | static 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 | |||
359 | static 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 | |||
369 | static 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 | |||
390 | static 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 | |||
409 | static 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 | |||
289 | static void set_channel(struct net_device *netdev, u8 channel) | 480 | static 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. */ | ||
299 | int zd_mac_request_channel(struct zd_mac *mac, u8 channel) | 489 | int 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 | ||
320 | int zd_mac_get_channel(struct zd_mac *mac, u8 *channel, u8 *flags) | 510 | u8 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 */ |
338 | static u8 cs_typed_rate(u8 cs_rate) | 519 | static 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. */ | ||
360 | static 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 | ||
389 | int zd_mac_set_mode(struct zd_mac *mac, u32 mode) | 540 | int 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 | ||
487 | static int zd_calc_tx_length_us(u8 *service, u8 cs_rate, u16 tx_length) | 638 | static 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 | ||
535 | static u8 cs_rate_to_modulation(u8 cs_rate, int flags) | 686 | static 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 | ||
572 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | 729 | static 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 | ||
726 | static void fill_rt_header(void *buffer, struct zd_mac *mac, | 875 | static 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) | |||
993 | static void softmac_init(struct ieee80211softmac_device *sm) | 1144 | static 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 | ||
998 | struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) | 1150 | struct 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 | ||
1032 | static 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 | |||
1041 | static 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 | |||
1053 | static int is_ofdm(u8 frame_status) | ||
1054 | { | ||
1055 | return (frame_status & ZD_RX_OFDM); | ||
1056 | } | ||
1057 | |||
1058 | void 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 | ||
1093 | static void link_led_handler(struct work_struct *work) | 1185 | static 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 { | |||
82 | struct rx_length_info { | 84 | struct 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 | ||
119 | enum mac_flags { | ||
120 | MAC_FIXED_CHANNEL = 0x01, | ||
121 | }; | ||
122 | |||
123 | struct housekeeping { | 121 | struct 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 | ||
144 | static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac) | 160 | static 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); | |||
180 | u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); | 196 | u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); |
181 | 197 | ||
182 | int zd_mac_request_channel(struct zd_mac *mac, u8 channel); | 198 | int zd_mac_request_channel(struct zd_mac *mac, u8 channel); |
183 | int zd_mac_get_channel(struct zd_mac *mac, u8 *channel, u8 *flags); | 199 | u8 zd_mac_get_channel(struct zd_mac *mac); |
184 | 200 | ||
185 | int zd_mac_set_mode(struct zd_mac *mac, u32 mode); | 201 | int zd_mac_set_mode(struct zd_mac *mac, u32 mode); |
186 | int zd_mac_get_mode(struct zd_mac *mac, u32 *mode); | 202 | int 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 | ||
127 | static int iw_set_mode(struct net_device *netdev, | 116 | static 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 | ||
369 | static 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 | ||
380 | static inline void handle_regs_int(struct urb *urb) | 377 | static 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 | ||
1140 | static void __exit usb_exit(void) | 1140 | static 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 | |||
1165 | static 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 | ||
1165 | static int get_results(struct zd_usb *usb, u16 *values, | 1174 | static 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; |
1206 | error_unlock: | 1215 | error_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 { | |||
74 | struct usb_req_read_regs { | 74 | struct usb_req_read_regs { |
75 | __le16 id; | 75 | __le16 id; |
76 | __le16 addr[0]; | 76 | __le16 addr[0]; |
77 | }; | 77 | } __attribute__((packed)); |
78 | 78 | ||
79 | struct reg_data { | 79 | struct reg_data { |
80 | __le16 addr; | 80 | __le16 addr; |
81 | __le16 value; | 81 | __le16 value; |
82 | }; | 82 | } __attribute__((packed)); |
83 | 83 | ||
84 | struct usb_req_write_regs { | 84 | struct 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 | ||
89 | enum { | 89 | enum { |
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 { | |||
118 | struct usb_int_header { | 118 | struct 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 | ||
123 | struct usb_int_regs { | 123 | struct 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 | ||
128 | struct usb_int_retry_fail { | 128 | struct 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 | ||
136 | struct read_regs_int { | 136 | struct read_regs_int { |
137 | struct completion completion; | 137 | struct completion completion; |