aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c397
1 files changed, 249 insertions, 148 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 9d371c18eb4..7aefbc63877 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -325,133 +325,122 @@ static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
325 tcap.flags_ext = 0x80601000; 325 tcap.flags_ext = 0x80601000;
326 tcap.ampdu_limit = 0xffff0000; 326 tcap.ampdu_limit = 0xffff0000;
327 tcap.ampdu_subframes = 20; 327 tcap.ampdu_subframes = 20;
328 tcap.tx_chainmask_legacy = 1; 328 tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
329 tcap.protmode = 1; 329 tcap.protmode = 1;
330 tcap.tx_chainmask = 1; 330 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
331 331
332 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); 332 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
333 333
334 return ret; 334 return ret;
335} 335}
336 336
337static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv, 337static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
338 struct ieee80211_vif *vif, 338 struct ieee80211_sta *sta,
339 struct ieee80211_sta *sta) 339 struct ath9k_htc_target_rate *trate)
340{ 340{
341 struct ath_common *common = ath9k_hw_common(priv->ah);
342 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; 341 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
343 struct ieee80211_supported_band *sband; 342 struct ieee80211_supported_band *sband;
344 struct ath9k_htc_target_rate trate;
345 u32 caps = 0; 343 u32 caps = 0;
346 u8 cmd_rsp; 344 int i, j;
347 int i, j, ret;
348
349 memset(&trate, 0, sizeof(trate));
350 345
351 /* Only 2GHz is supported */ 346 sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
352 sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
353 347
354 for (i = 0, j = 0; i < sband->n_bitrates; i++) { 348 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
355 if (sta->supp_rates[sband->band] & BIT(i)) { 349 if (sta->supp_rates[sband->band] & BIT(i)) {
356 priv->tgt_rate.rates.legacy_rates.rs_rates[j] 350 trate->rates.legacy_rates.rs_rates[j]
357 = (sband->bitrates[i].bitrate * 2) / 10; 351 = (sband->bitrates[i].bitrate * 2) / 10;
358 j++; 352 j++;
359 } 353 }
360 } 354 }
361 priv->tgt_rate.rates.legacy_rates.rs_nrates = j; 355 trate->rates.legacy_rates.rs_nrates = j;
362 356
363 if (sta->ht_cap.ht_supported) { 357 if (sta->ht_cap.ht_supported) {
364 for (i = 0, j = 0; i < 77; i++) { 358 for (i = 0, j = 0; i < 77; i++) {
365 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) 359 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
366 priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i; 360 trate->rates.ht_rates.rs_rates[j++] = i;
367 if (j == ATH_HTC_RATE_MAX) 361 if (j == ATH_HTC_RATE_MAX)
368 break; 362 break;
369 } 363 }
370 priv->tgt_rate.rates.ht_rates.rs_nrates = j; 364 trate->rates.ht_rates.rs_nrates = j;
371 365
372 caps = WLAN_RC_HT_FLAG; 366 caps = WLAN_RC_HT_FLAG;
367 if (priv->ah->caps.tx_chainmask != 1 &&
368 ath9k_hw_getcapability(priv->ah, ATH9K_CAP_DS, 0, NULL)) {
369 if (sta->ht_cap.mcs.rx_mask[1])
370 caps |= WLAN_RC_DS_FLAG;
371 }
373 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 372 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
374 caps |= WLAN_RC_40_FLAG; 373 caps |= WLAN_RC_40_FLAG;
375 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) 374 if (conf_is_ht40(&priv->hw->conf) &&
375 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
376 caps |= WLAN_RC_SGI_FLAG;
377 else if (conf_is_ht20(&priv->hw->conf) &&
378 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
376 caps |= WLAN_RC_SGI_FLAG; 379 caps |= WLAN_RC_SGI_FLAG;
377
378 } 380 }
379 381
380 priv->tgt_rate.sta_index = ista->index; 382 trate->sta_index = ista->index;
381 priv->tgt_rate.isnew = 1; 383 trate->isnew = 1;
382 trate = priv->tgt_rate; 384 trate->capflags = cpu_to_be32(caps);
383 priv->tgt_rate.capflags = cpu_to_be32(caps); 385}
384 trate.capflags = cpu_to_be32(caps);
385 386
386 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); 387static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
388 struct ath9k_htc_target_rate *trate)
389{
390 struct ath_common *common = ath9k_hw_common(priv->ah);
391 int ret;
392 u8 cmd_rsp;
393
394 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
387 if (ret) { 395 if (ret) {
388 ath_print(common, ATH_DBG_FATAL, 396 ath_print(common, ATH_DBG_FATAL,
389 "Unable to initialize Rate information on target\n"); 397 "Unable to initialize Rate information on target\n");
390 return ret;
391 } 398 }
392 399
393 ath_print(common, ATH_DBG_CONFIG, 400 return ret;
394 "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps);
395 return 0;
396} 401}
397 402
398static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40) 403static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
404 struct ieee80211_sta *sta)
399{ 405{
400 struct ath9k_htc_priv *priv = hw->priv; 406 struct ath_common *common = ath9k_hw_common(priv->ah);
401 struct ieee80211_conf *conf = &hw->conf; 407 struct ath9k_htc_target_rate trate;
402 408 int ret;
403 if (!conf_is_ht(conf))
404 return false;
405
406 if (!(priv->op_flags & OP_ASSOCIATED) ||
407 (priv->op_flags & OP_SCANNING))
408 return false;
409 409
410 if (conf_is_ht40(conf)) { 410 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
411 if (priv->ah->curchan->chanmode & 411 ath9k_htc_setup_rate(priv, sta, &trate);
412 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) { 412 ret = ath9k_htc_send_rate_cmd(priv, &trate);
413 return false; 413 if (!ret)
414 } else { 414 ath_print(common, ATH_DBG_CONFIG,
415 *cw40 = true; 415 "Updated target sta: %pM, rate caps: 0x%X\n",
416 return true; 416 sta->addr, be32_to_cpu(trate.capflags));
417 }
418 } else { /* ht20 */
419 if (priv->ah->curchan->chanmode & CHANNEL_HT20)
420 return false;
421 else
422 return true;
423 }
424} 417}
425 418
426static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40) 419static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
420 struct ieee80211_vif *vif,
421 struct ieee80211_bss_conf *bss_conf)
427{ 422{
428 struct ath9k_htc_target_rate trate;
429 struct ath_common *common = ath9k_hw_common(priv->ah); 423 struct ath_common *common = ath9k_hw_common(priv->ah);
424 struct ath9k_htc_target_rate trate;
425 struct ieee80211_sta *sta;
430 int ret; 426 int ret;
431 u32 caps = be32_to_cpu(priv->tgt_rate.capflags);
432 u8 cmd_rsp;
433
434 memset(&trate, 0, sizeof(trate));
435 427
436 trate = priv->tgt_rate; 428 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
437
438 if (is_cw40)
439 caps |= WLAN_RC_40_FLAG;
440 else
441 caps &= ~WLAN_RC_40_FLAG;
442 429
443 priv->tgt_rate.capflags = cpu_to_be32(caps); 430 rcu_read_lock();
444 trate.capflags = cpu_to_be32(caps); 431 sta = ieee80211_find_sta(vif, bss_conf->bssid);
445 432 if (!sta) {
446 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); 433 rcu_read_unlock();
447 if (ret) {
448 ath_print(common, ATH_DBG_FATAL,
449 "Unable to update Rate information on target\n");
450 return; 434 return;
451 } 435 }
436 ath9k_htc_setup_rate(priv, sta, &trate);
437 rcu_read_unlock();
452 438
453 ath_print(common, ATH_DBG_CONFIG, "Rate control updated with " 439 ret = ath9k_htc_send_rate_cmd(priv, &trate);
454 "caps:0x%x on target\n", priv->tgt_rate.capflags); 440 if (!ret)
441 ath_print(common, ATH_DBG_CONFIG,
442 "Updated target sta: %pM, rate caps: 0x%X\n",
443 bss_conf->bssid, be32_to_cpu(trate.capflags));
455} 444}
456 445
457static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv, 446static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
@@ -617,6 +606,19 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
617 "%20s : %10u\n", "SKBs dropped", 606 "%20s : %10u\n", "SKBs dropped",
618 priv->debug.tx_stats.skb_dropped); 607 priv->debug.tx_stats.skb_dropped);
619 608
609 len += snprintf(buf + len, sizeof(buf) - len,
610 "%20s : %10u\n", "BE queued",
611 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
612 len += snprintf(buf + len, sizeof(buf) - len,
613 "%20s : %10u\n", "BK queued",
614 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
615 len += snprintf(buf + len, sizeof(buf) - len,
616 "%20s : %10u\n", "VI queued",
617 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
618 len += snprintf(buf + len, sizeof(buf) - len,
619 "%20s : %10u\n", "VO queued",
620 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
621
620 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 622 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
621} 623}
622 624
@@ -1054,6 +1056,95 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
1054 wiphy_rfkill_start_polling(priv->hw->wiphy); 1056 wiphy_rfkill_start_polling(priv->hw->wiphy);
1055} 1057}
1056 1058
1059static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1060{
1061 struct ath9k_htc_priv *priv = hw->priv;
1062 struct ath_hw *ah = priv->ah;
1063 struct ath_common *common = ath9k_hw_common(ah);
1064 int ret;
1065 u8 cmd_rsp;
1066
1067 if (!ah->curchan)
1068 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1069
1070 /* Reset the HW */
1071 ret = ath9k_hw_reset(ah, ah->curchan, false);
1072 if (ret) {
1073 ath_print(common, ATH_DBG_FATAL,
1074 "Unable to reset hardware; reset status %d "
1075 "(freq %u MHz)\n", ret, ah->curchan->channel);
1076 }
1077
1078 ath_update_txpow(priv);
1079
1080 /* Start RX */
1081 WMI_CMD(WMI_START_RECV_CMDID);
1082 ath9k_host_rx_init(priv);
1083
1084 /* Start TX */
1085 htc_start(priv->htc);
1086 spin_lock_bh(&priv->tx_lock);
1087 priv->tx_queues_stop = false;
1088 spin_unlock_bh(&priv->tx_lock);
1089 ieee80211_wake_queues(hw);
1090
1091 WMI_CMD(WMI_ENABLE_INTR_CMDID);
1092
1093 /* Enable LED */
1094 ath9k_hw_cfg_output(ah, ah->led_pin,
1095 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1096 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1097}
1098
1099static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1100{
1101 struct ath9k_htc_priv *priv = hw->priv;
1102 struct ath_hw *ah = priv->ah;
1103 struct ath_common *common = ath9k_hw_common(ah);
1104 int ret;
1105 u8 cmd_rsp;
1106
1107 ath9k_htc_ps_wakeup(priv);
1108
1109 /* Disable LED */
1110 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1111 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1112
1113 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1114
1115 /* Stop TX */
1116 ieee80211_stop_queues(hw);
1117 htc_stop(priv->htc);
1118 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1119 skb_queue_purge(&priv->tx_queue);
1120
1121 /* Stop RX */
1122 WMI_CMD(WMI_STOP_RECV_CMDID);
1123
1124 /*
1125 * The MIB counters have to be disabled here,
1126 * since the target doesn't do it.
1127 */
1128 ath9k_hw_disable_mib_counters(ah);
1129
1130 if (!ah->curchan)
1131 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1132
1133 /* Reset the HW */
1134 ret = ath9k_hw_reset(ah, ah->curchan, false);
1135 if (ret) {
1136 ath_print(common, ATH_DBG_FATAL,
1137 "Unable to reset hardware; reset status %d "
1138 "(freq %u MHz)\n", ret, ah->curchan->channel);
1139 }
1140
1141 /* Disable the PHY */
1142 ath9k_hw_phy_disable(ah);
1143
1144 ath9k_htc_ps_restore(priv);
1145 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1146}
1147
1057/**********************/ 1148/**********************/
1058/* mac80211 Callbacks */ 1149/* mac80211 Callbacks */
1059/**********************/ 1150/**********************/
@@ -1099,7 +1190,7 @@ fail_tx:
1099 return 0; 1190 return 0;
1100} 1191}
1101 1192
1102static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) 1193static int ath9k_htc_start(struct ieee80211_hw *hw)
1103{ 1194{
1104 struct ath9k_htc_priv *priv = hw->priv; 1195 struct ath9k_htc_priv *priv = hw->priv;
1105 struct ath_hw *ah = priv->ah; 1196 struct ath_hw *ah = priv->ah;
@@ -1111,10 +1202,16 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led)
1111 __be16 htc_mode; 1202 __be16 htc_mode;
1112 u8 cmd_rsp; 1203 u8 cmd_rsp;
1113 1204
1205 mutex_lock(&priv->mutex);
1206
1114 ath_print(common, ATH_DBG_CONFIG, 1207 ath_print(common, ATH_DBG_CONFIG,
1115 "Starting driver with initial channel: %d MHz\n", 1208 "Starting driver with initial channel: %d MHz\n",
1116 curchan->center_freq); 1209 curchan->center_freq);
1117 1210
1211 /* Ensure that HW is awake before flushing RX */
1212 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1213 WMI_CMD(WMI_FLUSH_RECV_CMDID);
1214
1118 /* setup initial channel */ 1215 /* setup initial channel */
1119 init_channel = ath9k_cmn_get_curchannel(hw, ah); 1216 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1120 1217
@@ -1127,6 +1224,7 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led)
1127 ath_print(common, ATH_DBG_FATAL, 1224 ath_print(common, ATH_DBG_FATAL,
1128 "Unable to reset hardware; reset status %d " 1225 "Unable to reset hardware; reset status %d "
1129 "(freq %u MHz)\n", ret, curchan->center_freq); 1226 "(freq %u MHz)\n", ret, curchan->center_freq);
1227 mutex_unlock(&priv->mutex);
1130 return ret; 1228 return ret;
1131 } 1229 }
1132 1230
@@ -1147,31 +1245,14 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led)
1147 priv->tx_queues_stop = false; 1245 priv->tx_queues_stop = false;
1148 spin_unlock_bh(&priv->tx_lock); 1246 spin_unlock_bh(&priv->tx_lock);
1149 1247
1150 if (led) {
1151 /* Enable LED */
1152 ath9k_hw_cfg_output(ah, ah->led_pin,
1153 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1154 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1155 }
1156
1157 ieee80211_wake_queues(hw); 1248 ieee80211_wake_queues(hw);
1158 1249
1159 return ret;
1160}
1161
1162static int ath9k_htc_start(struct ieee80211_hw *hw)
1163{
1164 struct ath9k_htc_priv *priv = hw->priv;
1165 int ret = 0;
1166
1167 mutex_lock(&priv->mutex);
1168 ret = ath9k_htc_radio_enable(hw, false);
1169 mutex_unlock(&priv->mutex); 1250 mutex_unlock(&priv->mutex);
1170 1251
1171 return ret; 1252 return ret;
1172} 1253}
1173 1254
1174static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) 1255static void ath9k_htc_stop(struct ieee80211_hw *hw)
1175{ 1256{
1176 struct ath9k_htc_priv *priv = hw->priv; 1257 struct ath9k_htc_priv *priv = hw->priv;
1177 struct ath_hw *ah = priv->ah; 1258 struct ath_hw *ah = priv->ah;
@@ -1179,17 +1260,14 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led)
1179 int ret = 0; 1260 int ret = 0;
1180 u8 cmd_rsp; 1261 u8 cmd_rsp;
1181 1262
1263 mutex_lock(&priv->mutex);
1264
1182 if (priv->op_flags & OP_INVALID) { 1265 if (priv->op_flags & OP_INVALID) {
1183 ath_print(common, ATH_DBG_ANY, "Device not present\n"); 1266 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1267 mutex_unlock(&priv->mutex);
1184 return; 1268 return;
1185 } 1269 }
1186 1270
1187 if (led) {
1188 /* Disable LED */
1189 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1190 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1191 }
1192
1193 /* Cancel all the running timers/work .. */ 1271 /* Cancel all the running timers/work .. */
1194 cancel_work_sync(&priv->ps_work); 1272 cancel_work_sync(&priv->ps_work);
1195 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1273 cancel_delayed_work_sync(&priv->ath9k_ani_work);
@@ -1202,12 +1280,6 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led)
1202 WMI_CMD(WMI_DISABLE_INTR_CMDID); 1280 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1203 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 1281 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1204 WMI_CMD(WMI_STOP_RECV_CMDID); 1282 WMI_CMD(WMI_STOP_RECV_CMDID);
1205 ath9k_hw_phy_disable(ah);
1206 ath9k_hw_disable(ah);
1207 ath9k_hw_configpcipowersave(ah, 1, 1);
1208 ath9k_htc_ps_restore(priv);
1209 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1210
1211 skb_queue_purge(&priv->tx_queue); 1283 skb_queue_purge(&priv->tx_queue);
1212 1284
1213 /* Remove monitor interface here */ 1285 /* Remove monitor interface here */
@@ -1220,21 +1292,18 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led)
1220 "Monitor interface removed\n"); 1292 "Monitor interface removed\n");
1221 } 1293 }
1222 1294
1295 ath9k_hw_phy_disable(ah);
1296 ath9k_hw_disable(ah);
1297 ath9k_hw_configpcipowersave(ah, 1, 1);
1298 ath9k_htc_ps_restore(priv);
1299 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1300
1223 priv->op_flags |= OP_INVALID; 1301 priv->op_flags |= OP_INVALID;
1224 1302
1225 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); 1303 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1226}
1227
1228static void ath9k_htc_stop(struct ieee80211_hw *hw)
1229{
1230 struct ath9k_htc_priv *priv = hw->priv;
1231
1232 mutex_lock(&priv->mutex);
1233 ath9k_htc_radio_disable(hw, false);
1234 mutex_unlock(&priv->mutex); 1304 mutex_unlock(&priv->mutex);
1235} 1305}
1236 1306
1237
1238static int ath9k_htc_add_interface(struct ieee80211_hw *hw, 1307static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1239 struct ieee80211_vif *vif) 1308 struct ieee80211_vif *vif)
1240{ 1309{
@@ -1302,6 +1371,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1302out: 1371out:
1303 ath9k_htc_ps_restore(priv); 1372 ath9k_htc_ps_restore(priv);
1304 mutex_unlock(&priv->mutex); 1373 mutex_unlock(&priv->mutex);
1374
1305 return ret; 1375 return ret;
1306} 1376}
1307 1377
@@ -1318,6 +1388,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1318 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); 1388 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1319 1389
1320 mutex_lock(&priv->mutex); 1390 mutex_lock(&priv->mutex);
1391 ath9k_htc_ps_wakeup(priv);
1321 1392
1322 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); 1393 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1323 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); 1394 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
@@ -1328,6 +1399,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1328 ath9k_htc_remove_station(priv, vif, NULL); 1399 ath9k_htc_remove_station(priv, vif, NULL);
1329 priv->vif = NULL; 1400 priv->vif = NULL;
1330 1401
1402 ath9k_htc_ps_restore(priv);
1331 mutex_unlock(&priv->mutex); 1403 mutex_unlock(&priv->mutex);
1332} 1404}
1333 1405
@@ -1343,30 +1415,27 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1343 bool enable_radio = false; 1415 bool enable_radio = false;
1344 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); 1416 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1345 1417
1418 mutex_lock(&priv->htc_pm_lock);
1346 if (!idle && priv->ps_idle) 1419 if (!idle && priv->ps_idle)
1347 enable_radio = true; 1420 enable_radio = true;
1348
1349 priv->ps_idle = idle; 1421 priv->ps_idle = idle;
1422 mutex_unlock(&priv->htc_pm_lock);
1350 1423
1351 if (enable_radio) { 1424 if (enable_radio) {
1352 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1353 ath9k_htc_radio_enable(hw, true);
1354 ath_print(common, ATH_DBG_CONFIG, 1425 ath_print(common, ATH_DBG_CONFIG,
1355 "not-idle: enabling radio\n"); 1426 "not-idle: enabling radio\n");
1427 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1428 ath9k_htc_radio_enable(hw);
1356 } 1429 }
1357 } 1430 }
1358 1431
1359 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1432 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1360 struct ieee80211_channel *curchan = hw->conf.channel; 1433 struct ieee80211_channel *curchan = hw->conf.channel;
1361 int pos = curchan->hw_value; 1434 int pos = curchan->hw_value;
1362 bool is_cw40 = false;
1363 1435
1364 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", 1436 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1365 curchan->center_freq); 1437 curchan->center_freq);
1366 1438
1367 if (check_rc_update(hw, &is_cw40))
1368 ath9k_htc_rc_update(priv, is_cw40);
1369
1370 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]); 1439 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1371 1440
1372 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { 1441 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
@@ -1399,14 +1468,21 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1399 } 1468 }
1400 } 1469 }
1401 1470
1402 if (priv->ps_idle) { 1471 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1472 mutex_lock(&priv->htc_pm_lock);
1473 if (!priv->ps_idle) {
1474 mutex_unlock(&priv->htc_pm_lock);
1475 goto out;
1476 }
1477 mutex_unlock(&priv->htc_pm_lock);
1478
1403 ath_print(common, ATH_DBG_CONFIG, 1479 ath_print(common, ATH_DBG_CONFIG,
1404 "idle: disabling radio\n"); 1480 "idle: disabling radio\n");
1405 ath9k_htc_radio_disable(hw, true); 1481 ath9k_htc_radio_disable(hw);
1406 } 1482 }
1407 1483
1484out:
1408 mutex_unlock(&priv->mutex); 1485 mutex_unlock(&priv->mutex);
1409
1410 return 0; 1486 return 0;
1411} 1487}
1412 1488
@@ -1428,8 +1504,8 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1428 u32 rfilt; 1504 u32 rfilt;
1429 1505
1430 mutex_lock(&priv->mutex); 1506 mutex_lock(&priv->mutex);
1431
1432 ath9k_htc_ps_wakeup(priv); 1507 ath9k_htc_ps_wakeup(priv);
1508
1433 changed_flags &= SUPPORTED_FILTERS; 1509 changed_flags &= SUPPORTED_FILTERS;
1434 *total_flags &= SUPPORTED_FILTERS; 1510 *total_flags &= SUPPORTED_FILTERS;
1435 1511
@@ -1444,30 +1520,38 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1444 mutex_unlock(&priv->mutex); 1520 mutex_unlock(&priv->mutex);
1445} 1521}
1446 1522
1447static void ath9k_htc_sta_notify(struct ieee80211_hw *hw, 1523static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1448 struct ieee80211_vif *vif, 1524 struct ieee80211_vif *vif,
1449 enum sta_notify_cmd cmd, 1525 struct ieee80211_sta *sta)
1450 struct ieee80211_sta *sta)
1451{ 1526{
1452 struct ath9k_htc_priv *priv = hw->priv; 1527 struct ath9k_htc_priv *priv = hw->priv;
1453 int ret; 1528 int ret;
1454 1529
1455 mutex_lock(&priv->mutex); 1530 mutex_lock(&priv->mutex);
1531 ath9k_htc_ps_wakeup(priv);
1532 ret = ath9k_htc_add_station(priv, vif, sta);
1533 if (!ret)
1534 ath9k_htc_init_rate(priv, sta);
1535 ath9k_htc_ps_restore(priv);
1536 mutex_unlock(&priv->mutex);
1456 1537
1457 switch (cmd) { 1538 return ret;
1458 case STA_NOTIFY_ADD: 1539}
1459 ret = ath9k_htc_add_station(priv, vif, sta);
1460 if (!ret)
1461 ath9k_htc_init_rate(priv, vif, sta);
1462 break;
1463 case STA_NOTIFY_REMOVE:
1464 ath9k_htc_remove_station(priv, vif, sta);
1465 break;
1466 default:
1467 break;
1468 }
1469 1540
1541static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1542 struct ieee80211_vif *vif,
1543 struct ieee80211_sta *sta)
1544{
1545 struct ath9k_htc_priv *priv = hw->priv;
1546 int ret;
1547
1548 mutex_lock(&priv->mutex);
1549 ath9k_htc_ps_wakeup(priv);
1550 ret = ath9k_htc_remove_station(priv, vif, sta);
1551 ath9k_htc_ps_restore(priv);
1470 mutex_unlock(&priv->mutex); 1552 mutex_unlock(&priv->mutex);
1553
1554 return ret;
1471} 1555}
1472 1556
1473static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, 1557static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -1482,6 +1566,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1482 return 0; 1566 return 0;
1483 1567
1484 mutex_lock(&priv->mutex); 1568 mutex_lock(&priv->mutex);
1569 ath9k_htc_ps_wakeup(priv);
1485 1570
1486 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); 1571 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1487 1572
@@ -1499,9 +1584,16 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1499 params->cw_max, params->txop); 1584 params->cw_max, params->txop);
1500 1585
1501 ret = ath_htc_txq_update(priv, qnum, &qi); 1586 ret = ath_htc_txq_update(priv, qnum, &qi);
1502 if (ret) 1587 if (ret) {
1503 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); 1588 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1589 goto out;
1590 }
1504 1591
1592 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1593 (qnum == priv->hwq_map[ATH9K_WME_AC_BE]))
1594 ath9k_htc_beaconq_config(priv);
1595out:
1596 ath9k_htc_ps_restore(priv);
1505 mutex_unlock(&priv->mutex); 1597 mutex_unlock(&priv->mutex);
1506 1598
1507 return ret; 1599 return ret;
@@ -1574,7 +1666,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1574 ath_start_ani(priv); 1666 ath_start_ani(priv);
1575 } else { 1667 } else {
1576 priv->op_flags &= ~OP_ASSOCIATED; 1668 priv->op_flags &= ~OP_ASSOCIATED;
1577 cancel_work_sync(&priv->ps_work);
1578 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1669 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1579 } 1670 }
1580 } 1671 }
@@ -1631,6 +1722,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1631 ath9k_hw_init_global_settings(ah); 1722 ath9k_hw_init_global_settings(ah);
1632 } 1723 }
1633 1724
1725 if (changed & BSS_CHANGED_HT)
1726 ath9k_htc_update_rate(priv, vif, bss_conf);
1727
1634 ath9k_htc_ps_restore(priv); 1728 ath9k_htc_ps_restore(priv);
1635 mutex_unlock(&priv->mutex); 1729 mutex_unlock(&priv->mutex);
1636} 1730}
@@ -1641,7 +1735,9 @@ static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1641 u64 tsf; 1735 u64 tsf;
1642 1736
1643 mutex_lock(&priv->mutex); 1737 mutex_lock(&priv->mutex);
1738 ath9k_htc_ps_wakeup(priv);
1644 tsf = ath9k_hw_gettsf64(priv->ah); 1739 tsf = ath9k_hw_gettsf64(priv->ah);
1740 ath9k_htc_ps_restore(priv);
1645 mutex_unlock(&priv->mutex); 1741 mutex_unlock(&priv->mutex);
1646 1742
1647 return tsf; 1743 return tsf;
@@ -1652,7 +1748,9 @@ static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1652 struct ath9k_htc_priv *priv = hw->priv; 1748 struct ath9k_htc_priv *priv = hw->priv;
1653 1749
1654 mutex_lock(&priv->mutex); 1750 mutex_lock(&priv->mutex);
1751 ath9k_htc_ps_wakeup(priv);
1655 ath9k_hw_settsf64(priv->ah, tsf); 1752 ath9k_hw_settsf64(priv->ah, tsf);
1753 ath9k_htc_ps_restore(priv);
1656 mutex_unlock(&priv->mutex); 1754 mutex_unlock(&priv->mutex);
1657} 1755}
1658 1756
@@ -1660,11 +1758,11 @@ static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1660{ 1758{
1661 struct ath9k_htc_priv *priv = hw->priv; 1759 struct ath9k_htc_priv *priv = hw->priv;
1662 1760
1663 ath9k_htc_ps_wakeup(priv);
1664 mutex_lock(&priv->mutex); 1761 mutex_lock(&priv->mutex);
1762 ath9k_htc_ps_wakeup(priv);
1665 ath9k_hw_reset_tsf(priv->ah); 1763 ath9k_hw_reset_tsf(priv->ah);
1666 mutex_unlock(&priv->mutex);
1667 ath9k_htc_ps_restore(priv); 1764 ath9k_htc_ps_restore(priv);
1765 mutex_unlock(&priv->mutex);
1668} 1766}
1669 1767
1670static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, 1768static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
@@ -1722,8 +1820,8 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1722{ 1820{
1723 struct ath9k_htc_priv *priv = hw->priv; 1821 struct ath9k_htc_priv *priv = hw->priv;
1724 1822
1725 ath9k_htc_ps_wakeup(priv);
1726 mutex_lock(&priv->mutex); 1823 mutex_lock(&priv->mutex);
1824 ath9k_htc_ps_wakeup(priv);
1727 spin_lock_bh(&priv->beacon_lock); 1825 spin_lock_bh(&priv->beacon_lock);
1728 priv->op_flags &= ~OP_SCANNING; 1826 priv->op_flags &= ~OP_SCANNING;
1729 spin_unlock_bh(&priv->beacon_lock); 1827 spin_unlock_bh(&priv->beacon_lock);
@@ -1731,8 +1829,8 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1731 if (priv->op_flags & OP_ASSOCIATED) 1829 if (priv->op_flags & OP_ASSOCIATED)
1732 ath9k_htc_beacon_config(priv, priv->vif); 1830 ath9k_htc_beacon_config(priv, priv->vif);
1733 ath_start_ani(priv); 1831 ath_start_ani(priv);
1734 mutex_unlock(&priv->mutex);
1735 ath9k_htc_ps_restore(priv); 1832 ath9k_htc_ps_restore(priv);
1833 mutex_unlock(&priv->mutex);
1736} 1834}
1737 1835
1738static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1836static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
@@ -1746,8 +1844,10 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1746 struct ath9k_htc_priv *priv = hw->priv; 1844 struct ath9k_htc_priv *priv = hw->priv;
1747 1845
1748 mutex_lock(&priv->mutex); 1846 mutex_lock(&priv->mutex);
1847 ath9k_htc_ps_wakeup(priv);
1749 priv->ah->coverage_class = coverage_class; 1848 priv->ah->coverage_class = coverage_class;
1750 ath9k_hw_init_global_settings(priv->ah); 1849 ath9k_hw_init_global_settings(priv->ah);
1850 ath9k_htc_ps_restore(priv);
1751 mutex_unlock(&priv->mutex); 1851 mutex_unlock(&priv->mutex);
1752} 1852}
1753 1853
@@ -1759,7 +1859,8 @@ struct ieee80211_ops ath9k_htc_ops = {
1759 .remove_interface = ath9k_htc_remove_interface, 1859 .remove_interface = ath9k_htc_remove_interface,
1760 .config = ath9k_htc_config, 1860 .config = ath9k_htc_config,
1761 .configure_filter = ath9k_htc_configure_filter, 1861 .configure_filter = ath9k_htc_configure_filter,
1762 .sta_notify = ath9k_htc_sta_notify, 1862 .sta_add = ath9k_htc_sta_add,
1863 .sta_remove = ath9k_htc_sta_remove,
1763 .conf_tx = ath9k_htc_conf_tx, 1864 .conf_tx = ath9k_htc_conf_tx,
1764 .bss_info_changed = ath9k_htc_bss_info_changed, 1865 .bss_info_changed = ath9k_htc_bss_info_changed,
1765 .set_key = ath9k_htc_set_key, 1866 .set_key = ath9k_htc_set_key,