diff options
-rw-r--r-- | drivers/net/wireless/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/wireless/hermes.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco.c | 234 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco.h | 2 |
4 files changed, 229 insertions, 16 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index ea7da7117f4d..45bdf0b339bb 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -336,6 +336,8 @@ config HERMES | |||
336 | depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211 | 336 | depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211 |
337 | select WIRELESS_EXT | 337 | select WIRELESS_EXT |
338 | select FW_LOADER | 338 | select FW_LOADER |
339 | select CRYPTO | ||
340 | select CRYPTO_MICHAEL_MIC | ||
339 | ---help--- | 341 | ---help--- |
340 | A driver for 802.11b wireless cards based on the "Hermes" or | 342 | A driver for 802.11b wireless cards based on the "Hermes" or |
341 | Intersil HFA384x (Prism 2) MAC controller. This includes the vast | 343 | Intersil HFA384x (Prism 2) MAC controller. This includes the vast |
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h index 113f3f6cb2d1..8b13c8fef3dc 100644 --- a/drivers/net/wireless/hermes.h +++ b/drivers/net/wireless/hermes.h | |||
@@ -184,13 +184,18 @@ | |||
184 | #define HERMES_RXSTAT_ERR (0x0003) | 184 | #define HERMES_RXSTAT_ERR (0x0003) |
185 | #define HERMES_RXSTAT_BADCRC (0x0001) | 185 | #define HERMES_RXSTAT_BADCRC (0x0001) |
186 | #define HERMES_RXSTAT_UNDECRYPTABLE (0x0002) | 186 | #define HERMES_RXSTAT_UNDECRYPTABLE (0x0002) |
187 | #define HERMES_RXSTAT_MIC (0x0010) /* Frame contains MIC */ | ||
187 | #define HERMES_RXSTAT_MACPORT (0x0700) | 188 | #define HERMES_RXSTAT_MACPORT (0x0700) |
188 | #define HERMES_RXSTAT_PCF (0x1000) /* Frame was received in CF period */ | 189 | #define HERMES_RXSTAT_PCF (0x1000) /* Frame was received in CF period */ |
190 | #define HERMES_RXSTAT_MIC_KEY_ID (0x1800) /* MIC key used */ | ||
189 | #define HERMES_RXSTAT_MSGTYPE (0xE000) | 191 | #define HERMES_RXSTAT_MSGTYPE (0xE000) |
190 | #define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */ | 192 | #define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */ |
191 | #define HERMES_RXSTAT_TUNNEL (0x4000) /* bridge-tunnel encoded frame */ | 193 | #define HERMES_RXSTAT_TUNNEL (0x4000) /* bridge-tunnel encoded frame */ |
192 | #define HERMES_RXSTAT_WMP (0x6000) /* Wavelan-II Management Protocol frame */ | 194 | #define HERMES_RXSTAT_WMP (0x6000) /* Wavelan-II Management Protocol frame */ |
193 | 195 | ||
196 | /* Shift amount for key ID in RXSTAT and TXCTRL */ | ||
197 | #define HERMES_MIC_KEY_ID_SHIFT 11 | ||
198 | |||
194 | struct hermes_tx_descriptor { | 199 | struct hermes_tx_descriptor { |
195 | __le16 status; | 200 | __le16 status; |
196 | __le16 reserved1; | 201 | __le16 reserved1; |
@@ -209,6 +214,8 @@ struct hermes_tx_descriptor { | |||
209 | #define HERMES_TXCTRL_TX_OK (0x0002) /* ?? interrupt on Tx complete */ | 214 | #define HERMES_TXCTRL_TX_OK (0x0002) /* ?? interrupt on Tx complete */ |
210 | #define HERMES_TXCTRL_TX_EX (0x0004) /* ?? interrupt on Tx exception */ | 215 | #define HERMES_TXCTRL_TX_EX (0x0004) /* ?? interrupt on Tx exception */ |
211 | #define HERMES_TXCTRL_802_11 (0x0008) /* We supply 802.11 header */ | 216 | #define HERMES_TXCTRL_802_11 (0x0008) /* We supply 802.11 header */ |
217 | #define HERMES_TXCTRL_MIC (0x0010) /* 802.3 + TKIP */ | ||
218 | #define HERMES_TXCTRL_MIC_KEY_ID (0x1800) /* MIC Key ID mask */ | ||
212 | #define HERMES_TXCTRL_ALT_RTRY (0x0020) | 219 | #define HERMES_TXCTRL_ALT_RTRY (0x0020) |
213 | 220 | ||
214 | /* Inquiry constants and data types */ | 221 | /* Inquiry constants and data types */ |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 768b39452674..6a196c31de43 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -89,6 +89,9 @@ | |||
89 | #include <net/iw_handler.h> | 89 | #include <net/iw_handler.h> |
90 | #include <net/ieee80211.h> | 90 | #include <net/ieee80211.h> |
91 | 91 | ||
92 | #include <linux/scatterlist.h> | ||
93 | #include <linux/crypto.h> | ||
94 | |||
92 | #include "hermes_rid.h" | 95 | #include "hermes_rid.h" |
93 | #include "hermes_dld.h" | 96 | #include "hermes_dld.h" |
94 | #include "orinoco.h" | 97 | #include "orinoco.h" |
@@ -244,6 +247,74 @@ static int __orinoco_program_rids(struct net_device *dev); | |||
244 | static void __orinoco_set_multicast_list(struct net_device *dev); | 247 | static void __orinoco_set_multicast_list(struct net_device *dev); |
245 | 248 | ||
246 | /********************************************************************/ | 249 | /********************************************************************/ |
250 | /* Michael MIC crypto setup */ | ||
251 | /********************************************************************/ | ||
252 | #define MICHAEL_MIC_LEN 8 | ||
253 | static int orinoco_mic_init(struct orinoco_private *priv) | ||
254 | { | ||
255 | priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0); | ||
256 | if (IS_ERR(priv->tx_tfm_mic)) { | ||
257 | printk(KERN_DEBUG "orinoco_mic_init: could not allocate " | ||
258 | "crypto API michael_mic\n"); | ||
259 | priv->tx_tfm_mic = NULL; | ||
260 | return -ENOMEM; | ||
261 | } | ||
262 | |||
263 | priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0); | ||
264 | if (IS_ERR(priv->rx_tfm_mic)) { | ||
265 | printk(KERN_DEBUG "orinoco_mic_init: could not allocate " | ||
266 | "crypto API michael_mic\n"); | ||
267 | priv->rx_tfm_mic = NULL; | ||
268 | return -ENOMEM; | ||
269 | } | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static void orinoco_mic_free(struct orinoco_private *priv) | ||
275 | { | ||
276 | if (priv->tx_tfm_mic) | ||
277 | crypto_free_hash(priv->tx_tfm_mic); | ||
278 | if (priv->rx_tfm_mic) | ||
279 | crypto_free_hash(priv->rx_tfm_mic); | ||
280 | } | ||
281 | |||
282 | static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, | ||
283 | u8 *da, u8 *sa, u8 priority, | ||
284 | u8 *data, size_t data_len, u8 *mic) | ||
285 | { | ||
286 | struct hash_desc desc; | ||
287 | struct scatterlist sg[2]; | ||
288 | u8 hdr[ETH_HLEN + 2]; /* size of header + padding */ | ||
289 | |||
290 | if (tfm_michael == NULL) { | ||
291 | printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); | ||
292 | return -1; | ||
293 | } | ||
294 | |||
295 | /* Copy header into buffer. We need the padding on the end zeroed */ | ||
296 | memcpy(&hdr[0], da, ETH_ALEN); | ||
297 | memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN); | ||
298 | hdr[ETH_ALEN*2] = priority; | ||
299 | hdr[ETH_ALEN*2+1] = 0; | ||
300 | hdr[ETH_ALEN*2+2] = 0; | ||
301 | hdr[ETH_ALEN*2+3] = 0; | ||
302 | |||
303 | /* Use scatter gather to MIC header and data in one go */ | ||
304 | sg_init_table(sg, 2); | ||
305 | sg_set_buf(&sg[0], hdr, sizeof(hdr)); | ||
306 | sg_set_buf(&sg[1], data, data_len); | ||
307 | |||
308 | if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN)) | ||
309 | return -1; | ||
310 | |||
311 | desc.tfm = tfm_michael; | ||
312 | desc.flags = 0; | ||
313 | return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr), | ||
314 | mic); | ||
315 | } | ||
316 | |||
317 | /********************************************************************/ | ||
247 | /* Internal helper functions */ | 318 | /* Internal helper functions */ |
248 | /********************************************************************/ | 319 | /********************************************************************/ |
249 | 320 | ||
@@ -764,7 +835,6 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
764 | int err = 0; | 835 | int err = 0; |
765 | u16 txfid = priv->txfid; | 836 | u16 txfid = priv->txfid; |
766 | struct ethhdr *eh; | 837 | struct ethhdr *eh; |
767 | int data_off; | ||
768 | int tx_control; | 838 | int tx_control; |
769 | unsigned long flags; | 839 | unsigned long flags; |
770 | 840 | ||
@@ -797,10 +867,12 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
797 | if (skb->len < ETH_HLEN) | 867 | if (skb->len < ETH_HLEN) |
798 | goto drop; | 868 | goto drop; |
799 | 869 | ||
800 | eh = (struct ethhdr *)skb->data; | ||
801 | |||
802 | tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; | 870 | tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; |
803 | 871 | ||
872 | if (priv->encode_alg == IW_ENCODE_ALG_TKIP) | ||
873 | tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) | | ||
874 | HERMES_TXCTRL_MIC; | ||
875 | |||
804 | if (priv->has_alt_txcntl) { | 876 | if (priv->has_alt_txcntl) { |
805 | /* WPA enabled firmwares have tx_cntl at the end of | 877 | /* WPA enabled firmwares have tx_cntl at the end of |
806 | * the 802.11 header. So write zeroed descriptor and | 878 | * the 802.11 header. So write zeroed descriptor and |
@@ -842,6 +914,8 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
842 | HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); | 914 | HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); |
843 | } | 915 | } |
844 | 916 | ||
917 | eh = (struct ethhdr *)skb->data; | ||
918 | |||
845 | /* Encapsulate Ethernet-II frames */ | 919 | /* Encapsulate Ethernet-II frames */ |
846 | if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ | 920 | if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ |
847 | struct header_struct { | 921 | struct header_struct { |
@@ -851,33 +925,65 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
851 | 925 | ||
852 | /* Strip destination and source from the data */ | 926 | /* Strip destination and source from the data */ |
853 | skb_pull(skb, 2 * ETH_ALEN); | 927 | skb_pull(skb, 2 * ETH_ALEN); |
854 | data_off = HERMES_802_2_OFFSET + sizeof(encaps_hdr); | ||
855 | 928 | ||
856 | /* And move them to a separate header */ | 929 | /* And move them to a separate header */ |
857 | memcpy(&hdr.eth, eh, 2 * ETH_ALEN); | 930 | memcpy(&hdr.eth, eh, 2 * ETH_ALEN); |
858 | hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len); | 931 | hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len); |
859 | memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr)); | 932 | memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr)); |
860 | 933 | ||
861 | err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr), | 934 | /* Insert the SNAP header */ |
862 | txfid, HERMES_802_3_OFFSET); | 935 | if (skb_headroom(skb) < sizeof(hdr)) { |
863 | if (err) { | 936 | printk(KERN_ERR |
864 | if (net_ratelimit()) | 937 | "%s: Not enough headroom for 802.2 headers %d\n", |
865 | printk(KERN_ERR "%s: Error %d writing packet " | 938 | dev->name, skb_headroom(skb)); |
866 | "header to BAP\n", dev->name, err); | 939 | goto drop; |
867 | goto busy; | ||
868 | } | 940 | } |
869 | } else { /* IEEE 802.3 frame */ | 941 | eh = (struct ethhdr *) skb_push(skb, sizeof(hdr)); |
870 | data_off = HERMES_802_3_OFFSET; | 942 | memcpy(eh, &hdr, sizeof(hdr)); |
871 | } | 943 | } |
872 | 944 | ||
873 | err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len, | 945 | err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len, |
874 | txfid, data_off); | 946 | txfid, HERMES_802_3_OFFSET); |
875 | if (err) { | 947 | if (err) { |
876 | printk(KERN_ERR "%s: Error %d writing packet to BAP\n", | 948 | printk(KERN_ERR "%s: Error %d writing packet to BAP\n", |
877 | dev->name, err); | 949 | dev->name, err); |
878 | goto busy; | 950 | goto busy; |
879 | } | 951 | } |
880 | 952 | ||
953 | /* Calculate Michael MIC */ | ||
954 | if (priv->encode_alg == IW_ENCODE_ALG_TKIP) { | ||
955 | u8 mic_buf[MICHAEL_MIC_LEN + 1]; | ||
956 | u8 *mic; | ||
957 | size_t offset; | ||
958 | size_t len; | ||
959 | |||
960 | if (skb->len % 2) { | ||
961 | /* MIC start is on an odd boundary */ | ||
962 | mic_buf[0] = skb->data[skb->len - 1]; | ||
963 | mic = &mic_buf[1]; | ||
964 | offset = skb->len - 1; | ||
965 | len = MICHAEL_MIC_LEN + 1; | ||
966 | } else { | ||
967 | mic = &mic_buf[0]; | ||
968 | offset = skb->len; | ||
969 | len = MICHAEL_MIC_LEN; | ||
970 | } | ||
971 | |||
972 | michael_mic(priv->tx_tfm_mic, | ||
973 | priv->tkip_key[priv->tx_key].tx_mic, | ||
974 | eh->h_dest, eh->h_source, 0 /* priority */, | ||
975 | skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic); | ||
976 | |||
977 | /* Write the MIC */ | ||
978 | err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len, | ||
979 | txfid, HERMES_802_3_OFFSET + offset); | ||
980 | if (err) { | ||
981 | printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", | ||
982 | dev->name, err); | ||
983 | goto busy; | ||
984 | } | ||
985 | } | ||
986 | |||
881 | /* Finally, we actually initiate the send */ | 987 | /* Finally, we actually initiate the send */ |
882 | netif_stop_queue(dev); | 988 | netif_stop_queue(dev); |
883 | 989 | ||
@@ -892,7 +998,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
892 | } | 998 | } |
893 | 999 | ||
894 | dev->trans_start = jiffies; | 1000 | dev->trans_start = jiffies; |
895 | stats->tx_bytes += data_off + skb->len; | 1001 | stats->tx_bytes += HERMES_802_3_OFFSET + skb->len; |
896 | goto ok; | 1002 | goto ok; |
897 | 1003 | ||
898 | drop: | 1004 | drop: |
@@ -1172,6 +1278,25 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, | |||
1172 | stats->rx_dropped++; | 1278 | stats->rx_dropped++; |
1173 | } | 1279 | } |
1174 | 1280 | ||
1281 | /* Get tsc from the firmware */ | ||
1282 | static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, | ||
1283 | u8 *tsc) | ||
1284 | { | ||
1285 | hermes_t *hw = &priv->hw; | ||
1286 | int err = 0; | ||
1287 | u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE]; | ||
1288 | |||
1289 | if ((key < 0) || (key > 4)) | ||
1290 | return -EINVAL; | ||
1291 | |||
1292 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, | ||
1293 | sizeof(tsc_arr), NULL, &tsc_arr); | ||
1294 | if (!err) | ||
1295 | memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0])); | ||
1296 | |||
1297 | return err; | ||
1298 | } | ||
1299 | |||
1175 | static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | 1300 | static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) |
1176 | { | 1301 | { |
1177 | struct orinoco_private *priv = netdev_priv(dev); | 1302 | struct orinoco_private *priv = netdev_priv(dev); |
@@ -1240,6 +1365,11 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | |||
1240 | goto update_stats; | 1365 | goto update_stats; |
1241 | } | 1366 | } |
1242 | 1367 | ||
1368 | /* Payload size does not include Michael MIC. Increase payload | ||
1369 | * size to read it together with the data. */ | ||
1370 | if (status & HERMES_RXSTAT_MIC) | ||
1371 | length += MICHAEL_MIC_LEN; | ||
1372 | |||
1243 | /* We need space for the packet data itself, plus an ethernet | 1373 | /* We need space for the packet data itself, plus an ethernet |
1244 | header, plus 2 bytes so we can align the IP header on a | 1374 | header, plus 2 bytes so we can align the IP header on a |
1245 | 32bit boundary, plus 1 byte so we can read in odd length | 1375 | 32bit boundary, plus 1 byte so we can read in odd length |
@@ -1303,6 +1433,63 @@ static void orinoco_rx(struct net_device *dev, | |||
1303 | length = le16_to_cpu(desc->data_len); | 1433 | length = le16_to_cpu(desc->data_len); |
1304 | fc = le16_to_cpu(desc->frame_ctl); | 1434 | fc = le16_to_cpu(desc->frame_ctl); |
1305 | 1435 | ||
1436 | /* Calculate and check MIC */ | ||
1437 | if (status & HERMES_RXSTAT_MIC) { | ||
1438 | int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >> | ||
1439 | HERMES_MIC_KEY_ID_SHIFT); | ||
1440 | u8 mic[MICHAEL_MIC_LEN]; | ||
1441 | u8 *rxmic; | ||
1442 | u8 *src = (fc & IEEE80211_FCTL_FROMDS) ? | ||
1443 | desc->addr3 : desc->addr2; | ||
1444 | |||
1445 | /* Extract Michael MIC from payload */ | ||
1446 | rxmic = skb->data + skb->len - MICHAEL_MIC_LEN; | ||
1447 | |||
1448 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | ||
1449 | length -= MICHAEL_MIC_LEN; | ||
1450 | |||
1451 | michael_mic(priv->rx_tfm_mic, | ||
1452 | priv->tkip_key[key_id].rx_mic, | ||
1453 | desc->addr1, | ||
1454 | src, | ||
1455 | 0, /* priority or QoS? */ | ||
1456 | skb->data, | ||
1457 | skb->len, | ||
1458 | &mic[0]); | ||
1459 | |||
1460 | if (memcmp(mic, rxmic, | ||
1461 | MICHAEL_MIC_LEN)) { | ||
1462 | union iwreq_data wrqu; | ||
1463 | struct iw_michaelmicfailure wxmic; | ||
1464 | DECLARE_MAC_BUF(mac); | ||
1465 | |||
1466 | printk(KERN_WARNING "%s: " | ||
1467 | "Invalid Michael MIC in data frame from %s, " | ||
1468 | "using key %i\n", | ||
1469 | dev->name, print_mac(mac, src), key_id); | ||
1470 | |||
1471 | /* TODO: update stats */ | ||
1472 | |||
1473 | /* Notify userspace */ | ||
1474 | memset(&wxmic, 0, sizeof(wxmic)); | ||
1475 | wxmic.flags = key_id & IW_MICFAILURE_KEY_ID; | ||
1476 | wxmic.flags |= (desc->addr1[0] & 1) ? | ||
1477 | IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE; | ||
1478 | wxmic.src_addr.sa_family = ARPHRD_ETHER; | ||
1479 | memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN); | ||
1480 | |||
1481 | (void) orinoco_hw_get_tkip_iv(priv, key_id, | ||
1482 | &wxmic.tsc[0]); | ||
1483 | |||
1484 | memset(&wrqu, 0, sizeof(wrqu)); | ||
1485 | wrqu.data.length = sizeof(wxmic); | ||
1486 | wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, | ||
1487 | (char *) &wxmic); | ||
1488 | |||
1489 | goto drop; | ||
1490 | } | ||
1491 | } | ||
1492 | |||
1306 | /* Handle decapsulation | 1493 | /* Handle decapsulation |
1307 | * In most cases, the firmware tell us about SNAP frames. | 1494 | * In most cases, the firmware tell us about SNAP frames. |
1308 | * For some reason, the SNAP frames sent by LinkSys APs | 1495 | * For some reason, the SNAP frames sent by LinkSys APs |
@@ -1342,6 +1529,11 @@ static void orinoco_rx(struct net_device *dev, | |||
1342 | stats->rx_bytes += length; | 1529 | stats->rx_bytes += length; |
1343 | 1530 | ||
1344 | return; | 1531 | return; |
1532 | |||
1533 | drop: | ||
1534 | dev_kfree_skb(skb); | ||
1535 | stats->rx_errors++; | ||
1536 | stats->rx_dropped++; | ||
1345 | } | 1537 | } |
1346 | 1538 | ||
1347 | static void orinoco_rx_isr_tasklet(unsigned long data) | 1539 | static void orinoco_rx_isr_tasklet(unsigned long data) |
@@ -3112,8 +3304,14 @@ static int orinoco_init(struct net_device *dev) | |||
3112 | else | 3304 | else |
3113 | printk("40-bit key\n"); | 3305 | printk("40-bit key\n"); |
3114 | } | 3306 | } |
3115 | if (priv->has_wpa) | 3307 | if (priv->has_wpa) { |
3116 | printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name); | 3308 | printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name); |
3309 | if (orinoco_mic_init(priv)) { | ||
3310 | printk(KERN_ERR "%s: Failed to setup MIC crypto " | ||
3311 | "algorithm. Disabling WPA support\n", dev->name); | ||
3312 | priv->has_wpa = 0; | ||
3313 | } | ||
3314 | } | ||
3117 | 3315 | ||
3118 | /* Now we have the firmware capabilities, allocate appropiate | 3316 | /* Now we have the firmware capabilities, allocate appropiate |
3119 | * sized scan buffers */ | 3317 | * sized scan buffers */ |
@@ -3292,6 +3490,9 @@ struct net_device | |||
3292 | dev->set_multicast_list = orinoco_set_multicast_list; | 3490 | dev->set_multicast_list = orinoco_set_multicast_list; |
3293 | /* we use the default eth_mac_addr for setting the MAC addr */ | 3491 | /* we use the default eth_mac_addr for setting the MAC addr */ |
3294 | 3492 | ||
3493 | /* Reserve space in skb for the SNAP header */ | ||
3494 | dev->hard_header_len += ENCAPS_OVERHEAD; | ||
3495 | |||
3295 | /* Set up default callbacks */ | 3496 | /* Set up default callbacks */ |
3296 | dev->open = orinoco_open; | 3497 | dev->open = orinoco_open; |
3297 | dev->stop = orinoco_stop; | 3498 | dev->stop = orinoco_stop; |
@@ -3327,6 +3528,7 @@ void free_orinocodev(struct net_device *dev) | |||
3327 | tasklet_kill(&priv->rx_tasklet); | 3528 | tasklet_kill(&priv->rx_tasklet); |
3328 | priv->wpa_ie_len = 0; | 3529 | priv->wpa_ie_len = 0; |
3329 | kfree(priv->wpa_ie); | 3530 | kfree(priv->wpa_ie); |
3531 | orinoco_mic_free(priv); | ||
3330 | orinoco_bss_data_free(priv); | 3532 | orinoco_bss_data_free(priv); |
3331 | free_netdev(dev); | 3533 | free_netdev(dev); |
3332 | } | 3534 | } |
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h index e0c9be3daa30..981570bd3b9d 100644 --- a/drivers/net/wireless/orinoco.h +++ b/drivers/net/wireless/orinoco.h | |||
@@ -158,6 +158,8 @@ struct orinoco_private { | |||
158 | int wpa_ie_len; | 158 | int wpa_ie_len; |
159 | 159 | ||
160 | struct orinoco_tkip_key tkip_key[ORINOCO_MAX_KEYS]; | 160 | struct orinoco_tkip_key tkip_key[ORINOCO_MAX_KEYS]; |
161 | struct crypto_hash *rx_tfm_mic; | ||
162 | struct crypto_hash *tx_tfm_mic; | ||
161 | 163 | ||
162 | unsigned int wpa_enabled:1; | 164 | unsigned int wpa_enabled:1; |
163 | unsigned int tkip_cm_active:1; | 165 | unsigned int tkip_cm_active:1; |