|
@@ -576,13 +576,11 @@ static void b43legacy_set_slot_time(struct b43legacy_wldev *dev,
|
|
static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
|
|
static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
|
|
{
|
|
{
|
|
b43legacy_set_slot_time(dev, 9);
|
|
b43legacy_set_slot_time(dev, 9);
|
|
- dev->short_slot = 1;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
|
|
static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
|
|
{
|
|
{
|
|
b43legacy_set_slot_time(dev, 20);
|
|
b43legacy_set_slot_time(dev, 20);
|
|
- dev->short_slot = 0;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
|
|
/* 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,
|
|
if (conf->channel->hw_value != phy->channel)
|
|
if (conf->channel->hw_value != phy->channel)
|
|
b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
|
|
b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
|
|
|
|
|
|
- /* Enable/Disable ShortSlot timing. */
|
|
|
|
- if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME))
|
|
|
|
- != dev->short_slot) {
|
|
|
|
- B43legacy_WARN_ON(phy->type != B43legacy_PHYTYPE_G);
|
|
|
|
- if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)
|
|
|
|
- b43legacy_short_slot_timing_enable(dev);
|
|
|
|
- else
|
|
|
|
- b43legacy_short_slot_timing_disable(dev);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
|
|
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
|
|
|
|
|
|
/* Adjust the desired TX power level. */
|
|
/* Adjust the desired TX power level. */
|
|
@@ -2662,6 +2650,104 @@ out_unlock_mutex:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
|
|
|
|
+{
|
|
|
|
+ struct ieee80211_supported_band *sband =
|
|
|
|
+ dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
|
|
|
|
+ struct ieee80211_rate *rate;
|
|
|
|
+ int i;
|
|
|
|
+ u16 basic, direct, offset, basic_offset, rateptr;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < sband->n_bitrates; i++) {
|
|
|
|
+ rate = &sband->bitrates[i];
|
|
|
|
+
|
|
|
|
+ if (b43legacy_is_cck_rate(rate->hw_value)) {
|
|
|
|
+ direct = B43legacy_SHM_SH_CCKDIRECT;
|
|
|
|
+ basic = B43legacy_SHM_SH_CCKBASIC;
|
|
|
|
+ offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
|
|
|
|
+ offset &= 0xF;
|
|
|
|
+ } else {
|
|
|
|
+ direct = B43legacy_SHM_SH_OFDMDIRECT;
|
|
|
|
+ basic = B43legacy_SHM_SH_OFDMBASIC;
|
|
|
|
+ offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
|
|
|
|
+ offset &= 0xF;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
|
|
|
|
+
|
|
|
|
+ if (b43legacy_is_cck_rate(rate->hw_value)) {
|
|
|
|
+ basic_offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
|
|
|
|
+ basic_offset &= 0xF;
|
|
|
|
+ } else {
|
|
|
|
+ basic_offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
|
|
|
|
+ basic_offset &= 0xF;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Get the pointer that we need to point to
|
|
|
|
+ * from the direct map
|
|
|
|
+ */
|
|
|
|
+ rateptr = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
|
|
|
|
+ direct + 2 * basic_offset);
|
|
|
|
+ /* and write it to the basic map */
|
|
|
|
+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
|
|
|
|
+ basic + 2 * offset, rateptr);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
|
|
|
|
+ struct ieee80211_vif *vif,
|
|
|
|
+ struct ieee80211_bss_conf *conf,
|
|
|
|
+ u32 changed)
|
|
|
|
+{
|
|
|
|
+ struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
|
|
|
|
+ struct b43legacy_wldev *dev;
|
|
|
|
+ struct b43legacy_phy *phy;
|
|
|
|
+ unsigned long flags;
|
|
|
|
+ u32 savedirqs;
|
|
|
|
+
|
|
|
|
+ mutex_lock(&wl->mutex);
|
|
|
|
+
|
|
|
|
+ dev = wl->current_dev;
|
|
|
|
+ phy = &dev->phy;
|
|
|
|
+
|
|
|
|
+ /* Disable IRQs while reconfiguring the device.
|
|
|
|
+ * This makes it possible to drop the spinlock throughout
|
|
|
|
+ * the reconfiguration process. */
|
|
|
|
+ spin_lock_irqsave(&wl->irq_lock, flags);
|
|
|
|
+ if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
|
|
|
|
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
|
|
|
|
+ goto out_unlock_mutex;
|
|
|
|
+ }
|
|
|
|
+ savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
|
|
|
|
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
|
|
|
|
+ b43legacy_synchronize_irq(dev);
|
|
|
|
+
|
|
|
|
+ b43legacy_mac_suspend(dev);
|
|
|
|
+
|
|
|
|
+ if (changed & BSS_CHANGED_BASIC_RATES)
|
|
|
|
+ b43legacy_update_basic_rates(dev, conf->basic_rates);
|
|
|
|
+
|
|
|
|
+ if (changed & BSS_CHANGED_ERP_SLOT) {
|
|
|
|
+ if (conf->use_short_slot)
|
|
|
|
+ b43legacy_short_slot_timing_enable(dev);
|
|
|
|
+ else
|
|
|
|
+ b43legacy_short_slot_timing_disable(dev);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ b43legacy_mac_enable(dev);
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&wl->irq_lock, flags);
|
|
|
|
+ b43legacy_interrupt_enable(dev, savedirqs);
|
|
|
|
+ /* XXX: why? */
|
|
|
|
+ mmiowb();
|
|
|
|
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
|
|
|
|
+ out_unlock_mutex:
|
|
|
|
+ mutex_unlock(&wl->mutex);
|
|
|
|
+
|
|
|
|
+ return;
|
|
|
|
+}
|
|
|
|
+
|
|
static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
|
|
static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
|
|
unsigned int changed,
|
|
unsigned int changed,
|
|
unsigned int *fflags,
|
|
unsigned int *fflags,
|
|
@@ -3370,6 +3456,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
|
|
.add_interface = b43legacy_op_add_interface,
|
|
.add_interface = b43legacy_op_add_interface,
|
|
.remove_interface = b43legacy_op_remove_interface,
|
|
.remove_interface = b43legacy_op_remove_interface,
|
|
.config = b43legacy_op_dev_config,
|
|
.config = b43legacy_op_dev_config,
|
|
|
|
+ .bss_info_changed = b43legacy_op_bss_info_changed,
|
|
.config_interface = b43legacy_op_config_interface,
|
|
.config_interface = b43legacy_op_config_interface,
|
|
.configure_filter = b43legacy_op_configure_filter,
|
|
.configure_filter = b43legacy_op_configure_filter,
|
|
.get_stats = b43legacy_op_get_stats,
|
|
.get_stats = b43legacy_op_get_stats,
|