diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-01-31 11:50:55 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-31 11:50:55 -0500 |
commit | 0b310f36d7d96e27f6941ec0f9b95e15142f1e78 (patch) | |
tree | c2a3d403c82fd892ded3849cc721cf8e6f8c7824 /drivers/net/wireless | |
parent | 359b8800d3a46557844969c485e1a14baf119b06 (diff) | |
parent | 2f633db5e9c57e07a971b65e9a72f090f59fd5f6 (diff) | |
download | kernel-crypto-0b310f36d7d96e27f6941ec0f9b95e15142f1e78.tar.gz kernel-crypto-0b310f36d7d96e27f6941ec0f9b95e15142f1e78.tar.xz kernel-crypto-0b310f36d7d96e27f6941ec0f9b95e15142f1e78.zip |
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/wireless/airo.c | 331 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2100.c | 48 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2100.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 876 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2200.h | 64 | ||||
-rw-r--r-- | drivers/net/wireless/netwave_cs.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wavelan.p.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/wavelan_cs.p.h | 9 |
9 files changed, 812 insertions, 537 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 233a4f60808..3de5f1d0fba 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -6,7 +6,8 @@ menu "Wireless LAN (non-hamradio)" depends on NETDEVICES config NET_RADIO - bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions" + bool "Wireless LAN drivers (non-hamradio)" + select WIRELESS_EXT ---help--- Support for wireless LANs and everything having to do with radio, but not with amateur radio or FM broadcasting. @@ -239,7 +240,8 @@ config IPW2200_DEBUG config AIRO tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" - depends on NET_RADIO && ISA_DMA_API && CRYPTO && (PCI || BROKEN) + depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN) + select CRYPTO ---help--- This is the standard Linux driver to support Cisco/Aironet ISA and PCI 802.11 wireless cards. @@ -387,6 +389,7 @@ config PCMCIA_SPECTRUM config AIRO_CS tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) + select CRYPTO ---help--- This is the standard Linux driver to support Cisco/Aironet PCMCIA 802.11 wireless cards. This driver is the same as the Aironet diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a4c7ae94614..ef6495b0789 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -36,6 +36,7 @@ #include <linux/in.h> #include <linux/bitops.h> #include <linux/scatterlist.h> +#include <linux/crypto.h> #include <asm/io.h> #include <asm/system.h> @@ -87,14 +88,6 @@ static struct pci_driver airo_driver = { #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 @@ -1118,7 +1111,6 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp); 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); @@ -1127,9 +1119,6 @@ static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi); static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); -#include <linux/crypto.h> -#endif - struct airo_info { struct net_device_stats stats; struct net_device *dev; @@ -1190,12 +1179,10 @@ struct airo_info { 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; @@ -1229,7 +1216,6 @@ static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime); static int flashputbuf(struct airo_info *ai); static int flashrestart(struct airo_info *ai,struct net_device *dev); -#ifdef MICSUPPORT /*********************************************************************** * MIC ROUTINES * *********************************************************************** @@ -1686,7 +1672,6 @@ static void emmh32_final(emmh32_context *context, u8 digest[4]) digest[2] = (val>>8) & 0xFF; digest[3] = val & 0xFF; } -#endif static int readBSSListRid(struct airo_info *ai, int first, BSSListRid *list) { @@ -2005,7 +1990,6 @@ static int mpi_send_packet (struct net_device *dev) * 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; @@ -2022,9 +2006,7 @@ static int mpi_send_packet (struct net_device *dev) memcpy (sendbuf, &pMic, sizeof(pMic)); sendbuf += sizeof(pMic); memcpy (sendbuf, buffer, len - sizeof(etherHead)); - } else -#endif - { + } else { *payloadLen = cpu_to_le16(len - sizeof(etherHead)); dev->trans_start = jiffies; @@ -2400,9 +2382,7 @@ void stop_airo_card( struct net_device *dev, int freeres ) ai->shared, ai->shared_dma); } } -#ifdef MICSUPPORT crypto_free_tfm(ai->tfm); -#endif del_airo_dev( dev ); free_netdev( dev ); } @@ -2726,9 +2706,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, 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; @@ -2969,10 +2947,8 @@ static int airo_thread(void *data) { airo_read_wireless_stats(ai); else if (test_bit(JOB_PROMISC, &ai->flags)) airo_set_promisc(ai); -#ifdef MICSUPPORT else if (test_bit(JOB_MIC, &ai->flags)) micinit(ai); -#endif else if (test_bit(JOB_EVENT, &ai->flags)) airo_send_event(dev); else if (test_bit(JOB_AUTOWEP, &ai->flags)) @@ -3010,12 +2986,10 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) if ( status & EV_MIC ) { OUT4500( apriv, EVACK, EV_MIC ); -#ifdef MICSUPPORT if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { set_bit(JOB_MIC, &apriv->flags); wake_up_interruptible(&apriv->thr_wait); } -#endif } if ( status & EV_LINK ) { union iwreq_data wrqu; @@ -3194,11 +3168,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) } 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) @@ -3211,15 +3182,10 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) 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; @@ -3430,10 +3396,8 @@ static void mpi_receive_802_3(struct airo_info *ai) 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 */ @@ -3448,7 +3412,6 @@ static void mpi_receive_802_3(struct airo_info *ai) 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, @@ -3470,9 +3433,6 @@ badmic: 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; @@ -3689,13 +3649,11 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) 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++ ) { @@ -4170,15 +4128,12 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket) } 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; @@ -5801,11 +5756,13 @@ static int airo_set_wap(struct net_device *dev, Cmd cmd; Resp rsp; APListRid APList_rid; - static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 }; + static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (awrq->sa_family != ARPHRD_ETHER) return -EINVAL; - else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) { + else if (!memcmp(any, awrq->sa_data, ETH_ALEN) || + !memcmp(off, awrq->sa_data, ETH_ALEN)) { memset(&cmd, 0, sizeof(cmd)); cmd.cmd=CMD_LOSE_SYNC; if (down_interruptible(&local->sem)) @@ -6296,6 +6253,267 @@ static int airo_get_encode(struct net_device *dev, /*------------------------------------------------------------------*/ /* + * 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; /* Check encryption mode */ + 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; + + /* Just setting the transmit key? */ + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { + set_wep_key(local, idx, NULL, 0, perm, 1); + } else { + /* 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 */ static int airo_set_txpow(struct net_device *dev, @@ -7050,6 +7268,15 @@ static const iw_handler airo_handler[] = (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. @@ -7270,13 +7497,11 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) { 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; @@ -7308,9 +7533,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) { 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; @@ -7367,11 +7590,9 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) { 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))) { diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 6290c9f7e93..eb79198ac45 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -167,7 +167,7 @@ that only one external action is invoked at a time. #include "ipw2100.h" -#define IPW2100_VERSION "1.1.3" +#define IPW2100_VERSION "git-1.1.4" #define DRV_NAME "ipw2100" #define DRV_VERSION IPW2100_VERSION @@ -1672,6 +1672,18 @@ static int ipw2100_start_scan(struct ipw2100_priv *priv) return err; } +static const struct ieee80211_geo ipw_geos[] = { + { /* Restricted */ + "---", + .bg_channels = 14, + .bg = {{2412, 1}, {2417, 2}, {2422, 3}, + {2427, 4}, {2432, 5}, {2437, 6}, + {2442, 7}, {2447, 8}, {2452, 9}, + {2457, 10}, {2462, 11}, {2467, 12}, + {2472, 13}, {2484, 14}}, + }, +}; + static int ipw2100_up(struct ipw2100_priv *priv, int deferred) { unsigned long flags; @@ -1727,6 +1739,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) goto exit; } + /* Initialize the geo */ + if (ieee80211_set_geo(priv->ieee, &ipw_geos[0])) { + printk(KERN_WARNING DRV_NAME "Could not set geo\n"); + return 0; + } + priv->ieee->freq_band = IEEE80211_24GHZ_BAND; + lock = LOCK_NONE; if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) { printk(KERN_ERR DRV_NAME @@ -3750,7 +3769,7 @@ static ssize_t store_memory(struct device *d, struct device_attribute *attr, struct net_device *dev = priv->net_dev; const char *p = buf; - (void) dev; /* kill unused-var warning for debug-only code */ + (void)dev; /* kill unused-var warning for debug-only code */ if (count < 1) return count; @@ -4070,7 +4089,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, unsigned long val; char *p = buffer; - (void) dev; /* kill unused-var warning for debug-only code */ + (void)dev; /* kill unused-var warning for debug-only code */ IPW_DEBUG_INFO("enter\n"); @@ -5107,12 +5126,13 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power) .host_command_length = 4 }; int err = 0; + u32 tmp = tx_power; if (tx_power != IPW_TX_POWER_DEFAULT) - tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 / - (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM); + tmp = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 / + (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM); - cmd.host_command_parameters[0] = tx_power; + cmd.host_command_parameters[0] = tmp; if (priv->ieee->iw_mode == IW_MODE_ADHOC) err = ipw2100_hw_send_command(priv, &cmd); @@ -5365,9 +5385,12 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode) SEC_LEVEL_0, 0, 1); } else { auth_mode = IPW_AUTH_OPEN; - if ((priv->ieee->sec.flags & SEC_AUTH_MODE) && - (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) - auth_mode = IPW_AUTH_SHARED; + if (priv->ieee->sec.flags & SEC_AUTH_MODE) { + if (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY) + auth_mode = IPW_AUTH_SHARED; + else if (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP) + auth_mode = IPW_AUTH_LEAP_CISCO_ID; + } sec_level = SEC_LEVEL_0; if (priv->ieee->sec.flags & SEC_LEVEL) @@ -5760,6 +5783,9 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) { sec.auth_mode = WLAN_AUTH_OPEN; ieee->open_wep = 1; + } else if (value & IW_AUTH_ALG_LEAP) { + sec.auth_mode = WLAN_AUTH_LEAP; + ieee->open_wep = 1; } else return -EINVAL; @@ -5771,8 +5797,8 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) return ret; } -void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, - char *wpa_ie, int wpa_ie_len) +static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, + char *wpa_ie, int wpa_ie_len) { struct ipw2100_wpa_assoc_frame frame; diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h index f6c51441fa8..51360910d22 100644 --- a/drivers/net/wireless/ipw2100.h +++ b/drivers/net/wireless/ipw2100.h @@ -392,8 +392,10 @@ struct ipw2100_notification { #define IPW_WEP104_CIPHER (1<<5) #define IPW_CKIP_CIPHER (1<<6) -#define IPW_AUTH_OPEN 0 -#define IPW_AUTH_SHARED 1 +#define IPW_AUTH_OPEN 0 +#define IPW_AUTH_SHARED 1 +#define IPW_AUTH_LEAP 2 +#define IPW_AUTH_LEAP_CISCO_ID 0x80 struct statistic { int value; diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 916b24c544e..734d2cb1de0 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -33,7 +33,7 @@ #include "ipw2200.h" #include <linux/version.h> -#define IPW2200_VERSION "git-1.0.8" +#define IPW2200_VERSION "git-1.0.10" #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation" #define DRV_VERSION IPW2200_VERSION @@ -55,7 +55,9 @@ static int associate = 1; static int auto_create = 1; static int led = 0; static int disable = 0; -static int hwcrypto = 1; +static int bt_coexist = 0; +static int hwcrypto = 0; +static int roaming = 1; static const char ipw_modes[] = { 'a', 'b', 'g', '?' }; @@ -227,12 +229,15 @@ static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len) return total; } +/* alias for 32-bit indirect read (for SRAM/reg above 4K), with debug wrapper */ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg); #define ipw_read_reg32(a, b) _ipw_read_reg32(a, b) +/* alias for 8-bit indirect read (for SRAM/reg above 4K), with debug wrapper */ static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg); #define ipw_read_reg8(a, b) _ipw_read_reg8(a, b) +/* 8-bit indirect write (for SRAM/reg above 4K), with debug wrapper */ static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value); static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) { @@ -241,6 +246,7 @@ static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) _ipw_write_reg8(a, b, c); } +/* 16-bit indirect write (for SRAM/reg above 4K), with debug wrapper */ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value); static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) { @@ -249,6 +255,7 @@ static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) _ipw_write_reg16(a, b, c); } +/* 32-bit indirect write (for SRAM/reg above 4K), with debug wrapper */ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value); static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) { @@ -257,48 +264,70 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) _ipw_write_reg32(a, b, c); } +/* 8-bit direct write (low 4K) */ #define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs)) + +/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */ #define ipw_write8(ipw, ofs, val) \ IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ _ipw_write8(ipw, ofs, val) +/* 16-bit direct write (low 4K) */ #define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs)) + +/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */ #define ipw_write16(ipw, ofs, val) \ IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ _ipw_write16(ipw, ofs, val) +/* 32-bit direct write (low 4K) */ #define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs)) + +/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */ #define ipw_write32(ipw, ofs, val) \ IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \ _ipw_write32(ipw, ofs, val) +/* 8-bit direct read (low 4K) */ #define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs)) + +/* 8-bit direct read (low 4K), with debug wrapper */ static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs)); return _ipw_read8(ipw, ofs); } +/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */ #define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs) +/* 16-bit direct read (low 4K) */ #define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs)) + +/* 16-bit direct read (low 4K), with debug wrapper */ static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs)); return _ipw_read16(ipw, ofs); } +/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */ #define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs) +/* 32-bit direct read (low 4K) */ #define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs)) + +/* 32-bit direct read (low 4K), with debug wrapper */ static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs)); return _ipw_read32(ipw, ofs); } +/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */ #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) +/* multi-byte read (above 4K), with debug wrapper */ static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); static inline void __ipw_read_indirect(const char *f, int l, struct ipw_priv *a, u32 b, u8 * c, int d) @@ -308,15 +337,17 @@ static inline void __ipw_read_indirect(const char *f, int l, _ipw_read_indirect(a, b, c, d); } +/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */ #define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d) +/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, int num); #define ipw_write_indirect(a, b, c, d) \ IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ _ipw_write_indirect(a, b, c, d) -/* indirect write s */ +/* 32-bit indirect write (above 4K) */ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) { IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); @@ -324,22 +355,29 @@ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) _ipw_write32(priv, IPW_INDIRECT_DATA, value); } +/* 8-bit indirect write (above 4K) */ static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) { + u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */ + u32 dif_len = reg - aligned_addr; + IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); - _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); - _ipw_write8(priv, IPW_INDIRECT_DATA, value); + _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); + _ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value); } +/* 16-bit indirect write (above 4K) */ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) { + u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */ + u32 dif_len = (reg - aligned_addr) & (~0x1ul); + IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); - _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); - _ipw_write16(priv, IPW_INDIRECT_DATA, value); + _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); + _ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value); } -/* indirect read s */ - +/* 8-bit indirect read (above 4K) */ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) { u32 word; @@ -349,6 +387,7 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) return (word >> ((reg & 0x3) * 8)) & 0xff; } +/* 32-bit indirect read (above 4K) */ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg) { u32 value; @@ -361,11 +400,12 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg) return value; } -/* iterative/auto-increment 32 bit reads and writes */ +/* General purpose, no alignment requirement, iterative (multi-byte) read, */ +/* for area above 1st 4K of SRAM/reg space */ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, int num) { - u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; + u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */ u32 dif_len = addr - aligned_addr; u32 i; @@ -375,7 +415,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, return; } - /* Read the first nibble byte by byte */ + /* Read the first dword (or portion) byte by byte */ if (unlikely(dif_len)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); /* Start reading at aligned_addr + dif_len */ @@ -384,11 +424,12 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, aligned_addr += 4; } + /* Read all of the middle dwords as dwords, with auto-increment */ _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr); for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4) *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA); - /* Copy the last nibble */ + /* Read the last dword (or portion) byte by byte */ if (unlikely(num)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); for (i = 0; num > 0; i++, num--) @@ -396,10 +437,12 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, } } +/* General purpose, no alignment requirement, iterative (multi-byte) write, */ +/* for area above 1st 4K of SRAM/reg space */ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, int num) { - u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; + u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */ u32 dif_len = addr - aligned_addr; u32 i; @@ -409,20 +452,21 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, return; } - /* Write the first nibble byte by byte */ + /* Write the first dword (or portion) byte by byte */ if (unlikely(dif_len)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); - /* Start reading at aligned_addr + dif_len */ + /* Start writing at aligned_addr + dif_len */ for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++) _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf); aligned_addr += 4; } + /* Write all of the middle dwords as dwords, with auto-increment */ _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr); for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4) _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf); - /* Copy the last nibble */ + /* Write the last dword (or portion) byte by byte */ if (unlikely(num)) { _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr); for (i = 0; num > 0; i++, num--, buf++) @@ -430,17 +474,21 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, } } +/* General purpose, no alignment requirement, iterative (multi-byte) write, */ +/* for 1st 4K of SRAM/regs space */ static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, int num) { memcpy_toio((priv->hw_base + addr), buf, num); } +/* Set bit(s) in low 4K of SRAM/regs */ static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask) { ipw_write32(priv, reg, ipw_read32(priv, reg) | mask); } +/* Clear bit(s) in low 4K of SRAM/regs */ static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask) { ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); @@ -701,7 +749,7 @@ static void ipw_init_ordinals(struct ipw_priv *priv) } -u32 ipw_register_toggle(u32 reg) +static u32 ipw_register_toggle(u32 reg) { reg &= ~IPW_START_STANDBY; if (reg & IPW_GATE_ODMA) @@ -722,11 +770,11 @@ u32 ipw_register_toggle(u32 reg) * - On radio OFF, turn off any LEDs started during radio on * */ -#define LD_TIME_LINK_ON 300 -#define LD_TIME_LINK_OFF 2700 -#define LD_TIME_ACT_ON 250 +#define LD_TIME_LINK_ON msecs_to_jiffies(300) +#define LD_TIME_LINK_OFF msecs_to_jiffies(2700) +#define LD_TIME_ACT_ON msecs_to_jiffies(250) -void ipw_led_link_on(struct ipw_priv *priv) +static void ipw_led_link_on(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -764,12 +812,12 @@ void ipw_led_link_on(struct ipw_priv *priv) static void ipw_bg_led_link_on(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_led_link_on(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } -void ipw_led_link_off(struct ipw_priv *priv) +static void ipw_led_link_off(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -808,9 +856,9 @@ void ipw_led_link_off(struct ipw_priv *priv) static void ipw_bg_led_link_off(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_led_link_off(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static void __ipw_led_activity_on(struct ipw_priv *priv) @@ -847,6 +895,7 @@ static void __ipw_led_activity_on(struct ipw_priv *priv) } } +#if 0 void ipw_led_activity_on(struct ipw_priv *priv) { unsigned long flags; @@ -854,8 +903,9 @@ void ipw_led_activity_on(struct ipw_priv *priv) __ipw_led_activity_on(priv); spin_unlock_irqrestore(&priv->lock, flags); } +#endif /* 0 */ -void ipw_led_activity_off(struct ipw_priv *priv) +static void ipw_led_activity_off(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -885,12 +935,12 @@ void ipw_led_activity_off(struct ipw_priv *priv) static void ipw_bg_led_activity_off(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_led_activity_off(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } -void ipw_led_band_on(struct ipw_priv *priv) +static void ipw_led_band_on(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -925,7 +975,7 @@ void ipw_led_band_on(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -void ipw_led_band_off(struct ipw_priv *priv) +static void ipw_led_band_off(struct ipw_priv *priv) { unsigned long flags; u32 led; @@ -948,24 +998,24 @@ void ipw_led_band_off(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -void ipw_led_radio_on(struct ipw_priv *priv) +static void ipw_led_radio_on(struct ipw_priv *priv) { ipw_led_link_on(priv); } -void ipw_led_radio_off(struct ipw_priv *priv) +static void ipw_led_radio_off(struct ipw_priv *priv) { ipw_led_activity_off(priv); ipw_led_link_off(priv); } -void ipw_led_link_up(struct ipw_priv *priv) +static void ipw_led_link_up(struct ipw_priv *priv) { /* Set the Link Led on for all nic types */ ipw_led_link_on(priv); } -void ipw_led_link_down(struct ipw_priv *priv) +static void ipw_led_link_down(struct ipw_priv *priv) { ipw_led_activity_off(priv); ipw_led_link_off(priv); @@ -974,7 +1024,7 @@ void ipw_led_link_down(struct ipw_priv *priv) ipw_led_radio_off(priv); } -void ipw_led_init(struct ipw_priv *priv) +static void ipw_led_init(struct ipw_priv *priv) { priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE]; @@ -1025,7 +1075,7 @@ void ipw_led_init(struct ipw_priv *priv) } } -void ipw_led_shutdown(struct ipw_priv *priv) +static void ipw_led_shutdown(struct ipw_priv *priv) { ipw_led_activity_off(priv); ipw_led_link_off(priv); @@ -1074,6 +1124,7 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, static inline u32 ipw_get_event_log_len(struct ipw_priv *priv) { + /* length = 1st dword in log */ return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG)); } @@ -1870,7 +1921,8 @@ static char *get_cmd_string(u8 cmd) } #define HOST_COMPLETE_TIMEOUT HZ -static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) + +static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) { int rc = 0; unsigned long flags; @@ -1897,9 +1949,15 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n", get_cmd_string(cmd->cmd), cmd->cmd, cmd->len, priv->status); - printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); - rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); +#ifndef DEBUG_CMD_WEP_KEY + if (cmd->cmd == IPW_CMD_WEP_KEY) + IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n"); + else +#endif + printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); + + rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0); if (rc) { priv->status &= ~STATUS_HCMD_ACTIVE; IPW_ERROR("Failed to send %s: Reason %d\n", @@ -1942,61 +2000,62 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) return rc; } -static int ipw_send_host_complete(struct ipw_priv *priv) +static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command) { struct host_cmd cmd = { - .cmd = IPW_CMD_HOST_COMPLETE, - .len = 0 + .cmd = command, }; + return __ipw_send_cmd(priv, &cmd); +} + +static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len, + void *data) +{ + struct host_cmd cmd = { + .cmd = command, + .len = len, + .param = data, + }; + + return __ipw_send_cmd(priv, &cmd); +} + +static int ipw_send_host_complete(struct ipw_priv *priv) +{ if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE); } static int ipw_send_system_config(struct ipw_priv *priv, struct ipw_sys_config *config) { - struct host_cmd cmd = { - .cmd = IPW_CMD_SYSTEM_CONFIG, - .len = sizeof(*config) - }; - if (!priv || !config) { IPW_ERROR("Invalid args\n"); return -1; } - memcpy(cmd.param, config, sizeof(*config)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config), + config); } static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) { - struct host_cmd cmd = { - .cmd = IPW_CMD_SSID, - .len = min(len, IW_ESSID_MAX_SIZE) - }; - if (!priv || !ssid) { IPW_ERROR("Invalid args\n"); return -1; } - memcpy(cmd.param, ssid, cmd.len); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE), + ssid); } static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) { - struct host_cmd cmd = { - .cmd = IPW_CMD_ADAPTER_ADDRESS, - .len = ETH_ALEN - }; - if (!priv || !mac) { IPW_ERROR("Invalid args\n"); return -1; @@ -2005,8 +2064,7 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", priv->net_dev->name, MAC_ARG(mac)); - memcpy(cmd.param, mac, ETH_ALEN); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac); } /* @@ -2036,9 +2094,9 @@ static void ipw_adapter_restart(void *adapter) static void ipw_bg_adapter_restart(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_adapter_restart(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) @@ -2048,8 +2106,8 @@ static void ipw_scan_check(void *data) struct ipw_priv *priv = data; if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { IPW_DEBUG_SCAN("Scan completion watchdog resetting " - "adapter (%dms).\n", - IPW_SCAN_CHECK_WATCHDOG / 100); + "adapter after (%dms).\n", + jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); queue_work(priv->workqueue, &priv->adapter_restart); } } @@ -2057,59 +2115,48 @@ static void ipw_scan_check(void *data) static void ipw_bg_scan_check(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_scan_check(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static int ipw_send_scan_request_ext(struct ipw_priv *priv, struct ipw_scan_request_ext *request) { - struct host_cmd cmd = { - .cmd = IPW_CMD_SCAN_REQUEST_EXT, - .len = sizeof(*request) - }; - - memcpy(cmd.param, request, sizeof(*request)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT, + sizeof(*request), request); } static int ipw_send_scan_abort(struct ipw_priv *priv) { - struct host_cmd cmd = { - .cmd = IPW_CMD_SCAN_ABORT, - .len = 0 - }; - if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT); } static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) { - struct host_cmd cmd = { - .cmd = IPW_CMD_SENSITIVITY_CALIB, - .len = sizeof(struct ipw_sensitivity_calib) + struct ipw_sensitivity_calib calib = { + .beacon_rssi_raw = sens, }; - struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) - &cmd.param; - calib->beacon_rssi_raw = sens; - return ipw_send_cmd(priv, &cmd); + + return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib), + &calib); } static int ipw_send_associate(struct ipw_priv *priv, struct ipw_associate *associate) { - struct host_cmd cmd = { - .cmd = IPW_CMD_ASSOCIATE, - .len = sizeof(*associate) - }; - struct ipw_associate tmp_associate; + + if (!priv || !associate) { + IPW_ERROR("Invalid args\n"); + return -1; + } + memcpy(&tmp_associate, associate, sizeof(*associate)); tmp_associate.policy_support = cpu_to_le16(tmp_associate.policy_support); @@ -2122,80 +2169,55 @@ static int ipw_send_associate(struct ipw_priv *priv, cpu_to_le16(tmp_associate.beacon_interval); tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window); - if (!priv || !associate) { - IPW_ERROR("Invalid args\n"); - return -1; - } - - memcpy(cmd.param, &tmp_associate, sizeof(*associate)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate), + &tmp_associate); } static int ipw_send_supported_rates(struct ipw_priv *priv, struct ipw_supported_rates *rates) { - struct host_cmd cmd = { - .cmd = IPW_CMD_SUPPORTED_RATES, - .len = sizeof(*rates) - }; - if (!priv || !rates) { IPW_ERROR("Invalid args\n"); return -1; } - memcpy(cmd.param, rates, sizeof(*rates)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates), + rates); } static int ipw_set_random_seed(struct ipw_priv *priv) { - struct host_cmd cmd = { - .cmd = IPW_CMD_SEED_NUMBER, - .len = sizeof(u32) - }; + u32 val; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - get_random_bytes(&cmd.param, sizeof(u32)); + get_random_bytes(&val, sizeof(val)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val); } static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) { - struct host_cmd cmd = { - .cmd = IPW_CMD_CARD_DISABLE, - .len = sizeof(u32) - }; - if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - *((u32 *) & cmd.param) = phy_off; - - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off), + &phy_off); } static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) { - struct host_cmd cmd = { - .cmd = IPW_CMD_TX_POWER, - .len = sizeof(*power) - }; - if (!priv || !power) { IPW_ERROR("Invalid args\n"); return -1; } - memcpy(cmd.param, power, sizeof(*power)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power); } static int ipw_set_tx_power(struct ipw_priv *priv) @@ -2247,18 +2269,14 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) struct ipw_rts_threshold rts_threshold = { .rts_threshold = rts, }; - struct host_cmd cmd = { - .cmd = IPW_CMD_RTS_THRESHOLD, - .len = sizeof(rts_threshold) - }; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD, + sizeof(rts_threshold), &rts_threshold); } static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) @@ -2266,27 +2284,19 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) struct ipw_frag_threshold frag_threshold = { .frag_threshold = frag, }; - struct host_cmd cmd = { - .cmd = IPW_CMD_FRAG_THRESHOLD, - .len = sizeof(frag_threshold) - }; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD, + sizeof(frag_threshold), &frag_threshold); } static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) { - struct host_cmd cmd = { - .cmd = IPW_CMD_POWER_MODE, - .len = sizeof(u32) - }; - u32 *param = (u32 *) (&cmd.param); + u32 param; if (!priv) { IPW_ERROR("Invalid args\n"); @@ -2297,17 +2307,18 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) * level */ switch (mode) { case IPW_POWER_BATTERY: - *param = IPW_POWER_INDEX_3; + param = IPW_POWER_INDEX_3; break; case IPW_POWER_AC: - *param = IPW_POWER_MODE_CAM; + param = IPW_POWER_MODE_CAM; break; default: - *param = mode; + param = mode; break; } - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), + ¶m); } static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit) @@ -2316,18 +2327,14 @@ static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit) .short_retry_limit = slimit, .long_retry_limit = llimit }; - struct host_cmd cmd = { - .cmd = IPW_CMD_RETRY_LIMIT, - .len = sizeof(retry_limit) - }; if (!priv) { IPW_ERROR("Invalid args\n"); return -1; } - memcpy(cmd.param, &retry_limit, sizeof(retry_limit)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit), + &retry_limit); } /* @@ -2454,7 +2461,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv) /* If the data looks correct, then copy it to our private copy. Otherwise let the firmware know to perform the operation - on it's own + on its own. */ if ((priv->eeprom + EEPROM_VERSION) != 0) { IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); @@ -2707,22 +2714,25 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, static int ipw_fw_dma_wait(struct ipw_priv *priv) { - u32 current_index = 0; + u32 current_index = 0, previous_index; u32 watchdog = 0; IPW_DEBUG_FW(">> : \n"); current_index = ipw_fw_dma_command_block_index(priv); - IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", + IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n", (int)priv->sram_desc.last_cb_index); while (current_index < priv->sram_desc.last_cb_index) { udelay(50); + previous_index = current_index; current_index = ipw_fw_dma_command_block_index(priv); - watchdog++; - - if (watchdog > 400) { + if (previous_index < current_index) { + watchdog = 0; + continue; + } + if (++watchdog > 400) { IPW_DEBUG_FW_INFO("Timeout\n"); ipw_fw_dma_dump_command_block(priv); ipw_fw_dma_abort(priv); @@ -2772,6 +2782,7 @@ static inline int ipw_alive(struct ipw_priv *priv) return ipw_read32(priv, 0x90) == 0xd55555d5; } +/* timeout in msec, attempted in 10-msec quanta */ static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, int timeout) { @@ -2800,10 +2811,11 @@ static int ipw_stop_master(struct ipw_priv *priv) /* stop master. typical delay - 0 */ ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER); + /* timeout is in msec, polled in 10-msec quanta */ rc = ipw_poll_bit(priv, IPW_RESET_REG, IPW_RESET_REG_MASTER_DISABLED, 100); if (rc < 0) { - IPW_ERROR("stop master failed in 10ms\n"); + IPW_ERROR("wait for stop master failed after 100ms\n"); return -1; } @@ -2890,8 +2902,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) mdelay(1); /* enable ucode store */ - ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0); - ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS); + ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0); + ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS); mdelay(1); /* write ucode */ @@ -3036,7 +3048,7 @@ static int ipw_stop_nic(struct ipw_priv *priv) rc = ipw_poll_bit(priv, IPW_RESET_REG, IPW_RESET_REG_MASTER_DISABLED, 500); if (rc < 0) { - IPW_ERROR("wait for reg master disabled failed\n"); + IPW_ERROR("wait for reg master disabled failed after 500ms\n"); return rc; } @@ -3209,55 +3221,31 @@ static int ipw_load(struct ipw_priv *priv) const struct firmware *firmware = NULL; const struct firmware *ucode = NULL; #endif + char *ucode_name; + char *fw_name; int rc = 0, retries = 3; -#ifdef CONFIG_PM - if (!fw_loaded) { -#endif - rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); - if (rc) - goto error; - - switch (priv->ieee->iw_mode) { - case IW_MODE_ADHOC: - rc = ipw_get_fw(priv, &ucode, - IPW_FW_NAME("ibss_ucode")); - if (rc) - goto error; - - rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); - break; - + switch (priv->ieee->iw_mode) { + case IW_MODE_ADHOC: + ucode_name = IPW_FW_NAME("ibss_ucode"); + fw_name = IPW_FW_NAME("ibss"); + break; #ifdef CONFIG_IPW2200_MONITOR - case IW_MODE_MONITOR: - rc = ipw_get_fw(priv, &ucode, - IPW_FW_NAME("sniffer_ucode")); - if (rc) - goto error; - - rc = ipw_get_fw(priv, &firmware, - IPW_FW_NAME("sniffer")); - break; + case IW_MODE_MONITOR: + ucode_name = IPW_FW_NAME("sniffer_ucode"); + fw_name = IPW_FW_NAME("sniffer"); + break; #endif - case IW_MODE_INFRA: - rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode")); - if (rc) - goto error; - - rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss")); - break; - - default: - rc = -EINVAL; - } - - if (rc) - goto error; - -#ifdef CONFIG_PM - fw_loaded = 1; + case IW_MODE_INFRA: + ucode_name = IPW_FW_NAME("bss_ucode"); + fw_name = IPW_FW_NAME("bss"); + break; + default: + rc = -EINVAL; } -#endif + + if (rc < 0) + goto error; if (!priv->rxq) priv->rxq = ipw_rx_queue_alloc(priv); @@ -3279,7 +3267,7 @@ static int ipw_load(struct ipw_priv *priv) ipw_stop_nic(priv); rc = ipw_reset_nic(priv); - if (rc) { + if (rc < 0) { IPW_ERROR("Unable to reset NIC\n"); goto error; } @@ -3287,6 +3275,15 @@ static int ipw_load(struct ipw_priv *priv) ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND, IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); +#ifdef CONFIG_PM + if (!fw_loaded) { +#endif + rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); + if (rc < 0) + goto error; +#ifdef CONFIG_PM + } +#endif /* DMA the initial boot firmware into the device */ rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), bootfw->size - sizeof(struct fw_header)); @@ -3298,7 +3295,7 @@ static int ipw_load(struct ipw_priv *priv) /* kick start the device */ ipw_start_nic(priv); - /* wait for the device to finish it's initial startup sequence */ + /* wait for the device to finish its initial startup sequence */ rc = ipw_poll_bit(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500); if (rc < 0) { @@ -3310,6 +3307,16 @@ static int ipw_load(struct ipw_priv *priv) /* ack fw init done interrupt */ ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); +#ifdef CONFIG_PM + if (!fw_loaded) { +#endif + rc = ipw_get_fw(priv, &ucode, ucode_name); + if (rc < 0) + goto error; +#ifdef CONFIG_PM + } +#endif + /* DMA the ucode into the device */ rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), ucode->size - sizeof(struct fw_header)); @@ -3321,6 +3328,16 @@ static int ipw_load(struct ipw_priv *priv) /* stop nic */ ipw_stop_nic(priv); +#ifdef CONFIG_PM + if (!fw_loaded) { +#endif + rc = ipw_get_fw(priv, &firmware, fw_name); + if (rc < 0) + goto error; +#ifdef CONFIG_PM + } +#endif + /* DMA bss firmware into the device */ rc = ipw_load_firmware(priv, firmware->data + sizeof(struct fw_header), @@ -3329,11 +3346,14 @@ static int ipw_load(struct ipw_priv *priv) IPW_ERROR("Unable to load firmware: %d\n", rc); goto error; } +#ifdef CONFIG_PM + fw_loaded = 1; +#endif ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0); rc = ipw_queue_reset(priv); - if (rc) { + if (rc < 0) { IPW_ERROR("Unable to initialize queues\n"); goto error; } @@ -3362,7 +3382,7 @@ static int ipw_load(struct ipw_priv *priv) rc = ipw_poll_bit(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500); if (rc < 0) { - IPW_ERROR("device failed to start after 500ms\n"); + IPW_ERROR("device failed to start within 500ms\n"); goto error; } IPW_DEBUG_INFO("device response after %dms\n", rc); @@ -3715,9 +3735,9 @@ static int ipw_disassociate(void *data) static void ipw_bg_disassociate(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_disassociate(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static void ipw_system_config(void *data) @@ -4077,9 +4097,9 @@ static void ipw_gather_stats(struct ipw_priv *priv) static void ipw_bg_gather_stats(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_gather_stats(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } /* Missed beacon behavior: @@ -4121,8 +4141,9 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, return; } - if (missed_count > priv->roaming_threshold && - missed_count <= priv->disassociate_threshold) { + if (roaming && + (missed_count > priv->roaming_threshold && + missed_count <= priv->disassociate_threshold)) { /* If we are not already roaming, set the ROAM * bit in the status and kick off a scan. * This can happen several times before we reach @@ -4150,7 +4171,6 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, } IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count); - } /** @@ -4911,13 +4931,13 @@ static void ipw_rx_queue_replenish(void *data) static void ipw_bg_rx_queue_replenish(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_rx_queue_replenish(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } /* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have it's SKB set to NULL + * If an SKB has been detached, the POOL needs to have its SKB set to NULL * This free routine walks the list of POOL entries and if SKB is set to * non NULL it is unmapped and freed */ @@ -5257,10 +5277,11 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " - "because of age: %lums.\n", + "because of age: %ums.\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid), - 1000 * (jiffies - network->last_scanned) / HZ); + jiffies_to_msecs(jiffies - + network->last_scanned)); return 0; } @@ -5369,7 +5390,7 @@ static void ipw_merge_adhoc_network(void *data) return; } - down(&priv->sem); + mutex_lock(&priv->mutex); if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { IPW_DEBUG_MERGE("remove network %s\n", escape_essid(priv->essid, @@ -5379,7 +5400,7 @@ static void ipw_merge_adhoc_network(void *data) ipw_disassociate(priv); priv->assoc_network = match.network; - up(&priv->sem); + mutex_unlock(&priv->mutex); return; } } @@ -5467,11 +5488,12 @@ static int ipw_best_network(struct ipw_priv *priv, if (network->last_associate && time_after(network->last_associate + (HZ * 3UL), jiffies)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " - "because of storming (%lus since last " + "because of storming (%ums since last " "assoc attempt).\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid), - (jiffies - network->last_associate) / HZ); + jiffies_to_msecs(jiffies - + network->last_associate)); return 0; } @@ -5479,10 +5501,11 @@ static int ipw_best_network(struct ipw_priv *priv, if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " - "because of age: %lums.\n", + "because of age: %ums.\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid), - 1000 * (jiffies - network->last_scanned) / HZ); + jiffies_to_msecs(jiffies - + network->last_scanned)); return 0; } @@ -5671,54 +5694,44 @@ static void ipw_adhoc_create(struct ipw_priv *priv, static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index) { - struct ipw_tgi_tx_key *key; - struct host_cmd cmd = { - .cmd = IPW_CMD_TGI_TX_KEY, - .len = sizeof(*key) - }; + struct ipw_tgi_tx_key key; if (!(priv->ieee->sec.flags & (1 << index))) return; - key = (struct ipw_tgi_tx_key *)&cmd.param; - key->key_id = index; - memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH); - key->security_type = type; - key->station_index = 0; /* always 0 for BSS */ - key->flags = 0; + key.key_id = index; + memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH); + key.security_type = type; + key.station_index = 0; /* always 0 for BSS */ + key.flags = 0; /* 0 for new key; previous value of counter (after fatal error) */ - key->tx_counter[0] = 0; - key->tx_counter[1] = 0; + key.tx_counter[0] = 0; + key.tx_counter[1] = 0; - ipw_send_cmd(priv, &cmd); + ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key); } static void ipw_send_wep_keys(struct ipw_priv *priv, int type) { - struct ipw_wep_key *key; + struct ipw_wep_key key; int i; - struct host_cmd cmd = { - .cmd = IPW_CMD_WEP_KEY, - .len = sizeof(*key) - }; - key = (struct ipw_wep_key *)&cmd.param; - key->cmd_id = DINO_CMD_WEP_KEY; - key->seq_num = 0; + key.cmd_id = DINO_CMD_WEP_KEY; + key.seq_num = 0; /* Note: AES keys cannot be set for multiple times. * Only set it at the first time. */ for (i = 0; i < 4; i++) { - key->key_index = i | type; + key.key_index = i | type; if (!(priv->ieee->sec.flags & (1 << i))) { - key->key_size = 0; + key.key_size = 0; continue; } - key->key_size = priv->ieee->sec.key_sizes[i]; - memcpy(key->key, priv->ieee->sec.keys[i], key->key_size); + key.key_size = priv->ieee->sec.key_sizes[i]; + memcpy(key.key, priv->ieee->sec.keys[i], key.key_size); - ipw_send_cmd(priv, &cmd); + ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key); } } @@ -5822,9 +5835,9 @@ static void ipw_adhoc_check(void *data) static void ipw_bg_adhoc_check(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_adhoc_check(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } #ifdef CONFIG_IPW2200_DEBUG @@ -6051,7 +6064,7 @@ static int ipw_request_scan(struct ipw_priv *priv) (priv->status & STATUS_EXIT_PENDING)) return 0; - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->status & STATUS_SCANNING) { IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n"); @@ -6159,16 +6172,16 @@ static int ipw_request_scan(struct ipw_priv *priv) queue_delayed_work(priv->workqueue, &priv->scan_check, IPW_SCAN_CHECK_WATCHDOG); done: - up(&priv->sem); + mutex_unlock(&priv->mutex); return err; } static void ipw_bg_abort_scan(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_abort_scan(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static int ipw_wpa_enable(struct ipw_priv *priv, int value) @@ -6193,6 +6206,9 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) { sec.auth_mode = WLAN_AUTH_OPEN; ieee->open_wep = 1; + } else if (value & IW_AUTH_ALG_LEAP) { + sec.auth_mode = WLAN_AUTH_LEAP; + ieee->open_wep = 1; } else return -EINVAL; @@ -6204,7 +6220,8 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) return ret; } -void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len) +static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, + int wpa_ie_len) { /* make sure WPA is enabled */ ipw_wpa_enable(priv, 1); @@ -6215,15 +6232,10 @@ void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len) static int ipw_set_rsn_capa(struct ipw_priv *priv, char *capabilities, int length) { - struct host_cmd cmd = { - .cmd = IPW_CMD_RSN_CAPABILITIES, - .len = length, - }; - IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n"); - memcpy(cmd.param, capabilities, length); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length, + capabilities); } /* @@ -6244,7 +6256,7 @@ static int ipw_wx_set_genie(struct net_device *dev, (wrqu->data.length && extra == NULL)) return -EINVAL; - //down(&priv->sem); + //mutex_lock(&priv->mutex); //if (!ieee->wpa_enabled) { // err = -EOPNOTSUPP; @@ -6270,7 +6282,7 @@ static int ipw_wx_set_genie(struct net_device *dev, ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); out: - //up(&priv->sem); + //mutex_unlock(&priv->mutex); return err; } @@ -6283,7 +6295,7 @@ static int ipw_wx_get_genie(struct net_device *dev, struct ieee80211_device *ieee = priv->ieee; int err = 0; - //down(&priv->sem); + //mutex_lock(&priv->mutex); //if (!ieee->wpa_enabled) { // err = -EOPNOTSUPP; @@ -6304,7 +6316,7 @@ static int ipw_wx_get_genie(struct net_device *dev, memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); out: - //up(&priv->sem); + //mutex_unlock(&priv->mutex); return err; } @@ -6964,12 +6976,12 @@ static void ipw_bg_qos_activate(void *data) if (priv == NULL) return; - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->status & STATUS_ASSOCIATED) ipw_qos_activate(priv, &(priv->assoc_network->qos_data)); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static int ipw_handle_probe_response(struct net_device *dev, @@ -7010,25 +7022,15 @@ static int ipw_handle_assoc_response(struct net_device *dev, static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters *qos_param) { - struct host_cmd cmd = { - .cmd = IPW_CMD_QOS_PARAMETERS, - .len = (sizeof(struct ieee80211_qos_parameters) * 3) - }; - - memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS, + sizeof(*qos_param) * 3, qos_param); } static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element *qos_param) { - struct host_cmd cmd = { - .cmd = IPW_CMD_WME_INFO, - .len = sizeof(*qos_param) - }; - - memcpy(cmd.param, qos_param, sizeof(*qos_param)); - return ipw_send_cmd(priv, &cmd); + return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param), + qos_param); } #endif /* CONFIG_IPW_QOS */ @@ -7052,19 +7054,22 @@ static int ipw_associate_network(struct ipw_priv *priv, memset(&priv->assoc_request, 0, sizeof(priv->assoc_request)); priv->assoc_request.channel = network->channel; + priv->assoc_request.auth_key = 0; + if ((priv->capability & CAP_PRIVACY_ON) && - (priv->capability & CAP_SHARED_KEY)) { + (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) { priv->assoc_request.auth_type = AUTH_SHARED_KEY; priv->assoc_request.auth_key = priv->ieee->sec.active_key; - if ((priv->capability & CAP_PRIVACY_ON) && - (priv->ieee->sec.level == SEC_LEVEL_1) && + if ((priv->ieee->sec.level == SEC_LEVEL_1) && !(priv->ieee->host_encrypt || priv->ieee->host_decrypt)) ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP); - } else { + + } else if ((priv->capability & CAP_PRIVACY_ON) && + (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP)) + priv->assoc_request.auth_type = AUTH_LEAP; + else priv->assoc_request.auth_type = AUTH_OPEN; - priv->assoc_request.auth_key = 0; - } if (priv->ieee->wpa_ie_len) { priv->assoc_request.policy_support = 0x02; /* RSN active */ @@ -7278,9 +7283,9 @@ static void ipw_roam(void *data) static void ipw_bg_roam(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_roam(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static int ipw_associate(void *data) @@ -7375,9 +7380,9 @@ static int ipw_associate(void *data) static void ipw_bg_associate(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_associate(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv, @@ -8126,7 +8131,7 @@ static int ipw_wx_get_name(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->status & STATUS_RF_KILL_MASK) strcpy(wrqu->name, "radio off"); else if (!(priv->status & STATUS_ASSOCIATED)) @@ -8135,7 +8140,7 @@ static int ipw_wx_get_name(struct net_device *dev, snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", ipw_modes[priv->assoc_request.ieee_mode]); IPW_DEBUG_WX("Name: %s\n", wrqu->name); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8204,9 +8209,9 @@ static int ipw_wx_set_freq(struct net_device *dev, if (fwrq->m == 0) { IPW_DEBUG_WX("SET Freq/Channel -> any\n"); - down(&priv->sem); + mutex_lock(&priv->mutex); ret = ipw_set_channel(priv, 0); - up(&priv->sem); + mutex_unlock(&priv->mutex); return ret; } /* if setting by freq convert to channel */ @@ -8234,9 +8239,9 @@ static int ipw_wx_set_freq(struct net_device *dev, } IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); - down(&priv->sem); + mutex_lock(&priv->mutex); ret = ipw_set_channel(priv, channel); - up(&priv->sem); + mutex_unlock(&priv->mutex); return ret; } @@ -8250,14 +8255,14 @@ static int ipw_wx_get_freq(struct net_device *dev, /* If we are associated, trying to associate, or have a statically * configured CHANNEL then return that; otherwise return ANY */ - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->config & CFG_STATIC_CHANNEL || priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) wrqu->freq.m = priv->channel; else wrqu->freq.m = 0; - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); return 0; } @@ -8287,7 +8292,7 @@ static int ipw_wx_set_mode(struct net_device *dev, if (wrqu->mode == priv->ieee->iw_mode) return 0; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_sw_reset(priv, 0); @@ -8310,7 +8315,7 @@ static int ipw_wx_set_mode(struct net_device *dev, priv->ieee->iw_mode = wrqu->mode; queue_work(priv->workqueue, &priv->adapter_restart); - up(&priv->sem); + mutex_unlock(&priv->mutex); return err; } @@ -8319,10 +8324,10 @@ static int ipw_wx_get_mode(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->mode = priv->ieee->iw_mode; IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8369,7 +8374,7 @@ static int ipw_wx_get_range(struct net_device *dev, range->avg_qual.level = 0; /* FIXME to real average level */ range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ - down(&priv->sem); + mutex_lock(&priv->mutex); range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); for (i = 0; i < range->num_bitrates; i++) @@ -8387,7 +8392,7 @@ static int ipw_wx_get_range(struct net_device *dev, /* Set the Wireless Extension versions */ range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 16; + range->we_version_source = 18; i = 0; if (priv->ieee->mode & (IEEE_B | IEEE_G)) { @@ -8411,7 +8416,7 @@ static int ipw_wx_get_range(struct net_device *dev, range->num_channels = i; range->num_frequency = i; - up(&priv->sem); + mutex_unlock(&priv->mutex); /* Event capability (kernel + driver) */ range->event_capa[0] = (IW_EVENT_CAPA_K_0 | @@ -8419,6 +8424,9 @@ static int ipw_wx_get_range(struct net_device *dev, IW_EVENT_CAPA_MASK(SIOCGIWAP)); range->event_capa[1] = IW_EVENT_CAPA_K_1; + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + IPW_DEBUG_WX("GET Range\n"); return 0; } @@ -8438,7 +8446,7 @@ static int ipw_wx_set_wap(struct net_device *dev, if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) return -EINVAL; - down(&priv->sem); + mutex_lock(&priv->mutex); if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { /* we disable mandatory BSSID association */ @@ -8447,14 +8455,14 @@ static int ipw_wx_set_wap(struct net_device *dev, IPW_DEBUG_ASSOC("Attempting to associate with new " "parameters.\n"); ipw_associate(priv); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } priv->config |= CFG_STATIC_BSSID; if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { IPW_DEBUG_WX("BSSID set to current BSSID.\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8468,7 +8476,7 @@ static int ipw_wx_set_wap(struct net_device *dev, if (!ipw_disassociate(priv)) ipw_associate(priv); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8479,7 +8487,7 @@ static int ipw_wx_get_wap(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); /* If we are associated, trying to associate, or have a statically * configured BSSID then return that; otherwise return ANY */ - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->config & CFG_STATIC_BSSID || priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { wrqu->ap_addr.sa_family = ARPHRD_ETHER; @@ -8489,7 +8497,7 @@ static int ipw_wx_get_wap(struct net_device *dev, IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", MAC_ARG(wrqu->ap_addr.sa_data)); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8500,7 +8508,7 @@ static int ipw_wx_set_essid(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); char *essid = ""; /* ANY */ int length = 0; - down(&priv->sem); + mutex_lock(&priv->mutex); if (wrqu->essid.flags && wrqu->essid.length) { length = wrqu->essid.length - 1; essid = extra; @@ -8515,7 +8523,7 @@ static int ipw_wx_set_essid(struct net_device *dev, priv->config &= ~CFG_STATIC_ESSID; ipw_associate(priv); } - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8525,7 +8533,7 @@ static int ipw_wx_set_essid(struct net_device *dev, if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { IPW_DEBUG_WX("ESSID set to current ESSID.\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8540,7 +8548,7 @@ static int ipw_wx_set_essid(struct net_device *dev, if (!ipw_disassociate(priv)) ipw_associate(priv); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8552,7 +8560,7 @@ static int ipw_wx_get_essid(struct net_device *dev, /* If we are associated, trying to associate, or have a statically * configured ESSID then return that; otherwise return ANY */ - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->config & CFG_STATIC_ESSID || priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { IPW_DEBUG_WX("Getting essid: '%s'\n", @@ -8565,7 +8573,7 @@ static int ipw_wx_get_essid(struct net_device *dev, wrqu->essid.length = 0; wrqu->essid.flags = 0; /* active */ } - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8578,12 +8586,12 @@ static int ipw_wx_set_nick(struct net_device *dev, IPW_DEBUG_WX("Setting nick to '%s'\n", extra); if (wrqu->data.length > IW_ESSID_MAX_SIZE) return -E2BIG; - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); memset(priv->nick, 0, sizeof(priv->nick)); memcpy(priv->nick, extra, wrqu->data.length); IPW_DEBUG_TRACE("<<\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8594,11 +8602,11 @@ static int ipw_wx_get_nick(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_WX("Getting nick\n"); - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->data.length = strlen(priv->nick) + 1; memcpy(extra, priv->nick, wrqu->data.length); wrqu->data.flags = 1; /* active */ - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8691,7 +8699,7 @@ static int ipw_wx_set_rate(struct net_device *dev, apply: IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n", mask, fixed ? "fixed" : "sub-rates"); - down(&priv->sem); + mutex_lock(&priv->mutex); if (mask == IEEE80211_DEFAULT_RATES_MASK) { priv->config &= ~CFG_FIXED_RATE; ipw_set_fixed_rate(priv, priv->ieee->mode); @@ -8700,7 +8708,7 @@ static int ipw_wx_set_rate(struct net_device *dev, if (priv->rates_mask == mask) { IPW_DEBUG_WX("Mask set to current mask.\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8711,7 +8719,7 @@ static int ipw_wx_set_rate(struct net_device *dev, if (!ipw_disassociate(priv)) ipw_associate(priv); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -8720,9 +8728,9 @@ static int ipw_wx_get_rate(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->bitrate.value = priv->last_rate; - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); return 0; } @@ -8732,20 +8740,20 @@ static int ipw_wx_set_rts(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); if (wrqu->rts.disabled) priv->rts_threshold = DEFAULT_RTS_THRESHOLD; else { if (wrqu->rts.value < MIN_RTS_THRESHOLD || wrqu->rts.value > MAX_RTS_THRESHOLD) { - up(&priv->sem); + mutex_unlock(&priv->mutex); return -EINVAL; } priv->rts_threshold = wrqu->rts.value; } ipw_send_rts_threshold(priv, priv->rts_threshold); - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); return 0; } @@ -8755,11 +8763,11 @@ static int ipw_wx_get_rts(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->rts.value = priv->rts_threshold; wrqu->rts.fixed = 0; /* no auto select */ wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); return 0; } @@ -8771,7 +8779,7 @@ static int ipw_wx_set_txpow(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); int err = 0; - down(&priv->sem); + mutex_lock(&priv->mutex); if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) { err = -EINPROGRESS; goto out; @@ -8794,7 +8802,7 @@ static int ipw_wx_set_txpow(struct net_device *dev, priv->tx_power = wrqu->power.value; err = ipw_set_tx_power(priv); out: - up(&priv->sem); + mutex_unlock(&priv->mutex); return err; } @@ -8803,12 +8811,12 @@ static int ipw_wx_get_txpow(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->power.value = priv->tx_power; wrqu->power.fixed = 1; wrqu->power.flags = IW_TXPOW_DBM; wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("GET TX Power -> %s %d \n", wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); @@ -8821,13 +8829,13 @@ static int ipw_wx_set_frag(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); if (wrqu->frag.disabled) priv->ieee->fts = DEFAULT_FTS; else { if (wrqu->frag.value < MIN_FRAG_THRESHOLD || wrqu->frag.value > MAX_FRAG_THRESHOLD) { - up(&priv->sem); + mutex_unlock(&priv->mutex); return -EINVAL; } @@ -8835,7 +8843,7 @@ static int ipw_wx_set_frag(struct net_device *dev, } ipw_send_frag_threshold(priv, wrqu->frag.value); - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); return 0; } @@ -8845,11 +8853,11 @@ static int ipw_wx_get_frag(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->frag.value = priv->ieee->fts; wrqu->frag.fixed = 0; /* no auto select */ wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); return 0; @@ -8870,7 +8878,7 @@ static int ipw_wx_set_retry(struct net_device *dev, if (wrqu->retry.value < 0 || wrqu->retry.value > 255) return -EINVAL; - down(&priv->sem); + mutex_lock(&priv->mutex); if (wrqu->retry.flags & IW_RETRY_MIN) priv->short_retry_limit = (u8) wrqu->retry.value; else if (wrqu->retry.flags & IW_RETRY_MAX) @@ -8882,7 +8890,7 @@ static int ipw_wx_set_retry(struct net_device *dev, ipw_send_retry_limit(priv, priv->short_retry_limit, priv->long_retry_limit); - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n", priv->short_retry_limit, priv->long_retry_limit); return 0; @@ -8894,11 +8902,11 @@ static int ipw_wx_get_retry(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); wrqu->retry.disabled = 0; if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { - up(&priv->sem); + mutex_unlock(&priv->mutex); return -EINVAL; } @@ -8912,7 +8920,7 @@ static int ipw_wx_get_retry(struct net_device *dev, wrqu->retry.flags = IW_RETRY_LIMIT; wrqu->retry.value = priv->short_retry_limit; } - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value); @@ -8929,7 +8937,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, (priv->status & STATUS_EXIT_PENDING)) return 0; - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->status & STATUS_RF_KILL_MASK) { IPW_DEBUG_HC("Aborting scan due to RF kill activation\n"); @@ -8981,7 +8989,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, priv->status |= STATUS_SCANNING; done: - up(&priv->sem); + mutex_unlock(&priv->mutex); return err; } @@ -9024,7 +9032,7 @@ static int ipw_wx_set_encode(struct net_device *dev, int ret; u32 cap = priv->capability; - down(&priv->sem); + mutex_lock(&priv->mutex); ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); /* In IBSS mode, we need to notify the firmware to update @@ -9034,7 +9042,7 @@ static int ipw_wx_set_encode(struct net_device *dev, priv->status & STATUS_ASSOCIATED) ipw_disassociate(priv); - up(&priv->sem); + mutex_unlock(&priv->mutex); return ret; } @@ -9052,17 +9060,17 @@ static int ipw_wx_set_power(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); int err; - down(&priv->sem); + mutex_lock(&priv->mutex); if (wrqu->power.disabled) { priv->power_mode = IPW_POWER_LEVEL(priv->power_mode); err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM); if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return err; } IPW_DEBUG_WX("SET Power Management Mode -> off\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9074,7 +9082,7 @@ static int ipw_wx_set_power(struct net_device *dev, default: /* Otherwise we don't support it */ IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", wrqu->power.flags); - up(&priv->sem); + mutex_unlock(&priv->mutex); return -EOPNOTSUPP; } @@ -9087,12 +9095,12 @@ static int ipw_wx_set_power(struct net_device *dev, err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return err; } IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9101,13 +9109,13 @@ static int ipw_wx_get_power(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); if (!(priv->power_mode & IPW_POWER_ENABLED)) wrqu->power.disabled = 1; else wrqu->power.disabled = 0; - up(&priv->sem); + mutex_unlock(&priv->mutex); IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); return 0; @@ -9120,7 +9128,7 @@ static int ipw_wx_set_powermode(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); int mode = *(int *)extra; int err; - down(&priv->sem); + mutex_lock(&priv->mutex); if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { mode = IPW_POWER_AC; priv->power_mode = mode; @@ -9133,11 +9141,11 @@ static int ipw_wx_set_powermode(struct net_device *dev, if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return err; } } - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9186,7 +9194,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); return -EINVAL; } - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->adapter == IPW_2915ABG) { priv->ieee->abg_true = 1; if (mode & IEEE_A) { @@ -9198,7 +9206,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, if (mode & IEEE_A) { IPW_WARNING("Attempt to set 2200BG into " "802.11a mode\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return -EINVAL; } @@ -9235,7 +9243,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", mode & IEEE_A ? 'a' : '.', mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9244,7 +9252,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); switch (priv->ieee->mode) { case IEEE_A: strncpy(extra, "802.11a (1)", MAX_WX_STRING); @@ -9275,7 +9283,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); wrqu->data.length = strlen(extra) + 1; - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9286,7 +9294,7 @@ static int ipw_wx_set_preamble(struct net_device *dev, { struct ipw_priv *priv = ieee80211_priv(dev); int mode = *(int *)extra; - down(&priv->sem); + mutex_lock(&priv->mutex); /* Switching from SHORT -> LONG requires a disassociation */ if (mode == 1) { if (!(priv->config & CFG_PREAMBLE_LONG)) { @@ -9305,11 +9313,11 @@ static int ipw_wx_set_preamble(struct net_device *dev, priv->config &= ~CFG_PREAMBLE_LONG; goto done; } - up(&priv->sem); + mutex_unlock(&priv->mutex); return -EINVAL; done: - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9318,12 +9326,12 @@ static int ipw_wx_get_preamble(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); if (priv->config & CFG_PREAMBLE_LONG) snprintf(wrqu->name, IFNAMSIZ, "long (1)"); else snprintf(wrqu->name, IFNAMSIZ, "auto (0)"); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9335,7 +9343,7 @@ static int ipw_wx_set_monitor(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); int *parms = (int *)extra; int enable = (parms[0] > 0); - down(&priv->sem); + mutex_lock(&priv->mutex); IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]); if (enable) { if (priv->ieee->iw_mode != IW_MODE_MONITOR) { @@ -9350,13 +9358,13 @@ static int ipw_wx_set_monitor(struct net_device *dev, ipw_set_channel(priv, parms[1]); } else { if (priv->ieee->iw_mode != IW_MODE_MONITOR) { - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } priv->net_dev->type = ARPHRD_ETHER; queue_work(priv->workqueue, &priv->adapter_restart); } - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9386,7 +9394,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, IPW_DEBUG_WX("SW_RESET\n"); - down(&priv->sem); + mutex_lock(&priv->mutex); ret = ipw_sw_reset(priv, 0); if (!ret) { @@ -9398,9 +9406,9 @@ static int ipw_wx_sw_reset(struct net_device *dev, * module parameter, so take appropriate action */ ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW); - up(&priv->sem); + mutex_unlock(&priv->mutex); ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL); - down(&priv->sem); + mutex_lock(&priv->mutex); if (!(priv->status & STATUS_RF_KILL_MASK)) { /* Configuration likely changed -- force [re]association */ @@ -9410,7 +9418,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, ipw_associate(priv); } - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9586,7 +9594,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev) static void init_sys_config(struct ipw_sys_config *sys_config) { memset(sys_config, 0, sizeof(struct ipw_sys_config)); - sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */ + sys_config->bt_coexistence = 0; sys_config->answer_broadcast_ssid_probe = 0; sys_config->accept_all_data_frames = 0; sys_config->accept_non_directed_frames = 1; @@ -9607,11 +9615,11 @@ static int ipw_net_open(struct net_device *dev) struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_INFO("dev->open\n"); /* we should be verifying the device is ready to be opened */ - down(&priv->sem); + mutex_lock(&priv->mutex); if (!(priv->status & STATUS_RF_KILL_MASK) && (priv->status & STATUS_ASSOCIATED)) netif_start_queue(dev); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9890,13 +9898,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p) struct sockaddr *addr = p; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - down(&priv->sem); + mutex_lock(&priv->mutex); priv->config |= CFG_CUSTOM_MAC; memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", priv->net_dev->name, MAC_ARG(priv->mac_addr)); queue_work(priv->workqueue, &priv->adapter_restart); - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -9940,9 +9948,9 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev, if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE) return -EINVAL; - down(&p->sem); + mutex_lock(&p->mutex); memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len); - up(&p->sem); + mutex_unlock(&p->mutex); return 0; } @@ -9954,12 +9962,12 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev, if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE) return -EINVAL; - down(&p->sem); + mutex_lock(&p->mutex); memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); for (i = IPW_EEPROM_DATA; i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++) ipw_write8(p, i, p->eeprom[i]); - up(&p->sem); + mutex_unlock(&p->mutex); return 0; } @@ -10054,12 +10062,12 @@ static void ipw_rf_kill(void *adapter) static void ipw_bg_rf_kill(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_rf_kill(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } -void ipw_link_up(struct ipw_priv *priv) +static void ipw_link_up(struct ipw_priv *priv) { priv->last_seq_num = -1; priv->last_frag_num = -1; @@ -10089,12 +10097,12 @@ void ipw_link_up(struct ipw_priv *priv) static void ipw_bg_link_up(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_link_up(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } -void ipw_link_down(struct ipw_priv *priv) +static void ipw_link_down(struct ipw_priv *priv) { ipw_led_link_down(priv); netif_carrier_off(priv->net_dev); @@ -10117,9 +10125,9 @@ void ipw_link_down(struct ipw_priv *priv) static void ipw_bg_link_down(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_link_down(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static int ipw_setup_deferred_work(struct ipw_priv *priv) @@ -10292,6 +10300,20 @@ static int ipw_config(struct ipw_priv *priv) /* set basic system config settings */ init_sys_config(&priv->sys_config); + + /* Support Bluetooth if we have BT h/w on board, and user wants to. + * Does not support BT priority yet (don't abort or defer our Tx) */ + if (bt_coexist) { + unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY]; + + if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG) + priv->sys_config.bt_coexistence + |= CFG_BT_COEXISTENCE_SIGNAL_CHNL; + if (bt_caps & EEPROM_SKU_CAP_BT_OOB) + priv->sys_config.bt_coexistence + |= CFG_BT_COEXISTENCE_OOB; + } + if (priv->ieee->iw_mode == IW_MODE_ADHOC) priv->sys_config.answer_broadcast_ssid_probe = 1; else @@ -10782,9 +10804,9 @@ static int ipw_up(struct ipw_priv *priv) static void ipw_bg_up(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_up(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } static void ipw_deinit(struct ipw_priv *priv) @@ -10853,23 +10875,23 @@ static void ipw_down(struct ipw_priv *priv) static void ipw_bg_down(void *data) { struct ipw_priv *priv = data; - down(&priv->sem); + mutex_lock(&priv->mutex); ipw_down(data); - up(&priv->sem); + mutex_unlock(&priv->mutex); } /* Called by register_netdev() */ static int ipw_net_init(struct net_device *dev) { struct ipw_priv *priv = ieee80211_priv(dev); - down(&priv->sem); + mutex_lock(&priv->mutex); if (ipw_up(priv)) { - up(&priv->sem); + mutex_unlock(&priv->mutex); return -EIO; } - up(&priv->sem); + mutex_unlock(&priv->mutex); return 0; } @@ -10959,7 +10981,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); - init_MUTEX(&priv->sem); + mutex_init(&priv->mutex); if (pci_enable_device(pdev)) { err = -ENODEV; goto out_free_ieee80211; @@ -11017,7 +11039,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) SET_MODULE_OWNER(net_dev); SET_NETDEV_DEV(net_dev, &pdev->dev); - down(&priv->sem); + mutex_lock(&priv->mutex); priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; priv->ieee->set_security = shim__set_security; @@ -11050,11 +11072,11 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); if (err) { IPW_ERROR("failed to create sysfs device attributes\n"); - up(&priv->sem); + mutex_unlock(&priv->mutex); goto out_release_irq; } - up(&priv->sem); + mutex_unlock(&priv->mutex); err = register_netdev(net_dev); if (err) { IPW_ERROR("failed to register network device\n"); @@ -11091,13 +11113,13 @@ static void ipw_pci_remove(struct pci_dev *pdev) if (!priv) return; - down(&priv->sem); + mutex_lock(&priv->mutex); priv->status |= STATUS_EXIT_PENDING; ipw_down(priv); sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); - up(&priv->sem); + mutex_unlock(&priv->mutex); unregister_netdev(priv->net_dev); @@ -11281,12 +11303,18 @@ module_param(mode, int, 0444); MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); #endif +module_param(bt_coexist, int, 0444); +MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)"); + module_param(hwcrypto, int, 0444); -MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)"); +MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)"); module_param(cmdlog, int, 0444); MODULE_PARM_DESC(cmdlog, "allocate a ring buffer for logging firmware commands"); +module_param(roaming, int, 0444); +MODULE_PARM_DESC(roaming, "enable roaming support (default on)"); + module_exit(ipw_exit); module_init(ipw_init); diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index e65620a4d79..5405ba105ab 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h @@ -33,6 +33,7 @@ #include <linux/moduleparam.h> #include <linux/config.h> #include <linux/init.h> +#include <linux/mutex.h> #include <linux/pci.h> #include <linux/netdevice.h> @@ -46,6 +47,7 @@ #include <linux/firmware.h> #include <linux/wireless.h> #include <linux/dma-mapping.h> +#include <linux/jiffies.h> #include <asm/io.h> #include <net/ieee80211.h> @@ -852,7 +854,7 @@ struct ipw_scan_request_ext { u16 dwell_time[IPW_SCAN_TYPES]; } __attribute__ ((packed)); -extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) +static inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) { if (index % 2) return scan->scan_type[index / 2] & 0x0F; @@ -860,7 +862,7 @@ extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) return (scan->scan_type[index / 2] & 0xF0) >> 4; } -extern inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan, +static inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan, u8 index, u8 scan_type) { if (index % 2) @@ -1120,7 +1122,7 @@ struct ipw_priv { struct ieee80211_device *ieee; spinlock_t lock; - struct semaphore sem; + struct mutex mutex; /* basic pci-network driver stuff */ struct pci_dev *pci_dev; @@ -1406,13 +1408,6 @@ do { if (ipw_debug_level & (level)) \ * Register bit definitions */ -/* Dino control registers bits */ - -#define DINO_ENABLE_SYSTEM 0x80 -#define DINO_ENABLE_CS 0x40 -#define DINO_RXFIFO_DATA 0x01 -#define DINO_CONTROL_REG 0x00200000 - #define IPW_INTA_RW 0x00000008 #define IPW_INTA_MASK_R 0x0000000C #define IPW_INDIRECT_ADDR 0x00000010 @@ -1459,6 +1454,11 @@ do { if (ipw_debug_level & (level)) \ #define IPW_DOMAIN_0_END 0x1000 #define CLX_MEM_BAR_SIZE 0x1000 +/* Dino/baseband control registers bits */ + +#define DINO_ENABLE_SYSTEM 0x80 /* 1 = baseband processor on, 0 = reset */ +#define DINO_ENABLE_CS 0x40 /* 1 = enable ucode load */ +#define DINO_RXFIFO_DATA 0x01 /* 1 = data available */ #define IPW_BASEBAND_CONTROL_STATUS 0X00200000 #define IPW_BASEBAND_TX_FIFO_WRITE 0X00200004 #define IPW_BASEBAND_RX_FIFO_READ 0X00200004 @@ -1567,13 +1567,18 @@ do { if (ipw_debug_level & (level)) \ #define EEPROM_BSS_CHANNELS_BG (GET_EEPROM_ADDR(0x2c,LSB)) /* 2 bytes */ #define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ -/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ +/* NIC type as found in the one byte EEPROM_NIC_TYPE offset */ #define EEPROM_NIC_TYPE_0 0 #define EEPROM_NIC_TYPE_1 1 #define EEPROM_NIC_TYPE_2 2 #define EEPROM_NIC_TYPE_3 3 #define EEPROM_NIC_TYPE_4 4 +/* Bluetooth Coexistence capabilities as found in EEPROM_SKU_CAPABILITY */ +#define EEPROM_SKU_CAP_BT_CHANNEL_SIG 0x01 /* we can tell BT our channel # */ +#define EEPROM_SKU_CAP_BT_PRIORITY 0x02 /* BT can take priority over us */ +#define EEPROM_SKU_CAP_BT_OOB 0x04 /* we can signal BT out-of-band */ + #define FW_MEM_REG_LOWER_BOUND 0x00300000 #define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) #define IPW_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04) @@ -1658,9 +1663,10 @@ enum { IPW_FW_ERROR_FATAL_ERROR }; -#define AUTH_OPEN 0 -#define AUTH_SHARED_KEY 1 -#define AUTH_IGNORE 3 +#define AUTH_OPEN 0 +#define AUTH_SHARED_KEY 1 +#define AUTH_LEAP 2 +#define AUTH_IGNORE 3 #define HC_ASSOCIATE 0 #define HC_REASSOCIATE 1 @@ -1860,7 +1866,7 @@ struct host_cmd { u8 cmd; u8 len; u16 reserved; - u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; + u32 *param; } __attribute__ ((packed)); struct ipw_cmd_log { @@ -1869,21 +1875,23 @@ struct ipw_cmd_log { struct host_cmd cmd; }; -#define CFG_BT_COEXISTENCE_MIN 0x00 -#define CFG_BT_COEXISTENCE_DEFER 0x02 -#define CFG_BT_COEXISTENCE_KILL 0x04 -#define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08 -#define CFG_BT_COEXISTENCE_OOB 0x10 -#define CFG_BT_COEXISTENCE_MAX 0xFF -#define CFG_BT_COEXISTENCE_DEF 0x80 /* read Bt from EEPROM */ - -#define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x0 -#define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x1 +/* SysConfig command parameters ... */ +/* bt_coexistence param */ +#define CFG_BT_COEXISTENCE_SIGNAL_CHNL 0x01 /* tell BT our chnl # */ +#define CFG_BT_COEXISTENCE_DEFER 0x02 /* defer our Tx if BT traffic */ +#define CFG_BT_COEXISTENCE_KILL 0x04 /* kill our Tx if BT traffic */ +#define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08 /* multimedia extensions */ +#define CFG_BT_COEXISTENCE_OOB 0x10 /* signal BT via out-of-band */ + +/* clear-to-send to self param */ +#define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x00 +#define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x01 #define CFG_CTS_TO_ITSELF_ENABLED_DEF CFG_CTS_TO_ITSELF_ENABLED_MIN -#define CFG_SYS_ANTENNA_BOTH 0x000 -#define CFG_SYS_ANTENNA_A 0x001 -#define CFG_SYS_ANTENNA_B 0x003 +/* Antenna diversity param (h/w can select best antenna, based on signal) */ +#define CFG_SYS_ANTENNA_BOTH 0x00 /* NIC selects best antenna */ +#define CFG_SYS_ANTENNA_A 0x01 /* force antenna A */ +#define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ /* * The definitions below were lifted off the ipw2100 driver, which only diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index bf6271ee387..75ce6ddb0cf 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -55,10 +55,8 @@ #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/bitops.h> -#ifdef CONFIG_NET_RADIO #include <linux/wireless.h> #include <net/iw_handler.h> -#endif #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h index 166e28b9a4f..5cb0bc8bb12 100644 --- a/drivers/net/wireless/wavelan.p.h +++ b/drivers/net/wireless/wavelan.p.h @@ -98,11 +98,7 @@ * characteristics of the hardware. Applications such as mobile IP may * take advantage of it. * - * You will need to enable the CONFIG_NET_RADIO define in the kernel - * configuration to enable the wireless extensions (this is the one - * giving access to the radio network device choice). - * - * It might also be a good idea as well to fetch the wireless tools to + * It might be a good idea as well to fetch the wireless tools to * configure the device and play a bit. */ diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h index f2d59756815..451f6271dcb 100644 --- a/drivers/net/wireless/wavelan_cs.p.h +++ b/drivers/net/wireless/wavelan_cs.p.h @@ -99,11 +99,7 @@ * caracteristics of the hardware in a standard way and support for * applications for taking advantage of it (like Mobile IP). * - * You will need to enable the CONFIG_NET_RADIO define in the kernel - * configuration to enable the wireless extensions (this is the one - * giving access to the radio network device choice). - * - * It might also be a good idea as well to fetch the wireless tools to + * It might be a good idea as well to fetch the wireless tools to * configure the device and play a bit. */ @@ -440,11 +436,8 @@ #include <linux/ioport.h> #include <linux/fcntl.h> #include <linux/ethtool.h> - -#ifdef CONFIG_NET_RADIO #include <linux/wireless.h> /* Wireless extensions */ #include <net/iw_handler.h> /* New driver API */ -#endif /* Pcmcia headers that we need */ #include <pcmcia/cs_types.h> |