aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2006-11-21 19:06:48 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-02 00:12:05 -0500
commitb1382edef9c06eca337e8982e6040e0699abab82 (patch)
treeffd9b959db655b6f06bdb09e1ef6ce245ffa8457 /drivers
parentb1cd84167b92de0f9fc7aad9cf272261496f4d0b (diff)
[PATCH] zd1211rw: Use softmac ERP handling functionality
This adds zd1211rw driver support for the softmac functionality I added a while back. We now obey changes in basic rates, use short preamble if it is available (but long if the AP says it's not), and send self-CTS in the proper situations. Locking fixed and improved by Ulrich Kunitz. Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c38
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h24
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c270
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h19
4 files changed, 286 insertions, 65 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index aa661b2b76c7..8be99ebbe1cd 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1076,6 +1076,31 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
1076 return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); 1076 return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
1077} 1077}
1078 1078
1079int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
1080 u8 rts_rate, int preamble)
1081{
1082 int rts_mod = ZD_RX_CCK;
1083 u32 value = 0;
1084
1085 /* Modulation bit */
1086 if (ZD_CS_TYPE(rts_rate) == ZD_CS_OFDM)
1087 rts_mod = ZD_RX_OFDM;
1088
1089 dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n",
1090 rts_rate, preamble);
1091
1092 value |= rts_rate << RTSCTS_SH_RTS_RATE;
1093 value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE;
1094 value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
1095 value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;
1096
1097 /* We always send 11M self-CTS messages, like the vendor driver. */
1098 value |= ZD_CCK_RATE_11M << RTSCTS_SH_CTS_RATE;
1099 value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;
1100
1101 return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE);
1102}
1103
1079int zd_chip_enable_hwint(struct zd_chip *chip) 1104int zd_chip_enable_hwint(struct zd_chip *chip)
1080{ 1105{
1081 int r; 1106 int r;
@@ -1355,17 +1380,12 @@ out:
1355 return r; 1380 return r;
1356} 1381}
1357 1382
1358int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) 1383int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates)
1359{ 1384{
1360 int r; 1385 ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
1361 1386 dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
1362 if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
1363 return -EINVAL;
1364 1387
1365 mutex_lock(&chip->mutex); 1388 return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
1366 r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
1367 mutex_unlock(&chip->mutex);
1368 return r;
1369} 1389}
1370 1390
1371static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) 1391static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index f441cf40f74b..ca892b9a6448 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -420,6 +420,15 @@
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
@@ -794,6 +803,9 @@ void zd_chip_disable_rx(struct zd_chip *chip);
794int zd_chip_enable_hwint(struct zd_chip *chip); 803int zd_chip_enable_hwint(struct zd_chip *chip);
795int zd_chip_disable_hwint(struct zd_chip *chip); 804int zd_chip_disable_hwint(struct zd_chip *chip);
796 805
806int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
807 u8 rts_rate, int preamble);
808
797static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) 809static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type)
798{ 810{
799 return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type); 811 return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type);
@@ -809,7 +821,17 @@ static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates)
809 return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates); 821 return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates);
810} 822}
811 823
812int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates); 824int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates);
825
826static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
827{
828 int r;
829
830 mutex_lock(&chip->mutex);
831 r = zd_chip_set_basic_rates_locked(chip, cr_rates);
832 mutex_unlock(&chip->mutex);
833 return r;
834}
813 835
814static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter) 836static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter)
815{ 837{
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index e6af18304bac..2696f95b9278 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -32,6 +32,8 @@
32 32
33static void ieee_init(struct ieee80211_device *ieee); 33static void ieee_init(struct ieee80211_device *ieee);
34static void softmac_init(struct ieee80211softmac_device *sm); 34static void softmac_init(struct ieee80211softmac_device *sm);
35static void set_rts_cts_work(void *d);
36static void set_basic_rates_work(void *d);
35 37
36static void housekeeping_init(struct zd_mac *mac); 38static void housekeeping_init(struct zd_mac *mac);
37static void housekeeping_enable(struct zd_mac *mac); 39static void housekeeping_enable(struct zd_mac *mac);
@@ -46,6 +48,8 @@ int zd_mac_init(struct zd_mac *mac,
46 memset(mac, 0, sizeof(*mac)); 48 memset(mac, 0, sizeof(*mac));
47 spin_lock_init(&mac->lock); 49 spin_lock_init(&mac->lock);
48 mac->netdev = netdev; 50 mac->netdev = netdev;
51 INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work, mac);
52 INIT_WORK(&mac->set_basic_rates_work, set_basic_rates_work, mac);
49 53
50 ieee_init(ieee); 54 ieee_init(ieee);
51 softmac_init(ieee80211_priv(netdev)); 55 softmac_init(ieee80211_priv(netdev));
@@ -213,6 +217,13 @@ int zd_mac_stop(struct net_device *netdev)
213 housekeeping_disable(mac); 217 housekeeping_disable(mac);
214 ieee80211softmac_stop(netdev); 218 ieee80211softmac_stop(netdev);
215 219
220 /* Ensure no work items are running or queued from this point */
221 cancel_delayed_work(&mac->set_rts_cts_work);
222 cancel_delayed_work(&mac->set_basic_rates_work);
223 flush_workqueue(zd_workqueue);
224 mac->updating_rts_rate = 0;
225 mac->updating_basic_rates = 0;
226
216 zd_chip_disable_hwint(chip); 227 zd_chip_disable_hwint(chip);
217 zd_chip_switch_radio_off(chip); 228 zd_chip_switch_radio_off(chip);
218 zd_chip_disable_int(chip); 229 zd_chip_disable_int(chip);
@@ -286,6 +297,186 @@ u8 zd_mac_get_regdomain(struct zd_mac *mac)
286 return regdomain; 297 return regdomain;
287} 298}
288 299
300/* Fallback to lowest rate, if rate is unknown. */
301static u8 rate_to_zd_rate(u8 rate)
302{
303 switch (rate) {
304 case IEEE80211_CCK_RATE_2MB:
305 return ZD_CCK_RATE_2M;
306 case IEEE80211_CCK_RATE_5MB:
307 return ZD_CCK_RATE_5_5M;
308 case IEEE80211_CCK_RATE_11MB:
309 return ZD_CCK_RATE_11M;
310 case IEEE80211_OFDM_RATE_6MB:
311 return ZD_OFDM_RATE_6M;
312 case IEEE80211_OFDM_RATE_9MB:
313 return ZD_OFDM_RATE_9M;
314 case IEEE80211_OFDM_RATE_12MB:
315 return ZD_OFDM_RATE_12M;
316 case IEEE80211_OFDM_RATE_18MB:
317 return ZD_OFDM_RATE_18M;
318 case IEEE80211_OFDM_RATE_24MB:
319 return ZD_OFDM_RATE_24M;
320 case IEEE80211_OFDM_RATE_36MB:
321 return ZD_OFDM_RATE_36M;
322 case IEEE80211_OFDM_RATE_48MB:
323 return ZD_OFDM_RATE_48M;
324 case IEEE80211_OFDM_RATE_54MB:
325 return ZD_OFDM_RATE_54M;
326 }
327 return ZD_CCK_RATE_1M;
328}
329
330static u16 rate_to_cr_rate(u8 rate)
331{
332 switch (rate) {
333 case IEEE80211_CCK_RATE_2MB:
334 return CR_RATE_1M;
335 case IEEE80211_CCK_RATE_5MB:
336 return CR_RATE_5_5M;
337 case IEEE80211_CCK_RATE_11MB:
338 return CR_RATE_11M;
339 case IEEE80211_OFDM_RATE_6MB:
340 return CR_RATE_6M;
341 case IEEE80211_OFDM_RATE_9MB:
342 return CR_RATE_9M;
343 case IEEE80211_OFDM_RATE_12MB:
344 return CR_RATE_12M;
345 case IEEE80211_OFDM_RATE_18MB:
346 return CR_RATE_18M;
347 case IEEE80211_OFDM_RATE_24MB:
348 return CR_RATE_24M;
349 case IEEE80211_OFDM_RATE_36MB:
350 return CR_RATE_36M;
351 case IEEE80211_OFDM_RATE_48MB:
352 return CR_RATE_48M;
353 case IEEE80211_OFDM_RATE_54MB:
354 return CR_RATE_54M;
355 }
356 return CR_RATE_1M;
357}
358
359static void try_enable_tx(struct zd_mac *mac)
360{
361 unsigned long flags;
362
363 spin_lock_irqsave(&mac->lock, flags);
364 if (mac->updating_rts_rate == 0 && mac->updating_basic_rates == 0)
365 netif_wake_queue(mac->netdev);
366 spin_unlock_irqrestore(&mac->lock, flags);
367}
368
369static void set_rts_cts_work(void *d)
370{
371 struct zd_mac *mac = d;
372 unsigned long flags;
373 u8 rts_rate;
374 unsigned int short_preamble;
375
376 mutex_lock(&mac->chip.mutex);
377
378 spin_lock_irqsave(&mac->lock, flags);
379 mac->updating_rts_rate = 0;
380 rts_rate = mac->rts_rate;
381 short_preamble = mac->short_preamble;
382 spin_unlock_irqrestore(&mac->lock, flags);
383
384 zd_chip_set_rts_cts_rate_locked(&mac->chip, rts_rate, short_preamble);
385 mutex_unlock(&mac->chip.mutex);
386
387 try_enable_tx(mac);
388}
389
390static void set_basic_rates_work(void *d)
391{
392 struct zd_mac *mac = d;
393 unsigned long flags;
394 u16 basic_rates;
395
396 mutex_lock(&mac->chip.mutex);
397
398 spin_lock_irqsave(&mac->lock, flags);
399 mac->updating_basic_rates = 0;
400 basic_rates = mac->basic_rates;
401 spin_unlock_irqrestore(&mac->lock, flags);
402
403 zd_chip_set_basic_rates_locked(&mac->chip, basic_rates);
404 mutex_unlock(&mac->chip.mutex);
405
406 try_enable_tx(mac);
407}
408
409static void bssinfo_change(struct net_device *netdev, u32 changes)
410{
411 struct zd_mac *mac = zd_netdev_mac(netdev);
412 struct ieee80211softmac_device *softmac = ieee80211_priv(netdev);
413 struct ieee80211softmac_bss_info *bssinfo = &softmac->bssinfo;
414 int need_set_rts_cts = 0;
415 int need_set_rates = 0;
416 u16 basic_rates;
417 unsigned long flags;
418
419 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
420
421 if (changes & IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE) {
422 spin_lock_irqsave(&mac->lock, flags);
423 mac->short_preamble = bssinfo->short_preamble;
424 spin_unlock_irqrestore(&mac->lock, flags);
425 need_set_rts_cts = 1;
426 }
427
428 if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) {
429 /* Set RTS rate to highest available basic rate */
430 u8 rate = ieee80211softmac_highest_supported_rate(softmac,
431 &bssinfo->supported_rates, 1);
432 rate = rate_to_zd_rate(rate);
433
434 spin_lock_irqsave(&mac->lock, flags);
435 if (rate != mac->rts_rate) {
436 mac->rts_rate = rate;
437 need_set_rts_cts = 1;
438 }
439 spin_unlock_irqrestore(&mac->lock, flags);
440
441 /* Set basic rates */
442 need_set_rates = 1;
443 if (bssinfo->supported_rates.count == 0) {
444 /* Allow the device to be flexible */
445 basic_rates = CR_RATES_80211B | CR_RATES_80211G;
446 } else {
447 int i = 0;
448 basic_rates = 0;
449
450 for (i = 0; i < bssinfo->supported_rates.count; i++) {
451 u16 rate = bssinfo->supported_rates.rates[i];
452 if ((rate & IEEE80211_BASIC_RATE_MASK) == 0)
453 continue;
454
455 rate &= ~IEEE80211_BASIC_RATE_MASK;
456 basic_rates |= rate_to_cr_rate(rate);
457 }
458 }
459 spin_lock_irqsave(&mac->lock, flags);
460 mac->basic_rates = basic_rates;
461 spin_unlock_irqrestore(&mac->lock, flags);
462 }
463
464 /* Schedule any changes we made above */
465
466 spin_lock_irqsave(&mac->lock, flags);
467 if (need_set_rts_cts && !mac->updating_rts_rate) {
468 mac->updating_rts_rate = 1;
469 netif_stop_queue(mac->netdev);
470 queue_work(zd_workqueue, &mac->set_rts_cts_work);
471 }
472 if (need_set_rates && !mac->updating_basic_rates) {
473 mac->updating_basic_rates = 1;
474 netif_stop_queue(mac->netdev);
475 queue_work(zd_workqueue, &mac->set_basic_rates_work);
476 }
477 spin_unlock_irqrestore(&mac->lock, flags);
478}
479
289static void set_channel(struct net_device *netdev, u8 channel) 480static void set_channel(struct net_device *netdev, u8 channel)
290{ 481{
291 struct zd_mac *mac = zd_netdev_mac(netdev); 482 struct zd_mac *mac = zd_netdev_mac(netdev);
@@ -346,36 +537,6 @@ static u8 zd_rate_typed(u8 zd_rate)
346 return typed_rates[zd_rate & ZD_CS_RATE_MASK]; 537 return typed_rates[zd_rate & ZD_CS_RATE_MASK];
347} 538}
348 539
349/* Fallback to lowest rate, if rate is unknown. */
350static u8 rate_to_zd_rate(u8 rate)
351{
352 switch (rate) {
353 case IEEE80211_CCK_RATE_2MB:
354 return ZD_CCK_RATE_2M;
355 case IEEE80211_CCK_RATE_5MB:
356 return ZD_CCK_RATE_5_5M;
357 case IEEE80211_CCK_RATE_11MB:
358 return ZD_CCK_RATE_11M;
359 case IEEE80211_OFDM_RATE_6MB:
360 return ZD_OFDM_RATE_6M;
361 case IEEE80211_OFDM_RATE_9MB:
362 return ZD_OFDM_RATE_9M;
363 case IEEE80211_OFDM_RATE_12MB:
364 return ZD_OFDM_RATE_12M;
365 case IEEE80211_OFDM_RATE_18MB:
366 return ZD_OFDM_RATE_18M;
367 case IEEE80211_OFDM_RATE_24MB:
368 return ZD_OFDM_RATE_24M;
369 case IEEE80211_OFDM_RATE_36MB:
370 return ZD_OFDM_RATE_36M;
371 case IEEE80211_OFDM_RATE_48MB:
372 return ZD_OFDM_RATE_48M;
373 case IEEE80211_OFDM_RATE_54MB:
374 return ZD_OFDM_RATE_54M;
375 }
376 return ZD_CCK_RATE_1M;
377}
378
379int zd_mac_set_mode(struct zd_mac *mac, u32 mode) 540int zd_mac_set_mode(struct zd_mac *mac, u32 mode)
380{ 541{
381 struct ieee80211_device *ieee; 542 struct ieee80211_device *ieee;
@@ -550,37 +711,34 @@ static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs,
550 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));
551 u8 rate, zd_rate; 712 u8 rate, zd_rate;
552 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;
553 718
554 /* FIXME: 802.11a? short preamble? */ 719 /* FIXME: 802.11a? */
555 rate = ieee80211softmac_suggest_txrate(softmac, 720 rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt);
556 is_multicast_ether_addr(hdr->addr1), is_mgt); 721
722 if (short_preamble)
723 flags |= R2M_SHORT_PREAMBLE;
557 724
558 zd_rate = rate_to_zd_rate(rate); 725 zd_rate = rate_to_zd_rate(rate);
559 cs->modulation = zd_rate_to_modulation(zd_rate, 0); 726 cs->modulation = zd_rate_to_modulation(zd_rate, flags);
560} 727}
561 728
562static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, 729static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
563 struct ieee80211_hdr_4addr *header) 730 struct ieee80211_hdr_4addr *header)
564{ 731{
732 struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev);
565 unsigned int tx_length = le16_to_cpu(cs->tx_length); 733 unsigned int tx_length = le16_to_cpu(cs->tx_length);
566 u16 fctl = le16_to_cpu(header->frame_ctl); 734 u16 fctl = le16_to_cpu(header->frame_ctl);
567 u16 ftype = WLAN_FC_GET_TYPE(fctl); 735 u16 ftype = WLAN_FC_GET_TYPE(fctl);
568 u16 stype = WLAN_FC_GET_STYPE(fctl); 736 u16 stype = WLAN_FC_GET_STYPE(fctl);
569 737
570 /* 738 /*
571 * CONTROL: 739 * CONTROL TODO:
572 * - start at 0x00
573 * - if fragment 0, enable bit 0
574 * - if backoff needed, enable bit 0 740 * - if backoff needed, enable bit 0
575 * - if burst (backoff not needed) disable bit 0 741 * - if burst (backoff not needed) disable bit 0
576 * - if multicast, enable bit 1
577 * - if PS-POLL frame, enable bit 2
578 * - if in INDEPENDENT_BSS mode and zd1205_DestPowerSave, then enable
579 * bit 4 (FIXME: wtf)
580 * - if frag_len > RTS threshold, set bit 5 as long if it isnt
581 * multicast or mgt
582 * - if bit 5 is set, and we are in OFDM mode, unset bit 5 and set bit
583 * 7
584 */ 742 */
585 743
586 cs->control = 0; 744 cs->control = 0;
@@ -597,17 +755,18 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
597 if (stype == IEEE80211_STYPE_PSPOLL) 755 if (stype == IEEE80211_STYPE_PSPOLL)
598 cs->control |= ZD_CS_PS_POLL_FRAME; 756 cs->control |= ZD_CS_PS_POLL_FRAME;
599 757
758 /* Unicast data frames over the threshold should have RTS */
600 if (!is_multicast_ether_addr(header->addr1) && 759 if (!is_multicast_ether_addr(header->addr1) &&
601 ftype != IEEE80211_FTYPE_MGMT && 760 ftype != IEEE80211_FTYPE_MGMT &&
602 tx_length > zd_netdev_ieee80211(mac->netdev)->rts) 761 tx_length > zd_netdev_ieee80211(mac->netdev)->rts)
603 { 762 cs->control |= ZD_CS_RTS;
604 /* FIXME: check the logic */ 763
605 if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM) { 764 /* Use CTS-to-self protection if required */
606 /* 802.11g */ 765 if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM &&
607 cs->control |= ZD_CS_SELF_CTS; 766 ieee80211softmac_protection_needed(softmac)) {
608 } else { /* 802.11b */ 767 /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */
609 cs->control |= ZD_CS_RTS; 768 cs->control &= ~ZD_CS_RTS;
610 } 769 cs->control |= ZD_CS_SELF_CTS;
611 } 770 }
612 771
613 /* FIXME: Management frame? */ 772 /* FIXME: Management frame? */
@@ -985,6 +1144,7 @@ static void ieee_init(struct ieee80211_device *ieee)
985static void softmac_init(struct ieee80211softmac_device *sm) 1144static void softmac_init(struct ieee80211softmac_device *sm)
986{ 1145{
987 sm->set_channel = set_channel; 1146 sm->set_channel = set_channel;
1147 sm->bssinfo_change = bssinfo_change;
988} 1148}
989 1149
990struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) 1150struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 3c86578150b3..5dcfb251f02e 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
@@ -127,15 +128,33 @@ struct zd_mac {
127 struct zd_chip chip; 128 struct zd_chip chip;
128 spinlock_t lock; 129 spinlock_t lock;
129 struct net_device *netdev; 130 struct net_device *netdev;
131
130 /* Unlocked reading possible */ 132 /* Unlocked reading possible */
131 struct iw_statistics iw_stats; 133 struct iw_statistics iw_stats;
134
132 struct housekeeping housekeeping; 135 struct housekeeping housekeeping;
136 struct work_struct set_rts_cts_work;
137 struct work_struct set_basic_rates_work;
138
133 unsigned int stats_count; 139 unsigned int stats_count;
134 u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; 140 u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
135 u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; 141 u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
136 u8 regdomain; 142 u8 regdomain;
137 u8 default_regdomain; 143 u8 default_regdomain;
138 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;
139}; 158};
140 159
141static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac) 160static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac)