~ubuntu-branches/ubuntu/lucid/linux-rt/lucid

« back to all changes in this revision

Viewing changes to drivers/net/wireless/airo.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2009-08-05 23:00:52 UTC
  • Revision ID: james.westby@ubuntu.com-20090805230052-7xedvqcyk9dnnxb2
Tags: 2.6.31-1.1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
496
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
499
/* This structure came from an email sent to me from an engineer at
503
500
   aironet for inclusion into this driver */
504
 
typedef struct {
 
501
typedef struct WepKeyRid WepKeyRid;
 
502
struct WepKeyRid {
505
503
        __le16 len;
506
504
        __le16 kindex;
507
505
        u8 mac[ETH_ALEN];
508
506
        __le16 klen;
509
507
        u8 key[16];
510
 
} WepKeyRid;
 
508
} __attribute__ ((packed));
511
509
 
512
510
/* These structures are from the Aironet's PC4500 Developers Manual */
513
 
typedef struct {
 
511
typedef struct Ssid Ssid;
 
512
struct Ssid {
514
513
        __le16 len;
515
514
        u8 ssid[32];
516
 
} Ssid;
 
515
} __attribute__ ((packed));
517
516
 
518
 
typedef struct {
 
517
typedef struct SsidRid SsidRid;
 
518
struct SsidRid {
519
519
        __le16 len;
520
520
        Ssid ssids[3];
521
 
} SsidRid;
 
521
} __attribute__ ((packed));
522
522
 
523
 
typedef struct {
 
523
typedef struct ModulationRid ModulationRid;
 
524
struct ModulationRid {
524
525
        __le16 len;
525
526
        __le16 modulation;
526
527
#define MOD_DEFAULT cpu_to_le16(0)
527
528
#define MOD_CCK cpu_to_le16(1)
528
529
#define MOD_MOK cpu_to_le16(2)
529
 
} ModulationRid;
 
530
} __attribute__ ((packed));
530
531
 
531
 
typedef struct {
 
532
typedef struct ConfigRid ConfigRid;
 
533
struct ConfigRid {
532
534
        __le16 len; /* sizeof(ConfigRid) */
533
535
        __le16 opmode; /* operating mode */
534
536
#define MODE_STA_IBSS cpu_to_le16(0)
649
651
#define MAGIC_STAY_IN_CAM (1<<10)
650
652
        u8 magicControl;
651
653
        __le16 autoWake;
652
 
} ConfigRid;
 
654
} __attribute__ ((packed));
653
655
 
654
 
typedef struct {
 
656
typedef struct StatusRid StatusRid;
 
657
struct StatusRid {
655
658
        __le16 len;
656
659
        u8 mac[ETH_ALEN];
657
660
        __le16 mode;
707
710
#define STAT_LEAPFAILED 91
708
711
#define STAT_LEAPTIMEDOUT 92
709
712
#define STAT_LEAPCOMPLETE 93
710
 
} StatusRid;
 
713
} __attribute__ ((packed));
711
714
 
712
 
typedef struct {
 
715
typedef struct StatsRid StatsRid;
 
716
struct StatsRid {
713
717
        __le16 len;
714
718
        __le16 spacer;
715
719
        __le32 vals[100];
716
 
} StatsRid;
717
 
 
718
 
 
719
 
typedef struct {
 
720
} __attribute__ ((packed));
 
721
 
 
722
typedef struct APListRid APListRid;
 
723
struct APListRid {
720
724
        __le16 len;
721
725
        u8 ap[4][ETH_ALEN];
722
 
} APListRid;
 
726
} __attribute__ ((packed));
723
727
 
724
 
typedef struct {
 
728
typedef struct CapabilityRid CapabilityRid;
 
729
struct CapabilityRid {
725
730
        __le16 len;
726
731
        char oui[3];
727
732
        char zero;
748
753
        __le16 bootBlockVer;
749
754
        __le16 requiredHard;
750
755
        __le16 extSoftCap;
751
 
} CapabilityRid;
752
 
 
 
756
} __attribute__ ((packed));
753
757
 
754
758
/* Only present on firmware >= 5.30.17 */
755
 
typedef struct {
 
759
typedef struct BSSListRidExtra BSSListRidExtra;
 
760
struct BSSListRidExtra {
756
761
  __le16 unknown[4];
757
762
  u8 fixed[12]; /* WLAN management frame */
758
763
  u8 iep[624];
759
 
} BSSListRidExtra;
 
764
} __attribute__ ((packed));
760
765
 
761
 
typedef struct {
 
766
typedef struct BSSListRid BSSListRid;
 
767
struct BSSListRid {
762
768
  __le16 len;
763
769
  __le16 index; /* First is 0 and 0xffff means end of list */
764
770
#define RADIO_FH 1 /* Frequency hopping radio type */
789
795
 
790
796
  /* Only present on firmware >= 5.30.17 */
791
797
  BSSListRidExtra extra;
792
 
} BSSListRid;
 
798
} __attribute__ ((packed));
793
799
 
794
800
typedef struct {
795
801
  BSSListRid bss;
796
802
  struct list_head list;
797
803
} BSSListElement;
798
804
 
799
 
typedef struct {
 
805
typedef struct tdsRssiEntry tdsRssiEntry;
 
806
struct tdsRssiEntry {
800
807
  u8 rssipct;
801
808
  u8 rssidBm;
802
 
} tdsRssiEntry;
 
809
} __attribute__ ((packed));
803
810
 
804
 
typedef struct {
 
811
typedef struct tdsRssiRid tdsRssiRid;
 
812
struct tdsRssiRid {
805
813
  u16 len;
806
814
  tdsRssiEntry x[256];
807
 
} tdsRssiRid;
 
815
} __attribute__ ((packed));
808
816
 
809
 
typedef struct {
810
 
        u16 len;
811
 
        u16 state;
812
 
        u16 multicastValid;
 
817
typedef struct MICRid MICRid;
 
818
struct MICRid {
 
819
        __le16 len;
 
820
        __le16 state;
 
821
        __le16 multicastValid;
813
822
        u8  multicast[16];
814
 
        u16 unicastValid;
 
823
        __le16 unicastValid;
815
824
        u8  unicast[16];
816
 
} MICRid;
 
825
} __attribute__ ((packed));
817
826
 
818
 
typedef struct {
 
827
typedef struct MICBuffer MICBuffer;
 
828
struct MICBuffer {
819
829
        __be16 typelen;
820
830
 
821
831
        union {
830
840
        } u;
831
841
        __be32 mic;
832
842
        __be32 seq;
833
 
} MICBuffer;
 
843
} __attribute__ ((packed));
834
844
 
835
845
typedef struct {
836
846
        u8 da[ETH_ALEN];
837
847
        u8 sa[ETH_ALEN];
838
848
} etherHead;
839
849
 
840
 
#pragma pack()
841
 
 
842
850
#define TXCTL_TXOK (1<<1) /* report if tx is ok */
843
851
#define TXCTL_TXEX (1<<2) /* report if tx fails */
844
852
#define TXCTL_802_3 (0<<3) /* 802.3 packet */
981
989
        dma_addr_t host_addr;
982
990
} TxFid;
983
991
 
 
992
struct rx_hdr {
 
993
        __le16 status, len;
 
994
        u8 rssi[2];
 
995
        u8 rate;
 
996
        u8 freq;
 
997
        __le16 tmp[4];
 
998
} __attribute__ ((packed));
 
999
 
984
1000
typedef struct {
985
1001
        unsigned int  ctl: 15;
986
1002
        unsigned int  rdy: 1;
1070
1086
        }
1071
1087
};
1072
1088
 
1073
 
// Frequency list (map channels to frequencies)
1074
 
static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
1075
 
                                2447, 2452, 2457, 2462, 2467, 2472, 2484 };
1076
 
 
1077
1089
// A few details needed for WEP (Wireless Equivalent Privacy)
1078
1090
#define MAX_KEY_SIZE 13                 // 128 (?) bits
1079
1091
#define MIN_KEY_SIZE  5                 // 40 bits RC4 - WEP
1082
1094
        u8      key[16];        /* 40-bit and 104-bit keys */
1083
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
1097
/* List of Wireless Handlers (new API) */
1092
1098
static const struct iw_handler_def      airo_handler_def;
1093
1099
 
1155
1161
           use the high bit to mark whether it is in use. */
1156
1162
#define MAX_FIDS 6
1157
1163
#define MPI_MAX_FIDS 1
1158
 
        int                           fids[MAX_FIDS];
 
1164
        u32                           fids[MAX_FIDS];
1159
1165
        ConfigRid config;
1160
1166
        char keyindex; // Used with auto wep
1161
1167
        char defindex; // Used with auto wep
1229
1235
#define PCI_SHARED_LEN          2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
1230
1236
        char                    proc_name[IFNAMSIZ];
1231
1237
 
 
1238
        int                     wep_capable;
 
1239
        int                     max_wep_idx;
 
1240
 
1232
1241
        /* WPA-related stuff */
1233
1242
        unsigned int bssListFirst;
1234
1243
        unsigned int bssListNext;
1287
1296
static void emmh32_final(emmh32_context *context, u8 digest[4]);
1288
1297
static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
1289
1298
 
 
1299
static 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
1322
/* micinit - Initialize mic seed */
1291
1323
 
1292
1324
static void micinit(struct airo_info *ai)
1297
1329
        PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
1298
1330
        up(&ai->sem);
1299
1331
 
1300
 
        ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0;
1301
 
 
1302
 
        if (ai->micstats.enabled) {
1303
 
                /* Key must be valid and different */
1304
 
                if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid ||
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
 
       */
 
1332
        ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
 
1333
        if (!ai->micstats.enabled) {
 
1334
                /* So next time we have a valid key and mic is enabled, we will
 
1335
                 * update the sequence number if the key is the same as before.
 
1336
                 */
1341
1337
                ai->mod[0].uCtx.valid = 0;
1342
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
 
1926
1935
                netif_stop_queue (dev);
1927
1936
                if (npacks > MAXTXQ) {
1928
1937
                        dev->stats.tx_fifo_errors++;
1929
 
                        return 1;
 
1938
                        return NETDEV_TX_BUSY;
1930
1939
                }
1931
1940
                skb_queue_tail (&ai->txq, skb);
1932
1941
                return 0;
2130
2139
 
2131
2140
                if (i == MAX_FIDS / 2) {
2132
2141
                        dev->stats.tx_fifo_errors++;
2133
 
                        return 1;
 
2142
                        return NETDEV_TX_BUSY;
2134
2143
                }
2135
2144
        }
2136
2145
        /* check min length*/
2184
2193
        if (test_bit(FLAG_MPI, &priv->flags)) {
2185
2194
                /* Not implemented yet for MPI350 */
2186
2195
                netif_stop_queue(dev);
2187
 
                return -ENETDOWN;
 
2196
                dev_kfree_skb_any(skb);
 
2197
                return NETDEV_TX_OK;
2188
2198
        }
2189
2199
 
2190
2200
        if ( skb == NULL ) {
2201
2211
 
2202
2212
                if (i == MAX_FIDS) {
2203
2213
                        dev->stats.tx_fifo_errors++;
2204
 
                        return 1;
 
2214
                        return NETDEV_TX_BUSY;
2205
2215
                }
2206
2216
        }
2207
2217
        /* check min length*/
2637
2647
        .parse = wll_header_parse,
2638
2648
};
2639
2649
 
 
2650
static const struct net_device_ops airo11_netdev_ops = {
 
2651
        .ndo_open               = airo_open,
 
2652
        .ndo_stop               = airo_close,
 
2653
        .ndo_start_xmit         = airo_start_xmit11,
 
2654
        .ndo_get_stats          = airo_get_stats,
 
2655
        .ndo_set_mac_address    = airo_set_mac_address,
 
2656
        .ndo_do_ioctl           = airo_ioctl,
 
2657
        .ndo_change_mtu         = airo_change_mtu,
 
2658
};
 
2659
 
2640
2660
static void wifi_setup(struct net_device *dev)
2641
2661
{
 
2662
        dev->netdev_ops = &airo11_netdev_ops;
2642
2663
        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
2664
        dev->wireless_handlers = &airo_handler_def;
2648
 
        dev->change_mtu = &airo_change_mtu;
2649
 
        dev->open = &airo_open;
2650
 
        dev->stop = &airo_close;
2651
2665
 
2652
2666
        dev->type               = ARPHRD_IEEE80211;
2653
2667
        dev->hard_header_len    = ETH_HLEN;
2730
2744
                              &ai->network_free_list);
2731
2745
}
2732
2746
 
2733
 
static 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
 
}
 
2747
static const struct net_device_ops airo_netdev_ops = {
 
2748
        .ndo_open               = airo_open,
 
2749
        .ndo_stop               = airo_close,
 
2750
        .ndo_start_xmit         = airo_start_xmit,
 
2751
        .ndo_get_stats          = airo_get_stats,
 
2752
        .ndo_set_multicast_list = airo_set_multicast_list,
 
2753
        .ndo_set_mac_address    = airo_set_mac_address,
 
2754
        .ndo_do_ioctl           = airo_ioctl,
 
2755
        .ndo_change_mtu         = airo_change_mtu,
 
2756
        .ndo_validate_addr      = eth_validate_addr,
 
2757
};
 
2758
 
 
2759
static const struct net_device_ops mpi_netdev_ops = {
 
2760
        .ndo_open               = airo_open,
 
2761
        .ndo_stop               = airo_close,
 
2762
        .ndo_start_xmit         = mpi_start_xmit,
 
2763
        .ndo_get_stats          = airo_get_stats,
 
2764
        .ndo_set_multicast_list = airo_set_multicast_list,
 
2765
        .ndo_set_mac_address    = airo_set_mac_address,
 
2766
        .ndo_do_ioctl           = airo_ioctl,
 
2767
        .ndo_change_mtu         = airo_change_mtu,
 
2768
        .ndo_validate_addr      = eth_validate_addr,
 
2769
};
 
2770
 
2754
2771
 
2755
2772
static struct net_device *_init_airo_card( unsigned short irq, int port,
2756
2773
                                           int is_pcmcia, struct pci_dev *pci,
2759
2776
        struct net_device *dev;
2760
2777
        struct airo_info *ai;
2761
2778
        int i, rc;
 
2779
        CapabilityRid cap_rid;
2762
2780
 
2763
2781
        /* Create the network device object. */
2764
2782
        dev = alloc_netdev(sizeof(*ai), "", ether_setup);
2788
2806
                goto err_out_free;
2789
2807
        airo_networks_initialize (ai);
2790
2808
 
 
2809
        skb_queue_head_init (&ai->txq);
 
2810
 
2791
2811
        /* The Airo-specific entries in the device structure. */
2792
 
        if (test_bit(FLAG_MPI,&ai->flags)) {
2793
 
                skb_queue_head_init (&ai->txq);
2794
 
                dev->hard_start_xmit = &mpi_start_xmit;
2795
 
        } else
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;
 
2812
        if (test_bit(FLAG_MPI,&ai->flags))
 
2813
                dev->netdev_ops = &mpi_netdev_ops;
 
2814
        else
 
2815
                dev->netdev_ops = &airo_netdev_ops;
2801
2816
        dev->wireless_handlers = &airo_handler_def;
2802
2817
        ai->wireless_data.spy_data = &ai->spy_data;
2803
2818
        dev->wireless_data = &ai->wireless_data;
2804
 
        dev->change_mtu = &airo_change_mtu;
2805
 
        dev->open = &airo_open;
2806
 
        dev->stop = &airo_close;
2807
2819
        dev->irq = irq;
2808
2820
        dev->base_addr = port;
2809
2821
 
2828
2840
        }
2829
2841
 
2830
2842
        if (probe) {
2831
 
                if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
 
2843
                if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
2832
2844
                        airo_print_err(dev->name, "MAC could not be enabled" );
2833
2845
                        rc = -EIO;
2834
2846
                        goto err_out_map;
2838
2850
                set_bit(FLAG_FLASHING, &ai->flags);
2839
2851
        }
2840
2852
 
 
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
        rc = readCapabilityRid(ai, &cap_rid, 1);
 
2864
        if (rc != SUCCESS) {
 
2865
                rc = -EIO;
 
2866
                goto err_out_wifi;
 
2867
        }
 
2868
        /* WEP capability discovery */
 
2869
        ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
 
2870
        ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
 
2871
 
 
2872
        airo_print_info(dev->name, "Firmware version %x.%x.%02x",
 
2873
                        ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
 
2874
                        (le16_to_cpu(cap_rid.softVer) & 0xFF),
 
2875
                        le16_to_cpu(cap_rid.softSubVer));
 
2876
 
2841
2877
        /* Test for WPA support */
2842
 
        if (airo_test_wpa_capable(ai)) {
 
2878
        /* Only firmware versions 5.30.17 or better can do WPA */
 
2879
        if (le16_to_cpu(cap_rid.softVer) > 0x530
 
2880
         || (le16_to_cpu(cap_rid.softVer) == 0x530
 
2881
              && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
 
2882
                airo_print_info(ai->dev->name, "WPA supported.");
 
2883
 
2843
2884
                set_bit(FLAG_WPA_CAPABLE, &ai->flags);
2844
2885
                ai->bssListFirst = RID_WPA_BSSLISTFIRST;
2845
2886
                ai->bssListNext = RID_WPA_BSSLISTNEXT;
2846
2887
                ai->bssListRidLen = sizeof(BSSListRid);
2847
2888
        } else {
 
2889
                airo_print_info(ai->dev->name, "WPA unsupported with firmware "
 
2890
                        "versions older than 5.30.17.");
 
2891
 
2848
2892
                ai->bssListFirst = RID_BSSLISTFIRST;
2849
2893
                ai->bssListNext = RID_BSSLISTNEXT;
2850
2894
                ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
2851
2895
        }
2852
2896
 
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
2897
        set_bit(FLAG_REGISTERED,&ai->flags);
2864
2898
        airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2865
2899
 
3127
3161
        return 24;
3128
3162
}
3129
3163
 
 
3164
static void airo_handle_cisco_mic(struct airo_info *ai)
 
3165
{
 
3166
        if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
 
3167
                set_bit(JOB_MIC, &ai->jobs);
 
3168
                wake_up_interruptible(&ai->thr_wait);
 
3169
        }
 
3170
}
 
3171
 
 
3172
/* Airo Status codes */
 
3173
#define STAT_NOBEACON   0x8000 /* Loss of sync - missed beacons */
 
3174
#define STAT_MAXRETRIES 0x8001 /* Loss of sync - max retries */
 
3175
#define STAT_MAXARL     0x8002 /* Loss of sync - average retry level exceeded*/
 
3176
#define STAT_FORCELOSS  0x8003 /* Loss of sync - host request */
 
3177
#define STAT_TSFSYNC    0x8004 /* Loss of sync - TSF synchronization */
 
3178
#define STAT_DEAUTH     0x8100 /* low byte is 802.11 reason code */
 
3179
#define STAT_DISASSOC   0x8200 /* low byte is 802.11 reason code */
 
3180
#define STAT_ASSOC_FAIL 0x8400 /* low byte is 802.11 reason code */
 
3181
#define STAT_AUTH_FAIL  0x0300 /* low byte is 802.11 reason code */
 
3182
#define STAT_ASSOC      0x0400 /* Associated */
 
3183
#define STAT_REASSOC    0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
 
3184
 
 
3185
static void airo_print_status(const char *devname, u16 status)
 
3186
{
 
3187
        u8 reason = status & 0xFF;
 
3188
 
 
3189
        switch (status) {
 
3190
        case STAT_NOBEACON:
 
3191
                airo_print_dbg(devname, "link lost (missed beacons)");
 
3192
                break;
 
3193
        case STAT_MAXRETRIES:
 
3194
        case STAT_MAXARL:
 
3195
                airo_print_dbg(devname, "link lost (max retries)");
 
3196
                break;
 
3197
        case STAT_FORCELOSS:
 
3198
                airo_print_dbg(devname, "link lost (local choice)");
 
3199
                break;
 
3200
        case STAT_TSFSYNC:
 
3201
                airo_print_dbg(devname, "link lost (TSF sync lost)");
 
3202
                break;
 
3203
        case STAT_DEAUTH:
 
3204
                airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
 
3205
                break;
 
3206
        case STAT_DISASSOC:
 
3207
                airo_print_dbg(devname, "disassociated (reason: %d)", reason);
 
3208
                break;
 
3209
        case STAT_ASSOC_FAIL:
 
3210
                airo_print_dbg(devname, "association failed (reason: %d)",
 
3211
                               reason);
 
3212
                break;
 
3213
        case STAT_AUTH_FAIL:
 
3214
                airo_print_dbg(devname, "authentication failed (reason: %d)",
 
3215
                               reason);
 
3216
                break;
 
3217
        default:
 
3218
                break;
 
3219
        }
 
3220
}
 
3221
 
 
3222
static void airo_handle_link(struct airo_info *ai)
 
3223
{
 
3224
        union iwreq_data wrqu;
 
3225
        int scan_forceloss = 0;
 
3226
        u16 status;
 
3227
 
 
3228
        /* Get new status and acknowledge the link change */
 
3229
        status = le16_to_cpu(IN4500(ai, LINKSTAT));
 
3230
        OUT4500(ai, EVACK, EV_LINK);
 
3231
 
 
3232
        if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
 
3233
                scan_forceloss = 1;
 
3234
 
 
3235
        airo_print_status(ai->dev->name, status);
 
3236
 
 
3237
        if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
 
3238
                if (auto_wep)
 
3239
                        ai->expires = 0;
 
3240
                if (ai->list_bss_task)
 
3241
                        wake_up_process(ai->list_bss_task);
 
3242
                set_bit(FLAG_UPDATE_UNI, &ai->flags);
 
3243
                set_bit(FLAG_UPDATE_MULTI, &ai->flags);
 
3244
 
 
3245
                if (down_trylock(&ai->sem) != 0) {
 
3246
                        set_bit(JOB_EVENT, &ai->jobs);
 
3247
                        wake_up_interruptible(&ai->thr_wait);
 
3248
                } else
 
3249
                        airo_send_event(ai->dev);
 
3250
        } else if (!scan_forceloss) {
 
3251
                if (auto_wep && !ai->expires) {
 
3252
                        ai->expires = RUN_AT(3*HZ);
 
3253
                        wake_up_interruptible(&ai->thr_wait);
 
3254
                }
 
3255
 
 
3256
                /* Send event to user space */
 
3257
                memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
 
3258
                wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 
3259
                wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
 
3260
        }
 
3261
}
 
3262
 
 
3263
static void airo_handle_rx(struct airo_info *ai)
 
3264
{
 
3265
        struct sk_buff *skb = NULL;
 
3266
        __le16 fc, v, *buffer, tmpbuf[4];
 
3267
        u16 len, hdrlen = 0, gap, fid;
 
3268
        struct rx_hdr hdr;
 
3269
        int success = 0;
 
3270
 
 
3271
        if (test_bit(FLAG_MPI, &ai->flags)) {
 
3272
                if (test_bit(FLAG_802_11, &ai->flags))
 
3273
                        mpi_receive_802_11(ai);
 
3274
                else
 
3275
                        mpi_receive_802_3(ai);
 
3276
                OUT4500(ai, EVACK, EV_RX);
 
3277
                return;
 
3278
        }
 
3279
 
 
3280
        fid = IN4500(ai, RXFID);
 
3281
 
 
3282
        /* Get the packet length */
 
3283
        if (test_bit(FLAG_802_11, &ai->flags)) {
 
3284
                bap_setup (ai, fid, 4, BAP0);
 
3285
                bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
 
3286
                /* Bad CRC. Ignore packet */
 
3287
                if (le16_to_cpu(hdr.status) & 2)
 
3288
                        hdr.len = 0;
 
3289
                if (ai->wifidev == NULL)
 
3290
                        hdr.len = 0;
 
3291
        } else {
 
3292
                bap_setup(ai, fid, 0x36, BAP0);
 
3293
                bap_read(ai, &hdr.len, 2, BAP0);
 
3294
        }
 
3295
        len = le16_to_cpu(hdr.len);
 
3296
 
 
3297
        if (len > AIRO_DEF_MTU) {
 
3298
                airo_print_err(ai->dev->name, "Bad size %d", len);
 
3299
                goto done;
 
3300
        }
 
3301
        if (len == 0)
 
3302
                goto done;
 
3303
 
 
3304
        if (test_bit(FLAG_802_11, &ai->flags)) {
 
3305
                bap_read(ai, &fc, sizeof (fc), BAP0);
 
3306
                hdrlen = header_len(fc);
 
3307
        } else
 
3308
                hdrlen = ETH_ALEN * 2;
 
3309
 
 
3310
        skb = dev_alloc_skb(len + hdrlen + 2 + 2);
 
3311
        if (!skb) {
 
3312
                ai->dev->stats.rx_dropped++;
 
3313
                goto done;
 
3314
        }
 
3315
 
 
3316
        skb_reserve(skb, 2); /* This way the IP header is aligned */
 
3317
        buffer = (__le16 *) skb_put(skb, len + hdrlen);
 
3318
        if (test_bit(FLAG_802_11, &ai->flags)) {
 
3319
                buffer[0] = fc;
 
3320
                bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
 
3321
                if (hdrlen == 24)
 
3322
                        bap_read(ai, tmpbuf, 6, BAP0);
 
3323
 
 
3324
                bap_read(ai, &v, sizeof(v), BAP0);
 
3325
                gap = le16_to_cpu(v);
 
3326
                if (gap) {
 
3327
                        if (gap <= 8) {
 
3328
                                bap_read(ai, tmpbuf, gap, BAP0);
 
3329
                        } else {
 
3330
                                airo_print_err(ai->dev->name, "gaplen too "
 
3331
                                        "big. Problems will follow...");
 
3332
                        }
 
3333
                }
 
3334
                bap_read(ai, buffer + hdrlen/2, len, BAP0);
 
3335
        } else {
 
3336
                MICBuffer micbuf;
 
3337
 
 
3338
                bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
 
3339
                if (ai->micstats.enabled) {
 
3340
                        bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
 
3341
                        if (ntohs(micbuf.typelen) > 0x05DC)
 
3342
                                bap_setup(ai, fid, 0x44, BAP0);
 
3343
                        else {
 
3344
                                if (len <= sizeof (micbuf)) {
 
3345
                                        dev_kfree_skb_irq(skb);
 
3346
                                        goto done;
 
3347
                                }
 
3348
 
 
3349
                                len -= sizeof(micbuf);
 
3350
                                skb_trim(skb, len + hdrlen);
 
3351
                        }
 
3352
                }
 
3353
 
 
3354
                bap_read(ai, buffer + ETH_ALEN, len, BAP0);
 
3355
                if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
 
3356
                        dev_kfree_skb_irq (skb);
 
3357
                else
 
3358
                        success = 1;
 
3359
        }
 
3360
 
 
3361
#ifdef WIRELESS_SPY
 
3362
        if (success && (ai->spy_data.spy_number > 0)) {
 
3363
                char *sa;
 
3364
                struct iw_quality wstats;
 
3365
 
 
3366
                /* Prepare spy data : addr + qual */
 
3367
                if (!test_bit(FLAG_802_11, &ai->flags)) {
 
3368
                        sa = (char *) buffer + 6;
 
3369
                        bap_setup(ai, fid, 8, BAP0);
 
3370
                        bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
 
3371
                } else
 
3372
                        sa = (char *) buffer + 10;
 
3373
                wstats.qual = hdr.rssi[0];
 
3374
                if (ai->rssi)
 
3375
                        wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
 
3376
                else
 
3377
                        wstats.level = (hdr.rssi[1] + 321) / 2;
 
3378
                wstats.noise = ai->wstats.qual.noise;
 
3379
                wstats.updated =  IW_QUAL_LEVEL_UPDATED
 
3380
                                | IW_QUAL_QUAL_UPDATED
 
3381
                                | IW_QUAL_DBM;
 
3382
                /* Update spy records */
 
3383
                wireless_spy_update(ai->dev, sa, &wstats);
 
3384
        }
 
3385
#endif /* WIRELESS_SPY */
 
3386
 
 
3387
done:
 
3388
        OUT4500(ai, EVACK, EV_RX);
 
3389
 
 
3390
        if (success) {
 
3391
                if (test_bit(FLAG_802_11, &ai->flags)) {
 
3392
                        skb_reset_mac_header(skb);
 
3393
                        skb->pkt_type = PACKET_OTHERHOST;
 
3394
                        skb->dev = ai->wifidev;
 
3395
                        skb->protocol = htons(ETH_P_802_2);
 
3396
                } else
 
3397
                        skb->protocol = eth_type_trans(skb, ai->dev);
 
3398
                skb->ip_summed = CHECKSUM_NONE;
 
3399
 
 
3400
                netif_rx(skb);
 
3401
        }
 
3402
}
 
3403
 
 
3404
static void airo_handle_tx(struct airo_info *ai, u16 status)
 
3405
{
 
3406
        int i, len = 0, index = -1;
 
3407
        u16 fid;
 
3408
 
 
3409
        if (test_bit(FLAG_MPI, &ai->flags)) {
 
3410
                unsigned long flags;
 
3411
 
 
3412
                if (status & EV_TXEXC)
 
3413
                        get_tx_error(ai, -1);
 
3414
 
 
3415
                spin_lock_irqsave(&ai->aux_lock, flags);
 
3416
                if (!skb_queue_empty(&ai->txq)) {
 
3417
                        spin_unlock_irqrestore(&ai->aux_lock,flags);
 
3418
                        mpi_send_packet(ai->dev);
 
3419
                } else {
 
3420
                        clear_bit(FLAG_PENDING_XMIT, &ai->flags);
 
3421
                        spin_unlock_irqrestore(&ai->aux_lock,flags);
 
3422
                        netif_wake_queue(ai->dev);
 
3423
                }
 
3424
                OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
 
3425
                return;
 
3426
        }
 
3427
 
 
3428
        fid = IN4500(ai, TXCOMPLFID);
 
3429
 
 
3430
        for(i = 0; i < MAX_FIDS; i++) {
 
3431
                if ((ai->fids[i] & 0xffff) == fid) {
 
3432
                        len = ai->fids[i] >> 16;
 
3433
                        index = i;
 
3434
                }
 
3435
        }
 
3436
 
 
3437
        if (index != -1) {
 
3438
                if (status & EV_TXEXC)
 
3439
                        get_tx_error(ai, index);
 
3440
 
 
3441
                OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
 
3442
 
 
3443
                /* Set up to be used again */
 
3444
                ai->fids[index] &= 0xffff;
 
3445
                if (index < MAX_FIDS / 2) {
 
3446
                        if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
 
3447
                                netif_wake_queue(ai->dev);
 
3448
                } else {
 
3449
                        if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
 
3450
                                netif_wake_queue(ai->wifidev);
 
3451
                }
 
3452
        } else {
 
3453
                OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
 
3454
                airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
 
3455
        }
 
3456
}
 
3457
 
3130
3458
static irqreturn_t airo_interrupt(int irq, void *dev_id)
3131
3459
{
3132
3460
        struct net_device *dev = dev_id;
3133
 
        u16 status;
3134
 
        u16 fid;
3135
 
        struct airo_info *apriv = dev->ml_priv;
3136
 
        u16 savedInterrupts = 0;
 
3461
        u16 status, savedInterrupts = 0;
 
3462
        struct airo_info *ai = dev->ml_priv;
3137
3463
        int handled = 0;
3138
3464
 
3139
3465
        if (!netif_device_present(dev))
3140
3466
                return IRQ_NONE;
3141
3467
 
3142
3468
        for (;;) {
3143
 
                status = IN4500( apriv, EVSTAT );
3144
 
                if ( !(status & STATUS_INTS) || status == 0xffff ) break;
 
3469
                status = IN4500(ai, EVSTAT);
 
3470
                if (!(status & STATUS_INTS) || (status == 0xffff))
 
3471
                        break;
3145
3472
 
3146
3473
                handled = 1;
3147
3474
 
3148
 
                if ( status & EV_AWAKE ) {
3149
 
                        OUT4500( apriv, EVACK, EV_AWAKE );
3150
 
                        OUT4500( apriv, EVACK, EV_AWAKE );
 
3475
                if (status & EV_AWAKE) {
 
3476
                        OUT4500(ai, EVACK, EV_AWAKE);
 
3477
                        OUT4500(ai, EVACK, EV_AWAKE);
3151
3478
                }
3152
3479
 
3153
3480
                if (!savedInterrupts) {
3154
 
                        savedInterrupts = IN4500( apriv, EVINTEN );
3155
 
                        OUT4500( apriv, EVINTEN, 0 );
3156
 
                }
3157
 
 
3158
 
                if ( status & EV_MIC ) {
3159
 
                        OUT4500( apriv, EVACK, EV_MIC );
3160
 
                        if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
3161
 
                                set_bit(JOB_MIC, &apriv->jobs);
3162
 
                                wake_up_interruptible(&apriv->thr_wait);
3163
 
                        }
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
 
 
3225
 
                                /* Send event to user space */
3226
 
                                memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3227
 
                                wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3228
 
                                wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
3229
 
                        }
 
3481
                        savedInterrupts = IN4500(ai, EVINTEN);
 
3482
                        OUT4500(ai, EVINTEN, 0);
 
3483
                }
 
3484
 
 
3485
                if (status & EV_MIC) {
 
3486
                        OUT4500(ai, EVACK, EV_MIC);
 
3487
                        airo_handle_cisco_mic(ai);
 
3488
                }
 
3489
 
 
3490
                if (status & EV_LINK) {
 
3491
                        /* Link status changed */
 
3492
                        airo_handle_link(ai);
3230
3493
                }
3231
3494
 
3232
3495
                /* Check to see if there is something to receive */
3233
 
                if ( status & EV_RX  ) {
3234
 
                        struct sk_buff *skb = NULL;
3235
 
                        __le16 fc, v;
3236
 
                        u16 len, hdrlen = 0;
3237
 
#pragma pack(1)
3238
 
                        struct {
3239
 
                                __le16 status, len;
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
 
 
3259
 
                        fid = IN4500( apriv, 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
 
 
3276
 
                        if (len > AIRO_DEF_MTU) {
3277
 
                                airo_print_err(apriv->dev->name, "Bad size %d", len);
3278
 
                                goto badrx;
3279
 
                        }
3280
 
                        if (len == 0)
3281
 
                                goto badrx;
3282
 
 
3283
 
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
3284
 
                                bap_read (apriv, &fc, sizeof(fc), BAP0);
3285
 
                                hdrlen = header_len(fc);
3286
 
                        } else
3287
 
                                hdrlen = ETH_ALEN * 2;
3288
 
 
3289
 
                        skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
3290
 
                        if ( !skb ) {
3291
 
                                dev->stats.rx_dropped++;
3292
 
                                goto badrx;
3293
 
                        }
3294
 
                        skb_reserve(skb, 2); /* This way the IP header is aligned */
3295
 
                        buffer = (__le16*)skb_put (skb, len + hdrlen);
3296
 
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
3297
 
                                buffer[0] = fc;
3298
 
                                bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
3299
 
                                if (hdrlen == 24)
3300
 
                                        bap_read (apriv, tmpbuf, 6, BAP0);
3301
 
 
3302
 
                                bap_read (apriv, &v, sizeof(v), BAP0);
3303
 
                                gap = le16_to_cpu(v);
3304
 
                                if (gap) {
3305
 
                                        if (gap <= 8) {
3306
 
                                                bap_read (apriv, tmpbuf, gap, BAP0);
3307
 
                                        } else {
3308
 
                                                airo_print_err(apriv->dev->name, "gaplen too "
3309
 
                                                        "big. Problems will follow...");
3310
 
                                        }
3311
 
                                }
3312
 
                                bap_read (apriv, buffer + hdrlen/2, len, BAP0);
3313
 
                        } else {
3314
 
                                MICBuffer micbuf;
3315
 
                                bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
3316
 
                                if (apriv->micstats.enabled) {
3317
 
                                        bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0);
3318
 
                                        if (ntohs(micbuf.typelen) > 0x05DC)
3319
 
                                                bap_setup (apriv, fid, 0x44, BAP0);
3320
 
                                        else {
3321
 
                                                if (len <= sizeof(micbuf))
3322
 
                                                        goto badmic;
3323
 
 
3324
 
                                                len -= sizeof(micbuf);
3325
 
                                                skb_trim (skb, len + hdrlen);
3326
 
                                        }
3327
 
                                }
3328
 
                                bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
3329
 
                                if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
3330
 
badmic:
3331
 
                                        dev_kfree_skb_irq (skb);
3332
 
badrx:
3333
 
                                        OUT4500( apriv, EVACK, EV_RX);
3334
 
                                        goto exitrx;
3335
 
                                }
3336
 
                        }
3337
 
#ifdef WIRELESS_SPY
3338
 
                        if (apriv->spy_data.spy_number > 0) {
3339
 
                                char *sa;
3340
 
                                struct iw_quality wstats;
3341
 
                                /* Prepare spy data : addr + qual */
3342
 
                                if (!test_bit(FLAG_802_11, &apriv->flags)) {
3343
 
                                        sa = (char*)buffer + 6;
3344
 
                                        bap_setup (apriv, fid, 8, BAP0);
3345
 
                                        bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0);
3346
 
                                } else
3347
 
                                        sa = (char*)buffer + 10;
3348
 
                                wstats.qual = hdr.rssi[0];
3349
 
                                if (apriv->rssi)
3350
 
                                        wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
3351
 
                                else
3352
 
                                        wstats.level = (hdr.rssi[1] + 321) / 2;
3353
 
                                wstats.noise = apriv->wstats.qual.noise;
3354
 
                                wstats.updated = IW_QUAL_LEVEL_UPDATED
3355
 
                                        | IW_QUAL_QUAL_UPDATED
3356
 
                                        | IW_QUAL_DBM;
3357
 
                                /* Update spy records */
3358
 
                                wireless_spy_update(dev, sa, &wstats);
3359
 
                        }
3360
 
#endif /* WIRELESS_SPY */
3361
 
                        OUT4500( apriv, EVACK, EV_RX);
3362
 
 
3363
 
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
3364
 
                                skb_reset_mac_header(skb);
3365
 
                                skb->pkt_type = PACKET_OTHERHOST;
3366
 
                                skb->dev = apriv->wifidev;
3367
 
                                skb->protocol = htons(ETH_P_802_2);
3368
 
                        } else
3369
 
                                skb->protocol = eth_type_trans(skb,dev);
3370
 
                        skb->ip_summed = CHECKSUM_NONE;
3371
 
 
3372
 
                        netif_rx( skb );
3373
 
                }
3374
 
exitrx:
 
3496
                if (status & EV_RX)
 
3497
                        airo_handle_rx(ai);
3375
3498
 
3376
3499
                /* Check to see if a packet has been transmitted */
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
 
 
3401
 
                        fid = IN4500(apriv, TXCOMPLFID);
3402
 
 
3403
 
                        for( i = 0; i < MAX_FIDS; i++ ) {
3404
 
                                if ( ( apriv->fids[i] & 0xffff ) == fid ) {
3405
 
                                        len = apriv->fids[i] >> 16;
3406
 
                                        index = i;
3407
 
                                }
3408
 
                        }
3409
 
                        if (index != -1) {
3410
 
                                if (status & EV_TXEXC)
3411
 
                                        get_tx_error(apriv, index);
3412
 
                                OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
3413
 
                                /* Set up to be used again */
3414
 
                                apriv->fids[index] &= 0xffff;
3415
 
                                if (index < MAX_FIDS / 2) {
3416
 
                                        if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
3417
 
                                                netif_wake_queue(dev);
3418
 
                                } else {
3419
 
                                        if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
3420
 
                                                netif_wake_queue(apriv->wifidev);
3421
 
                                }
3422
 
                        } else {
3423
 
                                OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3424
 
                                airo_print_err(apriv->dev->name, "Unallocated FID was "
3425
 
                                        "used to xmit" );
3426
 
                        }
3427
 
                }
3428
 
exittx:
3429
 
                if ( status & ~STATUS_INTS & ~IGNORE_INTS )
3430
 
                        airo_print_warn(apriv->dev->name, "Got weird status %x",
 
3500
                if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
 
3501
                        airo_handle_tx(ai, status);
 
3502
 
 
3503
                if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
 
3504
                        airo_print_warn(ai->dev->name, "Got weird status %x",
3431
3505
                                status & ~STATUS_INTS & ~IGNORE_INTS );
 
3506
                }
3432
3507
        }
3433
3508
 
3434
3509
        if (savedInterrupts)
3435
 
                OUT4500( apriv, EVINTEN, savedInterrupts );
 
3510
                OUT4500(ai, EVINTEN, savedInterrupts);
3436
3511
 
3437
 
        /* done.. */
3438
3512
        return IRQ_RETVAL(handled);
3439
3513
}
3440
3514
 
3613
3687
        struct sk_buff *skb = NULL;
3614
3688
        u16 len, hdrlen = 0;
3615
3689
        __le16 fc;
3616
 
#pragma pack(1)
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()
 
3690
        struct rx_hdr hdr;
3625
3691
        u16 gap;
3626
3692
        u16 *buffer;
3627
 
        char *ptr = ai->rxfids[0].virtual_host_addr+4;
 
3693
        char *ptr = ai->rxfids[0].virtual_host_addr + 4;
3628
3694
 
3629
3695
        memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3630
3696
        memcpy ((char *)&hdr, ptr, sizeof(hdr));
3691
3757
        skb->protocol = htons(ETH_P_802_2);
3692
3758
        skb->ip_summed = CHECKSUM_NONE;
3693
3759
        netif_rx( skb );
 
3760
 
3694
3761
badrx:
3695
3762
        if (rxd.valid == 0) {
3696
3763
                rxd.valid = 1;
3705
3772
        Cmd cmd;
3706
3773
        Resp rsp;
3707
3774
        int status;
3708
 
        int i;
3709
3775
        SsidRid mySsid;
3710
3776
        __le16 lastindex;
3711
3777
        WepKeyRid wkr;
3747
3813
        if (lock)
3748
3814
                up(&ai->sem);
3749
3815
        if (ai->config.len == 0) {
 
3816
                int i;
3750
3817
                tdsRssiRid rssi_rid;
3751
3818
                CapabilityRid cap_rid;
3752
3819
 
3794
3861
                /* Check to see if there are any insmod configured
3795
3862
                   rates to add */
3796
3863
                if ( rates[0] ) {
3797
 
                        int i = 0;
3798
3864
                        memset(ai->config.rates,0,sizeof(ai->config.rates));
3799
3865
                        for( i = 0; i < 8 && rates[i]; i++ ) {
3800
3866
                                ai->config.rates[i] = rates[i];
3801
3867
                        }
3802
3868
                }
3803
3869
                if ( basic_rate > 0 ) {
3804
 
                        int i;
3805
3870
                        for( i = 0; i < 8; i++ ) {
3806
3871
                                if ( ai->config.rates[i] == basic_rate ||
3807
3872
                                     !ai->config.rates ) {
4428
4493
                goto fail;
4429
4494
        apriv->proc_entry->uid = proc_uid;
4430
4495
        apriv->proc_entry->gid = proc_gid;
4431
 
        apriv->proc_entry->owner = THIS_MODULE;
4432
4496
 
4433
4497
        /* Setup the StatsDelta */
4434
4498
        entry = proc_create_data("StatsDelta",
4686
4750
        StatsRid stats;
4687
4751
        int i, j;
4688
4752
        __le32 *vals = stats.vals;
4689
 
        int len = le16_to_cpu(stats.len);
 
4753
        int len;
4690
4754
 
4691
4755
        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4692
4756
                return -ENOMEM;
4697
4761
        }
4698
4762
 
4699
4763
        readStatsRid(apriv, &stats, rid, 1);
 
4764
        len = le16_to_cpu(stats.len);
4700
4765
 
4701
4766
        j = 0;
4702
4767
        for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
5131
5196
        return rc;
5132
5197
}
5133
5198
 
5134
 
/* Returns the length of the key at the index.  If index == 0xffff
5135
 
 * the index of the transmit key is returned.  If the key doesn't exist,
5136
 
 * -1 will be returned.
 
5199
/* Returns the WEP key at the specified index, or -1 if that key does
 
5200
 * not exist.  The buffer is assumed to be at least 16 bytes in length.
5137
5201
 */
5138
 
static int get_wep_key(struct airo_info *ai, u16 index) {
 
5202
static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
 
5203
{
5139
5204
        WepKeyRid wkr;
5140
5205
        int rc;
5141
5206
        __le16 lastindex;
5142
5207
 
5143
5208
        rc = readWepKeyRid(ai, &wkr, 1, 1);
5144
 
        if (rc == SUCCESS) do {
 
5209
        if (rc != SUCCESS)
 
5210
                return -1;
 
5211
        do {
5145
5212
                lastindex = wkr.kindex;
5146
 
                if (wkr.kindex == cpu_to_le16(index)) {
5147
 
                        if (index == 0xffff) {
5148
 
                                return wkr.mac[0];
5149
 
                        }
5150
 
                        return le16_to_cpu(wkr.klen);
 
5213
                if (le16_to_cpu(wkr.kindex) == index) {
 
5214
                        int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
 
5215
                        memcpy(buf, wkr.key, klen);
 
5216
                        return klen;
5151
5217
                }
5152
 
                readWepKeyRid(ai, &wkr, 0, 1);
5153
 
        } while (lastindex != wkr.kindex);
5154
 
        return -1;
5155
 
}
5156
 
 
5157
 
static int set_wep_key(struct airo_info *ai, u16 index,
5158
 
                       const char *key, u16 keylen, int perm, int lock )
 
5218
                rc = readWepKeyRid(ai, &wkr, 0, 1);
 
5219
                if (rc != SUCCESS)
 
5220
                        return -1;
 
5221
        } while (lastindex != wkr.kindex);
 
5222
        return -1;
 
5223
}
 
5224
 
 
5225
static int get_wep_tx_idx(struct airo_info *ai)
 
5226
{
 
5227
        WepKeyRid wkr;
 
5228
        int rc;
 
5229
        __le16 lastindex;
 
5230
 
 
5231
        rc = readWepKeyRid(ai, &wkr, 1, 1);
 
5232
        if (rc != SUCCESS)
 
5233
                return -1;
 
5234
        do {
 
5235
                lastindex = wkr.kindex;
 
5236
                if (wkr.kindex == cpu_to_le16(0xffff))
 
5237
                        return wkr.mac[0];
 
5238
                rc = readWepKeyRid(ai, &wkr, 0, 1);
 
5239
                if (rc != SUCCESS)
 
5240
                        return -1;
 
5241
        } while (lastindex != wkr.kindex);
 
5242
        return -1;
 
5243
}
 
5244
 
 
5245
static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
 
5246
                       u16 keylen, int perm, int lock)
5159
5247
{
5160
5248
        static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5161
5249
        WepKeyRid wkr;
 
5250
        int rc;
5162
5251
 
5163
 
        memset(&wkr, 0, sizeof(wkr));
5164
5252
        if (keylen == 0) {
5165
 
// We are selecting which key to use
5166
 
                wkr.len = cpu_to_le16(sizeof(wkr));
5167
 
                wkr.kindex = cpu_to_le16(0xffff);
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 );
 
5253
                airo_print_err(ai->dev->name, "%s: key length to set was zero",
 
5254
                               __func__);
 
5255
                return -1;
5177
5256
        }
5178
5257
 
 
5258
        memset(&wkr, 0, sizeof(wkr));
 
5259
        wkr.len = cpu_to_le16(sizeof(wkr));
 
5260
        wkr.kindex = cpu_to_le16(index);
 
5261
        wkr.klen = cpu_to_le16(keylen);
 
5262
        memcpy(wkr.key, key, keylen);
 
5263
        memcpy(wkr.mac, macaddr, ETH_ALEN);
 
5264
 
5179
5265
        if (perm) disable_MAC(ai, lock);
5180
 
        writeWepKeyRid(ai, &wkr, perm, lock);
 
5266
        rc = writeWepKeyRid(ai, &wkr, perm, lock);
5181
5267
        if (perm) enable_MAC(ai, lock);
5182
 
        return 0;
 
5268
        return rc;
 
5269
}
 
5270
 
 
5271
static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
 
5272
{
 
5273
        WepKeyRid wkr;
 
5274
        int rc;
 
5275
 
 
5276
        memset(&wkr, 0, sizeof(wkr));
 
5277
        wkr.len = cpu_to_le16(sizeof(wkr));
 
5278
        wkr.kindex = cpu_to_le16(0xffff);
 
5279
        wkr.mac[0] = (char)index;
 
5280
 
 
5281
        if (perm) {
 
5282
                ai->defindex = (char)index;
 
5283
                disable_MAC(ai, lock);
 
5284
        }
 
5285
 
 
5286
        rc = writeWepKeyRid(ai, &wkr, perm, lock);
 
5287
 
 
5288
        if (perm)
 
5289
                enable_MAC(ai, lock);
 
5290
        return rc;
5183
5291
}
5184
5292
 
5185
5293
static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5187
5295
        struct proc_dir_entry *dp = PDE(inode);
5188
5296
        struct net_device *dev = dp->data;
5189
5297
        struct airo_info *ai = dev->ml_priv;
5190
 
        int i;
 
5298
        int i, rc;
5191
5299
        char key[16];
5192
5300
        u16 index = 0;
5193
5301
        int j = 0;
5201
5309
            (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5202
5310
                index = data->wbuffer[0] - '0';
5203
5311
                if (data->wbuffer[1] == '\n') {
5204
 
                        set_wep_key(ai, index, NULL, 0, 1, 1);
 
5312
                        rc = set_wep_tx_idx(ai, index, 1, 1);
 
5313
                        if (rc < 0) {
 
5314
                                airo_print_err(ai->dev->name, "failed to set "
 
5315
                                               "WEP transmit index to %d: %d.",
 
5316
                                               index, rc);
 
5317
                        }
5205
5318
                        return;
5206
5319
                }
5207
5320
                j = 2;
5220
5333
                        break;
5221
5334
                }
5222
5335
        }
5223
 
        set_wep_key(ai, index, key, i/3, 1, 1);
 
5336
 
 
5337
        rc = set_wep_key(ai, index, key, i/3, 1, 1);
 
5338
        if (rc < 0) {
 
5339
                airo_print_err(ai->dev->name, "failed to set WEP key at index "
 
5340
                               "%d: %d.", index, rc);
 
5341
        }
5224
5342
}
5225
5343
 
5226
5344
static int proc_wepkey_open( struct inode *inode, struct file *file )
5451
5569
                        break;
5452
5570
                case AUTH_SHAREDKEY:
5453
5571
                        if (apriv->keyindex < auto_wep) {
5454
 
                                set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
 
5572
                                set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
5455
5573
                                apriv->config.authType = AUTH_SHAREDKEY;
5456
5574
                                apriv->keyindex++;
5457
5575
                        } else {
5458
5576
                                /* Drop to ENCRYPT */
5459
5577
                                apriv->keyindex = 0;
5460
 
                                set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
 
5578
                                set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
5461
5579
                                apriv->config.authType = AUTH_ENCRYPT;
5462
5580
                        }
5463
5581
                        break;
5725
5843
        int rc = -EINPROGRESS;          /* Call commit handler */
5726
5844
 
5727
5845
        /* If setting by frequency, convert to a channel */
5728
 
        if((fwrq->e == 1) &&
5729
 
           (fwrq->m >= (int) 2.412e8) &&
5730
 
           (fwrq->m <= (int) 2.487e8)) {
 
5846
        if(fwrq->e == 1) {
5731
5847
                int f = fwrq->m / 100000;
5732
 
                int c = 0;
5733
 
                while((c < 14) && (f != frequency_list[c]))
5734
 
                        c++;
 
5848
 
5735
5849
                /* Hack to fall through... */
5736
5850
                fwrq->e = 0;
5737
 
                fwrq->m = c + 1;
 
5851
                fwrq->m = ieee80211_freq_to_dsss_chan(f);
5738
5852
        }
5739
5853
        /* Setting by channel number */
5740
5854
        if((fwrq->m > 1000) || (fwrq->e > 0))
5778
5892
 
5779
5893
        ch = le16_to_cpu(status_rid.channel);
5780
5894
        if((ch > 0) && (ch < 15)) {
5781
 
                fwrq->m = frequency_list[ch - 1] * 100000;
 
5895
                fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000;
5782
5896
                fwrq->e = 1;
5783
5897
        } else {
5784
5898
                fwrq->m = ch;
6234
6348
        return 0;
6235
6349
}
6236
6350
 
6237
 
static inline int valid_index(CapabilityRid *p, int index)
 
6351
static inline int valid_index(struct airo_info *ai, int index)
6238
6352
{
6239
 
        if (index < 0)
6240
 
                return 0;
6241
 
        return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
 
6353
        return (index >= 0) && (index <= ai->max_wep_idx);
6242
6354
}
6243
6355
 
6244
6356
/*------------------------------------------------------------------*/
6251
6363
                           char *extra)
6252
6364
{
6253
6365
        struct airo_info *local = dev->ml_priv;
6254
 
        CapabilityRid cap_rid;          /* Card capability info */
6255
 
        int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
 
6366
        int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
6256
6367
        __le16 currentAuthType = local->config.authType;
 
6368
        int rc = 0;
6257
6369
 
6258
 
        /* Is WEP supported ? */
6259
 
        readCapabilityRid(local, &cap_rid, 1);
6260
 
        /* Older firmware doesn't support this...
6261
 
        if(!(cap_rid.softCap & cpu_to_le16(2))) {
 
6370
        if (!local->wep_capable)
6262
6371
                return -EOPNOTSUPP;
6263
 
        } */
 
6372
 
6264
6373
        readConfigRid(local, 1);
6265
6374
 
6266
6375
        /* Basic checking: do we have a key to set ?
6272
6381
        if (dwrq->length > 0) {
6273
6382
                wep_key_t key;
6274
6383
                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6275
 
                int current_index = get_wep_key(local, 0xffff);
 
6384
                int current_index;
 
6385
 
6276
6386
                /* Check the size of the key */
6277
6387
                if (dwrq->length > MAX_KEY_SIZE) {
6278
6388
                        return -EINVAL;
6279
6389
                }
 
6390
 
 
6391
                current_index = get_wep_tx_idx(local);
 
6392
                if (current_index < 0)
 
6393
                        current_index = 0;
 
6394
 
6280
6395
                /* Check the index (none -> use current) */
6281
 
                if (!valid_index(&cap_rid, index))
 
6396
                if (!valid_index(local, index))
6282
6397
                        index = current_index;
 
6398
 
6283
6399
                /* Set the length */
6284
6400
                if (dwrq->length > MIN_KEY_SIZE)
6285
6401
                        key.len = MAX_KEY_SIZE;
6296
6412
                        /* Copy the key in the driver */
6297
6413
                        memcpy(key.key, extra, dwrq->length);
6298
6414
                        /* Send the key to the card */
6299
 
                        set_wep_key(local, index, key.key, key.len, perm, 1);
 
6415
                        rc = set_wep_key(local, index, key.key, key.len, perm, 1);
 
6416
                        if (rc < 0) {
 
6417
                                airo_print_err(local->dev->name, "failed to set"
 
6418
                                               " WEP key at index %d: %d.",
 
6419
                                               index, rc);
 
6420
                                return rc;
 
6421
                        }
6300
6422
                }
6301
6423
                /* WE specify that if a valid key is set, encryption
6302
6424
                 * should be enabled (user may turn it off later)
6308
6430
        } else {
6309
6431
                /* Do we want to just set the transmit key index ? */
6310
6432
                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6311
 
                if (valid_index(&cap_rid, index)) {
6312
 
                        set_wep_key(local, index, NULL, 0, perm, 1);
6313
 
                } else
 
6433
                if (valid_index(local, index)) {
 
6434
                        rc = set_wep_tx_idx(local, index, perm, 1);
 
6435
                        if (rc < 0) {
 
6436
                                airo_print_err(local->dev->name, "failed to set"
 
6437
                                               " WEP transmit index to %d: %d.",
 
6438
                                               index, rc);
 
6439
                                return rc;
 
6440
                        }
 
6441
                } else {
6314
6442
                        /* Don't complain if only change the mode */
6315
6443
                        if (!(dwrq->flags & IW_ENCODE_MODE))
6316
6444
                                return -EINVAL;
 
6445
                }
6317
6446
        }
6318
6447
        /* Read the flags */
6319
6448
        if(dwrq->flags & IW_ENCODE_DISABLED)
6339
6468
{
6340
6469
        struct airo_info *local = dev->ml_priv;
6341
6470
        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6342
 
        CapabilityRid cap_rid;          /* Card capability info */
 
6471
        int wep_key_len;
 
6472
        u8 buf[16];
6343
6473
 
6344
 
        /* Is it supported ? */
6345
 
        readCapabilityRid(local, &cap_rid, 1);
6346
 
        if(!(cap_rid.softCap & cpu_to_le16(2))) {
 
6474
        if (!local->wep_capable)
6347
6475
                return -EOPNOTSUPP;
6348
 
        }
 
6476
 
6349
6477
        readConfigRid(local, 1);
 
6478
 
6350
6479
        /* Check encryption mode */
6351
6480
        switch(local->config.authType)  {
6352
6481
                case AUTH_ENCRYPT:
6365
6494
        memset(extra, 0, 16);
6366
6495
 
6367
6496
        /* Which key do we want ? -1 -> tx index */
6368
 
        if (!valid_index(&cap_rid, index))
6369
 
                index = get_wep_key(local, 0xffff);
 
6497
        if (!valid_index(local, index)) {
 
6498
                index = get_wep_tx_idx(local);
 
6499
                if (index < 0)
 
6500
                        index = 0;
 
6501
        }
6370
6502
        dwrq->flags |= index + 1;
 
6503
 
6371
6504
        /* Copy the key to the user buffer */
6372
 
        dwrq->length = get_wep_key(local, index);
6373
 
        if (dwrq->length > 16) {
6374
 
                dwrq->length=0;
 
6505
        wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
 
6506
        if (wep_key_len < 0) {
 
6507
                dwrq->length = 0;
 
6508
        } else {
 
6509
                dwrq->length = wep_key_len;
 
6510
                memcpy(extra, buf, dwrq->length);
6375
6511
        }
 
6512
 
6376
6513
        return 0;
6377
6514
}
6378
6515
 
6388
6525
        struct airo_info *local = dev->ml_priv;
6389
6526
        struct iw_point *encoding = &wrqu->encoding;
6390
6527
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6391
 
        CapabilityRid cap_rid;          /* Card capability info */
6392
6528
        int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
6393
6529
        __le16 currentAuthType = local->config.authType;
6394
 
        int idx, key_len, alg = ext->alg, set_key = 1;
 
6530
        int idx, key_len, alg = ext->alg, set_key = 1, rc;
6395
6531
        wep_key_t key;
6396
6532
 
6397
 
        /* Is WEP supported ? */
6398
 
        readCapabilityRid(local, &cap_rid, 1);
6399
 
        /* Older firmware doesn't support this...
6400
 
        if(!(cap_rid.softCap & cpu_to_le16(2))) {
 
6533
        if (!local->wep_capable)
6401
6534
                return -EOPNOTSUPP;
6402
 
        } */
 
6535
 
6403
6536
        readConfigRid(local, 1);
6404
6537
 
6405
6538
        /* Determine and validate the key index */
6406
6539
        idx = encoding->flags & IW_ENCODE_INDEX;
6407
6540
        if (idx) {
6408
 
                if (!valid_index(&cap_rid, idx - 1))
 
6541
                if (!valid_index(local, idx - 1))
6409
6542
                        return -EINVAL;
6410
6543
                idx--;
6411
 
        } else
6412
 
                idx = get_wep_key(local, 0xffff);
 
6544
        } else {
 
6545
                idx = get_wep_tx_idx(local);
 
6546
                if (idx < 0)
 
6547
                        idx = 0;
 
6548
        }
6413
6549
 
6414
6550
        if (encoding->flags & IW_ENCODE_DISABLED)
6415
6551
                alg = IW_ENCODE_ALG_NONE;
6418
6554
                /* Only set transmit key index here, actual
6419
6555
                 * key is set below if needed.
6420
6556
                 */
6421
 
                set_wep_key(local, idx, NULL, 0, perm, 1);
 
6557
                rc = set_wep_tx_idx(local, idx, perm, 1);
 
6558
                if (rc < 0) {
 
6559
                        airo_print_err(local->dev->name, "failed to set "
 
6560
                                       "WEP transmit index to %d: %d.",
 
6561
                                       idx, rc);
 
6562
                        return rc;
 
6563
                }
6422
6564
                set_key = ext->key_len > 0 ? 1 : 0;
6423
6565
        }
6424
6566
 
6444
6586
                        return -EINVAL;
6445
6587
                }
6446
6588
                /* Send the key to the card */
6447
 
                set_wep_key(local, idx, key.key, key.len, perm, 1);
 
6589
                rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
 
6590
                if (rc < 0) {
 
6591
                        airo_print_err(local->dev->name, "failed to set WEP key"
 
6592
                                       " at index %d: %d.", idx, rc);
 
6593
                        return rc;
 
6594
                }
6448
6595
        }
6449
6596
 
6450
6597
        /* Read the flags */
6474
6621
        struct airo_info *local = dev->ml_priv;
6475
6622
        struct iw_point *encoding = &wrqu->encoding;
6476
6623
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6477
 
        CapabilityRid cap_rid;          /* Card capability info */
6478
 
        int idx, max_key_len;
 
6624
        int idx, max_key_len, wep_key_len;
 
6625
        u8 buf[16];
6479
6626
 
6480
 
        /* Is it supported ? */
6481
 
        readCapabilityRid(local, &cap_rid, 1);
6482
 
        if(!(cap_rid.softCap & cpu_to_le16(2))) {
 
6627
        if (!local->wep_capable)
6483
6628
                return -EOPNOTSUPP;
6484
 
        }
 
6629
 
6485
6630
        readConfigRid(local, 1);
6486
6631
 
6487
6632
        max_key_len = encoding->length - sizeof(*ext);
6490
6635
 
6491
6636
        idx = encoding->flags & IW_ENCODE_INDEX;
6492
6637
        if (idx) {
6493
 
                if (!valid_index(&cap_rid, idx - 1))
 
6638
                if (!valid_index(local, idx - 1))
6494
6639
                        return -EINVAL;
6495
6640
                idx--;
6496
 
        } else
6497
 
                idx = get_wep_key(local, 0xffff);
 
6641
        } else {
 
6642
                idx = get_wep_tx_idx(local);
 
6643
                if (idx < 0)
 
6644
                        idx = 0;
 
6645
        }
6498
6646
 
6499
6647
        encoding->flags = idx + 1;
6500
6648
        memset(ext, 0, sizeof(*ext));
6517
6665
        memset(extra, 0, 16);
6518
6666
        
6519
6667
        /* Copy the key to the user buffer */
6520
 
        ext->key_len = get_wep_key(local, idx);
6521
 
        if (ext->key_len > 16) {
6522
 
                ext->key_len=0;
 
6668
        wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
 
6669
        if (wep_key_len < 0) {
 
6670
                ext->key_len = 0;
 
6671
        } else {
 
6672
                ext->key_len = wep_key_len;
 
6673
                memcpy(extra, buf, ext->key_len);
6523
6674
        }
6524
6675
 
6525
6676
        return 0;
6574
6725
                                local->config.authType = AUTH_ENCRYPT;
6575
6726
                        } else
6576
6727
                                return -EINVAL;
6577
 
                        break;
6578
6728
 
6579
6729
                        /* Commit the changes to flags if needed */
6580
6730
                        if (local->config.authType != currentAuthType)
6581
6731
                                set_bit (FLAG_COMMIT, &local->flags);
 
6732
                        break;
6582
6733
                }
6583
6734
 
6584
6735
        case IW_AUTH_WPA_ENABLED:
6795
6946
        k = 0;
6796
6947
        for(i = 0; i < 14; i++) {
6797
6948
                range->freq[k].i = i + 1; /* List index */
6798
 
                range->freq[k].m = frequency_list[i] * 100000;
6799
 
                range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
 
6949
                range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
 
6950
                range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
6800
6951
        }
6801
6952
        range->num_frequency = k;
6802
6953
 
7031
7182
{
7032
7183
        struct airo_info *local = dev->ml_priv;
7033
7184
        struct sockaddr *address = (struct sockaddr *) extra;
7034
 
        struct iw_quality qual[IW_MAX_AP];
 
7185
        struct iw_quality *qual;
7035
7186
        BSSListRid BSSList;
7036
7187
        int i;
7037
7188
        int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7038
7189
 
 
7190
        qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
 
7191
        if (!qual)
 
7192
                return -ENOMEM;
 
7193
 
7039
7194
        for (i = 0; i < IW_MAX_AP; i++) {
7040
7195
                u16 dBm;
7041
7196
                if (readBSSListRid(local, loseSync, &BSSList))
7090
7245
        }
7091
7246
        dwrq->length = i;
7092
7247
 
 
7248
        kfree(qual);
7093
7249
        return 0;
7094
7250
}
7095
7251
 
7189
7345
        /* Add frequency */
7190
7346
        iwe.cmd = SIOCGIWFREQ;
7191
7347
        iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7192
 
        /* iwe.u.freq.m containt the channel (starting 1), our 
7193
 
         * frequency_list array start at index 0...
7194
 
         */
7195
 
        iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
 
7348
        iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000;
7196
7349
        iwe.u.freq.e = 1;
7197
7350
        current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7198
7351
                                          &iwe, IW_EV_FREQ_LEN);