|
@@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
|
|
struct ieee80211softmac_network *n;
|
|
struct ieee80211softmac_network *n;
|
|
struct ieee80211softmac_auth_queue_item *authptr;
|
|
struct ieee80211softmac_auth_queue_item *authptr;
|
|
int length = 0;
|
|
int length = 0;
|
|
- unsigned long flags;
|
|
|
|
|
|
+
|
|
|
|
+ mutex_lock(&sm->associnfo.mutex);
|
|
|
|
|
|
/* Check if we're already associating to this or another network
|
|
/* 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 another network, cancel and start over with our new network
|
|
* If it's our network, ignore the change, we're already doing it!
|
|
* If it's our network, ignore the change, we're already doing it!
|
|
*/
|
|
*/
|
|
- if((sm->associnfo.associating || sm->associated) &&
|
|
|
|
|
|
+ if((sm->associnfo.associating || sm->associnfo.associated) &&
|
|
(data->essid.flags && data->essid.length)) {
|
|
(data->essid.flags && data->essid.length)) {
|
|
/* Get the associating network */
|
|
/* Get the associating network */
|
|
n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
|
|
n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
|
|
@@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
|
|
!memcmp(n->essid.data, extra, n->essid.len)) {
|
|
!memcmp(n->essid.data, extra, n->essid.len)) {
|
|
dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
|
|
dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
|
|
MAC_ARG(sm->associnfo.bssid));
|
|
MAC_ARG(sm->associnfo.bssid));
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
} else {
|
|
} else {
|
|
dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
|
|
dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
|
|
- spin_lock_irqsave(&sm->lock,flags);
|
|
|
|
/* Cancel assoc work */
|
|
/* Cancel assoc work */
|
|
cancel_delayed_work(&sm->associnfo.work);
|
|
cancel_delayed_work(&sm->associnfo.work);
|
|
/* We don't have to do this, but it's a little cleaner */
|
|
/* We don't have to do this, but it's a little cleaner */
|
|
@@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
|
|
cancel_delayed_work(&authptr->work);
|
|
cancel_delayed_work(&authptr->work);
|
|
sm->associnfo.bssvalid = 0;
|
|
sm->associnfo.bssvalid = 0;
|
|
sm->associnfo.bssfixed = 0;
|
|
sm->associnfo.bssfixed = 0;
|
|
- spin_unlock_irqrestore(&sm->lock,flags);
|
|
|
|
flush_scheduled_work();
|
|
flush_scheduled_work();
|
|
|
|
+ sm->associnfo.associating = 0;
|
|
|
|
+ sm->associnfo.associated = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- spin_lock_irqsave(&sm->lock, flags);
|
|
|
|
-
|
|
|
|
sm->associnfo.static_essid = 0;
|
|
sm->associnfo.static_essid = 0;
|
|
sm->associnfo.assoc_wait = 0;
|
|
sm->associnfo.assoc_wait = 0;
|
|
|
|
|
|
@@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
|
|
* If applicable, we have already copied the data in */
|
|
* If applicable, we have already copied the data in */
|
|
sm->associnfo.req_essid.len = length;
|
|
sm->associnfo.req_essid.len = length;
|
|
|
|
|
|
|
|
+ sm->associnfo.associating = 1;
|
|
/* queue lower level code to do work (if necessary) */
|
|
/* queue lower level code to do work (if necessary) */
|
|
schedule_work(&sm->associnfo.work);
|
|
schedule_work(&sm->associnfo.work);
|
|
|
|
+out:
|
|
|
|
+ mutex_unlock(&sm->associnfo.mutex);
|
|
|
|
|
|
- spin_unlock_irqrestore(&sm->lock, flags);
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
|
|
@@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
|
|
char *extra)
|
|
char *extra)
|
|
{
|
|
{
|
|
struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
|
|
struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
|
|
- unsigned long flags;
|
|
|
|
|
|
|
|
- /* avoid getting inconsistent information */
|
|
|
|
- spin_lock_irqsave(&sm->lock, flags);
|
|
|
|
|
|
+ mutex_lock(&sm->associnfo.mutex);
|
|
/* If all fails, return ANY (empty) */
|
|
/* If all fails, return ANY (empty) */
|
|
data->essid.length = 0;
|
|
data->essid.length = 0;
|
|
data->essid.flags = 0; /* active */
|
|
data->essid.flags = 0; /* active */
|
|
@@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
|
|
}
|
|
}
|
|
|
|
|
|
/* If we're associating/associated, return that */
|
|
/* If we're associating/associated, return that */
|
|
- if (sm->associated || sm->associnfo.associating) {
|
|
|
|
|
|
+ if (sm->associnfo.associated || sm->associnfo.associating) {
|
|
data->essid.length = sm->associnfo.associate_essid.len;
|
|
data->essid.length = sm->associnfo.associate_essid.len;
|
|
data->essid.flags = 1; /* active */
|
|
data->essid.flags = 1; /* active */
|
|
memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
|
|
memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
|
|
}
|
|
}
|
|
- spin_unlock_irqrestore(&sm->lock, flags);
|
|
|
|
|
|
+ mutex_unlock(&sm->associnfo.mutex);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
|
|
@@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_device *net_dev,
|
|
{
|
|
{
|
|
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
|
|
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
|
|
int err = 0;
|
|
int err = 0;
|
|
- unsigned long flags;
|
|
|
|
|
|
|
|
- spin_lock_irqsave(&mac->lock, flags);
|
|
|
|
|
|
+ mutex_lock(&mac->associnfo.mutex);
|
|
if (mac->associnfo.bssvalid)
|
|
if (mac->associnfo.bssvalid)
|
|
memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
|
|
memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
|
|
else
|
|
else
|
|
memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
|
|
memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
|
|
data->ap_addr.sa_family = ARPHRD_ETHER;
|
|
data->ap_addr.sa_family = ARPHRD_ETHER;
|
|
- spin_unlock_irqrestore(&mac->lock, flags);
|
|
|
|
|
|
+ mutex_unlock(&mac->associnfo.mutex);
|
|
|
|
+
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
|
|
@@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
|
|
char *extra)
|
|
char *extra)
|
|
{
|
|
{
|
|
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
|
|
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
|
|
- unsigned long flags;
|
|
|
|
|
|
|
|
/* sanity check */
|
|
/* sanity check */
|
|
if (data->ap_addr.sa_family != ARPHRD_ETHER) {
|
|
if (data->ap_addr.sa_family != ARPHRD_ETHER) {
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- spin_lock_irqsave(&mac->lock, flags);
|
|
|
|
|
|
+ mutex_lock(&mac->associnfo.mutex);
|
|
if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
|
|
if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
|
|
/* the bssid we have is not to be fixed any longer,
|
|
/* the bssid we have is not to be fixed any longer,
|
|
* and we should reassociate to the best AP. */
|
|
* and we should reassociate to the best AP. */
|
|
mac->associnfo.bssfixed = 0;
|
|
mac->associnfo.bssfixed = 0;
|
|
/* force reassociation */
|
|
/* force reassociation */
|
|
mac->associnfo.bssvalid = 0;
|
|
mac->associnfo.bssvalid = 0;
|
|
- if (mac->associated)
|
|
|
|
|
|
+ if (mac->associnfo.associated)
|
|
schedule_work(&mac->associnfo.work);
|
|
schedule_work(&mac->associnfo.work);
|
|
} else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
|
|
} else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
|
|
/* the bssid we have is no longer fixed */
|
|
/* the bssid we have is no longer fixed */
|
|
mac->associnfo.bssfixed = 0;
|
|
mac->associnfo.bssfixed = 0;
|
|
} else {
|
|
} else {
|
|
if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
|
|
if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
|
|
- if (mac->associnfo.associating || mac->associated) {
|
|
|
|
|
|
+ if (mac->associnfo.associating || mac->associnfo.associated) {
|
|
/* bssid unchanged and associated or associating - just return */
|
|
/* bssid unchanged and associated or associating - just return */
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
|
|
}
|
|
}
|
|
|
|
|
|
out:
|
|
out:
|
|
- spin_unlock_irqrestore(&mac->lock, flags);
|
|
|
|
|
|
+ mutex_unlock(&mac->associnfo.mutex);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
|
|
@@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
|
|
int err = 0;
|
|
int err = 0;
|
|
char *buf;
|
|
char *buf;
|
|
int i;
|
|
int i;
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ mutex_lock(&mac->associnfo.mutex);
|
|
spin_lock_irqsave(&mac->lock, flags);
|
|
spin_lock_irqsave(&mac->lock, flags);
|
|
/* bleh. shouldn't be locked for that kmalloc... */
|
|
/* bleh. shouldn't be locked for that kmalloc... */
|
|
|
|
|
|
@@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
|
|
|
|
|
|
out:
|
|
out:
|
|
spin_unlock_irqrestore(&mac->lock, flags);
|
|
spin_unlock_irqrestore(&mac->lock, flags);
|
|
|
|
+ mutex_unlock(&mac->associnfo.mutex);
|
|
|
|
+
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
|
|
@@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
int err = 0;
|
|
int err = 0;
|
|
int space = wrqu->data.length;
|
|
int space = wrqu->data.length;
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ mutex_lock(&mac->associnfo.mutex);
|
|
spin_lock_irqsave(&mac->lock, flags);
|
|
spin_lock_irqsave(&mac->lock, flags);
|
|
|
|
|
|
wrqu->data.length = 0;
|
|
wrqu->data.length = 0;
|
|
@@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
|
|
err = -E2BIG;
|
|
err = -E2BIG;
|
|
}
|
|
}
|
|
spin_unlock_irqrestore(&mac->lock, flags);
|
|
spin_unlock_irqrestore(&mac->lock, flags);
|
|
|
|
+ mutex_lock(&mac->associnfo.mutex);
|
|
|
|
+
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
|
|
@@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
|
|
struct iw_mlme *mlme = (struct iw_mlme *)extra;
|
|
struct iw_mlme *mlme = (struct iw_mlme *)extra;
|
|
u16 reason = cpu_to_le16(mlme->reason_code);
|
|
u16 reason = cpu_to_le16(mlme->reason_code);
|
|
struct ieee80211softmac_network *net;
|
|
struct ieee80211softmac_network *net;
|
|
|
|
+ int err = -EINVAL;
|
|
|
|
+
|
|
|
|
+ mutex_lock(&mac->associnfo.mutex);
|
|
|
|
|
|
if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
|
|
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");
|
|
printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
|
|
- return -EINVAL;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
switch (mlme->cmd) {
|
|
switch (mlme->cmd) {
|
|
@@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
|
|
net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
|
|
net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
|
|
if (!net) {
|
|
if (!net) {
|
|
printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
|
|
printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
|
|
- return -EINVAL;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
return ieee80211softmac_deauth_req(mac, net, reason);
|
|
return ieee80211softmac_deauth_req(mac, net, reason);
|
|
case IW_MLME_DISASSOC:
|
|
case IW_MLME_DISASSOC:
|
|
ieee80211softmac_send_disassoc_req(mac, reason);
|
|
ieee80211softmac_send_disassoc_req(mac, reason);
|
|
- return 0;
|
|
|
|
|
|
+ mac->associnfo.associated = 0;
|
|
|
|
+ mac->associnfo.associating = 0;
|
|
|
|
+ err = 0;
|
|
|
|
+ goto out;
|
|
default:
|
|
default:
|
|
- return -EOPNOTSUPP;
|
|
|
|
|
|
+ err = -EOPNOTSUPP;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ mutex_unlock(&mac->associnfo.mutex);
|
|
|
|
+
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);
|
|
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);
|