diff options
Diffstat (limited to 'drivers/net/wireless/libertas/main.c')
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 41 |
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); | |||
956 | static int lbs_setup_firmware(struct lbs_private *priv) | 958 | static 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); |
971 | done: | 980 | done: |
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); |