aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKiran Divekar <dkiran@marvell.com>2010-06-05 02:20:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-23 15:13:59 -0400
commite4fe4eafa41cf951fb8fe2b9725ae84c599668d8 (patch)
treecf943b3f3be3f70f74edad6923234d425ba59a8b
parente86dc1ca4676445d9f0dfe35104efe0eb8a2f566 (diff)
Libertas: fix WARN_ON issues in cfg80211 support
In following scenarios WARN_ON() in cfg80211 code was triggered. a) Driver unload or card removal. b) Disconnect from infra network c) Adhoc start/join d) Adhoc stop Added following fixes to avoid WARN_ON() in cfg80211 code. a) Ensured that cfg80211_disconnected() function defined in cfg80211 code will be called only in infra mode. b) Solved timing issue by moving cfg80211_disconnected() call inside lbs_cfg_disconnect(). c) Updated "wdev->ssid" in driver code after Adhoc join/start d) Removed unnecessory cfg80211_disconnected() call in lbs_remove_card. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/libertas/cfg.c37
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c4
-rw-r--r--drivers/net/wireless/libertas/main.c2
3 files changed, 15 insertions, 28 deletions
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 682b276f06f9..089f0722fa20 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1238,28 +1238,6 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1238 return ret; 1238 return ret;
1239} 1239}
1240 1240
1241
1242
1243
1244/* callback from lbs_cfg_disconnect() */
1245static int lbs_cfg_ret_disconnect(struct lbs_private *priv, unsigned long dummy,
1246 struct cmd_header *resp)
1247{
1248 lbs_deb_enter(LBS_DEB_CFG80211);
1249
1250 cfg80211_disconnected(priv->dev,
1251 priv->disassoc_reason,
1252 NULL, 0, /* TODO? */
1253 GFP_KERNEL);
1254
1255 /* TODO: get rid of priv->connect_status */
1256 priv->connect_status = LBS_CONNECTED;
1257
1258 lbs_deb_leave(LBS_DEB_CFG80211);
1259 return 0;
1260}
1261
1262
1263static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev, 1241static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1264 u16 reason_code) 1242 u16 reason_code)
1265{ 1243{
@@ -1277,9 +1255,14 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1277 memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN); 1255 memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
1278 cmd.reasoncode = cpu_to_le16(reason_code); 1256 cmd.reasoncode = cpu_to_le16(reason_code);
1279 1257
1280 __lbs_cmd_async(priv, CMD_802_11_DEAUTHENTICATE, 1258 if (lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd))
1281 &cmd.hdr, sizeof(cmd), 1259 return -EFAULT;
1282 lbs_cfg_ret_disconnect, 0); 1260
1261 cfg80211_disconnected(priv->dev,
1262 priv->disassoc_reason,
1263 NULL, 0,
1264 GFP_KERNEL);
1265 priv->connect_status = LBS_DISCONNECTED;
1283 1266
1284 return 0; 1267 return 0;
1285} 1268}
@@ -1673,6 +1656,10 @@ static void lbs_join_post(struct lbs_private *priv,
1673 params->beacon_interval, 1656 params->beacon_interval,
1674 fake_ie, fake - fake_ie, 1657 fake_ie, fake - fake_ie,
1675 0, GFP_KERNEL); 1658 0, GFP_KERNEL);
1659
1660 memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
1661 priv->wdev->ssid_len = params->ssid_len;
1662
1676 cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL); 1663 cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
1677 1664
1678 /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */ 1665 /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 9c18227ecc75..52b543c52a93 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -31,7 +31,9 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
31 * It causes problem in the Supplicant 31 * It causes problem in the Supplicant
32 */ 32 */
33 msleep_interruptible(1000); 33 msleep_interruptible(1000);
34 lbs_send_disconnect_notification(priv); 34
35 if (priv->wdev->iftype == NL80211_IFTYPE_STATION)
36 lbs_send_disconnect_notification(priv);
35 37
36 /* report disconnect to upper layer */ 38 /* report disconnect to upper layer */
37 netif_stop_queue(priv->dev); 39 netif_stop_queue(priv->dev);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 51b7e1923ab2..58b031c52410 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -932,8 +932,6 @@ void lbs_remove_card(struct lbs_private *priv)
932 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); 932 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
933 } 933 }
934 934
935 lbs_send_disconnect_notification(priv);
936
937 if (priv->is_deep_sleep) { 935 if (priv->is_deep_sleep) {
938 priv->is_deep_sleep = 0; 936 priv->is_deep_sleep = 0;
939 wake_up_interruptible(&priv->ds_awake_q); 937 wake_up_interruptible(&priv->ds_awake_q);