======================================================================*/
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/in.h>
#include <linux/bitops.h>
#include <linux/scatterlist.h>
-#include <linux/crypto.h>
#include <asm/io.h>
#include <asm/system.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
-#include <net/ieee80211.h>
#include "airo.h"
#include <linux/delay.h>
#endif
+/* Support Cisco MIC feature */
+#define MICSUPPORT
+
+#if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO)
+#warning MIC support requires Crypto API
+#undef MICSUPPORT
+#endif
+
/* Hack to do some power saving */
#define POWER_ON_DOWN
#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;
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 */
} fh;
u16 dsChannel;
u16 atimWindow;
-
- /* Only present on firmware >= 5.30.17 */
- BSSListRidExtra extra;
} BSSListRid;
-typedef struct {
- BSSListRid bss;
- struct list_head list;
-} BSSListElement;
-
typedef struct {
u8 rssipct;
u8 rssidBm;
#define NUM_MODULES 2
#define MIC_MSGLEN_MAX 2400
#define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
-#define AIRO_DEF_MTU 2312
typedef struct {
u32 size; // size
static int writerids(struct net_device *dev, aironet_ioctl *comp);
static int flashcard(struct net_device *dev, aironet_ioctl *comp);
#endif /* CISCO_EXT */
+#ifdef MICSUPPORT
static void micinit(struct airo_info *ai);
static int micsetup(struct airo_info *ai);
static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
-static void airo_networks_free(struct airo_info *ai);
+#include <linux/crypto.h>
+#endif
struct airo_info {
struct net_device_stats stats;
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
#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
#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 0x1ff0000
+#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
int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
int whichbap);
unsigned short *flash;
} xmit, xmit11;
struct net_device *wifidev;
struct iw_statistics wstats; // wireless stats
- unsigned long scan_timeout; /* Time scan should be read */
+ unsigned long scan_timestamp; /* Time started to scan */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
+#ifdef MICSUPPORT
/* MIC stuff */
struct crypto_tfm *tfm;
mic_module mod[2];
mic_statistics micstats;
+#endif
HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
HostTxDesc txfids[MPI_MAX_FIDS];
HostRidDesc config_desc;
APListRid *APList;
#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;
};
static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
static int flashputbuf(struct airo_info *ai);
static int flashrestart(struct airo_info *ai,struct net_device *dev);
-#define airo_print(type, name, fmt, args...) \
- { printk(type "airo(%s): " fmt "\n", name, ##args); }
-
-#define airo_print_info(name, fmt, args...) \
- airo_print(KERN_INFO, name, fmt, ##args)
-
-#define airo_print_dbg(name, fmt, args...) \
- airo_print(KERN_DEBUG, name, fmt, ##args)
-
-#define airo_print_warn(name, fmt, args...) \
- airo_print(KERN_WARNING, name, fmt, ##args)
-
-#define airo_print_err(name, fmt, args...) \
- airo_print(KERN_ERR, name, fmt, ##args)
-
-
+#ifdef MICSUPPORT
/***********************************************************************
* MIC ROUTINES *
***********************************************************************
{
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);
ai->tfm = crypto_alloc_tfm("aes", CRYPTO_TFM_REQ_MAY_SLEEP);
if (ai->tfm == NULL) {
- airo_print_err(ai->dev->name, "failed to load transform for AES");
+ printk(KERN_ERR "airo: failed to load transform for AES\n");
return ERROR;
}
digest[2] = (val>>8) & 0xFF;
digest[3] = val & 0xFF;
}
+#endif
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);
wkr.kindex = cpu_to_le16(wkr.kindex);
wkr.klen = cpu_to_le16(wkr.klen);
rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock);
- if (rc!=SUCCESS) airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
+ if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc);
if (perm) {
rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock);
if (rc!=SUCCESS) {
- airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
+ printk(KERN_ERR "airo: WEP_PERM set %x\n", rc);
}
}
return rc;
struct airo_info *ai = dev->priv;
if (!skb) {
- airo_print_err(dev->name, "%s: skb == NULL!",__FUNCTION__);
+ printk(KERN_ERR "airo: %s: skb==NULL\n",__FUNCTION__);
return 0;
}
npacks = skb_queue_len (&ai->txq);
/* get a packet to send */
if ((skb = skb_dequeue(&ai->txq)) == 0) {
- airo_print_err(dev->name,
- "%s: Dequeue'd zero in send_packet()",
+ printk (KERN_ERR
+ "airo: %s: Dequeue'd zero in send_packet()\n",
__FUNCTION__);
return 0;
}
* Firmware automaticly puts 802 header on so
* we don't need to account for it in the length
*/
+#ifdef MICSUPPORT
if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
(ntohs(((u16 *)buffer)[6]) != 0x888E)) {
MICBuffer pMic;
memcpy (sendbuf, &pMic, sizeof(pMic));
sendbuf += sizeof(pMic);
memcpy (sendbuf, buffer, len - sizeof(etherHead));
- } else {
+ } else
+#endif
+ {
*payloadLen = cpu_to_le16(len - sizeof(etherHead));
dev->trans_start = jiffies;
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);
u32 *fids = priv->fids;
if ( skb == NULL ) {
- airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__);
+ printk( KERN_ERR "airo: skb == NULL!!!\n" );
return 0;
}
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);
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);
}
if ( skb == NULL ) {
- airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__);
+ printk( KERN_ERR "airo: skb == NULL!!!\n" );
return 0;
}
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);
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;
{
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);
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);
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);
}
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);
dev_kfree_skb(skb);
}
- airo_networks_free (ai);
-
kfree(ai->flash);
kfree(ai->rssi);
kfree(ai->APList);
ai->shared, ai->shared_dma);
}
}
+#ifdef MICSUPPORT
crypto_free_tfm(ai->tfm);
+#endif
del_airo_dev( dev );
free_netdev( dev );
}
cmd.parm2 = MPI_MAX_FIDS;
rc=issuecommand(ai, &cmd, &rsp);
if (rc != SUCCESS) {
- airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
+ printk(KERN_ERR "airo: Couldn't allocate RX FID\n");
return rc;
}
rc=issuecommand(ai, &cmd, &rsp);
if (rc != SUCCESS) {
- airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
+ printk(KERN_ERR "airo: Couldn't allocate TX FID\n");
return rc;
}
cmd.parm2 = 1; /* Magic number... */
rc=issuecommand(ai, &cmd, &rsp);
if (rc != SUCCESS) {
- airo_print_err(ai->dev->name, "Couldn't allocate RID");
+ printk(KERN_ERR "airo: Couldn't allocate RID\n");
return rc;
}
aux_len = AUXMEMSIZE;
if (!request_mem_region(mem_start, mem_len, name)) {
- airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s",
+ printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
(int)mem_start, (int)mem_len, name);
goto out;
}
if (!request_mem_region(aux_start, aux_len, name)) {
- airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s",
+ printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
(int)aux_start, (int)aux_len, name);
goto free_region1;
}
ai->pcimem = ioremap(mem_start, mem_len);
if (!ai->pcimem) {
- airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s",
+ printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
(int)mem_start, (int)mem_len, name);
goto free_region2;
}
ai->pciaux = ioremap(aux_start, aux_len);
if (!ai->pciaux) {
- airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s",
+ printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
(int)aux_start, (int)aux_len, name);
goto free_memmap;
}
/* Reserve PKTSIZE for each fid and 2K for the Rids */
ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
if (!ai->shared) {
- airo_print_err(ai->dev->name, "Couldn't alloc_consistent %d",
+ printk(KERN_ERR "airo: Couldn't alloc_consistent %d\n",
PCI_SHARED_LEN);
goto free_auxmap;
}
dev->type = ARPHRD_IEEE80211;
dev->hard_header_len = ETH_HLEN;
- dev->mtu = AIRO_DEF_MTU;
+ dev->mtu = 2312;
dev->addr_len = ETH_ALEN;
dev->tx_queue_len = 100;
return 0;
}
-#define AIRO_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),
- GFP_KERNEL);
- if (!ai->networks) {
- airo_print_warn(ai->dev->name, "Out of memory allocating beacons");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void airo_networks_free(struct airo_info *ai)
-{
- if (!ai->networks)
- return;
- kfree(ai->networks);
- ai->networks = NULL;
-}
-
-static void airo_networks_initialize(struct airo_info *ai)
-{
- int i;
-
- INIT_LIST_HEAD(&ai->network_free_list);
- INIT_LIST_HEAD(&ai->network_list);
- for (i = 0; i < AIRO_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 )
/* Create the network device object. */
dev = alloc_etherdev(sizeof(*ai));
if (!dev) {
- airo_print_err("", "Couldn't alloc_etherdev");
+ printk(KERN_ERR "airo: Couldn't alloc_etherdev\n");
return NULL;
}
if (dev_alloc_name(dev, dev->name) < 0) {
- airo_print_err("", "Couldn't get name!");
+ printk(KERN_ERR "airo: Couldn't get name!\n");
goto err_out_free;
}
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");
+ printk(KERN_DEBUG "airo: Found an MPI350 card\n");
set_bit(FLAG_MPI, &ai->flags);
}
+ ai->dev = dev;
spin_lock_init(&ai->aux_lock);
sema_init(&ai->sem, 1);
ai->config.len = 0;
ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);
if (ai->thr_pid < 0)
goto err_out_free;
+#ifdef MICSUPPORT
ai->tfm = NULL;
+#endif
rc = add_airo_dev( dev );
if (rc)
goto err_out_thr;
- if (airo_networks_allocate (ai))
- goto err_out_unlink;
- airo_networks_initialize (ai);
-
/* The Airo-specific entries in the device structure. */
if (test_bit(FLAG_MPI,&ai->flags)) {
skb_queue_head_init (&ai->txq);
SET_NETDEV_DEV(dev, dmdev);
+
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);
+ printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
goto err_out_unlink;
}
if (!is_pcmcia) {
if (!request_region( dev->base_addr, 64, dev->name )) {
rc = -EBUSY;
- airo_print_err(dev->name, "Couldn't request region");
+ printk(KERN_ERR "airo: Couldn't request region\n");
goto err_out_irq;
}
}
if (test_bit(FLAG_MPI,&ai->flags)) {
if (mpi_map_card(ai, pci, dev->name)) {
- airo_print_err(dev->name, "Could not map memory");
+ printk(KERN_ERR "airo: Could not map memory\n");
goto err_out_res;
}
}
if (probe) {
if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
- airo_print_err(dev->name, "MAC could not be enabled" );
+ printk( KERN_ERR "airo: MAC could not be enabled\n" );
rc = -EIO;
goto err_out_map;
}
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");
+ printk(KERN_ERR "airo: Couldn't register_netdev\n");
goto err_out_map;
}
ai->wifidev = init_wifidev(ai, dev);
set_bit(FLAG_REGISTERED,&ai->flags);
- airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x",
+ printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
+ dev->name,
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
/* Allocate the transmit buffers */
if (probe && !test_bit(FLAG_MPI,&ai->flags))
for( i = 0; i < MAX_FIDS; i++ )
- ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
+ ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
netif_start_queue(dev);
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:
return -1;
if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
- airo_print_err(dev->name, "MAC could not be enabled");
+ printk( KERN_ERR "airo: MAC could not be enabled\n" );
return -1;
}
- airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x",
+ printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", dev->name,
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
/* Allocate the transmit buffers if needed */
if (!test_bit(FLAG_MPI,&ai->flags))
for( i = 0; i < MAX_FIDS; i++ )
- ai->fids[i] = transmit_allocate (ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
+ ai->fids[i] = transmit_allocate (ai,2312,i>=MAX_FIDS/2);
enable_interrupts( ai );
netif_wake_queue(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;
wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
}
-static void airo_process_scan_results (struct airo_info *ai) {
- union iwreq_data wrqu;
- BSSListRid bss;
- int rc;
- BSSListElement * loop_net;
- BSSListElement * tmp_net;
-
- /* Blow away current list of scan results */
- list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
- list_move_tail (&loop_net->list, &ai->network_free_list);
- /* Don't blow away ->list, just BSS data */
- memset (loop_net, 0, sizeof (loop_net->bss));
- }
-
- /* 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)) {
- /* No scan results */
- goto out;
- }
-
- /* Read and parse all entries */
- tmp_net = NULL;
- while((!rc) && (bss.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,
- BSSListElement, list);
- list_del(ai->network_free_list.next);
- }
-
- if (tmp_net != NULL) {
- memcpy(tmp_net, &bss, 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);
- }
-
-out:
- ai->scan_timeout = 0;
- clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
- up(&ai->sem);
-
- /* Send an empty event to user space.
- * We don't send the received data on
- * the event because it would require
- * us to do complex transcoding, and
- * we want to minimise the work done in
- * the irq handler. Use a request to
- * extract the data - Jean II */
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
-}
-
static int airo_thread(void *data) {
struct net_device *dev = data;
struct airo_info *ai = dev->priv;
/* 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;
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);
- break;
- } else if (ai->expires &&
- time_after_eq(jiffies,ai->expires)){
- set_bit(JOB_AUTOWEP, &ai->jobs);
+ if (ai->expires) {
+ if (time_after_eq(jiffies,ai->expires)){
+ set_bit(JOB_AUTOWEP,&ai->flags);
break;
}
if (!signal_pending(current)) {
- unsigned long wake_at;
- if (!ai->expires || !ai->scan_timeout) {
- wake_at = max(ai->expires,
- ai->scan_timeout);
- } else {
- wake_at = min(ai->expires,
- ai->scan_timeout);
- }
- schedule_timeout(wake_at - jiffies);
+ schedule_timeout(ai->expires - jiffies);
continue;
}
} else if (!signal_pending(current)) {
if (locked)
continue;
- if (test_bit(JOB_DIE, &ai->jobs)) {
+ if (test_bit(JOB_DIE, &ai->flags)) {
up(&ai->sem);
break;
}
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))
+#ifdef MICSUPPORT
+ else if (test_bit(JOB_MIC, &ai->flags))
micinit(ai);
- else if (test_bit(JOB_EVENT, &ai->jobs))
+#endif
+ 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))
- airo_process_scan_results(ai);
- else /* Shouldn't get here, but we make sure to unlock */
- up(&ai->sem);
}
complete_and_exit (&ai->thr_exited, 0);
}
if ( status & EV_MIC ) {
OUT4500( apriv, EVACK, EV_MIC );
+#ifdef MICSUPPORT
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);
}
+#endif
}
if ( status & EV_LINK ) {
union iwreq_data wrqu;
- int scan_forceloss = 0;
/* The link status has changed, if you want to put a
monitor hook in, do it here. (Remember that
interrupts are still disabled!)
code) */
#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
code) */
-#define ASSOCIATED 0x0400 /* Associated */
-#define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
+#define ASSOCIATED 0x0400 /* Assocatied */
#define RC_RESERVED 0 /* Reserved return code */
#define RC_NOREASON 1 /* Unspecified reason */
#define RC_AUTHINV 2 /* Previous authentication invalid */
leaving BSS */
#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
Authenticated with the responding station */
- if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
- scan_forceloss = 1;
- if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
+ if (newStatus != ASSOCIATED) {
+ if (auto_wep && !apriv->expires) {
+ apriv->expires = RUN_AT(3*HZ);
+ wake_up_interruptible(&apriv->thr_wait);
+ }
+ } else {
+ struct task_struct *task = apriv->task;
if (auto_wep)
apriv->expires = 0;
- if (apriv->task)
- wake_up_process (apriv->task);
+ if (task)
+ wake_up_process (task);
set_bit(FLAG_UPDATE_UNI, &apriv->flags);
set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
-
+ }
+ /* Question : is ASSOCIATED the only status
+ * that is valid ? We want to catch handover
+ * and reassociations as valid status
+ * Jean II */
+ if(newStatus == ASSOCIATED) {
+ if (apriv->scan_timestamp) {
+ /* Send an empty event to user space.
+ * We don't send the received data on
+ * the event because it would require
+ * us to do complex transcoding, and
+ * we want to minimise the work done in
+ * the irq handler. Use a request to
+ * extract the data - Jean II */
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+ apriv->scan_timestamp = 0;
+ }
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);
- } else if (!scan_forceloss) {
- if (auto_wep && !apriv->expires) {
- apriv->expires = RUN_AT(3*HZ);
- wake_up_interruptible(&apriv->thr_wait);
- }
-
- /* Send event to user space */
+ } else {
memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+
+ /* Send event to user space */
wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
}
}
}
len = le16_to_cpu(hdr.len);
- if (len > AIRO_DEF_MTU) {
- airo_print_err(apriv->dev->name, "Bad size %d", len);
+ if (len > 2312) {
+ printk( KERN_ERR "airo: Bad size %d\n", len );
goto badrx;
}
if (len == 0)
bap_read (apriv, &gap, sizeof(gap), BAP0);
gap = le16_to_cpu(gap);
if (gap) {
- if (gap <= 8) {
+ if (gap <= 8)
bap_read (apriv, tmpbuf, gap, BAP0);
- } else {
- airo_print_err(apriv->dev->name, "gaplen too "
- "big. Problems will follow...");
- }
+ else
+ printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n");
}
bap_read (apriv, buffer + hdrlen/2, len, BAP0);
} else {
+#ifdef MICSUPPORT
MICBuffer micbuf;
+#endif
bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
+#ifdef MICSUPPORT
if (apriv->micstats.enabled) {
bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
if (ntohs(micbuf.typelen) > 0x05DC)
skb_trim (skb, len + hdrlen);
}
}
+#endif
bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
+#ifdef MICSUPPORT
if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
badmic:
dev_kfree_skb_irq (skb);
+#else
+ if (0) {
+#endif
badrx:
OUT4500( apriv, EVACK, EV_RX);
goto exitrx;
}
} else {
OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
- airo_print_err(apriv->dev->name, "Unallocated FID was "
- "used to xmit" );
+ printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
}
}
exittx:
if ( status & ~STATUS_INTS & ~IGNORE_INTS )
- airo_print_warn(apriv->dev->name, "Got weird status %x",
+ printk( KERN_WARNING "airo: Got weird status %x\n",
status & ~STATUS_INTS & ~IGNORE_INTS );
}
up(&ai->sem);
if (rc)
- airo_print_err(ai->dev->name, "%s: Cannot enable MAC, err=%d",
- __FUNCTION__, rc);
+ printk(KERN_ERR "%s: Cannot enable MAC, err=%d\n",
+ __FUNCTION__,rc);
return rc;
}
int len = 0;
struct sk_buff *skb;
char *buffer;
+#ifdef MICSUPPORT
int off = 0;
MICBuffer micbuf;
+#endif
memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
/* Make sure we got something */
goto badrx;
}
buffer = skb_put(skb,len);
+#ifdef MICSUPPORT
memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
if (ai->micstats.enabled) {
memcpy(&micbuf,
dev_kfree_skb_irq (skb);
goto badrx;
}
+#else
+ memcpy(buffer, ai->rxfids[0].virtual_host_addr, len);
+#endif
#ifdef WIRELESS_SPY
if (ai->spy_data.spy_number > 0) {
char *sa;
if (ai->wifidev == NULL)
hdr.len = 0;
len = le16_to_cpu(hdr.len);
- if (len > AIRO_DEF_MTU) {
- airo_print_err(ai->dev->name, "Bad size %d", len);
+ if (len > 2312) {
+ printk( KERN_ERR "airo: Bad size %d\n", len );
goto badrx;
}
if (len == 0)
if (gap <= 8)
ptr += gap;
else
- airo_print_err(ai->dev->name,
- "gaplen too big. Problems will follow...");
+ printk(KERN_ERR
+ "airo: gaplen too big. Problems will follow...\n");
}
memcpy ((char *)buffer + hdrlen, ptr, len);
ptr += len;
if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
if (lock)
up(&ai->sem);
- airo_print_err(ai->dev->name, "Error checking for AUX port");
+ printk(KERN_ERR "airo: Error checking for AUX port\n");
return ERROR;
}
if (!aux_bap || rsp.status & 0xff00) {
ai->bap_read = fast_bap_read;
- airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
+ printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
} else {
ai->bap_read = aux_bap_read;
- airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
+ printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
}
}
if (lock)
if (cap_rid.softCap & 8)
ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
else
- airo_print_warn(ai->dev->name, "unknown received signal "
- "level scale");
+ printk(KERN_WARNING "airo: unknown received signal level scale\n");
}
ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
ai->config.authType = AUTH_OPEN;
ai->config.modulation = MOD_CCK;
+#ifdef MICSUPPORT
if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
(micsetup(ai) == SUCCESS)) {
ai->config.opmode |= MODE_MIC;
set_bit(FLAG_MIC_CAPABLE, &ai->flags);
}
+#endif
/* Save off the MAC */
for( i = 0; i < ETH_ALEN; i++ ) {
status = enable_MAC(ai, &rsp, lock);
if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
- airo_print_err(ai->dev->name, "Bad MAC enable reason = %x, rid = %x,"
- " offset = %d", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
+ printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
return ERROR;
}
}
if ( max_tries == -1 ) {
- airo_print_err(ai->dev->name,
- "Max tries exceeded when issueing command");
+ printk( KERN_ERR
+ "airo: Max tries exceeded when issueing command\n" );
if (IN4500(ai, COMMAND) & COMMAND_BUSY)
OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
return ERROR;
pRsp->rsp1 = IN4500(ai, RESP1);
pRsp->rsp2 = IN4500(ai, RESP2);
if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) {
- airo_print_err(ai->dev->name, "cmd= %x\n", pCmd->cmd);
- airo_print_err(ai->dev->name, "status= %x\n", pRsp->status);
- airo_print_err(ai->dev->name, "Rsp0= %x\n", pRsp->rsp0);
- airo_print_err(ai->dev->name, "Rsp1= %x\n", pRsp->rsp1);
- airo_print_err(ai->dev->name, "Rsp2= %x\n", pRsp->rsp2);
+ printk (KERN_ERR "airo: cmd= %x\n", pCmd->cmd);
+ printk (KERN_ERR "airo: status= %x\n", pRsp->status);
+ printk (KERN_ERR "airo: Rsp0= %x\n", pRsp->rsp0);
+ printk (KERN_ERR "airo: Rsp1= %x\n", pRsp->rsp1);
+ printk (KERN_ERR "airo: Rsp2= %x\n", pRsp->rsp2);
}
// clear stuck command busy if necessary
}
} else if ( status & BAP_ERR ) {
/* invalid rid or offset */
- airo_print_err(ai->dev->name, "BAP error %x %d",
+ printk( KERN_ERR "airo: BAP error %x %d\n",
status, whichbap );
return ERROR;
} else if (status & BAP_DONE) { // success
return SUCCESS;
}
if ( !(max_tries--) ) {
- airo_print_err(ai->dev->name,
- "airo: BAP setup error too many retries\n");
+ printk( KERN_ERR
+ "airo: BAP setup error too many retries\n" );
return ERROR;
}
// -- PC4500 missed it, try again
len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
if ( len <= 2 ) {
- airo_print_err(ai->dev->name,
- "Rid %x has a length of %d which is too short",
+ printk( KERN_ERR
+ "airo: Rid %x has a length of %d which is too short\n",
(int)rid, (int)len );
rc = ERROR;
goto done;
Resp rsp;
if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
- airo_print_err(ai->dev->name,
- "%s: MAC should be disabled (rid=%04x)",
+ printk(KERN_ERR
+ "%s: MAC should be disabled (rid=%04x)\n",
__FUNCTION__, rid);
memset(&cmd, 0, sizeof(cmd));
memset(&rsp, 0, sizeof(rsp));
&ai->config_desc.rid_desc, sizeof(Rid));
if (len < 4 || len > 2047) {
- airo_print_err(ai->dev->name, "%s: len=%d", __FUNCTION__, len);
+ printk(KERN_ERR "%s: len=%d\n",__FUNCTION__,len);
rc = -1;
} else {
memcpy((char *)ai->config_desc.virtual_host_addr,
rc = issuecommand(ai, &cmd, &rsp);
if ((rc & 0xff00) != 0) {
- airo_print_err(ai->dev->name, "%s: Write rid Error %d",
- __FUNCTION__, rc);
- airo_print_err(ai->dev->name, "%s: Cmd=%04x",
- __FUNCTION__, cmd.cmd);
+ printk(KERN_ERR "%s: Write rid Error %d\n",
+ __FUNCTION__,rc);
+ printk(KERN_ERR "%s: Cmd=%04x\n",
+ __FUNCTION__,cmd.cmd);
}
if ((rsp.status & 0x7f00))
len >>= 16;
if (len <= ETH_ALEN * 2) {
- airo_print_warn(ai->dev->name, "Short packet %d", len);
+ printk( KERN_WARNING "Short packet %d\n", len );
return ERROR;
}
len -= ETH_ALEN * 2;
+#ifdef MICSUPPORT
if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
(ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
return ERROR;
miclen = sizeof(pMic);
}
+#endif
+
// packet is destination[6], source[6], payload[len-12]
// write the payload length and dst/src/payload
if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
}
if (len < hdrlen) {
- airo_print_warn(ai->dev->name, "Short packet %d", len);
+ printk( KERN_WARNING "Short packet %d\n", len );
return ERROR;
}
i*4<stats.len; i++){
if (!statsLabels[i]) continue;
if (j+strlen(statsLabels[i])+16>4096) {
- airo_print_warn(apriv->dev->name,
- "Potentially disasterous buffer overflow averted!");
+ printk(KERN_WARNING
+ "airo: Potentially disasterous buffer overflow averted!\n");
break;
}
j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]);
}
if (i*4>=stats.len){
- airo_print_warn(apriv->dev->name, "Got a short rid");
+ printk(KERN_WARNING
+ "airo: Got a short rid\n");
}
data->readlen = j;
return 0;
line += 14;
v = get_dec_u16(line, &i, 4);
- v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
+ v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
ai->config.rtsThres = (u16)v;
set_bit (FLAG_COMMIT, &ai->flags);
} else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
line += 15;
v = get_dec_u16(line, &i, 4);
- v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
+ v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
v = v & 0xfffe; /* Make sure its even */
ai->config.fragThresh = (u16)v;
set_bit (FLAG_COMMIT, &ai->flags);
case 'd': ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
case 'c': ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
case 'm': ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
- default: airo_print_warn(ai->dev->name, "Unknown modulation");
+ default:
+ printk( KERN_WARNING "airo: Unknown modulation\n" );
}
} else if (!strncmp(line, "Preamble: ", 10)) {
line += 10;
case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
- default: airo_print_warn(ai->dev->name, "Unknown preamble");
+ default: printk(KERN_WARNING "airo: Unknown preamble\n");
}
} else {
- airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
+ printk( KERN_WARNING "Couldn't figure out %s\n", line );
}
while( line[0] && line[0] != '\n' ) line++;
if ( line[0] ) line++;
wkr.len = sizeof(wkr);
wkr.kindex = 0xffff;
wkr.mac[0] = (char)index;
+ if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index);
if (perm) ai->defindex = (char)index;
} else {
// We are actually setting the key
wkr.klen = keylen;
memcpy( wkr.key, key, keylen );
memcpy( wkr.mac, macaddr, ETH_ALEN );
+ printk(KERN_INFO "Setting key %d\n", index);
}
if (perm) disable_MAC(ai, lock);
}
j = 2;
} else {
- airo_print_err(ai->dev->name, "WepKey passed invalid key index");
+ printk(KERN_ERR "airo: WepKey passed invalid key index\n");
return;
}
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);
}
airo_entry->gid = proc_gid;
for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
- airo_print_info("", "Trying to configure ISA adapter at irq=%d "
- "io=0x%x", irq[i], io[i] );
+ printk( KERN_INFO
+ "airo: Trying to configure ISA adapter at irq=%d io=0x%x\n",
+ irq[i], io[i] );
if (init_airo_card( irq[i], io[i], 0, NULL ))
have_isa_dev = 1;
}
#ifdef CONFIG_PCI
- airo_print_info("", "Probing for PCI adapters");
+ printk( KERN_INFO "airo: Probing for PCI adapters\n" );
pci_register_driver(&airo_driver);
- airo_print_info("", "Finished probing for PCI adapters");
+ printk( KERN_INFO "airo: Finished probing for PCI adapters\n" );
#endif
/* Always exit with success, as we are a library module
static void __exit airo_cleanup_module( void )
{
while( airo_devices ) {
- airo_print_info(airo_devices->dev->name, "Unregistering...\n");
+ printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
stop_airo_card( airo_devices->dev, 1 );
}
#ifdef CONFIG_PCI
/* We should do a better check than that,
* based on the card capability !!! */
if((channel < 1) || (channel > 14)) {
- airo_print_dbg(dev->name, "New channel value of %d is invalid!",
- fwrq->m);
+ printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m);
rc = -EINVAL;
} else {
readConfigRid(local, 1);
Cmd cmd;
Resp rsp;
APListRid APList_rid;
- static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
- static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
if (awrq->sa_family != ARPHRD_ETHER)
return -EINVAL;
- else if (!memcmp(any, awrq->sa_data, ETH_ALEN) ||
- !memcmp(off, awrq->sa_data, ETH_ALEN)) {
+ else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
memset(&cmd, 0, sizeof(cmd));
cmd.cmd=CMD_LOSE_SYNC;
if (down_interruptible(&local->sem))
int rthr = vwrq->value;
if(vwrq->disabled)
- rthr = AIRO_DEF_MTU;
- if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
+ rthr = 2312;
+ if((rthr < 0) || (rthr > 2312)) {
return -EINVAL;
}
readConfigRid(local, 1);
readConfigRid(local, 1);
vwrq->value = local->config.rtsThres;
- vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
+ vwrq->disabled = (vwrq->value >= 2312);
vwrq->fixed = 1;
return 0;
int fthr = vwrq->value;
if(vwrq->disabled)
- fthr = AIRO_DEF_MTU;
- if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
+ fthr = 2312;
+ if((fthr < 256) || (fthr > 2312)) {
return -EINVAL;
}
fthr &= ~0x1; /* Get an even value - is it really needed ??? */
readConfigRid(local, 1);
vwrq->value = local->config.fragThresh;
- vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
+ vwrq->disabled = (vwrq->value >= 2312);
vwrq->fixed = 1;
return 0;
return 0;
}
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set extended Encryption parameters
- */
-static int airo_set_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct airo_info *local = dev->priv;
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- CapabilityRid cap_rid; /* Card capability info */
- int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
- u16 currentAuthType = local->config.authType;
- int idx, key_len, alg = ext->alg, set_key = 1;
- wep_key_t key;
-
- /* Is WEP supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- /* Older firmware doesn't support this...
- if(!(cap_rid.softCap & 2)) {
- return -EOPNOTSUPP;
- } */
- readConfigRid(local, 1);
-
- /* Determine and validate the key index */
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1))
- return -EINVAL;
- idx--;
- } else
- idx = get_wep_key(local, 0xffff);
-
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- /* Only set transmit key index here, actual
- * key is set below if needed.
- */
- set_wep_key(local, idx, NULL, 0, perm, 1);
- set_key = ext->key_len > 0 ? 1 : 0;
- }
-
- if (set_key) {
- /* Set the requested key first */
- memset(key.key, 0, MAX_KEY_SIZE);
- switch (alg) {
- case IW_ENCODE_ALG_NONE:
- key.len = 0;
- break;
- case IW_ENCODE_ALG_WEP:
- if (ext->key_len > MIN_KEY_SIZE) {
- key.len = MAX_KEY_SIZE;
- } else if (ext->key_len > 0) {
- key.len = MIN_KEY_SIZE;
- } else {
- return -EINVAL;
- }
- key_len = min (ext->key_len, key.len);
- memcpy(key.key, ext->key, key_len);
- break;
- default:
- return -EINVAL;
- }
- /* Send the key to the card */
- set_wep_key(local, idx, key.key, key.len, perm, 1);
- }
-
- /* Read the flags */
- if(encoding->flags & IW_ENCODE_DISABLED)
- local->config.authType = AUTH_OPEN; // disable encryption
- if(encoding->flags & IW_ENCODE_RESTRICTED)
- local->config.authType = AUTH_SHAREDKEY; // Only Both
- if(encoding->flags & IW_ENCODE_OPEN)
- local->config.authType = AUTH_ENCRYPT; // Only Wep
- /* Commit the changes to flags if needed */
- if (local->config.authType != currentAuthType)
- set_bit (FLAG_COMMIT, &local->flags);
-
- return -EINPROGRESS;
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get extended Encryption parameters
- */
-static int airo_get_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct airo_info *local = dev->priv;
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- CapabilityRid cap_rid; /* Card capability info */
- int idx, max_key_len;
-
- /* Is it supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- if(!(cap_rid.softCap & 2)) {
- return -EOPNOTSUPP;
- }
- readConfigRid(local, 1);
-
- max_key_len = encoding->length - sizeof(*ext);
- if (max_key_len < 0)
- return -EINVAL;
-
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1))
- return -EINVAL;
- idx--;
- } else
- idx = get_wep_key(local, 0xffff);
-
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
-
- /* Check encryption mode */
- switch(local->config.authType) {
- case AUTH_ENCRYPT:
- encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
- break;
- case AUTH_SHAREDKEY:
- encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
- break;
- default:
- case AUTH_OPEN:
- encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
- break;
- }
- /* We can't return the key, so set the proper flag and return zero */
- encoding->flags |= IW_ENCODE_NOKEY;
- memset(extra, 0, 16);
-
- /* Copy the key to the user buffer */
- ext->key_len = get_wep_key(local, idx);
- if (ext->key_len > 16) {
- ext->key_len=0;
- }
-
- return 0;
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set extended authentication parameters
- */
-static int airo_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct airo_info *local = dev->priv;
- struct iw_param *param = &wrqu->param;
- u16 currentAuthType = local->config.authType;
-
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_KEY_MGMT:
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- case IW_AUTH_PRIVACY_INVOKED:
- /*
- * airo does not use these parameters
- */
- break;
-
- case IW_AUTH_DROP_UNENCRYPTED:
- if (param->value) {
- /* Only change auth type if unencrypted */
- if (currentAuthType == AUTH_OPEN)
- local->config.authType = AUTH_ENCRYPT;
- } else {
- local->config.authType = AUTH_OPEN;
- }
-
- /* Commit the changes to flags if needed */
- if (local->config.authType != currentAuthType)
- set_bit (FLAG_COMMIT, &local->flags);
- break;
-
- case IW_AUTH_80211_AUTH_ALG: {
- /* FIXME: What about AUTH_OPEN? This API seems to
- * disallow setting our auth to AUTH_OPEN.
- */
- if (param->value & IW_AUTH_ALG_SHARED_KEY) {
- local->config.authType = AUTH_SHAREDKEY;
- } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- local->config.authType = AUTH_ENCRYPT;
- } else
- return -EINVAL;
- break;
-
- /* Commit the changes to flags if needed */
- if (local->config.authType != currentAuthType)
- set_bit (FLAG_COMMIT, &local->flags);
- }
-
- case IW_AUTH_WPA_ENABLED:
- /* Silently accept disable of WPA */
- if (param->value > 0)
- return -EOPNOTSUPP;
- break;
-
- default:
- return -EOPNOTSUPP;
- }
- return -EINPROGRESS;
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get extended authentication parameters
- */
-static int airo_get_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct airo_info *local = dev->priv;
- struct iw_param *param = &wrqu->param;
- u16 currentAuthType = local->config.authType;
-
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_DROP_UNENCRYPTED:
- switch (currentAuthType) {
- case AUTH_SHAREDKEY:
- case AUTH_ENCRYPT:
- param->value = 1;
- break;
- default:
- param->value = 0;
- break;
- }
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- switch (currentAuthType) {
- case AUTH_SHAREDKEY:
- param->value = IW_AUTH_ALG_SHARED_KEY;
- break;
- case AUTH_ENCRYPT:
- default:
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- }
- break;
-
- case IW_AUTH_WPA_ENABLED:
- param->value = 0;
- break;
-
- default:
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-
/*------------------------------------------------------------------*/
/*
* Wireless Handler : set Tx-Power
range->throughput = 1500 * 1000;
range->min_rts = 0;
- range->max_rts = AIRO_DEF_MTU;
+ range->max_rts = 2312;
range->min_frag = 256;
- range->max_frag = AIRO_DEF_MTU;
+ range->max_frag = 2312;
if(cap_rid.softCap & 2) {
// WEP: RC4 40 bits
}
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;
struct airo_info *ai = dev->priv;
Cmd cmd;
Resp rsp;
- int wake = 0;
/* Note : you may have realised that, as this is a SET operation,
* this is privileged and therefore a normal user can't
* Jean II */
if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
- if (down_interruptible(&ai->sem))
- return -ERESTARTSYS;
-
- /* If there's already a scan in progress, don't
- * trigger another one. */
- if (ai->scan_timeout > 0)
- goto out;
-
/* Initiate a scan command */
- ai->scan_timeout = RUN_AT(3*HZ);
memset(&cmd, 0, sizeof(cmd));
cmd.cmd=CMD_LISTBSS;
+ if (down_interruptible(&ai->sem))
+ return -ERESTARTSYS;
issuecommand(ai, &cmd, &rsp);
- wake = 1;
-
-out:
+ ai->scan_timestamp = jiffies;
up(&ai->sem);
- if (wake)
- wake_up_interruptible(&ai->thr_wait);
+
+ /* At this point, just return to the user. */
+
return 0;
}
u16 capabilities;
char * current_val; /* For rates */
int i;
- char * buf;
/* First entry *MUST* be the AP MAC address */
iwe.cmd = SIOCGIWAP;
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;
}
char *extra)
{
struct airo_info *ai = dev->priv;
- BSSListElement *net;
- int err = 0;
+ BSSListRid BSSList;
+ int rc;
char *current_ev = extra;
- /* If a scan is in-progress, return -EAGAIN */
- if (ai->scan_timeout > 0)
+ /* When we are associated again, the scan has surely finished.
+ * Just in case, let's make sure enough time has elapsed since
+ * we started the scan. - Javier */
+ if(ai->scan_timestamp && time_before(jiffies,ai->scan_timestamp+3*HZ)) {
+ /* Important note : we don't want to block the caller
+ * until results are ready for various reasons.
+ * First, managing wait queues is complex and racy
+ * (there may be multiple simultaneous callers).
+ * Second, we grab some rtnetlink lock before comming
+ * here (in dev_ioctl()).
+ * Third, the caller can wait on the Wireless Event
+ * - Jean II */
return -EAGAIN;
+ }
+ ai->scan_timestamp = 0;
- if (down_interruptible(&ai->sem))
- return -EAGAIN;
+ /* There's only a race with proc_BSSList_open(), but its
+ * consequences are begnign. So I don't bother fixing it - Javier */
- list_for_each_entry (net, &ai->network_list, list) {
+ /* Try to read the first entry of the scan result */
+ rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1);
+ if((rc) || (BSSList.index == 0xffff)) {
+ /* Client error, no scan results...
+ * The caller need to restart the scan. */
+ return -ENODATA;
+ }
+
+ /* Read and parse all entries */
+ while((!rc) && (BSSList.index != 0xffff)) {
/* Translate to WE format this entry */
current_ev = airo_translate_scan(dev, current_ev,
extra + dwrq->length,
- &net->bss);
+ &BSSList);
/* Check if there is space for one more entry */
if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
/* Ask user space to try again with a bigger buffer */
- err = -E2BIG;
- goto out;
+ return -E2BIG;
}
- }
+ /* Read next entry */
+ rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
+ &BSSList, sizeof(BSSList), 1);
+ }
/* Length of data */
dwrq->length = (current_ev - extra);
dwrq->flags = 0; /* todo */
-out:
- up(&ai->sem);
- return err;
+ return 0;
}
/*------------------------------------------------------------------*/
(iw_handler) airo_get_encode, /* SIOCGIWENCODE */
(iw_handler) airo_set_power, /* SIOCSIWPOWER */
(iw_handler) airo_get_power, /* SIOCGIWPOWER */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCSIWGENIE */
- (iw_handler) NULL, /* SIOCGIWGENIE */
- (iw_handler) airo_set_auth, /* SIOCSIWAUTH */
- (iw_handler) airo_get_auth, /* SIOCGIWAUTH */
- (iw_handler) airo_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) airo_get_encodeext, /* SIOCGIWENCODEEXT */
- (iw_handler) NULL, /* SIOCSIWPMKSA */
};
/* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
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;
{
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);
case AIROGSTAT: ridcode = RID_STATUS; break;
case AIROGSTATSD32: ridcode = RID_STATSDELTA; break;
case AIROGSTATSC32: ridcode = RID_STATS; break;
+#ifdef MICSUPPORT
case AIROGMICSTATS:
if (copy_to_user(comp->data, &ai->micstats,
min((int)comp->len,(int)sizeof(ai->micstats))))
return -EFAULT;
return 0;
+#endif
case AIRORRID: ridcode = comp->ridnum; break;
default:
return -EINVAL;
static int writerids(struct net_device *dev, aironet_ioctl *comp) {
struct airo_info *ai = dev->priv;
int ridcode;
+#ifdef MICSUPPORT
int enabled;
+#endif
Resp rsp;
static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
unsigned char *iobuf;
PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
+#ifdef MICSUPPORT
enabled = ai->micstats.enabled;
memset(&ai->micstats,0,sizeof(ai->micstats));
ai->micstats.enabled = enabled;
+#endif
if (copy_to_user(comp->data, iobuf,
min((int)comp->len, (int)RIDSIZE))) {
disable_MAC(ai, 1);
if(!waitbusy (ai)){
- airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
+ printk(KERN_INFO "Waitbusy hang before RESET\n");
return -EBUSY;
}
ssleep(1); /* WAS 600 12/7/00 */
if(!waitbusy (ai)){
- airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
+ printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
return -EBUSY;
}
return 0;
if(!waitbusy(ai)) {
clear_bit (FLAG_FLASHING, &ai->flags);
- airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
+ printk(KERN_INFO "Waitbusy hang after setflash mode\n");
return -EIO;
}
return 0;
/* timeout for busy clear wait */
if(waittime <= 0 ){
- airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
+ printk(KERN_INFO "flash putchar busywait timeout! \n");
return -EBUSY;
}
if (!test_bit(FLAG_MPI,&ai->flags))
for( i = 0; i < MAX_FIDS; i++ ) {
ai->fids[i] = transmit_allocate
- ( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
+ ( ai, 2312, i >= MAX_FIDS / 2 );
}
ssleep(1); /* Added 12/7/00 */