aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r--drivers/net/wireless/airo.c1137
1 files changed, 626 insertions, 511 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index fc4322ca669f..acda45838e98 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -496,39 +496,41 @@ typedef struct {
496 * so all rid access should use the read/writeXXXRid routines. 496 * so all rid access should use the read/writeXXXRid routines.
497 */ 497 */
498 498
499/* This is redundant for x86 archs, but it seems necessary for ARM */
500#pragma pack(1)
501
502/* This structure came from an email sent to me from an engineer at 499/* This structure came from an email sent to me from an engineer at
503 aironet for inclusion into this driver */ 500 aironet for inclusion into this driver */
504typedef struct { 501typedef struct WepKeyRid WepKeyRid;
502struct WepKeyRid {
505 __le16 len; 503 __le16 len;
506 __le16 kindex; 504 __le16 kindex;
507 u8 mac[ETH_ALEN]; 505 u8 mac[ETH_ALEN];
508 __le16 klen; 506 __le16 klen;
509 u8 key[16]; 507 u8 key[16];
510} WepKeyRid; 508} __attribute__ ((packed));
511 509
512/* These structures are from the Aironet's PC4500 Developers Manual */ 510/* These structures are from the Aironet's PC4500 Developers Manual */
513typedef struct { 511typedef struct Ssid Ssid;
512struct Ssid {
514 __le16 len; 513 __le16 len;
515 u8 ssid[32]; 514 u8 ssid[32];
516} Ssid; 515} __attribute__ ((packed));
517 516
518typedef struct { 517typedef struct SsidRid SsidRid;
518struct SsidRid {
519 __le16 len; 519 __le16 len;
520 Ssid ssids[3]; 520 Ssid ssids[3];
521} SsidRid; 521} __attribute__ ((packed));
522 522
523typedef struct { 523typedef struct ModulationRid ModulationRid;
524struct ModulationRid {
524 __le16 len; 525 __le16 len;
525 __le16 modulation; 526 __le16 modulation;
526#define MOD_DEFAULT cpu_to_le16(0) 527#define MOD_DEFAULT cpu_to_le16(0)
527#define MOD_CCK cpu_to_le16(1) 528#define MOD_CCK cpu_to_le16(1)
528#define MOD_MOK cpu_to_le16(2) 529#define MOD_MOK cpu_to_le16(2)
529} ModulationRid; 530} __attribute__ ((packed));
530 531
531typedef struct { 532typedef struct ConfigRid ConfigRid;
533struct ConfigRid {
532 __le16 len; /* sizeof(ConfigRid) */ 534 __le16 len; /* sizeof(ConfigRid) */
533 __le16 opmode; /* operating mode */ 535 __le16 opmode; /* operating mode */
534#define MODE_STA_IBSS cpu_to_le16(0) 536#define MODE_STA_IBSS cpu_to_le16(0)
@@ -649,9 +651,10 @@ typedef struct {
649#define MAGIC_STAY_IN_CAM (1<<10) 651#define MAGIC_STAY_IN_CAM (1<<10)
650 u8 magicControl; 652 u8 magicControl;
651 __le16 autoWake; 653 __le16 autoWake;
652} ConfigRid; 654} __attribute__ ((packed));
653 655
654typedef struct { 656typedef struct StatusRid StatusRid;
657struct StatusRid {
655 __le16 len; 658 __le16 len;
656 u8 mac[ETH_ALEN]; 659 u8 mac[ETH_ALEN];
657 __le16 mode; 660 __le16 mode;
@@ -707,21 +710,23 @@ typedef struct {
707#define STAT_LEAPFAILED 91 710#define STAT_LEAPFAILED 91
708#define STAT_LEAPTIMEDOUT 92 711#define STAT_LEAPTIMEDOUT 92
709#define STAT_LEAPCOMPLETE 93 712#define STAT_LEAPCOMPLETE 93
710} StatusRid; 713} __attribute__ ((packed));
711 714
712typedef struct { 715typedef struct StatsRid StatsRid;
716struct StatsRid {
713 __le16 len; 717 __le16 len;
714 __le16 spacer; 718 __le16 spacer;
715 __le32 vals[100]; 719 __le32 vals[100];
716} StatsRid; 720} __attribute__ ((packed));
717
718 721
719typedef struct { 722typedef struct APListRid APListRid;
723struct APListRid {
720 __le16 len; 724 __le16 len;
721 u8 ap[4][ETH_ALEN]; 725 u8 ap[4][ETH_ALEN];
722} APListRid; 726} __attribute__ ((packed));
723 727
724typedef struct { 728typedef struct CapabilityRid CapabilityRid;
729struct CapabilityRid {
725 __le16 len; 730 __le16 len;
726 char oui[3]; 731 char oui[3];
727 char zero; 732 char zero;
@@ -748,17 +753,18 @@ typedef struct {
748 __le16 bootBlockVer; 753 __le16 bootBlockVer;
749 __le16 requiredHard; 754 __le16 requiredHard;
750 __le16 extSoftCap; 755 __le16 extSoftCap;
751} CapabilityRid; 756} __attribute__ ((packed));
752
753 757
754/* Only present on firmware >= 5.30.17 */ 758/* Only present on firmware >= 5.30.17 */
755typedef struct { 759typedef struct BSSListRidExtra BSSListRidExtra;
760struct BSSListRidExtra {
756 __le16 unknown[4]; 761 __le16 unknown[4];
757 u8 fixed[12]; /* WLAN management frame */ 762 u8 fixed[12]; /* WLAN management frame */
758 u8 iep[624]; 763 u8 iep[624];
759} BSSListRidExtra; 764} __attribute__ ((packed));
760 765
761typedef struct { 766typedef struct BSSListRid BSSListRid;
767struct BSSListRid {
762 __le16 len; 768 __le16 len;
763 __le16 index; /* First is 0 and 0xffff means end of list */ 769 __le16 index; /* First is 0 and 0xffff means end of list */
764#define RADIO_FH 1 /* Frequency hopping radio type */ 770#define RADIO_FH 1 /* Frequency hopping radio type */
@@ -789,33 +795,37 @@ typedef struct {
789 795
790 /* Only present on firmware >= 5.30.17 */ 796 /* Only present on firmware >= 5.30.17 */
791 BSSListRidExtra extra; 797 BSSListRidExtra extra;
792} BSSListRid; 798} __attribute__ ((packed));
793 799
794typedef struct { 800typedef struct {
795 BSSListRid bss; 801 BSSListRid bss;
796 struct list_head list; 802 struct list_head list;
797} BSSListElement; 803} BSSListElement;
798 804
799typedef struct { 805typedef struct tdsRssiEntry tdsRssiEntry;
806struct tdsRssiEntry {
800 u8 rssipct; 807 u8 rssipct;
801 u8 rssidBm; 808 u8 rssidBm;
802} tdsRssiEntry; 809} __attribute__ ((packed));
803 810
804typedef struct { 811typedef struct tdsRssiRid tdsRssiRid;
812struct tdsRssiRid {
805 u16 len; 813 u16 len;
806 tdsRssiEntry x[256]; 814 tdsRssiEntry x[256];
807} tdsRssiRid; 815} __attribute__ ((packed));
808 816
809typedef struct { 817typedef struct MICRid MICRid;
810 u16 len; 818struct MICRid {
811 u16 state; 819 __le16 len;
812 u16 multicastValid; 820 __le16 state;
821 __le16 multicastValid;
813 u8 multicast[16]; 822 u8 multicast[16];
814 u16 unicastValid; 823 __le16 unicastValid;
815 u8 unicast[16]; 824 u8 unicast[16];
816} MICRid; 825} __attribute__ ((packed));
817 826
818typedef struct { 827typedef struct MICBuffer MICBuffer;
828struct MICBuffer {
819 __be16 typelen; 829 __be16 typelen;
820 830
821 union { 831 union {
@@ -830,15 +840,13 @@ typedef struct {
830 } u; 840 } u;
831 __be32 mic; 841 __be32 mic;
832 __be32 seq; 842 __be32 seq;
833} MICBuffer; 843} __attribute__ ((packed));
834 844
835typedef struct { 845typedef struct {
836 u8 da[ETH_ALEN]; 846 u8 da[ETH_ALEN];
837 u8 sa[ETH_ALEN]; 847 u8 sa[ETH_ALEN];
838} etherHead; 848} etherHead;
839 849
840#pragma pack()
841
842#define TXCTL_TXOK (1<<1) /* report if tx is ok */ 850#define TXCTL_TXOK (1<<1) /* report if tx is ok */
843#define TXCTL_TXEX (1<<2) /* report if tx fails */ 851#define TXCTL_TXEX (1<<2) /* report if tx fails */
844#define TXCTL_802_3 (0<<3) /* 802.3 packet */ 852#define TXCTL_802_3 (0<<3) /* 802.3 packet */
@@ -981,6 +989,14 @@ typedef struct {
981 dma_addr_t host_addr; 989 dma_addr_t host_addr;
982} TxFid; 990} TxFid;
983 991
992struct rx_hdr {
993 __le16 status, len;
994 u8 rssi[2];
995 u8 rate;
996 u8 freq;
997 __le16 tmp[4];
998} __attribute__ ((packed));
999
984typedef struct { 1000typedef struct {
985 unsigned int ctl: 15; 1001 unsigned int ctl: 15;
986 unsigned int rdy: 1; 1002 unsigned int rdy: 1;
@@ -1070,10 +1086,6 @@ static WifiCtlHdr wifictlhdr8023 = {
1070 } 1086 }
1071}; 1087};
1072 1088
1073// Frequency list (map channels to frequencies)
1074static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
1075 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
1076
1077// A few details needed for WEP (Wireless Equivalent Privacy) 1089// A few details needed for WEP (Wireless Equivalent Privacy)
1078#define MAX_KEY_SIZE 13 // 128 (?) bits 1090#define MAX_KEY_SIZE 13 // 128 (?) bits
1079#define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP 1091#define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
@@ -1082,12 +1094,6 @@ typedef struct wep_key_t {
1082 u8 key[16]; /* 40-bit and 104-bit keys */ 1094 u8 key[16]; /* 40-bit and 104-bit keys */
1083} wep_key_t; 1095} wep_key_t;
1084 1096
1085/* Backward compatibility */
1086#ifndef IW_ENCODE_NOKEY
1087#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
1088#define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
1089#endif /* IW_ENCODE_NOKEY */
1090
1091/* List of Wireless Handlers (new API) */ 1097/* List of Wireless Handlers (new API) */
1092static const struct iw_handler_def airo_handler_def; 1098static const struct iw_handler_def airo_handler_def;
1093 1099
@@ -1229,6 +1235,9 @@ struct airo_info {
1229#define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE 1235#define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
1230 char proc_name[IFNAMSIZ]; 1236 char proc_name[IFNAMSIZ];
1231 1237
1238 int wep_capable;
1239 int max_wep_idx;
1240
1232 /* WPA-related stuff */ 1241 /* WPA-related stuff */
1233 unsigned int bssListFirst; 1242 unsigned int bssListFirst;
1234 unsigned int bssListNext; 1243 unsigned int bssListNext;
@@ -1287,6 +1296,29 @@ static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1287static void emmh32_final(emmh32_context *context, u8 digest[4]); 1296static void emmh32_final(emmh32_context *context, u8 digest[4]);
1288static int flashpchar(struct airo_info *ai,int byte,int dwelltime); 1297static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
1289 1298
1299static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
1300 struct crypto_cipher *tfm)
1301{
1302 /* If the current MIC context is valid and its key is the same as
1303 * the MIC register, there's nothing to do.
1304 */
1305 if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
1306 return;
1307
1308 /* Age current mic Context */
1309 memcpy(old, cur, sizeof(*cur));
1310
1311 /* Initialize new context */
1312 memcpy(cur->key, key, key_len);
1313 cur->window = 33; /* Window always points to the middle */
1314 cur->rx = 0; /* Rx Sequence numbers */
1315 cur->tx = 0; /* Tx sequence numbers */
1316 cur->valid = 1; /* Key is now valid */
1317
1318 /* Give key to mic seed */
1319 emmh32_setseed(&cur->seed, key, key_len, tfm);
1320}
1321
1290/* micinit - Initialize mic seed */ 1322/* micinit - Initialize mic seed */
1291 1323
1292static void micinit(struct airo_info *ai) 1324static void micinit(struct airo_info *ai)
@@ -1297,49 +1329,26 @@ static void micinit(struct airo_info *ai)
1297 PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); 1329 PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
1298 up(&ai->sem); 1330 up(&ai->sem);
1299 1331
1300 ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0; 1332 ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
1301 1333 if (!ai->micstats.enabled) {
1302 if (ai->micstats.enabled) { 1334 /* So next time we have a valid key and mic is enabled, we will
1303 /* Key must be valid and different */ 1335 * update the sequence number if the key is the same as before.
1304 if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid || 1336 */
1305 (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast,
1306 sizeof(ai->mod[0].mCtx.key)) != 0))) {
1307 /* Age current mic Context */
1308 memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx));
1309 /* Initialize new context */
1310 memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast));
1311 ai->mod[0].mCtx.window = 33; //Window always points to the middle
1312 ai->mod[0].mCtx.rx = 0; //Rx Sequence numbers
1313 ai->mod[0].mCtx.tx = 0; //Tx sequence numbers
1314 ai->mod[0].mCtx.valid = 1; //Key is now valid
1315
1316 /* Give key to mic seed */
1317 emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm);
1318 }
1319
1320 /* Key must be valid and different */
1321 if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid ||
1322 (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast,
1323 sizeof(ai->mod[0].uCtx.key)) != 0))) {
1324 /* Age current mic Context */
1325 memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx));
1326 /* Initialize new context */
1327 memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast));
1328
1329 ai->mod[0].uCtx.window = 33; //Window always points to the middle
1330 ai->mod[0].uCtx.rx = 0; //Rx Sequence numbers
1331 ai->mod[0].uCtx.tx = 0; //Tx sequence numbers
1332 ai->mod[0].uCtx.valid = 1; //Key is now valid
1333
1334 //Give key to mic seed
1335 emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm);
1336 }
1337 } else {
1338 /* So next time we have a valid key and mic is enabled, we will update
1339 * the sequence number if the key is the same as before.
1340 */
1341 ai->mod[0].uCtx.valid = 0; 1337 ai->mod[0].uCtx.valid = 0;
1342 ai->mod[0].mCtx.valid = 0; 1338 ai->mod[0].mCtx.valid = 0;
1339 return;
1340 }
1341
1342 if (mic_rid.multicastValid) {
1343 age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
1344 mic_rid.multicast, sizeof(mic_rid.multicast),
1345 ai->tfm);
1346 }
1347
1348 if (mic_rid.unicastValid) {
1349 age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
1350 mic_rid.unicast, sizeof(mic_rid.unicast),
1351 ai->tfm);
1343 } 1352 }
1344} 1353}
1345 1354
@@ -2730,28 +2739,6 @@ static void airo_networks_initialize(struct airo_info *ai)
2730 &ai->network_free_list); 2739 &ai->network_free_list);
2731} 2740}
2732 2741
2733static int airo_test_wpa_capable(struct airo_info *ai)
2734{
2735 int status;
2736 CapabilityRid cap_rid;
2737
2738 status = readCapabilityRid(ai, &cap_rid, 1);
2739 if (status != SUCCESS) return 0;
2740
2741 /* Only firmware versions 5.30.17 or better can do WPA */
2742 if (le16_to_cpu(cap_rid.softVer) > 0x530
2743 || (le16_to_cpu(cap_rid.softVer) == 0x530
2744 && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2745 airo_print_info("", "WPA is supported.");
2746 return 1;
2747 }
2748
2749 /* No WPA support */
2750 airo_print_info("", "WPA unsupported (only firmware versions 5.30.17"
2751 " and greater support WPA. Detected %s)", cap_rid.prodVer);
2752 return 0;
2753}
2754
2755static struct net_device *_init_airo_card( unsigned short irq, int port, 2742static struct net_device *_init_airo_card( unsigned short irq, int port,
2756 int is_pcmcia, struct pci_dev *pci, 2743 int is_pcmcia, struct pci_dev *pci,
2757 struct device *dmdev ) 2744 struct device *dmdev )
@@ -2759,6 +2746,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2759 struct net_device *dev; 2746 struct net_device *dev;
2760 struct airo_info *ai; 2747 struct airo_info *ai;
2761 int i, rc; 2748 int i, rc;
2749 CapabilityRid cap_rid;
2762 2750
2763 /* Create the network device object. */ 2751 /* Create the network device object. */
2764 dev = alloc_netdev(sizeof(*ai), "", ether_setup); 2752 dev = alloc_netdev(sizeof(*ai), "", ether_setup);
@@ -2828,7 +2816,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2828 } 2816 }
2829 2817
2830 if (probe) { 2818 if (probe) {
2831 if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) { 2819 if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
2832 airo_print_err(dev->name, "MAC could not be enabled" ); 2820 airo_print_err(dev->name, "MAC could not be enabled" );
2833 rc = -EIO; 2821 rc = -EIO;
2834 goto err_out_map; 2822 goto err_out_map;
@@ -2838,28 +2826,50 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2838 set_bit(FLAG_FLASHING, &ai->flags); 2826 set_bit(FLAG_FLASHING, &ai->flags);
2839 } 2827 }
2840 2828
2829 strcpy(dev->name, "eth%d");
2830 rc = register_netdev(dev);
2831 if (rc) {
2832 airo_print_err(dev->name, "Couldn't register_netdev");
2833 goto err_out_map;
2834 }
2835 ai->wifidev = init_wifidev(ai, dev);
2836 if (!ai->wifidev)
2837 goto err_out_reg;
2838
2839 rc = readCapabilityRid(ai, &cap_rid, 1);
2840 if (rc != SUCCESS) {
2841 rc = -EIO;
2842 goto err_out_wifi;
2843 }
2844 /* WEP capability discovery */
2845 ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
2846 ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
2847
2848 airo_print_info(dev->name, "Firmware version %x.%x.%02x",
2849 ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
2850 (le16_to_cpu(cap_rid.softVer) & 0xFF),
2851 le16_to_cpu(cap_rid.softSubVer));
2852
2841 /* Test for WPA support */ 2853 /* Test for WPA support */
2842 if (airo_test_wpa_capable(ai)) { 2854 /* Only firmware versions 5.30.17 or better can do WPA */
2855 if (le16_to_cpu(cap_rid.softVer) > 0x530
2856 || (le16_to_cpu(cap_rid.softVer) == 0x530
2857 && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2858 airo_print_info(ai->dev->name, "WPA supported.");
2859
2843 set_bit(FLAG_WPA_CAPABLE, &ai->flags); 2860 set_bit(FLAG_WPA_CAPABLE, &ai->flags);
2844 ai->bssListFirst = RID_WPA_BSSLISTFIRST; 2861 ai->bssListFirst = RID_WPA_BSSLISTFIRST;
2845 ai->bssListNext = RID_WPA_BSSLISTNEXT; 2862 ai->bssListNext = RID_WPA_BSSLISTNEXT;
2846 ai->bssListRidLen = sizeof(BSSListRid); 2863 ai->bssListRidLen = sizeof(BSSListRid);
2847 } else { 2864 } else {
2865 airo_print_info(ai->dev->name, "WPA unsupported with firmware "
2866 "versions older than 5.30.17.");
2867
2848 ai->bssListFirst = RID_BSSLISTFIRST; 2868 ai->bssListFirst = RID_BSSLISTFIRST;
2849 ai->bssListNext = RID_BSSLISTNEXT; 2869 ai->bssListNext = RID_BSSLISTNEXT;
2850 ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra); 2870 ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
2851 } 2871 }
2852 2872
2853 strcpy(dev->name, "eth%d");
2854 rc = register_netdev(dev);
2855 if (rc) {
2856 airo_print_err(dev->name, "Couldn't register_netdev");
2857 goto err_out_map;
2858 }
2859 ai->wifidev = init_wifidev(ai, dev);
2860 if (!ai->wifidev)
2861 goto err_out_reg;
2862
2863 set_bit(FLAG_REGISTERED,&ai->flags); 2873 set_bit(FLAG_REGISTERED,&ai->flags);
2864 airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr); 2874 airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2865 2875
@@ -3127,314 +3137,354 @@ static int header_len(__le16 ctl)
3127 return 24; 3137 return 24;
3128} 3138}
3129 3139
3130static irqreturn_t airo_interrupt(int irq, void *dev_id) 3140static void airo_handle_cisco_mic(struct airo_info *ai)
3131{ 3141{
3132 struct net_device *dev = dev_id; 3142 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
3143 set_bit(JOB_MIC, &ai->jobs);
3144 wake_up_interruptible(&ai->thr_wait);
3145 }
3146}
3147
3148/* Airo Status codes */
3149#define STAT_NOBEACON 0x8000 /* Loss of sync - missed beacons */
3150#define STAT_MAXRETRIES 0x8001 /* Loss of sync - max retries */
3151#define STAT_MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
3152#define STAT_FORCELOSS 0x8003 /* Loss of sync - host request */
3153#define STAT_TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
3154#define STAT_DEAUTH 0x8100 /* low byte is 802.11 reason code */
3155#define STAT_DISASSOC 0x8200 /* low byte is 802.11 reason code */
3156#define STAT_ASSOC_FAIL 0x8400 /* low byte is 802.11 reason code */
3157#define STAT_AUTH_FAIL 0x0300 /* low byte is 802.11 reason code */
3158#define STAT_ASSOC 0x0400 /* Associated */
3159#define STAT_REASSOC 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
3160
3161static void airo_print_status(const char *devname, u16 status)
3162{
3163 u8 reason = status & 0xFF;
3164
3165 switch (status) {
3166 case STAT_NOBEACON:
3167 airo_print_dbg(devname, "link lost (missed beacons)");
3168 break;
3169 case STAT_MAXRETRIES:
3170 case STAT_MAXARL:
3171 airo_print_dbg(devname, "link lost (max retries)");
3172 break;
3173 case STAT_FORCELOSS:
3174 airo_print_dbg(devname, "link lost (local choice)");
3175 break;
3176 case STAT_TSFSYNC:
3177 airo_print_dbg(devname, "link lost (TSF sync lost)");
3178 break;
3179 case STAT_DEAUTH:
3180 airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
3181 break;
3182 case STAT_DISASSOC:
3183 airo_print_dbg(devname, "disassociated (reason: %d)", reason);
3184 break;
3185 case STAT_ASSOC_FAIL:
3186 airo_print_dbg(devname, "association failed (reason: %d)",
3187 reason);
3188 break;
3189 case STAT_AUTH_FAIL:
3190 airo_print_dbg(devname, "authentication failed (reason: %d)",
3191 reason);
3192 break;
3193 default:
3194 break;
3195 }
3196}
3197
3198static void airo_handle_link(struct airo_info *ai)
3199{
3200 union iwreq_data wrqu;
3201 int scan_forceloss = 0;
3133 u16 status; 3202 u16 status;
3134 u16 fid;
3135 struct airo_info *apriv = dev->ml_priv;
3136 u16 savedInterrupts = 0;
3137 int handled = 0;
3138 3203
3139 if (!netif_device_present(dev)) 3204 /* Get new status and acknowledge the link change */
3140 return IRQ_NONE; 3205 status = le16_to_cpu(IN4500(ai, LINKSTAT));
3206 OUT4500(ai, EVACK, EV_LINK);
3141 3207
3142 for (;;) { 3208 if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
3143 status = IN4500( apriv, EVSTAT ); 3209 scan_forceloss = 1;
3144 if ( !(status & STATUS_INTS) || status == 0xffff ) break;
3145 3210
3146 handled = 1; 3211 airo_print_status(ai->dev->name, status);
3147 3212
3148 if ( status & EV_AWAKE ) { 3213 if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
3149 OUT4500( apriv, EVACK, EV_AWAKE ); 3214 if (auto_wep)
3150 OUT4500( apriv, EVACK, EV_AWAKE ); 3215 ai->expires = 0;
3151 } 3216 if (ai->list_bss_task)
3217 wake_up_process(ai->list_bss_task);
3218 set_bit(FLAG_UPDATE_UNI, &ai->flags);
3219 set_bit(FLAG_UPDATE_MULTI, &ai->flags);
3152 3220
3153 if (!savedInterrupts) { 3221 if (down_trylock(&ai->sem) != 0) {
3154 savedInterrupts = IN4500( apriv, EVINTEN ); 3222 set_bit(JOB_EVENT, &ai->jobs);
3155 OUT4500( apriv, EVINTEN, 0 ); 3223 wake_up_interruptible(&ai->thr_wait);
3224 } else
3225 airo_send_event(ai->dev);
3226 } else if (!scan_forceloss) {
3227 if (auto_wep && !ai->expires) {
3228 ai->expires = RUN_AT(3*HZ);
3229 wake_up_interruptible(&ai->thr_wait);
3156 } 3230 }
3157 3231
3158 if ( status & EV_MIC ) { 3232 /* Send event to user space */
3159 OUT4500( apriv, EVACK, EV_MIC ); 3233 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3160 if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { 3234 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3161 set_bit(JOB_MIC, &apriv->jobs); 3235 wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
3162 wake_up_interruptible(&apriv->thr_wait); 3236 }
3163 } 3237}
3164 }
3165 if ( status & EV_LINK ) {
3166 union iwreq_data wrqu;
3167 int scan_forceloss = 0;
3168 /* The link status has changed, if you want to put a
3169 monitor hook in, do it here. (Remember that
3170 interrupts are still disabled!)
3171 */
3172 u16 newStatus = IN4500(apriv, LINKSTAT);
3173 OUT4500( apriv, EVACK, EV_LINK);
3174 /* Here is what newStatus means: */
3175#define NOBEACON 0x8000 /* Loss of sync - missed beacons */
3176#define MAXRETRIES 0x8001 /* Loss of sync - max retries */
3177#define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
3178#define FORCELOSS 0x8003 /* Loss of sync - host request */
3179#define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
3180#define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
3181#define DISASS 0x8200 /* Disassociation (low byte is reason code) */
3182#define ASSFAIL 0x8400 /* Association failure (low byte is reason
3183 code) */
3184#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
3185 code) */
3186#define ASSOCIATED 0x0400 /* Associated */
3187#define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
3188#define RC_RESERVED 0 /* Reserved return code */
3189#define RC_NOREASON 1 /* Unspecified reason */
3190#define RC_AUTHINV 2 /* Previous authentication invalid */
3191#define RC_DEAUTH 3 /* Deauthenticated because sending station is
3192 leaving */
3193#define RC_NOACT 4 /* Disassociated due to inactivity */
3194#define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
3195 all currently associated stations */
3196#define RC_BADCLASS2 6 /* Class 2 frame received from
3197 non-Authenticated station */
3198#define RC_BADCLASS3 7 /* Class 3 frame received from
3199 non-Associated station */
3200#define RC_STATLEAVE 8 /* Disassociated because sending station is
3201 leaving BSS */
3202#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
3203 Authenticated with the responding station */
3204 if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
3205 scan_forceloss = 1;
3206 if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
3207 if (auto_wep)
3208 apriv->expires = 0;
3209 if (apriv->list_bss_task)
3210 wake_up_process(apriv->list_bss_task);
3211 set_bit(FLAG_UPDATE_UNI, &apriv->flags);
3212 set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
3213
3214 if (down_trylock(&apriv->sem) != 0) {
3215 set_bit(JOB_EVENT, &apriv->jobs);
3216 wake_up_interruptible(&apriv->thr_wait);
3217 } else
3218 airo_send_event(dev);
3219 } else if (!scan_forceloss) {
3220 if (auto_wep && !apriv->expires) {
3221 apriv->expires = RUN_AT(3*HZ);
3222 wake_up_interruptible(&apriv->thr_wait);
3223 }
3224 3238
3225 /* Send event to user space */ 3239static void airo_handle_rx(struct airo_info *ai)
3226 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); 3240{
3227 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3241 struct sk_buff *skb = NULL;
3228 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL); 3242 __le16 fc, v, *buffer, tmpbuf[4];
3229 } 3243 u16 len, hdrlen = 0, gap, fid;
3230 } 3244 struct rx_hdr hdr;
3245 int success = 0;
3231 3246
3232 /* Check to see if there is something to receive */ 3247 if (test_bit(FLAG_MPI, &ai->flags)) {
3233 if ( status & EV_RX ) { 3248 if (test_bit(FLAG_802_11, &ai->flags))
3234 struct sk_buff *skb = NULL; 3249 mpi_receive_802_11(ai);
3235 __le16 fc, v; 3250 else
3236 u16 len, hdrlen = 0; 3251 mpi_receive_802_3(ai);
3237#pragma pack(1) 3252 OUT4500(ai, EVACK, EV_RX);
3238 struct { 3253 return;
3239 __le16 status, len; 3254 }
3240 u8 rssi[2];
3241 u8 rate;
3242 u8 freq;
3243 __le16 tmp[4];
3244 } hdr;
3245#pragma pack()
3246 u16 gap;
3247 __le16 tmpbuf[4];
3248 __le16 *buffer;
3249
3250 if (test_bit(FLAG_MPI,&apriv->flags)) {
3251 if (test_bit(FLAG_802_11, &apriv->flags))
3252 mpi_receive_802_11(apriv);
3253 else
3254 mpi_receive_802_3(apriv);
3255 OUT4500(apriv, EVACK, EV_RX);
3256 goto exitrx;
3257 }
3258 3255
3259 fid = IN4500( apriv, RXFID ); 3256 fid = IN4500(ai, RXFID);
3260
3261 /* Get the packet length */
3262 if (test_bit(FLAG_802_11, &apriv->flags)) {
3263 bap_setup (apriv, fid, 4, BAP0);
3264 bap_read (apriv, (__le16*)&hdr, sizeof(hdr), BAP0);
3265 /* Bad CRC. Ignore packet */
3266 if (le16_to_cpu(hdr.status) & 2)
3267 hdr.len = 0;
3268 if (apriv->wifidev == NULL)
3269 hdr.len = 0;
3270 } else {
3271 bap_setup (apriv, fid, 0x36, BAP0);
3272 bap_read (apriv, &hdr.len, 2, BAP0);
3273 }
3274 len = le16_to_cpu(hdr.len);
3275 3257
3276 if (len > AIRO_DEF_MTU) { 3258 /* Get the packet length */
3277 airo_print_err(apriv->dev->name, "Bad size %d", len); 3259 if (test_bit(FLAG_802_11, &ai->flags)) {
3278 goto badrx; 3260 bap_setup (ai, fid, 4, BAP0);
3279 } 3261 bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
3280 if (len == 0) 3262 /* Bad CRC. Ignore packet */
3281 goto badrx; 3263 if (le16_to_cpu(hdr.status) & 2)
3264 hdr.len = 0;
3265 if (ai->wifidev == NULL)
3266 hdr.len = 0;
3267 } else {
3268 bap_setup(ai, fid, 0x36, BAP0);
3269 bap_read(ai, &hdr.len, 2, BAP0);
3270 }
3271 len = le16_to_cpu(hdr.len);
3282 3272
3283 if (test_bit(FLAG_802_11, &apriv->flags)) { 3273 if (len > AIRO_DEF_MTU) {
3284 bap_read (apriv, &fc, sizeof(fc), BAP0); 3274 airo_print_err(ai->dev->name, "Bad size %d", len);
3285 hdrlen = header_len(fc); 3275 goto done;
3286 } else 3276 }
3287 hdrlen = ETH_ALEN * 2; 3277 if (len == 0)
3278 goto done;
3288 3279
3289 skb = dev_alloc_skb( len + hdrlen + 2 + 2 ); 3280 if (test_bit(FLAG_802_11, &ai->flags)) {
3290 if ( !skb ) { 3281 bap_read(ai, &fc, sizeof (fc), BAP0);
3291 dev->stats.rx_dropped++; 3282 hdrlen = header_len(fc);
3292 goto badrx; 3283 } else
3293 } 3284 hdrlen = ETH_ALEN * 2;
3294 skb_reserve(skb, 2); /* This way the IP header is aligned */ 3285
3295 buffer = (__le16*)skb_put (skb, len + hdrlen); 3286 skb = dev_alloc_skb(len + hdrlen + 2 + 2);
3296 if (test_bit(FLAG_802_11, &apriv->flags)) { 3287 if (!skb) {
3297 buffer[0] = fc; 3288 ai->dev->stats.rx_dropped++;
3298 bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); 3289 goto done;
3299 if (hdrlen == 24) 3290 }
3300 bap_read (apriv, tmpbuf, 6, BAP0); 3291
3301 3292 skb_reserve(skb, 2); /* This way the IP header is aligned */
3302 bap_read (apriv, &v, sizeof(v), BAP0); 3293 buffer = (__le16 *) skb_put(skb, len + hdrlen);
3303 gap = le16_to_cpu(v); 3294 if (test_bit(FLAG_802_11, &ai->flags)) {
3304 if (gap) { 3295 buffer[0] = fc;
3305 if (gap <= 8) { 3296 bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
3306 bap_read (apriv, tmpbuf, gap, BAP0); 3297 if (hdrlen == 24)
3307 } else { 3298 bap_read(ai, tmpbuf, 6, BAP0);
3308 airo_print_err(apriv->dev->name, "gaplen too " 3299
3309 "big. Problems will follow..."); 3300 bap_read(ai, &v, sizeof(v), BAP0);
3310 } 3301 gap = le16_to_cpu(v);
3311 } 3302 if (gap) {
3312 bap_read (apriv, buffer + hdrlen/2, len, BAP0); 3303 if (gap <= 8) {
3304 bap_read(ai, tmpbuf, gap, BAP0);
3313 } else { 3305 } else {
3314 MICBuffer micbuf; 3306 airo_print_err(ai->dev->name, "gaplen too "
3315 bap_read (apriv, buffer, ETH_ALEN*2, BAP0); 3307 "big. Problems will follow...");
3316 if (apriv->micstats.enabled) { 3308 }
3317 bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0); 3309 }
3318 if (ntohs(micbuf.typelen) > 0x05DC) 3310 bap_read(ai, buffer + hdrlen/2, len, BAP0);
3319 bap_setup (apriv, fid, 0x44, BAP0); 3311 } else {
3320 else { 3312 MICBuffer micbuf;
3321 if (len <= sizeof(micbuf)) 3313
3322 goto badmic; 3314 bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
3323 3315 if (ai->micstats.enabled) {
3324 len -= sizeof(micbuf); 3316 bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
3325 skb_trim (skb, len + hdrlen); 3317 if (ntohs(micbuf.typelen) > 0x05DC)
3326 } 3318 bap_setup(ai, fid, 0x44, BAP0);
3327 } 3319 else {
3328 bap_read(apriv,buffer+ETH_ALEN,len,BAP0); 3320 if (len <= sizeof (micbuf)) {
3329 if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { 3321 dev_kfree_skb_irq(skb);
3330badmic: 3322 goto done;
3331 dev_kfree_skb_irq (skb);
3332badrx:
3333 OUT4500( apriv, EVACK, EV_RX);
3334 goto exitrx;
3335 } 3323 }
3324
3325 len -= sizeof(micbuf);
3326 skb_trim(skb, len + hdrlen);
3336 } 3327 }
3328 }
3329
3330 bap_read(ai, buffer + ETH_ALEN, len, BAP0);
3331 if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
3332 dev_kfree_skb_irq (skb);
3333 else
3334 success = 1;
3335 }
3336
3337#ifdef WIRELESS_SPY 3337#ifdef WIRELESS_SPY
3338 if (apriv->spy_data.spy_number > 0) { 3338 if (success && (ai->spy_data.spy_number > 0)) {
3339 char *sa; 3339 char *sa;
3340 struct iw_quality wstats; 3340 struct iw_quality wstats;
3341 /* Prepare spy data : addr + qual */ 3341
3342 if (!test_bit(FLAG_802_11, &apriv->flags)) { 3342 /* Prepare spy data : addr + qual */
3343 sa = (char*)buffer + 6; 3343 if (!test_bit(FLAG_802_11, &ai->flags)) {
3344 bap_setup (apriv, fid, 8, BAP0); 3344 sa = (char *) buffer + 6;
3345 bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0); 3345 bap_setup(ai, fid, 8, BAP0);
3346 } else 3346 bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
3347 sa = (char*)buffer + 10; 3347 } else
3348 wstats.qual = hdr.rssi[0]; 3348 sa = (char *) buffer + 10;
3349 if (apriv->rssi) 3349 wstats.qual = hdr.rssi[0];
3350 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; 3350 if (ai->rssi)
3351 else 3351 wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3352 wstats.level = (hdr.rssi[1] + 321) / 2; 3352 else
3353 wstats.noise = apriv->wstats.qual.noise; 3353 wstats.level = (hdr.rssi[1] + 321) / 2;
3354 wstats.updated = IW_QUAL_LEVEL_UPDATED 3354 wstats.noise = ai->wstats.qual.noise;
3355 | IW_QUAL_QUAL_UPDATED 3355 wstats.updated = IW_QUAL_LEVEL_UPDATED
3356 | IW_QUAL_DBM; 3356 | IW_QUAL_QUAL_UPDATED
3357 /* Update spy records */ 3357 | IW_QUAL_DBM;
3358 wireless_spy_update(dev, sa, &wstats); 3358 /* Update spy records */
3359 } 3359 wireless_spy_update(ai->dev, sa, &wstats);
3360 }
3360#endif /* WIRELESS_SPY */ 3361#endif /* WIRELESS_SPY */
3361 OUT4500( apriv, EVACK, EV_RX);
3362 3362
3363 if (test_bit(FLAG_802_11, &apriv->flags)) { 3363done:
3364 skb_reset_mac_header(skb); 3364 OUT4500(ai, EVACK, EV_RX);
3365 skb->pkt_type = PACKET_OTHERHOST; 3365
3366 skb->dev = apriv->wifidev; 3366 if (success) {
3367 skb->protocol = htons(ETH_P_802_2); 3367 if (test_bit(FLAG_802_11, &ai->flags)) {
3368 } else 3368 skb_reset_mac_header(skb);
3369 skb->protocol = eth_type_trans(skb,dev); 3369 skb->pkt_type = PACKET_OTHERHOST;
3370 skb->ip_summed = CHECKSUM_NONE; 3370 skb->dev = ai->wifidev;
3371 skb->protocol = htons(ETH_P_802_2);
3372 } else
3373 skb->protocol = eth_type_trans(skb, ai->dev);
3374 skb->ip_summed = CHECKSUM_NONE;
3375
3376 netif_rx(skb);
3377 }
3378}
3379
3380static void airo_handle_tx(struct airo_info *ai, u16 status)
3381{
3382 int i, len = 0, index = -1;
3383 u16 fid;
3371 3384
3372 netif_rx( skb ); 3385 if (test_bit(FLAG_MPI, &ai->flags)) {
3386 unsigned long flags;
3387
3388 if (status & EV_TXEXC)
3389 get_tx_error(ai, -1);
3390
3391 spin_lock_irqsave(&ai->aux_lock, flags);
3392 if (!skb_queue_empty(&ai->txq)) {
3393 spin_unlock_irqrestore(&ai->aux_lock,flags);
3394 mpi_send_packet(ai->dev);
3395 } else {
3396 clear_bit(FLAG_PENDING_XMIT, &ai->flags);
3397 spin_unlock_irqrestore(&ai->aux_lock,flags);
3398 netif_wake_queue(ai->dev);
3373 } 3399 }
3374exitrx: 3400 OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3401 return;
3402 }
3375 3403
3376 /* Check to see if a packet has been transmitted */ 3404 fid = IN4500(ai, TXCOMPLFID);
3377 if ( status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
3378 int i;
3379 int len = 0;
3380 int index = -1;
3381
3382 if (test_bit(FLAG_MPI,&apriv->flags)) {
3383 unsigned long flags;
3384
3385 if (status & EV_TXEXC)
3386 get_tx_error(apriv, -1);
3387 spin_lock_irqsave(&apriv->aux_lock, flags);
3388 if (!skb_queue_empty(&apriv->txq)) {
3389 spin_unlock_irqrestore(&apriv->aux_lock,flags);
3390 mpi_send_packet (dev);
3391 } else {
3392 clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
3393 spin_unlock_irqrestore(&apriv->aux_lock,flags);
3394 netif_wake_queue (dev);
3395 }
3396 OUT4500( apriv, EVACK,
3397 status & (EV_TX|EV_TXCPY|EV_TXEXC));
3398 goto exittx;
3399 }
3400 3405
3401 fid = IN4500(apriv, TXCOMPLFID); 3406 for(i = 0; i < MAX_FIDS; i++) {
3407 if ((ai->fids[i] & 0xffff) == fid) {
3408 len = ai->fids[i] >> 16;
3409 index = i;
3410 }
3411 }
3402 3412
3403 for( i = 0; i < MAX_FIDS; i++ ) { 3413 if (index != -1) {
3404 if ( ( apriv->fids[i] & 0xffff ) == fid ) { 3414 if (status & EV_TXEXC)
3405 len = apriv->fids[i] >> 16; 3415 get_tx_error(ai, index);
3406 index = i; 3416
3407 } 3417 OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
3408 } 3418
3409 if (index != -1) { 3419 /* Set up to be used again */
3410 if (status & EV_TXEXC) 3420 ai->fids[index] &= 0xffff;
3411 get_tx_error(apriv, index); 3421 if (index < MAX_FIDS / 2) {
3412 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); 3422 if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
3413 /* Set up to be used again */ 3423 netif_wake_queue(ai->dev);
3414 apriv->fids[index] &= 0xffff; 3424 } else {
3415 if (index < MAX_FIDS / 2) { 3425 if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
3416 if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags)) 3426 netif_wake_queue(ai->wifidev);
3417 netif_wake_queue(dev); 3427 }
3418 } else { 3428 } else {
3419 if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags)) 3429 OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3420 netif_wake_queue(apriv->wifidev); 3430 airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
3421 } 3431 }
3422 } else { 3432}
3423 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC)); 3433
3424 airo_print_err(apriv->dev->name, "Unallocated FID was " 3434static irqreturn_t airo_interrupt(int irq, void *dev_id)
3425 "used to xmit" ); 3435{
3426 } 3436 struct net_device *dev = dev_id;
3437 u16 status, savedInterrupts = 0;
3438 struct airo_info *ai = dev->ml_priv;
3439 int handled = 0;
3440
3441 if (!netif_device_present(dev))
3442 return IRQ_NONE;
3443
3444 for (;;) {
3445 status = IN4500(ai, EVSTAT);
3446 if (!(status & STATUS_INTS) || (status == 0xffff))
3447 break;
3448
3449 handled = 1;
3450
3451 if (status & EV_AWAKE) {
3452 OUT4500(ai, EVACK, EV_AWAKE);
3453 OUT4500(ai, EVACK, EV_AWAKE);
3454 }
3455
3456 if (!savedInterrupts) {
3457 savedInterrupts = IN4500(ai, EVINTEN);
3458 OUT4500(ai, EVINTEN, 0);
3459 }
3460
3461 if (status & EV_MIC) {
3462 OUT4500(ai, EVACK, EV_MIC);
3463 airo_handle_cisco_mic(ai);
3427 } 3464 }
3428exittx: 3465
3429 if ( status & ~STATUS_INTS & ~IGNORE_INTS ) 3466 if (status & EV_LINK) {
3430 airo_print_warn(apriv->dev->name, "Got weird status %x", 3467 /* Link status changed */
3468 airo_handle_link(ai);
3469 }
3470
3471 /* Check to see if there is something to receive */
3472 if (status & EV_RX)
3473 airo_handle_rx(ai);
3474
3475 /* Check to see if a packet has been transmitted */
3476 if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
3477 airo_handle_tx(ai, status);
3478
3479 if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
3480 airo_print_warn(ai->dev->name, "Got weird status %x",
3431 status & ~STATUS_INTS & ~IGNORE_INTS ); 3481 status & ~STATUS_INTS & ~IGNORE_INTS );
3482 }
3432 } 3483 }
3433 3484
3434 if (savedInterrupts) 3485 if (savedInterrupts)
3435 OUT4500( apriv, EVINTEN, savedInterrupts ); 3486 OUT4500(ai, EVINTEN, savedInterrupts);
3436 3487
3437 /* done.. */
3438 return IRQ_RETVAL(handled); 3488 return IRQ_RETVAL(handled);
3439} 3489}
3440 3490
@@ -3613,18 +3663,10 @@ static void mpi_receive_802_11(struct airo_info *ai)
3613 struct sk_buff *skb = NULL; 3663 struct sk_buff *skb = NULL;
3614 u16 len, hdrlen = 0; 3664 u16 len, hdrlen = 0;
3615 __le16 fc; 3665 __le16 fc;
3616#pragma pack(1) 3666 struct rx_hdr hdr;
3617 struct {
3618 __le16 status, len;
3619 u8 rssi[2];
3620 u8 rate;
3621 u8 freq;
3622 __le16 tmp[4];
3623 } hdr;
3624#pragma pack()
3625 u16 gap; 3667 u16 gap;
3626 u16 *buffer; 3668 u16 *buffer;
3627 char *ptr = ai->rxfids[0].virtual_host_addr+4; 3669 char *ptr = ai->rxfids[0].virtual_host_addr + 4;
3628 3670
3629 memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd)); 3671 memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3630 memcpy ((char *)&hdr, ptr, sizeof(hdr)); 3672 memcpy ((char *)&hdr, ptr, sizeof(hdr));
@@ -3691,6 +3733,7 @@ static void mpi_receive_802_11(struct airo_info *ai)
3691 skb->protocol = htons(ETH_P_802_2); 3733 skb->protocol = htons(ETH_P_802_2);
3692 skb->ip_summed = CHECKSUM_NONE; 3734 skb->ip_summed = CHECKSUM_NONE;
3693 netif_rx( skb ); 3735 netif_rx( skb );
3736
3694badrx: 3737badrx:
3695 if (rxd.valid == 0) { 3738 if (rxd.valid == 0) {
3696 rxd.valid = 1; 3739 rxd.valid = 1;
@@ -5131,55 +5174,98 @@ static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5131 return rc; 5174 return rc;
5132} 5175}
5133 5176
5134/* Returns the length of the key at the index. If index == 0xffff 5177/* Returns the WEP key at the specified index, or -1 if that key does
5135 * the index of the transmit key is returned. If the key doesn't exist, 5178 * not exist. The buffer is assumed to be at least 16 bytes in length.
5136 * -1 will be returned.
5137 */ 5179 */
5138static int get_wep_key(struct airo_info *ai, u16 index) { 5180static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
5181{
5139 WepKeyRid wkr; 5182 WepKeyRid wkr;
5140 int rc; 5183 int rc;
5141 __le16 lastindex; 5184 __le16 lastindex;
5142 5185
5143 rc = readWepKeyRid(ai, &wkr, 1, 1); 5186 rc = readWepKeyRid(ai, &wkr, 1, 1);
5144 if (rc == SUCCESS) do { 5187 if (rc != SUCCESS)
5188 return -1;
5189 do {
5145 lastindex = wkr.kindex; 5190 lastindex = wkr.kindex;
5146 if (wkr.kindex == cpu_to_le16(index)) { 5191 if (le16_to_cpu(wkr.kindex) == index) {
5147 if (index == 0xffff) { 5192 int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
5148 return wkr.mac[0]; 5193 memcpy(buf, wkr.key, klen);
5149 } 5194 return klen;
5150 return le16_to_cpu(wkr.klen);
5151 } 5195 }
5152 readWepKeyRid(ai, &wkr, 0, 1); 5196 rc = readWepKeyRid(ai, &wkr, 0, 1);
5197 if (rc != SUCCESS)
5198 return -1;
5153 } while (lastindex != wkr.kindex); 5199 } while (lastindex != wkr.kindex);
5154 return -1; 5200 return -1;
5155} 5201}
5156 5202
5157static int set_wep_key(struct airo_info *ai, u16 index, 5203static int get_wep_tx_idx(struct airo_info *ai)
5158 const char *key, u16 keylen, int perm, int lock ) 5204{
5205 WepKeyRid wkr;
5206 int rc;
5207 __le16 lastindex;
5208
5209 rc = readWepKeyRid(ai, &wkr, 1, 1);
5210 if (rc != SUCCESS)
5211 return -1;
5212 do {
5213 lastindex = wkr.kindex;
5214 if (wkr.kindex == cpu_to_le16(0xffff))
5215 return wkr.mac[0];
5216 rc = readWepKeyRid(ai, &wkr, 0, 1);
5217 if (rc != SUCCESS)
5218 return -1;
5219 } while (lastindex != wkr.kindex);
5220 return -1;
5221}
5222
5223static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5224 u16 keylen, int perm, int lock)
5159{ 5225{
5160 static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; 5226 static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5161 WepKeyRid wkr; 5227 WepKeyRid wkr;
5228 int rc;
5162 5229
5163 memset(&wkr, 0, sizeof(wkr));
5164 if (keylen == 0) { 5230 if (keylen == 0) {
5165// We are selecting which key to use 5231 airo_print_err(ai->dev->name, "%s: key length to set was zero",
5166 wkr.len = cpu_to_le16(sizeof(wkr)); 5232 __func__);
5167 wkr.kindex = cpu_to_le16(0xffff); 5233 return -1;
5168 wkr.mac[0] = (char)index;
5169 if (perm) ai->defindex = (char)index;
5170 } else {
5171// We are actually setting the key
5172 wkr.len = cpu_to_le16(sizeof(wkr));
5173 wkr.kindex = cpu_to_le16(index);
5174 wkr.klen = cpu_to_le16(keylen);
5175 memcpy( wkr.key, key, keylen );
5176 memcpy( wkr.mac, macaddr, ETH_ALEN );
5177 } 5234 }
5178 5235
5236 memset(&wkr, 0, sizeof(wkr));
5237 wkr.len = cpu_to_le16(sizeof(wkr));
5238 wkr.kindex = cpu_to_le16(index);
5239 wkr.klen = cpu_to_le16(keylen);
5240 memcpy(wkr.key, key, keylen);
5241 memcpy(wkr.mac, macaddr, ETH_ALEN);
5242
5179 if (perm) disable_MAC(ai, lock); 5243 if (perm) disable_MAC(ai, lock);
5180 writeWepKeyRid(ai, &wkr, perm, lock); 5244 rc = writeWepKeyRid(ai, &wkr, perm, lock);
5181 if (perm) enable_MAC(ai, lock); 5245 if (perm) enable_MAC(ai, lock);
5182 return 0; 5246 return rc;
5247}
5248
5249static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
5250{
5251 WepKeyRid wkr;
5252 int rc;
5253
5254 memset(&wkr, 0, sizeof(wkr));
5255 wkr.len = cpu_to_le16(sizeof(wkr));
5256 wkr.kindex = cpu_to_le16(0xffff);
5257 wkr.mac[0] = (char)index;
5258
5259 if (perm) {
5260 ai->defindex = (char)index;
5261 disable_MAC(ai, lock);
5262 }
5263
5264 rc = writeWepKeyRid(ai, &wkr, perm, lock);
5265
5266 if (perm)
5267 enable_MAC(ai, lock);
5268 return rc;
5183} 5269}
5184 5270
5185static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { 5271static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
@@ -5187,7 +5273,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5187 struct proc_dir_entry *dp = PDE(inode); 5273 struct proc_dir_entry *dp = PDE(inode);
5188 struct net_device *dev = dp->data; 5274 struct net_device *dev = dp->data;
5189 struct airo_info *ai = dev->ml_priv; 5275 struct airo_info *ai = dev->ml_priv;
5190 int i; 5276 int i, rc;
5191 char key[16]; 5277 char key[16];
5192 u16 index = 0; 5278 u16 index = 0;
5193 int j = 0; 5279 int j = 0;
@@ -5201,7 +5287,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5201 (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) { 5287 (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5202 index = data->wbuffer[0] - '0'; 5288 index = data->wbuffer[0] - '0';
5203 if (data->wbuffer[1] == '\n') { 5289 if (data->wbuffer[1] == '\n') {
5204 set_wep_key(ai, index, NULL, 0, 1, 1); 5290 rc = set_wep_tx_idx(ai, index, 1, 1);
5291 if (rc < 0) {
5292 airo_print_err(ai->dev->name, "failed to set "
5293 "WEP transmit index to %d: %d.",
5294 index, rc);
5295 }
5205 return; 5296 return;
5206 } 5297 }
5207 j = 2; 5298 j = 2;
@@ -5220,7 +5311,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5220 break; 5311 break;
5221 } 5312 }
5222 } 5313 }
5223 set_wep_key(ai, index, key, i/3, 1, 1); 5314
5315 rc = set_wep_key(ai, index, key, i/3, 1, 1);
5316 if (rc < 0) {
5317 airo_print_err(ai->dev->name, "failed to set WEP key at index "
5318 "%d: %d.", index, rc);
5319 }
5224} 5320}
5225 5321
5226static int proc_wepkey_open( struct inode *inode, struct file *file ) 5322static int proc_wepkey_open( struct inode *inode, struct file *file )
@@ -5451,13 +5547,13 @@ static void timer_func( struct net_device *dev ) {
5451 break; 5547 break;
5452 case AUTH_SHAREDKEY: 5548 case AUTH_SHAREDKEY:
5453 if (apriv->keyindex < auto_wep) { 5549 if (apriv->keyindex < auto_wep) {
5454 set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0); 5550 set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
5455 apriv->config.authType = AUTH_SHAREDKEY; 5551 apriv->config.authType = AUTH_SHAREDKEY;
5456 apriv->keyindex++; 5552 apriv->keyindex++;
5457 } else { 5553 } else {
5458 /* Drop to ENCRYPT */ 5554 /* Drop to ENCRYPT */
5459 apriv->keyindex = 0; 5555 apriv->keyindex = 0;
5460 set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0); 5556 set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
5461 apriv->config.authType = AUTH_ENCRYPT; 5557 apriv->config.authType = AUTH_ENCRYPT;
5462 } 5558 }
5463 break; 5559 break;
@@ -5725,16 +5821,12 @@ static int airo_set_freq(struct net_device *dev,
5725 int rc = -EINPROGRESS; /* Call commit handler */ 5821 int rc = -EINPROGRESS; /* Call commit handler */
5726 5822
5727 /* If setting by frequency, convert to a channel */ 5823 /* If setting by frequency, convert to a channel */
5728 if((fwrq->e == 1) && 5824 if(fwrq->e == 1) {
5729 (fwrq->m >= (int) 2.412e8) &&
5730 (fwrq->m <= (int) 2.487e8)) {
5731 int f = fwrq->m / 100000; 5825 int f = fwrq->m / 100000;
5732 int c = 0; 5826
5733 while((c < 14) && (f != frequency_list[c]))
5734 c++;
5735 /* Hack to fall through... */ 5827 /* Hack to fall through... */
5736 fwrq->e = 0; 5828 fwrq->e = 0;
5737 fwrq->m = c + 1; 5829 fwrq->m = ieee80211_freq_to_dsss_chan(f);
5738 } 5830 }
5739 /* Setting by channel number */ 5831 /* Setting by channel number */
5740 if((fwrq->m > 1000) || (fwrq->e > 0)) 5832 if((fwrq->m > 1000) || (fwrq->e > 0))
@@ -5778,7 +5870,7 @@ static int airo_get_freq(struct net_device *dev,
5778 5870
5779 ch = le16_to_cpu(status_rid.channel); 5871 ch = le16_to_cpu(status_rid.channel);
5780 if((ch > 0) && (ch < 15)) { 5872 if((ch > 0) && (ch < 15)) {
5781 fwrq->m = frequency_list[ch - 1] * 100000; 5873 fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000;
5782 fwrq->e = 1; 5874 fwrq->e = 1;
5783 } else { 5875 } else {
5784 fwrq->m = ch; 5876 fwrq->m = ch;
@@ -6234,11 +6326,9 @@ static int airo_get_mode(struct net_device *dev,
6234 return 0; 6326 return 0;
6235} 6327}
6236 6328
6237static inline int valid_index(CapabilityRid *p, int index) 6329static inline int valid_index(struct airo_info *ai, int index)
6238{ 6330{
6239 if (index < 0) 6331 return (index >= 0) && (index <= ai->max_wep_idx);
6240 return 0;
6241 return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
6242} 6332}
6243 6333
6244/*------------------------------------------------------------------*/ 6334/*------------------------------------------------------------------*/
@@ -6251,16 +6341,13 @@ static int airo_set_encode(struct net_device *dev,
6251 char *extra) 6341 char *extra)
6252{ 6342{
6253 struct airo_info *local = dev->ml_priv; 6343 struct airo_info *local = dev->ml_priv;
6254 CapabilityRid cap_rid; /* Card capability info */ 6344 int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
6255 int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
6256 __le16 currentAuthType = local->config.authType; 6345 __le16 currentAuthType = local->config.authType;
6346 int rc = 0;
6257 6347
6258 /* Is WEP supported ? */ 6348 if (!local->wep_capable)
6259 readCapabilityRid(local, &cap_rid, 1);
6260 /* Older firmware doesn't support this...
6261 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6262 return -EOPNOTSUPP; 6349 return -EOPNOTSUPP;
6263 } */ 6350
6264 readConfigRid(local, 1); 6351 readConfigRid(local, 1);
6265 6352
6266 /* Basic checking: do we have a key to set ? 6353 /* Basic checking: do we have a key to set ?
@@ -6272,14 +6359,21 @@ static int airo_set_encode(struct net_device *dev,
6272 if (dwrq->length > 0) { 6359 if (dwrq->length > 0) {
6273 wep_key_t key; 6360 wep_key_t key;
6274 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 6361 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6275 int current_index = get_wep_key(local, 0xffff); 6362 int current_index;
6363
6276 /* Check the size of the key */ 6364 /* Check the size of the key */
6277 if (dwrq->length > MAX_KEY_SIZE) { 6365 if (dwrq->length > MAX_KEY_SIZE) {
6278 return -EINVAL; 6366 return -EINVAL;
6279 } 6367 }
6368
6369 current_index = get_wep_tx_idx(local);
6370 if (current_index < 0)
6371 current_index = 0;
6372
6280 /* Check the index (none -> use current) */ 6373 /* Check the index (none -> use current) */
6281 if (!valid_index(&cap_rid, index)) 6374 if (!valid_index(local, index))
6282 index = current_index; 6375 index = current_index;
6376
6283 /* Set the length */ 6377 /* Set the length */
6284 if (dwrq->length > MIN_KEY_SIZE) 6378 if (dwrq->length > MIN_KEY_SIZE)
6285 key.len = MAX_KEY_SIZE; 6379 key.len = MAX_KEY_SIZE;
@@ -6296,7 +6390,13 @@ static int airo_set_encode(struct net_device *dev,
6296 /* Copy the key in the driver */ 6390 /* Copy the key in the driver */
6297 memcpy(key.key, extra, dwrq->length); 6391 memcpy(key.key, extra, dwrq->length);
6298 /* Send the key to the card */ 6392 /* Send the key to the card */
6299 set_wep_key(local, index, key.key, key.len, perm, 1); 6393 rc = set_wep_key(local, index, key.key, key.len, perm, 1);
6394 if (rc < 0) {
6395 airo_print_err(local->dev->name, "failed to set"
6396 " WEP key at index %d: %d.",
6397 index, rc);
6398 return rc;
6399 }
6300 } 6400 }
6301 /* WE specify that if a valid key is set, encryption 6401 /* WE specify that if a valid key is set, encryption
6302 * should be enabled (user may turn it off later) 6402 * should be enabled (user may turn it off later)
@@ -6308,12 +6408,19 @@ static int airo_set_encode(struct net_device *dev,
6308 } else { 6408 } else {
6309 /* Do we want to just set the transmit key index ? */ 6409 /* Do we want to just set the transmit key index ? */
6310 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 6410 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6311 if (valid_index(&cap_rid, index)) { 6411 if (valid_index(local, index)) {
6312 set_wep_key(local, index, NULL, 0, perm, 1); 6412 rc = set_wep_tx_idx(local, index, perm, 1);
6313 } else 6413 if (rc < 0) {
6414 airo_print_err(local->dev->name, "failed to set"
6415 " WEP transmit index to %d: %d.",
6416 index, rc);
6417 return rc;
6418 }
6419 } else {
6314 /* Don't complain if only change the mode */ 6420 /* Don't complain if only change the mode */
6315 if (!(dwrq->flags & IW_ENCODE_MODE)) 6421 if (!(dwrq->flags & IW_ENCODE_MODE))
6316 return -EINVAL; 6422 return -EINVAL;
6423 }
6317 } 6424 }
6318 /* Read the flags */ 6425 /* Read the flags */
6319 if(dwrq->flags & IW_ENCODE_DISABLED) 6426 if(dwrq->flags & IW_ENCODE_DISABLED)
@@ -6339,14 +6446,13 @@ static int airo_get_encode(struct net_device *dev,
6339{ 6446{
6340 struct airo_info *local = dev->ml_priv; 6447 struct airo_info *local = dev->ml_priv;
6341 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 6448 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6342 CapabilityRid cap_rid; /* Card capability info */ 6449 u8 buf[16];
6343 6450
6344 /* Is it supported ? */ 6451 if (!local->wep_capable)
6345 readCapabilityRid(local, &cap_rid, 1);
6346 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6347 return -EOPNOTSUPP; 6452 return -EOPNOTSUPP;
6348 } 6453
6349 readConfigRid(local, 1); 6454 readConfigRid(local, 1);
6455
6350 /* Check encryption mode */ 6456 /* Check encryption mode */
6351 switch(local->config.authType) { 6457 switch(local->config.authType) {
6352 case AUTH_ENCRYPT: 6458 case AUTH_ENCRYPT:
@@ -6365,14 +6471,17 @@ static int airo_get_encode(struct net_device *dev,
6365 memset(extra, 0, 16); 6471 memset(extra, 0, 16);
6366 6472
6367 /* Which key do we want ? -1 -> tx index */ 6473 /* Which key do we want ? -1 -> tx index */
6368 if (!valid_index(&cap_rid, index)) 6474 if (!valid_index(local, index)) {
6369 index = get_wep_key(local, 0xffff); 6475 index = get_wep_tx_idx(local);
6476 if (index < 0)
6477 index = 0;
6478 }
6370 dwrq->flags |= index + 1; 6479 dwrq->flags |= index + 1;
6480
6371 /* Copy the key to the user buffer */ 6481 /* Copy the key to the user buffer */
6372 dwrq->length = get_wep_key(local, index); 6482 dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf));
6373 if (dwrq->length > 16) { 6483 memcpy(extra, buf, dwrq->length);
6374 dwrq->length=0; 6484
6375 }
6376 return 0; 6485 return 0;
6377} 6486}
6378 6487
@@ -6388,28 +6497,27 @@ static int airo_set_encodeext(struct net_device *dev,
6388 struct airo_info *local = dev->ml_priv; 6497 struct airo_info *local = dev->ml_priv;
6389 struct iw_point *encoding = &wrqu->encoding; 6498 struct iw_point *encoding = &wrqu->encoding;
6390 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 6499 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6391 CapabilityRid cap_rid; /* Card capability info */
6392 int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 ); 6500 int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
6393 __le16 currentAuthType = local->config.authType; 6501 __le16 currentAuthType = local->config.authType;
6394 int idx, key_len, alg = ext->alg, set_key = 1; 6502 int idx, key_len, alg = ext->alg, set_key = 1, rc;
6395 wep_key_t key; 6503 wep_key_t key;
6396 6504
6397 /* Is WEP supported ? */ 6505 if (!local->wep_capable)
6398 readCapabilityRid(local, &cap_rid, 1);
6399 /* Older firmware doesn't support this...
6400 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6401 return -EOPNOTSUPP; 6506 return -EOPNOTSUPP;
6402 } */ 6507
6403 readConfigRid(local, 1); 6508 readConfigRid(local, 1);
6404 6509
6405 /* Determine and validate the key index */ 6510 /* Determine and validate the key index */
6406 idx = encoding->flags & IW_ENCODE_INDEX; 6511 idx = encoding->flags & IW_ENCODE_INDEX;
6407 if (idx) { 6512 if (idx) {
6408 if (!valid_index(&cap_rid, idx - 1)) 6513 if (!valid_index(local, idx - 1))
6409 return -EINVAL; 6514 return -EINVAL;
6410 idx--; 6515 idx--;
6411 } else 6516 } else {
6412 idx = get_wep_key(local, 0xffff); 6517 idx = get_wep_tx_idx(local);
6518 if (idx < 0)
6519 idx = 0;
6520 }
6413 6521
6414 if (encoding->flags & IW_ENCODE_DISABLED) 6522 if (encoding->flags & IW_ENCODE_DISABLED)
6415 alg = IW_ENCODE_ALG_NONE; 6523 alg = IW_ENCODE_ALG_NONE;
@@ -6418,7 +6526,13 @@ static int airo_set_encodeext(struct net_device *dev,
6418 /* Only set transmit key index here, actual 6526 /* Only set transmit key index here, actual
6419 * key is set below if needed. 6527 * key is set below if needed.
6420 */ 6528 */
6421 set_wep_key(local, idx, NULL, 0, perm, 1); 6529 rc = set_wep_tx_idx(local, idx, perm, 1);
6530 if (rc < 0) {
6531 airo_print_err(local->dev->name, "failed to set "
6532 "WEP transmit index to %d: %d.",
6533 idx, rc);
6534 return rc;
6535 }
6422 set_key = ext->key_len > 0 ? 1 : 0; 6536 set_key = ext->key_len > 0 ? 1 : 0;
6423 } 6537 }
6424 6538
@@ -6444,7 +6558,12 @@ static int airo_set_encodeext(struct net_device *dev,
6444 return -EINVAL; 6558 return -EINVAL;
6445 } 6559 }
6446 /* Send the key to the card */ 6560 /* Send the key to the card */
6447 set_wep_key(local, idx, key.key, key.len, perm, 1); 6561 rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6562 if (rc < 0) {
6563 airo_print_err(local->dev->name, "failed to set WEP key"
6564 " at index %d: %d.", idx, rc);
6565 return rc;
6566 }
6448 } 6567 }
6449 6568
6450 /* Read the flags */ 6569 /* Read the flags */
@@ -6474,14 +6593,12 @@ static int airo_get_encodeext(struct net_device *dev,
6474 struct airo_info *local = dev->ml_priv; 6593 struct airo_info *local = dev->ml_priv;
6475 struct iw_point *encoding = &wrqu->encoding; 6594 struct iw_point *encoding = &wrqu->encoding;
6476 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 6595 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6477 CapabilityRid cap_rid; /* Card capability info */
6478 int idx, max_key_len; 6596 int idx, max_key_len;
6597 u8 buf[16];
6479 6598
6480 /* Is it supported ? */ 6599 if (!local->wep_capable)
6481 readCapabilityRid(local, &cap_rid, 1);
6482 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6483 return -EOPNOTSUPP; 6600 return -EOPNOTSUPP;
6484 } 6601
6485 readConfigRid(local, 1); 6602 readConfigRid(local, 1);
6486 6603
6487 max_key_len = encoding->length - sizeof(*ext); 6604 max_key_len = encoding->length - sizeof(*ext);
@@ -6490,11 +6607,14 @@ static int airo_get_encodeext(struct net_device *dev,
6490 6607
6491 idx = encoding->flags & IW_ENCODE_INDEX; 6608 idx = encoding->flags & IW_ENCODE_INDEX;
6492 if (idx) { 6609 if (idx) {
6493 if (!valid_index(&cap_rid, idx - 1)) 6610 if (!valid_index(local, idx - 1))
6494 return -EINVAL; 6611 return -EINVAL;
6495 idx--; 6612 idx--;
6496 } else 6613 } else {
6497 idx = get_wep_key(local, 0xffff); 6614 idx = get_wep_tx_idx(local);
6615 if (idx < 0)
6616 idx = 0;
6617 }
6498 6618
6499 encoding->flags = idx + 1; 6619 encoding->flags = idx + 1;
6500 memset(ext, 0, sizeof(*ext)); 6620 memset(ext, 0, sizeof(*ext));
@@ -6517,10 +6637,8 @@ static int airo_get_encodeext(struct net_device *dev,
6517 memset(extra, 0, 16); 6637 memset(extra, 0, 16);
6518 6638
6519 /* Copy the key to the user buffer */ 6639 /* Copy the key to the user buffer */
6520 ext->key_len = get_wep_key(local, idx); 6640 ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
6521 if (ext->key_len > 16) { 6641 memcpy(extra, buf, ext->key_len);
6522 ext->key_len=0;
6523 }
6524 6642
6525 return 0; 6643 return 0;
6526} 6644}
@@ -6795,8 +6913,8 @@ static int airo_get_range(struct net_device *dev,
6795 k = 0; 6913 k = 0;
6796 for(i = 0; i < 14; i++) { 6914 for(i = 0; i < 14; i++) {
6797 range->freq[k].i = i + 1; /* List index */ 6915 range->freq[k].i = i + 1; /* List index */
6798 range->freq[k].m = frequency_list[i] * 100000; 6916 range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
6799 range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ 6917 range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
6800 } 6918 }
6801 range->num_frequency = k; 6919 range->num_frequency = k;
6802 6920
@@ -7189,10 +7307,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
7189 /* Add frequency */ 7307 /* Add frequency */
7190 iwe.cmd = SIOCGIWFREQ; 7308 iwe.cmd = SIOCGIWFREQ;
7191 iwe.u.freq.m = le16_to_cpu(bss->dsChannel); 7309 iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7192 /* iwe.u.freq.m containt the channel (starting 1), our 7310 iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000;
7193 * frequency_list array start at index 0...
7194 */
7195 iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
7196 iwe.u.freq.e = 1; 7311 iwe.u.freq.e = 1;
7197 current_ev = iwe_stream_add_event(info, current_ev, end_buf, 7312 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7198 &iwe, IW_EV_FREQ_LEN); 7313 &iwe, IW_EV_FREQ_LEN);