diff options
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index ba7a5ab7fe1d..7b31a327b24a 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -992,6 +992,52 @@ static void b43_clear_keys(struct b43_wldev *dev) | |||
992 | b43_key_clear(dev, i); | 992 | b43_key_clear(dev, i); |
993 | } | 993 | } |
994 | 994 | ||
995 | static void b43_dump_keymemory(struct b43_wldev *dev) | ||
996 | { | ||
997 | unsigned int i, index, offset; | ||
998 | DECLARE_MAC_BUF(macbuf); | ||
999 | u8 mac[ETH_ALEN]; | ||
1000 | u16 algo; | ||
1001 | u32 rcmta0; | ||
1002 | u16 rcmta1; | ||
1003 | u64 hf; | ||
1004 | struct b43_key *key; | ||
1005 | |||
1006 | if (!b43_debug(dev, B43_DBG_KEYS)) | ||
1007 | return; | ||
1008 | |||
1009 | hf = b43_hf_read(dev); | ||
1010 | b43dbg(dev->wl, "Hardware key memory dump: USEDEFKEYS=%u\n", | ||
1011 | !!(hf & B43_HF_USEDEFKEYS)); | ||
1012 | for (index = 0; index < dev->max_nr_keys; index++) { | ||
1013 | key = &(dev->key[index]); | ||
1014 | printk(KERN_DEBUG "Key slot %02u: %s", | ||
1015 | index, (key->keyconf == NULL) ? " " : "*"); | ||
1016 | offset = dev->ktp + (index * B43_SEC_KEYSIZE); | ||
1017 | for (i = 0; i < B43_SEC_KEYSIZE; i += 2) { | ||
1018 | u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i); | ||
1019 | printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF)); | ||
1020 | } | ||
1021 | |||
1022 | algo = b43_shm_read16(dev, B43_SHM_SHARED, | ||
1023 | B43_SHM_SH_KEYIDXBLOCK + (index * 2)); | ||
1024 | printk(" Algo: %04X/%02X", algo, key->algorithm); | ||
1025 | |||
1026 | if (index >= 4) { | ||
1027 | rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA, | ||
1028 | ((index - 4) * 2) + 0); | ||
1029 | rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA, | ||
1030 | ((index - 4) * 2) + 1); | ||
1031 | *((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0); | ||
1032 | *((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1); | ||
1033 | printk(" MAC: %s", | ||
1034 | print_mac(macbuf, mac)); | ||
1035 | } else | ||
1036 | printk(" DEFAULT KEY"); | ||
1037 | printk("\n"); | ||
1038 | } | ||
1039 | } | ||
1040 | |||
995 | void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | 1041 | void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) |
996 | { | 1042 | { |
997 | u32 macctl; | 1043 | u32 macctl; |
@@ -3324,7 +3370,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3324 | unsigned long flags; | 3370 | unsigned long flags; |
3325 | int antenna; | 3371 | int antenna; |
3326 | int err = 0; | 3372 | int err = 0; |
3327 | u32 savedirqs; | ||
3328 | 3373 | ||
3329 | mutex_lock(&wl->mutex); | 3374 | mutex_lock(&wl->mutex); |
3330 | 3375 | ||
@@ -3335,24 +3380,14 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3335 | dev = wl->current_dev; | 3380 | dev = wl->current_dev; |
3336 | phy = &dev->phy; | 3381 | phy = &dev->phy; |
3337 | 3382 | ||
3383 | b43_mac_suspend(dev); | ||
3384 | |||
3338 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 3385 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
3339 | b43_set_retry_limits(dev, conf->short_frame_max_tx_count, | 3386 | b43_set_retry_limits(dev, conf->short_frame_max_tx_count, |
3340 | conf->long_frame_max_tx_count); | 3387 | conf->long_frame_max_tx_count); |
3341 | changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS; | 3388 | changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS; |
3342 | if (!changed) | 3389 | if (!changed) |
3343 | goto out_unlock_mutex; | 3390 | goto out_mac_enable; |
3344 | |||
3345 | /* Disable IRQs while reconfiguring the device. | ||
3346 | * This makes it possible to drop the spinlock throughout | ||
3347 | * the reconfiguration process. */ | ||
3348 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
3349 | if (b43_status(dev) < B43_STAT_STARTED) { | ||
3350 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3351 | goto out_unlock_mutex; | ||
3352 | } | ||
3353 | savedirqs = b43_interrupt_disable(dev, B43_IRQ_ALL); | ||
3354 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3355 | b43_synchronize_irq(dev); | ||
3356 | 3391 | ||
3357 | /* Switch to the requested channel. | 3392 | /* Switch to the requested channel. |
3358 | * The firmware takes care of races with the TX handler. */ | 3393 | * The firmware takes care of races with the TX handler. */ |
@@ -3399,11 +3434,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3399 | } | 3434 | } |
3400 | } | 3435 | } |
3401 | 3436 | ||
3402 | spin_lock_irqsave(&wl->irq_lock, flags); | 3437 | out_mac_enable: |
3403 | b43_interrupt_enable(dev, savedirqs); | 3438 | b43_mac_enable(dev); |
3404 | mmiowb(); | 3439 | out_unlock_mutex: |
3405 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3406 | out_unlock_mutex: | ||
3407 | mutex_unlock(&wl->mutex); | 3440 | mutex_unlock(&wl->mutex); |
3408 | 3441 | ||
3409 | return err; | 3442 | return err; |
@@ -3461,27 +3494,12 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw, | |||
3461 | { | 3494 | { |
3462 | struct b43_wl *wl = hw_to_b43_wl(hw); | 3495 | struct b43_wl *wl = hw_to_b43_wl(hw); |
3463 | struct b43_wldev *dev; | 3496 | struct b43_wldev *dev; |
3464 | struct b43_phy *phy; | ||
3465 | unsigned long flags; | ||
3466 | u32 savedirqs; | ||
3467 | 3497 | ||
3468 | mutex_lock(&wl->mutex); | 3498 | mutex_lock(&wl->mutex); |
3469 | 3499 | ||
3470 | dev = wl->current_dev; | 3500 | dev = wl->current_dev; |
3471 | phy = &dev->phy; | 3501 | if (!dev || b43_status(dev) < B43_STAT_STARTED) |
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; | 3502 | 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); | 3503 | b43_mac_suspend(dev); |
3486 | 3504 | ||
3487 | if (changed & BSS_CHANGED_BASIC_RATES) | 3505 | if (changed & BSS_CHANGED_BASIC_RATES) |
@@ -3495,13 +3513,7 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw, | |||
3495 | } | 3513 | } |
3496 | 3514 | ||
3497 | b43_mac_enable(dev); | 3515 | b43_mac_enable(dev); |
3498 | 3516 | out_unlock_mutex: | |
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); | 3517 | mutex_unlock(&wl->mutex); |
3506 | 3518 | ||
3507 | return; | 3519 | return; |
@@ -3599,15 +3611,18 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3599 | default: | 3611 | default: |
3600 | B43_WARN_ON(1); | 3612 | B43_WARN_ON(1); |
3601 | } | 3613 | } |
3614 | |||
3602 | out_unlock: | 3615 | out_unlock: |
3603 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3604 | mutex_unlock(&wl->mutex); | ||
3605 | if (!err) { | 3616 | if (!err) { |
3606 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " | 3617 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " |
3607 | "mac: %pM\n", | 3618 | "mac: %pM\n", |
3608 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, | 3619 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, |
3609 | addr); | 3620 | addr); |
3621 | b43_dump_keymemory(dev); | ||
3610 | } | 3622 | } |
3623 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3624 | mutex_unlock(&wl->mutex); | ||
3625 | |||
3611 | return err; | 3626 | return err; |
3612 | } | 3627 | } |
3613 | 3628 | ||