aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43legacy
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-11-06 09:18:11 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-21 11:06:06 -0500
commit7f3704e992ee4044f8e0068e060458377004473a (patch)
tree28ecc56df8b69a74a25773ec1ac5fcd4bad4ac18 /drivers/net/wireless/b43legacy
parent3e4127fa6db34765685599fb8d1177e51850a63c (diff)
b43legacy: implement short slot and basic rate handling
This implements proper short slot handling and adds code to program the hardware for the correct response rates derived from the basic rate set for the current BSS. (port from b43) Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43legacy')
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h5
-rw-r--r--drivers/net/wireless/b43legacy/main.c111
2 files changed, 103 insertions, 13 deletions
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index c40078e1fff9..97b0e06dfe21 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -145,6 +145,10 @@
145#define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */ 145#define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */
146#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */ 146#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */
147/* SHM_SHARED rate tables */ 147/* SHM_SHARED rate tables */
148#define B43legacy_SHM_SH_OFDMDIRECT 0x0480 /* Pointer to OFDM direct map */
149#define B43legacy_SHM_SH_OFDMBASIC 0x04A0 /* Pointer to OFDM basic rate map */
150#define B43legacy_SHM_SH_CCKDIRECT 0x04C0 /* Pointer to CCK direct map */
151#define B43legacy_SHM_SH_CCKBASIC 0x04E0 /* Pointer to CCK basic rate map */
148/* SHM_SHARED microcode soft registers */ 152/* SHM_SHARED microcode soft registers */
149#define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */ 153#define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */
150#define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */ 154#define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */
@@ -663,7 +667,6 @@ struct b43legacy_wldev {
663 bool bad_frames_preempt;/* Use "Bad Frames Preemption". */ 667 bool bad_frames_preempt;/* Use "Bad Frames Preemption". */
664 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */ 668 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */
665 bool short_preamble; /* TRUE if using short preamble. */ 669 bool short_preamble; /* TRUE if using short preamble. */
666 bool short_slot; /* TRUE if using short slot timing. */
667 bool radio_hw_enable; /* State of radio hardware enable bit. */ 670 bool radio_hw_enable; /* State of radio hardware enable bit. */
668 671
669 /* PHY/Radio device. */ 672 /* PHY/Radio device. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 6c8eb4d2519a..c1324e31d2f6 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -576,13 +576,11 @@ static void b43legacy_set_slot_time(struct b43legacy_wldev *dev,
576static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev) 576static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
577{ 577{
578 b43legacy_set_slot_time(dev, 9); 578 b43legacy_set_slot_time(dev, 9);
579 dev->short_slot = 1;
580} 579}
581 580
582static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev) 581static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
583{ 582{
584 b43legacy_set_slot_time(dev, 20); 583 b43legacy_set_slot_time(dev, 20);
585 dev->short_slot = 0;
586} 584}
587 585
588/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. 586/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
@@ -2608,16 +2606,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
2608 if (conf->channel->hw_value != phy->channel) 2606 if (conf->channel->hw_value != phy->channel)
2609 b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); 2607 b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
2610 2608
2611 /* Enable/Disable ShortSlot timing. */
2612 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME))
2613 != dev->short_slot) {
2614 B43legacy_WARN_ON(phy->type != B43legacy_PHYTYPE_G);
2615 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)
2616 b43legacy_short_slot_timing_enable(dev);
2617 else
2618 b43legacy_short_slot_timing_disable(dev);
2619 }
2620
2621 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); 2609 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
2622 2610
2623 /* Adjust the desired TX power level. */ 2611 /* Adjust the desired TX power level. */
@@ -2662,6 +2650,104 @@ out_unlock_mutex:
2662 return err; 2650 return err;
2663} 2651}
2664 2652
2653static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
2654{
2655 struct ieee80211_supported_band *sband =
2656 dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
2657 struct ieee80211_rate *rate;
2658 int i;
2659 u16 basic, direct, offset, basic_offset, rateptr;
2660
2661 for (i = 0; i < sband->n_bitrates; i++) {
2662 rate = &sband->bitrates[i];
2663
2664 if (b43legacy_is_cck_rate(rate->hw_value)) {
2665 direct = B43legacy_SHM_SH_CCKDIRECT;
2666 basic = B43legacy_SHM_SH_CCKBASIC;
2667 offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
2668 offset &= 0xF;
2669 } else {
2670 direct = B43legacy_SHM_SH_OFDMDIRECT;
2671 basic = B43legacy_SHM_SH_OFDMBASIC;
2672 offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
2673 offset &= 0xF;
2674 }
2675
2676 rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
2677
2678 if (b43legacy_is_cck_rate(rate->hw_value)) {
2679 basic_offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
2680 basic_offset &= 0xF;
2681 } else {
2682 basic_offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
2683 basic_offset &= 0xF;
2684 }
2685
2686 /*
2687 * Get the pointer that we need to point to
2688 * from the direct map
2689 */
2690 rateptr = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
2691 direct + 2 * basic_offset);
2692 /* and write it to the basic map */
2693 b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
2694 basic + 2 * offset, rateptr);
2695 }
2696}
2697
2698static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2699 struct ieee80211_vif *vif,
2700 struct ieee80211_bss_conf *conf,
2701 u32 changed)
2702{
2703 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2704 struct b43legacy_wldev *dev;
2705 struct b43legacy_phy *phy;
2706 unsigned long flags;
2707 u32 savedirqs;
2708
2709 mutex_lock(&wl->mutex);
2710
2711 dev = wl->current_dev;
2712 phy = &dev->phy;
2713
2714 /* Disable IRQs while reconfiguring the device.
2715 * This makes it possible to drop the spinlock throughout
2716 * the reconfiguration process. */
2717 spin_lock_irqsave(&wl->irq_lock, flags);
2718 if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
2719 spin_unlock_irqrestore(&wl->irq_lock, flags);
2720 goto out_unlock_mutex;
2721 }
2722 savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
2723 spin_unlock_irqrestore(&wl->irq_lock, flags);
2724 b43legacy_synchronize_irq(dev);
2725
2726 b43legacy_mac_suspend(dev);
2727
2728 if (changed & BSS_CHANGED_BASIC_RATES)
2729 b43legacy_update_basic_rates(dev, conf->basic_rates);
2730
2731 if (changed & BSS_CHANGED_ERP_SLOT) {
2732 if (conf->use_short_slot)
2733 b43legacy_short_slot_timing_enable(dev);
2734 else
2735 b43legacy_short_slot_timing_disable(dev);
2736 }
2737
2738 b43legacy_mac_enable(dev);
2739
2740 spin_lock_irqsave(&wl->irq_lock, flags);
2741 b43legacy_interrupt_enable(dev, savedirqs);
2742 /* XXX: why? */
2743 mmiowb();
2744 spin_unlock_irqrestore(&wl->irq_lock, flags);
2745 out_unlock_mutex:
2746 mutex_unlock(&wl->mutex);
2747
2748 return;
2749}
2750
2665static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, 2751static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
2666 unsigned int changed, 2752 unsigned int changed,
2667 unsigned int *fflags, 2753 unsigned int *fflags,
@@ -3370,6 +3456,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
3370 .add_interface = b43legacy_op_add_interface, 3456 .add_interface = b43legacy_op_add_interface,
3371 .remove_interface = b43legacy_op_remove_interface, 3457 .remove_interface = b43legacy_op_remove_interface,
3372 .config = b43legacy_op_dev_config, 3458 .config = b43legacy_op_dev_config,
3459 .bss_info_changed = b43legacy_op_bss_info_changed,
3373 .config_interface = b43legacy_op_config_interface, 3460 .config_interface = b43legacy_op_config_interface,
3374 .configure_filter = b43legacy_op_configure_filter, 3461 .configure_filter = b43legacy_op_configure_filter,
3375 .get_stats = b43legacy_op_get_stats, 3462 .get_stats = b43legacy_op_get_stats,