summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Cahill <ben.m.cahill@intel.com>2005-10-06 20:34:41 (GMT)
committerJames Ketrenos <jketreno@linux.intel.com>2005-11-07 23:52:00 (GMT)
commite758256104c3c2475f7746bc1b348c99cdb207f2 (patch)
treec3076d27876f5d633db3ed5f8e3e4775679b7245
parent8935f39e86e3707770e091fb58d9060307edf959 (diff)
downloadlinux-e758256104c3c2475f7746bc1b348c99cdb207f2.tar.xz
Fixes missed beacon logic in relation to on-network AP roaming.
Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
-rw-r--r--drivers/net/wireless/ipw2200.c27
-rw-r--r--drivers/net/wireless/ipw2200.h3
2 files changed, 23 insertions, 7 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 8e17308..8941929 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4082,6 +4082,11 @@ static void ipw_bg_gather_stats(void *data)
up(&priv->sem);
}
+/* Missed beacon behavior:
+ * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
+ * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
+ * Above disassociate threshold, give up and stop scanning.
+ * Roaming is disabled if disassociate_threshold <= roaming_threshold */
static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
int missed_count)
{
@@ -4116,9 +4121,12 @@ static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
return;
}
- if (missed_count > priv->roaming_threshold) {
+ if (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 */
+ * bit in the status and kick off a scan.
+ * This can happen several times before we reach
+ * disassociate_threshold. */
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
"Missed beacon: %d - initiate "
"roaming\n", missed_count);
@@ -4480,11 +4488,16 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
STATUS_DISASSOCIATING)))
queue_work(priv->workqueue, &priv->associate);
else if (priv->status & STATUS_ROAMING) {
- /* If a scan completed and we are in roam mode, then
- * the scan that completed was the one requested as a
- * result of entering roam... so, schedule the
- * roam work */
- queue_work(priv->workqueue, &priv->roam);
+ if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
+ /* If a scan completed and we are in roam mode, then
+ * the scan that completed was the one requested as a
+ * result of entering roam... so, schedule the
+ * roam work */
+ queue_work(priv->workqueue,
+ &priv->roam);
+ else
+ /* Don't schedule if we aborted the scan */
+ priv->status &= ~STATUS_ROAMING;
} else if (priv->status & STATUS_SCAN_PENDING)
queue_work(priv->workqueue,
&priv->request_scan);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 3e76994..617ec4d 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -590,6 +590,9 @@ struct notif_channel_result {
u8 uReserved;
} __attribute__ ((packed));
+#define SCAN_COMPLETED_STATUS_COMPLETE 1
+#define SCAN_COMPLETED_STATUS_ABORTED 2
+
struct notif_scan_complete {
u8 scan_type;
u8 num_channels;