aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/main.c')
-rw-r--r--drivers/net/wireless/libertas/main.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index bd32ac0b4e07..73dc8c72402a 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -291,9 +291,11 @@ static ssize_t lbs_rtap_set(struct device *dev,
291 if (priv->infra_open || priv->mesh_open) 291 if (priv->infra_open || priv->mesh_open)
292 return -EBUSY; 292 return -EBUSY;
293 if (priv->mode == IW_MODE_INFRA) 293 if (priv->mode == IW_MODE_INFRA)
294 lbs_send_deauthentication(priv); 294 lbs_cmd_80211_deauthenticate(priv,
295 priv->curbssparams.bssid,
296 WLAN_REASON_DEAUTH_LEAVING);
295 else if (priv->mode == IW_MODE_ADHOC) 297 else if (priv->mode == IW_MODE_ADHOC)
296 lbs_stop_adhoc_network(priv); 298 lbs_adhoc_stop(priv);
297 lbs_add_rtap(priv); 299 lbs_add_rtap(priv);
298 } 300 }
299 priv->monitormode = monitor_mode; 301 priv->monitormode = monitor_mode;
@@ -956,17 +958,24 @@ EXPORT_SYMBOL_GPL(lbs_resume);
956static int lbs_setup_firmware(struct lbs_private *priv) 958static int lbs_setup_firmware(struct lbs_private *priv)
957{ 959{
958 int ret = -1; 960 int ret = -1;
961 s16 curlevel = 0, minlevel = 0, maxlevel = 0;
959 962
960 lbs_deb_enter(LBS_DEB_FW); 963 lbs_deb_enter(LBS_DEB_FW);
961 964
962 /* 965 /* Read MAC address from firmware */
963 * Read MAC address from HW
964 */
965 memset(priv->current_addr, 0xff, ETH_ALEN); 966 memset(priv->current_addr, 0xff, ETH_ALEN);
966 ret = lbs_update_hw_spec(priv); 967 ret = lbs_update_hw_spec(priv);
967 if (ret) 968 if (ret)
968 goto done; 969 goto done;
969 970
971 /* Read power levels if available */
972 ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
973 if (ret == 0) {
974 priv->txpower_cur = curlevel;
975 priv->txpower_min = minlevel;
976 priv->txpower_max = maxlevel;
977 }
978
970 lbs_set_mac_control(priv); 979 lbs_set_mac_control(priv);
971done: 980done:
972 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); 981 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
@@ -1042,7 +1051,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
1042 priv->mode = IW_MODE_INFRA; 1051 priv->mode = IW_MODE_INFRA;
1043 priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; 1052 priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
1044 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 1053 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
1045 priv->radioon = RADIO_ON; 1054 priv->radio_on = 1;
1046 priv->enablehwauto = 1; 1055 priv->enablehwauto = 1;
1047 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; 1056 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
1048 priv->psmode = LBS802_11POWERMODECAM; 1057 priv->psmode = LBS802_11POWERMODECAM;
@@ -1196,7 +1205,13 @@ void lbs_remove_card(struct lbs_private *priv)
1196 cancel_delayed_work_sync(&priv->scan_work); 1205 cancel_delayed_work_sync(&priv->scan_work);
1197 cancel_delayed_work_sync(&priv->assoc_work); 1206 cancel_delayed_work_sync(&priv->assoc_work);
1198 cancel_work_sync(&priv->mcast_work); 1207 cancel_work_sync(&priv->mcast_work);
1208
1209 /* worker thread destruction blocks on the in-flight command which
1210 * should have been cleared already in lbs_stop_card().
1211 */
1212 lbs_deb_main("destroying worker thread\n");
1199 destroy_workqueue(priv->work_thread); 1213 destroy_workqueue(priv->work_thread);
1214 lbs_deb_main("done destroying worker thread\n");
1200 1215
1201 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { 1216 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
1202 priv->psmode = LBS802_11POWERMODECAM; 1217 priv->psmode = LBS802_11POWERMODECAM;
@@ -1314,14 +1329,26 @@ void lbs_stop_card(struct lbs_private *priv)
1314 device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1329 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1315 } 1330 }
1316 1331
1317 /* Flush pending command nodes */ 1332 /* Delete the timeout of the currently processing command */
1318 del_timer_sync(&priv->command_timer); 1333 del_timer_sync(&priv->command_timer);
1334
1335 /* Flush pending command nodes */
1319 spin_lock_irqsave(&priv->driver_lock, flags); 1336 spin_lock_irqsave(&priv->driver_lock, flags);
1337 lbs_deb_main("clearing pending commands\n");
1320 list_for_each_entry(cmdnode, &priv->cmdpendingq, list) { 1338 list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
1321 cmdnode->result = -ENOENT; 1339 cmdnode->result = -ENOENT;
1322 cmdnode->cmdwaitqwoken = 1; 1340 cmdnode->cmdwaitqwoken = 1;
1323 wake_up_interruptible(&cmdnode->cmdwait_q); 1341 wake_up_interruptible(&cmdnode->cmdwait_q);
1324 } 1342 }
1343
1344 /* Flush the command the card is currently processing */
1345 if (priv->cur_cmd) {
1346 lbs_deb_main("clearing current command\n");
1347 priv->cur_cmd->result = -ENOENT;
1348 priv->cur_cmd->cmdwaitqwoken = 1;
1349 wake_up_interruptible(&priv->cur_cmd->cmdwait_q);
1350 }
1351 lbs_deb_main("done clearing commands\n");
1325 spin_unlock_irqrestore(&priv->driver_lock, flags); 1352 spin_unlock_irqrestore(&priv->driver_lock, flags);
1326 1353
1327 unregister_netdev(dev); 1354 unregister_netdev(dev);