diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_main.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 149 |
1 files changed, 128 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 20a2c1341e20..eb7722b2cfcc 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -65,6 +65,56 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | |||
| 65 | return mode; | 65 | return mode; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | ||
| 69 | enum ath9k_power_mode mode) | ||
| 70 | { | ||
| 71 | bool ret; | ||
| 72 | |||
| 73 | mutex_lock(&priv->htc_pm_lock); | ||
| 74 | ret = ath9k_hw_setpower(priv->ah, mode); | ||
| 75 | mutex_unlock(&priv->htc_pm_lock); | ||
| 76 | |||
| 77 | return ret; | ||
| 78 | } | ||
| 79 | |||
| 80 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv) | ||
| 81 | { | ||
| 82 | mutex_lock(&priv->htc_pm_lock); | ||
| 83 | if (++priv->ps_usecount != 1) | ||
| 84 | goto unlock; | ||
| 85 | ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE); | ||
| 86 | |||
| 87 | unlock: | ||
| 88 | mutex_unlock(&priv->htc_pm_lock); | ||
| 89 | } | ||
| 90 | |||
| 91 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv) | ||
| 92 | { | ||
| 93 | mutex_lock(&priv->htc_pm_lock); | ||
| 94 | if (--priv->ps_usecount != 0) | ||
| 95 | goto unlock; | ||
| 96 | |||
| 97 | if (priv->ps_enabled) | ||
| 98 | ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); | ||
| 99 | unlock: | ||
| 100 | mutex_unlock(&priv->htc_pm_lock); | ||
| 101 | } | ||
| 102 | |||
| 103 | void ath9k_ps_work(struct work_struct *work) | ||
| 104 | { | ||
| 105 | struct ath9k_htc_priv *priv = | ||
| 106 | container_of(work, struct ath9k_htc_priv, | ||
| 107 | ps_work); | ||
| 108 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | ||
| 109 | |||
| 110 | /* The chip wakes up after receiving the first beacon | ||
| 111 | while network sleep is enabled. For the driver to | ||
| 112 | be in sync with the hw, set the chip to awake and | ||
| 113 | only then set it to sleep. | ||
| 114 | */ | ||
| 115 | ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); | ||
| 116 | } | ||
| 117 | |||
| 68 | static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | 118 | static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, |
| 69 | struct ieee80211_hw *hw, | 119 | struct ieee80211_hw *hw, |
| 70 | struct ath9k_channel *hchan) | 120 | struct ath9k_channel *hchan) |
| @@ -87,7 +137,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
| 87 | 137 | ||
| 88 | /* Fiddle around with fastcc later on, for now just use full reset */ | 138 | /* Fiddle around with fastcc later on, for now just use full reset */ |
| 89 | fastcc = false; | 139 | fastcc = false; |
| 90 | 140 | ath9k_htc_ps_wakeup(priv); | |
| 91 | htc_stop(priv->htc); | 141 | htc_stop(priv->htc); |
| 92 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 142 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
| 93 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 143 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
| @@ -103,6 +153,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
| 103 | ath_print(common, ATH_DBG_FATAL, | 153 | ath_print(common, ATH_DBG_FATAL, |
| 104 | "Unable to reset channel (%u Mhz) " | 154 | "Unable to reset channel (%u Mhz) " |
| 105 | "reset status %d\n", channel->center_freq, ret); | 155 | "reset status %d\n", channel->center_freq, ret); |
| 156 | ath9k_htc_ps_restore(priv); | ||
| 106 | goto err; | 157 | goto err; |
| 107 | } | 158 | } |
| 108 | 159 | ||
| @@ -128,6 +179,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
| 128 | 179 | ||
| 129 | priv->op_flags &= ~OP_FULL_RESET; | 180 | priv->op_flags &= ~OP_FULL_RESET; |
| 130 | err: | 181 | err: |
| 182 | ath9k_htc_ps_restore(priv); | ||
| 131 | return ret; | 183 | return ret; |
| 132 | } | 184 | } |
| 133 | 185 | ||
| @@ -412,32 +464,31 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv, | |||
| 412 | if (tid > ATH9K_HTC_MAX_TID) | 464 | if (tid > ATH9K_HTC_MAX_TID) |
| 413 | return -EINVAL; | 465 | return -EINVAL; |
| 414 | 466 | ||
| 467 | memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr)); | ||
| 468 | |||
| 415 | rcu_read_lock(); | 469 | rcu_read_lock(); |
| 470 | |||
| 471 | /* Check if we are able to retrieve the station */ | ||
| 416 | sta = ieee80211_find_sta(vif, sta_addr); | 472 | sta = ieee80211_find_sta(vif, sta_addr); |
| 417 | if (sta) { | 473 | if (!sta) { |
| 418 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
| 419 | } else { | ||
| 420 | rcu_read_unlock(); | 474 | rcu_read_unlock(); |
| 421 | return -EINVAL; | 475 | return -EINVAL; |
| 422 | } | 476 | } |
| 423 | 477 | ||
| 424 | if (!ista) { | 478 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
| 425 | rcu_read_unlock(); | ||
| 426 | return -EINVAL; | ||
| 427 | } | ||
| 428 | 479 | ||
| 429 | memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr)); | 480 | if (oper) |
| 481 | ista->tid_state[tid] = AGGR_START; | ||
| 482 | else | ||
| 483 | ista->tid_state[tid] = AGGR_STOP; | ||
| 430 | 484 | ||
| 431 | aggr.sta_index = ista->index; | 485 | aggr.sta_index = ista->index; |
| 486 | |||
| 432 | rcu_read_unlock(); | 487 | rcu_read_unlock(); |
| 488 | |||
| 433 | aggr.tidno = tid; | 489 | aggr.tidno = tid; |
| 434 | aggr.aggr_enable = oper; | 490 | aggr.aggr_enable = oper; |
| 435 | 491 | ||
| 436 | if (oper) | ||
| 437 | ista->tid_state[tid] = AGGR_START; | ||
| 438 | else | ||
| 439 | ista->tid_state[tid] = AGGR_STOP; | ||
| 440 | |||
| 441 | WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); | 492 | WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); |
| 442 | if (ret) | 493 | if (ret) |
| 443 | ath_print(common, ATH_DBG_CONFIG, | 494 | ath_print(common, ATH_DBG_CONFIG, |
| @@ -694,6 +745,10 @@ void ath9k_ani_work(struct work_struct *work) | |||
| 694 | 745 | ||
| 695 | short_cal_interval = ATH_STA_SHORT_CALINTERVAL; | 746 | short_cal_interval = ATH_STA_SHORT_CALINTERVAL; |
| 696 | 747 | ||
| 748 | /* Only calibrate if awake */ | ||
| 749 | if (ah->power_mode != ATH9K_PM_AWAKE) | ||
| 750 | goto set_timer; | ||
| 751 | |||
| 697 | /* Long calibration runs independently of short calibration. */ | 752 | /* Long calibration runs independently of short calibration. */ |
| 698 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { | 753 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { |
| 699 | longcal = true; | 754 | longcal = true; |
| @@ -728,6 +783,9 @@ void ath9k_ani_work(struct work_struct *work) | |||
| 728 | 783 | ||
| 729 | /* Skip all processing if there's nothing to do. */ | 784 | /* Skip all processing if there's nothing to do. */ |
| 730 | if (longcal || shortcal || aniflag) { | 785 | if (longcal || shortcal || aniflag) { |
| 786 | |||
| 787 | ath9k_htc_ps_wakeup(priv); | ||
| 788 | |||
| 731 | /* Call ANI routine if necessary */ | 789 | /* Call ANI routine if necessary */ |
| 732 | if (aniflag) | 790 | if (aniflag) |
| 733 | ath9k_hw_ani_monitor(ah, ah->curchan); | 791 | ath9k_hw_ani_monitor(ah, ah->curchan); |
| @@ -749,8 +807,11 @@ void ath9k_ani_work(struct work_struct *work) | |||
| 749 | ah->curchan->channelFlags, | 807 | ah->curchan->channelFlags, |
| 750 | common->ani.noise_floor); | 808 | common->ani.noise_floor); |
| 751 | } | 809 | } |
| 810 | |||
| 811 | ath9k_htc_ps_restore(priv); | ||
| 752 | } | 812 | } |
| 753 | 813 | ||
| 814 | set_timer: | ||
| 754 | /* | 815 | /* |
| 755 | * Set timer interval based on previous results. | 816 | * Set timer interval based on previous results. |
| 756 | * The interval must be the shortest necessary to satisfy ANI, | 817 | * The interval must be the shortest necessary to satisfy ANI, |
| @@ -995,7 +1056,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 995 | { | 1056 | { |
| 996 | struct ieee80211_hdr *hdr; | 1057 | struct ieee80211_hdr *hdr; |
| 997 | struct ath9k_htc_priv *priv = hw->priv; | 1058 | struct ath9k_htc_priv *priv = hw->priv; |
| 998 | int padpos, padsize; | 1059 | int padpos, padsize, ret; |
| 999 | 1060 | ||
| 1000 | hdr = (struct ieee80211_hdr *) skb->data; | 1061 | hdr = (struct ieee80211_hdr *) skb->data; |
| 1001 | 1062 | ||
| @@ -1009,8 +1070,19 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 1009 | memmove(skb->data, skb->data + padsize, padpos); | 1070 | memmove(skb->data, skb->data + padsize, padpos); |
| 1010 | } | 1071 | } |
| 1011 | 1072 | ||
| 1012 | if (ath9k_htc_tx_start(priv, skb) != 0) { | 1073 | ret = ath9k_htc_tx_start(priv, skb); |
| 1013 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Tx failed"); | 1074 | if (ret != 0) { |
| 1075 | if (ret == -ENOMEM) { | ||
| 1076 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
| 1077 | "Stopping TX queues\n"); | ||
| 1078 | ieee80211_stop_queues(hw); | ||
| 1079 | spin_lock_bh(&priv->tx_lock); | ||
| 1080 | priv->tx_queues_stop = true; | ||
| 1081 | spin_unlock_bh(&priv->tx_lock); | ||
| 1082 | } else { | ||
| 1083 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
| 1084 | "Tx failed"); | ||
| 1085 | } | ||
| 1014 | goto fail_tx; | 1086 | goto fail_tx; |
| 1015 | } | 1087 | } |
| 1016 | 1088 | ||
| @@ -1075,6 +1147,12 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
| 1075 | priv->op_flags &= ~OP_INVALID; | 1147 | priv->op_flags &= ~OP_INVALID; |
| 1076 | htc_start(priv->htc); | 1148 | htc_start(priv->htc); |
| 1077 | 1149 | ||
| 1150 | spin_lock_bh(&priv->tx_lock); | ||
| 1151 | priv->tx_queues_stop = false; | ||
| 1152 | spin_unlock_bh(&priv->tx_lock); | ||
| 1153 | |||
| 1154 | ieee80211_wake_queues(hw); | ||
| 1155 | |||
| 1078 | mutex_unlock: | 1156 | mutex_unlock: |
| 1079 | mutex_unlock(&priv->mutex); | 1157 | mutex_unlock(&priv->mutex); |
| 1080 | return ret; | 1158 | return ret; |
| @@ -1096,6 +1174,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 1096 | return; | 1174 | return; |
| 1097 | } | 1175 | } |
| 1098 | 1176 | ||
| 1177 | ath9k_htc_ps_wakeup(priv); | ||
| 1099 | htc_stop(priv->htc); | 1178 | htc_stop(priv->htc); |
| 1100 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 1179 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
| 1101 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 1180 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
| @@ -1103,8 +1182,10 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 1103 | ath9k_hw_phy_disable(ah); | 1182 | ath9k_hw_phy_disable(ah); |
| 1104 | ath9k_hw_disable(ah); | 1183 | ath9k_hw_disable(ah); |
| 1105 | ath9k_hw_configpcipowersave(ah, 1, 1); | 1184 | ath9k_hw_configpcipowersave(ah, 1, 1); |
| 1106 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 1185 | ath9k_htc_ps_restore(priv); |
| 1186 | ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); | ||
| 1107 | 1187 | ||
| 1188 | cancel_work_sync(&priv->ps_work); | ||
| 1108 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | 1189 | cancel_delayed_work_sync(&priv->ath9k_ani_work); |
| 1109 | cancel_delayed_work_sync(&priv->ath9k_aggr_work); | 1190 | cancel_delayed_work_sync(&priv->ath9k_aggr_work); |
| 1110 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | 1191 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); |
| @@ -1145,6 +1226,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
| 1145 | goto out; | 1226 | goto out; |
| 1146 | } | 1227 | } |
| 1147 | 1228 | ||
| 1229 | ath9k_htc_ps_wakeup(priv); | ||
| 1148 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | 1230 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); |
| 1149 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); | 1231 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); |
| 1150 | 1232 | ||
| @@ -1191,6 +1273,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
| 1191 | 1273 | ||
| 1192 | priv->vif = vif; | 1274 | priv->vif = vif; |
| 1193 | out: | 1275 | out: |
| 1276 | ath9k_htc_ps_restore(priv); | ||
| 1194 | mutex_unlock(&priv->mutex); | 1277 | mutex_unlock(&priv->mutex); |
| 1195 | return ret; | 1278 | return ret; |
| 1196 | } | 1279 | } |
| @@ -1259,6 +1342,16 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1259 | } | 1342 | } |
| 1260 | 1343 | ||
| 1261 | } | 1344 | } |
| 1345 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
| 1346 | if (conf->flags & IEEE80211_CONF_PS) { | ||
| 1347 | ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); | ||
| 1348 | priv->ps_enabled = true; | ||
| 1349 | } else { | ||
| 1350 | priv->ps_enabled = false; | ||
| 1351 | cancel_work_sync(&priv->ps_work); | ||
| 1352 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | ||
| 1353 | } | ||
| 1354 | } | ||
| 1262 | 1355 | ||
| 1263 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 1356 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
| 1264 | if (conf->flags & IEEE80211_CONF_MONITOR) { | 1357 | if (conf->flags & IEEE80211_CONF_MONITOR) { |
| @@ -1295,16 +1388,18 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
| 1295 | 1388 | ||
| 1296 | mutex_lock(&priv->mutex); | 1389 | mutex_lock(&priv->mutex); |
| 1297 | 1390 | ||
| 1391 | ath9k_htc_ps_wakeup(priv); | ||
| 1298 | changed_flags &= SUPPORTED_FILTERS; | 1392 | changed_flags &= SUPPORTED_FILTERS; |
| 1299 | *total_flags &= SUPPORTED_FILTERS; | 1393 | *total_flags &= SUPPORTED_FILTERS; |
| 1300 | 1394 | ||
| 1301 | priv->rxfilter = *total_flags; | 1395 | priv->rxfilter = *total_flags; |
| 1302 | rfilt = ath9k_cmn_calcrxfilter(hw, priv->ah, priv->rxfilter); | 1396 | rfilt = ath9k_htc_calcrxfilter(priv); |
| 1303 | ath9k_hw_setrxfilter(priv->ah, rfilt); | 1397 | ath9k_hw_setrxfilter(priv->ah, rfilt); |
| 1304 | 1398 | ||
| 1305 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG, | 1399 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG, |
| 1306 | "Set HW RX filter: 0x%x\n", rfilt); | 1400 | "Set HW RX filter: 0x%x\n", rfilt); |
| 1307 | 1401 | ||
| 1402 | ath9k_htc_ps_restore(priv); | ||
| 1308 | mutex_unlock(&priv->mutex); | 1403 | mutex_unlock(&priv->mutex); |
| 1309 | } | 1404 | } |
| 1310 | 1405 | ||
| @@ -1382,6 +1477,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, | |||
| 1382 | 1477 | ||
| 1383 | mutex_lock(&priv->mutex); | 1478 | mutex_lock(&priv->mutex); |
| 1384 | ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); | 1479 | ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); |
| 1480 | ath9k_htc_ps_wakeup(priv); | ||
| 1385 | 1481 | ||
| 1386 | switch (cmd) { | 1482 | switch (cmd) { |
| 1387 | case SET_KEY: | 1483 | case SET_KEY: |
| @@ -1404,6 +1500,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, | |||
| 1404 | ret = -EINVAL; | 1500 | ret = -EINVAL; |
| 1405 | } | 1501 | } |
| 1406 | 1502 | ||
| 1503 | ath9k_htc_ps_restore(priv); | ||
| 1407 | mutex_unlock(&priv->mutex); | 1504 | mutex_unlock(&priv->mutex); |
| 1408 | 1505 | ||
| 1409 | return ret; | 1506 | return ret; |
| @@ -1419,6 +1516,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1419 | struct ath_common *common = ath9k_hw_common(ah); | 1516 | struct ath_common *common = ath9k_hw_common(ah); |
| 1420 | 1517 | ||
| 1421 | mutex_lock(&priv->mutex); | 1518 | mutex_lock(&priv->mutex); |
| 1519 | ath9k_htc_ps_wakeup(priv); | ||
| 1422 | 1520 | ||
| 1423 | if (changed & BSS_CHANGED_ASSOC) { | 1521 | if (changed & BSS_CHANGED_ASSOC) { |
| 1424 | common->curaid = bss_conf->assoc ? | 1522 | common->curaid = bss_conf->assoc ? |
| @@ -1431,6 +1529,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1431 | ath_start_ani(priv); | 1529 | ath_start_ani(priv); |
| 1432 | } else { | 1530 | } else { |
| 1433 | priv->op_flags &= ~OP_ASSOCIATED; | 1531 | priv->op_flags &= ~OP_ASSOCIATED; |
| 1532 | cancel_work_sync(&priv->ps_work); | ||
| 1434 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | 1533 | cancel_delayed_work_sync(&priv->ath9k_ani_work); |
| 1435 | } | 1534 | } |
| 1436 | } | 1535 | } |
| @@ -1450,7 +1549,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1450 | ((changed & BSS_CHANGED_BEACON_ENABLED) && | 1549 | ((changed & BSS_CHANGED_BEACON_ENABLED) && |
| 1451 | bss_conf->enable_beacon)) { | 1550 | bss_conf->enable_beacon)) { |
| 1452 | priv->op_flags |= OP_ENABLE_BEACON; | 1551 | priv->op_flags |= OP_ENABLE_BEACON; |
| 1453 | ath9k_htc_beacon_config(priv, vif, bss_conf); | 1552 | ath9k_htc_beacon_config(priv, vif); |
| 1454 | } | 1553 | } |
| 1455 | 1554 | ||
| 1456 | if (changed & BSS_CHANGED_BEACON) | 1555 | if (changed & BSS_CHANGED_BEACON) |
| @@ -1459,7 +1558,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1459 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && | 1558 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && |
| 1460 | !bss_conf->enable_beacon) { | 1559 | !bss_conf->enable_beacon) { |
| 1461 | priv->op_flags &= ~OP_ENABLE_BEACON; | 1560 | priv->op_flags &= ~OP_ENABLE_BEACON; |
| 1462 | ath9k_htc_beacon_config(priv, vif, bss_conf); | 1561 | ath9k_htc_beacon_config(priv, vif); |
| 1463 | } | 1562 | } |
| 1464 | 1563 | ||
| 1465 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 1564 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
| @@ -1490,6 +1589,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1490 | ath9k_hw_init_global_settings(ah); | 1589 | ath9k_hw_init_global_settings(ah); |
| 1491 | } | 1590 | } |
| 1492 | 1591 | ||
| 1592 | ath9k_htc_ps_restore(priv); | ||
| 1493 | mutex_unlock(&priv->mutex); | 1593 | mutex_unlock(&priv->mutex); |
| 1494 | } | 1594 | } |
| 1495 | 1595 | ||
| @@ -1518,9 +1618,11 @@ static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw) | |||
| 1518 | { | 1618 | { |
| 1519 | struct ath9k_htc_priv *priv = hw->priv; | 1619 | struct ath9k_htc_priv *priv = hw->priv; |
| 1520 | 1620 | ||
| 1621 | ath9k_htc_ps_wakeup(priv); | ||
| 1521 | mutex_lock(&priv->mutex); | 1622 | mutex_lock(&priv->mutex); |
| 1522 | ath9k_hw_reset_tsf(priv->ah); | 1623 | ath9k_hw_reset_tsf(priv->ah); |
| 1523 | mutex_unlock(&priv->mutex); | 1624 | mutex_unlock(&priv->mutex); |
| 1625 | ath9k_htc_ps_restore(priv); | ||
| 1524 | } | 1626 | } |
| 1525 | 1627 | ||
| 1526 | static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | 1628 | static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, |
| @@ -1569,6 +1671,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) | |||
| 1569 | spin_lock_bh(&priv->beacon_lock); | 1671 | spin_lock_bh(&priv->beacon_lock); |
| 1570 | priv->op_flags |= OP_SCANNING; | 1672 | priv->op_flags |= OP_SCANNING; |
| 1571 | spin_unlock_bh(&priv->beacon_lock); | 1673 | spin_unlock_bh(&priv->beacon_lock); |
| 1674 | cancel_work_sync(&priv->ps_work); | ||
| 1572 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | 1675 | cancel_delayed_work_sync(&priv->ath9k_ani_work); |
| 1573 | mutex_unlock(&priv->mutex); | 1676 | mutex_unlock(&priv->mutex); |
| 1574 | } | 1677 | } |
| @@ -1577,13 +1680,17 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) | |||
| 1577 | { | 1680 | { |
| 1578 | struct ath9k_htc_priv *priv = hw->priv; | 1681 | struct ath9k_htc_priv *priv = hw->priv; |
| 1579 | 1682 | ||
| 1683 | ath9k_htc_ps_wakeup(priv); | ||
| 1580 | mutex_lock(&priv->mutex); | 1684 | mutex_lock(&priv->mutex); |
| 1581 | spin_lock_bh(&priv->beacon_lock); | 1685 | spin_lock_bh(&priv->beacon_lock); |
| 1582 | priv->op_flags &= ~OP_SCANNING; | 1686 | priv->op_flags &= ~OP_SCANNING; |
| 1583 | spin_unlock_bh(&priv->beacon_lock); | 1687 | spin_unlock_bh(&priv->beacon_lock); |
| 1584 | priv->op_flags |= OP_FULL_RESET; | 1688 | priv->op_flags |= OP_FULL_RESET; |
| 1689 | if (priv->op_flags & OP_ASSOCIATED) | ||
| 1690 | ath9k_htc_beacon_config(priv, NULL); | ||
| 1585 | ath_start_ani(priv); | 1691 | ath_start_ani(priv); |
| 1586 | mutex_unlock(&priv->mutex); | 1692 | mutex_unlock(&priv->mutex); |
| 1693 | ath9k_htc_ps_restore(priv); | ||
| 1587 | } | 1694 | } |
| 1588 | 1695 | ||
| 1589 | static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | 1696 | static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) |
