if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len))
                return 0;
 
+       /* assume that users know what they're doing ...
+        * (note we don't let them select a net we're incompatible with) */
+       if (mac->associnfo.bssfixed) {
+               return !memcmp(mac->associnfo.bssid, net->bssid, ETH_ALEN);
+       }
+
        /* if 'ANY' network requested, take any that doesn't have privacy enabled */
        if (mac->associnfo.req_essid.len == 0 
            && !(net->capability & WLAN_CAPABILITY_PRIVACY))
                ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
 
        /* try to find the requested network in our list, if we found one already */
-       if (mac->associnfo.bssvalid)
+       if (mac->associnfo.bssvalid || mac->associnfo.bssfixed)
                found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);       
        
        /* Search the ieee80211 networks for this network if we didn't find it by bssid,
                        if (ieee80211softmac_start_scan(mac))
                                dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
                        return;
-               }
-               else {
+               } else {
                        spin_lock_irqsave(&mac->lock, flags);
                        mac->associnfo.associating = 0;
                        mac->associated = 0;
                        spin_unlock_irqrestore(&mac->lock, flags);
 
                        dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n");
+                       /* reset the retry counter for the next user request since we
+                        * break out and don't reschedule ourselves after this point. */
+                       mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
                        ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL);
                        return;
                }
        }
-       
+
+       /* reset the retry counter for the next user request since we
+        * now found a net and will try to associate to it, but not
+        * schedule this function again. */
+       mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
        mac->associnfo.bssvalid = 1;
        memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN);
        /* copy the ESSID for displaying it */
 
 #include "ieee80211softmac_priv.h"
 
 #include <net/iw_handler.h>
-
+/* for is_broadcast_ether_addr and is_zero_ether_addr */
+#include <linux/etherdevice.h>
 
 int
 ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
                        sm->associnfo.static_essid = 1;
                }
        }
-       sm->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
 
        /* set our requested ESSID length.
         * If applicable, we have already copied the data in */
                            char *extra)
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
-       static const unsigned char any[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-       static const unsigned char off[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        unsigned long flags;
 
        /* sanity check */
        }
 
        spin_lock_irqsave(&mac->lock, flags);
-       if (!memcmp(any, data->ap_addr.sa_data, ETH_ALEN) ||
-           !memcmp(off, data->ap_addr.sa_data, ETH_ALEN)) {
-               schedule_work(&mac->associnfo.work);
-               goto out;
+       if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
+               /* the bssid we have is not to be fixed any longer,
+                * and we should reassociate to the best AP. */
+               mac->associnfo.bssfixed = 0;
+               /* force reassociation */
+               mac->associnfo.bssvalid = 0;
+               if (mac->associated)
+                       schedule_work(&mac->associnfo.work);
+       } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
+               /* the bssid we have is no longer fixed */
+               mac->associnfo.bssfixed = 0;
         } else {
                if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
                        if (mac->associnfo.associating || mac->associated) {
                } else {
                        /* copy new value in data->ap_addr.sa_data to bssid */
                        memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN);
-               }       
+               }
+               /* tell the other code that this bssid should be used no matter what */
+               mac->associnfo.bssfixed = 1;
                /* queue associate if new bssid or (old one again and not associated) */
                schedule_work(&mac->associnfo.work);
         }
 
-out:
+ out:
        spin_unlock_irqrestore(&mac->lock, flags);
        return 0;
 }