diff options
author | Michael Buesch <mb@bu3sch.de> | 2008-12-19 15:30:52 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 15:58:33 -0500 |
commit | e808e586b77a10949e209f8a00cb8bf27e51df12 (patch) | |
tree | 3c50175f3e4d50e6d80c1b1255e5deb4db959e9a /drivers/net/wireless | |
parent | a73efd0a8552927ebe5dff84936f7fdac4f7e314 (diff) |
b43: Fixup set_key handling
This fixes the key handling for mac80211's new key->flags.
It also adds TX locking to the set_key handler and adds a comment why this is required.
This doesn't fix any known bugs.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c788bad10661..dad0781b4b67 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -937,8 +937,7 @@ static int b43_key_write(struct b43_wldev *dev, | |||
937 | B43_WARN_ON(dev->key[i].keyconf == keyconf); | 937 | B43_WARN_ON(dev->key[i].keyconf == keyconf); |
938 | } | 938 | } |
939 | if (index < 0) { | 939 | if (index < 0) { |
940 | /* Either pairwise key or address is 00:00:00:00:00:00 | 940 | /* Pairwise key. Get an empty slot for the key. */ |
941 | * for transmit-only keys. Search the index. */ | ||
942 | if (b43_new_kidx_api(dev)) | 941 | if (b43_new_kidx_api(dev)) |
943 | sta_keys_start = 4; | 942 | sta_keys_start = 4; |
944 | else | 943 | else |
@@ -951,7 +950,7 @@ static int b43_key_write(struct b43_wldev *dev, | |||
951 | } | 950 | } |
952 | } | 951 | } |
953 | if (index < 0) { | 952 | if (index < 0) { |
954 | b43err(dev->wl, "Out of hardware key memory\n"); | 953 | b43warn(dev->wl, "Out of hardware key memory\n"); |
955 | return -ENOSPC; | 954 | return -ENOSPC; |
956 | } | 955 | } |
957 | } else | 956 | } else |
@@ -3525,7 +3524,6 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3525 | { | 3524 | { |
3526 | struct b43_wl *wl = hw_to_b43_wl(hw); | 3525 | struct b43_wl *wl = hw_to_b43_wl(hw); |
3527 | struct b43_wldev *dev; | 3526 | struct b43_wldev *dev; |
3528 | unsigned long flags; | ||
3529 | u8 algorithm; | 3527 | u8 algorithm; |
3530 | u8 index; | 3528 | u8 index; |
3531 | int err; | 3529 | int err; |
@@ -3534,7 +3532,15 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3534 | return -ENOSPC; /* User disabled HW-crypto */ | 3532 | return -ENOSPC; /* User disabled HW-crypto */ |
3535 | 3533 | ||
3536 | mutex_lock(&wl->mutex); | 3534 | mutex_lock(&wl->mutex); |
3537 | spin_lock_irqsave(&wl->irq_lock, flags); | 3535 | spin_lock_irq(&wl->irq_lock); |
3536 | write_lock(&wl->tx_lock); | ||
3537 | /* Why do we need all this locking here? | ||
3538 | * mutex -> Every config operation must take it. | ||
3539 | * irq_lock -> We modify the dev->key array, which is accessed | ||
3540 | * in the IRQ handlers. | ||
3541 | * tx_lock -> We modify the dev->key array, which is accessed | ||
3542 | * in the TX handler. | ||
3543 | */ | ||
3538 | 3544 | ||
3539 | dev = wl->current_dev; | 3545 | dev = wl->current_dev; |
3540 | err = -ENODEV; | 3546 | err = -ENODEV; |
@@ -3551,7 +3557,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3551 | err = -EINVAL; | 3557 | err = -EINVAL; |
3552 | switch (key->alg) { | 3558 | switch (key->alg) { |
3553 | case ALG_WEP: | 3559 | case ALG_WEP: |
3554 | if (key->keylen == 5) | 3560 | if (key->keylen == LEN_WEP40) |
3555 | algorithm = B43_SEC_ALGO_WEP40; | 3561 | algorithm = B43_SEC_ALGO_WEP40; |
3556 | else | 3562 | else |
3557 | algorithm = B43_SEC_ALGO_WEP104; | 3563 | algorithm = B43_SEC_ALGO_WEP104; |
@@ -3578,17 +3584,14 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3578 | goto out_unlock; | 3584 | goto out_unlock; |
3579 | } | 3585 | } |
3580 | 3586 | ||
3581 | if (is_broadcast_ether_addr(addr)) { | 3587 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { |
3582 | /* addr is FF:FF:FF:FF:FF:FF for default keys */ | 3588 | /* Pairwise key with an assigned MAC address. */ |
3583 | err = b43_key_write(dev, index, algorithm, | ||
3584 | key->key, key->keylen, NULL, key); | ||
3585 | } else { | ||
3586 | /* | ||
3587 | * either pairwise key or address is 00:00:00:00:00:00 | ||
3588 | * for transmit-only keys | ||
3589 | */ | ||
3590 | err = b43_key_write(dev, -1, algorithm, | 3589 | err = b43_key_write(dev, -1, algorithm, |
3591 | key->key, key->keylen, addr, key); | 3590 | key->key, key->keylen, addr, key); |
3591 | } else { | ||
3592 | /* Group key */ | ||
3593 | err = b43_key_write(dev, index, algorithm, | ||
3594 | key->key, key->keylen, NULL, key); | ||
3592 | } | 3595 | } |
3593 | if (err) | 3596 | if (err) |
3594 | goto out_unlock; | 3597 | goto out_unlock; |
@@ -3620,7 +3623,8 @@ out_unlock: | |||
3620 | addr); | 3623 | addr); |
3621 | b43_dump_keymemory(dev); | 3624 | b43_dump_keymemory(dev); |
3622 | } | 3625 | } |
3623 | spin_unlock_irqrestore(&wl->irq_lock, flags); | 3626 | write_unlock(&wl->tx_lock); |
3627 | spin_unlock_irq(&wl->irq_lock); | ||
3624 | mutex_unlock(&wl->mutex); | 3628 | mutex_unlock(&wl->mutex); |
3625 | 3629 | ||
3626 | return err; | 3630 | return err; |