X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fairo.c;h=00764ddd74d8fc5593339107cd149fac3fec8ed1;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=a4dd1394271446192ccf51a26a82d70c4d0bf042;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a4dd13942..00764ddd7 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -19,6 +19,7 @@ ======================================================================*/ +#include #include #include @@ -46,7 +47,6 @@ #include #include #include -#include #include "airo.h" @@ -467,8 +467,6 @@ static int do8bitIO = 0; #define RID_ECHOTEST_RESULTS 0xFF71 #define RID_BSSLISTFIRST 0xFF72 #define RID_BSSLISTNEXT 0xFF73 -#define RID_WPA_BSSLISTFIRST 0xFF74 -#define RID_WPA_BSSLISTNEXT 0xFF75 typedef struct { u16 cmd; @@ -741,14 +739,6 @@ typedef struct { u16 extSoftCap; } CapabilityRid; - -/* Only present on firmware >= 5.30.17 */ -typedef struct { - u16 unknown[4]; - u8 fixed[12]; /* WLAN management frame */ - u8 iep[624]; -} BSSListRidExtra; - typedef struct { u16 len; u16 index; /* First is 0 and 0xffff means end of list */ @@ -777,9 +767,6 @@ typedef struct { } fh; u16 dsChannel; u16 atimWindow; - - /* Only present on firmware >= 5.30.17 */ - BSSListRidExtra extra; } BSSListRid; typedef struct { @@ -1153,6 +1140,8 @@ struct airo_info { char defindex; // Used with auto wep struct proc_dir_entry *proc_entry; spinlock_t aux_lock; + unsigned long flags; +#define FLAG_PROMISC 8 /* IFF_PROMISC 0x100 - include/linux/if.h */ #define FLAG_RADIO_OFF 0 /* User disabling of MAC */ #define FLAG_RADIO_DOWN 1 /* ifup/ifdown disabling of MAC */ #define FLAG_RADIO_MASK 0x03 @@ -1162,7 +1151,6 @@ struct airo_info { #define FLAG_UPDATE_MULTI 5 #define FLAG_UPDATE_UNI 6 #define FLAG_802_11 7 -#define FLAG_PROMISC 8 /* IFF_PROMISC 0x100 - include/linux/if.h */ #define FLAG_PENDING_XMIT 9 #define FLAG_PENDING_XMIT11 10 #define FLAG_MPI 11 @@ -1170,19 +1158,17 @@ struct airo_info { #define FLAG_COMMIT 13 #define FLAG_RESET 14 #define FLAG_FLASHING 15 -#define FLAG_WPA_CAPABLE 16 - unsigned long flags; -#define JOB_DIE 0 -#define JOB_XMIT 1 -#define JOB_XMIT11 2 -#define JOB_STATS 3 -#define JOB_PROMISC 4 -#define JOB_MIC 5 -#define JOB_EVENT 6 -#define JOB_AUTOWEP 7 -#define JOB_WSTATS 8 -#define JOB_SCAN_RESULTS 9 - unsigned long jobs; +#define JOB_MASK 0x2ff0000 +#define JOB_DIE 16 +#define JOB_XMIT 17 +#define JOB_XMIT11 18 +#define JOB_STATS 19 +#define JOB_PROMISC 20 +#define JOB_MIC 21 +#define JOB_EVENT 22 +#define JOB_AUTOWEP 23 +#define JOB_WSTATS 24 +#define JOB_SCAN_RESULTS 25 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); unsigned short *flash; @@ -1222,11 +1208,6 @@ struct airo_info { #define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE char proc_name[IFNAMSIZ]; - /* WPA-related stuff */ - unsigned int bssListFirst; - unsigned int bssListNext; - unsigned int bssListRidLen; - struct list_head network_list; struct list_head network_free_list; BSSListElement *networks; @@ -1283,7 +1264,7 @@ static void micinit(struct airo_info *ai) { MICRid mic_rid; - clear_bit(JOB_MIC, &ai->jobs); + clear_bit(JOB_MIC, &ai->flags); PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); up(&ai->sem); @@ -1724,24 +1705,24 @@ static void emmh32_final(emmh32_context *context, u8 digest[4]) static int readBSSListRid(struct airo_info *ai, int first, BSSListRid *list) { int rc; - Cmd cmd; - Resp rsp; + Cmd cmd; + Resp rsp; if (first == 1) { - if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN; - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd=CMD_LISTBSS; - if (down_interruptible(&ai->sem)) - return -ERESTARTSYS; - issuecommand(ai, &cmd, &rsp); - up(&ai->sem); - /* Let the command take effect */ - ai->task = current; - ssleep(3); - ai->task = NULL; - } - rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext, - list, ai->bssListRidLen, 1); + if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN; + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd=CMD_LISTBSS; + if (down_interruptible(&ai->sem)) + return -ERESTARTSYS; + issuecommand(ai, &cmd, &rsp); + up(&ai->sem); + /* Let the command take effect */ + ai->task = current; + ssleep(3); + ai->task = NULL; + } + rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT, + list, sizeof(*list), 1); list->len = le16_to_cpu(list->len); list->index = le16_to_cpu(list->index); @@ -2131,7 +2112,7 @@ static void airo_end_xmit(struct net_device *dev) { int fid = priv->xmit.fid; u32 *fids = priv->fids; - clear_bit(JOB_XMIT, &priv->jobs); + clear_bit(JOB_XMIT, &priv->flags); clear_bit(FLAG_PENDING_XMIT, &priv->flags); status = transmit_802_3_packet (priv, fids[fid], skb->data); up(&priv->sem); @@ -2181,7 +2162,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { if (down_trylock(&priv->sem) != 0) { set_bit(FLAG_PENDING_XMIT, &priv->flags); netif_stop_queue(dev); - set_bit(JOB_XMIT, &priv->jobs); + set_bit(JOB_XMIT, &priv->flags); wake_up_interruptible(&priv->thr_wait); } else airo_end_xmit(dev); @@ -2196,7 +2177,7 @@ static void airo_end_xmit11(struct net_device *dev) { int fid = priv->xmit11.fid; u32 *fids = priv->fids; - clear_bit(JOB_XMIT11, &priv->jobs); + clear_bit(JOB_XMIT11, &priv->flags); clear_bit(FLAG_PENDING_XMIT11, &priv->flags); status = transmit_802_11_packet (priv, fids[fid], skb->data); up(&priv->sem); @@ -2252,7 +2233,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { if (down_trylock(&priv->sem) != 0) { set_bit(FLAG_PENDING_XMIT11, &priv->flags); netif_stop_queue(dev); - set_bit(JOB_XMIT11, &priv->jobs); + set_bit(JOB_XMIT11, &priv->flags); wake_up_interruptible(&priv->thr_wait); } else airo_end_xmit11(dev); @@ -2263,7 +2244,7 @@ static void airo_read_stats(struct airo_info *ai) { StatsRid stats_rid; u32 *vals = stats_rid.vals; - clear_bit(JOB_STATS, &ai->jobs); + clear_bit(JOB_STATS, &ai->flags); if (ai->power.event) { up(&ai->sem); return; @@ -2291,10 +2272,10 @@ static struct net_device_stats *airo_get_stats(struct net_device *dev) { struct airo_info *local = dev->priv; - if (!test_bit(JOB_STATS, &local->jobs)) { + if (!test_bit(JOB_STATS, &local->flags)) { /* Get stats out of the card if available */ if (down_trylock(&local->sem) != 0) { - set_bit(JOB_STATS, &local->jobs); + set_bit(JOB_STATS, &local->flags); wake_up_interruptible(&local->thr_wait); } else airo_read_stats(local); @@ -2309,7 +2290,7 @@ static void airo_set_promisc(struct airo_info *ai) { memset(&cmd, 0, sizeof(cmd)); cmd.cmd=CMD_SETMODE; - clear_bit(JOB_PROMISC, &ai->jobs); + clear_bit(JOB_PROMISC, &ai->flags); cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC; issuecommand(ai, &cmd, &rsp); up(&ai->sem); @@ -2321,7 +2302,7 @@ static void airo_set_multicast_list(struct net_device *dev) { if ((dev->flags ^ ai->flags) & IFF_PROMISC) { change_bit(FLAG_PROMISC, &ai->flags); if (down_trylock(&ai->sem) != 0) { - set_bit(JOB_PROMISC, &ai->jobs); + set_bit(JOB_PROMISC, &ai->flags); wake_up_interruptible(&ai->thr_wait); } else airo_set_promisc(ai); @@ -2399,7 +2380,7 @@ void stop_airo_card( struct net_device *dev, int freeres ) } clear_bit(FLAG_REGISTERED, &ai->flags); } - set_bit(JOB_DIE, &ai->jobs); + set_bit(JOB_DIE, &ai->flags); kill_proc(ai->thr_pid, SIGTERM, 1); wait_for_completion(&ai->thr_exited); @@ -2720,14 +2701,14 @@ static int reset_card( struct net_device *dev , int lock) { return 0; } -#define AIRO_MAX_NETWORK_COUNT 64 +#define MAX_NETWORK_COUNT 64 static int airo_networks_allocate(struct airo_info *ai) { if (ai->networks) return 0; ai->networks = - kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement), + kzalloc(MAX_NETWORK_COUNT * sizeof(BSSListElement), GFP_KERNEL); if (!ai->networks) { airo_print_warn(ai->dev->name, "Out of memory allocating beacons"); @@ -2751,33 +2732,11 @@ static void airo_networks_initialize(struct airo_info *ai) INIT_LIST_HEAD(&ai->network_free_list); INIT_LIST_HEAD(&ai->network_list); - for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++) + for (i = 0; i < MAX_NETWORK_COUNT; i++) list_add_tail(&ai->networks[i].list, &ai->network_free_list); } -static int airo_test_wpa_capable(struct airo_info *ai) -{ - int status; - CapabilityRid cap_rid; - const char *name = ai->dev->name; - - status = readCapabilityRid(ai, &cap_rid, 1); - if (status != SUCCESS) return 0; - - /* Only firmware versions 5.30.17 or better can do WPA */ - if ((cap_rid.softVer > 0x530) - || ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 17))) { - airo_print_info(name, "WPA is supported."); - return 1; - } - - /* No WPA support */ - airo_print_info(name, "WPA unsupported (only firmware versions 5.30.17" - " and greater support WPA. Detected %s)", cap_rid.prodVer); - return 0; -} - static struct net_device *_init_airo_card( unsigned short irq, int port, int is_pcmcia, struct pci_dev *pci, struct device *dmdev ) @@ -2800,7 +2759,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ai = dev->priv; ai->wifidev = NULL; ai->flags = 0; - ai->jobs = 0; ai->dev = dev; if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) { airo_print_dbg(dev->name, "Found an MPI350 card"); @@ -2848,7 +2806,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, reset_card (dev, 1); msleep(400); - rc = request_irq( dev->irq, airo_interrupt, IRQF_SHARED, dev->name, dev ); + rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev ); if (rc) { airo_print_err(dev->name, "register interrupt %d failed, rc %d", irq, rc); @@ -2880,18 +2838,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, set_bit(FLAG_FLASHING, &ai->flags); } - /* Test for WPA support */ - if (airo_test_wpa_capable(ai)) { - set_bit(FLAG_WPA_CAPABLE, &ai->flags); - ai->bssListFirst = RID_WPA_BSSLISTFIRST; - ai->bssListNext = RID_WPA_BSSLISTNEXT; - ai->bssListRidLen = sizeof(BSSListRid); - } else { - ai->bssListFirst = RID_BSSLISTFIRST; - ai->bssListNext = RID_BSSLISTNEXT; - ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra); - } - rc = register_netdev(dev); if (rc) { airo_print_err(dev->name, "Couldn't register_netdev"); @@ -2929,7 +2875,7 @@ err_out_irq: err_out_unlink: del_airo_dev(dev); err_out_thr: - set_bit(JOB_DIE, &ai->jobs); + set_bit(JOB_DIE, &ai->flags); kill_proc(ai->thr_pid, SIGTERM, 1); wait_for_completion(&ai->thr_exited); err_out_free: @@ -2987,7 +2933,7 @@ static void airo_send_event(struct net_device *dev) { union iwreq_data wrqu; StatusRid status_rid; - clear_bit(JOB_EVENT, &ai->jobs); + clear_bit(JOB_EVENT, &ai->flags); PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0); up(&ai->sem); wrqu.data.length = 0; @@ -3001,7 +2947,7 @@ static void airo_send_event(struct net_device *dev) { static void airo_process_scan_results (struct airo_info *ai) { union iwreq_data wrqu; - BSSListRid bss; + BSSListRid BSSList; int rc; BSSListElement * loop_net; BSSListElement * tmp_net; @@ -3014,15 +2960,15 @@ static void airo_process_scan_results (struct airo_info *ai) { } /* Try to read the first entry of the scan result */ - rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0); - if((rc) || (bss.index == 0xffff)) { + rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 0); + if((rc) || (BSSList.index == 0xffff)) { /* No scan results */ goto out; } /* Read and parse all entries */ tmp_net = NULL; - while((!rc) && (bss.index != 0xffff)) { + while((!rc) && (BSSList.index != 0xffff)) { /* Grab a network off the free list */ if (!list_empty(&ai->network_free_list)) { tmp_net = list_entry(ai->network_free_list.next, @@ -3031,19 +2977,19 @@ static void airo_process_scan_results (struct airo_info *ai) { } if (tmp_net != NULL) { - memcpy(tmp_net, &bss, sizeof(tmp_net->bss)); + memcpy(tmp_net, &BSSList, sizeof(tmp_net->bss)); list_add_tail(&tmp_net->list, &ai->network_list); tmp_net = NULL; } /* Read next entry */ - rc = PC4500_readrid(ai, ai->bssListNext, - &bss, ai->bssListRidLen, 0); + rc = PC4500_readrid(ai, RID_BSSLISTNEXT, + &BSSList, sizeof(BSSList), 0); } out: ai->scan_timeout = 0; - clear_bit(JOB_SCAN_RESULTS, &ai->jobs); + clear_bit(JOB_SCAN_RESULTS, &ai->flags); up(&ai->sem); /* Send an empty event to user space. @@ -3073,10 +3019,10 @@ static int airo_thread(void *data) { /* make swsusp happy with our thread */ try_to_freeze(); - if (test_bit(JOB_DIE, &ai->jobs)) + if (test_bit(JOB_DIE, &ai->flags)) break; - if (ai->jobs) { + if (ai->flags & JOB_MASK) { locked = down_interruptible(&ai->sem); } else { wait_queue_t wait; @@ -3085,16 +3031,16 @@ static int airo_thread(void *data) { add_wait_queue(&ai->thr_wait, &wait); for (;;) { set_current_state(TASK_INTERRUPTIBLE); - if (ai->jobs) + if (ai->flags & JOB_MASK) break; if (ai->expires || ai->scan_timeout) { if (ai->scan_timeout && time_after_eq(jiffies,ai->scan_timeout)){ - set_bit(JOB_SCAN_RESULTS, &ai->jobs); + set_bit(JOB_SCAN_RESULTS,&ai->flags); break; } else if (ai->expires && time_after_eq(jiffies,ai->expires)){ - set_bit(JOB_AUTOWEP, &ai->jobs); + set_bit(JOB_AUTOWEP,&ai->flags); break; } if (!signal_pending(current)) { @@ -3123,7 +3069,7 @@ static int airo_thread(void *data) { if (locked) continue; - if (test_bit(JOB_DIE, &ai->jobs)) { + if (test_bit(JOB_DIE, &ai->flags)) { up(&ai->sem); break; } @@ -3133,23 +3079,23 @@ static int airo_thread(void *data) { continue; } - if (test_bit(JOB_XMIT, &ai->jobs)) + if (test_bit(JOB_XMIT, &ai->flags)) airo_end_xmit(dev); - else if (test_bit(JOB_XMIT11, &ai->jobs)) + else if (test_bit(JOB_XMIT11, &ai->flags)) airo_end_xmit11(dev); - else if (test_bit(JOB_STATS, &ai->jobs)) + else if (test_bit(JOB_STATS, &ai->flags)) airo_read_stats(ai); - else if (test_bit(JOB_WSTATS, &ai->jobs)) + else if (test_bit(JOB_WSTATS, &ai->flags)) airo_read_wireless_stats(ai); - else if (test_bit(JOB_PROMISC, &ai->jobs)) + else if (test_bit(JOB_PROMISC, &ai->flags)) airo_set_promisc(ai); - else if (test_bit(JOB_MIC, &ai->jobs)) + else if (test_bit(JOB_MIC, &ai->flags)) micinit(ai); - else if (test_bit(JOB_EVENT, &ai->jobs)) + else if (test_bit(JOB_EVENT, &ai->flags)) airo_send_event(dev); - else if (test_bit(JOB_AUTOWEP, &ai->jobs)) + else if (test_bit(JOB_AUTOWEP, &ai->flags)) timer_func(dev); - else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs)) + else if (test_bit(JOB_SCAN_RESULTS, &ai->flags)) airo_process_scan_results(ai); else /* Shouldn't get here, but we make sure to unlock */ up(&ai->sem); @@ -3187,7 +3133,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) if ( status & EV_MIC ) { OUT4500( apriv, EVACK, EV_MIC ); if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { - set_bit(JOB_MIC, &apriv->jobs); + set_bit(JOB_MIC, &apriv->flags); wake_up_interruptible(&apriv->thr_wait); } } @@ -3241,7 +3187,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) set_bit(FLAG_UPDATE_MULTI, &apriv->flags); if (down_trylock(&apriv->sem) != 0) { - set_bit(JOB_EVENT, &apriv->jobs); + set_bit(JOB_EVENT, &apriv->flags); wake_up_interruptible(&apriv->thr_wait); } else airo_send_event(dev); @@ -5539,7 +5485,7 @@ static void timer_func( struct net_device *dev ) { up(&apriv->sem); /* Schedule check to see if the change worked */ - clear_bit(JOB_AUTOWEP, &apriv->jobs); + clear_bit(JOB_AUTOWEP, &apriv->flags); apriv->expires = RUN_AT(HZ*3); } @@ -6930,7 +6876,7 @@ static int airo_get_range(struct net_device *dev, } range->num_txpower = i; range->txpower_capa = IW_TXPOW_MWATT; - range->we_version_source = 19; + range->we_version_source = 12; range->we_version_compiled = WIRELESS_EXT; range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME; range->retry_flags = IW_RETRY_LIMIT; @@ -7206,7 +7152,6 @@ static inline char *airo_translate_scan(struct net_device *dev, u16 capabilities; char * current_val; /* For rates */ int i; - char * buf; /* First entry *MUST* be the AP MAC address */ iwe.cmd = SIOCGIWAP; @@ -7293,69 +7238,8 @@ static inline char *airo_translate_scan(struct net_device *dev, if((current_val - current_ev) > IW_EV_LCP_LEN) current_ev = current_val; - /* Beacon interval */ - buf = kmalloc(30, GFP_KERNEL); - if (buf) { - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "bcn_int=%d", bss->beaconInterval); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); - kfree(buf); - } - - /* Put WPA/RSN Information Elements into the event stream */ - if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) { - unsigned int num_null_ies = 0; - u16 length = sizeof (bss->extra.iep); - struct ieee80211_info_element *info_element = - (struct ieee80211_info_element *) &bss->extra.iep; - - while ((length >= sizeof(*info_element)) && (num_null_ies < 2)) { - if (sizeof(*info_element) + info_element->len > length) { - /* Invalid element, don't continue parsing IE */ - break; - } - - switch (info_element->id) { - case MFIE_TYPE_SSID: - /* Two zero-length SSID elements - * mean we're done parsing elements */ - if (!info_element->len) - num_null_ies++; - break; - - case MFIE_TYPE_GENERIC: - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x01) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = min(info_element->len + 2, - MAX_WPA_IE_LEN); - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, (char *) info_element); - } - break; - - case MFIE_TYPE_RSN: - iwe.cmd = IWEVGENIE; - iwe.u.data.length = min(info_element->len + 2, - MAX_WPA_IE_LEN); - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, (char *) info_element); - break; - - default: - break; - } - - length -= sizeof(*info_element) + info_element->len; - info_element = - (struct ieee80211_info_element *)&info_element-> - data[info_element->len]; - } - } + /* The other data in the scan result are not really + * interesting, so for now drop it - Jean II */ return current_ev; } @@ -7637,7 +7521,7 @@ static void airo_read_wireless_stats(struct airo_info *local) u32 *vals = stats_rid.vals; /* Get stats out of the card */ - clear_bit(JOB_WSTATS, &local->jobs); + clear_bit(JOB_WSTATS, &local->flags); if (local->power.event) { up(&local->sem); return; @@ -7681,10 +7565,10 @@ static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) { struct airo_info *local = dev->priv; - if (!test_bit(JOB_WSTATS, &local->jobs)) { + if (!test_bit(JOB_WSTATS, &local->flags)) { /* Get stats out of the card if available */ if (down_trylock(&local->sem) != 0) { - set_bit(JOB_WSTATS, &local->jobs); + set_bit(JOB_WSTATS, &local->flags); wake_up_interruptible(&local->thr_wait); } else airo_read_wireless_stats(local);