Undo the following commits due to kABI concerns... commit 837925df022a667c302b24aad9d6a58f94efd959 Author: Larry Finger Date: Tue Oct 3 18:49:32 2006 -0500 [PATCH] ieee80211: Drop and count duplicate data frames to remove 'replay detected' log messages In the SoftMAC version of the IEEE 802.11 stack, not all duplicate messages are detected. For the most part, there is no difficulty; however for TKIP and CCMP encryption, the duplicates result in a "replay detected" log message where the received and previous values of the TSC are identical. This change adds a new variable to the ieee80211_device structure that holds the 'seq_ctl' value for the previous frame. When a new frame repeats the value, the frame is dropped and the appropriate counter is incremented. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit 7c28ad2d83ecc637237fe684659a6afbce0bb2a8 Author: Michael Buesch Date: Wed Sep 27 15:26:33 2006 +0300 [PATCH] softmac: Fix WX and association related races This fixes some race conditions in the WirelessExtension handling and association handling code. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville commit 5acd0c4153be25269d7cb9a4b09fd6db571c5cc1 Author: Daniel Drake Date: Tue Jul 18 21:33:27 2006 +0100 [PATCH] softmac: ERP handling and driver-level notifications This patch implements ERP handling in softmac so that the drivers can support protection and preambles properly. I added a new struct, ieee80211softmac_bss_info, which is used for BSS-dependent variables like these. A new hook has been added (bssinfo_change), which allows the drivers to be notified when anything in bssinfo changes. I modified the txrates_change API to match the bssinfo_change API. The existing one is a little messy and the usefulness of providing the old rates is questionable (and can be implemented at driver level if really necessary). No drivers are using this API (yet), so this should be safe. Signed-off-by: Daniel Drake Acked-by: Johannes Berg Signed-off-by: John W. Linville --- linux-2.6.18.noarch/include/net/ieee80211.h.orig 2007-06-12 16:09:12.000000000 -0400 +++ linux-2.6.18.noarch/include/net/ieee80211.h 2007-06-12 16:09:18.000000000 -0400 @@ -1076,8 +1076,6 @@ struct ieee80211_device { int perfect_rssi; int worst_rssi; - u16 prev_seq_ctl; /* used to drop duplicate frames */ - /* Callback functions */ void (*set_security) (struct net_device * dev, struct ieee80211_security * sec); --- linux-2.6.18.noarch/include/net/ieee80211softmac.h.orig 2007-06-12 16:09:12.000000000 -0400 +++ linux-2.6.18.noarch/include/net/ieee80211softmac.h 2007-06-12 16:09:18.000000000 -0400 @@ -63,11 +63,13 @@ struct ieee80211softmac_wpa { /* * Information about association + * + * Do we need a lock for this? + * We only ever use this structure inlined + * into our global struct. I've used its lock, + * but maybe we need a local one here? */ struct ieee80211softmac_assoc_info { - - struct mutex mutex; - /* * This is the requested ESSID. It is written * only by the WX handlers. @@ -84,6 +86,9 @@ struct ieee80211softmac_assoc_info { /* BSSID we're trying to associate to */ char bssid[ETH_ALEN]; + + /* Rates supported by the network */ + struct ieee80211softmac_ratesinfo supported_rates; /* some flags. * static_essid is valid if the essid is constant, @@ -97,13 +102,11 @@ struct ieee80211softmac_assoc_info { * * bssfixed is used for SIOCSIWAP. */ - u8 static_essid; - u8 short_preamble_available; - u8 associating; - u8 associated; - u8 assoc_wait; - u8 bssvalid; - u8 bssfixed; + u8 static_essid:1, + associating:1, + assoc_wait:1, + bssvalid:1, + bssfixed:1; /* Scan retries remaining */ int scan_retry; @@ -112,19 +115,6 @@ struct ieee80211softmac_assoc_info { struct work_struct timeout; }; -struct ieee80211softmac_bss_info { - /* Rates supported by the network */ - struct ieee80211softmac_ratesinfo supported_rates; - - /* This indicates whether frames can currently be transmitted with - * short preamble (only use this variable during TX at CCK rates) */ - u8 short_preamble:1; - - /* This indicates whether protection (e.g. self-CTS) should be used - * when transmitting with OFDM modulation */ - u8 use_protection:1; -}; - enum { IEEE80211SOFTMAC_AUTH_OPEN_REQUEST = 1, IEEE80211SOFTMAC_AUTH_OPEN_RESPONSE = 2, @@ -167,10 +157,6 @@ struct ieee80211softmac_txrates { #define IEEE80211SOFTMAC_TXRATECHG_MCAST (1 << 2) /* mcast_rate */ #define IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST (1 << 3) /* mgt_mcast_rate */ -#define IEEE80211SOFTMAC_BSSINFOCHG_RATES (1 << 0) /* supported_rates */ -#define IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE (1 << 1) /* short_preamble */ -#define IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION (1 << 2) /* use_protection */ - struct ieee80211softmac_device { /* 802.11 structure for data stuff */ struct ieee80211_device *ieee; @@ -214,27 +200,22 @@ struct ieee80211softmac_device { * The driver just needs to read them. */ struct ieee80211softmac_txrates txrates; - - /* If the driver needs to do stuff on TX rate changes, assign this - * callback. See IEEE80211SOFTMAC_TXRATECHG for change flags. */ + /* If the driver needs to do stuff on TX rate changes, assign this callback. */ void (*txrates_change)(struct net_device *dev, - u32 changes); - - /* If the driver needs to do stuff when BSS properties change, assign - * this callback. see IEEE80211SOFTMAC_BSSINFOCHG for change flags. */ - void (*bssinfo_change)(struct net_device *dev, - u32 changes); + u32 changes, /* see IEEE80211SOFTMAC_TXRATECHG flags */ + const struct ieee80211softmac_txrates *rates_before_change); /* private stuff follows */ /* this lock protects this structure */ spinlock_t lock; - - u8 running; /* SoftMAC started? */ - u8 scanning; - + + /* couple of flags */ + u8 scanning:1, /* protects scanning from being done multiple times at once */ + associated:1, + running:1; + struct ieee80211softmac_scaninfo *scaninfo; struct ieee80211softmac_assoc_info associnfo; - struct ieee80211softmac_bss_info bssinfo; struct list_head auth_queue; struct list_head events; @@ -247,7 +228,7 @@ struct ieee80211softmac_device { /* we need to keep a list of network structs we copied */ struct list_head network_list; - + /* This must be the last item so that it points to the data * allocated beyond this structure by alloc_ieee80211 */ u8 priv[0]; @@ -284,7 +265,7 @@ static inline u8 ieee80211softmac_sugges { struct ieee80211softmac_txrates *txrates = &mac->txrates; - if (!mac->associnfo.associated) + if (!mac->associated) return txrates->mgt_mcast_rate; /* We are associated, sending unicast frame */ @@ -298,24 +279,6 @@ static inline u8 ieee80211softmac_sugges return txrates->mcast_rate; } -/* Helper function which advises you when it is safe to transmit with short - * preamble. - * You should only call this function when transmitting at CCK rates. */ -static inline int ieee80211softmac_short_preamble_ok(struct ieee80211softmac_device *mac, - int is_multicast, - int is_mgt) -{ - return (is_multicast && is_mgt) ? 0 : mac->bssinfo.short_preamble; -} - -/* Helper function which advises you whether protection (e.g. self-CTS) is - * needed. 1 = protection needed, 0 = no protection needed - * Only use this function when transmitting with OFDM modulation. */ -static inline int ieee80211softmac_protection_needed(struct ieee80211softmac_device *mac) -{ - return mac->bssinfo.use_protection; -} - /* Start the SoftMAC. Call this after you initialized the device * and it is ready to run. */ --- linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_module.c.orig 2007-06-12 16:09:12.000000000 -0400 +++ linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_module.c 2007-06-12 16:09:18.000000000 -0400 @@ -44,7 +44,6 @@ struct net_device *alloc_ieee80211softma softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response; softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req; softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; - softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon; softmac->scaninfo = NULL; softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; @@ -57,7 +56,6 @@ struct net_device *alloc_ieee80211softma INIT_LIST_HEAD(&softmac->network_list); INIT_LIST_HEAD(&softmac->events); - mutex_init(&softmac->associnfo.mutex); INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); softmac->start_scan = ieee80211softmac_start_scan_implementation; @@ -211,59 +209,35 @@ static u8 highest_supported_rate(struct return user_rate; } -void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac, - u8 erp_value) -{ - int use_protection; - int short_preamble; - u32 changes = 0; - - /* Barker preamble mode */ - short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0 - && mac->associnfo.short_preamble_available) ? 1 : 0; - - /* Protection needed? */ - use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; - - if (mac->bssinfo.short_preamble != short_preamble) { - changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE; - mac->bssinfo.short_preamble = short_preamble; - } - - if (mac->bssinfo.use_protection != use_protection) { - changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION; - mac->bssinfo.use_protection = use_protection; - } - - if (mac->bssinfo_change && changes) - mac->bssinfo_change(mac->dev, changes); -} - void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac) { struct ieee80211softmac_txrates *txrates = &mac->txrates; + struct ieee80211softmac_txrates oldrates; u32 change = 0; + if (mac->txrates_change) + oldrates = mac->txrates; + change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; - txrates->default_rate = highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0); + txrates->default_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 0); change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; txrates->default_fallback = lower_rate(mac, txrates->default_rate); change |= IEEE80211SOFTMAC_TXRATECHG_MCAST; - txrates->mcast_rate = highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1); + txrates->mcast_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 1); if (mac->txrates_change) - mac->txrates_change(mac->dev, change); + mac->txrates_change(mac->dev, change, &oldrates); } -void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac) +void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac) { struct ieee80211_device *ieee = mac->ieee; u32 change = 0; struct ieee80211softmac_txrates *txrates = &mac->txrates; - struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo; + struct ieee80211softmac_txrates oldrates; /* TODO: We need some kind of state machine to lower the default rates * if we loose too many packets. @@ -289,23 +263,7 @@ void ieee80211softmac_init_bss(struct ie change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST; if (mac->txrates_change) - mac->txrates_change(mac->dev, change); - - change = 0; - - bssinfo->supported_rates.count = 0; - memset(bssinfo->supported_rates.rates, 0, - sizeof(bssinfo->supported_rates.rates)); - change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES; - - bssinfo->short_preamble = 0; - change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE; - - bssinfo->use_protection = 0; - change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION; - - if (mac->bssinfo_change) - mac->bssinfo_change(mac->dev, change); + mac->txrates_change(mac->dev, change, &oldrates); mac->running = 1; } @@ -315,7 +273,7 @@ void ieee80211softmac_start(struct net_d struct ieee80211softmac_device *mac = ieee80211_priv(dev); ieee80211softmac_start_check_rates(mac); - ieee80211softmac_init_bss(mac); + ieee80211softmac_init_txrates(mac); } EXPORT_SYMBOL_GPL(ieee80211softmac_start); @@ -368,6 +326,7 @@ u8 ieee80211softmac_lower_rate_delta(str static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac, int amount) { + struct ieee80211softmac_txrates oldrates; u8 default_rate = mac->txrates.default_rate; u8 default_fallback = mac->txrates.default_fallback; u32 changes = 0; @@ -380,6 +339,8 @@ printk("badness %d\n", mac->txrate_badne mac->txrate_badness += amount; if (mac->txrate_badness <= -1000) { /* Very small badness. Try a faster bitrate. */ + if (mac->txrates_change) + memcpy(&oldrates, &mac->txrates, sizeof(oldrates)); default_rate = raise_rate(mac, default_rate); changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; default_fallback = get_fallback_rate(mac, default_rate); @@ -388,6 +349,8 @@ printk("badness %d\n", mac->txrate_badne printk("Bitrate raised to %u\n", default_rate); } else if (mac->txrate_badness >= 10000) { /* Very high badness. Try a slower bitrate. */ + if (mac->txrates_change) + memcpy(&oldrates, &mac->txrates, sizeof(oldrates)); default_rate = lower_rate(mac, default_rate); changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; default_fallback = get_fallback_rate(mac, default_rate); @@ -400,7 +363,7 @@ printk("Bitrate lowered to %u\n", defaul mac->txrates.default_fallback = default_fallback; if (changes && mac->txrates_change) - mac->txrates_change(mac->dev, changes); + mac->txrates_change(mac->dev, changes, &oldrates); } void ieee80211softmac_fragment_lost(struct net_device *dev, @@ -444,11 +407,7 @@ ieee80211softmac_create_network(struct i memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len); softnet->supported_rates.count += net->rates_ex_len; sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL); - - /* we save the ERP value because it is needed at association time, and - * many AP's do not include an ERP IE in the association response. */ - softnet->erp_value = net->erp_value; - + softnet->capabilities = net->capability; return softnet; } --- linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_priv.h.orig 2007-06-12 16:09:12.000000000 -0400 +++ linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_priv.h 2007-06-12 16:09:18.000000000 -0400 @@ -116,11 +116,9 @@ ieee80211softmac_get_network_by_essid(st struct ieee80211softmac_essid *essid); /* Rates related */ -void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac, - u8 erp_value); int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate); u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta); -void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac); +void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac); void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac); static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) { return ieee80211softmac_lower_rate_delta(mac, rate, 1); @@ -135,9 +133,6 @@ static inline u8 get_fallback_rate(struc /*** prototypes from _io.c */ int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac, void* ptrarg, u32 type, u32 arg); -int ieee80211softmac_handle_beacon(struct net_device *dev, - struct ieee80211_beacon *beacon, - struct ieee80211_network *network); /*** prototypes from _auth.c */ /* do these have to go into the public header? */ @@ -194,7 +189,6 @@ struct ieee80211softmac_network { authenticated:1, auth_desynced_once:1; - u8 erp_value; /* Saved ERP value */ u16 capabilities; /* Capabilities bitfield */ u8 challenge_len; /* Auth Challenge length */ char *challenge; /* Challenge Text */ --- linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_io.c.orig 2007-06-12 16:09:44.000000000 -0400 +++ linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_io.c 2007-06-12 16:12:00.000000000 -0400 @@ -467,22 +467,3 @@ ieee80211softmac_send_mgt_frame(struct i kfree(pkt); return 0; } - -/* Beacon handling */ -int ieee80211softmac_handle_beacon(struct net_device *dev, - struct ieee80211_beacon *beacon, - struct ieee80211_network *network) -{ - struct ieee80211softmac_device *mac = ieee80211_priv(dev); - - /* This might race, but we don't really care and it's not worth - * adding heavyweight locking in this fastpath. - */ - if (mac->associnfo.associated) { - if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) - ieee80211softmac_process_erp(mac, network->erp_value); - } - - return 0; -} - --- linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_wx.c.orig 2007-06-12 16:09:12.000000000 -0400 +++ linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_wx.c 2007-06-12 16:09:18.000000000 -0400 @@ -73,14 +73,13 @@ ieee80211softmac_wx_set_essid(struct net struct ieee80211softmac_network *n; struct ieee80211softmac_auth_queue_item *authptr; int length = 0; - - mutex_lock(&sm->associnfo.mutex); + unsigned long flags; /* Check if we're already associating to this or another network * If it's another network, cancel and start over with our new network * If it's our network, ignore the change, we're already doing it! */ - if((sm->associnfo.associating || sm->associnfo.associated) && + if((sm->associnfo.associating || sm->associated) && (data->essid.flags && data->essid.length && extra)) { /* Get the associating network */ n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); @@ -88,9 +87,10 @@ ieee80211softmac_wx_set_essid(struct net !memcmp(n->essid.data, extra, n->essid.len)) { dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", MAC_ARG(sm->associnfo.bssid)); - goto out; + return 0; } else { dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); + spin_lock_irqsave(&sm->lock,flags); /* Cancel assoc work */ cancel_delayed_work(&sm->associnfo.work); /* We don't have to do this, but it's a little cleaner */ @@ -98,13 +98,14 @@ ieee80211softmac_wx_set_essid(struct net cancel_delayed_work(&authptr->work); sm->associnfo.bssvalid = 0; sm->associnfo.bssfixed = 0; + spin_unlock_irqrestore(&sm->lock,flags); flush_scheduled_work(); - sm->associnfo.associating = 0; - sm->associnfo.associated = 0; } } + spin_lock_irqsave(&sm->lock, flags); + sm->associnfo.static_essid = 0; sm->associnfo.assoc_wait = 0; @@ -120,12 +121,10 @@ ieee80211softmac_wx_set_essid(struct net * If applicable, we have already copied the data in */ sm->associnfo.req_essid.len = length; - sm->associnfo.associating = 1; /* queue lower level code to do work (if necessary) */ schedule_work(&sm->associnfo.work); -out: - mutex_unlock(&sm->associnfo.mutex); + spin_unlock_irqrestore(&sm->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); @@ -137,8 +136,10 @@ ieee80211softmac_wx_get_essid(struct net char *extra) { struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); + unsigned long flags; - mutex_lock(&sm->associnfo.mutex); + /* avoid getting inconsistent information */ + spin_lock_irqsave(&sm->lock, flags); /* If all fails, return ANY (empty) */ data->essid.length = 0; data->essid.flags = 0; /* active */ @@ -151,13 +152,12 @@ ieee80211softmac_wx_get_essid(struct net } /* If we're associating/associated, return that */ - if (sm->associnfo.associated || sm->associnfo.associating) { + if (sm->associated || sm->associnfo.associating) { data->essid.length = sm->associnfo.associate_essid.len; data->essid.flags = 1; /* active */ memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); } - mutex_unlock(&sm->associnfo.mutex); - + spin_unlock_irqrestore(&sm->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); @@ -323,15 +323,15 @@ ieee80211softmac_wx_get_wap(struct net_d { struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); int err = 0; + unsigned long flags; - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); if (mac->associnfo.bssvalid) memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); else memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); data->ap_addr.sa_family = ARPHRD_ETHER; - mutex_unlock(&mac->associnfo.mutex); - + spin_unlock_irqrestore(&mac->lock, flags); return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); @@ -343,27 +343,28 @@ ieee80211softmac_wx_set_wap(struct net_d char *extra) { struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); + unsigned long flags; /* sanity check */ if (data->ap_addr.sa_family != ARPHRD_ETHER) { return -EINVAL; } - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); 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->associnfo.associated) + 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->associnfo.associated) { + if (mac->associnfo.associating || mac->associated) { /* bssid unchanged and associated or associating - just return */ goto out; } @@ -378,8 +379,7 @@ ieee80211softmac_wx_set_wap(struct net_d } out: - mutex_unlock(&mac->associnfo.mutex); - + spin_unlock_irqrestore(&mac->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); @@ -395,8 +395,7 @@ ieee80211softmac_wx_set_genie(struct net int err = 0; char *buf; int i; - - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); /* bleh. shouldn't be locked for that kmalloc... */ @@ -434,8 +433,6 @@ ieee80211softmac_wx_set_genie(struct net out: spin_unlock_irqrestore(&mac->lock, flags); - mutex_unlock(&mac->associnfo.mutex); - return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); @@ -450,8 +447,7 @@ ieee80211softmac_wx_get_genie(struct net unsigned long flags; int err = 0; int space = wrqu->data.length; - - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); wrqu->data.length = 0; @@ -464,8 +460,6 @@ ieee80211softmac_wx_get_genie(struct net err = -E2BIG; } spin_unlock_irqrestore(&mac->lock, flags); - mutex_unlock(&mac->associnfo.mutex); - return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); @@ -480,13 +474,10 @@ ieee80211softmac_wx_set_mlme(struct net_ struct iw_mlme *mlme = (struct iw_mlme *)extra; u16 reason = cpu_to_le16(mlme->reason_code); struct ieee80211softmac_network *net; - int err = -EINVAL; - - mutex_lock(&mac->associnfo.mutex); if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); - goto out; + return -EINVAL; } switch (mlme->cmd) { @@ -494,23 +485,14 @@ ieee80211softmac_wx_set_mlme(struct net_ net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); if (!net) { printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); - goto out; + return -EINVAL; } - err = ieee80211softmac_deauth_req(mac, net, reason); - goto out; + return ieee80211softmac_deauth_req(mac, net, reason); case IW_MLME_DISASSOC: ieee80211softmac_send_disassoc_req(mac, reason); - mac->associnfo.associated = 0; - mac->associnfo.associating = 0; - err = 0; - goto out; + return 0; default: - err = -EOPNOTSUPP; + return -EOPNOTSUPP; } - -out: - mutex_unlock(&mac->associnfo.mutex); - - return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); --- linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_assoc.c.orig 2007-06-12 16:09:12.000000000 -0400 +++ linux-2.6.18.noarch/net/ieee80211/softmac/ieee80211softmac_assoc.c 2007-06-12 16:09:18.000000000 -0400 @@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211s dprintk(KERN_INFO PFX "sent association request!\n"); spin_lock_irqsave(&mac->lock, flags); - mac->associnfo.associated = 0; /* just to make sure */ + mac->associated = 0; /* just to make sure */ /* Set a timer for timeout */ /* FIXME: make timeout configurable */ @@ -62,22 +62,24 @@ ieee80211softmac_assoc_timeout(void *d) { struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; struct ieee80211softmac_network *n; + unsigned long flags; - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); /* we might race against ieee80211softmac_handle_assoc_response, * so make sure only one of us does something */ - if (!mac->associnfo.associating) - goto out; + if (!mac->associnfo.associating) { + spin_unlock_irqrestore(&mac->lock, flags); + return; + } mac->associnfo.associating = 0; mac->associnfo.bssvalid = 0; - mac->associnfo.associated = 0; + mac->associated = 0; n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); + spin_unlock_irqrestore(&mac->lock, flags); dprintk(KERN_INFO PFX "assoc request timed out!\n"); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); -out: - mutex_unlock(&mac->associnfo.mutex); } void @@ -91,10 +93,10 @@ ieee80211softmac_disassoc(struct ieee802 netif_carrier_off(mac->dev); - mac->associnfo.associated = 0; + mac->associated = 0; mac->associnfo.bssvalid = 0; mac->associnfo.associating = 0; - ieee80211softmac_init_bss(mac); + ieee80211softmac_init_txrates(mac); ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); spin_unlock_irqrestore(&mac->lock, flags); } @@ -105,7 +107,7 @@ ieee80211softmac_send_disassoc_req(struc { struct ieee80211softmac_network *found; - if (mac->associnfo.bssvalid && mac->associnfo.associated) { + if (mac->associnfo.bssvalid && mac->associated) { found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); if (found) ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); @@ -194,18 +196,17 @@ ieee80211softmac_assoc_work(void *d) int bssvalid; unsigned long flags; - mutex_lock(&mac->associnfo.mutex); - - if (!mac->associnfo.associating) - goto out; - /* ieee80211_disassoc might clear this */ bssvalid = mac->associnfo.bssvalid; /* meh */ - if (mac->associnfo.associated) + if (mac->associated) ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); + spin_lock_irqsave(&mac->lock, flags); + mac->associnfo.associating = 1; + spin_unlock_irqrestore(&mac->lock, flags); + /* try to find the requested network in our list, if we found one already */ if (bssvalid || mac->associnfo.bssfixed) found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); @@ -259,8 +260,10 @@ ieee80211softmac_assoc_work(void *d) if (!found) { if (mac->associnfo.scan_retry > 0) { + spin_lock_irqsave(&mac->lock, flags); mac->associnfo.scan_retry--; - + spin_unlock_irqrestore(&mac->lock, flags); + /* We know of no such network. Let's scan. * NB: this also happens if we had no memory to copy the network info... * Maybe we can hope to have more memory after scanning finishes ;) @@ -269,17 +272,19 @@ ieee80211softmac_assoc_work(void *d) ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); if (ieee80211softmac_start_scan(mac)) dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); - goto out; + return; } else { + spin_lock_irqsave(&mac->lock, flags); mac->associnfo.associating = 0; - mac->associnfo.associated = 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); - goto out; + return; } } @@ -292,7 +297,7 @@ ieee80211softmac_assoc_work(void *d) /* copy the ESSID for displaying it */ mac->associnfo.associate_essid.len = found->essid.len; memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); - + /* we found a network! authenticate (if necessary) and associate to it. */ if (found->authenticating) { dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); @@ -300,7 +305,7 @@ ieee80211softmac_assoc_work(void *d) mac->associnfo.assoc_wait = 1; ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); } - goto out; + return; } if (!found->authenticated && !found->authenticating) { /* This relies on the fact that _auth_req only queues the work, @@ -316,14 +321,11 @@ ieee80211softmac_assoc_work(void *d) mac->associnfo.assoc_wait = 0; ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); } - goto out; + return; } /* finally! now we can start associating */ mac->associnfo.assoc_wait = 0; ieee80211softmac_assoc(mac, found); - -out: - mutex_unlock(&mac->associnfo.mutex); } /* call this to do whatever is necessary when we're associated */ @@ -332,19 +334,11 @@ ieee80211softmac_associated(struct ieee8 struct ieee80211_assoc_response * resp, struct ieee80211softmac_network *net) { - u16 cap = le16_to_cpu(resp->capability); - u8 erp_value = net->erp_value; - mac->associnfo.associating = 0; - mac->bssinfo.supported_rates = net->supported_rates; + mac->associnfo.supported_rates = net->supported_rates; ieee80211softmac_recalc_txrates(mac); - mac->associnfo.associated = 1; - - mac->associnfo.short_preamble_available = - (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; - ieee80211softmac_process_erp(mac, erp_value); - + mac->associated = 1; if (mac->set_bssid_filter) mac->set_bssid_filter(mac->dev, net->bssid); memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN); @@ -357,9 +351,9 @@ ieee80211softmac_associated(struct ieee8 int ieee80211softmac_handle_assoc_response(struct net_device * dev, struct ieee80211_assoc_response * resp, - struct ieee80211_network * _ieee80211_network) + struct ieee80211_network * _ieee80211_network_do_not_use) { - /* NOTE: the network parameter has to be mostly ignored by + /* NOTE: the network parameter has to be ignored by * this code because it is the ieee80211's pointer * to the struct, not ours (we made a copy) */ @@ -391,11 +385,6 @@ ieee80211softmac_handle_assoc_response(s /* now that we know it was for us, we can cancel the timeout */ cancel_delayed_work(&mac->associnfo.timeout); - /* if the association response included an ERP IE, update our saved - * copy */ - if (_ieee80211_network->flags & NETWORK_HAS_ERP_VALUE) - network->erp_value = _ieee80211_network->erp_value; - switch (status) { case 0: dprintk(KERN_INFO PFX "associated!\n"); @@ -419,7 +408,7 @@ ieee80211softmac_handle_assoc_response(s dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); mac->associnfo.associating = 0; mac->associnfo.bssvalid = 0; - mac->associnfo.associated = 0; + mac->associated = 0; ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); } --- linux-2.6.18.noarch/net/ieee80211/ieee80211_rx.c.orig 2007-06-12 16:09:12.000000000 -0400 +++ linux-2.6.18.noarch/net/ieee80211/ieee80211_rx.c 2007-06-12 16:09:18.000000000 -0400 @@ -479,11 +479,6 @@ int ieee80211_rx(struct ieee80211_device goto rx_exit; } #endif - /* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */ - if (sc == ieee->prev_seq_ctl) - goto rx_dropped; - else - ieee->prev_seq_ctl = sc; /* Data frame - extract src/dst addresses */ if (skb->len < IEEE80211_3ADDR_LEN)