aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco
diff options
context:
space:
mode:
authorDavid Kilroy <kilroyd@googlemail.com>2009-08-05 16:23:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:12:45 -0400
commit4af198fb7a99b07980b1bd52df550ba3f24688df (patch)
tree8955b89e70dbf82bcf7537130f43a8a1ab2350e3 /drivers/net/wireless/orinoco
parent2b2603515e26466685895e93cae59bc061389f11 (diff)
orinoco: consolidate storage of WEP and TKIP keys
When TKIP support was added, we stored the keys separately to avoid issues when both TKIP and WEP keys are sent to the driver. We need to consolidate the storage to convert to cfg80211, so do this first and try iron out the issues. Signed-off-by: David Kilroy <kilroyd@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/orinoco')
-rw-r--r--drivers/net/wireless/orinoco/hw.c42
-rw-r--r--drivers/net/wireless/orinoco/main.c33
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h4
-rw-r--r--drivers/net/wireless/orinoco/wext.c122
4 files changed, 139 insertions, 62 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);
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 931f7deddb54..2c7dc65cd2be 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -341,12 +341,14 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
341{ 341{
342 struct orinoco_private *priv = ndev_priv(dev); 342 struct orinoco_private *priv = ndev_priv(dev);
343 struct net_device_stats *stats = &priv->stats; 343 struct net_device_stats *stats = &priv->stats;
344 struct orinoco_tkip_key *key;
344 hermes_t *hw = &priv->hw; 345 hermes_t *hw = &priv->hw;
345 int err = 0; 346 int err = 0;
346 u16 txfid = priv->txfid; 347 u16 txfid = priv->txfid;
347 struct ethhdr *eh; 348 struct ethhdr *eh;
348 int tx_control; 349 int tx_control;
349 unsigned long flags; 350 unsigned long flags;
351 int do_mic;
350 352
351 if (!netif_running(dev)) { 353 if (!netif_running(dev)) {
352 printk(KERN_ERR "%s: Tx on stopped device!\n", 354 printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -378,9 +380,14 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
378 if (skb->len < ETH_HLEN) 380 if (skb->len < ETH_HLEN)
379 goto drop; 381 goto drop;
380 382
383 key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
384
385 do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
386 (key != NULL));
387
381 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; 388 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
382 389
383 if (priv->encode_alg == ORINOCO_ALG_TKIP) 390 if (do_mic)
384 tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) | 391 tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
385 HERMES_TXCTRL_MIC; 392 HERMES_TXCTRL_MIC;
386 393
@@ -462,7 +469,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
462 } 469 }
463 470
464 /* Calculate Michael MIC */ 471 /* Calculate Michael MIC */
465 if (priv->encode_alg == ORINOCO_ALG_TKIP) { 472 if (do_mic) {
466 u8 mic_buf[MICHAEL_MIC_LEN + 1]; 473 u8 mic_buf[MICHAEL_MIC_LEN + 1];
467 u8 *mic; 474 u8 *mic;
468 size_t offset; 475 size_t offset;
@@ -480,8 +487,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
480 len = MICHAEL_MIC_LEN; 487 len = MICHAEL_MIC_LEN;
481 } 488 }
482 489
483 orinoco_mic(priv->tx_tfm_mic, 490 orinoco_mic(priv->tx_tfm_mic, key->tx_mic,
484 priv->tkip_key[priv->tx_key].tx_mic,
485 eh->h_dest, eh->h_source, 0 /* priority */, 491 eh->h_dest, eh->h_source, 0 /* priority */,
486 skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic); 492 skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
487 493
@@ -926,6 +932,7 @@ static void orinoco_rx(struct net_device *dev,
926 932
927 /* Calculate and check MIC */ 933 /* Calculate and check MIC */
928 if (status & HERMES_RXSTAT_MIC) { 934 if (status & HERMES_RXSTAT_MIC) {
935 struct orinoco_tkip_key *key;
929 int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >> 936 int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
930 HERMES_MIC_KEY_ID_SHIFT); 937 HERMES_MIC_KEY_ID_SHIFT);
931 u8 mic[MICHAEL_MIC_LEN]; 938 u8 mic[MICHAEL_MIC_LEN];
@@ -939,14 +946,18 @@ static void orinoco_rx(struct net_device *dev,
939 skb_trim(skb, skb->len - MICHAEL_MIC_LEN); 946 skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
940 length -= MICHAEL_MIC_LEN; 947 length -= MICHAEL_MIC_LEN;
941 948
942 orinoco_mic(priv->rx_tfm_mic, 949 key = (struct orinoco_tkip_key *) priv->keys[key_id].key;
943 priv->tkip_key[key_id].rx_mic, 950
944 desc->addr1, 951 if (!key) {
945 src, 952 printk(KERN_WARNING "%s: Received encrypted frame from "
953 "%pM using key %i, but key is not installed\n",
954 dev->name, src, key_id);
955 goto drop;
956 }
957
958 orinoco_mic(priv->rx_tfm_mic, key->rx_mic, desc->addr1, src,
946 0, /* priority or QoS? */ 959 0, /* priority or QoS? */
947 skb->data, 960 skb->data, skb->len, &mic[0]);
948 skb->len,
949 &mic[0]);
950 961
951 if (memcmp(mic, rxmic, 962 if (memcmp(mic, rxmic,
952 MICHAEL_MIC_LEN)) { 963 MICHAEL_MIC_LEN)) {
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index badfc5665242..9ac6f1dda4b0 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -120,7 +120,8 @@ struct orinoco_private {
120 enum nl80211_iftype iw_mode; 120 enum nl80211_iftype iw_mode;
121 enum orinoco_alg encode_alg; 121 enum orinoco_alg encode_alg;
122 u16 wep_restrict, tx_key; 122 u16 wep_restrict, tx_key;
123 struct orinoco_key keys[ORINOCO_MAX_KEYS]; 123 struct key_params keys[ORINOCO_MAX_KEYS];
124
124 int bitratemode; 125 int bitratemode;
125 char nick[IW_ESSID_MAX_SIZE+1]; 126 char nick[IW_ESSID_MAX_SIZE+1];
126 char desired_essid[IW_ESSID_MAX_SIZE+1]; 127 char desired_essid[IW_ESSID_MAX_SIZE+1];
@@ -150,7 +151,6 @@ struct orinoco_private {
150 u8 *wpa_ie; 151 u8 *wpa_ie;
151 int wpa_ie_len; 152 int wpa_ie_len;
152 153
153 struct orinoco_tkip_key tkip_key[ORINOCO_MAX_KEYS];
154 struct crypto_hash *rx_tfm_mic; 154 struct crypto_hash *rx_tfm_mic;
155 struct crypto_hash *tx_tfm_mic; 155 struct crypto_hash *tx_tfm_mic;
156 156
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index f68bbe383e0f..3e56f7643df5 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -22,6 +22,67 @@
22 22
23#define MAX_RID_LEN 1024 23#define MAX_RID_LEN 1024
24 24
25/* Helper routine to record keys
26 * Do not call from interrupt context */
27static int orinoco_set_key(struct orinoco_private *priv, int index,
28 enum orinoco_alg alg, const u8 *key, int key_len,
29 const u8 *seq, int seq_len)
30{
31 kzfree(priv->keys[index].key);
32 kzfree(priv->keys[index].seq);
33
34 if (key_len) {
35 priv->keys[index].key = kzalloc(key_len, GFP_KERNEL);
36 if (!priv->keys[index].key)
37 goto nomem;
38 } else
39 priv->keys[index].key = NULL;
40
41 if (seq_len) {
42 priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL);
43 if (!priv->keys[index].seq)
44 goto free_key;
45 } else
46 priv->keys[index].seq = NULL;
47
48 priv->keys[index].key_len = key_len;
49 priv->keys[index].seq_len = seq_len;
50
51 if (key_len)
52 memcpy(priv->keys[index].key, key, key_len);
53 if (seq_len)
54 memcpy(priv->keys[index].seq, seq, seq_len);
55
56 switch (alg) {
57 case ORINOCO_ALG_TKIP:
58 priv->keys[index].cipher = WLAN_CIPHER_SUITE_TKIP;
59 break;
60
61 case ORINOCO_ALG_WEP:
62 priv->keys[index].cipher = (key_len > SMALL_KEY_SIZE) ?
63 WLAN_CIPHER_SUITE_WEP104 : WLAN_CIPHER_SUITE_WEP40;
64 break;
65
66 case ORINOCO_ALG_NONE:
67 default:
68 priv->keys[index].cipher = 0;
69 break;
70 }
71
72 return 0;
73
74free_key:
75 kfree(priv->keys[index].key);
76 priv->keys[index].key = NULL;
77
78nomem:
79 priv->keys[index].key_len = 0;
80 priv->keys[index].seq_len = 0;
81 priv->keys[index].cipher = 0;
82
83 return -ENOMEM;
84}
85
25static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) 86static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
26{ 87{
27 struct orinoco_private *priv = ndev_priv(dev); 88 struct orinoco_private *priv = ndev_priv(dev);
@@ -180,7 +241,6 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
180 int setindex = priv->tx_key; 241 int setindex = priv->tx_key;
181 enum orinoco_alg encode_alg = priv->encode_alg; 242 enum orinoco_alg encode_alg = priv->encode_alg;
182 int restricted = priv->wep_restrict; 243 int restricted = priv->wep_restrict;
183 u16 xlen = 0;
184 int err = -EINPROGRESS; /* Call commit handler */ 244 int err = -EINPROGRESS; /* Call commit handler */
185 unsigned long flags; 245 unsigned long flags;
186 246
@@ -207,12 +267,6 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
207 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) 267 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
208 index = priv->tx_key; 268 index = priv->tx_key;
209 269
210 /* Adjust key length to a supported value */
211 if (erq->length > SMALL_KEY_SIZE)
212 xlen = LARGE_KEY_SIZE;
213 else /* (erq->length > 0) */
214 xlen = SMALL_KEY_SIZE;
215
216 /* Switch on WEP if off */ 270 /* Switch on WEP if off */
217 if (encode_alg != ORINOCO_ALG_WEP) { 271 if (encode_alg != ORINOCO_ALG_WEP) {
218 setindex = index; 272 setindex = index;
@@ -229,7 +283,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
229 } 283 }
230 } else { 284 } else {
231 /* Set the index : Check that the key is valid */ 285 /* Set the index : Check that the key is valid */
232 if (priv->keys[index].len == 0) { 286 if (priv->keys[index].key_len == 0) {
233 err = -EINVAL; 287 err = -EINVAL;
234 goto out; 288 goto out;
235 } 289 }
@@ -245,10 +299,8 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
245 restricted = 1; 299 restricted = 1;
246 300
247 if (erq->pointer && erq->length > 0) { 301 if (erq->pointer && erq->length > 0) {
248 priv->keys[index].len = cpu_to_le16(xlen); 302 err = orinoco_set_key(priv, index, ORINOCO_ALG_WEP, keybuf,
249 memset(priv->keys[index].data, 0, 303 erq->length, NULL, 0);
250 sizeof(priv->keys[index].data));
251 memcpy(priv->keys[index].data, keybuf, erq->length);
252 } 304 }
253 priv->tx_key = setindex; 305 priv->tx_key = setindex;
254 306
@@ -277,7 +329,6 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev,
277{ 329{
278 struct orinoco_private *priv = ndev_priv(dev); 330 struct orinoco_private *priv = ndev_priv(dev);
279 int index = (erq->flags & IW_ENCODE_INDEX) - 1; 331 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
280 u16 xlen = 0;
281 unsigned long flags; 332 unsigned long flags;
282 333
283 if (!priv->has_wep) 334 if (!priv->has_wep)
@@ -299,11 +350,9 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev,
299 else 350 else
300 erq->flags |= IW_ENCODE_OPEN; 351 erq->flags |= IW_ENCODE_OPEN;
301 352
302 xlen = le16_to_cpu(priv->keys[index].len); 353 erq->length = priv->keys[index].key_len;
303 354
304 erq->length = xlen; 355 memcpy(keybuf, priv->keys[index].key, erq->length);
305
306 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
307 356
308 orinoco_unlock(priv, &flags); 357 orinoco_unlock(priv, &flags);
309 return 0; 358 return 0;
@@ -789,7 +838,6 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
789 int idx, alg = ext->alg, set_key = 1; 838 int idx, alg = ext->alg, set_key = 1;
790 unsigned long flags; 839 unsigned long flags;
791 int err = -EINVAL; 840 int err = -EINVAL;
792 u16 key_len;
793 841
794 if (orinoco_lock(priv, &flags) != 0) 842 if (orinoco_lock(priv, &flags) != 0)
795 return -EBUSY; 843 return -EBUSY;
@@ -822,24 +870,17 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
822 switch (alg) { 870 switch (alg) {
823 case IW_ENCODE_ALG_NONE: 871 case IW_ENCODE_ALG_NONE:
824 priv->encode_alg = ORINOCO_ALG_NONE; 872 priv->encode_alg = ORINOCO_ALG_NONE;
825 priv->keys[idx].len = 0; 873 err = orinoco_set_key(priv, idx, ORINOCO_ALG_NONE,
874 NULL, 0, NULL, 0);
826 break; 875 break;
827 876
828 case IW_ENCODE_ALG_WEP: 877 case IW_ENCODE_ALG_WEP:
829 if (ext->key_len > SMALL_KEY_SIZE) 878 if (ext->key_len <= 0)
830 key_len = LARGE_KEY_SIZE;
831 else if (ext->key_len > 0)
832 key_len = SMALL_KEY_SIZE;
833 else
834 goto out; 879 goto out;
835 880
836 priv->encode_alg = ORINOCO_ALG_WEP; 881 priv->encode_alg = ORINOCO_ALG_WEP;
837 priv->keys[idx].len = cpu_to_le16(key_len); 882 err = orinoco_set_key(priv, idx, ORINOCO_ALG_WEP,
838 883 ext->key, ext->key_len, NULL, 0);
839 key_len = min(ext->key_len, key_len);
840
841 memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
842 memcpy(priv->keys[idx].data, ext->key, key_len);
843 break; 884 break;
844 885
845 case IW_ENCODE_ALG_TKIP: 886 case IW_ENCODE_ALG_TKIP:
@@ -847,20 +888,21 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
847 u8 *tkip_iv = NULL; 888 u8 *tkip_iv = NULL;
848 889
849 if (!priv->has_wpa || 890 if (!priv->has_wpa ||
850 (ext->key_len > sizeof(priv->tkip_key[0]))) 891 (ext->key_len > sizeof(struct orinoco_tkip_key)))
851 goto out; 892 goto out;
852 893
853 priv->encode_alg = ORINOCO_ALG_TKIP; 894 priv->encode_alg = ORINOCO_ALG_TKIP;
854 memset(&priv->tkip_key[idx], 0,
855 sizeof(priv->tkip_key[idx]));
856 memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
857 895
858 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) 896 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
859 tkip_iv = &ext->rx_seq[0]; 897 tkip_iv = &ext->rx_seq[0];
860 898
899 err = orinoco_set_key(priv, idx, ORINOCO_ALG_TKIP,
900 ext->key, ext->key_len, tkip_iv,
901 ORINOCO_SEQ_LEN);
902
861 err = __orinoco_hw_set_tkip_key(priv, idx, 903 err = __orinoco_hw_set_tkip_key(priv, idx,
862 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 904 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
863 (u8 *) &priv->tkip_key[idx], 905 priv->keys[idx].key,
864 tkip_iv, ORINOCO_SEQ_LEN, NULL, 0); 906 tkip_iv, ORINOCO_SEQ_LEN, NULL, 0);
865 if (err) 907 if (err)
866 printk(KERN_ERR "%s: Error %d setting TKIP key" 908 printk(KERN_ERR "%s: Error %d setting TKIP key"
@@ -918,16 +960,14 @@ static int orinoco_ioctl_get_encodeext(struct net_device *dev,
918 break; 960 break;
919 case ORINOCO_ALG_WEP: 961 case ORINOCO_ALG_WEP:
920 ext->alg = IW_ENCODE_ALG_WEP; 962 ext->alg = IW_ENCODE_ALG_WEP;
921 ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len), 963 ext->key_len = min(priv->keys[idx].key_len, max_key_len);
922 max_key_len); 964 memcpy(ext->key, priv->keys[idx].key, ext->key_len);
923 memcpy(ext->key, priv->keys[idx].data, ext->key_len);
924 encoding->flags |= IW_ENCODE_ENABLED; 965 encoding->flags |= IW_ENCODE_ENABLED;
925 break; 966 break;
926 case ORINOCO_ALG_TKIP: 967 case ORINOCO_ALG_TKIP:
927 ext->alg = IW_ENCODE_ALG_TKIP; 968 ext->alg = IW_ENCODE_ALG_TKIP;
928 ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key), 969 ext->key_len = min(priv->keys[idx].key_len, max_key_len);
929 max_key_len); 970 memcpy(ext->key, priv->keys[idx].key, ext->key_len);
930 memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
931 encoding->flags |= IW_ENCODE_ENABLED; 971 encoding->flags |= IW_ENCODE_ENABLED;
932 break; 972 break;
933 } 973 }