aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/airo.c152
-rw-r--r--drivers/net/wireless/atmel_cs.c1
-rw-r--r--drivers/net/wireless/orinoco.c332
-rw-r--r--drivers/net/wireless/orinoco.h1
-rw-r--r--drivers/net/wireless/strip.c2
6 files changed, 177 insertions, 313 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 0aaa12c0c09..1d3231cc471 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -323,7 +323,7 @@ config PRISM54
For a complete list of supported cards visit <http://prism54.org>.
Here is the latest confirmed list of supported cards:
- 3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72
+ 3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 (version 1)
Allnet ALL0271 PCI Card
Compex WL54G Cardbus Card
Corega CG-WLCB54GT Cardbus Card
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 463c789cdc7..d72e0385e4f 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -754,7 +754,7 @@ typedef struct {
u8 zero;
u8 ssidLen;
u8 ssid[32];
- u16 rssi;
+ u16 dBm;
#define CAP_ESS (1<<0)
#define CAP_IBSS (1<<1)
#define CAP_PRIVACY (1<<4)
@@ -1125,6 +1125,9 @@ static int micsetup(struct airo_info *ai);
static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
+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
@@ -1713,6 +1716,7 @@ static int readBSSListRid(struct airo_info *ai, int first,
list->fh.dwell = le16_to_cpu(list->fh.dwell);
list->dsChannel = le16_to_cpu(list->dsChannel);
list->atimWindow = le16_to_cpu(list->atimWindow);
+ list->dBm = le16_to_cpu(list->dBm);
return rc;
}
@@ -2914,7 +2918,7 @@ static int airo_thread(void *data) {
flush_signals(current);
/* make swsusp happy with our thread */
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
if (test_bit(JOB_DIE, &ai->flags))
break;
@@ -3245,7 +3249,10 @@ badrx:
wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
else
wstats.level = (hdr.rssi[1] + 321) / 2;
- wstats.updated = 3;
+ wstats.noise = apriv->wstats.qual.noise;
+ wstats.updated = IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_NOISE_UPDATED;
/* Update spy records */
wireless_spy_update(dev, sa, &wstats);
}
@@ -3588,7 +3595,10 @@ void mpi_receive_802_11 (struct airo_info *ai)
wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
else
wstats.level = (hdr.rssi[1] + 321) / 2;
- wstats.updated = 3;
+ wstats.noise = ai->wstats.qual.noise;
+ wstats.updated = IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_UPDATED;
/* Update spy records */
wireless_spy_update(ai->dev, sa, &wstats);
}
@@ -3679,7 +3689,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
if ( status == SUCCESS ) {
if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
- memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
+ memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
}
else {
if (ai->rssi) {
@@ -5348,7 +5358,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
(int)BSSList_rid.bssid[5],
(int)BSSList_rid.ssidLen,
BSSList_rid.ssid,
- (int)BSSList_rid.rssi);
+ (int)BSSList_rid.dBm);
ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
(int)BSSList_rid.dsChannel,
BSSList_rid.cap & CAP_ESS ? "ESS" : "",
@@ -5593,6 +5603,29 @@ static void __exit airo_cleanup_module( void )
* would not work at all... - Jean II
*/
+static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
+{
+ if( !rssi_rid )
+ return 0;
+
+ return (0x100 - rssi_rid[rssi].rssidBm);
+}
+
+static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
+{
+ int i;
+
+ if( !rssi_rid )
+ return 0;
+
+ for( i = 0; i < 256; i++ )
+ if (rssi_rid[i].rssidBm == dbm)
+ return rssi_rid[i].rssipct;
+
+ return 0;
+}
+
+
static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
{
int quality = 0;
@@ -6443,11 +6476,29 @@ static int airo_get_range(struct net_device *dev,
}
range->num_frequency = k;
+ range->sensitivity = 65535;
+
/* Hum... Should put the right values there */
- range->max_qual.qual = airo_get_max_quality(&cap_rid);
- range->max_qual.level = 0x100 - 120; /* -120 dBm */
+ if (local->rssi)
+ range->max_qual.qual = 100; /* % */
+ else
+ range->max_qual.qual = airo_get_max_quality(&cap_rid);
+ range->max_qual.level = 0; /* 0 means we use dBm */
range->max_qual.noise = 0;
- range->sensitivity = 65535;
+ range->max_qual.updated = 0;
+
+ /* Experimental measurements - boundary 11/5.5 Mb/s */
+ /* Note : with or without the (local->rssi), results
+ * are somewhat different. - Jean II */
+ if (local->rssi) {
+ range->avg_qual.qual = 50; /* % */
+ range->avg_qual.level = 186; /* -70 dBm */
+ } else {
+ range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
+ range->avg_qual.level = 176; /* -80 dBm */
+ }
+ range->avg_qual.noise = 0;
+ range->avg_qual.updated = 0;
for(i = 0 ; i < 8 ; i++) {
range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
@@ -6508,15 +6559,6 @@ static int airo_get_range(struct net_device *dev,
range->max_retry = 65535;
range->min_r_time = 1024;
range->max_r_time = 65535 * 1024;
- /* Experimental measurements - boundary 11/5.5 Mb/s */
- /* Note : with or without the (local->rssi), results
- * are somewhat different. - Jean II */
- range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
- if (local->rssi)
- range->avg_qual.level = 186; /* -70 dBm */
- else
- range->avg_qual.level = 176; /* -80 dBm */
- range->avg_qual.noise = 0;
/* Event capability (kernel + driver) */
range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
@@ -6676,12 +6718,18 @@ static int airo_get_aplist(struct net_device *dev,
loseSync = 0;
memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
address[i].sa_family = ARPHRD_ETHER;
- if (local->rssi)
- qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
- else
- qual[i].level = (BSSList.rssi + 321) / 2;
- qual[i].qual = qual[i].noise = 0;
- qual[i].updated = 2;
+ if (local->rssi) {
+ qual[i].level = 0x100 - BSSList.dBm;
+ qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm );
+ qual[i].updated = IW_QUAL_QUAL_UPDATED;
+ } else {
+ qual[i].level = (BSSList.dBm + 321) / 2;
+ qual[i].qual = 0;
+ qual[i].updated = IW_QUAL_QUAL_INVALID;
+ }
+ qual[i].noise = local->wstats.qual.noise;
+ qual[i].updated = IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_UPDATED;
if (BSSList.index == 0xffff)
break;
}
@@ -6760,7 +6808,7 @@ static int airo_set_scan(struct net_device *dev,
static inline char *airo_translate_scan(struct net_device *dev,
char *current_ev,
char *end_buf,
- BSSListRid *list)
+ BSSListRid *bss)
{
struct airo_info *ai = dev->priv;
struct iw_event iwe; /* Temporary buffer */
@@ -6771,22 +6819,22 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* First entry *MUST* be the AP MAC address */
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
+ memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
/* Add the ESSID */
- iwe.u.data.length = list->ssidLen;
+ iwe.u.data.length = bss->ssidLen;
if(iwe.u.data.length > 32)
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
+ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
- capabilities = le16_to_cpu(list->cap);
+ capabilities = le16_to_cpu(bss->cap);
if(capabilities & (CAP_ESS | CAP_IBSS)) {
if(capabilities & CAP_ESS)
iwe.u.mode = IW_MODE_MASTER;
@@ -6797,19 +6845,25 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Add frequency */
iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = le16_to_cpu(list->dsChannel);
+ iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
- if (ai->rssi)
- iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm;
- else
- iwe.u.qual.level = (list->rssi + 321) / 2;
- iwe.u.qual.noise = 0;
- iwe.u.qual.qual = 0;
+ if (ai->rssi) {
+ iwe.u.qual.level = 0x100 - bss->dBm;
+ iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm );
+ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED;
+ } else {
+ iwe.u.qual.level = (bss->dBm + 321) / 2;
+ iwe.u.qual.qual = 0;
+ iwe.u.qual.updated = IW_QUAL_QUAL_INVALID;
+ }
+ iwe.u.qual.noise = ai->wstats.qual.noise;
+ iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_UPDATED;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
@@ -6819,7 +6873,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
+ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
/* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */
@@ -6831,10 +6885,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Max 8 values */
for(i = 0 ; i < 8 ; i++) {
/* NULL terminated */
- if(list->rates[i] == 0)
+ if(bss->rates[i] == 0)
break;
/* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000);
+ iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
/* Add new value to event */
current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
}
@@ -7153,18 +7207,22 @@ static void airo_read_wireless_stats(struct airo_info *local)
/* The status */
local->wstats.status = status_rid.mode;
- /* Signal quality and co. But where is the noise level ??? */
- local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
- if (local->rssi)
- local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
- else
+ /* Signal quality and co */
+ if (local->rssi) {
+ local->wstats.qual.level = airo_rssi_to_dbm( local->rssi, status_rid.sigQuality );
+ /* normalizedSignalStrength appears to be a percentage */
+ local->wstats.qual.qual = status_rid.normalizedSignalStrength;
+ } else {
local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
+ local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
+ }
+ local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED;
if (status_rid.len >= 124) {
- local->wstats.qual.noise = 256 - status_rid.noisedBm;
- local->wstats.qual.updated = 7;
+ local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
+ local->wstats.qual.updated |= IW_QUAL_NOISE_UPDATED;
} else {
local->wstats.qual.noise = 0;
- local->wstats.qual.updated = 3;
+ local->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
}
/* Packets discarded in the wireless adapter due to wireless
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index a91b507e0a7..a4ed28d9c78 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -321,6 +321,7 @@ static struct {
{ 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" },
{ 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
{ 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
+ { 0, 0, "IEEE 802.11b/Wireless LAN Card S", ATMEL_FW_TYPE_504_2958, "Siemens Gigaset PC Card II" },
{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
{ 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
{ 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index a3a32430ae9..b1078baa1d5 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -492,6 +492,9 @@ EXPORT_SYMBOL(orinoco_debug);
static int suppress_linkstatus; /* = 0 */
module_param(suppress_linkstatus, bool, 0644);
MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
+static int ignore_disconnect; /* = 0 */
+module_param(ignore_disconnect, int, 0644);
+MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
/********************************************************************/
/* Compile time configuration and compatibility stuff */
@@ -604,7 +607,6 @@ struct hermes_rx_descriptor {
static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int __orinoco_program_rids(struct net_device *dev);
static void __orinoco_set_multicast_list(struct net_device *dev);
-static int orinoco_debug_dump_recs(struct net_device *dev);
/********************************************************************/
/* Internal helper functions */
@@ -655,7 +657,7 @@ static int orinoco_open(struct net_device *dev)
return err;
}
-int orinoco_stop(struct net_device *dev)
+static int orinoco_stop(struct net_device *dev)
{
struct orinoco_private *priv = netdev_priv(dev);
int err = 0;
@@ -686,7 +688,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
struct orinoco_private *priv = netdev_priv(dev);
hermes_t *hw = &priv->hw;
struct iw_statistics *wstats = &priv->wstats;
- int err = 0;
+ int err;
unsigned long flags;
if (! netif_device_present(dev)) {
@@ -695,9 +697,21 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
return NULL; /* FIXME: Can we do better than this? */
}
+ /* If busy, return the old stats. Returning NULL may cause
+ * the interface to disappear from /proc/net/wireless */
if (orinoco_lock(priv, &flags) != 0)
- return NULL; /* FIXME: Erg, we've been signalled, how
- * do we propagate this back up? */
+ return wstats;
+
+ /* We can't really wait for the tallies inquiry command to
+ * complete, so we just use the previous results and trigger
+ * a new tallies inquiry command for next time - Jean II */
+ /* FIXME: Really we should wait for the inquiry to come back -
+ * as it is the stats we give don't make a whole lot of sense.
+ * Unfortunately, it's not clear how to do that within the
+ * wireless extensions framework: I think we're in user
+ * context, but a lock seems to be held by the time we get in
+ * here so we're not safe to sleep here. */
+ hermes_inquire(hw, HERMES_INQ_TALLIES);
if (priv->iw_mode == IW_MODE_ADHOC) {
memset(&wstats->qual, 0, sizeof(wstats->qual));
@@ -716,25 +730,16 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
err = HERMES_READ_RECORD(hw, USER_BAP,
HERMES_RID_COMMSQUALITY, &cq);
-
- wstats->qual.qual = (int)le16_to_cpu(cq.qual);
- wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
- wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
- wstats->qual.updated = 7;
+
+ if (!err) {
+ wstats->qual.qual = (int)le16_to_cpu(cq.qual);
+ wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
+ wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
+ wstats->qual.updated = 7;
+ }
}
- /* We can't really wait for the tallies inquiry command to
- * complete, so we just use the previous results and trigger
- * a new tallies inquiry command for next time - Jean II */
- /* FIXME: We're in user context (I think?), so we should just
- wait for the tallies to come through */
- err = hermes_inquire(hw, HERMES_INQ_TALLIES);
-
orinoco_unlock(priv, &flags);
-
- if (err)
- return NULL;
-
return wstats;
}
@@ -1275,9 +1280,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
len = sizeof(tallies);
}
- /* Read directly the data (no seek) */
- hermes_read_words(hw, HERMES_DATA1, (void *) &tallies,
- len / 2); /* FIXME: blech! */
+ err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
+ infofid, sizeof(info));
+ if (err)
+ break;
/* Increment our various counters */
/* wstats->discard.nwid - no wrong BSSID stuff */
@@ -1307,8 +1313,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
break;
}
- hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,
- len / 2);
+ err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
+ infofid, sizeof(info));
+ if (err)
+ break;
newstatus = le16_to_cpu(linkstatus.linkstatus);
connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
@@ -1317,7 +1325,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
if (connected)
netif_carrier_on(dev);
- else
+ else if (!ignore_disconnect)
netif_carrier_off(dev);
if (newstatus != priv->last_linkstatus)
@@ -1350,6 +1358,8 @@ int __orinoco_up(struct net_device *dev)
struct hermes *hw = &priv->hw;
int err;
+ netif_carrier_off(dev); /* just to make sure */
+
err = __orinoco_program_rids(dev);
if (err) {
printk(KERN_ERR "%s: Error %d configuring card\n",
@@ -1413,7 +1423,7 @@ int orinoco_reinit_firmware(struct net_device *dev)
return err;
err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err == -EIO) {
+ if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
/* Try workaround for old Symbol firmware bug */
printk(KERN_WARNING "%s: firmware ALLOC bug detected "
"(old Symbol firmware?). Trying to work around... ",
@@ -1610,17 +1620,15 @@ static int __orinoco_program_rids(struct net_device *dev)
return err;
}
/* Set the channel/frequency */
- if (priv->channel == 0) {
- printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);
- if (priv->createibss)
- priv->channel = 10;
- }
- err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL,
- priv->channel);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting channel\n",
- dev->name, err);
- return err;
+ if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFOWNCHANNEL,
+ priv->channel);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting channel %d\n",
+ dev->name, err, priv->channel);
+ return err;
+ }
}
if (priv->has_ibss) {
@@ -1916,7 +1924,7 @@ static void orinoco_reset(struct net_device *dev)
{
struct orinoco_private *priv = netdev_priv(dev);
struct hermes *hw = &priv->hw;
- int err = 0;
+ int err;
unsigned long flags;
if (orinoco_lock(priv, &flags) != 0)
@@ -1938,20 +1946,20 @@ static void orinoco_reset(struct net_device *dev)
orinoco_unlock(priv, &flags);
- if (priv->hard_reset)
+ if (priv->hard_reset) {
err = (*priv->hard_reset)(priv);
- if (err) {
- printk(KERN_ERR "%s: orinoco_reset: Error %d "
- "performing hard reset\n", dev->name, err);
- /* FIXME: shutdown of some sort */
- return;
+ if (err) {
+ printk(KERN_ERR "%s: orinoco_reset: Error %d "
+ "performing hard reset\n", dev->name, err);
+ goto disable;
+ }
}
err = orinoco_reinit_firmware(dev);
if (err) {
printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
dev->name, err);
- return;
+ goto disable;
}
spin_lock_irq(&priv->lock); /* This has to be called from user context */
@@ -1972,6 +1980,10 @@ static void orinoco_reset(struct net_device *dev)
spin_unlock_irq(&priv->lock);
return;
+ disable:
+ hermes_set_irqmask(hw, 0);
+ netif_device_detach(dev);
+ printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
}
/********************************************************************/
@@ -2056,7 +2068,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (events & HERMES_EV_ALLOC)
__orinoco_ev_alloc(dev, hw);
- hermes_write_regn(hw, EVACK, events);
+ hermes_write_regn(hw, EVACK, evstat);
evstat = hermes_read_regn(hw, EVSTAT);
events = evstat & hw->inten;
@@ -2215,6 +2227,8 @@ static int determine_firmware(struct net_device *dev)
firmver >= 0x31000;
priv->has_preamble = (firmver >= 0x20000);
priv->ibss_port = 4;
+ priv->broken_disableport = (firmver == 0x25013) ||
+ (firmver >= 0x30000 && firmver <= 0x31000);
/* Tested with Intel firmware : 0x20015 => Jean II */
/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
break;
@@ -2267,7 +2281,7 @@ static int orinoco_init(struct net_device *dev)
priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
/* Initialize the firmware */
- err = hermes_init(hw);
+ err = orinoco_reinit_firmware(dev);
if (err != 0) {
printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
dev->name, err);
@@ -2400,31 +2414,12 @@ static int orinoco_init(struct net_device *dev)
/* By default use IEEE/IBSS ad-hoc mode if we have it */
priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
set_port_type(priv);
- priv->channel = 10; /* default channel, more-or-less arbitrary */
+ priv->channel = 0; /* use firmware default */
priv->promiscuous = 0;
priv->wep_on = 0;
priv->tx_key = 0;
- err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err == -EIO) {
- /* Try workaround for old Symbol firmware bug */
- printk(KERN_WARNING "%s: firmware ALLOC bug detected "
- "(old Symbol firmware?). Trying to work around... ",
- dev->name);
-
- priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
- err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err)
- printk("failed!\n");
- else
- printk("ok.\n");
- }
- if (err) {
- printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
- goto out;
- }
-
/* Make the hardware available, as long as it hasn't been
* removed elsewhere (e.g. by PCMCIA hot unplug) */
spin_lock_irq(&priv->lock);
@@ -2450,7 +2445,7 @@ struct net_device *alloc_orinocodev(int sizeof_card,
priv = netdev_priv(dev);
priv->ndev = dev;
if (sizeof_card)
- priv->card = (void *)((unsigned long)netdev_priv(dev)
+ priv->card = (void *)((unsigned long)priv
+ sizeof(struct orinoco_private));
else
priv->card = NULL;
@@ -2555,6 +2550,7 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
}
len = le16_to_cpu(essidbuf.len);
+ BUG_ON(len > IW_ESSID_MAX_SIZE);
memset(buf, 0, IW_ESSID_MAX_SIZE+1);
memcpy(buf, p, len);
@@ -2923,13 +2919,14 @@ static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
memset(&essidbuf, 0, sizeof(essidbuf));
if (erq->flags) {
- if (erq->length > IW_ESSID_MAX_SIZE)
+ /* iwconfig includes the NUL in the specified length */
+ if (erq->length > IW_ESSID_MAX_SIZE+1)
return -E2BIG;
if (copy_from_user(&essidbuf, erq->pointer, erq->length))
return -EFAULT;
- essidbuf[erq->length] = '\0';
+ essidbuf[IW_ESSID_MAX_SIZE] = '\0';
}
if (orinoco_lock(priv, &flags) != 0)
@@ -3855,7 +3852,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ SIOCIWFIRSTPRIV + 0x7, 0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_ibssport" },
- { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
};
wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
@@ -3943,14 +3939,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
err = orinoco_ioctl_getibssport(dev, wrq);
break;
- case SIOCIWLASTPRIV:
- err = orinoco_debug_dump_recs(dev);
- if (err)
- printk(KERN_ERR "%s: Unable to dump records (%d)\n",
- dev->name, err);
- break;
-
-
default:
err = -EOPNOTSUPP;
}
@@ -3964,187 +3952,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return err;
}
-struct {
- u16 rid;
- char *name;
- int displaytype;
-#define DISPLAY_WORDS 0
-#define DISPLAY_BYTES 1
-#define DISPLAY_STRING 2
-#define DISPLAY_XSTRING 3
-} record_table[] = {
-#define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
- DEBUG_REC(CNFPORTTYPE,WORDS),
- DEBUG_REC(CNFOWNMACADDR,BYTES),
- DEBUG_REC(CNFDESIREDSSID,STRING),
- DEBUG_REC(CNFOWNCHANNEL,WORDS),
- DEBUG_REC(CNFOWNSSID,STRING),
- DEBUG_REC(CNFOWNATIMWINDOW,WORDS),
- DEBUG_REC(CNFSYSTEMSCALE,WORDS),
- DEBUG_REC(CNFMAXDATALEN,WORDS),
- DEBUG_REC(CNFPMENABLED,WORDS),
- DEBUG_REC(CNFPMEPS,WORDS),
- DEBUG_REC(CNFMULTICASTRECEIVE,WORDS),
- DEBUG_REC(CNFMAXSLEEPDURATION,WORDS),
- DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS),
- DEBUG_REC(CNFOWNNAME,STRING),
- DEBUG_REC(CNFOWNDTIMPERIOD,WORDS),
- DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS),
- DEBUG_REC(CNFWEPENABLED_AGERE,WORDS),
- DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
- DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS),
- DEBUG_REC(CNFDEFAULTKEY0,BYTES),
- DEBUG_REC(CNFDEFAULTKEY1,BYTES),
- DEBUG_REC(CNFMWOROBUST_AGERE,WORDS),
- DEBUG_REC(CNFDEFAULTKEY2,BYTES),
- DEBUG_REC(CNFDEFAULTKEY3,BYTES),
- DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS),
- DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
- DEBUG_REC(CNFAUTHENTICATION,WORDS),
- DEBUG_REC(CNFMAXASSOCSTA,WORDS),
- DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS),
- DEBUG_REC(CNFTXCONTROL,WORDS),
- DEBUG_REC(CNFROAMINGMODE,WORDS),
- DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS),
- DEBUG_REC(CNFRCVCRCERROR,WORDS),
- DEBUG_REC(CNFMMLIFE,WORDS),
- DEBUG_REC(CNFALTRETRYCOUNT,WORDS),
- DEBUG_REC(CNFBEACONINT,WORDS),
- DEBUG_REC(CNFAPPCFINFO,WORDS),
- DEBUG_REC(CNFSTAPCFINFO,WORDS),
- DEBUG_REC(CNFPRIORITYQUSAGE,WORDS),
- DEBUG_REC(CNFTIMCTRL,WORDS),
- DEBUG_REC(CNFTHIRTY2TALLY,WORDS),
- DEBUG_REC(CNFENHSECURITY,WORDS),
- DEBUG_REC(CNFGROUPADDRESSES,BYTES),
- DEBUG_REC(CNFCREATEIBSS,WORDS),
- DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
- DEBUG_REC(CNFRTSTHRESHOLD,WORDS),
- DEBUG_REC(CNFTXRATECONTROL,WORDS),
- DEBUG_REC(CNFPROMISCUOUSMODE,WORDS),
- DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS),
- DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS),
- DEBUG_REC(CNFSHORTPREAMBLE,WORDS),
- DEBUG_REC(CNFWEPKEYS_AGERE,BYTES),
- DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
- DEBUG_REC(CNFTXKEY_AGERE,WORDS),
- DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS),
- DEBUG_REC(CNFBASICRATES,WORDS),
- DEBUG_REC(CNFSUPPORTEDRATES,WORDS),
- DEBUG_REC(CNFTICKTIME,WORDS),
- DEBUG_REC(CNFSCANREQUEST,WORDS),
- DEBUG_REC(CNFJOINREQUEST,WORDS),
- DEBUG_REC(CNFAUTHENTICATESTATION,WORDS),
- DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS),
- DEBUG_REC(MAXLOADTIME,WORDS),
- DEBUG_REC(DOWNLOADBUFFER,WORDS),
- DEBUG_REC(PRIID,WORDS),
- DEBUG_REC(PRISUPRANGE,WORDS),
- DEBUG_REC(CFIACTRANGES,WORDS),
- DEBUG_REC(NICSERNUM,XSTRING),
- DEBUG_REC(NICID,WORDS),
- DEBUG_REC(MFISUPRANGE,WORDS),
- DEBUG_REC(CFISUPRANGE,WORDS),
- DEBUG_REC(CHANNELLIST,WORDS),
- DEBUG_REC(REGULATORYDOMAINS,WORDS),
- DEBUG_REC(TEMPTYPE,WORDS),
-/* DEBUG_REC(CIS,BYTES), */
- DEBUG_REC(STAID,WORDS),
- DEBUG_REC(CURRENTSSID,STRING),
- DEBUG_REC(CURRENTBSSID,BYTES),
- DEBUG_REC(COMMSQUALITY,WORDS),
- DEBUG_REC(CURRENTTXRATE,WORDS),
- DEBUG_REC(CURRENTBEACONINTERVAL,WORDS),
- DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS),
- DEBUG_REC(PROTOCOLRSPTIME,WORDS),
- DEBUG_REC(SHORTRETRYLIMIT,WORDS),
- DEBUG_REC(LONGRETRYLIMIT,WORDS),
- DEBUG_REC(MAXTRANSMITLIFETIME,WORDS),
- DEBUG_REC(MAXRECEIVELIFETIME,WORDS),
- DEBUG_REC(CFPOLLABLE,WORDS),
- DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS),
- DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
- DEBUG_REC(OWNMACADDR,BYTES),
- DEBUG_REC(SCANRESULTSTABLE,WORDS),
- DEBUG_REC(PHYTYPE,WORDS),
- DEBUG_REC(CURRENTCHANNEL,WORDS),
- DEBUG_REC(CURRENTPOWERSTATE,WORDS),
- DEBUG_REC(CCAMODE,WORDS),
- DEBUG_REC(SUPPORTEDDATARATES,WORDS),
- DEBUG_REC(BUILDSEQ,BYTES),
- DEBUG_REC(FWID,XSTRING)
-#undef DEBUG_REC
-};
-
-#define DEBUG_LTV_SIZE 128
-
-static int orinoco_debug_dump_recs(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- u8 *val8;
- u16 *val16;
- int i,j;
- u16 length;
- int err;
-
- /* I'm not sure: we might have a lock here, so we'd better go
- atomic, just in case. */
- val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC);
- if (! val8)
- return -ENOMEM;
- val16 = (u16 *)val8;
-
- for (i = 0; i < ARRAY_SIZE(record_table); i++) {
- u16 rid = record_table[i].rid;
- int len;
-
- memset(val8, 0, DEBUG_LTV_SIZE + 2);
-
- err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE,
- &length, val8);
- if (err) {
- DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
- continue;
- }
- val16 = (u16 *)val8;
- if (length == 0)
- continue;
-
- printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=",
- record_table[i].name,
- rid, length, (length-1)*2);
- len = min(((int)length-1)*2, DEBUG_LTV_SIZE);
-
- switch (record_table[i].displaytype) {
- case DISPLAY_WORDS:
- for (j = 0; j < len / 2; j++)
- printk("%04X-", le16_to_cpu(val16[j]));
- break;
-
- case DISPLAY_BYTES:
- default:
- for (j = 0; j < len; j++)
- printk("%02X:", val8[j]);
- break;
-
- case DISPLAY_STRING:
- len = min(len, le16_to_cpu(val16[0])+2);
- val8[len] = '\0';
- printk("\"%s\"", (char *)&val16[1]);
- break;
-
- case DISPLAY_XSTRING:
- printk("'%s'", (char *)val8);
- }
-
- printk("\n");
- }
-
- kfree(val8);
-
- return 0;
-}
/********************************************************************/
/* Debugging */
@@ -4218,7 +4025,6 @@ EXPORT_SYMBOL(free_orinocodev);
EXPORT_SYMBOL(__orinoco_up);
EXPORT_SYMBOL(__orinoco_down);
-EXPORT_SYMBOL(orinoco_stop);
EXPORT_SYMBOL(orinoco_reinit_firmware);
EXPORT_SYMBOL(orinoco_interrupt);
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 13e42c2afb2..f749b50d108 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -119,7 +119,6 @@ extern struct net_device *alloc_orinocodev(int sizeof_card,
extern void free_orinocodev(struct net_device *dev);
extern int __orinoco_up(struct net_device *dev);
extern int __orinoco_down(struct net_device *dev);
-extern int orinoco_stop(struct net_device *dev);
extern int orinoco_reinit_firmware(struct net_device *dev);
extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index ec8cf29ffce..6c42b573a95 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -2828,7 +2828,7 @@ static void __exit strip_exit_driver(void)
/* Unregister with the /proc/net file here. */
proc_net_remove("strip");
- if ((i = tty_register_ldisc(N_STRIP, NULL)))
+ if ((i = tty_unregister_ldisc(N_STRIP)))
printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
printk(signoff);