]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/ipw2x00/ipw2200.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / ipw2x00 / ipw2200.c
index 48fa6df3a774fa8a4976118c8ca830578ec09fa5..625f2cf99fa9f9a7bf4976aeb460523e18b1b920 100644 (file)
@@ -3895,6 +3895,7 @@ static int ipw_disassociate(void *data)
        if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
                return 0;
        ipw_send_disassociate(data, 0);
+       netif_carrier_off(priv->net_dev);
        return 1;
 }
 
@@ -4344,7 +4345,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
                return;
        }
 
-       if (priv->status & STATUS_SCANNING) {
+       if (priv->status & STATUS_SCANNING &&
+           missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {
                /* Stop scan to keep fw from getting
                 * stuck (only if we aren't roaming --
                 * otherwise we'll never scan more than 2 or 3
@@ -6270,6 +6272,20 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
        }
 }
 
+static int ipw_passive_dwell_time(struct ipw_priv *priv)
+{
+       /* staying on passive channels longer than the DTIM interval during a
+        * scan, while associated, causes the firmware to cancel the scan
+        * without notification. Hence, don't stay on passive channels longer
+        * than the beacon interval.
+        */
+       if (priv->status & STATUS_ASSOCIATED
+           && priv->assoc_network->beacon_interval > 10)
+               return priv->assoc_network->beacon_interval - 10;
+       else
+               return 120;
+}
+
 static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
 {
        struct ipw_scan_request_ext scan;
@@ -6313,16 +6329,16 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
        scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
 
        if (type == IW_SCAN_TYPE_PASSIVE) {
-               IPW_DEBUG_WX("use passive scanning\n");
-               scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
+               IPW_DEBUG_WX("use passive scanning\n");
+               scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
                scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
-                       cpu_to_le16(120);
+                       cpu_to_le16(ipw_passive_dwell_time(priv));
                ipw_add_scan_channels(priv, &scan, scan_type);
                goto send_request;
        }
 
        /* Use active scan by default. */
-       if (priv->config & CFG_SPEED_SCAN)
+       if (priv->config & CFG_SPEED_SCAN)
                scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
                        cpu_to_le16(30);
        else
@@ -6332,7 +6348,8 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
        scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
                cpu_to_le16(20);
 
-       scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
+       scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
+               cpu_to_le16(ipw_passive_dwell_time(priv));
        scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
 
 #ifdef CONFIG_IPW2200_MONITOR
@@ -10155,6 +10172,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
        u16 remaining_bytes;
        int fc;
 
+       if (!(priv->status & STATUS_ASSOCIATED))
+               goto drop;
+
        hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
        switch (priv->ieee->iw_mode) {
        case IW_MODE_ADHOC: