aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c111
1 files changed, 99 insertions, 12 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9d1768d5fbad..ba7a5ab7fe1d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -703,13 +703,11 @@ static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
703static void b43_short_slot_timing_enable(struct b43_wldev *dev) 703static void b43_short_slot_timing_enable(struct b43_wldev *dev)
704{ 704{
705 b43_set_slot_time(dev, 9); 705 b43_set_slot_time(dev, 9);
706 dev->short_slot = 1;
707} 706}
708 707
709static void b43_short_slot_timing_disable(struct b43_wldev *dev) 708static void b43_short_slot_timing_disable(struct b43_wldev *dev)
710{ 709{
711 b43_set_slot_time(dev, 20); 710 b43_set_slot_time(dev, 20);
712 dev->short_slot = 0;
713} 711}
714 712
715/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. 713/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
@@ -3361,16 +3359,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3361 if (conf->channel->hw_value != phy->channel) 3359 if (conf->channel->hw_value != phy->channel)
3362 b43_switch_channel(dev, conf->channel->hw_value); 3360 b43_switch_channel(dev, conf->channel->hw_value);
3363 3361
3364 /* Enable/Disable ShortSlot timing. */
3365 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
3366 dev->short_slot) {
3367 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
3368 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)
3369 b43_short_slot_timing_enable(dev);
3370 else
3371 b43_short_slot_timing_disable(dev);
3372 }
3373
3374 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); 3362 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
3375 3363
3376 /* Adjust the desired TX power level. */ 3364 /* Adjust the desired TX power level. */
@@ -3421,6 +3409,104 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3421 return err; 3409 return err;
3422} 3410}
3423 3411
3412static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates)
3413{
3414 struct ieee80211_supported_band *sband =
3415 dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)];
3416 struct ieee80211_rate *rate;
3417 int i;
3418 u16 basic, direct, offset, basic_offset, rateptr;
3419
3420 for (i = 0; i < sband->n_bitrates; i++) {
3421 rate = &sband->bitrates[i];
3422
3423 if (b43_is_cck_rate(rate->hw_value)) {
3424 direct = B43_SHM_SH_CCKDIRECT;
3425 basic = B43_SHM_SH_CCKBASIC;
3426 offset = b43_plcp_get_ratecode_cck(rate->hw_value);
3427 offset &= 0xF;
3428 } else {
3429 direct = B43_SHM_SH_OFDMDIRECT;
3430 basic = B43_SHM_SH_OFDMBASIC;
3431 offset = b43_plcp_get_ratecode_ofdm(rate->hw_value);
3432 offset &= 0xF;
3433 }
3434
3435 rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
3436
3437 if (b43_is_cck_rate(rate->hw_value)) {
3438 basic_offset = b43_plcp_get_ratecode_cck(rate->hw_value);
3439 basic_offset &= 0xF;
3440 } else {
3441 basic_offset = b43_plcp_get_ratecode_ofdm(rate->hw_value);
3442 basic_offset &= 0xF;
3443 }
3444
3445 /*
3446 * Get the pointer that we need to point to
3447 * from the direct map
3448 */
3449 rateptr = b43_shm_read16(dev, B43_SHM_SHARED,
3450 direct + 2 * basic_offset);
3451 /* and write it to the basic map */
3452 b43_shm_write16(dev, B43_SHM_SHARED, basic + 2 * offset,
3453 rateptr);
3454 }
3455}
3456
3457static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3458 struct ieee80211_vif *vif,
3459 struct ieee80211_bss_conf *conf,
3460 u32 changed)
3461{
3462 struct b43_wl *wl = hw_to_b43_wl(hw);
3463 struct b43_wldev *dev;
3464 struct b43_phy *phy;
3465 unsigned long flags;
3466 u32 savedirqs;
3467
3468 mutex_lock(&wl->mutex);
3469
3470 dev = wl->current_dev;
3471 phy = &dev->phy;
3472
3473 /* Disable IRQs while reconfiguring the device.
3474 * This makes it possible to drop the spinlock throughout
3475 * the reconfiguration process. */
3476 spin_lock_irqsave(&wl->irq_lock, flags);
3477 if (b43_status(dev) < B43_STAT_STARTED) {
3478 spin_unlock_irqrestore(&wl->irq_lock, flags);
3479 goto out_unlock_mutex;
3480 }
3481 savedirqs = b43_interrupt_disable(dev, B43_IRQ_ALL);
3482 spin_unlock_irqrestore(&wl->irq_lock, flags);
3483 b43_synchronize_irq(dev);
3484
3485 b43_mac_suspend(dev);
3486
3487 if (changed & BSS_CHANGED_BASIC_RATES)
3488 b43_update_basic_rates(dev, conf->basic_rates);
3489
3490 if (changed & BSS_CHANGED_ERP_SLOT) {
3491 if (conf->use_short_slot)
3492 b43_short_slot_timing_enable(dev);
3493 else
3494 b43_short_slot_timing_disable(dev);
3495 }
3496
3497 b43_mac_enable(dev);
3498
3499 spin_lock_irqsave(&wl->irq_lock, flags);
3500 b43_interrupt_enable(dev, savedirqs);
3501 /* XXX: why? */
3502 mmiowb();
3503 spin_unlock_irqrestore(&wl->irq_lock, flags);
3504 out_unlock_mutex:
3505 mutex_unlock(&wl->mutex);
3506
3507 return;
3508}
3509
3424static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 3510static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3425 const u8 *local_addr, const u8 *addr, 3511 const u8 *local_addr, const u8 *addr,
3426 struct ieee80211_key_conf *key) 3512 struct ieee80211_key_conf *key)
@@ -4210,6 +4296,7 @@ static const struct ieee80211_ops b43_hw_ops = {
4210 .add_interface = b43_op_add_interface, 4296 .add_interface = b43_op_add_interface,
4211 .remove_interface = b43_op_remove_interface, 4297 .remove_interface = b43_op_remove_interface,
4212 .config = b43_op_config, 4298 .config = b43_op_config,
4299 .bss_info_changed = b43_op_bss_info_changed,
4213 .config_interface = b43_op_config_interface, 4300 .config_interface = b43_op_config_interface,
4214 .configure_filter = b43_op_configure_filter, 4301 .configure_filter = b43_op_configure_filter,
4215 .set_key = b43_op_set_key, 4302 .set_key = b43_op_set_key,