diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy/main.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 111 |
1 files changed, 99 insertions, 12 deletions
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 6c8eb4d2519..c1324e31d2f 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, | |||
576 | static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev) | 576 | static 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 | ||
582 | static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev) | 581 | static 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 | ||
2653 | static 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 | |||
2698 | static 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 | |||
2665 | static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, | 2751 | static 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, |