diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-21 12:08:21 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-21 12:08:21 -0500 |
| commit | ac58c9059da8886b5e8cde012a80266b18ca146e (patch) | |
| tree | 40bf486843a2cace6c3a959d73423e50e6aa0c00 /drivers/net/wireless/airo.c | |
| parent | df6db302cb236ac3a683d535a3e2073d9f4b2833 (diff) | |
| parent | c4a1745aa09fc110afdefea0e5d025043e348bae (diff) | |
Merge branch 'linus'
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))) { |
