aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/power.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c395
1 files changed, 243 insertions, 152 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 550824aa84ea..483ecc67501f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -186,6 +186,92 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
186 } 186 }
187} 187}
188 188
189static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
190 struct ieee80211_vif *vif,
191 struct iwl_mac_power_cmd *cmd)
192{
193 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
194 enum ieee80211_ac_numbers ac;
195 bool tid_found = false;
196
197 for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) {
198 if (!mvmvif->queue_params[ac].uapsd)
199 continue;
200
201 if (mvm->cur_ucode != IWL_UCODE_WOWLAN)
202 cmd->flags |=
203 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
204
205 cmd->uapsd_ac_flags |= BIT(ac);
206
207 /* QNDP TID - the highest TID with no admission control */
208 if (!tid_found && !mvmvif->queue_params[ac].acm) {
209 tid_found = true;
210 switch (ac) {
211 case IEEE80211_AC_VO:
212 cmd->qndp_tid = 6;
213 break;
214 case IEEE80211_AC_VI:
215 cmd->qndp_tid = 5;
216 break;
217 case IEEE80211_AC_BE:
218 cmd->qndp_tid = 0;
219 break;
220 case IEEE80211_AC_BK:
221 cmd->qndp_tid = 1;
222 break;
223 }
224 }
225 }
226
227 if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
228 return;
229
230 cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK);
231
232 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
233 BIT(IEEE80211_AC_VI) |
234 BIT(IEEE80211_AC_BE) |
235 BIT(IEEE80211_AC_BK))) {
236 cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
237 cmd->snooze_interval = cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL);
238 cmd->snooze_window = (mvm->cur_ucode == IWL_UCODE_WOWLAN) ?
239 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) :
240 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
241 }
242
243 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
244
245 if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
246 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
247 cmd->rx_data_timeout_uapsd =
248 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
249 cmd->tx_data_timeout_uapsd =
250 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
251 } else {
252 cmd->rx_data_timeout_uapsd =
253 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
254 cmd->tx_data_timeout_uapsd =
255 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
256 }
257
258 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
259 cmd->heavy_tx_thld_packets =
260 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
261 cmd->heavy_rx_thld_packets =
262 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
263 } else {
264 cmd->heavy_tx_thld_packets =
265 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
266 cmd->heavy_rx_thld_packets =
267 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
268 }
269 cmd->heavy_tx_thld_percentage =
270 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
271 cmd->heavy_rx_thld_percentage =
272 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
273}
274
189static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, 275static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
190 struct ieee80211_vif *vif, 276 struct ieee80211_vif *vif,
191 struct iwl_mac_power_cmd *cmd) 277 struct iwl_mac_power_cmd *cmd)
@@ -198,8 +284,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
198 bool radar_detect = false; 284 bool radar_detect = false;
199 struct iwl_mvm_vif *mvmvif __maybe_unused = 285 struct iwl_mvm_vif *mvmvif __maybe_unused =
200 iwl_mvm_vif_from_mac80211(vif); 286 iwl_mvm_vif_from_mac80211(vif);
201 enum ieee80211_ac_numbers ac; 287 bool allow_uapsd = true;
202 bool tid_found = false;
203 288
204 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 289 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
205 mvmvif->color)); 290 mvmvif->color));
@@ -217,7 +302,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
217 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 302 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
218 cmd->keep_alive_seconds = cpu_to_le16(keep_alive); 303 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
219 304
220 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 305 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
306 mvm->ps_prevented)
221 return; 307 return;
222 308
223 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 309 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
@@ -227,7 +313,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
227 mvmvif->dbgfs_pm.disable_power_off) 313 mvmvif->dbgfs_pm.disable_power_off)
228 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); 314 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
229#endif 315#endif
230 if (!vif->bss_conf.ps) 316 if (!vif->bss_conf.ps || mvmvif->pm_prevented)
231 return; 317 return;
232 318
233 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 319 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -269,81 +355,24 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
269 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); 355 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
270 } 356 }
271 357
272 for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) { 358 if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
273 if (!mvmvif->queue_params[ac].uapsd) 359 ETH_ALEN))
274 continue; 360 allow_uapsd = false;
275
276 if (mvm->cur_ucode != IWL_UCODE_WOWLAN)
277 cmd->flags |=
278 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
279
280 cmd->uapsd_ac_flags |= BIT(ac);
281 361
282 /* QNDP TID - the highest TID with no admission control */ 362 if (vif->p2p &&
283 if (!tid_found && !mvmvif->queue_params[ac].acm) { 363 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD))
284 tid_found = true; 364 allow_uapsd = false;
285 switch (ac) { 365 /*
286 case IEEE80211_AC_VO: 366 * Avoid using uAPSD if P2P client is associated to GO that uses
287 cmd->qndp_tid = 6; 367 * opportunistic power save. This is due to current FW limitation.
288 break; 368 */
289 case IEEE80211_AC_VI: 369 if (vif->p2p &&
290 cmd->qndp_tid = 5; 370 vif->bss_conf.p2p_noa_attr.oppps_ctwindow &
291 break; 371 IEEE80211_P2P_OPPPS_ENABLE_BIT)
292 case IEEE80211_AC_BE: 372 allow_uapsd = false;
293 cmd->qndp_tid = 0;
294 break;
295 case IEEE80211_AC_BK:
296 cmd->qndp_tid = 1;
297 break;
298 }
299 }
300 }
301
302 if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
303 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
304 BIT(IEEE80211_AC_VI) |
305 BIT(IEEE80211_AC_BE) |
306 BIT(IEEE80211_AC_BK))) {
307 cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
308 cmd->snooze_interval =
309 cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL);
310 cmd->snooze_window =
311 (mvm->cur_ucode == IWL_UCODE_WOWLAN) ?
312 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) :
313 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
314 }
315
316 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
317
318 if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
319 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
320 cmd->rx_data_timeout_uapsd =
321 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
322 cmd->tx_data_timeout_uapsd =
323 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
324 } else {
325 cmd->rx_data_timeout_uapsd =
326 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
327 cmd->tx_data_timeout_uapsd =
328 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
329 }
330 373
331 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { 374 if (allow_uapsd)
332 cmd->heavy_tx_thld_packets = 375 iwl_mvm_power_configure_uapsd(mvm, vif, cmd);
333 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
334 cmd->heavy_rx_thld_packets =
335 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
336 } else {
337 cmd->heavy_tx_thld_packets =
338 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
339 cmd->heavy_rx_thld_packets =
340 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
341 }
342 cmd->heavy_tx_thld_percentage =
343 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
344 cmd->heavy_rx_thld_percentage =
345 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
346 }
347 376
348#ifdef CONFIG_IWLWIFI_DEBUGFS 377#ifdef CONFIG_IWLWIFI_DEBUGFS
349 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) 378 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
@@ -381,6 +410,13 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
381 cmd->flags &= 410 cmd->flags &=
382 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK); 411 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK);
383 } 412 }
413 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_UAPSD_MISBEHAVING) {
414 u16 flag = POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK;
415 if (mvmvif->dbgfs_pm.uapsd_misbehaving)
416 cmd->flags |= cpu_to_le16(flag);
417 else
418 cmd->flags &= cpu_to_le16(flag);
419 }
384#endif /* CONFIG_IWLWIFI_DEBUGFS */ 420#endif /* CONFIG_IWLWIFI_DEBUGFS */
385} 421}
386 422
@@ -391,18 +427,11 @@ static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
391 bool ba_enable; 427 bool ba_enable;
392 struct iwl_mac_power_cmd cmd = {}; 428 struct iwl_mac_power_cmd cmd = {};
393 429
394 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 430 if (vif->type != NL80211_IFTYPE_STATION)
395 return 0; 431 return 0;
396 432
397 /* 433 if (vif->p2p &&
398 * TODO: The following vif_count verification is temporary condition. 434 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
399 * Avoid power mode update if more than one interface is currently
400 * active. Remove this condition when FW will support power management
401 * on multiple MACs.
402 */
403 IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
404 mvm->vif_count);
405 if (mvm->vif_count > 1)
406 return 0; 435 return 0;
407 436
408 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 437 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
@@ -446,7 +475,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
446 sizeof(cmd), &cmd); 475 sizeof(cmd), &cmd);
447} 476}
448 477
449static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) 478static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable)
450{ 479{
451 struct iwl_device_power_cmd cmd = { 480 struct iwl_device_power_cmd cmd = {
452 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), 481 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
@@ -455,7 +484,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
455 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) 484 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
456 return 0; 485 return 0;
457 486
458 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 487 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
488 force_disable)
459 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); 489 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);
460 490
461#ifdef CONFIG_IWLWIFI_DEBUGFS 491#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -472,6 +502,78 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
472 &cmd); 502 &cmd);
473} 503}
474 504
505static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
506{
507 return _iwl_mvm_power_update_device(mvm, false);
508}
509
510void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
511{
512 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
513
514 if (memcmp(vif->bss_conf.bssid, mvmvif->uapsd_misbehaving_bssid,
515 ETH_ALEN))
516 memset(mvmvif->uapsd_misbehaving_bssid, 0, ETH_ALEN);
517}
518
519static void iwl_mvm_power_uapsd_misbehav_ap_iterator(void *_data, u8 *mac,
520 struct ieee80211_vif *vif)
521{
522 u8 *ap_sta_id = _data;
523 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
524
525 /* The ap_sta_id is not expected to change during current association
526 * so no explicit protection is needed
527 */
528 if (mvmvif->ap_sta_id == *ap_sta_id)
529 memcpy(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
530 ETH_ALEN);
531}
532
533int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
534 struct iwl_rx_cmd_buffer *rxb,
535 struct iwl_device_cmd *cmd)
536{
537 struct iwl_rx_packet *pkt = rxb_addr(rxb);
538 struct iwl_uapsd_misbehaving_ap_notif *notif = (void *)pkt->data;
539 u8 ap_sta_id = le32_to_cpu(notif->sta_id);
540
541 ieee80211_iterate_active_interfaces_atomic(
542 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
543 iwl_mvm_power_uapsd_misbehav_ap_iterator, &ap_sta_id);
544
545 return 0;
546}
547
548static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac,
549 struct ieee80211_vif *vif)
550{
551 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
552 struct iwl_mvm *mvm = _data;
553 int ret;
554
555 mvmvif->pm_prevented = (mvm->bound_vif_cnt <= 1) ? false : true;
556
557 ret = iwl_mvm_power_mac_update_mode(mvm, vif);
558 WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n");
559}
560
561static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
562 struct ieee80211_vif *vif,
563 bool assign)
564{
565 if (vif->type == NL80211_IFTYPE_MONITOR) {
566 int ret = _iwl_mvm_power_update_device(mvm, assign);
567 mvm->ps_prevented = assign;
568 WARN_ONCE(ret, "Failed to update power device state\n");
569 }
570
571 ieee80211_iterate_active_interfaces(mvm->hw,
572 IEEE80211_IFACE_ITER_NORMAL,
573 iwl_mvm_power_binding_iterator,
574 mvm);
575}
576
475#ifdef CONFIG_IWLWIFI_DEBUGFS 577#ifdef CONFIG_IWLWIFI_DEBUGFS
476static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, 578static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
477 struct ieee80211_vif *vif, char *buf, 579 struct ieee80211_vif *vif, char *buf,
@@ -494,70 +596,58 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
494 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", 596 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
495 le16_to_cpu(cmd.keep_alive_seconds)); 597 le16_to_cpu(cmd.keep_alive_seconds));
496 598
497 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { 599 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)))
498 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", 600 return pos;
499 (cmd.flags & 601
500 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 602 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
501 1 : 0); 603 (cmd.flags &
502 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", 604 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 1 : 0);
503 cmd.skip_dtim_periods); 605 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
504 if (!(cmd.flags & 606 cmd.skip_dtim_periods);
505 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) { 607 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) {
506 pos += scnprintf(buf+pos, bufsz-pos, 608 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
507 "rx_data_timeout = %d\n", 609 le32_to_cpu(cmd.rx_data_timeout));
508 le32_to_cpu(cmd.rx_data_timeout)); 610 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
509 pos += scnprintf(buf+pos, bufsz-pos, 611 le32_to_cpu(cmd.tx_data_timeout));
510 "tx_data_timeout = %d\n",
511 le32_to_cpu(cmd.tx_data_timeout));
512 }
513 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
514 pos += scnprintf(buf+pos, bufsz-pos,
515 "lprx_rssi_threshold = %d\n",
516 cmd.lprx_rssi_threshold);
517 if (cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
518 pos +=
519 scnprintf(buf+pos, bufsz-pos,
520 "rx_data_timeout_uapsd = %d\n",
521 le32_to_cpu(cmd.rx_data_timeout_uapsd));
522 pos +=
523 scnprintf(buf+pos, bufsz-pos,
524 "tx_data_timeout_uapsd = %d\n",
525 le32_to_cpu(cmd.tx_data_timeout_uapsd));
526 pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n",
527 cmd.qndp_tid);
528 pos += scnprintf(buf+pos, bufsz-pos,
529 "uapsd_ac_flags = 0x%x\n",
530 cmd.uapsd_ac_flags);
531 pos += scnprintf(buf+pos, bufsz-pos,
532 "uapsd_max_sp = %d\n",
533 cmd.uapsd_max_sp);
534 pos += scnprintf(buf+pos, bufsz-pos,
535 "heavy_tx_thld_packets = %d\n",
536 cmd.heavy_tx_thld_packets);
537 pos += scnprintf(buf+pos, bufsz-pos,
538 "heavy_rx_thld_packets = %d\n",
539 cmd.heavy_rx_thld_packets);
540 pos += scnprintf(buf+pos, bufsz-pos,
541 "heavy_tx_thld_percentage = %d\n",
542 cmd.heavy_tx_thld_percentage);
543 pos += scnprintf(buf+pos, bufsz-pos,
544 "heavy_rx_thld_percentage = %d\n",
545 cmd.heavy_rx_thld_percentage);
546 pos +=
547 scnprintf(buf+pos, bufsz-pos, "snooze_enable = %d\n",
548 (cmd.flags &
549 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) ?
550 1 : 0);
551 }
552 if (cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
553 pos += scnprintf(buf+pos, bufsz-pos,
554 "snooze_interval = %d\n",
555 cmd.snooze_interval);
556 pos += scnprintf(buf+pos, bufsz-pos,
557 "snooze_window = %d\n",
558 cmd.snooze_window);
559 }
560 } 612 }
613 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
614 pos += scnprintf(buf+pos, bufsz-pos,
615 "lprx_rssi_threshold = %d\n",
616 cmd.lprx_rssi_threshold);
617
618 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
619 return pos;
620
621 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout_uapsd = %d\n",
622 le32_to_cpu(cmd.rx_data_timeout_uapsd));
623 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout_uapsd = %d\n",
624 le32_to_cpu(cmd.tx_data_timeout_uapsd));
625 pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n", cmd.qndp_tid);
626 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_ac_flags = 0x%x\n",
627 cmd.uapsd_ac_flags);
628 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_max_sp = %d\n",
629 cmd.uapsd_max_sp);
630 pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_packets = %d\n",
631 cmd.heavy_tx_thld_packets);
632 pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_packets = %d\n",
633 cmd.heavy_rx_thld_packets);
634 pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_percentage = %d\n",
635 cmd.heavy_tx_thld_percentage);
636 pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_percentage = %d\n",
637 cmd.heavy_rx_thld_percentage);
638 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_misbehaving_enable = %d\n",
639 (cmd.flags &
640 cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK)) ?
641 1 : 0);
642
643 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)))
644 return pos;
645
646 pos += scnprintf(buf+pos, bufsz-pos, "snooze_interval = %d\n",
647 cmd.snooze_interval);
648 pos += scnprintf(buf+pos, bufsz-pos, "snooze_window = %d\n",
649 cmd.snooze_window);
650
561 return pos; 651 return pos;
562} 652}
563 653
@@ -654,6 +744,7 @@ const struct iwl_mvm_power_ops pm_mac_ops = {
654 .power_update_mode = iwl_mvm_power_mac_update_mode, 744 .power_update_mode = iwl_mvm_power_mac_update_mode,
655 .power_update_device_mode = iwl_mvm_power_update_device, 745 .power_update_device_mode = iwl_mvm_power_update_device,
656 .power_disable = iwl_mvm_power_mac_disable, 746 .power_disable = iwl_mvm_power_mac_disable,
747 .power_update_binding = _iwl_mvm_power_update_binding,
657#ifdef CONFIG_IWLWIFI_DEBUGFS 748#ifdef CONFIG_IWLWIFI_DEBUGFS
658 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, 749 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read,
659#endif 750#endif