1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
5 * Copyright (C) 2015-2017 Intel Deutschland GmbH
7 #include <net/mac80211.h>
14 #include "fw/api/rs.h"
18 * Will return 0 even if the cmd failed when RFKILL is asserted unless
19 * CMD_WANT_SKB is set in cmd->flags.
21 int iwl_mvm_send_cmd(struct iwl_mvm
*mvm
, struct iwl_host_cmd
*cmd
)
25 #if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
26 if (WARN_ON(mvm
->d3_test_active
))
31 * Synchronous commands from this op-mode must hold
32 * the mutex, this ensures we don't try to send two
33 * (or more) synchronous commands at a time.
35 if (!(cmd
->flags
& CMD_ASYNC
))
36 lockdep_assert_held(&mvm
->mutex
);
38 ret
= iwl_trans_send_cmd(mvm
->trans
, cmd
);
41 * If the caller wants the SKB, then don't hide any problems, the
42 * caller might access the response buffer which will be NULL if
45 if (cmd
->flags
& CMD_WANT_SKB
)
49 * Silently ignore failures if RFKILL is asserted or
50 * we are in suspend\resume process
52 if (!ret
|| ret
== -ERFKILL
|| ret
== -EHOSTDOWN
)
57 int iwl_mvm_send_cmd_pdu(struct iwl_mvm
*mvm
, u32 id
,
58 u32 flags
, u16 len
, const void *data
)
60 struct iwl_host_cmd cmd
= {
67 return iwl_mvm_send_cmd(mvm
, &cmd
);
71 * We assume that the caller set the status to the success value
73 int iwl_mvm_send_cmd_status(struct iwl_mvm
*mvm
, struct iwl_host_cmd
*cmd
,
76 struct iwl_rx_packet
*pkt
;
77 struct iwl_cmd_response
*resp
;
80 lockdep_assert_held(&mvm
->mutex
);
82 #if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
83 if (WARN_ON(mvm
->d3_test_active
))
88 * Only synchronous commands can wait for status,
89 * we use WANT_SKB so the caller can't.
91 if (WARN_ONCE(cmd
->flags
& (CMD_ASYNC
| CMD_WANT_SKB
),
92 "cmd flags %x", cmd
->flags
))
95 cmd
->flags
|= CMD_WANT_SKB
;
97 ret
= iwl_trans_send_cmd(mvm
->trans
, cmd
);
98 if (ret
== -ERFKILL
) {
100 * The command failed because of RFKILL, don't update
101 * the status, leave it as success and return 0.
110 resp_len
= iwl_rx_packet_payload_len(pkt
);
111 if (WARN_ON_ONCE(resp_len
!= sizeof(*resp
))) {
116 resp
= (void *)pkt
->data
;
117 *status
= le32_to_cpu(resp
->status
);
124 * We assume that the caller set the status to the sucess value
126 int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm
*mvm
, u32 id
, u16 len
,
127 const void *data
, u32
*status
)
129 struct iwl_host_cmd cmd
= {
135 return iwl_mvm_send_cmd_status(mvm
, &cmd
, status
);
138 #define IWL_DECLARE_RATE_INFO(r) \
139 [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
142 * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
144 static const u8 fw_rate_idx_to_plcp
[IWL_RATE_COUNT
] = {
145 IWL_DECLARE_RATE_INFO(1),
146 IWL_DECLARE_RATE_INFO(2),
147 IWL_DECLARE_RATE_INFO(5),
148 IWL_DECLARE_RATE_INFO(11),
149 IWL_DECLARE_RATE_INFO(6),
150 IWL_DECLARE_RATE_INFO(9),
151 IWL_DECLARE_RATE_INFO(12),
152 IWL_DECLARE_RATE_INFO(18),
153 IWL_DECLARE_RATE_INFO(24),
154 IWL_DECLARE_RATE_INFO(36),
155 IWL_DECLARE_RATE_INFO(48),
156 IWL_DECLARE_RATE_INFO(54),
159 int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags
,
160 enum nl80211_band band
)
162 int rate
= rate_n_flags
& RATE_LEGACY_RATE_MSK
;
166 /* Legacy rate format, search for match in table */
167 if (band
!= NL80211_BAND_2GHZ
)
168 band_offset
= IWL_FIRST_OFDM_RATE
;
169 for (idx
= band_offset
; idx
< IWL_RATE_COUNT_LEGACY
; idx
++)
170 if (fw_rate_idx_to_plcp
[idx
] == rate
)
171 return idx
- band_offset
;
176 u8
iwl_mvm_mac80211_idx_to_hwrate(int rate_idx
)
178 /* Get PLCP rate for tx_cmd->rate_n_flags */
179 return fw_rate_idx_to_plcp
[rate_idx
];
182 u8
iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac
)
184 static const u8 mac80211_ac_to_ucode_ac
[] = {
191 return mac80211_ac_to_ucode_ac
[ac
];
194 void iwl_mvm_rx_fw_error(struct iwl_mvm
*mvm
, struct iwl_rx_cmd_buffer
*rxb
)
196 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
197 struct iwl_error_resp
*err_resp
= (void *)pkt
->data
;
199 IWL_ERR(mvm
, "FW Error notification: type 0x%08X cmd_id 0x%02X\n",
200 le32_to_cpu(err_resp
->error_type
), err_resp
->cmd_id
);
201 IWL_ERR(mvm
, "FW Error notification: seq 0x%04X service 0x%08X\n",
202 le16_to_cpu(err_resp
->bad_cmd_seq_num
),
203 le32_to_cpu(err_resp
->error_service
));
204 IWL_ERR(mvm
, "FW Error notification: timestamp 0x%016llX\n",
205 le64_to_cpu(err_resp
->timestamp
));
209 * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h.
210 * The parameter should also be a combination of ANT_[ABC].
212 u8
first_antenna(u8 mask
)
214 BUILD_BUG_ON(ANT_A
!= BIT(0)); /* using ffs is wrong if not */
215 if (WARN_ON_ONCE(!mask
)) /* ffs will return 0 if mask is zeroed */
217 return BIT(ffs(mask
) - 1);
221 * Toggles between TX antennas to send the probe request on.
222 * Receives the bitmask of valid TX antennas and the *index* used
223 * for the last TX, and returns the next valid *index* to use.
224 * In order to set it in the tx_cmd, must do BIT(idx).
226 u8
iwl_mvm_next_antenna(struct iwl_mvm
*mvm
, u8 valid
, u8 last_idx
)
231 for (i
= 0; i
< MAX_ANT_NUM
; i
++) {
232 ind
= (ind
+ 1) % MAX_ANT_NUM
;
233 if (valid
& BIT(ind
))
237 WARN_ONCE(1, "Failed to toggle between antennas 0x%x", valid
);
242 * Note: This structure is read from the device with IO accesses,
243 * and the reading already does the endian conversion. As it is
244 * read with u32-sized accesses, any members with a different size
245 * need to be ordered correctly though!
247 struct iwl_error_event_table_v1
{
248 u32 valid
; /* (nonzero) valid, (0) log is empty */
249 u32 error_id
; /* type of error */
250 u32 pc
; /* program counter */
251 u32 blink1
; /* branch link */
252 u32 blink2
; /* branch link */
253 u32 ilink1
; /* interrupt link */
254 u32 ilink2
; /* interrupt link */
255 u32 data1
; /* error-specific data */
256 u32 data2
; /* error-specific data */
257 u32 data3
; /* error-specific data */
258 u32 bcon_time
; /* beacon timer */
259 u32 tsf_low
; /* network timestamp function timer */
260 u32 tsf_hi
; /* network timestamp function timer */
261 u32 gp1
; /* GP1 timer register */
262 u32 gp2
; /* GP2 timer register */
263 u32 gp3
; /* GP3 timer register */
264 u32 ucode_ver
; /* uCode version */
265 u32 hw_ver
; /* HW Silicon version */
266 u32 brd_ver
; /* HW board version */
267 u32 log_pc
; /* log program counter */
268 u32 frame_ptr
; /* frame pointer */
269 u32 stack_ptr
; /* stack pointer */
270 u32 hcmd
; /* last host command header */
271 u32 isr0
; /* isr status register LMPM_NIC_ISR0:
273 u32 isr1
; /* isr status register LMPM_NIC_ISR1:
275 u32 isr2
; /* isr status register LMPM_NIC_ISR2:
277 u32 isr3
; /* isr status register LMPM_NIC_ISR3:
279 u32 isr4
; /* isr status register LMPM_NIC_ISR4:
281 u32 isr_pref
; /* isr status register LMPM_NIC_PREF_STAT */
282 u32 wait_event
; /* wait event() caller address */
283 u32 l2p_control
; /* L2pControlField */
284 u32 l2p_duration
; /* L2pDurationField */
285 u32 l2p_mhvalid
; /* L2pMhValidBits */
286 u32 l2p_addr_match
; /* L2pAddrMatchStat */
287 u32 lmpm_pmg_sel
; /* indicate which clocks are turned on
289 u32 u_timestamp
; /* indicate when the date and time of the
291 u32 flow_handler
; /* FH read/write pointers, RX credit */
292 } __packed
/* LOG_ERROR_TABLE_API_S_VER_1 */;
294 struct iwl_error_event_table
{
295 u32 valid
; /* (nonzero) valid, (0) log is empty */
296 u32 error_id
; /* type of error */
297 u32 trm_hw_status0
; /* TRM HW status */
298 u32 trm_hw_status1
; /* TRM HW status */
299 u32 blink2
; /* branch link */
300 u32 ilink1
; /* interrupt link */
301 u32 ilink2
; /* interrupt link */
302 u32 data1
; /* error-specific data */
303 u32 data2
; /* error-specific data */
304 u32 data3
; /* error-specific data */
305 u32 bcon_time
; /* beacon timer */
306 u32 tsf_low
; /* network timestamp function timer */
307 u32 tsf_hi
; /* network timestamp function timer */
308 u32 gp1
; /* GP1 timer register */
309 u32 gp2
; /* GP2 timer register */
310 u32 fw_rev_type
; /* firmware revision type */
311 u32 major
; /* uCode version major */
312 u32 minor
; /* uCode version minor */
313 u32 hw_ver
; /* HW Silicon version */
314 u32 brd_ver
; /* HW board version */
315 u32 log_pc
; /* log program counter */
316 u32 frame_ptr
; /* frame pointer */
317 u32 stack_ptr
; /* stack pointer */
318 u32 hcmd
; /* last host command header */
319 u32 isr0
; /* isr status register LMPM_NIC_ISR0:
321 u32 isr1
; /* isr status register LMPM_NIC_ISR1:
323 u32 isr2
; /* isr status register LMPM_NIC_ISR2:
325 u32 isr3
; /* isr status register LMPM_NIC_ISR3:
327 u32 isr4
; /* isr status register LMPM_NIC_ISR4:
329 u32 last_cmd_id
; /* last HCMD id handled by the firmware */
330 u32 wait_event
; /* wait event() caller address */
331 u32 l2p_control
; /* L2pControlField */
332 u32 l2p_duration
; /* L2pDurationField */
333 u32 l2p_mhvalid
; /* L2pMhValidBits */
334 u32 l2p_addr_match
; /* L2pAddrMatchStat */
335 u32 lmpm_pmg_sel
; /* indicate which clocks are turned on
337 u32 u_timestamp
; /* indicate when the date and time of the
339 u32 flow_handler
; /* FH read/write pointers, RX credit */
340 } __packed
/* LOG_ERROR_TABLE_API_S_VER_3 */;
343 * UMAC error struct - relevant starting from family 8000 chip.
344 * Note: This structure is read from the device with IO accesses,
345 * and the reading already does the endian conversion. As it is
346 * read with u32-sized accesses, any members with a different size
347 * need to be ordered correctly though!
349 struct iwl_umac_error_event_table
{
350 u32 valid
; /* (nonzero) valid, (0) log is empty */
351 u32 error_id
; /* type of error */
352 u32 blink1
; /* branch link */
353 u32 blink2
; /* branch link */
354 u32 ilink1
; /* interrupt link */
355 u32 ilink2
; /* interrupt link */
356 u32 data1
; /* error-specific data */
357 u32 data2
; /* error-specific data */
358 u32 data3
; /* error-specific data */
361 u32 frame_pointer
; /* core register 27*/
362 u32 stack_pointer
; /* core register 28 */
363 u32 cmd_header
; /* latest host cmd sent to UMAC */
364 u32 nic_isr_pref
; /* ISR status register */
367 #define ERROR_START_OFFSET (1 * sizeof(u32))
368 #define ERROR_ELEM_SIZE (7 * sizeof(u32))
370 static void iwl_mvm_dump_umac_error_log(struct iwl_mvm
*mvm
)
372 struct iwl_trans
*trans
= mvm
->trans
;
373 struct iwl_umac_error_event_table table
= {};
374 u32 base
= mvm
->trans
->dbg
.umac_error_event_table
;
377 !(mvm
->trans
->dbg
.error_event_table_tlv_status
&
378 IWL_ERROR_EVENT_TABLE_UMAC
))
381 iwl_trans_read_mem_bytes(trans
, base
, &table
, sizeof(table
));
384 mvm
->fwrt
.dump
.umac_err_id
= table
.error_id
;
386 if (ERROR_START_OFFSET
<= table
.valid
* ERROR_ELEM_SIZE
) {
387 IWL_ERR(trans
, "Start IWL Error Log Dump:\n");
388 IWL_ERR(trans
, "Status: 0x%08lX, count: %d\n",
389 mvm
->status
, table
.valid
);
392 IWL_ERR(mvm
, "0x%08X | %s\n", table
.error_id
,
393 iwl_fw_lookup_assert_desc(table
.error_id
));
394 IWL_ERR(mvm
, "0x%08X | umac branchlink1\n", table
.blink1
);
395 IWL_ERR(mvm
, "0x%08X | umac branchlink2\n", table
.blink2
);
396 IWL_ERR(mvm
, "0x%08X | umac interruptlink1\n", table
.ilink1
);
397 IWL_ERR(mvm
, "0x%08X | umac interruptlink2\n", table
.ilink2
);
398 IWL_ERR(mvm
, "0x%08X | umac data1\n", table
.data1
);
399 IWL_ERR(mvm
, "0x%08X | umac data2\n", table
.data2
);
400 IWL_ERR(mvm
, "0x%08X | umac data3\n", table
.data3
);
401 IWL_ERR(mvm
, "0x%08X | umac major\n", table
.umac_major
);
402 IWL_ERR(mvm
, "0x%08X | umac minor\n", table
.umac_minor
);
403 IWL_ERR(mvm
, "0x%08X | frame pointer\n", table
.frame_pointer
);
404 IWL_ERR(mvm
, "0x%08X | stack pointer\n", table
.stack_pointer
);
405 IWL_ERR(mvm
, "0x%08X | last host cmd\n", table
.cmd_header
);
406 IWL_ERR(mvm
, "0x%08X | isr status reg\n", table
.nic_isr_pref
);
409 static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm
*mvm
, u8 lmac_num
)
411 struct iwl_trans
*trans
= mvm
->trans
;
412 struct iwl_error_event_table table
= {};
413 u32 val
, base
= mvm
->trans
->dbg
.lmac_error_event_table
[lmac_num
];
415 if (mvm
->fwrt
.cur_fw_img
== IWL_UCODE_INIT
) {
417 base
= mvm
->fw
->init_errlog_ptr
;
420 base
= mvm
->fw
->inst_errlog_ptr
;
423 if (base
< 0x400000) {
425 "Not valid error log pointer 0x%08X for %s uCode\n",
427 (mvm
->fwrt
.cur_fw_img
== IWL_UCODE_INIT
)
432 /* check if there is a HW error */
433 val
= iwl_trans_read_mem32(trans
, base
);
434 if (((val
& ~0xf) == 0xa5a5a5a0) || ((val
& ~0xf) == 0x5a5a5a50)) {
437 IWL_ERR(trans
, "HW error, resetting before reading\n");
439 /* reset the device */
440 iwl_trans_sw_reset(trans
);
442 err
= iwl_finish_nic_init(trans
, trans
->trans_cfg
);
447 iwl_trans_read_mem_bytes(trans
, base
, &table
, sizeof(table
));
450 mvm
->fwrt
.dump
.lmac_err_id
[lmac_num
] = table
.error_id
;
452 if (ERROR_START_OFFSET
<= table
.valid
* ERROR_ELEM_SIZE
) {
453 IWL_ERR(trans
, "Start IWL Error Log Dump:\n");
454 IWL_ERR(trans
, "Status: 0x%08lX, count: %d\n",
455 mvm
->status
, table
.valid
);
458 /* Do not change this output - scripts rely on it */
460 IWL_ERR(mvm
, "Loaded firmware version: %s\n", mvm
->fw
->fw_version
);
462 IWL_ERR(mvm
, "0x%08X | %-28s\n", table
.error_id
,
463 iwl_fw_lookup_assert_desc(table
.error_id
));
464 IWL_ERR(mvm
, "0x%08X | trm_hw_status0\n", table
.trm_hw_status0
);
465 IWL_ERR(mvm
, "0x%08X | trm_hw_status1\n", table
.trm_hw_status1
);
466 IWL_ERR(mvm
, "0x%08X | branchlink2\n", table
.blink2
);
467 IWL_ERR(mvm
, "0x%08X | interruptlink1\n", table
.ilink1
);
468 IWL_ERR(mvm
, "0x%08X | interruptlink2\n", table
.ilink2
);
469 IWL_ERR(mvm
, "0x%08X | data1\n", table
.data1
);
470 IWL_ERR(mvm
, "0x%08X | data2\n", table
.data2
);
471 IWL_ERR(mvm
, "0x%08X | data3\n", table
.data3
);
472 IWL_ERR(mvm
, "0x%08X | beacon time\n", table
.bcon_time
);
473 IWL_ERR(mvm
, "0x%08X | tsf low\n", table
.tsf_low
);
474 IWL_ERR(mvm
, "0x%08X | tsf hi\n", table
.tsf_hi
);
475 IWL_ERR(mvm
, "0x%08X | time gp1\n", table
.gp1
);
476 IWL_ERR(mvm
, "0x%08X | time gp2\n", table
.gp2
);
477 IWL_ERR(mvm
, "0x%08X | uCode revision type\n", table
.fw_rev_type
);
478 IWL_ERR(mvm
, "0x%08X | uCode version major\n", table
.major
);
479 IWL_ERR(mvm
, "0x%08X | uCode version minor\n", table
.minor
);
480 IWL_ERR(mvm
, "0x%08X | hw version\n", table
.hw_ver
);
481 IWL_ERR(mvm
, "0x%08X | board version\n", table
.brd_ver
);
482 IWL_ERR(mvm
, "0x%08X | hcmd\n", table
.hcmd
);
483 IWL_ERR(mvm
, "0x%08X | isr0\n", table
.isr0
);
484 IWL_ERR(mvm
, "0x%08X | isr1\n", table
.isr1
);
485 IWL_ERR(mvm
, "0x%08X | isr2\n", table
.isr2
);
486 IWL_ERR(mvm
, "0x%08X | isr3\n", table
.isr3
);
487 IWL_ERR(mvm
, "0x%08X | isr4\n", table
.isr4
);
488 IWL_ERR(mvm
, "0x%08X | last cmd Id\n", table
.last_cmd_id
);
489 IWL_ERR(mvm
, "0x%08X | wait_event\n", table
.wait_event
);
490 IWL_ERR(mvm
, "0x%08X | l2p_control\n", table
.l2p_control
);
491 IWL_ERR(mvm
, "0x%08X | l2p_duration\n", table
.l2p_duration
);
492 IWL_ERR(mvm
, "0x%08X | l2p_mhvalid\n", table
.l2p_mhvalid
);
493 IWL_ERR(mvm
, "0x%08X | l2p_addr_match\n", table
.l2p_addr_match
);
494 IWL_ERR(mvm
, "0x%08X | lmpm_pmg_sel\n", table
.lmpm_pmg_sel
);
495 IWL_ERR(mvm
, "0x%08X | timestamp\n", table
.u_timestamp
);
496 IWL_ERR(mvm
, "0x%08X | flow_handler\n", table
.flow_handler
);
499 static void iwl_mvm_dump_iml_error_log(struct iwl_mvm
*mvm
)
501 struct iwl_trans
*trans
= mvm
->trans
;
504 if (mvm
->trans
->trans_cfg
->device_family
>= IWL_DEVICE_FAMILY_22000
) {
505 error
= UMAG_SB_CPU_2_STATUS
;
506 data1
= UMAG_SB_CPU_1_STATUS
;
507 } else if (mvm
->trans
->trans_cfg
->device_family
>=
508 IWL_DEVICE_FAMILY_8000
) {
509 error
= SB_CPU_2_STATUS
;
510 data1
= SB_CPU_1_STATUS
;
515 error
= iwl_read_umac_prph(trans
, UMAG_SB_CPU_2_STATUS
);
517 IWL_ERR(trans
, "IML/ROM dump:\n");
519 if (error
& 0xFFFF0000)
520 IWL_ERR(trans
, "0x%04X | IML/ROM SYSASSERT\n", error
>> 16);
522 IWL_ERR(mvm
, "0x%08X | IML/ROM error/state\n", error
);
523 IWL_ERR(mvm
, "0x%08X | IML/ROM data1\n",
524 iwl_read_umac_prph(trans
, data1
));
526 if (mvm
->trans
->trans_cfg
->device_family
>= IWL_DEVICE_FAMILY_22000
)
527 IWL_ERR(mvm
, "0x%08X | IML/ROM WFPM_AUTH_KEY_0\n",
528 iwl_read_umac_prph(trans
, SB_MODIFY_CFG_FLAG
));
531 void iwl_mvm_dump_nic_error_log(struct iwl_mvm
*mvm
)
533 if (!test_bit(STATUS_DEVICE_ENABLED
, &mvm
->trans
->status
)) {
535 "DEVICE_ENABLED bit is not set. Aborting dump.\n");
539 iwl_mvm_dump_lmac_error_log(mvm
, 0);
541 if (mvm
->trans
->dbg
.lmac_error_event_table
[1])
542 iwl_mvm_dump_lmac_error_log(mvm
, 1);
544 iwl_mvm_dump_umac_error_log(mvm
);
546 iwl_mvm_dump_iml_error_log(mvm
);
548 iwl_fw_error_print_fseq_regs(&mvm
->fwrt
);
551 int iwl_mvm_reconfig_scd(struct iwl_mvm
*mvm
, int queue
, int fifo
, int sta_id
,
552 int tid
, int frame_limit
, u16 ssn
)
554 struct iwl_scd_txq_cfg_cmd cmd
= {
556 .action
= SCD_CFG_ENABLE_QUEUE
,
557 .window
= frame_limit
,
559 .ssn
= cpu_to_le16(ssn
),
561 .aggregate
= (queue
>= IWL_MVM_DQA_MIN_DATA_QUEUE
||
562 queue
== IWL_MVM_DQA_BSS_CLIENT_QUEUE
),
567 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm
)))
570 if (WARN(mvm
->queue_info
[queue
].tid_bitmap
== 0,
571 "Trying to reconfig unallocated queue %d\n", queue
))
574 IWL_DEBUG_TX_QUEUES(mvm
, "Reconfig SCD for TXQ #%d\n", queue
);
576 ret
= iwl_mvm_send_cmd_pdu(mvm
, SCD_QUEUE_CFG
, 0, sizeof(cmd
), &cmd
);
577 WARN_ONCE(ret
, "Failed to re-configure queue %d on FIFO %d, ret=%d\n",
584 * iwl_mvm_send_lq_cmd() - Send link quality command
586 * @lq: Link quality command to send.
588 * The link quality command is sent as the last step of station creation.
589 * This is the special case in which init is set and we call a callback in
590 * this case to clear the state indicating that station creation is in
593 int iwl_mvm_send_lq_cmd(struct iwl_mvm
*mvm
, struct iwl_lq_cmd
*lq
)
595 struct iwl_host_cmd cmd
= {
597 .len
= { sizeof(struct iwl_lq_cmd
), },
602 if (WARN_ON(lq
->sta_id
== IWL_MVM_INVALID_STA
||
603 iwl_mvm_has_tlc_offload(mvm
)))
606 return iwl_mvm_send_cmd(mvm
, &cmd
);
610 * iwl_mvm_update_smps - Get a request to change the SMPS mode
612 * @vif: Pointer to the ieee80211_vif structure
613 * @req_type: The part of the driver who call for a change.
614 * @smps_request: The request to change the SMPS mode.
616 * Get a requst to change the SMPS mode,
617 * and change it according to all other requests in the driver.
619 void iwl_mvm_update_smps(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
620 enum iwl_mvm_smps_type_request req_type
,
621 enum ieee80211_smps_mode smps_request
)
623 struct iwl_mvm_vif
*mvmvif
;
624 enum ieee80211_smps_mode smps_mode
= IEEE80211_SMPS_AUTOMATIC
;
627 lockdep_assert_held(&mvm
->mutex
);
629 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
630 if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm
)) == 1)
633 if (vif
->type
!= NL80211_IFTYPE_STATION
)
636 mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
637 mvmvif
->smps_requests
[req_type
] = smps_request
;
638 for (i
= 0; i
< NUM_IWL_MVM_SMPS_REQ
; i
++) {
639 if (mvmvif
->smps_requests
[i
] == IEEE80211_SMPS_STATIC
) {
640 smps_mode
= IEEE80211_SMPS_STATIC
;
643 if (mvmvif
->smps_requests
[i
] == IEEE80211_SMPS_DYNAMIC
)
644 smps_mode
= IEEE80211_SMPS_DYNAMIC
;
647 ieee80211_request_smps(vif
, smps_mode
);
650 int iwl_mvm_request_statistics(struct iwl_mvm
*mvm
, bool clear
)
652 struct iwl_statistics_cmd scmd
= {
653 .flags
= clear
? cpu_to_le32(IWL_STATISTICS_FLG_CLEAR
) : 0,
655 struct iwl_host_cmd cmd
= {
656 .id
= STATISTICS_CMD
,
657 .len
[0] = sizeof(scmd
),
659 .flags
= CMD_WANT_SKB
,
663 ret
= iwl_mvm_send_cmd(mvm
, &cmd
);
667 iwl_mvm_handle_rx_statistics(mvm
, cmd
.resp_pkt
);
671 iwl_mvm_accu_radio_stats(mvm
);
676 void iwl_mvm_accu_radio_stats(struct iwl_mvm
*mvm
)
678 mvm
->accu_radio_stats
.rx_time
+= mvm
->radio_stats
.rx_time
;
679 mvm
->accu_radio_stats
.tx_time
+= mvm
->radio_stats
.tx_time
;
680 mvm
->accu_radio_stats
.on_time_rf
+= mvm
->radio_stats
.on_time_rf
;
681 mvm
->accu_radio_stats
.on_time_scan
+= mvm
->radio_stats
.on_time_scan
;
684 struct iwl_mvm_diversity_iter_data
{
685 struct iwl_mvm_phy_ctxt
*ctxt
;
689 static void iwl_mvm_diversity_iter(void *_data
, u8
*mac
,
690 struct ieee80211_vif
*vif
)
692 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
693 struct iwl_mvm_diversity_iter_data
*data
= _data
;
696 if (mvmvif
->phy_ctxt
!= data
->ctxt
)
699 for (i
= 0; i
< NUM_IWL_MVM_SMPS_REQ
; i
++) {
700 if (mvmvif
->smps_requests
[i
] == IEEE80211_SMPS_STATIC
||
701 mvmvif
->smps_requests
[i
] == IEEE80211_SMPS_DYNAMIC
) {
702 data
->result
= false;
708 bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm
*mvm
,
709 struct iwl_mvm_phy_ctxt
*ctxt
)
711 struct iwl_mvm_diversity_iter_data data
= {
716 lockdep_assert_held(&mvm
->mutex
);
718 if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm
)) == 1)
721 if (mvm
->cfg
->rx_with_siso_diversity
)
724 ieee80211_iterate_active_interfaces_atomic(
725 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
726 iwl_mvm_diversity_iter
, &data
);
731 void iwl_mvm_send_low_latency_cmd(struct iwl_mvm
*mvm
,
732 bool low_latency
, u16 mac_id
)
734 struct iwl_mac_low_latency_cmd cmd
= {
735 .mac_id
= cpu_to_le32(mac_id
)
738 if (!fw_has_capa(&mvm
->fw
->ucode_capa
,
739 IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA
))
743 /* currently we don't care about the direction */
744 cmd
.low_latency_rx
= 1;
745 cmd
.low_latency_tx
= 1;
748 if (iwl_mvm_send_cmd_pdu(mvm
, iwl_cmd_id(LOW_LATENCY_CMD
,
750 0, sizeof(cmd
), &cmd
))
751 IWL_ERR(mvm
, "Failed to send low latency command\n");
754 int iwl_mvm_update_low_latency(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
756 enum iwl_mvm_low_latency_cause cause
)
758 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
762 lockdep_assert_held(&mvm
->mutex
);
764 prev
= iwl_mvm_vif_low_latency(mvmvif
);
765 iwl_mvm_vif_set_low_latency(mvmvif
, low_latency
, cause
);
767 low_latency
= iwl_mvm_vif_low_latency(mvmvif
);
769 if (low_latency
== prev
)
772 iwl_mvm_send_low_latency_cmd(mvm
, low_latency
, mvmvif
->id
);
774 res
= iwl_mvm_update_quotas(mvm
, false, NULL
);
778 iwl_mvm_bt_coex_vif_change(mvm
);
780 return iwl_mvm_power_update_mac(mvm
);
783 struct iwl_mvm_low_latency_iter
{
785 bool result_per_band
[NUM_NL80211_BANDS
];
788 static void iwl_mvm_ll_iter(void *_data
, u8
*mac
, struct ieee80211_vif
*vif
)
790 struct iwl_mvm_low_latency_iter
*result
= _data
;
791 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
792 enum nl80211_band band
;
794 if (iwl_mvm_vif_low_latency(mvmvif
)) {
795 result
->result
= true;
797 if (!mvmvif
->phy_ctxt
)
800 band
= mvmvif
->phy_ctxt
->channel
->band
;
801 result
->result_per_band
[band
] = true;
805 bool iwl_mvm_low_latency(struct iwl_mvm
*mvm
)
807 struct iwl_mvm_low_latency_iter data
= {};
809 ieee80211_iterate_active_interfaces_atomic(
810 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
811 iwl_mvm_ll_iter
, &data
);
816 bool iwl_mvm_low_latency_band(struct iwl_mvm
*mvm
, enum nl80211_band band
)
818 struct iwl_mvm_low_latency_iter data
= {};
820 ieee80211_iterate_active_interfaces_atomic(
821 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
822 iwl_mvm_ll_iter
, &data
);
824 return data
.result_per_band
[band
];
827 struct iwl_bss_iter_data
{
828 struct ieee80211_vif
*vif
;
832 static void iwl_mvm_bss_iface_iterator(void *_data
, u8
*mac
,
833 struct ieee80211_vif
*vif
)
835 struct iwl_bss_iter_data
*data
= _data
;
837 if (vif
->type
!= NL80211_IFTYPE_STATION
|| vif
->p2p
)
848 struct ieee80211_vif
*iwl_mvm_get_bss_vif(struct iwl_mvm
*mvm
)
850 struct iwl_bss_iter_data bss_iter_data
= {};
852 ieee80211_iterate_active_interfaces_atomic(
853 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
854 iwl_mvm_bss_iface_iterator
, &bss_iter_data
);
856 if (bss_iter_data
.error
) {
857 IWL_ERR(mvm
, "More than one managed interface active!\n");
858 return ERR_PTR(-EINVAL
);
861 return bss_iter_data
.vif
;
864 struct iwl_bss_find_iter_data
{
865 struct ieee80211_vif
*vif
;
869 static void iwl_mvm_bss_find_iface_iterator(void *_data
, u8
*mac
,
870 struct ieee80211_vif
*vif
)
872 struct iwl_bss_find_iter_data
*data
= _data
;
873 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
875 if (mvmvif
->id
== data
->macid
)
879 struct ieee80211_vif
*iwl_mvm_get_vif_by_macid(struct iwl_mvm
*mvm
, u32 macid
)
881 struct iwl_bss_find_iter_data data
= {
885 lockdep_assert_held(&mvm
->mutex
);
887 ieee80211_iterate_active_interfaces_atomic(
888 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
889 iwl_mvm_bss_find_iface_iterator
, &data
);
894 struct iwl_sta_iter_data
{
898 static void iwl_mvm_sta_iface_iterator(void *_data
, u8
*mac
,
899 struct ieee80211_vif
*vif
)
901 struct iwl_sta_iter_data
*data
= _data
;
903 if (vif
->type
!= NL80211_IFTYPE_STATION
)
906 if (vif
->bss_conf
.assoc
)
910 bool iwl_mvm_is_vif_assoc(struct iwl_mvm
*mvm
)
912 struct iwl_sta_iter_data data
= {
916 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
917 IEEE80211_IFACE_ITER_NORMAL
,
918 iwl_mvm_sta_iface_iterator
,
923 unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm
*mvm
,
924 struct ieee80211_vif
*vif
,
925 bool tdls
, bool cmd_q
)
927 struct iwl_fw_dbg_trigger_tlv
*trigger
;
928 struct iwl_fw_dbg_trigger_txq_timer
*txq_timer
;
929 unsigned int default_timeout
= cmd_q
?
931 mvm
->trans
->trans_cfg
->base_params
->wd_timeout
;
933 if (!iwl_fw_dbg_trigger_enabled(mvm
->fw
, FW_DBG_TRIGGER_TXQ_TIMERS
)) {
935 * We can't know when the station is asleep or awake, so we
936 * must disable the queue hang detection.
938 if (fw_has_capa(&mvm
->fw
->ucode_capa
,
939 IWL_UCODE_TLV_CAPA_STA_PM_NOTIF
) &&
940 vif
&& vif
->type
== NL80211_IFTYPE_AP
)
941 return IWL_WATCHDOG_DISABLED
;
942 return default_timeout
;
945 trigger
= iwl_fw_dbg_get_trigger(mvm
->fw
, FW_DBG_TRIGGER_TXQ_TIMERS
);
946 txq_timer
= (void *)trigger
->data
;
949 return le32_to_cpu(txq_timer
->tdls
);
952 return le32_to_cpu(txq_timer
->command_queue
);
955 return default_timeout
;
957 switch (ieee80211_vif_type_p2p(vif
)) {
958 case NL80211_IFTYPE_ADHOC
:
959 return le32_to_cpu(txq_timer
->ibss
);
960 case NL80211_IFTYPE_STATION
:
961 return le32_to_cpu(txq_timer
->bss
);
962 case NL80211_IFTYPE_AP
:
963 return le32_to_cpu(txq_timer
->softap
);
964 case NL80211_IFTYPE_P2P_CLIENT
:
965 return le32_to_cpu(txq_timer
->p2p_client
);
966 case NL80211_IFTYPE_P2P_GO
:
967 return le32_to_cpu(txq_timer
->p2p_go
);
968 case NL80211_IFTYPE_P2P_DEVICE
:
969 return le32_to_cpu(txq_timer
->p2p_device
);
970 case NL80211_IFTYPE_MONITOR
:
971 return default_timeout
;
974 return mvm
->trans
->trans_cfg
->base_params
->wd_timeout
;
978 void iwl_mvm_connection_loss(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
981 struct iwl_fw_dbg_trigger_tlv
*trig
;
982 struct iwl_fw_dbg_trigger_mlme
*trig_mlme
;
984 trig
= iwl_fw_dbg_trigger_on(&mvm
->fwrt
, ieee80211_vif_to_wdev(vif
),
985 FW_DBG_TRIGGER_MLME
);
989 trig_mlme
= (void *)trig
->data
;
991 if (trig_mlme
->stop_connection_loss
&&
992 --trig_mlme
->stop_connection_loss
)
995 iwl_fw_dbg_collect_trig(&mvm
->fwrt
, trig
, "%s", errmsg
);
998 ieee80211_connection_loss(vif
);
1001 void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm
*mvm
,
1002 struct ieee80211_vif
*vif
,
1003 const struct ieee80211_sta
*sta
,
1006 struct iwl_fw_dbg_trigger_tlv
*trig
;
1007 struct iwl_fw_dbg_trigger_ba
*ba_trig
;
1009 trig
= iwl_fw_dbg_trigger_on(&mvm
->fwrt
, ieee80211_vif_to_wdev(vif
),
1014 ba_trig
= (void *)trig
->data
;
1016 if (!(le16_to_cpu(ba_trig
->frame_timeout
) & BIT(tid
)))
1019 iwl_fw_dbg_collect_trig(&mvm
->fwrt
, trig
,
1020 "Frame from %pM timed out, tid %d",
1024 u8
iwl_mvm_tcm_load_percentage(u32 airtime
, u32 elapsed
)
1029 return (100 * airtime
/ elapsed
) / USEC_PER_MSEC
;
1032 static enum iwl_mvm_traffic_load
1033 iwl_mvm_tcm_load(struct iwl_mvm
*mvm
, u32 airtime
, unsigned long elapsed
)
1035 u8 load
= iwl_mvm_tcm_load_percentage(airtime
, elapsed
);
1037 if (load
> IWL_MVM_TCM_LOAD_HIGH_THRESH
)
1038 return IWL_MVM_TRAFFIC_HIGH
;
1039 if (load
> IWL_MVM_TCM_LOAD_MEDIUM_THRESH
)
1040 return IWL_MVM_TRAFFIC_MEDIUM
;
1042 return IWL_MVM_TRAFFIC_LOW
;
1045 static void iwl_mvm_tcm_iter(void *_data
, u8
*mac
, struct ieee80211_vif
*vif
)
1047 struct iwl_mvm
*mvm
= _data
;
1048 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1049 bool low_latency
, prev
= mvmvif
->low_latency
& LOW_LATENCY_TRAFFIC
;
1051 if (mvmvif
->id
>= NUM_MAC_INDEX_DRIVER
)
1054 low_latency
= mvm
->tcm
.result
.low_latency
[mvmvif
->id
];
1056 if (!mvm
->tcm
.result
.change
[mvmvif
->id
] &&
1057 prev
== low_latency
) {
1058 iwl_mvm_update_quotas(mvm
, false, NULL
);
1062 if (prev
!= low_latency
) {
1063 /* this sends traffic load and updates quota as well */
1064 iwl_mvm_update_low_latency(mvm
, vif
, low_latency
,
1065 LOW_LATENCY_TRAFFIC
);
1067 iwl_mvm_update_quotas(mvm
, false, NULL
);
1071 static void iwl_mvm_tcm_results(struct iwl_mvm
*mvm
)
1073 mutex_lock(&mvm
->mutex
);
1075 ieee80211_iterate_active_interfaces(
1076 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
1077 iwl_mvm_tcm_iter
, mvm
);
1079 if (fw_has_capa(&mvm
->fw
->ucode_capa
, IWL_UCODE_TLV_CAPA_UMAC_SCAN
))
1080 iwl_mvm_config_scan(mvm
);
1082 mutex_unlock(&mvm
->mutex
);
1085 static void iwl_mvm_tcm_uapsd_nonagg_detected_wk(struct work_struct
*wk
)
1087 struct iwl_mvm
*mvm
;
1088 struct iwl_mvm_vif
*mvmvif
;
1089 struct ieee80211_vif
*vif
;
1091 mvmvif
= container_of(wk
, struct iwl_mvm_vif
,
1092 uapsd_nonagg_detected_wk
.work
);
1093 vif
= container_of((void *)mvmvif
, struct ieee80211_vif
, drv_priv
);
1096 if (mvm
->tcm
.data
[mvmvif
->id
].opened_rx_ba_sessions
)
1099 /* remember that this AP is broken */
1100 memcpy(mvm
->uapsd_noagg_bssids
[mvm
->uapsd_noagg_bssid_write_idx
].addr
,
1101 vif
->bss_conf
.bssid
, ETH_ALEN
);
1102 mvm
->uapsd_noagg_bssid_write_idx
++;
1103 if (mvm
->uapsd_noagg_bssid_write_idx
>= IWL_MVM_UAPSD_NOAGG_LIST_LEN
)
1104 mvm
->uapsd_noagg_bssid_write_idx
= 0;
1106 iwl_mvm_connection_loss(mvm
, vif
,
1107 "AP isn't using AMPDU with uAPSD enabled");
1110 static void iwl_mvm_uapsd_agg_disconnect(struct iwl_mvm
*mvm
,
1111 struct ieee80211_vif
*vif
)
1113 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1115 if (vif
->type
!= NL80211_IFTYPE_STATION
)
1118 if (!vif
->bss_conf
.assoc
)
1121 if (!mvmvif
->queue_params
[IEEE80211_AC_VO
].uapsd
&&
1122 !mvmvif
->queue_params
[IEEE80211_AC_VI
].uapsd
&&
1123 !mvmvif
->queue_params
[IEEE80211_AC_BE
].uapsd
&&
1124 !mvmvif
->queue_params
[IEEE80211_AC_BK
].uapsd
)
1127 if (mvm
->tcm
.data
[mvmvif
->id
].uapsd_nonagg_detect
.detected
)
1130 mvm
->tcm
.data
[mvmvif
->id
].uapsd_nonagg_detect
.detected
= true;
1132 "detected AP should do aggregation but isn't, likely due to U-APSD\n");
1133 schedule_delayed_work(&mvmvif
->uapsd_nonagg_detected_wk
, 15 * HZ
);
1136 static void iwl_mvm_check_uapsd_agg_expected_tpt(struct iwl_mvm
*mvm
,
1137 unsigned int elapsed
,
1140 u64 bytes
= mvm
->tcm
.data
[mac
].uapsd_nonagg_detect
.rx_bytes
;
1143 struct ieee80211_vif
*vif
;
1145 rate
= ewma_rate_read(&mvm
->tcm
.data
[mac
].uapsd_nonagg_detect
.rate
);
1147 if (!rate
|| mvm
->tcm
.data
[mac
].opened_rx_ba_sessions
||
1148 mvm
->tcm
.data
[mac
].uapsd_nonagg_detect
.detected
)
1151 if (iwl_mvm_has_new_rx_api(mvm
)) {
1152 tpt
= 8 * bytes
; /* kbps */
1153 do_div(tpt
, elapsed
);
1154 rate
*= 1000; /* kbps */
1155 if (tpt
< 22 * rate
/ 100)
1159 * the rate here is actually the threshold, in 100Kbps units,
1160 * so do the needed conversion from bytes to 100Kbps:
1161 * 100kb = bits / (100 * 1000),
1162 * 100kbps = 100kb / (msecs / 1000) ==
1163 * (bits / (100 * 1000)) / (msecs / 1000) ==
1164 * bits / (100 * msecs)
1167 do_div(tpt
, elapsed
* 100);
1173 vif
= rcu_dereference(mvm
->vif_id_to_mac
[mac
]);
1175 iwl_mvm_uapsd_agg_disconnect(mvm
, vif
);
1179 static void iwl_mvm_tcm_iterator(void *_data
, u8
*mac
,
1180 struct ieee80211_vif
*vif
)
1182 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1185 if (!mvmvif
->phy_ctxt
)
1188 band
[mvmvif
->id
] = mvmvif
->phy_ctxt
->channel
->band
;
1191 static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm
*mvm
,
1195 unsigned int elapsed
= jiffies_to_msecs(ts
- mvm
->tcm
.ts
);
1196 unsigned int uapsd_elapsed
=
1197 jiffies_to_msecs(ts
- mvm
->tcm
.uapsd_nonagg_ts
);
1198 u32 total_airtime
= 0;
1199 u32 band_airtime
[NUM_NL80211_BANDS
] = {0};
1200 u32 band
[NUM_MAC_INDEX_DRIVER
] = {0};
1202 bool low_latency
= false;
1203 enum iwl_mvm_traffic_load load
, band_load
;
1204 bool handle_ll
= time_after(ts
, mvm
->tcm
.ll_ts
+ MVM_LL_PERIOD
);
1207 mvm
->tcm
.ll_ts
= ts
;
1209 mvm
->tcm
.uapsd_nonagg_ts
= ts
;
1211 mvm
->tcm
.result
.elapsed
= elapsed
;
1213 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
1214 IEEE80211_IFACE_ITER_NORMAL
,
1215 iwl_mvm_tcm_iterator
,
1218 for (mac
= 0; mac
< NUM_MAC_INDEX_DRIVER
; mac
++) {
1219 struct iwl_mvm_tcm_mac
*mdata
= &mvm
->tcm
.data
[mac
];
1221 u32 airtime
= mdata
->rx
.airtime
+ mdata
->tx
.airtime
;
1223 total_airtime
+= airtime
;
1224 band_airtime
[band
[mac
]] += airtime
;
1226 load
= iwl_mvm_tcm_load(mvm
, airtime
, elapsed
);
1227 mvm
->tcm
.result
.change
[mac
] = load
!= mvm
->tcm
.result
.load
[mac
];
1228 mvm
->tcm
.result
.load
[mac
] = load
;
1229 mvm
->tcm
.result
.airtime
[mac
] = airtime
;
1231 for (ac
= IEEE80211_AC_VO
; ac
<= IEEE80211_AC_VI
; ac
++)
1232 vo_vi_pkts
+= mdata
->rx
.pkts
[ac
] +
1235 /* enable immediately with enough packets but defer disabling */
1236 if (vo_vi_pkts
> IWL_MVM_TCM_LOWLAT_ENABLE_THRESH
)
1237 mvm
->tcm
.result
.low_latency
[mac
] = true;
1239 mvm
->tcm
.result
.low_latency
[mac
] = false;
1242 /* clear old data */
1243 memset(&mdata
->rx
.pkts
, 0, sizeof(mdata
->rx
.pkts
));
1244 memset(&mdata
->tx
.pkts
, 0, sizeof(mdata
->tx
.pkts
));
1246 low_latency
|= mvm
->tcm
.result
.low_latency
[mac
];
1248 if (!mvm
->tcm
.result
.low_latency
[mac
] && handle_uapsd
)
1249 iwl_mvm_check_uapsd_agg_expected_tpt(mvm
, uapsd_elapsed
,
1251 /* clear old data */
1253 mdata
->uapsd_nonagg_detect
.rx_bytes
= 0;
1254 memset(&mdata
->rx
.airtime
, 0, sizeof(mdata
->rx
.airtime
));
1255 memset(&mdata
->tx
.airtime
, 0, sizeof(mdata
->tx
.airtime
));
1258 load
= iwl_mvm_tcm_load(mvm
, total_airtime
, elapsed
);
1259 mvm
->tcm
.result
.global_load
= load
;
1261 for (i
= 0; i
< NUM_NL80211_BANDS
; i
++) {
1262 band_load
= iwl_mvm_tcm_load(mvm
, band_airtime
[i
], elapsed
);
1263 mvm
->tcm
.result
.band_load
[i
] = band_load
;
1267 * If the current load isn't low we need to force re-evaluation
1268 * in the TCM period, so that we can return to low load if there
1269 * was no traffic at all (and thus iwl_mvm_recalc_tcm didn't get
1270 * triggered by traffic).
1272 if (load
!= IWL_MVM_TRAFFIC_LOW
)
1273 return MVM_TCM_PERIOD
;
1275 * If low-latency is active we need to force re-evaluation after
1276 * (the longer) MVM_LL_PERIOD, so that we can disable low-latency
1277 * when there's no traffic at all.
1280 return MVM_LL_PERIOD
;
1282 * Otherwise, we don't need to run the work struct because we're
1283 * in the default "idle" state - traffic indication is low (which
1284 * also covers the "no traffic" case) and low-latency is disabled
1285 * so there's no state that may need to be disabled when there's
1286 * no traffic at all.
1288 * Note that this has no impact on the regular scheduling of the
1289 * updates triggered by traffic - those happen whenever one of the
1290 * two timeouts expire (if there's traffic at all.)
1295 void iwl_mvm_recalc_tcm(struct iwl_mvm
*mvm
)
1297 unsigned long ts
= jiffies
;
1299 time_after(ts
, mvm
->tcm
.uapsd_nonagg_ts
+
1300 msecs_to_jiffies(IWL_MVM_UAPSD_NONAGG_PERIOD
));
1302 spin_lock(&mvm
->tcm
.lock
);
1303 if (mvm
->tcm
.paused
|| !time_after(ts
, mvm
->tcm
.ts
+ MVM_TCM_PERIOD
)) {
1304 spin_unlock(&mvm
->tcm
.lock
);
1307 spin_unlock(&mvm
->tcm
.lock
);
1309 if (handle_uapsd
&& iwl_mvm_has_new_rx_api(mvm
)) {
1310 mutex_lock(&mvm
->mutex
);
1311 if (iwl_mvm_request_statistics(mvm
, true))
1312 handle_uapsd
= false;
1313 mutex_unlock(&mvm
->mutex
);
1316 spin_lock(&mvm
->tcm
.lock
);
1317 /* re-check if somebody else won the recheck race */
1318 if (!mvm
->tcm
.paused
&& time_after(ts
, mvm
->tcm
.ts
+ MVM_TCM_PERIOD
)) {
1319 /* calculate statistics */
1320 unsigned long work_delay
= iwl_mvm_calc_tcm_stats(mvm
, ts
,
1323 /* the memset needs to be visible before the timestamp */
1327 schedule_delayed_work(&mvm
->tcm
.work
, work_delay
);
1329 spin_unlock(&mvm
->tcm
.lock
);
1331 iwl_mvm_tcm_results(mvm
);
1334 void iwl_mvm_tcm_work(struct work_struct
*work
)
1336 struct delayed_work
*delayed_work
= to_delayed_work(work
);
1337 struct iwl_mvm
*mvm
= container_of(delayed_work
, struct iwl_mvm
,
1340 iwl_mvm_recalc_tcm(mvm
);
1343 void iwl_mvm_pause_tcm(struct iwl_mvm
*mvm
, bool with_cancel
)
1345 spin_lock_bh(&mvm
->tcm
.lock
);
1346 mvm
->tcm
.paused
= true;
1347 spin_unlock_bh(&mvm
->tcm
.lock
);
1349 cancel_delayed_work_sync(&mvm
->tcm
.work
);
1352 void iwl_mvm_resume_tcm(struct iwl_mvm
*mvm
)
1355 bool low_latency
= false;
1357 spin_lock_bh(&mvm
->tcm
.lock
);
1358 mvm
->tcm
.ts
= jiffies
;
1359 mvm
->tcm
.ll_ts
= jiffies
;
1360 for (mac
= 0; mac
< NUM_MAC_INDEX_DRIVER
; mac
++) {
1361 struct iwl_mvm_tcm_mac
*mdata
= &mvm
->tcm
.data
[mac
];
1363 memset(&mdata
->rx
.pkts
, 0, sizeof(mdata
->rx
.pkts
));
1364 memset(&mdata
->tx
.pkts
, 0, sizeof(mdata
->tx
.pkts
));
1365 memset(&mdata
->rx
.airtime
, 0, sizeof(mdata
->rx
.airtime
));
1366 memset(&mdata
->tx
.airtime
, 0, sizeof(mdata
->tx
.airtime
));
1368 if (mvm
->tcm
.result
.low_latency
[mac
])
1371 /* The TCM data needs to be reset before "paused" flag changes */
1373 mvm
->tcm
.paused
= false;
1376 * if the current load is not low or low latency is active, force
1377 * re-evaluation to cover the case of no traffic.
1379 if (mvm
->tcm
.result
.global_load
> IWL_MVM_TRAFFIC_LOW
)
1380 schedule_delayed_work(&mvm
->tcm
.work
, MVM_TCM_PERIOD
);
1381 else if (low_latency
)
1382 schedule_delayed_work(&mvm
->tcm
.work
, MVM_LL_PERIOD
);
1384 spin_unlock_bh(&mvm
->tcm
.lock
);
1387 void iwl_mvm_tcm_add_vif(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
1389 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1391 INIT_DELAYED_WORK(&mvmvif
->uapsd_nonagg_detected_wk
,
1392 iwl_mvm_tcm_uapsd_nonagg_detected_wk
);
1395 void iwl_mvm_tcm_rm_vif(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
1397 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1399 cancel_delayed_work_sync(&mvmvif
->uapsd_nonagg_detected_wk
);
1402 u32
iwl_mvm_get_systime(struct iwl_mvm
*mvm
)
1404 u32 reg_addr
= DEVICE_SYSTEM_TIME_REG
;
1406 if (mvm
->trans
->trans_cfg
->device_family
>= IWL_DEVICE_FAMILY_22000
&&
1407 mvm
->trans
->cfg
->gp2_reg_addr
)
1408 reg_addr
= mvm
->trans
->cfg
->gp2_reg_addr
;
1410 return iwl_read_prph(mvm
->trans
, reg_addr
);
1413 void iwl_mvm_get_sync_time(struct iwl_mvm
*mvm
, int clock_type
,
1414 u32
*gp2
, u64
*boottime
, ktime_t
*realtime
)
1418 lockdep_assert_held(&mvm
->mutex
);
1420 /* Disable power save when reading GP2 */
1421 ps_disabled
= mvm
->ps_disabled
;
1423 mvm
->ps_disabled
= true;
1424 iwl_mvm_power_update_device(mvm
);
1427 *gp2
= iwl_mvm_get_systime(mvm
);
1429 if (clock_type
== CLOCK_BOOTTIME
&& boottime
)
1430 *boottime
= ktime_get_boottime_ns();
1431 else if (clock_type
== CLOCK_REALTIME
&& realtime
)
1432 *realtime
= ktime_get_real();
1435 mvm
->ps_disabled
= ps_disabled
;
1436 iwl_mvm_power_update_device(mvm
);