diff options
Diffstat (limited to 'drivers/net/wireless/orinoco/hw.c')
-rw-r--r-- | drivers/net/wireless/orinoco/hw.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 5b1265426922..40d8dfa7eace 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -768,12 +768,29 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv) | |||
768 | { | 768 | { |
769 | hermes_t *hw = &priv->hw; | 769 | hermes_t *hw = &priv->hw; |
770 | int err = 0; | 770 | int err = 0; |
771 | int i; | ||
771 | 772 | ||
772 | switch (priv->firmware_type) { | 773 | switch (priv->firmware_type) { |
773 | case FIRMWARE_TYPE_AGERE: | 774 | case FIRMWARE_TYPE_AGERE: |
775 | { | ||
776 | struct orinoco_key keys[ORINOCO_MAX_KEYS]; | ||
777 | |||
778 | memset(&keys, 0, sizeof(keys)); | ||
779 | for (i = 0; i < ORINOCO_MAX_KEYS; i++) { | ||
780 | int len = min(priv->keys[i].key_len, | ||
781 | ORINOCO_MAX_KEY_SIZE); | ||
782 | memcpy(&keys[i].data, priv->keys[i].key, len); | ||
783 | if (len > SMALL_KEY_SIZE) | ||
784 | keys[i].len = cpu_to_le16(LARGE_KEY_SIZE); | ||
785 | else if (len > 0) | ||
786 | keys[i].len = cpu_to_le16(SMALL_KEY_SIZE); | ||
787 | else | ||
788 | keys[i].len = cpu_to_le16(0); | ||
789 | } | ||
790 | |||
774 | err = HERMES_WRITE_RECORD(hw, USER_BAP, | 791 | err = HERMES_WRITE_RECORD(hw, USER_BAP, |
775 | HERMES_RID_CNFWEPKEYS_AGERE, | 792 | HERMES_RID_CNFWEPKEYS_AGERE, |
776 | &priv->keys); | 793 | &keys); |
777 | if (err) | 794 | if (err) |
778 | return err; | 795 | return err; |
779 | err = hermes_write_wordrec(hw, USER_BAP, | 796 | err = hermes_write_wordrec(hw, USER_BAP, |
@@ -782,28 +799,38 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv) | |||
782 | if (err) | 799 | if (err) |
783 | return err; | 800 | return err; |
784 | break; | 801 | break; |
802 | } | ||
785 | case FIRMWARE_TYPE_INTERSIL: | 803 | case FIRMWARE_TYPE_INTERSIL: |
786 | case FIRMWARE_TYPE_SYMBOL: | 804 | case FIRMWARE_TYPE_SYMBOL: |
787 | { | 805 | { |
788 | int keylen; | 806 | int keylen; |
789 | int i; | ||
790 | 807 | ||
791 | /* Force uniform key length to work around | 808 | /* Force uniform key length to work around |
792 | * firmware bugs */ | 809 | * firmware bugs */ |
793 | keylen = le16_to_cpu(priv->keys[priv->tx_key].len); | 810 | keylen = priv->keys[priv->tx_key].key_len; |
794 | 811 | ||
795 | if (keylen > LARGE_KEY_SIZE) { | 812 | if (keylen > LARGE_KEY_SIZE) { |
796 | printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n", | 813 | printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n", |
797 | priv->ndev->name, priv->tx_key, keylen); | 814 | priv->ndev->name, priv->tx_key, keylen); |
798 | return -E2BIG; | 815 | return -E2BIG; |
799 | } | 816 | } else if (keylen > SMALL_KEY_SIZE) |
817 | keylen = LARGE_KEY_SIZE; | ||
818 | else if (keylen > 0) | ||
819 | keylen = SMALL_KEY_SIZE; | ||
820 | else | ||
821 | keylen = 0; | ||
800 | 822 | ||
801 | /* Write all 4 keys */ | 823 | /* Write all 4 keys */ |
802 | for (i = 0; i < ORINOCO_MAX_KEYS; i++) { | 824 | for (i = 0; i < ORINOCO_MAX_KEYS; i++) { |
825 | u8 key[LARGE_KEY_SIZE] = { 0 }; | ||
826 | |||
827 | memcpy(key, priv->keys[i].key, | ||
828 | priv->keys[i].key_len); | ||
829 | |||
803 | err = hermes_write_ltv(hw, USER_BAP, | 830 | err = hermes_write_ltv(hw, USER_BAP, |
804 | HERMES_RID_CNFDEFAULTKEY0 + i, | 831 | HERMES_RID_CNFDEFAULTKEY0 + i, |
805 | HERMES_BYTES_TO_RECLEN(keylen), | 832 | HERMES_BYTES_TO_RECLEN(keylen), |
806 | priv->keys[i].data); | 833 | key); |
807 | if (err) | 834 | if (err) |
808 | return err; | 835 | return err; |
809 | } | 836 | } |
@@ -829,8 +856,8 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv) | |||
829 | int auth_flag; | 856 | int auth_flag; |
830 | int enc_flag; | 857 | int enc_flag; |
831 | 858 | ||
832 | /* Setup WEP keys for WEP and WPA */ | 859 | /* Setup WEP keys */ |
833 | if (priv->encode_alg) | 860 | if (priv->encode_alg == ORINOCO_ALG_WEP) |
834 | __orinoco_hw_setup_wepkeys(priv); | 861 | __orinoco_hw_setup_wepkeys(priv); |
835 | 862 | ||
836 | if (priv->wep_restrict) | 863 | if (priv->wep_restrict) |
@@ -976,7 +1003,6 @@ int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx) | |||
976 | hermes_t *hw = &priv->hw; | 1003 | hermes_t *hw = &priv->hw; |
977 | int err; | 1004 | int err; |
978 | 1005 | ||
979 | memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx])); | ||
980 | err = hermes_write_wordrec(hw, USER_BAP, | 1006 | err = hermes_write_wordrec(hw, USER_BAP, |
981 | HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE, | 1007 | HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE, |
982 | key_idx); | 1008 | key_idx); |