aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-03-28 17:27:45 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-28 17:27:45 -0400
commit3fab191002b184e4390aa07c7149c6cc7b638ec7 (patch)
tree821382d49e47c19531bfc3bb9e1f8922486374d4 /drivers/net/wireless/airo.c
parent93394a761d78503f11d05b1a7b23d5a9ccc8dad2 (diff)
parent7c730ccdc1188b97f5c8cb690906242c7ed75c22 (diff)
Merge branch 'linus' into x86/core
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r--drivers/net/wireless/airo.c1210
1 files changed, 677 insertions, 533 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index fc4322ca669f..7e80aba8a148 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
@@ -1155,7 +1161,7 @@ struct airo_info {
1155 use the high bit to mark whether it is in use. */ 1161 use the high bit to mark whether it is in use. */
1156#define MAX_FIDS 6 1162#define MAX_FIDS 6
1157#define MPI_MAX_FIDS 1 1163#define MPI_MAX_FIDS 1
1158 int fids[MAX_FIDS]; 1164 u32 fids[MAX_FIDS];
1159 ConfigRid config; 1165 ConfigRid config;
1160 char keyindex; // Used with auto wep 1166 char keyindex; // Used with auto wep
1161 char defindex; // Used with auto wep 1167 char defindex; // Used with auto wep
@@ -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
@@ -2637,17 +2646,21 @@ static const struct header_ops airo_header_ops = {
2637 .parse = wll_header_parse, 2646 .parse = wll_header_parse,
2638}; 2647};
2639 2648
2649static const struct net_device_ops airo11_netdev_ops = {
2650 .ndo_open = airo_open,
2651 .ndo_stop = airo_close,
2652 .ndo_start_xmit = airo_start_xmit11,
2653 .ndo_get_stats = airo_get_stats,
2654 .ndo_set_mac_address = airo_set_mac_address,
2655 .ndo_do_ioctl = airo_ioctl,
2656 .ndo_change_mtu = airo_change_mtu,
2657};
2658
2640static void wifi_setup(struct net_device *dev) 2659static void wifi_setup(struct net_device *dev)
2641{ 2660{
2661 dev->netdev_ops = &airo11_netdev_ops;
2642 dev->header_ops = &airo_header_ops; 2662 dev->header_ops = &airo_header_ops;
2643 dev->hard_start_xmit = &airo_start_xmit11;
2644 dev->get_stats = &airo_get_stats;
2645 dev->set_mac_address = &airo_set_mac_address;
2646 dev->do_ioctl = &airo_ioctl;
2647 dev->wireless_handlers = &airo_handler_def; 2663 dev->wireless_handlers = &airo_handler_def;
2648 dev->change_mtu = &airo_change_mtu;
2649 dev->open = &airo_open;
2650 dev->stop = &airo_close;
2651 2664
2652 dev->type = ARPHRD_IEEE80211; 2665 dev->type = ARPHRD_IEEE80211;
2653 dev->hard_header_len = ETH_HLEN; 2666 dev->hard_header_len = ETH_HLEN;
@@ -2730,27 +2743,32 @@ static void airo_networks_initialize(struct airo_info *ai)
2730 &ai->network_free_list); 2743 &ai->network_free_list);
2731} 2744}
2732 2745
2733static int airo_test_wpa_capable(struct airo_info *ai) 2746static const struct net_device_ops airo_netdev_ops = {
2734{ 2747 .ndo_open = airo_open,
2735 int status; 2748 .ndo_stop = airo_close,
2736 CapabilityRid cap_rid; 2749 .ndo_start_xmit = airo_start_xmit,
2737 2750 .ndo_get_stats = airo_get_stats,
2738 status = readCapabilityRid(ai, &cap_rid, 1); 2751 .ndo_set_multicast_list = airo_set_multicast_list,
2739 if (status != SUCCESS) return 0; 2752 .ndo_set_mac_address = airo_set_mac_address,
2753 .ndo_do_ioctl = airo_ioctl,
2754 .ndo_change_mtu = airo_change_mtu,
2755 .ndo_set_mac_address = eth_mac_addr,
2756 .ndo_validate_addr = eth_validate_addr,
2757};
2740 2758
2741 /* Only firmware versions 5.30.17 or better can do WPA */ 2759static const struct net_device_ops mpi_netdev_ops = {
2742 if (le16_to_cpu(cap_rid.softVer) > 0x530 2760 .ndo_open = airo_open,
2743 || (le16_to_cpu(cap_rid.softVer) == 0x530 2761 .ndo_stop = airo_close,
2744 && le16_to_cpu(cap_rid.softSubVer) >= 17)) { 2762 .ndo_start_xmit = mpi_start_xmit,
2745 airo_print_info("", "WPA is supported."); 2763 .ndo_get_stats = airo_get_stats,
2746 return 1; 2764 .ndo_set_multicast_list = airo_set_multicast_list,
2747 } 2765 .ndo_set_mac_address = airo_set_mac_address,
2766 .ndo_do_ioctl = airo_ioctl,
2767 .ndo_change_mtu = airo_change_mtu,
2768 .ndo_set_mac_address = eth_mac_addr,
2769 .ndo_validate_addr = eth_validate_addr,
2770};
2748 2771
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 2772
2755static struct net_device *_init_airo_card( unsigned short irq, int port, 2773static struct net_device *_init_airo_card( unsigned short irq, int port,
2756 int is_pcmcia, struct pci_dev *pci, 2774 int is_pcmcia, struct pci_dev *pci,
@@ -2759,6 +2777,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2759 struct net_device *dev; 2777 struct net_device *dev;
2760 struct airo_info *ai; 2778 struct airo_info *ai;
2761 int i, rc; 2779 int i, rc;
2780 CapabilityRid cap_rid;
2762 2781
2763 /* Create the network device object. */ 2782 /* Create the network device object. */
2764 dev = alloc_netdev(sizeof(*ai), "", ether_setup); 2783 dev = alloc_netdev(sizeof(*ai), "", ether_setup);
@@ -2788,22 +2807,16 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2788 goto err_out_free; 2807 goto err_out_free;
2789 airo_networks_initialize (ai); 2808 airo_networks_initialize (ai);
2790 2809
2810 skb_queue_head_init (&ai->txq);
2811
2791 /* The Airo-specific entries in the device structure. */ 2812 /* The Airo-specific entries in the device structure. */
2792 if (test_bit(FLAG_MPI,&ai->flags)) { 2813 if (test_bit(FLAG_MPI,&ai->flags))
2793 skb_queue_head_init (&ai->txq); 2814 dev->netdev_ops = &mpi_netdev_ops;
2794 dev->hard_start_xmit = &mpi_start_xmit; 2815 else
2795 } else 2816 dev->netdev_ops = &airo_netdev_ops;
2796 dev->hard_start_xmit = &airo_start_xmit;
2797 dev->get_stats = &airo_get_stats;
2798 dev->set_multicast_list = &airo_set_multicast_list;
2799 dev->set_mac_address = &airo_set_mac_address;
2800 dev->do_ioctl = &airo_ioctl;
2801 dev->wireless_handlers = &airo_handler_def; 2817 dev->wireless_handlers = &airo_handler_def;
2802 ai->wireless_data.spy_data = &ai->spy_data; 2818 ai->wireless_data.spy_data = &ai->spy_data;
2803 dev->wireless_data = &ai->wireless_data; 2819 dev->wireless_data = &ai->wireless_data;
2804 dev->change_mtu = &airo_change_mtu;
2805 dev->open = &airo_open;
2806 dev->stop = &airo_close;
2807 dev->irq = irq; 2820 dev->irq = irq;
2808 dev->base_addr = port; 2821 dev->base_addr = port;
2809 2822
@@ -2828,7 +2841,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2828 } 2841 }
2829 2842
2830 if (probe) { 2843 if (probe) {
2831 if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) { 2844 if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
2832 airo_print_err(dev->name, "MAC could not be enabled" ); 2845 airo_print_err(dev->name, "MAC could not be enabled" );
2833 rc = -EIO; 2846 rc = -EIO;
2834 goto err_out_map; 2847 goto err_out_map;
@@ -2838,28 +2851,50 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2838 set_bit(FLAG_FLASHING, &ai->flags); 2851 set_bit(FLAG_FLASHING, &ai->flags);
2839 } 2852 }
2840 2853
2854 strcpy(dev->name, "eth%d");
2855 rc = register_netdev(dev);
2856 if (rc) {
2857 airo_print_err(dev->name, "Couldn't register_netdev");
2858 goto err_out_map;
2859 }
2860 ai->wifidev = init_wifidev(ai, dev);
2861 if (!ai->wifidev)
2862 goto err_out_reg;
2863
2864 rc = readCapabilityRid(ai, &cap_rid, 1);
2865 if (rc != SUCCESS) {
2866 rc = -EIO;
2867 goto err_out_wifi;
2868 }
2869 /* WEP capability discovery */
2870 ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
2871 ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
2872
2873 airo_print_info(dev->name, "Firmware version %x.%x.%02x",
2874 ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
2875 (le16_to_cpu(cap_rid.softVer) & 0xFF),
2876 le16_to_cpu(cap_rid.softSubVer));
2877
2841 /* Test for WPA support */ 2878 /* Test for WPA support */
2842 if (airo_test_wpa_capable(ai)) { 2879 /* Only firmware versions 5.30.17 or better can do WPA */
2880 if (le16_to_cpu(cap_rid.softVer) > 0x530
2881 || (le16_to_cpu(cap_rid.softVer) == 0x530
2882 && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2883 airo_print_info(ai->dev->name, "WPA supported.");
2884
2843 set_bit(FLAG_WPA_CAPABLE, &ai->flags); 2885 set_bit(FLAG_WPA_CAPABLE, &ai->flags);
2844 ai->bssListFirst = RID_WPA_BSSLISTFIRST; 2886 ai->bssListFirst = RID_WPA_BSSLISTFIRST;
2845 ai->bssListNext = RID_WPA_BSSLISTNEXT; 2887 ai->bssListNext = RID_WPA_BSSLISTNEXT;
2846 ai->bssListRidLen = sizeof(BSSListRid); 2888 ai->bssListRidLen = sizeof(BSSListRid);
2847 } else { 2889 } else {
2890 airo_print_info(ai->dev->name, "WPA unsupported with firmware "
2891 "versions older than 5.30.17.");
2892
2848 ai->bssListFirst = RID_BSSLISTFIRST; 2893 ai->bssListFirst = RID_BSSLISTFIRST;
2849 ai->bssListNext = RID_BSSLISTNEXT; 2894 ai->bssListNext = RID_BSSLISTNEXT;
2850 ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra); 2895 ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
2851 } 2896 }
2852 2897
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); 2898 set_bit(FLAG_REGISTERED,&ai->flags);
2864 airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr); 2899 airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2865 2900
@@ -3127,314 +3162,354 @@ static int header_len(__le16 ctl)
3127 return 24; 3162 return 24;
3128} 3163}
3129 3164
3130static irqreturn_t airo_interrupt(int irq, void *dev_id) 3165static void airo_handle_cisco_mic(struct airo_info *ai)
3131{ 3166{
3132 struct net_device *dev = dev_id; 3167 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
3168 set_bit(JOB_MIC, &ai->jobs);
3169 wake_up_interruptible(&ai->thr_wait);
3170 }
3171}
3172
3173/* Airo Status codes */
3174#define STAT_NOBEACON 0x8000 /* Loss of sync - missed beacons */
3175#define STAT_MAXRETRIES 0x8001 /* Loss of sync - max retries */
3176#define STAT_MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
3177#define STAT_FORCELOSS 0x8003 /* Loss of sync - host request */
3178#define STAT_TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
3179#define STAT_DEAUTH 0x8100 /* low byte is 802.11 reason code */
3180#define STAT_DISASSOC 0x8200 /* low byte is 802.11 reason code */
3181#define STAT_ASSOC_FAIL 0x8400 /* low byte is 802.11 reason code */
3182#define STAT_AUTH_FAIL 0x0300 /* low byte is 802.11 reason code */
3183#define STAT_ASSOC 0x0400 /* Associated */
3184#define STAT_REASSOC 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
3185
3186static void airo_print_status(const char *devname, u16 status)
3187{
3188 u8 reason = status & 0xFF;
3189
3190 switch (status) {
3191 case STAT_NOBEACON:
3192 airo_print_dbg(devname, "link lost (missed beacons)");
3193 break;
3194 case STAT_MAXRETRIES:
3195 case STAT_MAXARL:
3196 airo_print_dbg(devname, "link lost (max retries)");
3197 break;
3198 case STAT_FORCELOSS:
3199 airo_print_dbg(devname, "link lost (local choice)");
3200 break;
3201 case STAT_TSFSYNC:
3202 airo_print_dbg(devname, "link lost (TSF sync lost)");
3203 break;
3204 case STAT_DEAUTH:
3205 airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
3206 break;
3207 case STAT_DISASSOC:
3208 airo_print_dbg(devname, "disassociated (reason: %d)", reason);
3209 break;
3210 case STAT_ASSOC_FAIL:
3211 airo_print_dbg(devname, "association failed (reason: %d)",
3212 reason);
3213 break;
3214 case STAT_AUTH_FAIL:
3215 airo_print_dbg(devname, "authentication failed (reason: %d)",
3216 reason);
3217 break;
3218 default:
3219 break;
3220 }
3221}
3222
3223static void airo_handle_link(struct airo_info *ai)
3224{
3225 union iwreq_data wrqu;
3226 int scan_forceloss = 0;
3133 u16 status; 3227 u16 status;
3134 u16 fid;
3135 struct airo_info *apriv = dev->ml_priv;
3136 u16 savedInterrupts = 0;
3137 int handled = 0;
3138 3228
3139 if (!netif_device_present(dev)) 3229 /* Get new status and acknowledge the link change */
3140 return IRQ_NONE; 3230 status = le16_to_cpu(IN4500(ai, LINKSTAT));
3231 OUT4500(ai, EVACK, EV_LINK);
3141 3232
3142 for (;;) { 3233 if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
3143 status = IN4500( apriv, EVSTAT ); 3234 scan_forceloss = 1;
3144 if ( !(status & STATUS_INTS) || status == 0xffff ) break;
3145 3235
3146 handled = 1; 3236 airo_print_status(ai->dev->name, status);
3147 3237
3148 if ( status & EV_AWAKE ) { 3238 if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
3149 OUT4500( apriv, EVACK, EV_AWAKE ); 3239 if (auto_wep)
3150 OUT4500( apriv, EVACK, EV_AWAKE ); 3240 ai->expires = 0;
3151 } 3241 if (ai->list_bss_task)
3242 wake_up_process(ai->list_bss_task);
3243 set_bit(FLAG_UPDATE_UNI, &ai->flags);
3244 set_bit(FLAG_UPDATE_MULTI, &ai->flags);
3152 3245
3153 if (!savedInterrupts) { 3246 if (down_trylock(&ai->sem) != 0) {
3154 savedInterrupts = IN4500( apriv, EVINTEN ); 3247 set_bit(JOB_EVENT, &ai->jobs);
3155 OUT4500( apriv, EVINTEN, 0 ); 3248 wake_up_interruptible(&ai->thr_wait);
3249 } else
3250 airo_send_event(ai->dev);
3251 } else if (!scan_forceloss) {
3252 if (auto_wep && !ai->expires) {
3253 ai->expires = RUN_AT(3*HZ);
3254 wake_up_interruptible(&ai->thr_wait);
3156 } 3255 }
3157 3256
3158 if ( status & EV_MIC ) { 3257 /* Send event to user space */
3159 OUT4500( apriv, EVACK, EV_MIC ); 3258 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3160 if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { 3259 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3161 set_bit(JOB_MIC, &apriv->jobs); 3260 wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
3162 wake_up_interruptible(&apriv->thr_wait); 3261 }
3163 } 3262}
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 3263
3225 /* Send event to user space */ 3264static void airo_handle_rx(struct airo_info *ai)
3226 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); 3265{
3227 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3266 struct sk_buff *skb = NULL;
3228 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL); 3267 __le16 fc, v, *buffer, tmpbuf[4];
3229 } 3268 u16 len, hdrlen = 0, gap, fid;
3230 } 3269 struct rx_hdr hdr;
3270 int success = 0;
3231 3271
3232 /* Check to see if there is something to receive */ 3272 if (test_bit(FLAG_MPI, &ai->flags)) {
3233 if ( status & EV_RX ) { 3273 if (test_bit(FLAG_802_11, &ai->flags))
3234 struct sk_buff *skb = NULL; 3274 mpi_receive_802_11(ai);
3235 __le16 fc, v; 3275 else
3236 u16 len, hdrlen = 0; 3276 mpi_receive_802_3(ai);
3237#pragma pack(1) 3277 OUT4500(ai, EVACK, EV_RX);
3238 struct { 3278 return;
3239 __le16 status, len; 3279 }
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 3280
3259 fid = IN4500( apriv, RXFID ); 3281 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 3282
3276 if (len > AIRO_DEF_MTU) { 3283 /* Get the packet length */
3277 airo_print_err(apriv->dev->name, "Bad size %d", len); 3284 if (test_bit(FLAG_802_11, &ai->flags)) {
3278 goto badrx; 3285 bap_setup (ai, fid, 4, BAP0);
3279 } 3286 bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
3280 if (len == 0) 3287 /* Bad CRC. Ignore packet */
3281 goto badrx; 3288 if (le16_to_cpu(hdr.status) & 2)
3289 hdr.len = 0;
3290 if (ai->wifidev == NULL)
3291 hdr.len = 0;
3292 } else {
3293 bap_setup(ai, fid, 0x36, BAP0);
3294 bap_read(ai, &hdr.len, 2, BAP0);
3295 }
3296 len = le16_to_cpu(hdr.len);
3282 3297
3283 if (test_bit(FLAG_802_11, &apriv->flags)) { 3298 if (len > AIRO_DEF_MTU) {
3284 bap_read (apriv, &fc, sizeof(fc), BAP0); 3299 airo_print_err(ai->dev->name, "Bad size %d", len);
3285 hdrlen = header_len(fc); 3300 goto done;
3286 } else 3301 }
3287 hdrlen = ETH_ALEN * 2; 3302 if (len == 0)
3303 goto done;
3288 3304
3289 skb = dev_alloc_skb( len + hdrlen + 2 + 2 ); 3305 if (test_bit(FLAG_802_11, &ai->flags)) {
3290 if ( !skb ) { 3306 bap_read(ai, &fc, sizeof (fc), BAP0);
3291 dev->stats.rx_dropped++; 3307 hdrlen = header_len(fc);
3292 goto badrx; 3308 } else
3293 } 3309 hdrlen = ETH_ALEN * 2;
3294 skb_reserve(skb, 2); /* This way the IP header is aligned */ 3310
3295 buffer = (__le16*)skb_put (skb, len + hdrlen); 3311 skb = dev_alloc_skb(len + hdrlen + 2 + 2);
3296 if (test_bit(FLAG_802_11, &apriv->flags)) { 3312 if (!skb) {
3297 buffer[0] = fc; 3313 ai->dev->stats.rx_dropped++;
3298 bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); 3314 goto done;
3299 if (hdrlen == 24) 3315 }
3300 bap_read (apriv, tmpbuf, 6, BAP0); 3316
3301 3317 skb_reserve(skb, 2); /* This way the IP header is aligned */
3302 bap_read (apriv, &v, sizeof(v), BAP0); 3318 buffer = (__le16 *) skb_put(skb, len + hdrlen);
3303 gap = le16_to_cpu(v); 3319 if (test_bit(FLAG_802_11, &ai->flags)) {
3304 if (gap) { 3320 buffer[0] = fc;
3305 if (gap <= 8) { 3321 bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
3306 bap_read (apriv, tmpbuf, gap, BAP0); 3322 if (hdrlen == 24)
3307 } else { 3323 bap_read(ai, tmpbuf, 6, BAP0);
3308 airo_print_err(apriv->dev->name, "gaplen too " 3324
3309 "big. Problems will follow..."); 3325 bap_read(ai, &v, sizeof(v), BAP0);
3310 } 3326 gap = le16_to_cpu(v);
3311 } 3327 if (gap) {
3312 bap_read (apriv, buffer + hdrlen/2, len, BAP0); 3328 if (gap <= 8) {
3329 bap_read(ai, tmpbuf, gap, BAP0);
3313 } else { 3330 } else {
3314 MICBuffer micbuf; 3331 airo_print_err(ai->dev->name, "gaplen too "
3315 bap_read (apriv, buffer, ETH_ALEN*2, BAP0); 3332 "big. Problems will follow...");
3316 if (apriv->micstats.enabled) { 3333 }
3317 bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0); 3334 }
3318 if (ntohs(micbuf.typelen) > 0x05DC) 3335 bap_read(ai, buffer + hdrlen/2, len, BAP0);
3319 bap_setup (apriv, fid, 0x44, BAP0); 3336 } else {
3320 else { 3337 MICBuffer micbuf;
3321 if (len <= sizeof(micbuf)) 3338
3322 goto badmic; 3339 bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
3323 3340 if (ai->micstats.enabled) {
3324 len -= sizeof(micbuf); 3341 bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
3325 skb_trim (skb, len + hdrlen); 3342 if (ntohs(micbuf.typelen) > 0x05DC)
3326 } 3343 bap_setup(ai, fid, 0x44, BAP0);
3327 } 3344 else {
3328 bap_read(apriv,buffer+ETH_ALEN,len,BAP0); 3345 if (len <= sizeof (micbuf)) {
3329 if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { 3346 dev_kfree_skb_irq(skb);
3330badmic: 3347 goto done;
3331 dev_kfree_skb_irq (skb);
3332badrx:
3333 OUT4500( apriv, EVACK, EV_RX);
3334 goto exitrx;
3335 } 3348 }
3349
3350 len -= sizeof(micbuf);
3351 skb_trim(skb, len + hdrlen);
3336 } 3352 }
3353 }
3354
3355 bap_read(ai, buffer + ETH_ALEN, len, BAP0);
3356 if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
3357 dev_kfree_skb_irq (skb);
3358 else
3359 success = 1;
3360 }
3361
3337#ifdef WIRELESS_SPY 3362#ifdef WIRELESS_SPY
3338 if (apriv->spy_data.spy_number > 0) { 3363 if (success && (ai->spy_data.spy_number > 0)) {
3339 char *sa; 3364 char *sa;
3340 struct iw_quality wstats; 3365 struct iw_quality wstats;
3341 /* Prepare spy data : addr + qual */ 3366
3342 if (!test_bit(FLAG_802_11, &apriv->flags)) { 3367 /* Prepare spy data : addr + qual */
3343 sa = (char*)buffer + 6; 3368 if (!test_bit(FLAG_802_11, &ai->flags)) {
3344 bap_setup (apriv, fid, 8, BAP0); 3369 sa = (char *) buffer + 6;
3345 bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0); 3370 bap_setup(ai, fid, 8, BAP0);
3346 } else 3371 bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
3347 sa = (char*)buffer + 10; 3372 } else
3348 wstats.qual = hdr.rssi[0]; 3373 sa = (char *) buffer + 10;
3349 if (apriv->rssi) 3374 wstats.qual = hdr.rssi[0];
3350 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; 3375 if (ai->rssi)
3351 else 3376 wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3352 wstats.level = (hdr.rssi[1] + 321) / 2; 3377 else
3353 wstats.noise = apriv->wstats.qual.noise; 3378 wstats.level = (hdr.rssi[1] + 321) / 2;
3354 wstats.updated = IW_QUAL_LEVEL_UPDATED 3379 wstats.noise = ai->wstats.qual.noise;
3355 | IW_QUAL_QUAL_UPDATED 3380 wstats.updated = IW_QUAL_LEVEL_UPDATED
3356 | IW_QUAL_DBM; 3381 | IW_QUAL_QUAL_UPDATED
3357 /* Update spy records */ 3382 | IW_QUAL_DBM;
3358 wireless_spy_update(dev, sa, &wstats); 3383 /* Update spy records */
3359 } 3384 wireless_spy_update(ai->dev, sa, &wstats);
3385 }
3360#endif /* WIRELESS_SPY */ 3386#endif /* WIRELESS_SPY */
3361 OUT4500( apriv, EVACK, EV_RX);
3362 3387
3363 if (test_bit(FLAG_802_11, &apriv->flags)) { 3388done:
3364 skb_reset_mac_header(skb); 3389 OUT4500(ai, EVACK, EV_RX);
3365 skb->pkt_type = PACKET_OTHERHOST; 3390
3366 skb->dev = apriv->wifidev; 3391 if (success) {
3367 skb->protocol = htons(ETH_P_802_2); 3392 if (test_bit(FLAG_802_11, &ai->flags)) {
3368 } else 3393 skb_reset_mac_header(skb);
3369 skb->protocol = eth_type_trans(skb,dev); 3394 skb->pkt_type = PACKET_OTHERHOST;
3370 skb->ip_summed = CHECKSUM_NONE; 3395 skb->dev = ai->wifidev;
3396 skb->protocol = htons(ETH_P_802_2);
3397 } else
3398 skb->protocol = eth_type_trans(skb, ai->dev);
3399 skb->ip_summed = CHECKSUM_NONE;
3400
3401 netif_rx(skb);
3402 }
3403}
3404
3405static void airo_handle_tx(struct airo_info *ai, u16 status)
3406{
3407 int i, len = 0, index = -1;
3408 u16 fid;
3371 3409
3372 netif_rx( skb ); 3410 if (test_bit(FLAG_MPI, &ai->flags)) {
3411 unsigned long flags;
3412
3413 if (status & EV_TXEXC)
3414 get_tx_error(ai, -1);
3415
3416 spin_lock_irqsave(&ai->aux_lock, flags);
3417 if (!skb_queue_empty(&ai->txq)) {
3418 spin_unlock_irqrestore(&ai->aux_lock,flags);
3419 mpi_send_packet(ai->dev);
3420 } else {
3421 clear_bit(FLAG_PENDING_XMIT, &ai->flags);
3422 spin_unlock_irqrestore(&ai->aux_lock,flags);
3423 netif_wake_queue(ai->dev);
3373 } 3424 }
3374exitrx: 3425 OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3426 return;
3427 }
3375 3428
3376 /* Check to see if a packet has been transmitted */ 3429 fid = IN4500(ai, TXCOMPLFID);
3377 if ( status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) { 3430
3378 int i; 3431 for(i = 0; i < MAX_FIDS; i++) {
3379 int len = 0; 3432 if ((ai->fids[i] & 0xffff) == fid) {
3380 int index = -1; 3433 len = ai->fids[i] >> 16;
3381 3434 index = i;
3382 if (test_bit(FLAG_MPI,&apriv->flags)) { 3435 }
3383 unsigned long flags; 3436 }
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 3437
3401 fid = IN4500(apriv, TXCOMPLFID); 3438 if (index != -1) {
3439 if (status & EV_TXEXC)
3440 get_tx_error(ai, index);
3402 3441
3403 for( i = 0; i < MAX_FIDS; i++ ) { 3442 OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
3404 if ( ( apriv->fids[i] & 0xffff ) == fid ) { 3443
3405 len = apriv->fids[i] >> 16; 3444 /* Set up to be used again */
3406 index = i; 3445 ai->fids[index] &= 0xffff;
3407 } 3446 if (index < MAX_FIDS / 2) {
3408 } 3447 if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
3409 if (index != -1) { 3448 netif_wake_queue(ai->dev);
3410 if (status & EV_TXEXC) 3449 } else {
3411 get_tx_error(apriv, index); 3450 if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
3412 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); 3451 netif_wake_queue(ai->wifidev);
3413 /* Set up to be used again */ 3452 }
3414 apriv->fids[index] &= 0xffff; 3453 } else {
3415 if (index < MAX_FIDS / 2) { 3454 OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3416 if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags)) 3455 airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
3417 netif_wake_queue(dev); 3456 }
3418 } else { 3457}
3419 if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags)) 3458
3420 netif_wake_queue(apriv->wifidev); 3459static irqreturn_t airo_interrupt(int irq, void *dev_id)
3421 } 3460{
3422 } else { 3461 struct net_device *dev = dev_id;
3423 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC)); 3462 u16 status, savedInterrupts = 0;
3424 airo_print_err(apriv->dev->name, "Unallocated FID was " 3463 struct airo_info *ai = dev->ml_priv;
3425 "used to xmit" ); 3464 int handled = 0;
3426 } 3465
3466 if (!netif_device_present(dev))
3467 return IRQ_NONE;
3468
3469 for (;;) {
3470 status = IN4500(ai, EVSTAT);
3471 if (!(status & STATUS_INTS) || (status == 0xffff))
3472 break;
3473
3474 handled = 1;
3475
3476 if (status & EV_AWAKE) {
3477 OUT4500(ai, EVACK, EV_AWAKE);
3478 OUT4500(ai, EVACK, EV_AWAKE);
3479 }
3480
3481 if (!savedInterrupts) {
3482 savedInterrupts = IN4500(ai, EVINTEN);
3483 OUT4500(ai, EVINTEN, 0);
3484 }
3485
3486 if (status & EV_MIC) {
3487 OUT4500(ai, EVACK, EV_MIC);
3488 airo_handle_cisco_mic(ai);
3427 } 3489 }
3428exittx: 3490
3429 if ( status & ~STATUS_INTS & ~IGNORE_INTS ) 3491 if (status & EV_LINK) {
3430 airo_print_warn(apriv->dev->name, "Got weird status %x", 3492 /* Link status changed */
3493 airo_handle_link(ai);
3494 }
3495
3496 /* Check to see if there is something to receive */
3497 if (status & EV_RX)
3498 airo_handle_rx(ai);
3499
3500 /* Check to see if a packet has been transmitted */
3501 if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
3502 airo_handle_tx(ai, status);
3503
3504 if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
3505 airo_print_warn(ai->dev->name, "Got weird status %x",
3431 status & ~STATUS_INTS & ~IGNORE_INTS ); 3506 status & ~STATUS_INTS & ~IGNORE_INTS );
3507 }
3432 } 3508 }
3433 3509
3434 if (savedInterrupts) 3510 if (savedInterrupts)
3435 OUT4500( apriv, EVINTEN, savedInterrupts ); 3511 OUT4500(ai, EVINTEN, savedInterrupts);
3436 3512
3437 /* done.. */
3438 return IRQ_RETVAL(handled); 3513 return IRQ_RETVAL(handled);
3439} 3514}
3440 3515
@@ -3613,18 +3688,10 @@ static void mpi_receive_802_11(struct airo_info *ai)
3613 struct sk_buff *skb = NULL; 3688 struct sk_buff *skb = NULL;
3614 u16 len, hdrlen = 0; 3689 u16 len, hdrlen = 0;
3615 __le16 fc; 3690 __le16 fc;
3616#pragma pack(1) 3691 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; 3692 u16 gap;
3626 u16 *buffer; 3693 u16 *buffer;
3627 char *ptr = ai->rxfids[0].virtual_host_addr+4; 3694 char *ptr = ai->rxfids[0].virtual_host_addr + 4;
3628 3695
3629 memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd)); 3696 memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3630 memcpy ((char *)&hdr, ptr, sizeof(hdr)); 3697 memcpy ((char *)&hdr, ptr, sizeof(hdr));
@@ -3691,6 +3758,7 @@ static void mpi_receive_802_11(struct airo_info *ai)
3691 skb->protocol = htons(ETH_P_802_2); 3758 skb->protocol = htons(ETH_P_802_2);
3692 skb->ip_summed = CHECKSUM_NONE; 3759 skb->ip_summed = CHECKSUM_NONE;
3693 netif_rx( skb ); 3760 netif_rx( skb );
3761
3694badrx: 3762badrx:
3695 if (rxd.valid == 0) { 3763 if (rxd.valid == 0) {
3696 rxd.valid = 1; 3764 rxd.valid = 1;
@@ -3705,7 +3773,6 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3705 Cmd cmd; 3773 Cmd cmd;
3706 Resp rsp; 3774 Resp rsp;
3707 int status; 3775 int status;
3708 int i;
3709 SsidRid mySsid; 3776 SsidRid mySsid;
3710 __le16 lastindex; 3777 __le16 lastindex;
3711 WepKeyRid wkr; 3778 WepKeyRid wkr;
@@ -3747,6 +3814,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3747 if (lock) 3814 if (lock)
3748 up(&ai->sem); 3815 up(&ai->sem);
3749 if (ai->config.len == 0) { 3816 if (ai->config.len == 0) {
3817 int i;
3750 tdsRssiRid rssi_rid; 3818 tdsRssiRid rssi_rid;
3751 CapabilityRid cap_rid; 3819 CapabilityRid cap_rid;
3752 3820
@@ -3794,14 +3862,12 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3794 /* Check to see if there are any insmod configured 3862 /* Check to see if there are any insmod configured
3795 rates to add */ 3863 rates to add */
3796 if ( rates[0] ) { 3864 if ( rates[0] ) {
3797 int i = 0;
3798 memset(ai->config.rates,0,sizeof(ai->config.rates)); 3865 memset(ai->config.rates,0,sizeof(ai->config.rates));
3799 for( i = 0; i < 8 && rates[i]; i++ ) { 3866 for( i = 0; i < 8 && rates[i]; i++ ) {
3800 ai->config.rates[i] = rates[i]; 3867 ai->config.rates[i] = rates[i];
3801 } 3868 }
3802 } 3869 }
3803 if ( basic_rate > 0 ) { 3870 if ( basic_rate > 0 ) {
3804 int i;
3805 for( i = 0; i < 8; i++ ) { 3871 for( i = 0; i < 8; i++ ) {
3806 if ( ai->config.rates[i] == basic_rate || 3872 if ( ai->config.rates[i] == basic_rate ||
3807 !ai->config.rates ) { 3873 !ai->config.rates ) {
@@ -4686,7 +4752,7 @@ static int proc_stats_rid_open( struct inode *inode,
4686 StatsRid stats; 4752 StatsRid stats;
4687 int i, j; 4753 int i, j;
4688 __le32 *vals = stats.vals; 4754 __le32 *vals = stats.vals;
4689 int len = le16_to_cpu(stats.len); 4755 int len;
4690 4756
4691 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4757 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4692 return -ENOMEM; 4758 return -ENOMEM;
@@ -4697,6 +4763,7 @@ static int proc_stats_rid_open( struct inode *inode,
4697 } 4763 }
4698 4764
4699 readStatsRid(apriv, &stats, rid, 1); 4765 readStatsRid(apriv, &stats, rid, 1);
4766 len = le16_to_cpu(stats.len);
4700 4767
4701 j = 0; 4768 j = 0;
4702 for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) { 4769 for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
@@ -5131,55 +5198,98 @@ static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5131 return rc; 5198 return rc;
5132} 5199}
5133 5200
5134/* Returns the length of the key at the index. If index == 0xffff 5201/* 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, 5202 * not exist. The buffer is assumed to be at least 16 bytes in length.
5136 * -1 will be returned.
5137 */ 5203 */
5138static int get_wep_key(struct airo_info *ai, u16 index) { 5204static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
5205{
5139 WepKeyRid wkr; 5206 WepKeyRid wkr;
5140 int rc; 5207 int rc;
5141 __le16 lastindex; 5208 __le16 lastindex;
5142 5209
5143 rc = readWepKeyRid(ai, &wkr, 1, 1); 5210 rc = readWepKeyRid(ai, &wkr, 1, 1);
5144 if (rc == SUCCESS) do { 5211 if (rc != SUCCESS)
5212 return -1;
5213 do {
5145 lastindex = wkr.kindex; 5214 lastindex = wkr.kindex;
5146 if (wkr.kindex == cpu_to_le16(index)) { 5215 if (le16_to_cpu(wkr.kindex) == index) {
5147 if (index == 0xffff) { 5216 int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
5148 return wkr.mac[0]; 5217 memcpy(buf, wkr.key, klen);
5149 } 5218 return klen;
5150 return le16_to_cpu(wkr.klen);
5151 } 5219 }
5152 readWepKeyRid(ai, &wkr, 0, 1); 5220 rc = readWepKeyRid(ai, &wkr, 0, 1);
5221 if (rc != SUCCESS)
5222 return -1;
5153 } while (lastindex != wkr.kindex); 5223 } while (lastindex != wkr.kindex);
5154 return -1; 5224 return -1;
5155} 5225}
5156 5226
5157static int set_wep_key(struct airo_info *ai, u16 index, 5227static int get_wep_tx_idx(struct airo_info *ai)
5158 const char *key, u16 keylen, int perm, int lock ) 5228{
5229 WepKeyRid wkr;
5230 int rc;
5231 __le16 lastindex;
5232
5233 rc = readWepKeyRid(ai, &wkr, 1, 1);
5234 if (rc != SUCCESS)
5235 return -1;
5236 do {
5237 lastindex = wkr.kindex;
5238 if (wkr.kindex == cpu_to_le16(0xffff))
5239 return wkr.mac[0];
5240 rc = readWepKeyRid(ai, &wkr, 0, 1);
5241 if (rc != SUCCESS)
5242 return -1;
5243 } while (lastindex != wkr.kindex);
5244 return -1;
5245}
5246
5247static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5248 u16 keylen, int perm, int lock)
5159{ 5249{
5160 static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; 5250 static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5161 WepKeyRid wkr; 5251 WepKeyRid wkr;
5252 int rc;
5162 5253
5163 memset(&wkr, 0, sizeof(wkr));
5164 if (keylen == 0) { 5254 if (keylen == 0) {
5165// We are selecting which key to use 5255 airo_print_err(ai->dev->name, "%s: key length to set was zero",
5166 wkr.len = cpu_to_le16(sizeof(wkr)); 5256 __func__);
5167 wkr.kindex = cpu_to_le16(0xffff); 5257 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 } 5258 }
5178 5259
5260 memset(&wkr, 0, sizeof(wkr));
5261 wkr.len = cpu_to_le16(sizeof(wkr));
5262 wkr.kindex = cpu_to_le16(index);
5263 wkr.klen = cpu_to_le16(keylen);
5264 memcpy(wkr.key, key, keylen);
5265 memcpy(wkr.mac, macaddr, ETH_ALEN);
5266
5179 if (perm) disable_MAC(ai, lock); 5267 if (perm) disable_MAC(ai, lock);
5180 writeWepKeyRid(ai, &wkr, perm, lock); 5268 rc = writeWepKeyRid(ai, &wkr, perm, lock);
5181 if (perm) enable_MAC(ai, lock); 5269 if (perm) enable_MAC(ai, lock);
5182 return 0; 5270 return rc;
5271}
5272
5273static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
5274{
5275 WepKeyRid wkr;
5276 int rc;
5277
5278 memset(&wkr, 0, sizeof(wkr));
5279 wkr.len = cpu_to_le16(sizeof(wkr));
5280 wkr.kindex = cpu_to_le16(0xffff);
5281 wkr.mac[0] = (char)index;
5282
5283 if (perm) {
5284 ai->defindex = (char)index;
5285 disable_MAC(ai, lock);
5286 }
5287
5288 rc = writeWepKeyRid(ai, &wkr, perm, lock);
5289
5290 if (perm)
5291 enable_MAC(ai, lock);
5292 return rc;
5183} 5293}
5184 5294
5185static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { 5295static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
@@ -5187,7 +5297,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5187 struct proc_dir_entry *dp = PDE(inode); 5297 struct proc_dir_entry *dp = PDE(inode);
5188 struct net_device *dev = dp->data; 5298 struct net_device *dev = dp->data;
5189 struct airo_info *ai = dev->ml_priv; 5299 struct airo_info *ai = dev->ml_priv;
5190 int i; 5300 int i, rc;
5191 char key[16]; 5301 char key[16];
5192 u16 index = 0; 5302 u16 index = 0;
5193 int j = 0; 5303 int j = 0;
@@ -5201,7 +5311,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5201 (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) { 5311 (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5202 index = data->wbuffer[0] - '0'; 5312 index = data->wbuffer[0] - '0';
5203 if (data->wbuffer[1] == '\n') { 5313 if (data->wbuffer[1] == '\n') {
5204 set_wep_key(ai, index, NULL, 0, 1, 1); 5314 rc = set_wep_tx_idx(ai, index, 1, 1);
5315 if (rc < 0) {
5316 airo_print_err(ai->dev->name, "failed to set "
5317 "WEP transmit index to %d: %d.",
5318 index, rc);
5319 }
5205 return; 5320 return;
5206 } 5321 }
5207 j = 2; 5322 j = 2;
@@ -5220,7 +5335,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5220 break; 5335 break;
5221 } 5336 }
5222 } 5337 }
5223 set_wep_key(ai, index, key, i/3, 1, 1); 5338
5339 rc = set_wep_key(ai, index, key, i/3, 1, 1);
5340 if (rc < 0) {
5341 airo_print_err(ai->dev->name, "failed to set WEP key at index "
5342 "%d: %d.", index, rc);
5343 }
5224} 5344}
5225 5345
5226static int proc_wepkey_open( struct inode *inode, struct file *file ) 5346static int proc_wepkey_open( struct inode *inode, struct file *file )
@@ -5451,13 +5571,13 @@ static void timer_func( struct net_device *dev ) {
5451 break; 5571 break;
5452 case AUTH_SHAREDKEY: 5572 case AUTH_SHAREDKEY:
5453 if (apriv->keyindex < auto_wep) { 5573 if (apriv->keyindex < auto_wep) {
5454 set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0); 5574 set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
5455 apriv->config.authType = AUTH_SHAREDKEY; 5575 apriv->config.authType = AUTH_SHAREDKEY;
5456 apriv->keyindex++; 5576 apriv->keyindex++;
5457 } else { 5577 } else {
5458 /* Drop to ENCRYPT */ 5578 /* Drop to ENCRYPT */
5459 apriv->keyindex = 0; 5579 apriv->keyindex = 0;
5460 set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0); 5580 set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
5461 apriv->config.authType = AUTH_ENCRYPT; 5581 apriv->config.authType = AUTH_ENCRYPT;
5462 } 5582 }
5463 break; 5583 break;
@@ -5725,16 +5845,12 @@ static int airo_set_freq(struct net_device *dev,
5725 int rc = -EINPROGRESS; /* Call commit handler */ 5845 int rc = -EINPROGRESS; /* Call commit handler */
5726 5846
5727 /* If setting by frequency, convert to a channel */ 5847 /* If setting by frequency, convert to a channel */
5728 if((fwrq->e == 1) && 5848 if(fwrq->e == 1) {
5729 (fwrq->m >= (int) 2.412e8) &&
5730 (fwrq->m <= (int) 2.487e8)) {
5731 int f = fwrq->m / 100000; 5849 int f = fwrq->m / 100000;
5732 int c = 0; 5850
5733 while((c < 14) && (f != frequency_list[c]))
5734 c++;
5735 /* Hack to fall through... */ 5851 /* Hack to fall through... */
5736 fwrq->e = 0; 5852 fwrq->e = 0;
5737 fwrq->m = c + 1; 5853 fwrq->m = ieee80211_freq_to_dsss_chan(f);
5738 } 5854 }
5739 /* Setting by channel number */ 5855 /* Setting by channel number */
5740 if((fwrq->m > 1000) || (fwrq->e > 0)) 5856 if((fwrq->m > 1000) || (fwrq->e > 0))
@@ -5778,7 +5894,7 @@ static int airo_get_freq(struct net_device *dev,
5778 5894
5779 ch = le16_to_cpu(status_rid.channel); 5895 ch = le16_to_cpu(status_rid.channel);
5780 if((ch > 0) && (ch < 15)) { 5896 if((ch > 0) && (ch < 15)) {
5781 fwrq->m = frequency_list[ch - 1] * 100000; 5897 fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000;
5782 fwrq->e = 1; 5898 fwrq->e = 1;
5783 } else { 5899 } else {
5784 fwrq->m = ch; 5900 fwrq->m = ch;
@@ -6234,11 +6350,9 @@ static int airo_get_mode(struct net_device *dev,
6234 return 0; 6350 return 0;
6235} 6351}
6236 6352
6237static inline int valid_index(CapabilityRid *p, int index) 6353static inline int valid_index(struct airo_info *ai, int index)
6238{ 6354{
6239 if (index < 0) 6355 return (index >= 0) && (index <= ai->max_wep_idx);
6240 return 0;
6241 return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
6242} 6356}
6243 6357
6244/*------------------------------------------------------------------*/ 6358/*------------------------------------------------------------------*/
@@ -6251,16 +6365,13 @@ static int airo_set_encode(struct net_device *dev,
6251 char *extra) 6365 char *extra)
6252{ 6366{
6253 struct airo_info *local = dev->ml_priv; 6367 struct airo_info *local = dev->ml_priv;
6254 CapabilityRid cap_rid; /* Card capability info */ 6368 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; 6369 __le16 currentAuthType = local->config.authType;
6370 int rc = 0;
6257 6371
6258 /* Is WEP supported ? */ 6372 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; 6373 return -EOPNOTSUPP;
6263 } */ 6374
6264 readConfigRid(local, 1); 6375 readConfigRid(local, 1);
6265 6376
6266 /* Basic checking: do we have a key to set ? 6377 /* Basic checking: do we have a key to set ?
@@ -6272,14 +6383,21 @@ static int airo_set_encode(struct net_device *dev,
6272 if (dwrq->length > 0) { 6383 if (dwrq->length > 0) {
6273 wep_key_t key; 6384 wep_key_t key;
6274 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 6385 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6275 int current_index = get_wep_key(local, 0xffff); 6386 int current_index;
6387
6276 /* Check the size of the key */ 6388 /* Check the size of the key */
6277 if (dwrq->length > MAX_KEY_SIZE) { 6389 if (dwrq->length > MAX_KEY_SIZE) {
6278 return -EINVAL; 6390 return -EINVAL;
6279 } 6391 }
6392
6393 current_index = get_wep_tx_idx(local);
6394 if (current_index < 0)
6395 current_index = 0;
6396
6280 /* Check the index (none -> use current) */ 6397 /* Check the index (none -> use current) */
6281 if (!valid_index(&cap_rid, index)) 6398 if (!valid_index(local, index))
6282 index = current_index; 6399 index = current_index;
6400
6283 /* Set the length */ 6401 /* Set the length */
6284 if (dwrq->length > MIN_KEY_SIZE) 6402 if (dwrq->length > MIN_KEY_SIZE)
6285 key.len = MAX_KEY_SIZE; 6403 key.len = MAX_KEY_SIZE;
@@ -6296,7 +6414,13 @@ static int airo_set_encode(struct net_device *dev,
6296 /* Copy the key in the driver */ 6414 /* Copy the key in the driver */
6297 memcpy(key.key, extra, dwrq->length); 6415 memcpy(key.key, extra, dwrq->length);
6298 /* Send the key to the card */ 6416 /* Send the key to the card */
6299 set_wep_key(local, index, key.key, key.len, perm, 1); 6417 rc = set_wep_key(local, index, key.key, key.len, perm, 1);
6418 if (rc < 0) {
6419 airo_print_err(local->dev->name, "failed to set"
6420 " WEP key at index %d: %d.",
6421 index, rc);
6422 return rc;
6423 }
6300 } 6424 }
6301 /* WE specify that if a valid key is set, encryption 6425 /* WE specify that if a valid key is set, encryption
6302 * should be enabled (user may turn it off later) 6426 * should be enabled (user may turn it off later)
@@ -6308,12 +6432,19 @@ static int airo_set_encode(struct net_device *dev,
6308 } else { 6432 } else {
6309 /* Do we want to just set the transmit key index ? */ 6433 /* Do we want to just set the transmit key index ? */
6310 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 6434 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6311 if (valid_index(&cap_rid, index)) { 6435 if (valid_index(local, index)) {
6312 set_wep_key(local, index, NULL, 0, perm, 1); 6436 rc = set_wep_tx_idx(local, index, perm, 1);
6313 } else 6437 if (rc < 0) {
6438 airo_print_err(local->dev->name, "failed to set"
6439 " WEP transmit index to %d: %d.",
6440 index, rc);
6441 return rc;
6442 }
6443 } else {
6314 /* Don't complain if only change the mode */ 6444 /* Don't complain if only change the mode */
6315 if (!(dwrq->flags & IW_ENCODE_MODE)) 6445 if (!(dwrq->flags & IW_ENCODE_MODE))
6316 return -EINVAL; 6446 return -EINVAL;
6447 }
6317 } 6448 }
6318 /* Read the flags */ 6449 /* Read the flags */
6319 if(dwrq->flags & IW_ENCODE_DISABLED) 6450 if(dwrq->flags & IW_ENCODE_DISABLED)
@@ -6339,14 +6470,13 @@ static int airo_get_encode(struct net_device *dev,
6339{ 6470{
6340 struct airo_info *local = dev->ml_priv; 6471 struct airo_info *local = dev->ml_priv;
6341 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 6472 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6342 CapabilityRid cap_rid; /* Card capability info */ 6473 u8 buf[16];
6343 6474
6344 /* Is it supported ? */ 6475 if (!local->wep_capable)
6345 readCapabilityRid(local, &cap_rid, 1);
6346 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6347 return -EOPNOTSUPP; 6476 return -EOPNOTSUPP;
6348 } 6477
6349 readConfigRid(local, 1); 6478 readConfigRid(local, 1);
6479
6350 /* Check encryption mode */ 6480 /* Check encryption mode */
6351 switch(local->config.authType) { 6481 switch(local->config.authType) {
6352 case AUTH_ENCRYPT: 6482 case AUTH_ENCRYPT:
@@ -6365,14 +6495,17 @@ static int airo_get_encode(struct net_device *dev,
6365 memset(extra, 0, 16); 6495 memset(extra, 0, 16);
6366 6496
6367 /* Which key do we want ? -1 -> tx index */ 6497 /* Which key do we want ? -1 -> tx index */
6368 if (!valid_index(&cap_rid, index)) 6498 if (!valid_index(local, index)) {
6369 index = get_wep_key(local, 0xffff); 6499 index = get_wep_tx_idx(local);
6500 if (index < 0)
6501 index = 0;
6502 }
6370 dwrq->flags |= index + 1; 6503 dwrq->flags |= index + 1;
6504
6371 /* Copy the key to the user buffer */ 6505 /* Copy the key to the user buffer */
6372 dwrq->length = get_wep_key(local, index); 6506 dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf));
6373 if (dwrq->length > 16) { 6507 memcpy(extra, buf, dwrq->length);
6374 dwrq->length=0; 6508
6375 }
6376 return 0; 6509 return 0;
6377} 6510}
6378 6511
@@ -6388,28 +6521,27 @@ static int airo_set_encodeext(struct net_device *dev,
6388 struct airo_info *local = dev->ml_priv; 6521 struct airo_info *local = dev->ml_priv;
6389 struct iw_point *encoding = &wrqu->encoding; 6522 struct iw_point *encoding = &wrqu->encoding;
6390 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 6523 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 ); 6524 int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
6393 __le16 currentAuthType = local->config.authType; 6525 __le16 currentAuthType = local->config.authType;
6394 int idx, key_len, alg = ext->alg, set_key = 1; 6526 int idx, key_len, alg = ext->alg, set_key = 1, rc;
6395 wep_key_t key; 6527 wep_key_t key;
6396 6528
6397 /* Is WEP supported ? */ 6529 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; 6530 return -EOPNOTSUPP;
6402 } */ 6531
6403 readConfigRid(local, 1); 6532 readConfigRid(local, 1);
6404 6533
6405 /* Determine and validate the key index */ 6534 /* Determine and validate the key index */
6406 idx = encoding->flags & IW_ENCODE_INDEX; 6535 idx = encoding->flags & IW_ENCODE_INDEX;
6407 if (idx) { 6536 if (idx) {
6408 if (!valid_index(&cap_rid, idx - 1)) 6537 if (!valid_index(local, idx - 1))
6409 return -EINVAL; 6538 return -EINVAL;
6410 idx--; 6539 idx--;
6411 } else 6540 } else {
6412 idx = get_wep_key(local, 0xffff); 6541 idx = get_wep_tx_idx(local);
6542 if (idx < 0)
6543 idx = 0;
6544 }
6413 6545
6414 if (encoding->flags & IW_ENCODE_DISABLED) 6546 if (encoding->flags & IW_ENCODE_DISABLED)
6415 alg = IW_ENCODE_ALG_NONE; 6547 alg = IW_ENCODE_ALG_NONE;
@@ -6418,7 +6550,13 @@ static int airo_set_encodeext(struct net_device *dev,
6418 /* Only set transmit key index here, actual 6550 /* Only set transmit key index here, actual
6419 * key is set below if needed. 6551 * key is set below if needed.
6420 */ 6552 */
6421 set_wep_key(local, idx, NULL, 0, perm, 1); 6553 rc = set_wep_tx_idx(local, idx, perm, 1);
6554 if (rc < 0) {
6555 airo_print_err(local->dev->name, "failed to set "
6556 "WEP transmit index to %d: %d.",
6557 idx, rc);
6558 return rc;
6559 }
6422 set_key = ext->key_len > 0 ? 1 : 0; 6560 set_key = ext->key_len > 0 ? 1 : 0;
6423 } 6561 }
6424 6562
@@ -6444,7 +6582,12 @@ static int airo_set_encodeext(struct net_device *dev,
6444 return -EINVAL; 6582 return -EINVAL;
6445 } 6583 }
6446 /* Send the key to the card */ 6584 /* Send the key to the card */
6447 set_wep_key(local, idx, key.key, key.len, perm, 1); 6585 rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6586 if (rc < 0) {
6587 airo_print_err(local->dev->name, "failed to set WEP key"
6588 " at index %d: %d.", idx, rc);
6589 return rc;
6590 }
6448 } 6591 }
6449 6592
6450 /* Read the flags */ 6593 /* Read the flags */
@@ -6474,14 +6617,12 @@ static int airo_get_encodeext(struct net_device *dev,
6474 struct airo_info *local = dev->ml_priv; 6617 struct airo_info *local = dev->ml_priv;
6475 struct iw_point *encoding = &wrqu->encoding; 6618 struct iw_point *encoding = &wrqu->encoding;
6476 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 6619 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6477 CapabilityRid cap_rid; /* Card capability info */
6478 int idx, max_key_len; 6620 int idx, max_key_len;
6621 u8 buf[16];
6479 6622
6480 /* Is it supported ? */ 6623 if (!local->wep_capable)
6481 readCapabilityRid(local, &cap_rid, 1);
6482 if(!(cap_rid.softCap & cpu_to_le16(2))) {
6483 return -EOPNOTSUPP; 6624 return -EOPNOTSUPP;
6484 } 6625
6485 readConfigRid(local, 1); 6626 readConfigRid(local, 1);
6486 6627
6487 max_key_len = encoding->length - sizeof(*ext); 6628 max_key_len = encoding->length - sizeof(*ext);
@@ -6490,11 +6631,14 @@ static int airo_get_encodeext(struct net_device *dev,
6490 6631
6491 idx = encoding->flags & IW_ENCODE_INDEX; 6632 idx = encoding->flags & IW_ENCODE_INDEX;
6492 if (idx) { 6633 if (idx) {
6493 if (!valid_index(&cap_rid, idx - 1)) 6634 if (!valid_index(local, idx - 1))
6494 return -EINVAL; 6635 return -EINVAL;
6495 idx--; 6636 idx--;
6496 } else 6637 } else {
6497 idx = get_wep_key(local, 0xffff); 6638 idx = get_wep_tx_idx(local);
6639 if (idx < 0)
6640 idx = 0;
6641 }
6498 6642
6499 encoding->flags = idx + 1; 6643 encoding->flags = idx + 1;
6500 memset(ext, 0, sizeof(*ext)); 6644 memset(ext, 0, sizeof(*ext));
@@ -6517,10 +6661,8 @@ static int airo_get_encodeext(struct net_device *dev,
6517 memset(extra, 0, 16); 6661 memset(extra, 0, 16);
6518 6662
6519 /* Copy the key to the user buffer */ 6663 /* Copy the key to the user buffer */
6520 ext->key_len = get_wep_key(local, idx); 6664 ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
6521 if (ext->key_len > 16) { 6665 memcpy(extra, buf, ext->key_len);
6522 ext->key_len=0;
6523 }
6524 6666
6525 return 0; 6667 return 0;
6526} 6668}
@@ -6795,8 +6937,8 @@ static int airo_get_range(struct net_device *dev,
6795 k = 0; 6937 k = 0;
6796 for(i = 0; i < 14; i++) { 6938 for(i = 0; i < 14; i++) {
6797 range->freq[k].i = i + 1; /* List index */ 6939 range->freq[k].i = i + 1; /* List index */
6798 range->freq[k].m = frequency_list[i] * 100000; 6940 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 */ 6941 range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
6800 } 6942 }
6801 range->num_frequency = k; 6943 range->num_frequency = k;
6802 6944
@@ -7031,11 +7173,15 @@ static int airo_get_aplist(struct net_device *dev,
7031{ 7173{
7032 struct airo_info *local = dev->ml_priv; 7174 struct airo_info *local = dev->ml_priv;
7033 struct sockaddr *address = (struct sockaddr *) extra; 7175 struct sockaddr *address = (struct sockaddr *) extra;
7034 struct iw_quality qual[IW_MAX_AP]; 7176 struct iw_quality *qual;
7035 BSSListRid BSSList; 7177 BSSListRid BSSList;
7036 int i; 7178 int i;
7037 int loseSync = capable(CAP_NET_ADMIN) ? 1: -1; 7179 int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7038 7180
7181 qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
7182 if (!qual)
7183 return -ENOMEM;
7184
7039 for (i = 0; i < IW_MAX_AP; i++) { 7185 for (i = 0; i < IW_MAX_AP; i++) {
7040 u16 dBm; 7186 u16 dBm;
7041 if (readBSSListRid(local, loseSync, &BSSList)) 7187 if (readBSSListRid(local, loseSync, &BSSList))
@@ -7090,6 +7236,7 @@ static int airo_get_aplist(struct net_device *dev,
7090 } 7236 }
7091 dwrq->length = i; 7237 dwrq->length = i;
7092 7238
7239 kfree(qual);
7093 return 0; 7240 return 0;
7094} 7241}
7095 7242
@@ -7189,10 +7336,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
7189 /* Add frequency */ 7336 /* Add frequency */
7190 iwe.cmd = SIOCGIWFREQ; 7337 iwe.cmd = SIOCGIWFREQ;
7191 iwe.u.freq.m = le16_to_cpu(bss->dsChannel); 7338 iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7192 /* iwe.u.freq.m containt the channel (starting 1), our 7339 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; 7340 iwe.u.freq.e = 1;
7197 current_ev = iwe_stream_add_event(info, current_ev, end_buf, 7341 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7198 &iwe, IW_EV_FREQ_LEN); 7342 &iwe, IW_EV_FREQ_LEN);