diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-20 13:30:31 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-20 13:30:31 -0500 |
commit | c7cace6437b2f8bbab5ef05b465738283a9a100a (patch) | |
tree | 304a7dca0354eaa8ac21aa05cd287e317fa21b8c /drivers/net/wireless/airo.c | |
parent | a90779bfc83b7489270a8ce2c3fc9df20dac2b24 (diff) | |
parent | 2e9ff56efbc005ab2b92b68df65940c7459446c6 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (150 commits)
[PATCH] ipw2100: Update version ipw2100 stamp to 1.2.2
[PATCH] ipw2100: move mutex.h include from ipw2100.c to ipw2100.h
[PATCH] ipw2100: semaphore to mutexes conversion
[PATCH] ipw2100: Fix radiotap code gcc warning
[PATCH] ipw2100: add radiotap headers to packtes captured in monitor mode
[PATCH] ipw2x00: expend Copyright to 2006
[PATCH] drivers/net/wireless/ipw2200.c: fix an array overun
[PATCH] ieee80211: Don't update network statistics from off-channel packets.
[PATCH] ipw2200: Update ipw2200 version stamp to 1.1.1
[PATCH] ipw2200: switch to the new ipw2200-fw-3.0 image format
[PATCH] ipw2200: wireless extension sensitivity threshold support
[PATCH] ipw2200: Enables the "slow diversity" algorithm
[PATCH] ipw2200: Set a meaningful silence threshold value
[PATCH] ipw2200: export `debug' module param only if CONFIG_IPW2200_DEBUG
[PATCH] ipw2200: Change debug level for firmware error logging
[PATCH] ipw2200: Filter unsupported channels out in ad-hoc mode
[PATCH] ipw2200: Fix ipw_sw_reset() implementation inconsistent with comment
[PATCH] ipw2200: Fix rf_kill is activated after mode change with 'disable=1'
[PATCH] ipw2200: remove the WPA card associates to non-WPA AP checking
[PATCH] ipw2200: Add signal level to iwlist scan output
...
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r-- | drivers/net/wireless/airo.c | 338 |
1 files changed, 281 insertions, 57 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a4c7ae94614d..864937a409e5 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/in.h> | 36 | #include <linux/in.h> |
37 | #include <linux/bitops.h> | 37 | #include <linux/bitops.h> |
38 | #include <linux/scatterlist.h> | 38 | #include <linux/scatterlist.h> |
39 | #include <linux/crypto.h> | ||
39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
40 | #include <asm/system.h> | 41 | #include <asm/system.h> |
41 | 42 | ||
@@ -87,14 +88,6 @@ static struct pci_driver airo_driver = { | |||
87 | #include <linux/delay.h> | 88 | #include <linux/delay.h> |
88 | #endif | 89 | #endif |
89 | 90 | ||
90 | /* Support Cisco MIC feature */ | ||
91 | #define MICSUPPORT | ||
92 | |||
93 | #if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO) | ||
94 | #warning MIC support requires Crypto API | ||
95 | #undef MICSUPPORT | ||
96 | #endif | ||
97 | |||
98 | /* Hack to do some power saving */ | 91 | /* Hack to do some power saving */ |
99 | #define POWER_ON_DOWN | 92 | #define POWER_ON_DOWN |
100 | 93 | ||
@@ -1118,7 +1111,6 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp); | |||
1118 | static int writerids(struct net_device *dev, aironet_ioctl *comp); | 1111 | static int writerids(struct net_device *dev, aironet_ioctl *comp); |
1119 | static int flashcard(struct net_device *dev, aironet_ioctl *comp); | 1112 | static int flashcard(struct net_device *dev, aironet_ioctl *comp); |
1120 | #endif /* CISCO_EXT */ | 1113 | #endif /* CISCO_EXT */ |
1121 | #ifdef MICSUPPORT | ||
1122 | static void micinit(struct airo_info *ai); | 1114 | static void micinit(struct airo_info *ai); |
1123 | static int micsetup(struct airo_info *ai); | 1115 | static int micsetup(struct airo_info *ai); |
1124 | static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); | 1116 | static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); |
@@ -1127,9 +1119,6 @@ static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, | |||
1127 | static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi); | 1119 | static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi); |
1128 | static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); | 1120 | static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); |
1129 | 1121 | ||
1130 | #include <linux/crypto.h> | ||
1131 | #endif | ||
1132 | |||
1133 | struct airo_info { | 1122 | struct airo_info { |
1134 | struct net_device_stats stats; | 1123 | struct net_device_stats stats; |
1135 | struct net_device *dev; | 1124 | struct net_device *dev; |
@@ -1190,12 +1179,10 @@ struct airo_info { | |||
1190 | unsigned long scan_timestamp; /* Time started to scan */ | 1179 | unsigned long scan_timestamp; /* Time started to scan */ |
1191 | struct iw_spy_data spy_data; | 1180 | struct iw_spy_data spy_data; |
1192 | struct iw_public_data wireless_data; | 1181 | struct iw_public_data wireless_data; |
1193 | #ifdef MICSUPPORT | ||
1194 | /* MIC stuff */ | 1182 | /* MIC stuff */ |
1195 | struct crypto_tfm *tfm; | 1183 | struct crypto_tfm *tfm; |
1196 | mic_module mod[2]; | 1184 | mic_module mod[2]; |
1197 | mic_statistics micstats; | 1185 | mic_statistics micstats; |
1198 | #endif | ||
1199 | HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors | 1186 | HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors |
1200 | HostTxDesc txfids[MPI_MAX_FIDS]; | 1187 | HostTxDesc txfids[MPI_MAX_FIDS]; |
1201 | HostRidDesc config_desc; | 1188 | HostRidDesc config_desc; |
@@ -1229,7 +1216,6 @@ static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime); | |||
1229 | static int flashputbuf(struct airo_info *ai); | 1216 | static int flashputbuf(struct airo_info *ai); |
1230 | static int flashrestart(struct airo_info *ai,struct net_device *dev); | 1217 | static int flashrestart(struct airo_info *ai,struct net_device *dev); |
1231 | 1218 | ||
1232 | #ifdef MICSUPPORT | ||
1233 | /*********************************************************************** | 1219 | /*********************************************************************** |
1234 | * MIC ROUTINES * | 1220 | * MIC ROUTINES * |
1235 | *********************************************************************** | 1221 | *********************************************************************** |
@@ -1686,7 +1672,6 @@ static void emmh32_final(emmh32_context *context, u8 digest[4]) | |||
1686 | digest[2] = (val>>8) & 0xFF; | 1672 | digest[2] = (val>>8) & 0xFF; |
1687 | digest[3] = val & 0xFF; | 1673 | digest[3] = val & 0xFF; |
1688 | } | 1674 | } |
1689 | #endif | ||
1690 | 1675 | ||
1691 | static int readBSSListRid(struct airo_info *ai, int first, | 1676 | static int readBSSListRid(struct airo_info *ai, int first, |
1692 | BSSListRid *list) { | 1677 | BSSListRid *list) { |
@@ -2005,7 +1990,6 @@ static int mpi_send_packet (struct net_device *dev) | |||
2005 | * Firmware automaticly puts 802 header on so | 1990 | * Firmware automaticly puts 802 header on so |
2006 | * we don't need to account for it in the length | 1991 | * we don't need to account for it in the length |
2007 | */ | 1992 | */ |
2008 | #ifdef MICSUPPORT | ||
2009 | if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && | 1993 | if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && |
2010 | (ntohs(((u16 *)buffer)[6]) != 0x888E)) { | 1994 | (ntohs(((u16 *)buffer)[6]) != 0x888E)) { |
2011 | MICBuffer pMic; | 1995 | MICBuffer pMic; |
@@ -2022,9 +2006,7 @@ static int mpi_send_packet (struct net_device *dev) | |||
2022 | memcpy (sendbuf, &pMic, sizeof(pMic)); | 2006 | memcpy (sendbuf, &pMic, sizeof(pMic)); |
2023 | sendbuf += sizeof(pMic); | 2007 | sendbuf += sizeof(pMic); |
2024 | memcpy (sendbuf, buffer, len - sizeof(etherHead)); | 2008 | memcpy (sendbuf, buffer, len - sizeof(etherHead)); |
2025 | } else | 2009 | } else { |
2026 | #endif | ||
2027 | { | ||
2028 | *payloadLen = cpu_to_le16(len - sizeof(etherHead)); | 2010 | *payloadLen = cpu_to_le16(len - sizeof(etherHead)); |
2029 | 2011 | ||
2030 | dev->trans_start = jiffies; | 2012 | dev->trans_start = jiffies; |
@@ -2400,9 +2382,7 @@ void stop_airo_card( struct net_device *dev, int freeres ) | |||
2400 | ai->shared, ai->shared_dma); | 2382 | ai->shared, ai->shared_dma); |
2401 | } | 2383 | } |
2402 | } | 2384 | } |
2403 | #ifdef MICSUPPORT | ||
2404 | crypto_free_tfm(ai->tfm); | 2385 | crypto_free_tfm(ai->tfm); |
2405 | #endif | ||
2406 | del_airo_dev( dev ); | 2386 | del_airo_dev( dev ); |
2407 | free_netdev( dev ); | 2387 | free_netdev( dev ); |
2408 | } | 2388 | } |
@@ -2726,9 +2706,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2726 | ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); | 2706 | ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); |
2727 | if (ai->thr_pid < 0) | 2707 | if (ai->thr_pid < 0) |
2728 | goto err_out_free; | 2708 | goto err_out_free; |
2729 | #ifdef MICSUPPORT | ||
2730 | ai->tfm = NULL; | 2709 | ai->tfm = NULL; |
2731 | #endif | ||
2732 | rc = add_airo_dev( dev ); | 2710 | rc = add_airo_dev( dev ); |
2733 | if (rc) | 2711 | if (rc) |
2734 | goto err_out_thr; | 2712 | goto err_out_thr; |
@@ -2969,10 +2947,8 @@ static int airo_thread(void *data) { | |||
2969 | airo_read_wireless_stats(ai); | 2947 | airo_read_wireless_stats(ai); |
2970 | else if (test_bit(JOB_PROMISC, &ai->flags)) | 2948 | else if (test_bit(JOB_PROMISC, &ai->flags)) |
2971 | airo_set_promisc(ai); | 2949 | airo_set_promisc(ai); |
2972 | #ifdef MICSUPPORT | ||
2973 | else if (test_bit(JOB_MIC, &ai->flags)) | 2950 | else if (test_bit(JOB_MIC, &ai->flags)) |
2974 | micinit(ai); | 2951 | micinit(ai); |
2975 | #endif | ||
2976 | else if (test_bit(JOB_EVENT, &ai->flags)) | 2952 | else if (test_bit(JOB_EVENT, &ai->flags)) |
2977 | airo_send_event(dev); | 2953 | airo_send_event(dev); |
2978 | else if (test_bit(JOB_AUTOWEP, &ai->flags)) | 2954 | else if (test_bit(JOB_AUTOWEP, &ai->flags)) |
@@ -3010,12 +2986,10 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) | |||
3010 | 2986 | ||
3011 | if ( status & EV_MIC ) { | 2987 | if ( status & EV_MIC ) { |
3012 | OUT4500( apriv, EVACK, EV_MIC ); | 2988 | OUT4500( apriv, EVACK, EV_MIC ); |
3013 | #ifdef MICSUPPORT | ||
3014 | if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { | 2989 | if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { |
3015 | set_bit(JOB_MIC, &apriv->flags); | 2990 | set_bit(JOB_MIC, &apriv->flags); |
3016 | wake_up_interruptible(&apriv->thr_wait); | 2991 | wake_up_interruptible(&apriv->thr_wait); |
3017 | } | 2992 | } |
3018 | #endif | ||
3019 | } | 2993 | } |
3020 | if ( status & EV_LINK ) { | 2994 | if ( status & EV_LINK ) { |
3021 | union iwreq_data wrqu; | 2995 | union iwreq_data wrqu; |
@@ -3194,11 +3168,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) | |||
3194 | } | 3168 | } |
3195 | bap_read (apriv, buffer + hdrlen/2, len, BAP0); | 3169 | bap_read (apriv, buffer + hdrlen/2, len, BAP0); |
3196 | } else { | 3170 | } else { |
3197 | #ifdef MICSUPPORT | ||
3198 | MICBuffer micbuf; | 3171 | MICBuffer micbuf; |
3199 | #endif | ||
3200 | bap_read (apriv, buffer, ETH_ALEN*2, BAP0); | 3172 | bap_read (apriv, buffer, ETH_ALEN*2, BAP0); |
3201 | #ifdef MICSUPPORT | ||
3202 | if (apriv->micstats.enabled) { | 3173 | if (apriv->micstats.enabled) { |
3203 | bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0); | 3174 | bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0); |
3204 | if (ntohs(micbuf.typelen) > 0x05DC) | 3175 | if (ntohs(micbuf.typelen) > 0x05DC) |
@@ -3211,15 +3182,10 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) | |||
3211 | skb_trim (skb, len + hdrlen); | 3182 | skb_trim (skb, len + hdrlen); |
3212 | } | 3183 | } |
3213 | } | 3184 | } |
3214 | #endif | ||
3215 | bap_read(apriv,buffer+ETH_ALEN,len,BAP0); | 3185 | bap_read(apriv,buffer+ETH_ALEN,len,BAP0); |
3216 | #ifdef MICSUPPORT | ||
3217 | if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { | 3186 | if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { |
3218 | badmic: | 3187 | badmic: |
3219 | dev_kfree_skb_irq (skb); | 3188 | dev_kfree_skb_irq (skb); |
3220 | #else | ||
3221 | if (0) { | ||
3222 | #endif | ||
3223 | badrx: | 3189 | badrx: |
3224 | OUT4500( apriv, EVACK, EV_RX); | 3190 | OUT4500( apriv, EVACK, EV_RX); |
3225 | goto exitrx; | 3191 | goto exitrx; |
@@ -3430,10 +3396,8 @@ static void mpi_receive_802_3(struct airo_info *ai) | |||
3430 | int len = 0; | 3396 | int len = 0; |
3431 | struct sk_buff *skb; | 3397 | struct sk_buff *skb; |
3432 | char *buffer; | 3398 | char *buffer; |
3433 | #ifdef MICSUPPORT | ||
3434 | int off = 0; | 3399 | int off = 0; |
3435 | MICBuffer micbuf; | 3400 | MICBuffer micbuf; |
3436 | #endif | ||
3437 | 3401 | ||
3438 | memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd)); | 3402 | memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd)); |
3439 | /* Make sure we got something */ | 3403 | /* Make sure we got something */ |
@@ -3448,7 +3412,6 @@ static void mpi_receive_802_3(struct airo_info *ai) | |||
3448 | goto badrx; | 3412 | goto badrx; |
3449 | } | 3413 | } |
3450 | buffer = skb_put(skb,len); | 3414 | buffer = skb_put(skb,len); |
3451 | #ifdef MICSUPPORT | ||
3452 | memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2); | 3415 | memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2); |
3453 | if (ai->micstats.enabled) { | 3416 | if (ai->micstats.enabled) { |
3454 | memcpy(&micbuf, | 3417 | memcpy(&micbuf, |
@@ -3470,9 +3433,6 @@ badmic: | |||
3470 | dev_kfree_skb_irq (skb); | 3433 | dev_kfree_skb_irq (skb); |
3471 | goto badrx; | 3434 | goto badrx; |
3472 | } | 3435 | } |
3473 | #else | ||
3474 | memcpy(buffer, ai->rxfids[0].virtual_host_addr, len); | ||
3475 | #endif | ||
3476 | #ifdef WIRELESS_SPY | 3436 | #ifdef WIRELESS_SPY |
3477 | if (ai->spy_data.spy_number > 0) { | 3437 | if (ai->spy_data.spy_number > 0) { |
3478 | char *sa; | 3438 | char *sa; |
@@ -3689,13 +3649,11 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) | |||
3689 | ai->config.authType = AUTH_OPEN; | 3649 | ai->config.authType = AUTH_OPEN; |
3690 | ai->config.modulation = MOD_CCK; | 3650 | ai->config.modulation = MOD_CCK; |
3691 | 3651 | ||
3692 | #ifdef MICSUPPORT | ||
3693 | if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) && | 3652 | if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) && |
3694 | (micsetup(ai) == SUCCESS)) { | 3653 | (micsetup(ai) == SUCCESS)) { |
3695 | ai->config.opmode |= MODE_MIC; | 3654 | ai->config.opmode |= MODE_MIC; |
3696 | set_bit(FLAG_MIC_CAPABLE, &ai->flags); | 3655 | set_bit(FLAG_MIC_CAPABLE, &ai->flags); |
3697 | } | 3656 | } |
3698 | #endif | ||
3699 | 3657 | ||
3700 | /* Save off the MAC */ | 3658 | /* Save off the MAC */ |
3701 | for( i = 0; i < ETH_ALEN; i++ ) { | 3659 | for( i = 0; i < ETH_ALEN; i++ ) { |
@@ -4170,15 +4128,12 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket) | |||
4170 | } | 4128 | } |
4171 | len -= ETH_ALEN * 2; | 4129 | len -= ETH_ALEN * 2; |
4172 | 4130 | ||
4173 | #ifdef MICSUPPORT | ||
4174 | if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && | 4131 | if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && |
4175 | (ntohs(((u16 *)pPacket)[6]) != 0x888E)) { | 4132 | (ntohs(((u16 *)pPacket)[6]) != 0x888E)) { |
4176 | if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS) | 4133 | if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS) |
4177 | return ERROR; | 4134 | return ERROR; |
4178 | miclen = sizeof(pMic); | 4135 | miclen = sizeof(pMic); |
4179 | } | 4136 | } |
4180 | #endif | ||
4181 | |||
4182 | // packet is destination[6], source[6], payload[len-12] | 4137 | // packet is destination[6], source[6], payload[len-12] |
4183 | // write the payload length and dst/src/payload | 4138 | // write the payload length and dst/src/payload |
4184 | if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR; | 4139 | if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR; |
@@ -5081,7 +5036,6 @@ static int set_wep_key(struct airo_info *ai, u16 index, | |||
5081 | wkr.len = sizeof(wkr); | 5036 | wkr.len = sizeof(wkr); |
5082 | wkr.kindex = 0xffff; | 5037 | wkr.kindex = 0xffff; |
5083 | wkr.mac[0] = (char)index; | 5038 | wkr.mac[0] = (char)index; |
5084 | if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index); | ||
5085 | if (perm) ai->defindex = (char)index; | 5039 | if (perm) ai->defindex = (char)index; |
5086 | } else { | 5040 | } else { |
5087 | // We are actually setting the key | 5041 | // We are actually setting the key |
@@ -5090,7 +5044,6 @@ static int set_wep_key(struct airo_info *ai, u16 index, | |||
5090 | wkr.klen = keylen; | 5044 | wkr.klen = keylen; |
5091 | memcpy( wkr.key, key, keylen ); | 5045 | memcpy( wkr.key, key, keylen ); |
5092 | memcpy( wkr.mac, macaddr, ETH_ALEN ); | 5046 | memcpy( wkr.mac, macaddr, ETH_ALEN ); |
5093 | printk(KERN_INFO "Setting key %d\n", index); | ||
5094 | } | 5047 | } |
5095 | 5048 | ||
5096 | if (perm) disable_MAC(ai, lock); | 5049 | if (perm) disable_MAC(ai, lock); |
@@ -5801,11 +5754,13 @@ static int airo_set_wap(struct net_device *dev, | |||
5801 | Cmd cmd; | 5754 | Cmd cmd; |
5802 | Resp rsp; | 5755 | Resp rsp; |
5803 | APListRid APList_rid; | 5756 | APListRid APList_rid; |
5804 | static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 }; | 5757 | static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
5758 | static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
5805 | 5759 | ||
5806 | if (awrq->sa_family != ARPHRD_ETHER) | 5760 | if (awrq->sa_family != ARPHRD_ETHER) |
5807 | return -EINVAL; | 5761 | return -EINVAL; |
5808 | else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) { | 5762 | else if (!memcmp(any, awrq->sa_data, ETH_ALEN) || |
5763 | !memcmp(off, awrq->sa_data, ETH_ALEN)) { | ||
5809 | memset(&cmd, 0, sizeof(cmd)); | 5764 | memset(&cmd, 0, sizeof(cmd)); |
5810 | cmd.cmd=CMD_LOSE_SYNC; | 5765 | cmd.cmd=CMD_LOSE_SYNC; |
5811 | if (down_interruptible(&local->sem)) | 5766 | if (down_interruptible(&local->sem)) |
@@ -6296,6 +6251,272 @@ static int airo_get_encode(struct net_device *dev, | |||
6296 | 6251 | ||
6297 | /*------------------------------------------------------------------*/ | 6252 | /*------------------------------------------------------------------*/ |
6298 | /* | 6253 | /* |
6254 | * Wireless Handler : set extended Encryption parameters | ||
6255 | */ | ||
6256 | static int airo_set_encodeext(struct net_device *dev, | ||
6257 | struct iw_request_info *info, | ||
6258 | union iwreq_data *wrqu, | ||
6259 | char *extra) | ||
6260 | { | ||
6261 | struct airo_info *local = dev->priv; | ||
6262 | struct iw_point *encoding = &wrqu->encoding; | ||
6263 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | ||
6264 | CapabilityRid cap_rid; /* Card capability info */ | ||
6265 | int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 ); | ||
6266 | u16 currentAuthType = local->config.authType; | ||
6267 | int idx, key_len, alg = ext->alg, set_key = 1; | ||
6268 | wep_key_t key; | ||
6269 | |||
6270 | /* Is WEP supported ? */ | ||
6271 | readCapabilityRid(local, &cap_rid, 1); | ||
6272 | /* Older firmware doesn't support this... | ||
6273 | if(!(cap_rid.softCap & 2)) { | ||
6274 | return -EOPNOTSUPP; | ||
6275 | } */ | ||
6276 | readConfigRid(local, 1); | ||
6277 | |||
6278 | /* Determine and validate the key index */ | ||
6279 | idx = encoding->flags & IW_ENCODE_INDEX; | ||
6280 | if (idx) { | ||
6281 | if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1)) | ||
6282 | return -EINVAL; | ||
6283 | idx--; | ||
6284 | } else | ||
6285 | idx = get_wep_key(local, 0xffff); | ||
6286 | |||
6287 | if (encoding->flags & IW_ENCODE_DISABLED) | ||
6288 | alg = IW_ENCODE_ALG_NONE; | ||
6289 | |||
6290 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { | ||
6291 | /* Only set transmit key index here, actual | ||
6292 | * key is set below if needed. | ||
6293 | */ | ||
6294 | set_wep_key(local, idx, NULL, 0, perm, 1); | ||
6295 | set_key = ext->key_len > 0 ? 1 : 0; | ||
6296 | } | ||
6297 | |||
6298 | if (set_key) { | ||
6299 | /* Set the requested key first */ | ||
6300 | memset(key.key, 0, MAX_KEY_SIZE); | ||
6301 | switch (alg) { | ||
6302 | case IW_ENCODE_ALG_NONE: | ||
6303 | key.len = 0; | ||
6304 | break; | ||
6305 | case IW_ENCODE_ALG_WEP: | ||
6306 | if (ext->key_len > MIN_KEY_SIZE) { | ||
6307 | key.len = MAX_KEY_SIZE; | ||
6308 | } else if (ext->key_len > 0) { | ||
6309 | key.len = MIN_KEY_SIZE; | ||
6310 | } else { | ||
6311 | return -EINVAL; | ||
6312 | } | ||
6313 | key_len = min (ext->key_len, key.len); | ||
6314 | memcpy(key.key, ext->key, key_len); | ||
6315 | break; | ||
6316 | default: | ||
6317 | return -EINVAL; | ||
6318 | } | ||
6319 | /* Send the key to the card */ | ||
6320 | set_wep_key(local, idx, key.key, key.len, perm, 1); | ||
6321 | } | ||
6322 | |||
6323 | /* Read the flags */ | ||
6324 | if(encoding->flags & IW_ENCODE_DISABLED) | ||
6325 | local->config.authType = AUTH_OPEN; // disable encryption | ||
6326 | if(encoding->flags & IW_ENCODE_RESTRICTED) | ||
6327 | local->config.authType = AUTH_SHAREDKEY; // Only Both | ||
6328 | if(encoding->flags & IW_ENCODE_OPEN) | ||
6329 | local->config.authType = AUTH_ENCRYPT; // Only Wep | ||
6330 | /* Commit the changes to flags if needed */ | ||
6331 | if (local->config.authType != currentAuthType) | ||
6332 | set_bit (FLAG_COMMIT, &local->flags); | ||
6333 | |||
6334 | return -EINPROGRESS; | ||
6335 | } | ||
6336 | |||
6337 | |||
6338 | /*------------------------------------------------------------------*/ | ||
6339 | /* | ||
6340 | * Wireless Handler : get extended Encryption parameters | ||
6341 | */ | ||
6342 | static int airo_get_encodeext(struct net_device *dev, | ||
6343 | struct iw_request_info *info, | ||
6344 | union iwreq_data *wrqu, | ||
6345 | char *extra) | ||
6346 | { | ||
6347 | struct airo_info *local = dev->priv; | ||
6348 | struct iw_point *encoding = &wrqu->encoding; | ||
6349 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | ||
6350 | CapabilityRid cap_rid; /* Card capability info */ | ||
6351 | int idx, max_key_len; | ||
6352 | |||
6353 | /* Is it supported ? */ | ||
6354 | readCapabilityRid(local, &cap_rid, 1); | ||
6355 | if(!(cap_rid.softCap & 2)) { | ||
6356 | return -EOPNOTSUPP; | ||
6357 | } | ||
6358 | readConfigRid(local, 1); | ||
6359 | |||
6360 | max_key_len = encoding->length - sizeof(*ext); | ||
6361 | if (max_key_len < 0) | ||
6362 | return -EINVAL; | ||
6363 | |||
6364 | idx = encoding->flags & IW_ENCODE_INDEX; | ||
6365 | if (idx) { | ||
6366 | if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1)) | ||
6367 | return -EINVAL; | ||
6368 | idx--; | ||
6369 | } else | ||
6370 | idx = get_wep_key(local, 0xffff); | ||
6371 | |||
6372 | encoding->flags = idx + 1; | ||
6373 | memset(ext, 0, sizeof(*ext)); | ||
6374 | |||
6375 | /* Check encryption mode */ | ||
6376 | switch(local->config.authType) { | ||
6377 | case AUTH_ENCRYPT: | ||
6378 | encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED; | ||
6379 | break; | ||
6380 | case AUTH_SHAREDKEY: | ||
6381 | encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED; | ||
6382 | break; | ||
6383 | default: | ||
6384 | case AUTH_OPEN: | ||
6385 | encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED; | ||
6386 | break; | ||
6387 | } | ||
6388 | /* We can't return the key, so set the proper flag and return zero */ | ||
6389 | encoding->flags |= IW_ENCODE_NOKEY; | ||
6390 | memset(extra, 0, 16); | ||
6391 | |||
6392 | /* Copy the key to the user buffer */ | ||
6393 | ext->key_len = get_wep_key(local, idx); | ||
6394 | if (ext->key_len > 16) { | ||
6395 | ext->key_len=0; | ||
6396 | } | ||
6397 | |||
6398 | return 0; | ||
6399 | } | ||
6400 | |||
6401 | |||
6402 | /*------------------------------------------------------------------*/ | ||
6403 | /* | ||
6404 | * Wireless Handler : set extended authentication parameters | ||
6405 | */ | ||
6406 | static int airo_set_auth(struct net_device *dev, | ||
6407 | struct iw_request_info *info, | ||
6408 | union iwreq_data *wrqu, char *extra) | ||
6409 | { | ||
6410 | struct airo_info *local = dev->priv; | ||
6411 | struct iw_param *param = &wrqu->param; | ||
6412 | u16 currentAuthType = local->config.authType; | ||
6413 | |||
6414 | switch (param->flags & IW_AUTH_INDEX) { | ||
6415 | case IW_AUTH_WPA_VERSION: | ||
6416 | case IW_AUTH_CIPHER_PAIRWISE: | ||
6417 | case IW_AUTH_CIPHER_GROUP: | ||
6418 | case IW_AUTH_KEY_MGMT: | ||
6419 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: | ||
6420 | case IW_AUTH_PRIVACY_INVOKED: | ||
6421 | /* | ||
6422 | * airo does not use these parameters | ||
6423 | */ | ||
6424 | break; | ||
6425 | |||
6426 | case IW_AUTH_DROP_UNENCRYPTED: | ||
6427 | if (param->value) { | ||
6428 | /* Only change auth type if unencrypted */ | ||
6429 | if (currentAuthType == AUTH_OPEN) | ||
6430 | local->config.authType = AUTH_ENCRYPT; | ||
6431 | } else { | ||
6432 | local->config.authType = AUTH_OPEN; | ||
6433 | } | ||
6434 | |||
6435 | /* Commit the changes to flags if needed */ | ||
6436 | if (local->config.authType != currentAuthType) | ||
6437 | set_bit (FLAG_COMMIT, &local->flags); | ||
6438 | break; | ||
6439 | |||
6440 | case IW_AUTH_80211_AUTH_ALG: { | ||
6441 | /* FIXME: What about AUTH_OPEN? This API seems to | ||
6442 | * disallow setting our auth to AUTH_OPEN. | ||
6443 | */ | ||
6444 | if (param->value & IW_AUTH_ALG_SHARED_KEY) { | ||
6445 | local->config.authType = AUTH_SHAREDKEY; | ||
6446 | } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { | ||
6447 | local->config.authType = AUTH_ENCRYPT; | ||
6448 | } else | ||
6449 | return -EINVAL; | ||
6450 | break; | ||
6451 | |||
6452 | /* Commit the changes to flags if needed */ | ||
6453 | if (local->config.authType != currentAuthType) | ||
6454 | set_bit (FLAG_COMMIT, &local->flags); | ||
6455 | } | ||
6456 | |||
6457 | case IW_AUTH_WPA_ENABLED: | ||
6458 | /* Silently accept disable of WPA */ | ||
6459 | if (param->value > 0) | ||
6460 | return -EOPNOTSUPP; | ||
6461 | break; | ||
6462 | |||
6463 | default: | ||
6464 | return -EOPNOTSUPP; | ||
6465 | } | ||
6466 | return -EINPROGRESS; | ||
6467 | } | ||
6468 | |||
6469 | |||
6470 | /*------------------------------------------------------------------*/ | ||
6471 | /* | ||
6472 | * Wireless Handler : get extended authentication parameters | ||
6473 | */ | ||
6474 | static int airo_get_auth(struct net_device *dev, | ||
6475 | struct iw_request_info *info, | ||
6476 | union iwreq_data *wrqu, char *extra) | ||
6477 | { | ||
6478 | struct airo_info *local = dev->priv; | ||
6479 | struct iw_param *param = &wrqu->param; | ||
6480 | u16 currentAuthType = local->config.authType; | ||
6481 | |||
6482 | switch (param->flags & IW_AUTH_INDEX) { | ||
6483 | case IW_AUTH_DROP_UNENCRYPTED: | ||
6484 | switch (currentAuthType) { | ||
6485 | case AUTH_SHAREDKEY: | ||
6486 | case AUTH_ENCRYPT: | ||
6487 | param->value = 1; | ||
6488 | break; | ||
6489 | default: | ||
6490 | param->value = 0; | ||
6491 | break; | ||
6492 | } | ||
6493 | break; | ||
6494 | |||
6495 | case IW_AUTH_80211_AUTH_ALG: | ||
6496 | switch (currentAuthType) { | ||
6497 | case AUTH_SHAREDKEY: | ||
6498 | param->value = IW_AUTH_ALG_SHARED_KEY; | ||
6499 | break; | ||
6500 | case AUTH_ENCRYPT: | ||
6501 | default: | ||
6502 | param->value = IW_AUTH_ALG_OPEN_SYSTEM; | ||
6503 | break; | ||
6504 | } | ||
6505 | break; | ||
6506 | |||
6507 | case IW_AUTH_WPA_ENABLED: | ||
6508 | param->value = 0; | ||
6509 | break; | ||
6510 | |||
6511 | default: | ||
6512 | return -EOPNOTSUPP; | ||
6513 | } | ||
6514 | return 0; | ||
6515 | } | ||
6516 | |||
6517 | |||
6518 | /*------------------------------------------------------------------*/ | ||
6519 | /* | ||
6299 | * Wireless Handler : set Tx-Power | 6520 | * Wireless Handler : set Tx-Power |
6300 | */ | 6521 | */ |
6301 | static int airo_set_txpow(struct net_device *dev, | 6522 | static int airo_set_txpow(struct net_device *dev, |
@@ -7050,6 +7271,15 @@ static const iw_handler airo_handler[] = | |||
7050 | (iw_handler) airo_get_encode, /* SIOCGIWENCODE */ | 7271 | (iw_handler) airo_get_encode, /* SIOCGIWENCODE */ |
7051 | (iw_handler) airo_set_power, /* SIOCSIWPOWER */ | 7272 | (iw_handler) airo_set_power, /* SIOCSIWPOWER */ |
7052 | (iw_handler) airo_get_power, /* SIOCGIWPOWER */ | 7273 | (iw_handler) airo_get_power, /* SIOCGIWPOWER */ |
7274 | (iw_handler) NULL, /* -- hole -- */ | ||
7275 | (iw_handler) NULL, /* -- hole -- */ | ||
7276 | (iw_handler) NULL, /* SIOCSIWGENIE */ | ||
7277 | (iw_handler) NULL, /* SIOCGIWGENIE */ | ||
7278 | (iw_handler) airo_set_auth, /* SIOCSIWAUTH */ | ||
7279 | (iw_handler) airo_get_auth, /* SIOCGIWAUTH */ | ||
7280 | (iw_handler) airo_set_encodeext, /* SIOCSIWENCODEEXT */ | ||
7281 | (iw_handler) airo_get_encodeext, /* SIOCGIWENCODEEXT */ | ||
7282 | (iw_handler) NULL, /* SIOCSIWPMKSA */ | ||
7053 | }; | 7283 | }; |
7054 | 7284 | ||
7055 | /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here. | 7285 | /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here. |
@@ -7270,13 +7500,11 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) { | |||
7270 | case AIROGSTAT: ridcode = RID_STATUS; break; | 7500 | case AIROGSTAT: ridcode = RID_STATUS; break; |
7271 | case AIROGSTATSD32: ridcode = RID_STATSDELTA; break; | 7501 | case AIROGSTATSD32: ridcode = RID_STATSDELTA; break; |
7272 | case AIROGSTATSC32: ridcode = RID_STATS; break; | 7502 | case AIROGSTATSC32: ridcode = RID_STATS; break; |
7273 | #ifdef MICSUPPORT | ||
7274 | case AIROGMICSTATS: | 7503 | case AIROGMICSTATS: |
7275 | if (copy_to_user(comp->data, &ai->micstats, | 7504 | if (copy_to_user(comp->data, &ai->micstats, |
7276 | min((int)comp->len,(int)sizeof(ai->micstats)))) | 7505 | min((int)comp->len,(int)sizeof(ai->micstats)))) |
7277 | return -EFAULT; | 7506 | return -EFAULT; |
7278 | return 0; | 7507 | return 0; |
7279 | #endif | ||
7280 | case AIRORRID: ridcode = comp->ridnum; break; | 7508 | case AIRORRID: ridcode = comp->ridnum; break; |
7281 | default: | 7509 | default: |
7282 | return -EINVAL; | 7510 | return -EINVAL; |
@@ -7308,9 +7536,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) { | |||
7308 | static int writerids(struct net_device *dev, aironet_ioctl *comp) { | 7536 | static int writerids(struct net_device *dev, aironet_ioctl *comp) { |
7309 | struct airo_info *ai = dev->priv; | 7537 | struct airo_info *ai = dev->priv; |
7310 | int ridcode; | 7538 | int ridcode; |
7311 | #ifdef MICSUPPORT | ||
7312 | int enabled; | 7539 | int enabled; |
7313 | #endif | ||
7314 | Resp rsp; | 7540 | Resp rsp; |
7315 | static int (* writer)(struct airo_info *, u16 rid, const void *, int, int); | 7541 | static int (* writer)(struct airo_info *, u16 rid, const void *, int, int); |
7316 | unsigned char *iobuf; | 7542 | unsigned char *iobuf; |
@@ -7367,11 +7593,9 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) { | |||
7367 | 7593 | ||
7368 | PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1); | 7594 | PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1); |
7369 | 7595 | ||
7370 | #ifdef MICSUPPORT | ||
7371 | enabled = ai->micstats.enabled; | 7596 | enabled = ai->micstats.enabled; |
7372 | memset(&ai->micstats,0,sizeof(ai->micstats)); | 7597 | memset(&ai->micstats,0,sizeof(ai->micstats)); |
7373 | ai->micstats.enabled = enabled; | 7598 | ai->micstats.enabled = enabled; |
7374 | #endif | ||
7375 | 7599 | ||
7376 | if (copy_to_user(comp->data, iobuf, | 7600 | if (copy_to_user(comp->data, iobuf, |
7377 | min((int)comp->len, (int)RIDSIZE))) { | 7601 | min((int)comp->len, (int)RIDSIZE))) { |