Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'iwlwifi-next-for-kalle-2015-01-22' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

* more work for new devices (4165 / 8260)
* cleanups / improvemnts in rate control
* fixes for TDLS
* major statistics work from Johannes - more to come
* improvements for the fw error dump infrastructure
* usual amount of small fixes here and there (scan, D0i3 etc...)

+1232 -616
+3 -3
drivers/net/wireless/iwlwifi/iwl-7000.c
··· 69 69 #include "iwl-agn-hw.h" 70 70 71 71 /* Highest firmware API version supported */ 72 - #define IWL7260_UCODE_API_MAX 10 73 - #define IWL3160_UCODE_API_MAX 10 72 + #define IWL7260_UCODE_API_MAX 12 73 + #define IWL3160_UCODE_API_MAX 12 74 74 75 75 /* Oldest version we won't warn about */ 76 76 #define IWL7260_UCODE_API_OK 10 ··· 111 111 #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" 112 112 113 113 #define IWL7265D_FW_PRE "iwlwifi-7265D-" 114 - #define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" 114 + #define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode" 115 115 116 116 #define NVM_HW_SECTION_NUM_FAMILY_7000 0 117 117
+15 -1
drivers/net/wireless/iwlwifi/iwl-8000.c
··· 69 69 #include "iwl-agn-hw.h" 70 70 71 71 /* Highest firmware API version supported */ 72 - #define IWL8000_UCODE_API_MAX 10 72 + #define IWL8000_UCODE_API_MAX 12 73 73 74 74 /* Oldest version we won't warn about */ 75 75 #define IWL8000_UCODE_API_OK 10 ··· 84 84 /* Memory offsets and lengths */ 85 85 #define IWL8260_DCCM_OFFSET 0x800000 86 86 #define IWL8260_DCCM_LEN 0x18000 87 + #define IWL8260_DCCM2_OFFSET 0x880000 88 + #define IWL8260_DCCM2_LEN 0x8000 87 89 #define IWL8260_SMEM_OFFSET 0x400000 88 90 #define IWL8260_SMEM_LEN 0x68000 89 91 ··· 136 134 .non_shared_ant = ANT_A, \ 137 135 .dccm_offset = IWL8260_DCCM_OFFSET, \ 138 136 .dccm_len = IWL8260_DCCM_LEN, \ 137 + .dccm2_offset = IWL8260_DCCM2_OFFSET, \ 138 + .dccm2_len = IWL8260_DCCM2_LEN, \ 139 139 .smem_offset = IWL8260_SMEM_OFFSET, \ 140 140 .smem_len = IWL8260_SMEM_LEN 141 141 ··· 152 148 153 149 const struct iwl_cfg iwl8260_2ac_cfg = { 154 150 .name = "Intel(R) Dual Band Wireless AC 8260", 151 + .fw_name_pre = IWL8000_FW_PRE, 152 + IWL_DEVICE_8000, 153 + .ht_params = &iwl8000_ht_params, 154 + .nvm_ver = IWL8000_NVM_VERSION, 155 + .nvm_calib_ver = IWL8000_TX_POWER_VERSION, 156 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, 157 + }; 158 + 159 + const struct iwl_cfg iwl4165_2ac_cfg = { 160 + .name = "Intel(R) Dual Band Wireless AC 4165", 155 161 .fw_name_pre = IWL8000_FW_PRE, 156 162 IWL_DEVICE_8000, 157 163 .ht_params = &iwl8000_ht_params,
+5
drivers/net/wireless/iwlwifi/iwl-config.h
··· 263 263 * station can receive in VHT 264 264 * @dccm_offset: offset from which DCCM begins 265 265 * @dccm_len: length of DCCM (including runtime stack CCM) 266 + * @dccm2_offset: offset from which the second DCCM begins 267 + * @dccm2_len: length of the second DCCM 266 268 * @smem_offset: offset from which the SMEM begins 267 269 * @smem_len: the length of SMEM 268 270 * ··· 312 310 unsigned int max_vht_ampdu_exponent; 313 311 const u32 dccm_offset; 314 312 const u32 dccm_len; 313 + const u32 dccm2_offset; 314 + const u32 dccm2_len; 315 315 const u32 smem_offset; 316 316 const u32 smem_len; 317 317 }; ··· 382 378 extern const struct iwl_cfg iwl7265d_n_cfg; 383 379 extern const struct iwl_cfg iwl8260_2n_cfg; 384 380 extern const struct iwl_cfg iwl8260_2ac_cfg; 381 + extern const struct iwl_cfg iwl4165_2ac_cfg; 385 382 extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; 386 383 extern const struct iwl_cfg iwl4165_2ac_sdio_cfg; 387 384 #endif /* CONFIG_IWLMVM */
+1
drivers/net/wireless/iwlwifi/iwl-csr.h
··· 307 307 enum { 308 308 SILICON_A_STEP = 0, 309 309 SILICON_B_STEP, 310 + SILICON_C_STEP, 310 311 }; 311 312 312 313
+1 -1
drivers/net/wireless/iwlwifi/iwl-drv.c
··· 1490 1490 MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)"); 1491 1491 1492 1492 module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, 1493 - bool, S_IRUGO); 1493 + bool, S_IRUGO | S_IWUSR); 1494 1494 #ifdef CONFIG_IWLWIFI_UAPSD 1495 1495 MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); 1496 1496 #else
+21
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
··· 134 134 u8 data[]; 135 135 } __packed; 136 136 137 + /** 138 + * struct iwl_fw_error_dump_fifo - RX/TX FIFO data 139 + * @fifo_num: number of FIFO (starting from 0) 140 + * @available_bytes: num of bytes available in FIFO (may be less than FIFO size) 141 + * @wr_ptr: position of write pointer 142 + * @rd_ptr: position of read pointer 143 + * @fence_ptr: position of fence pointer 144 + * @fence_mode: the current mode of the fence (before locking) - 145 + * 0=follow RD pointer ; 1 = freeze 146 + * @data: all of the FIFO's data 147 + */ 148 + struct iwl_fw_error_dump_fifo { 149 + __le32 fifo_num; 150 + __le32 available_bytes; 151 + __le32 wr_ptr; 152 + __le32 rd_ptr; 153 + __le32 fence_ptr; 154 + __le32 fence_mode; 155 + u8 data[]; 156 + } __packed; 157 + 137 158 enum iwl_fw_error_dump_family { 138 159 IWL_FW_ERROR_DUMP_FAMILY_7 = 7, 139 160 IWL_FW_ERROR_DUMP_FAMILY_8 = 8,
+15 -6
drivers/net/wireless/iwlwifi/iwl-fw-file.h
··· 235 235 236 236 /** 237 237 * enum iwl_ucode_tlv_api - ucode api 238 - * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field. 239 - * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification 240 238 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex 241 - * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. 242 239 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. 243 240 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. 244 241 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. 245 242 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time 246 243 * longer than the passive one, which is essential for fragmented scan. 244 + * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR 245 + * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, 246 + * regardless of the band or the number of the probes. FW will calculate 247 + * the actual dwell time. 248 + * @IWL_UCODE_TLV_API_SCD_CFG: This firmware can configure the scheduler 249 + * through the dedicated host command. 250 + * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. 251 + * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported. 252 + * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params 247 253 */ 248 254 enum iwl_ucode_tlv_api { 249 - IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), 250 - IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1), 251 255 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 252 - IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), 253 256 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 254 257 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), 255 258 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), 256 259 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), 260 + IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), 261 + IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), 262 + IWL_UCODE_TLV_API_SCD_CFG = BIT(15), 263 + IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), 264 + IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17), 265 + IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18), 257 266 }; 258 267 259 268 /**
+7 -3
drivers/net/wireless/iwlwifi/iwl-io.c
··· 193 193 * DEVICE_SET_NMI_8000B_REG - is used. 194 194 */ 195 195 if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || 196 - (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) 197 - iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL); 198 - else 196 + (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) { 197 + iwl_write_prph(trans, DEVICE_SET_NMI_REG, 198 + DEVICE_SET_NMI_VAL_DRV); 199 + iwl_write_prph(trans, DEVICE_SET_NMI_REG, 200 + DEVICE_SET_NMI_VAL_HW); 201 + } else { 199 202 iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, 200 203 DEVICE_SET_NMI_8000B_VAL); 204 + } 201 205 } 202 206 IWL_EXPORT_SYMBOL(iwl_force_nmi); 203 207
+20 -1
drivers/net/wireless/iwlwifi/iwl-prph.h
··· 108 108 109 109 /* Device NMI register */ 110 110 #define DEVICE_SET_NMI_REG 0x00a01c30 111 - #define DEVICE_SET_NMI_VAL 0x1 111 + #define DEVICE_SET_NMI_VAL_HW BIT(0) 112 + #define DEVICE_SET_NMI_VAL_DRV BIT(7) 112 113 #define DEVICE_SET_NMI_8000B_REG 0x00a01c24 113 114 #define DEVICE_SET_NMI_8000B_VAL 0x1000000 114 115 ··· 360 359 361 360 /* Rx FIFO */ 362 361 #define RXF_SIZE_ADDR (0xa00c88) 362 + #define RXF_RD_D_SPACE (0xa00c40) 363 + #define RXF_RD_WR_PTR (0xa00c50) 364 + #define RXF_RD_RD_PTR (0xa00c54) 365 + #define RXF_RD_FENCE_PTR (0xa00c4c) 366 + #define RXF_SET_FENCE_MODE (0xa00c14) 367 + #define RXF_LD_WR2FENCE (0xa00c1c) 368 + #define RXF_FIFO_RD_FENCE_INC (0xa00c68) 363 369 #define RXF_SIZE_BYTE_CND_POS (7) 364 370 #define RXF_SIZE_BYTE_CNT_MSK (0x3ff << RXF_SIZE_BYTE_CND_POS) 371 + #define RXF_DIFF_FROM_PREV (0x200) 365 372 366 373 #define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10) 367 374 #define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c) 375 + 376 + /* Tx FIFO */ 377 + #define TXF_FIFO_ITEM_CNT (0xa00438) 378 + #define TXF_WR_PTR (0xa00414) 379 + #define TXF_RD_PTR (0xa00410) 380 + #define TXF_FENCE_PTR (0xa00418) 381 + #define TXF_LOCK_FENCE (0xa00424) 382 + #define TXF_LARC_NUM (0xa0043c) 383 + #define TXF_READ_MODIFY_DATA (0xa00448) 384 + #define TXF_READ_MODIFY_ADDR (0xa0044c) 368 385 369 386 /* FW monitor */ 370 387 #define MON_BUFF_SAMPLE_CTL (0xa03c00)
+8 -8
drivers/net/wireless/iwlwifi/mvm/coex.c
··· 342 342 { 343 343 .range = 12, 344 344 .lut20 = { 345 - cpu_to_le32(0x00000001), cpu_to_le32(0x00000000), 345 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 346 346 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 347 347 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 348 348 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 363 363 { 364 364 .range = 20, 365 365 .lut20 = { 366 - cpu_to_le32(0x00000002), cpu_to_le32(0x00000000), 366 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 367 367 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 368 368 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 369 369 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 384 384 { 385 385 .range = 21, 386 386 .lut20 = { 387 - cpu_to_le32(0x00000003), cpu_to_le32(0x00000000), 387 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 388 388 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 389 389 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 390 390 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 405 405 { 406 406 .range = 23, 407 407 .lut20 = { 408 - cpu_to_le32(0x00000004), cpu_to_le32(0x00000000), 408 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 409 409 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 410 410 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 411 411 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 426 426 { 427 427 .range = 27, 428 428 .lut20 = { 429 - cpu_to_le32(0x00000005), cpu_to_le32(0x00000000), 429 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 430 430 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 431 431 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 432 432 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 447 447 { 448 448 .range = 30, 449 449 .lut20 = { 450 - cpu_to_le32(0x00000006), cpu_to_le32(0x00000000), 450 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 451 451 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 452 452 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 453 453 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 468 468 { 469 469 .range = 32, 470 470 .lut20 = { 471 - cpu_to_le32(0x00000007), cpu_to_le32(0x00000000), 471 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 472 472 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 473 473 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 474 474 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 489 489 { 490 490 .range = 33, 491 491 .lut20 = { 492 - cpu_to_le32(0x00000008), cpu_to_le32(0x00000000), 492 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 493 493 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 494 494 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 495 495 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+8 -8
drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
··· 330 330 { 331 331 .range = 12, 332 332 .lut20 = { 333 - cpu_to_le32(0x00000001), cpu_to_le32(0x00000000), 333 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 334 334 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 335 335 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 336 336 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 351 351 { 352 352 .range = 20, 353 353 .lut20 = { 354 - cpu_to_le32(0x00000002), cpu_to_le32(0x00000000), 354 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 355 355 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 356 356 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 357 357 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 372 372 { 373 373 .range = 21, 374 374 .lut20 = { 375 - cpu_to_le32(0x00000003), cpu_to_le32(0x00000000), 375 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 376 376 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 377 377 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 378 378 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 393 393 { 394 394 .range = 23, 395 395 .lut20 = { 396 - cpu_to_le32(0x00000004), cpu_to_le32(0x00000000), 396 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 397 397 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 398 398 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 399 399 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 414 414 { 415 415 .range = 27, 416 416 .lut20 = { 417 - cpu_to_le32(0x00000005), cpu_to_le32(0x00000000), 417 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 418 418 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 419 419 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 420 420 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 435 435 { 436 436 .range = 30, 437 437 .lut20 = { 438 - cpu_to_le32(0x00000006), cpu_to_le32(0x00000000), 438 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 439 439 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 440 440 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 441 441 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 456 456 { 457 457 .range = 32, 458 458 .lut20 = { 459 - cpu_to_le32(0x00000007), cpu_to_le32(0x00000000), 459 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 460 460 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 461 461 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 462 462 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), ··· 477 477 { 478 478 .range = 33, 479 479 .lut20 = { 480 - cpu_to_le32(0x00000008), cpu_to_le32(0x00000000), 480 + cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 481 481 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 482 482 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 483 483 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+5 -4
drivers/net/wireless/iwlwifi/mvm/constants.h
··· 94 94 #define IWL_MVM_BT_COEX_MPLUT 1 95 95 #define IWL_MVM_BT_COEX_RRC 1 96 96 #define IWL_MVM_BT_COEX_TTC 1 97 - #define IWL_MVM_BT_COEX_MPLUT_REG0 0x28412201 97 + #define IWL_MVM_BT_COEX_MPLUT_REG0 0x22002200 98 98 #define IWL_MVM_BT_COEX_MPLUT_REG1 0x11118451 99 99 #define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 100 100 #define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 101 101 #define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 102 102 #define IWL_MVM_QUOTA_THRESHOLD 8 103 103 #define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 104 - #define IWL_MVM_RS_DISABLE_MIMO 0 104 + #define IWL_MVM_RS_DISABLE_P2P_MIMO 0 105 105 #define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 106 - #define IWL_MVM_RS_LEGACY_RETRIES_PER_RATE 1 107 106 #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 108 107 #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 109 108 #define IWL_MVM_RS_INITIAL_MIMO_NUM_RATES 3 110 109 #define IWL_MVM_RS_INITIAL_SISO_NUM_RATES 3 111 - #define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES 16 110 + #define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES 2 111 + #define IWL_MVM_RS_INITIAL_LEGACY_RETRIES 2 112 + #define IWL_MVM_RS_SECONDARY_LEGACY_RETRIES 1 112 113 #define IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES 16 113 114 #define IWL_MVM_RS_SECONDARY_SISO_NUM_RATES 3 114 115 #define IWL_MVM_RS_SECONDARY_SISO_RETRIES 1
+31
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
··· 517 517 return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf)); 518 518 } 519 519 520 + static ssize_t iwl_dbgfs_uapsd_misbehaving_read(struct file *file, 521 + char __user *user_buf, 522 + size_t count, loff_t *ppos) 523 + { 524 + struct ieee80211_vif *vif = file->private_data; 525 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 526 + char buf[20]; 527 + int len; 528 + 529 + len = sprintf(buf, "%pM\n", mvmvif->uapsd_misbehaving_bssid); 530 + return simple_read_from_buffer(user_buf, count, ppos, buf, len); 531 + } 532 + 533 + static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif, 534 + char *buf, size_t count, 535 + loff_t *ppos) 536 + { 537 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 538 + struct iwl_mvm *mvm = mvmvif->mvm; 539 + bool ret; 540 + 541 + mutex_lock(&mvm->mutex); 542 + ret = mac_pton(buf, mvmvif->uapsd_misbehaving_bssid); 543 + mutex_unlock(&mvm->mutex); 544 + 545 + return ret ? count : -EINVAL; 546 + } 547 + 520 548 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ 521 549 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif) 522 550 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ ··· 559 531 MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32); 560 532 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256); 561 533 MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10); 534 + MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20); 562 535 563 536 void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 564 537 { ··· 592 563 593 564 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, S_IRUSR); 594 565 MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir, 566 + S_IRUSR | S_IWUSR); 567 + MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir, 595 568 S_IRUSR | S_IWUSR); 596 569 597 570 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
+108 -87
drivers/net/wireless/iwlwifi/mvm/debugfs.c
··· 654 654 return ret ?: count; 655 655 } 656 656 657 - #define PRINT_STATS_LE32(_str, _val) \ 657 + #define PRINT_STATS_LE32(_struct, _memb) \ 658 658 pos += scnprintf(buf + pos, bufsz - pos, \ 659 - fmt_table, _str, \ 660 - le32_to_cpu(_val)) 659 + fmt_table, #_memb, \ 660 + le32_to_cpu(_struct->_memb)) 661 661 662 662 static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, 663 663 char __user *user_buf, size_t count, ··· 692 692 693 693 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 694 694 "Statistics_Rx - OFDM"); 695 - PRINT_STATS_LE32("ina_cnt", ofdm->ina_cnt); 696 - PRINT_STATS_LE32("fina_cnt", ofdm->fina_cnt); 697 - PRINT_STATS_LE32("plcp_err", ofdm->plcp_err); 698 - PRINT_STATS_LE32("crc32_err", ofdm->crc32_err); 699 - PRINT_STATS_LE32("overrun_err", ofdm->overrun_err); 700 - PRINT_STATS_LE32("early_overrun_err", ofdm->early_overrun_err); 701 - PRINT_STATS_LE32("crc32_good", ofdm->crc32_good); 702 - PRINT_STATS_LE32("false_alarm_cnt", ofdm->false_alarm_cnt); 703 - PRINT_STATS_LE32("fina_sync_err_cnt", ofdm->fina_sync_err_cnt); 704 - PRINT_STATS_LE32("sfd_timeout", ofdm->sfd_timeout); 705 - PRINT_STATS_LE32("fina_timeout", ofdm->fina_timeout); 706 - PRINT_STATS_LE32("unresponded_rts", ofdm->unresponded_rts); 707 - PRINT_STATS_LE32("rxe_frame_lmt_overrun", 708 - ofdm->rxe_frame_limit_overrun); 709 - PRINT_STATS_LE32("sent_ack_cnt", ofdm->sent_ack_cnt); 710 - PRINT_STATS_LE32("sent_cts_cnt", ofdm->sent_cts_cnt); 711 - PRINT_STATS_LE32("sent_ba_rsp_cnt", ofdm->sent_ba_rsp_cnt); 712 - PRINT_STATS_LE32("dsp_self_kill", ofdm->dsp_self_kill); 713 - PRINT_STATS_LE32("mh_format_err", ofdm->mh_format_err); 714 - PRINT_STATS_LE32("re_acq_main_rssi_sum", ofdm->re_acq_main_rssi_sum); 715 - PRINT_STATS_LE32("reserved", ofdm->reserved); 695 + PRINT_STATS_LE32(ofdm, ina_cnt); 696 + PRINT_STATS_LE32(ofdm, fina_cnt); 697 + PRINT_STATS_LE32(ofdm, plcp_err); 698 + PRINT_STATS_LE32(ofdm, crc32_err); 699 + PRINT_STATS_LE32(ofdm, overrun_err); 700 + PRINT_STATS_LE32(ofdm, early_overrun_err); 701 + PRINT_STATS_LE32(ofdm, crc32_good); 702 + PRINT_STATS_LE32(ofdm, false_alarm_cnt); 703 + PRINT_STATS_LE32(ofdm, fina_sync_err_cnt); 704 + PRINT_STATS_LE32(ofdm, sfd_timeout); 705 + PRINT_STATS_LE32(ofdm, fina_timeout); 706 + PRINT_STATS_LE32(ofdm, unresponded_rts); 707 + PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); 708 + PRINT_STATS_LE32(ofdm, sent_ack_cnt); 709 + PRINT_STATS_LE32(ofdm, sent_cts_cnt); 710 + PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); 711 + PRINT_STATS_LE32(ofdm, dsp_self_kill); 712 + PRINT_STATS_LE32(ofdm, mh_format_err); 713 + PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum); 714 + PRINT_STATS_LE32(ofdm, reserved); 716 715 717 716 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 718 717 "Statistics_Rx - CCK"); 719 - PRINT_STATS_LE32("ina_cnt", cck->ina_cnt); 720 - PRINT_STATS_LE32("fina_cnt", cck->fina_cnt); 721 - PRINT_STATS_LE32("plcp_err", cck->plcp_err); 722 - PRINT_STATS_LE32("crc32_err", cck->crc32_err); 723 - PRINT_STATS_LE32("overrun_err", cck->overrun_err); 724 - PRINT_STATS_LE32("early_overrun_err", cck->early_overrun_err); 725 - PRINT_STATS_LE32("crc32_good", cck->crc32_good); 726 - PRINT_STATS_LE32("false_alarm_cnt", cck->false_alarm_cnt); 727 - PRINT_STATS_LE32("fina_sync_err_cnt", cck->fina_sync_err_cnt); 728 - PRINT_STATS_LE32("sfd_timeout", cck->sfd_timeout); 729 - PRINT_STATS_LE32("fina_timeout", cck->fina_timeout); 730 - PRINT_STATS_LE32("unresponded_rts", cck->unresponded_rts); 731 - PRINT_STATS_LE32("rxe_frame_lmt_overrun", 732 - cck->rxe_frame_limit_overrun); 733 - PRINT_STATS_LE32("sent_ack_cnt", cck->sent_ack_cnt); 734 - PRINT_STATS_LE32("sent_cts_cnt", cck->sent_cts_cnt); 735 - PRINT_STATS_LE32("sent_ba_rsp_cnt", cck->sent_ba_rsp_cnt); 736 - PRINT_STATS_LE32("dsp_self_kill", cck->dsp_self_kill); 737 - PRINT_STATS_LE32("mh_format_err", cck->mh_format_err); 738 - PRINT_STATS_LE32("re_acq_main_rssi_sum", cck->re_acq_main_rssi_sum); 739 - PRINT_STATS_LE32("reserved", cck->reserved); 718 + PRINT_STATS_LE32(cck, ina_cnt); 719 + PRINT_STATS_LE32(cck, fina_cnt); 720 + PRINT_STATS_LE32(cck, plcp_err); 721 + PRINT_STATS_LE32(cck, crc32_err); 722 + PRINT_STATS_LE32(cck, overrun_err); 723 + PRINT_STATS_LE32(cck, early_overrun_err); 724 + PRINT_STATS_LE32(cck, crc32_good); 725 + PRINT_STATS_LE32(cck, false_alarm_cnt); 726 + PRINT_STATS_LE32(cck, fina_sync_err_cnt); 727 + PRINT_STATS_LE32(cck, sfd_timeout); 728 + PRINT_STATS_LE32(cck, fina_timeout); 729 + PRINT_STATS_LE32(cck, unresponded_rts); 730 + PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); 731 + PRINT_STATS_LE32(cck, sent_ack_cnt); 732 + PRINT_STATS_LE32(cck, sent_cts_cnt); 733 + PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); 734 + PRINT_STATS_LE32(cck, dsp_self_kill); 735 + PRINT_STATS_LE32(cck, mh_format_err); 736 + PRINT_STATS_LE32(cck, re_acq_main_rssi_sum); 737 + PRINT_STATS_LE32(cck, reserved); 740 738 741 739 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 742 740 "Statistics_Rx - GENERAL"); 743 - PRINT_STATS_LE32("bogus_cts", general->bogus_cts); 744 - PRINT_STATS_LE32("bogus_ack", general->bogus_ack); 745 - PRINT_STATS_LE32("non_bssid_frames", general->non_bssid_frames); 746 - PRINT_STATS_LE32("filtered_frames", general->filtered_frames); 747 - PRINT_STATS_LE32("non_channel_beacons", general->non_channel_beacons); 748 - PRINT_STATS_LE32("channel_beacons", general->channel_beacons); 749 - PRINT_STATS_LE32("num_missed_bcon", general->num_missed_bcon); 750 - PRINT_STATS_LE32("adc_rx_saturation_time", 751 - general->adc_rx_saturation_time); 752 - PRINT_STATS_LE32("ina_detection_search_time", 753 - general->ina_detection_search_time); 754 - PRINT_STATS_LE32("beacon_silence_rssi_a", 755 - general->beacon_silence_rssi_a); 756 - PRINT_STATS_LE32("beacon_silence_rssi_b", 757 - general->beacon_silence_rssi_b); 758 - PRINT_STATS_LE32("beacon_silence_rssi_c", 759 - general->beacon_silence_rssi_c); 760 - PRINT_STATS_LE32("interference_data_flag", 761 - general->interference_data_flag); 762 - PRINT_STATS_LE32("channel_load", general->channel_load); 763 - PRINT_STATS_LE32("dsp_false_alarms", general->dsp_false_alarms); 764 - PRINT_STATS_LE32("beacon_rssi_a", general->beacon_rssi_a); 765 - PRINT_STATS_LE32("beacon_rssi_b", general->beacon_rssi_b); 766 - PRINT_STATS_LE32("beacon_rssi_c", general->beacon_rssi_c); 767 - PRINT_STATS_LE32("beacon_energy_a", general->beacon_energy_a); 768 - PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b); 769 - PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c); 770 - PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills); 771 - PRINT_STATS_LE32("mac_id", general->mac_id); 772 - PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu); 741 + PRINT_STATS_LE32(general, bogus_cts); 742 + PRINT_STATS_LE32(general, bogus_ack); 743 + PRINT_STATS_LE32(general, non_bssid_frames); 744 + PRINT_STATS_LE32(general, filtered_frames); 745 + PRINT_STATS_LE32(general, non_channel_beacons); 746 + PRINT_STATS_LE32(general, channel_beacons); 747 + PRINT_STATS_LE32(general, num_missed_bcon); 748 + PRINT_STATS_LE32(general, adc_rx_saturation_time); 749 + PRINT_STATS_LE32(general, ina_detection_search_time); 750 + PRINT_STATS_LE32(general, beacon_silence_rssi_a); 751 + PRINT_STATS_LE32(general, beacon_silence_rssi_b); 752 + PRINT_STATS_LE32(general, beacon_silence_rssi_c); 753 + PRINT_STATS_LE32(general, interference_data_flag); 754 + PRINT_STATS_LE32(general, channel_load); 755 + PRINT_STATS_LE32(general, dsp_false_alarms); 756 + PRINT_STATS_LE32(general, beacon_rssi_a); 757 + PRINT_STATS_LE32(general, beacon_rssi_b); 758 + PRINT_STATS_LE32(general, beacon_rssi_c); 759 + PRINT_STATS_LE32(general, beacon_energy_a); 760 + PRINT_STATS_LE32(general, beacon_energy_b); 761 + PRINT_STATS_LE32(general, beacon_energy_c); 762 + PRINT_STATS_LE32(general, num_bt_kills); 763 + PRINT_STATS_LE32(general, mac_id); 764 + PRINT_STATS_LE32(general, directed_data_mpdu); 773 765 774 766 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 775 767 "Statistics_Rx - HT"); 776 - PRINT_STATS_LE32("plcp_err", ht->plcp_err); 777 - PRINT_STATS_LE32("overrun_err", ht->overrun_err); 778 - PRINT_STATS_LE32("early_overrun_err", ht->early_overrun_err); 779 - PRINT_STATS_LE32("crc32_good", ht->crc32_good); 780 - PRINT_STATS_LE32("crc32_err", ht->crc32_err); 781 - PRINT_STATS_LE32("mh_format_err", ht->mh_format_err); 782 - PRINT_STATS_LE32("agg_crc32_good", ht->agg_crc32_good); 783 - PRINT_STATS_LE32("agg_mpdu_cnt", ht->agg_mpdu_cnt); 784 - PRINT_STATS_LE32("agg_cnt", ht->agg_cnt); 785 - PRINT_STATS_LE32("unsupport_mcs", ht->unsupport_mcs); 768 + PRINT_STATS_LE32(ht, plcp_err); 769 + PRINT_STATS_LE32(ht, overrun_err); 770 + PRINT_STATS_LE32(ht, early_overrun_err); 771 + PRINT_STATS_LE32(ht, crc32_good); 772 + PRINT_STATS_LE32(ht, crc32_err); 773 + PRINT_STATS_LE32(ht, mh_format_err); 774 + PRINT_STATS_LE32(ht, agg_crc32_good); 775 + PRINT_STATS_LE32(ht, agg_mpdu_cnt); 776 + PRINT_STATS_LE32(ht, agg_cnt); 777 + PRINT_STATS_LE32(ht, unsupport_mcs); 786 778 787 779 mutex_unlock(&mvm->mutex); 788 780 ··· 980 988 char *buf, size_t count, 981 989 loff_t *ppos) 982 990 { 983 - mutex_lock(&mvm->mutex); 991 + int ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE); 992 + 993 + if (ret) 994 + return ret; 995 + 984 996 iwl_mvm_fw_dbg_collect(mvm); 985 - mutex_unlock(&mvm->mutex); 997 + 998 + iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE); 986 999 987 1000 return count; 988 1001 } ··· 1387 1390 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD); 1388 1391 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK); 1389 1392 PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA); 1393 + PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT); 1390 1394 1391 1395 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1392 1396 } ··· 1487 1489 return count; 1488 1490 } 1489 1491 1492 + static ssize_t iwl_dbgfs_enable_scan_iteration_notif_write(struct iwl_mvm *mvm, 1493 + char *buf, 1494 + size_t count, 1495 + loff_t *ppos) 1496 + { 1497 + int val; 1498 + 1499 + mutex_lock(&mvm->mutex); 1500 + 1501 + if (kstrtoint(buf, 10, &val)) { 1502 + mutex_unlock(&mvm->mutex); 1503 + return -EINVAL; 1504 + } 1505 + 1506 + mvm->scan_iter_notif_enabled = val; 1507 + mutex_unlock(&mvm->mutex); 1508 + 1509 + return count; 1510 + } 1511 + 1490 1512 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); 1491 1513 1492 1514 /* Device wide debugfs entries */ ··· 1529 1511 MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); 1530 1512 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); 1531 1513 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8); 1514 + MVM_DEBUGFS_WRITE_FILE_OPS(enable_scan_iteration_notif, 8); 1532 1515 1533 1516 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1534 1517 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); ··· 1573 1554 MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 1574 1555 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 1575 1556 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR); 1557 + MVM_DEBUGFS_ADD_FILE(enable_scan_iteration_notif, mvm->debugfs_dir, 1558 + S_IWUSR); 1576 1559 1577 1560 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1578 1561 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
+19 -1
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
··· 92 92 }; 93 93 94 94 /** 95 + * struct iwl_ltr_config_cmd_v1 - configures the LTR 96 + * @flags: See %enum iwl_ltr_config_flags 97 + */ 98 + struct iwl_ltr_config_cmd_v1 { 99 + __le32 flags; 100 + __le32 static_long; 101 + __le32 static_short; 102 + } __packed; /* LTR_CAPABLE_API_S_VER_1 */ 103 + 104 + #define LTR_VALID_STATES_NUM 4 105 + 106 + /** 95 107 * struct iwl_ltr_config_cmd - configures the LTR 96 108 * @flags: See %enum iwl_ltr_config_flags 109 + * @static_long: 110 + * @static_short: 111 + * @ltr_cfg_values: 112 + * @ltr_short_idle_timeout: 97 113 */ 98 114 struct iwl_ltr_config_cmd { 99 115 __le32 flags; 100 116 __le32 static_long; 101 117 __le32 static_short; 102 - } __packed; 118 + __le32 ltr_cfg_values[LTR_VALID_STATES_NUM]; 119 + __le32 ltr_short_idle_timeout; 120 + } __packed; /* LTR_CAPABLE_API_S_VER_2 */ 103 121 104 122 /* Radio LP RX Energy Threshold measured in dBm */ 105 123 #define POWER_LPRX_RSSI_THRESHOLD 75
+13 -2
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
··· 308 308 #define LQ_FLAG_DYNAMIC_BW_POS 6 309 309 #define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS) 310 310 311 + /* Single Stream Parameters 312 + * SS_STBC/BFER_ALLOWED - Controls whether STBC or Beamformer (BFER) is allowed 313 + * ucode will make a smart decision between SISO/STBC/BFER 314 + * SS_PARAMS_VALID - if not set ignore the ss_params field. 315 + */ 316 + enum { 317 + RS_SS_STBC_ALLOWED = BIT(0), 318 + RS_SS_BFER_ALLOWED = BIT(1), 319 + RS_SS_PARAMS_VALID = BIT(31), 320 + }; 321 + 311 322 /** 312 323 * struct iwl_lq_cmd - link quality command 313 324 * @sta_id: station to update ··· 341 330 * 2 - 0x3f: maximal number of frames (up to 3f == 63) 342 331 * @rs_table: array of rates for each TX try, each is rate_n_flags, 343 332 * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP 344 - * @bf_params: beam forming params, currently not used 333 + * @ss_params: single stream features. declare whether STBC or BFER are allowed. 345 334 */ 346 335 struct iwl_lq_cmd { 347 336 u8 sta_id; ··· 359 348 u8 agg_frame_cnt_limit; 360 349 __le32 reserved2; 361 350 __le32 rs_table[LQ_MAX_RETRY_NUM]; 362 - __le32 bf_params; 351 + __le32 ss_params; 363 352 }; /* LINK_QUALITY_CMD_API_S_VER_1 */ 364 353 #endif /* __fw_api_rs_h__ */
+2
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
··· 675 675 * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented 676 676 * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report 677 677 * and DS parameter set IEs into probe requests. 678 + * @IWL_MVM_LMAC_SCAN_FLAG_MATCH: Send match found notification on matches 678 679 */ 679 680 enum iwl_mvm_lmac_scan_flags { 680 681 IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0), ··· 685 684 IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4), 686 685 IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5), 687 686 IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6), 687 + IWL_MVM_LMAC_SCAN_FLAG_MATCH = BIT(9), 688 688 }; 689 689 690 690 enum iwl_scan_priority {
+277
drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
··· 1 + /****************************************************************************** 2 + * 3 + * This file is provided under a dual BSD/GPLv2 license. When using or 4 + * redistributing this file, you may do so under either license. 5 + * 6 + * GPL LICENSE SUMMARY 7 + * 8 + * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of version 2 of the GNU General Public License as 13 + * published by the Free Software Foundation. 14 + * 15 + * This program is distributed in the hope that it will be useful, but 16 + * WITHOUT ANY WARRANTY; without even the implied warranty of 17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 + * General Public License for more details. 19 + * 20 + * You should have received a copy of the GNU General Public License 21 + * along with this program; if not, write to the Free Software 22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 23 + * USA 24 + * 25 + * The full GNU General Public License is included in this distribution 26 + * in the file called COPYING. 27 + * 28 + * Contact Information: 29 + * Intel Linux Wireless <ilw@linux.intel.com> 30 + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 31 + * 32 + * BSD LICENSE 33 + * 34 + * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 35 + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 36 + * All rights reserved. 37 + * 38 + * Redistribution and use in source and binary forms, with or without 39 + * modification, are permitted provided that the following conditions 40 + * are met: 41 + * 42 + * * Redistributions of source code must retain the above copyright 43 + * notice, this list of conditions and the following disclaimer. 44 + * * Redistributions in binary form must reproduce the above copyright 45 + * notice, this list of conditions and the following disclaimer in 46 + * the documentation and/or other materials provided with the 47 + * distribution. 48 + * * Neither the name Intel Corporation nor the names of its 49 + * contributors may be used to endorse or promote products derived 50 + * from this software without specific prior written permission. 51 + * 52 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 53 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 54 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 55 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 56 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 57 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 58 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 59 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 60 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 61 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 62 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63 + * 64 + *****************************************************************************/ 65 + 66 + #ifndef __fw_api_stats_h__ 67 + #define __fw_api_stats_h__ 68 + 69 + struct mvm_statistics_dbg { 70 + __le32 burst_check; 71 + __le32 burst_count; 72 + __le32 wait_for_silence_timeout_cnt; 73 + __le32 reserved[3]; 74 + } __packed; /* STATISTICS_DEBUG_API_S_VER_2 */ 75 + 76 + struct mvm_statistics_div { 77 + __le32 tx_on_a; 78 + __le32 tx_on_b; 79 + __le32 exec_time; 80 + __le32 probe_time; 81 + __le32 rssi_ant; 82 + __le32 reserved2; 83 + } __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */ 84 + 85 + struct mvm_statistics_rx_non_phy { 86 + __le32 bogus_cts; /* CTS received when not expecting CTS */ 87 + __le32 bogus_ack; /* ACK received when not expecting ACK */ 88 + __le32 non_bssid_frames; /* number of frames with BSSID that 89 + * doesn't belong to the STA BSSID */ 90 + __le32 filtered_frames; /* count frames that were dumped in the 91 + * filtering process */ 92 + __le32 non_channel_beacons; /* beacons with our bss id but not on 93 + * our serving channel */ 94 + __le32 channel_beacons; /* beacons with our bss id and in our 95 + * serving channel */ 96 + __le32 num_missed_bcon; /* number of missed beacons */ 97 + __le32 adc_rx_saturation_time; /* count in 0.8us units the time the 98 + * ADC was in saturation */ 99 + __le32 ina_detection_search_time;/* total time (in 0.8us) searched 100 + * for INA */ 101 + __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */ 102 + __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */ 103 + __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */ 104 + __le32 interference_data_flag; /* flag for interference data 105 + * availability. 1 when data is 106 + * available. */ 107 + __le32 channel_load; /* counts RX Enable time in uSec */ 108 + __le32 dsp_false_alarms; /* DSP false alarm (both OFDM 109 + * and CCK) counter */ 110 + __le32 beacon_rssi_a; 111 + __le32 beacon_rssi_b; 112 + __le32 beacon_rssi_c; 113 + __le32 beacon_energy_a; 114 + __le32 beacon_energy_b; 115 + __le32 beacon_energy_c; 116 + __le32 num_bt_kills; 117 + __le32 mac_id; 118 + __le32 directed_data_mpdu; 119 + } __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */ 120 + 121 + struct mvm_statistics_rx_phy { 122 + __le32 ina_cnt; 123 + __le32 fina_cnt; 124 + __le32 plcp_err; 125 + __le32 crc32_err; 126 + __le32 overrun_err; 127 + __le32 early_overrun_err; 128 + __le32 crc32_good; 129 + __le32 false_alarm_cnt; 130 + __le32 fina_sync_err_cnt; 131 + __le32 sfd_timeout; 132 + __le32 fina_timeout; 133 + __le32 unresponded_rts; 134 + __le32 rxe_frame_lmt_overrun; 135 + __le32 sent_ack_cnt; 136 + __le32 sent_cts_cnt; 137 + __le32 sent_ba_rsp_cnt; 138 + __le32 dsp_self_kill; 139 + __le32 mh_format_err; 140 + __le32 re_acq_main_rssi_sum; 141 + __le32 reserved; 142 + } __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */ 143 + 144 + struct mvm_statistics_rx_ht_phy { 145 + __le32 plcp_err; 146 + __le32 overrun_err; 147 + __le32 early_overrun_err; 148 + __le32 crc32_good; 149 + __le32 crc32_err; 150 + __le32 mh_format_err; 151 + __le32 agg_crc32_good; 152 + __le32 agg_mpdu_cnt; 153 + __le32 agg_cnt; 154 + __le32 unsupport_mcs; 155 + } __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */ 156 + 157 + struct mvm_statistics_tx_non_phy { 158 + __le32 preamble_cnt; 159 + __le32 rx_detected_cnt; 160 + __le32 bt_prio_defer_cnt; 161 + __le32 bt_prio_kill_cnt; 162 + __le32 few_bytes_cnt; 163 + __le32 cts_timeout; 164 + __le32 ack_timeout; 165 + __le32 expected_ack_cnt; 166 + __le32 actual_ack_cnt; 167 + __le32 dump_msdu_cnt; 168 + __le32 burst_abort_next_frame_mismatch_cnt; 169 + __le32 burst_abort_missing_next_frame_cnt; 170 + __le32 cts_timeout_collision; 171 + __le32 ack_or_ba_timeout_collision; 172 + } __packed; /* STATISTICS_TX_NON_PHY_API_S_VER_3 */ 173 + 174 + #define MAX_CHAINS 3 175 + 176 + struct mvm_statistics_tx_non_phy_agg { 177 + __le32 ba_timeout; 178 + __le32 ba_reschedule_frames; 179 + __le32 scd_query_agg_frame_cnt; 180 + __le32 scd_query_no_agg; 181 + __le32 scd_query_agg; 182 + __le32 scd_query_mismatch; 183 + __le32 frame_not_ready; 184 + __le32 underrun; 185 + __le32 bt_prio_kill; 186 + __le32 rx_ba_rsp_cnt; 187 + __s8 txpower[MAX_CHAINS]; 188 + __s8 reserved; 189 + __le32 reserved2; 190 + } __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */ 191 + 192 + struct mvm_statistics_tx_channel_width { 193 + __le32 ext_cca_narrow_ch20[1]; 194 + __le32 ext_cca_narrow_ch40[2]; 195 + __le32 ext_cca_narrow_ch80[3]; 196 + __le32 ext_cca_narrow_ch160[4]; 197 + __le32 last_tx_ch_width_indx; 198 + __le32 rx_detected_per_ch_width[4]; 199 + __le32 success_per_ch_width[4]; 200 + __le32 fail_per_ch_width[4]; 201 + }; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */ 202 + 203 + struct mvm_statistics_tx { 204 + struct mvm_statistics_tx_non_phy general; 205 + struct mvm_statistics_tx_non_phy_agg agg; 206 + struct mvm_statistics_tx_channel_width channel_width; 207 + } __packed; /* STATISTICS_TX_API_S_VER_4 */ 208 + 209 + 210 + struct mvm_statistics_bt_activity { 211 + __le32 hi_priority_tx_req_cnt; 212 + __le32 hi_priority_tx_denied_cnt; 213 + __le32 lo_priority_tx_req_cnt; 214 + __le32 lo_priority_tx_denied_cnt; 215 + __le32 hi_priority_rx_req_cnt; 216 + __le32 hi_priority_rx_denied_cnt; 217 + __le32 lo_priority_rx_req_cnt; 218 + __le32 lo_priority_rx_denied_cnt; 219 + } __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */ 220 + 221 + struct mvm_statistics_general { 222 + __le32 radio_temperature; 223 + __le32 radio_voltage; 224 + struct mvm_statistics_dbg dbg; 225 + __le32 sleep_time; 226 + __le32 slots_out; 227 + __le32 slots_idle; 228 + __le32 ttl_timestamp; 229 + struct mvm_statistics_div slow_div; 230 + __le32 rx_enable_counter; 231 + /* 232 + * num_of_sos_states: 233 + * count the number of times we have to re-tune 234 + * in order to get out of bad PHY status 235 + */ 236 + __le32 num_of_sos_states; 237 + __le32 beacon_filtered; 238 + __le32 missed_beacons; 239 + __s8 beacon_filter_average_energy; 240 + __s8 beacon_filter_reason; 241 + __s8 beacon_filter_current_energy; 242 + __s8 beacon_filter_reserved; 243 + __le32 beacon_filter_delta_time; 244 + struct mvm_statistics_bt_activity bt_activity; 245 + } __packed; /* STATISTICS_GENERAL_API_S_VER_5 */ 246 + 247 + struct mvm_statistics_rx { 248 + struct mvm_statistics_rx_phy ofdm; 249 + struct mvm_statistics_rx_phy cck; 250 + struct mvm_statistics_rx_non_phy general; 251 + struct mvm_statistics_rx_ht_phy ofdm_ht; 252 + } __packed; /* STATISTICS_RX_API_S_VER_3 */ 253 + 254 + /* 255 + * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) 256 + * 257 + * By default, uCode issues this notification after receiving a beacon 258 + * while associated. To disable this behavior, set DISABLE_NOTIF flag in the 259 + * REPLY_STATISTICS_CMD 0x9c, above. 260 + * 261 + * Statistics counters continue to increment beacon after beacon, but are 262 + * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD 263 + * 0x9c with CLEAR_STATS bit set (see above). 264 + * 265 + * uCode also issues this notification during scans. uCode clears statistics 266 + * appropriately so that each notification contains statistics for only the 267 + * one channel that has just been scanned. 268 + */ 269 + 270 + struct iwl_notif_statistics { 271 + __le32 flag; 272 + struct mvm_statistics_rx rx; 273 + struct mvm_statistics_tx tx; 274 + struct mvm_statistics_general general; 275 + } __packed; /* STATISTICS_NTFY_API_S_VER_8 */ 276 + 277 + #endif /* __fw_api_stats_h__ */
+39
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
··· 592 592 tx_resp->frame_count) & 0xfff; 593 593 } 594 594 595 + /** 596 + * struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command 597 + * @token: 598 + * @sta_id: station id 599 + * @tid: 600 + * @scd_queue: scheduler queue to confiug 601 + * @enable: 1 queue enable, 0 queue disable 602 + * @aggregate: 1 aggregated queue, 0 otherwise 603 + * @tx_fifo: %enum iwl_mvm_tx_fifo 604 + * @window: BA window size 605 + * @ssn: SSN for the BA agreement 606 + */ 607 + struct iwl_scd_txq_cfg_cmd { 608 + u8 token; 609 + u8 sta_id; 610 + u8 tid; 611 + u8 scd_queue; 612 + u8 enable; 613 + u8 aggregate; 614 + u8 tx_fifo; 615 + u8 window; 616 + __le16 ssn; 617 + __le16 reserved; 618 + } __packed; /* SCD_QUEUE_CFG_CMD_API_S_VER_1 */ 619 + 620 + /** 621 + * struct iwl_scd_txq_cfg_rsp 622 + * @token: taken from the command 623 + * @sta_id: station id from the command 624 + * @tid: tid from the command 625 + * @scd_queue: scd_queue from the command 626 + */ 627 + struct iwl_scd_txq_cfg_rsp { 628 + u8 token; 629 + u8 sta_id; 630 + u8 tid; 631 + u8 scd_queue; 632 + } __packed; /* SCD_QUEUE_CFG_RSP_API_S_VER_1 */ 633 + 595 634 #endif /* __fw_api_tx_h__ */
+36 -265
drivers/net/wireless/iwlwifi/mvm/fw-api.h
··· 74 74 #include "fw-api-d3.h" 75 75 #include "fw-api-coex.h" 76 76 #include "fw-api-scan.h" 77 + #include "fw-api-stats.h" 77 78 78 79 /* Tx queue numbers */ 79 80 enum { ··· 128 127 129 128 /* global key */ 130 129 WEP_KEY = 0x20, 130 + 131 + /* Memory */ 132 + SHARED_MEM_CFG = 0x25, 131 133 132 134 /* TDLS */ 133 135 TDLS_CHANNEL_SWITCH_CMD = 0x27, ··· 1385 1381 __le32 metadata[0]; 1386 1382 } __packed; /* MARKER_API_S_VER_1 */ 1387 1383 1388 - struct mvm_statistics_dbg { 1389 - __le32 burst_check; 1390 - __le32 burst_count; 1391 - __le32 wait_for_silence_timeout_cnt; 1392 - __le32 reserved[3]; 1393 - } __packed; /* STATISTICS_DEBUG_API_S_VER_2 */ 1394 - 1395 - struct mvm_statistics_div { 1396 - __le32 tx_on_a; 1397 - __le32 tx_on_b; 1398 - __le32 exec_time; 1399 - __le32 probe_time; 1400 - __le32 rssi_ant; 1401 - __le32 reserved2; 1402 - } __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */ 1403 - 1404 - struct mvm_statistics_general_common { 1405 - __le32 temperature; /* radio temperature */ 1406 - __le32 temperature_m; /* radio voltage */ 1407 - struct mvm_statistics_dbg dbg; 1408 - __le32 sleep_time; 1409 - __le32 slots_out; 1410 - __le32 slots_idle; 1411 - __le32 ttl_timestamp; 1412 - struct mvm_statistics_div div; 1413 - __le32 rx_enable_counter; 1414 - /* 1415 - * num_of_sos_states: 1416 - * count the number of times we have to re-tune 1417 - * in order to get out of bad PHY status 1418 - */ 1419 - __le32 num_of_sos_states; 1420 - } __packed; /* STATISTICS_GENERAL_API_S_VER_5 */ 1421 - 1422 - struct mvm_statistics_rx_non_phy { 1423 - __le32 bogus_cts; /* CTS received when not expecting CTS */ 1424 - __le32 bogus_ack; /* ACK received when not expecting ACK */ 1425 - __le32 non_bssid_frames; /* number of frames with BSSID that 1426 - * doesn't belong to the STA BSSID */ 1427 - __le32 filtered_frames; /* count frames that were dumped in the 1428 - * filtering process */ 1429 - __le32 non_channel_beacons; /* beacons with our bss id but not on 1430 - * our serving channel */ 1431 - __le32 channel_beacons; /* beacons with our bss id and in our 1432 - * serving channel */ 1433 - __le32 num_missed_bcon; /* number of missed beacons */ 1434 - __le32 adc_rx_saturation_time; /* count in 0.8us units the time the 1435 - * ADC was in saturation */ 1436 - __le32 ina_detection_search_time;/* total time (in 0.8us) searched 1437 - * for INA */ 1438 - __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */ 1439 - __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */ 1440 - __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */ 1441 - __le32 interference_data_flag; /* flag for interference data 1442 - * availability. 1 when data is 1443 - * available. */ 1444 - __le32 channel_load; /* counts RX Enable time in uSec */ 1445 - __le32 dsp_false_alarms; /* DSP false alarm (both OFDM 1446 - * and CCK) counter */ 1447 - __le32 beacon_rssi_a; 1448 - __le32 beacon_rssi_b; 1449 - __le32 beacon_rssi_c; 1450 - __le32 beacon_energy_a; 1451 - __le32 beacon_energy_b; 1452 - __le32 beacon_energy_c; 1453 - __le32 num_bt_kills; 1454 - __le32 mac_id; 1455 - __le32 directed_data_mpdu; 1456 - } __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */ 1457 - 1458 - struct mvm_statistics_rx_phy { 1459 - __le32 ina_cnt; 1460 - __le32 fina_cnt; 1461 - __le32 plcp_err; 1462 - __le32 crc32_err; 1463 - __le32 overrun_err; 1464 - __le32 early_overrun_err; 1465 - __le32 crc32_good; 1466 - __le32 false_alarm_cnt; 1467 - __le32 fina_sync_err_cnt; 1468 - __le32 sfd_timeout; 1469 - __le32 fina_timeout; 1470 - __le32 unresponded_rts; 1471 - __le32 rxe_frame_limit_overrun; 1472 - __le32 sent_ack_cnt; 1473 - __le32 sent_cts_cnt; 1474 - __le32 sent_ba_rsp_cnt; 1475 - __le32 dsp_self_kill; 1476 - __le32 mh_format_err; 1477 - __le32 re_acq_main_rssi_sum; 1478 - __le32 reserved; 1479 - } __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */ 1480 - 1481 - struct mvm_statistics_rx_ht_phy { 1482 - __le32 plcp_err; 1483 - __le32 overrun_err; 1484 - __le32 early_overrun_err; 1485 - __le32 crc32_good; 1486 - __le32 crc32_err; 1487 - __le32 mh_format_err; 1488 - __le32 agg_crc32_good; 1489 - __le32 agg_mpdu_cnt; 1490 - __le32 agg_cnt; 1491 - __le32 unsupport_mcs; 1492 - } __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */ 1493 - 1494 - #define MAX_CHAINS 3 1495 - 1496 - struct mvm_statistics_tx_non_phy_agg { 1497 - __le32 ba_timeout; 1498 - __le32 ba_reschedule_frames; 1499 - __le32 scd_query_agg_frame_cnt; 1500 - __le32 scd_query_no_agg; 1501 - __le32 scd_query_agg; 1502 - __le32 scd_query_mismatch; 1503 - __le32 frame_not_ready; 1504 - __le32 underrun; 1505 - __le32 bt_prio_kill; 1506 - __le32 rx_ba_rsp_cnt; 1507 - __s8 txpower[MAX_CHAINS]; 1508 - __s8 reserved; 1509 - __le32 reserved2; 1510 - } __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */ 1511 - 1512 - struct mvm_statistics_tx_channel_width { 1513 - __le32 ext_cca_narrow_ch20[1]; 1514 - __le32 ext_cca_narrow_ch40[2]; 1515 - __le32 ext_cca_narrow_ch80[3]; 1516 - __le32 ext_cca_narrow_ch160[4]; 1517 - __le32 last_tx_ch_width_indx; 1518 - __le32 rx_detected_per_ch_width[4]; 1519 - __le32 success_per_ch_width[4]; 1520 - __le32 fail_per_ch_width[4]; 1521 - }; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */ 1522 - 1523 - struct mvm_statistics_tx { 1524 - __le32 preamble_cnt; 1525 - __le32 rx_detected_cnt; 1526 - __le32 bt_prio_defer_cnt; 1527 - __le32 bt_prio_kill_cnt; 1528 - __le32 few_bytes_cnt; 1529 - __le32 cts_timeout; 1530 - __le32 ack_timeout; 1531 - __le32 expected_ack_cnt; 1532 - __le32 actual_ack_cnt; 1533 - __le32 dump_msdu_cnt; 1534 - __le32 burst_abort_next_frame_mismatch_cnt; 1535 - __le32 burst_abort_missing_next_frame_cnt; 1536 - __le32 cts_timeout_collision; 1537 - __le32 ack_or_ba_timeout_collision; 1538 - struct mvm_statistics_tx_non_phy_agg agg; 1539 - struct mvm_statistics_tx_channel_width channel_width; 1540 - } __packed; /* STATISTICS_TX_API_S_VER_4 */ 1541 - 1542 - 1543 - struct mvm_statistics_bt_activity { 1544 - __le32 hi_priority_tx_req_cnt; 1545 - __le32 hi_priority_tx_denied_cnt; 1546 - __le32 lo_priority_tx_req_cnt; 1547 - __le32 lo_priority_tx_denied_cnt; 1548 - __le32 hi_priority_rx_req_cnt; 1549 - __le32 hi_priority_rx_denied_cnt; 1550 - __le32 lo_priority_rx_req_cnt; 1551 - __le32 lo_priority_rx_denied_cnt; 1552 - } __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */ 1553 - 1554 - struct mvm_statistics_general { 1555 - struct mvm_statistics_general_common common; 1556 - __le32 beacon_filtered; 1557 - __le32 missed_beacons; 1558 - __s8 beacon_filter_average_energy; 1559 - __s8 beacon_filter_reason; 1560 - __s8 beacon_filter_current_energy; 1561 - __s8 beacon_filter_reserved; 1562 - __le32 beacon_filter_delta_time; 1563 - struct mvm_statistics_bt_activity bt_activity; 1564 - } __packed; /* STATISTICS_GENERAL_API_S_VER_5 */ 1565 - 1566 - struct mvm_statistics_rx { 1567 - struct mvm_statistics_rx_phy ofdm; 1568 - struct mvm_statistics_rx_phy cck; 1569 - struct mvm_statistics_rx_non_phy general; 1570 - struct mvm_statistics_rx_ht_phy ofdm_ht; 1571 - } __packed; /* STATISTICS_RX_API_S_VER_3 */ 1572 - 1573 - /* 1574 - * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) 1575 - * 1576 - * By default, uCode issues this notification after receiving a beacon 1577 - * while associated. To disable this behavior, set DISABLE_NOTIF flag in the 1578 - * REPLY_STATISTICS_CMD 0x9c, above. 1579 - * 1580 - * Statistics counters continue to increment beacon after beacon, but are 1581 - * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD 1582 - * 0x9c with CLEAR_STATS bit set (see above). 1583 - * 1584 - * uCode also issues this notification during scans. uCode clears statistics 1585 - * appropriately so that each notification contains statistics for only the 1586 - * one channel that has just been scanned. 1587 - */ 1588 - 1589 - struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */ 1590 - __le32 flag; 1591 - struct mvm_statistics_rx rx; 1592 - struct mvm_statistics_tx tx; 1593 - struct mvm_statistics_general general; 1594 - } __packed; 1595 - 1596 1384 /*********************************** 1597 1385 * Smart Fifo API 1598 1386 ***********************************/ ··· 1475 1679 __le32 temp; 1476 1680 __le32 voltage; 1477 1681 } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */ 1478 - 1479 - /** 1480 - * enum iwl_scd_control - scheduler config command control flags 1481 - * @IWL_SCD_CONTROL_RM_TID: remove TID from this queue 1482 - * @IWL_SCD_CONTROL_SET_SSN: use the SSN and program it into HW 1483 - */ 1484 - enum iwl_scd_control { 1485 - IWL_SCD_CONTROL_RM_TID = BIT(4), 1486 - IWL_SCD_CONTROL_SET_SSN = BIT(5), 1487 - }; 1488 - 1489 - /** 1490 - * enum iwl_scd_flags - scheduler config command flags 1491 - * @IWL_SCD_FLAGS_SHARE_TID: multiple TIDs map to this queue 1492 - * @IWL_SCD_FLAGS_SHARE_RA: multiple RAs map to this queue 1493 - * @IWL_SCD_FLAGS_DQA_ENABLED: DQA is enabled 1494 - */ 1495 - enum iwl_scd_flags { 1496 - IWL_SCD_FLAGS_SHARE_TID = BIT(0), 1497 - IWL_SCD_FLAGS_SHARE_RA = BIT(1), 1498 - IWL_SCD_FLAGS_DQA_ENABLED = BIT(2), 1499 - }; 1500 - 1501 - #define IWL_SCDQ_INVALID_STA 0xff 1502 - 1503 - /** 1504 - * struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command 1505 - * @token: dialog token addba - unused legacy 1506 - * @sta_id: station id 4-bit 1507 - * @tid: TID 0..7 1508 - * @scd_queue: TFD queue num 0 .. 31 1509 - * @enable: 1 queue enable, 0 queue disable 1510 - * @aggregate: 1 aggregated queue, 0 otherwise 1511 - * @tx_fifo: tx fifo num 0..7 1512 - * @window: up to 64 1513 - * @ssn: starting seq num 12-bit 1514 - * @control: command control flags 1515 - * @flags: flags - see &enum iwl_scd_flags 1516 - * 1517 - * Note that every time the command is sent, all parameters must 1518 - * be filled with the exception of 1519 - * - the SSN, which is only used with @IWL_SCD_CONTROL_SET_SSN 1520 - * - the window, which is only relevant when starting aggregation 1521 - */ 1522 - struct iwl_scd_txq_cfg_cmd { 1523 - u8 token; 1524 - u8 sta_id; 1525 - u8 tid; 1526 - u8 scd_queue; 1527 - u8 enable; 1528 - u8 aggregate; 1529 - u8 tx_fifo; 1530 - u8 window; 1531 - __le16 ssn; 1532 - u8 control; 1533 - u8 flags; 1534 - } __packed; 1535 1682 1536 1683 /*********************************** 1537 1684 * TDLS API ··· 1616 1877 __le32 tx_to_ap_last_seq; 1617 1878 struct iwl_tdls_config_sta_info_res sta_info[IWL_MVM_TDLS_STA_COUNT]; 1618 1879 } __packed; /* TDLS_CONFIG_RSP_API_S_VER_1 */ 1880 + 1881 + #define TX_FIFO_MAX_NUM 8 1882 + #define RX_FIFO_MAX_NUM 2 1883 + 1884 + /** 1885 + * Shared memory configuration information from the FW 1886 + * 1887 + * @shared_mem_addr: shared memory addr (pre 8000 HW set to 0x0 as MARBH is not 1888 + * accessible) 1889 + * @shared_mem_size: shared memory size 1890 + * @sample_buff_addr: internal sample (mon/adc) buff addr (pre 8000 HW set to 1891 + * 0x0 as accessible only via DBGM RDAT) 1892 + * @sample_buff_size: internal sample buff size 1893 + * @txfifo_addr: start addr of TXF0 (excluding the context table 0.5KB), (pre 1894 + * 8000 HW set to 0x0 as not accessible) 1895 + * @txfifo_size: size of TXF0 ... TXF7 1896 + * @rxfifo_size: RXF1, RXF2 sizes. If there is no RXF2, it'll have a value of 0 1897 + * @page_buff_addr: used by UMAC and performance debug (page miss analysis), 1898 + * when paging is not supported this should be 0 1899 + * @page_buff_size: size of %page_buff_addr 1900 + */ 1901 + struct iwl_shared_mem_cfg { 1902 + __le32 shared_mem_addr; 1903 + __le32 shared_mem_size; 1904 + __le32 sample_buff_addr; 1905 + __le32 sample_buff_size; 1906 + __le32 txfifo_addr; 1907 + __le32 txfifo_size[TX_FIFO_MAX_NUM]; 1908 + __le32 rxfifo_size[RX_FIFO_MAX_NUM]; 1909 + __le32 page_buff_addr; 1910 + __le32 page_buff_size; 1911 + } __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */ 1619 1912 1620 1913 #endif /* __fw_api_h__ */
+83 -14
drivers/net/wireless/iwlwifi/mvm/fw.c
··· 400 400 return ret; 401 401 } 402 402 403 - void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm) 403 + static void iwl_mvm_get_shared_mem_conf(struct iwl_mvm *mvm) 404 404 { 405 + struct iwl_host_cmd cmd = { 406 + .id = SHARED_MEM_CFG, 407 + .flags = CMD_WANT_SKB, 408 + .data = { NULL, }, 409 + .len = { 0, }, 410 + }; 411 + struct iwl_rx_packet *pkt; 412 + struct iwl_shared_mem_cfg *mem_cfg; 413 + u32 i; 414 + 405 415 lockdep_assert_held(&mvm->mutex); 406 416 417 + if (WARN_ON(iwl_mvm_send_cmd(mvm, &cmd))) 418 + return; 419 + 420 + pkt = cmd.resp_pkt; 421 + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 422 + IWL_ERR(mvm, "Bad return from SHARED_MEM_CFG (0x%08X)\n", 423 + pkt->hdr.flags); 424 + goto exit; 425 + } 426 + 427 + mem_cfg = (void *)pkt->data; 428 + 429 + mvm->shared_mem_cfg.shared_mem_addr = 430 + le32_to_cpu(mem_cfg->shared_mem_addr); 431 + mvm->shared_mem_cfg.shared_mem_size = 432 + le32_to_cpu(mem_cfg->shared_mem_size); 433 + mvm->shared_mem_cfg.sample_buff_addr = 434 + le32_to_cpu(mem_cfg->sample_buff_addr); 435 + mvm->shared_mem_cfg.sample_buff_size = 436 + le32_to_cpu(mem_cfg->sample_buff_size); 437 + mvm->shared_mem_cfg.txfifo_addr = le32_to_cpu(mem_cfg->txfifo_addr); 438 + for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++) 439 + mvm->shared_mem_cfg.txfifo_size[i] = 440 + le32_to_cpu(mem_cfg->txfifo_size[i]); 441 + for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++) 442 + mvm->shared_mem_cfg.rxfifo_size[i] = 443 + le32_to_cpu(mem_cfg->rxfifo_size[i]); 444 + mvm->shared_mem_cfg.page_buff_addr = 445 + le32_to_cpu(mem_cfg->page_buff_addr); 446 + mvm->shared_mem_cfg.page_buff_size = 447 + le32_to_cpu(mem_cfg->page_buff_size); 448 + IWL_DEBUG_INFO(mvm, "SHARED MEM CFG: got memory offsets/sizes\n"); 449 + 450 + exit: 451 + iwl_free_resp(&cmd); 452 + } 453 + 454 + void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm) 455 + { 407 456 /* stop recording */ 408 457 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 409 458 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); ··· 461 412 iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0); 462 413 } 463 414 464 - iwl_mvm_fw_error_dump(mvm); 465 - 466 - /* start recording again */ 467 - WARN_ON_ONCE(mvm->fw->dbg_dest_tlv && 468 - iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf)); 415 + schedule_work(&mvm->fw_error_dump_wk); 469 416 } 470 417 471 418 int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id) ··· 497 452 498 453 mvm->fw_dbg_conf = conf_id; 499 454 return ret; 455 + } 456 + 457 + static int iwl_mvm_config_ltr_v1(struct iwl_mvm *mvm) 458 + { 459 + struct iwl_ltr_config_cmd_v1 cmd_v1 = { 460 + .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE), 461 + }; 462 + 463 + if (!mvm->trans->ltr_enabled) 464 + return 0; 465 + 466 + return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, 467 + sizeof(cmd_v1), &cmd_v1); 468 + } 469 + 470 + static int iwl_mvm_config_ltr(struct iwl_mvm *mvm) 471 + { 472 + struct iwl_ltr_config_cmd cmd = { 473 + .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE), 474 + }; 475 + 476 + if (!mvm->trans->ltr_enabled) 477 + return 0; 478 + 479 + if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_HDC_PHASE_0)) 480 + return iwl_mvm_config_ltr_v1(mvm); 481 + 482 + return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, 483 + sizeof(cmd), &cmd); 500 484 } 501 485 502 486 int iwl_mvm_up(struct iwl_mvm *mvm) ··· 574 500 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); 575 501 goto error; 576 502 } 503 + 504 + iwl_mvm_get_shared_mem_conf(mvm); 577 505 578 506 ret = iwl_mvm_sf_update(mvm, NULL, false); 579 507 if (ret) ··· 633 557 /* Initialize tx backoffs to the minimal possible */ 634 558 iwl_mvm_tt_tx_backoff(mvm, 0); 635 559 636 - if (mvm->trans->ltr_enabled) { 637 - struct iwl_ltr_config_cmd cmd = { 638 - .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE), 639 - }; 640 - 641 - WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, 642 - sizeof(cmd), &cmd)); 643 - } 560 + WARN_ON(iwl_mvm_config_ltr(mvm)); 644 561 645 562 ret = iwl_mvm_power_update_device(mvm); 646 563 if (ret)
+7 -5
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
··· 208 208 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 209 209 return BIT(IWL_MVM_OFFCHANNEL_QUEUE); 210 210 211 - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 212 - qmask |= BIT(vif->hw_queue[ac]); 211 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 212 + if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) 213 + qmask |= BIT(vif->hw_queue[ac]); 214 + } 213 215 214 216 if (vif->type == NL80211_IFTYPE_AP) 215 217 qmask |= BIT(vif->cab_queue); ··· 498 496 499 497 switch (vif->type) { 500 498 case NL80211_IFTYPE_P2P_DEVICE: 501 - iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE); 499 + iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE, 0); 502 500 break; 503 501 case NL80211_IFTYPE_AP: 504 - iwl_mvm_disable_txq(mvm, vif->cab_queue); 502 + iwl_mvm_disable_txq(mvm, vif->cab_queue, 0); 505 503 /* fall through */ 506 504 default: 507 505 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 508 - iwl_mvm_disable_txq(mvm, vif->hw_queue[ac]); 506 + iwl_mvm_disable_txq(mvm, vif->hw_queue[ac], 0); 509 507 } 510 508 } 511 509
+198 -35
drivers/net/wireless/iwlwifi/mvm/mac80211.c
··· 761 761 kfree(fw_error_dump); 762 762 } 763 763 764 + static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm, 765 + struct iwl_fw_error_dump_data **dump_data) 766 + { 767 + struct iwl_fw_error_dump_fifo *fifo_hdr; 768 + u32 *fifo_data; 769 + u32 fifo_len; 770 + unsigned long flags; 771 + int i, j; 772 + 773 + if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags)) 774 + return; 775 + 776 + /* Pull RXF data from all RXFs */ 777 + for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++) { 778 + /* 779 + * Keep aside the additional offset that might be needed for 780 + * next RXF 781 + */ 782 + u32 offset_diff = RXF_DIFF_FROM_PREV * i; 783 + 784 + fifo_hdr = (void *)(*dump_data)->data; 785 + fifo_data = (void *)fifo_hdr->data; 786 + fifo_len = mvm->shared_mem_cfg.rxfifo_size[i]; 787 + 788 + /* No need to try to read the data if the length is 0 */ 789 + if (fifo_len == 0) 790 + continue; 791 + 792 + /* Add a TLV for the RXF */ 793 + (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF); 794 + (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr)); 795 + 796 + fifo_hdr->fifo_num = cpu_to_le32(i); 797 + fifo_hdr->available_bytes = 798 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 799 + RXF_RD_D_SPACE + 800 + offset_diff)); 801 + fifo_hdr->wr_ptr = 802 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 803 + RXF_RD_WR_PTR + 804 + offset_diff)); 805 + fifo_hdr->rd_ptr = 806 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 807 + RXF_RD_RD_PTR + 808 + offset_diff)); 809 + fifo_hdr->fence_ptr = 810 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 811 + RXF_RD_FENCE_PTR + 812 + offset_diff)); 813 + fifo_hdr->fence_mode = 814 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 815 + RXF_SET_FENCE_MODE + 816 + offset_diff)); 817 + 818 + /* Lock fence */ 819 + iwl_trans_write_prph(mvm->trans, 820 + RXF_SET_FENCE_MODE + offset_diff, 0x1); 821 + /* Set fence pointer to the same place like WR pointer */ 822 + iwl_trans_write_prph(mvm->trans, 823 + RXF_LD_WR2FENCE + offset_diff, 0x1); 824 + /* Set fence offset */ 825 + iwl_trans_write_prph(mvm->trans, 826 + RXF_LD_FENCE_OFFSET_ADDR + offset_diff, 827 + 0x0); 828 + 829 + /* Read FIFO */ 830 + fifo_len /= sizeof(u32); /* Size in DWORDS */ 831 + for (j = 0; j < fifo_len; j++) 832 + fifo_data[j] = iwl_trans_read_prph(mvm->trans, 833 + RXF_FIFO_RD_FENCE_INC + 834 + offset_diff); 835 + *dump_data = iwl_fw_error_next_data(*dump_data); 836 + } 837 + 838 + /* Pull TXF data from all TXFs */ 839 + for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++) { 840 + /* Mark the number of TXF we're pulling now */ 841 + iwl_trans_write_prph(mvm->trans, TXF_LARC_NUM, i); 842 + 843 + fifo_hdr = (void *)(*dump_data)->data; 844 + fifo_data = (void *)fifo_hdr->data; 845 + fifo_len = mvm->shared_mem_cfg.txfifo_size[i]; 846 + 847 + /* No need to try to read the data if the length is 0 */ 848 + if (fifo_len == 0) 849 + continue; 850 + 851 + /* Add a TLV for the FIFO */ 852 + (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_TXF); 853 + (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr)); 854 + 855 + fifo_hdr->fifo_num = cpu_to_le32(i); 856 + fifo_hdr->available_bytes = 857 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 858 + TXF_FIFO_ITEM_CNT)); 859 + fifo_hdr->wr_ptr = 860 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 861 + TXF_WR_PTR)); 862 + fifo_hdr->rd_ptr = 863 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 864 + TXF_RD_PTR)); 865 + fifo_hdr->fence_ptr = 866 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 867 + TXF_FENCE_PTR)); 868 + fifo_hdr->fence_mode = 869 + cpu_to_le32(iwl_trans_read_prph(mvm->trans, 870 + TXF_LOCK_FENCE)); 871 + 872 + /* Set the TXF_READ_MODIFY_ADDR to TXF_WR_PTR */ 873 + iwl_trans_write_prph(mvm->trans, TXF_READ_MODIFY_ADDR, 874 + TXF_WR_PTR); 875 + 876 + /* Dummy-read to advance the read pointer to the head */ 877 + iwl_trans_read_prph(mvm->trans, TXF_READ_MODIFY_DATA); 878 + 879 + /* Read FIFO */ 880 + fifo_len /= sizeof(u32); /* Size in DWORDS */ 881 + for (j = 0; j < fifo_len; j++) 882 + fifo_data[j] = iwl_trans_read_prph(mvm->trans, 883 + TXF_READ_MODIFY_DATA); 884 + *dump_data = iwl_fw_error_next_data(*dump_data); 885 + } 886 + 887 + iwl_trans_release_nic_access(mvm->trans, &flags); 888 + } 889 + 764 890 void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) 765 891 { 766 892 struct iwl_fw_error_dump_file *dump_file; ··· 895 769 struct iwl_fw_error_dump_mem *dump_mem; 896 770 struct iwl_mvm_dump_ptrs *fw_error_dump; 897 771 u32 sram_len, sram_ofs; 898 - u32 file_len, rxf_len; 899 - unsigned long flags; 900 - int reg_val; 772 + u32 file_len, fifo_data_len = 0; 901 773 u32 smem_len = mvm->cfg->smem_len; 774 + u32 sram2_len = mvm->cfg->dccm2_len; 902 775 903 776 lockdep_assert_held(&mvm->mutex); 904 777 905 778 /* W/A for 8000 HW family A-step */ 906 - if (mvm->cfg->smem_len && 907 - mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && 908 - CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) 909 - smem_len = 0x38000; 779 + if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && 780 + CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) { 781 + if (smem_len) 782 + smem_len = 0x38000; 783 + 784 + if (sram2_len) 785 + sram2_len = 0x10000; 786 + } 910 787 911 788 fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL); 912 789 if (!fw_error_dump) ··· 927 798 sram_len = mvm->cfg->dccm_len; 928 799 } 929 800 930 - /* reading buffer size */ 931 - reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR); 932 - rxf_len = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS; 801 + /* reading RXF/TXF sizes */ 802 + if (test_bit(STATUS_FW_ERROR, &mvm->trans->status)) { 803 + struct iwl_mvm_shared_mem_cfg *mem_cfg = &mvm->shared_mem_cfg; 804 + int i; 933 805 934 - /* the register holds the value divided by 128 */ 935 - rxf_len = rxf_len << 7; 806 + fifo_data_len = 0; 807 + 808 + /* Count RXF size */ 809 + for (i = 0; i < ARRAY_SIZE(mem_cfg->rxfifo_size); i++) { 810 + if (!mem_cfg->rxfifo_size[i]) 811 + continue; 812 + 813 + /* Add header info */ 814 + fifo_data_len += mem_cfg->rxfifo_size[i] + 815 + sizeof(*dump_data) + 816 + sizeof(struct iwl_fw_error_dump_fifo); 817 + } 818 + 819 + for (i = 0; i < ARRAY_SIZE(mem_cfg->txfifo_size); i++) { 820 + if (!mem_cfg->txfifo_size[i]) 821 + continue; 822 + 823 + /* Add header info */ 824 + fifo_data_len += mem_cfg->txfifo_size[i] + 825 + sizeof(*dump_data) + 826 + sizeof(struct iwl_fw_error_dump_fifo); 827 + } 828 + } 936 829 937 830 file_len = sizeof(*dump_file) + 938 - sizeof(*dump_data) * 3 + 831 + sizeof(*dump_data) * 2 + 939 832 sram_len + sizeof(*dump_mem) + 940 - rxf_len + 833 + fifo_data_len + 941 834 sizeof(*dump_info); 942 835 943 836 /* Make room for the SMEM, if it exists */ 944 837 if (smem_len) 945 838 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len; 839 + 840 + /* Make room for the secondary SRAM, if it exists */ 841 + if (sram2_len) 842 + file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len; 946 843 947 844 dump_file = vzalloc(file_len); 948 845 if (!dump_file) { ··· 997 842 sizeof(dump_info->bus_human_readable)); 998 843 999 844 dump_data = iwl_fw_error_next_data(dump_data); 1000 - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF); 1001 - dump_data->len = cpu_to_le32(rxf_len); 845 + /* We only dump the FIFOs if the FW is in error state */ 846 + if (test_bit(STATUS_FW_ERROR, &mvm->trans->status)) 847 + iwl_mvm_dump_fifos(mvm, &dump_data); 1002 848 1003 - if (iwl_trans_grab_nic_access(mvm->trans, false, &flags)) { 1004 - u32 *rxf = (void *)dump_data->data; 1005 - int i; 1006 - 1007 - for (i = 0; i < (rxf_len / sizeof(u32)); i++) { 1008 - iwl_trans_write_prph(mvm->trans, 1009 - RXF_LD_FENCE_OFFSET_ADDR, 1010 - i * sizeof(u32)); 1011 - rxf[i] = iwl_trans_read_prph(mvm->trans, 1012 - RXF_FIFO_RD_FENCE_ADDR); 1013 - } 1014 - iwl_trans_release_nic_access(mvm->trans, &flags); 1015 - } 1016 - 1017 - dump_data = iwl_fw_error_next_data(dump_data); 1018 849 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); 1019 850 dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem)); 1020 851 dump_mem = (void *)dump_data->data; ··· 1018 877 dump_mem->offset = cpu_to_le32(mvm->cfg->smem_offset); 1019 878 iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->smem_offset, 1020 879 dump_mem->data, smem_len); 880 + } 881 + 882 + if (sram2_len) { 883 + dump_data = iwl_fw_error_next_data(dump_data); 884 + dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); 885 + dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem)); 886 + dump_mem = (void *)dump_data->data; 887 + dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM); 888 + dump_mem->offset = cpu_to_le32(mvm->cfg->dccm2_offset); 889 + iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->dccm2_offset, 890 + dump_mem->data, sram2_len); 1021 891 } 1022 892 1023 893 fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans); ··· 1365 1213 mvm->bf_allowed_vif = mvmvif; 1366 1214 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 1367 1215 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 1368 - if (mvm->fw->ucode_capa.flags & 1369 - IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT && 1370 - !iwlwifi_mod_params.uapsd_disable) 1371 - vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; 1372 1216 } 1373 1217 1374 1218 /* ··· 2312 2164 mutex_unlock(&mvm->mutex); 2313 2165 } 2314 2166 2167 + static void iwl_mvm_check_uapsd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 2168 + const u8 *bssid) 2169 + { 2170 + if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT)) 2171 + return; 2172 + 2173 + if (iwlwifi_mod_params.uapsd_disable) { 2174 + vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD; 2175 + return; 2176 + } 2177 + 2178 + vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; 2179 + } 2180 + 2315 2181 static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, 2316 2182 struct ieee80211_vif *vif, 2317 2183 struct ieee80211_sta *sta, ··· 2385 2223 * Reset EBS status here assuming environment has been changed. 2386 2224 */ 2387 2225 mvm->last_ebs_successful = true; 2226 + iwl_mvm_check_uapsd(mvm, vif, sta->addr); 2388 2227 ret = 0; 2389 2228 } else if (old_state == IEEE80211_STA_AUTH && 2390 2229 new_state == IEEE80211_STA_ASSOC) {
+27 -6
drivers/net/wireless/iwlwifi/mvm/mvm.h
··· 276 276 IWL_MVM_REF_TM_CMD, 277 277 IWL_MVM_REF_EXIT_WORK, 278 278 IWL_MVM_REF_PROTECT_CSA, 279 + IWL_MVM_REF_FW_DBG_COLLECT, 279 280 280 281 /* update debugfs.c when changing this */ 281 282 ··· 536 535 IWL_MVM_TDLS_SW_ACTIVE, 537 536 }; 538 537 538 + struct iwl_mvm_shared_mem_cfg { 539 + u32 shared_mem_addr; 540 + u32 shared_mem_size; 541 + u32 sample_buff_addr; 542 + u32 sample_buff_size; 543 + u32 txfifo_addr; 544 + u32 txfifo_size[TX_FIFO_MAX_NUM]; 545 + u32 rxfifo_size[RX_FIFO_MAX_NUM]; 546 + u32 page_buff_addr; 547 + u32 page_buff_size; 548 + }; 549 + 539 550 struct iwl_mvm { 540 551 /* for logger access */ 541 552 struct device *dev; ··· 653 640 u32 dbgfs_prph_reg_addr; 654 641 bool disable_power_off; 655 642 bool disable_power_off_d3; 643 + 644 + bool scan_iter_notif_enabled; 656 645 657 646 struct debugfs_blob_wrapper nvm_hw_blob; 658 647 struct debugfs_blob_wrapper nvm_sw_blob; ··· 799 784 u32 ch_sw_tm_ie; 800 785 } peer; 801 786 } tdls_cs; 787 + 788 + struct iwl_mvm_shared_mem_cfg shared_mem_cfg; 802 789 }; 803 790 804 791 /* Extract MVM priv from op_mode and _hw */ ··· 872 855 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT); 873 856 } 874 857 875 - static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm) 858 + static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) 876 859 { 877 - return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_DQA_SUPPORT; 860 + return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_API_SCD_CFG; 878 861 } 879 862 880 863 extern const u8 iwl_mvm_ac_to_tx_fifo[]; ··· 1016 999 struct iwl_device_cmd *cmd); 1017 1000 int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 1018 1001 struct iwl_device_cmd *cmd); 1002 + int iwl_mvm_rx_shared_mem_cfg_notif(struct iwl_mvm *mvm, 1003 + struct iwl_rx_cmd_buffer *rxb, 1004 + struct iwl_device_cmd *cmd); 1019 1005 1020 1006 /* MVM PHY */ 1021 1007 int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, ··· 1080 1060 int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 1081 1061 struct iwl_rx_cmd_buffer *rxb, 1082 1062 struct iwl_device_cmd *cmd); 1063 + int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 1064 + struct iwl_rx_cmd_buffer *rxb, 1065 + struct iwl_device_cmd *cmd); 1083 1066 int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, 1084 1067 struct ieee80211_vif *vif, 1085 1068 struct cfg80211_sched_scan_request *req, ··· 1143 1120 1144 1121 /* rate scaling */ 1145 1122 int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); 1146 - void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, 1147 - struct iwl_mvm_frame_stats *stats, 1148 - u32 rate, bool agg); 1123 + void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg); 1149 1124 int rs_pretty_print_rate(char *buf, const u32 rate); 1150 1125 void rs_update_last_rssi(struct iwl_mvm *mvm, 1151 1126 struct iwl_lq_sta *lq_sta, ··· 1313 1292 /* hw scheduler queue config */ 1314 1293 void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 1315 1294 const struct iwl_trans_txq_scd_cfg *cfg); 1316 - void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue); 1295 + void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags); 1317 1296 1318 1297 static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, 1319 1298 u8 fifo)
+3 -1
drivers/net/wireless/iwlwifi/mvm/nvm.c
··· 356 356 max_section_size = IWL_MAX_NVM_SECTION_SIZE; 357 357 else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) 358 358 max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE; 359 - else /* Family 8000 B-step */ 359 + else /* Family 8000 B-step or C-step */ 360 360 max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE; 361 361 362 362 /* ··· 565 565 mvm->nvm_data = iwl_parse_nvm_sections(mvm); 566 566 if (!mvm->nvm_data) 567 567 return -ENODATA; 568 + IWL_DEBUG_EEPROM(mvm->trans->dev, "nvm version = %x\n", 569 + mvm->nvm_data->nvm_version); 568 570 569 571 return 0; 570 572 }
+14
drivers/net/wireless/iwlwifi/mvm/ops.c
··· 234 234 235 235 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 236 236 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true), 237 + RX_HANDLER(SCAN_ITERATION_COMPLETE, 238 + iwl_mvm_rx_scan_offload_iter_complete_notif, false), 237 239 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 238 240 iwl_mvm_rx_scan_offload_complete_notif, true), 239 241 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results, ··· 270 268 CMD(MGMT_MCAST_KEY), 271 269 CMD(TX_CMD), 272 270 CMD(TXPATH_FLUSH), 271 + CMD(SHARED_MEM_CFG), 273 272 CMD(MAC_CONTEXT_CMD), 274 273 CMD(TIME_EVENT_CMD), 275 274 CMD(TIME_EVENT_NOTIFICATION), ··· 821 818 struct iwl_mvm *mvm = 822 819 container_of(work, struct iwl_mvm, fw_error_dump_wk); 823 820 821 + if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT)) 822 + return; 823 + 824 824 mutex_lock(&mvm->mutex); 825 825 iwl_mvm_fw_error_dump(mvm); 826 + 827 + /* start recording again if the firmware is not crashed */ 828 + WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) && 829 + mvm->fw->dbg_dest_tlv && 830 + iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf)); 831 + 826 832 mutex_unlock(&mvm->mutex); 833 + 834 + iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT); 827 835 } 828 836 829 837 void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
+1 -1
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
··· 170 170 active_cnt = 2; 171 171 } 172 172 173 - cmd->rxchain_info = cpu_to_le32(mvm->fw->valid_rx_ant << 173 + cmd->rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) << 174 174 PHY_RX_CHAIN_VALID_POS); 175 175 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 176 176 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
+99 -82
drivers/net/wireless/iwlwifi/mvm/rs.c
··· 917 917 break; 918 918 if (rate_mask & (1 << low)) 919 919 break; 920 - IWL_DEBUG_RATE(mvm, "Skipping masked lower rate: %d\n", low); 921 920 } 922 921 923 922 high = index; ··· 926 927 break; 927 928 if (rate_mask & (1 << high)) 928 929 break; 929 - IWL_DEBUG_RATE(mvm, "Skipping masked higher rate: %d\n", high); 930 930 } 931 931 932 932 return (high << 8) | low; ··· 1802 1804 static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 1803 1805 struct iwl_lq_sta *lq_sta) 1804 1806 { 1805 - struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 1806 - struct ieee80211_vif *vif = mvmsta->vif; 1807 - bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION && 1808 - !vif->bss_conf.ps); 1809 - 1810 1807 /* Our chip supports Tx STBC and the peer is an HT/VHT STA which 1811 1808 * supports STBC of at least 1*SS 1812 1809 */ 1813 1810 if (!lq_sta->stbc) 1814 - return false; 1815 - 1816 - if (!mvm->ps_disabled && !sta_ps_disabled) 1817 1811 return false; 1818 1812 1819 1813 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) ··· 2600 2610 } 2601 2611 } 2602 2612 2613 + static void rs_ht_init(struct iwl_mvm *mvm, 2614 + struct ieee80211_sta *sta, 2615 + struct iwl_lq_sta *lq_sta, 2616 + struct ieee80211_sta_ht_cap *ht_cap) 2617 + { 2618 + /* active_siso_rate mask includes 9 MBits (bit 5), 2619 + * and CCK (bits 0-3), supp_rates[] does not; 2620 + * shift to convert format, force 9 MBits off. 2621 + */ 2622 + lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; 2623 + lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; 2624 + lq_sta->active_siso_rate &= ~((u16)0x2); 2625 + lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; 2626 + 2627 + lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; 2628 + lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; 2629 + lq_sta->active_mimo2_rate &= ~((u16)0x2); 2630 + lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; 2631 + 2632 + if (mvm->cfg->ht_params->ldpc && 2633 + (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) 2634 + lq_sta->ldpc = true; 2635 + 2636 + if (mvm->cfg->ht_params->stbc && 2637 + (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && 2638 + (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) 2639 + lq_sta->stbc = true; 2640 + 2641 + lq_sta->is_vht = false; 2642 + } 2643 + 2644 + static void rs_vht_init(struct iwl_mvm *mvm, 2645 + struct ieee80211_sta *sta, 2646 + struct iwl_lq_sta *lq_sta, 2647 + struct ieee80211_sta_vht_cap *vht_cap) 2648 + { 2649 + rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); 2650 + 2651 + if (mvm->cfg->ht_params->ldpc && 2652 + (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) 2653 + lq_sta->ldpc = true; 2654 + 2655 + if (mvm->cfg->ht_params->stbc && 2656 + (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && 2657 + (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)) 2658 + lq_sta->stbc = true; 2659 + 2660 + lq_sta->is_vht = true; 2661 + } 2662 + 2603 2663 #ifdef CONFIG_IWLWIFI_DEBUGFS 2604 - static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm, 2605 - struct iwl_mvm_frame_stats *stats) 2664 + static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm) 2606 2665 { 2607 2666 spin_lock_bh(&mvm->drv_stats_lock); 2608 - memset(stats, 0, sizeof(*stats)); 2667 + memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats)); 2609 2668 spin_unlock_bh(&mvm->drv_stats_lock); 2610 2669 } 2611 2670 2612 - void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, 2613 - struct iwl_mvm_frame_stats *stats, 2614 - u32 rate, bool agg) 2671 + void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) 2615 2672 { 2616 2673 u8 nss = 0, mcs = 0; 2617 2674 2618 2675 spin_lock(&mvm->drv_stats_lock); 2619 2676 2620 2677 if (agg) 2621 - stats->agg_frames++; 2678 + mvm->drv_rx_stats.agg_frames++; 2622 2679 2623 - stats->success_frames++; 2680 + mvm->drv_rx_stats.success_frames++; 2624 2681 2625 2682 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) { 2626 2683 case RATE_MCS_CHAN_WIDTH_20: 2627 - stats->bw_20_frames++; 2684 + mvm->drv_rx_stats.bw_20_frames++; 2628 2685 break; 2629 2686 case RATE_MCS_CHAN_WIDTH_40: 2630 - stats->bw_40_frames++; 2687 + mvm->drv_rx_stats.bw_40_frames++; 2631 2688 break; 2632 2689 case RATE_MCS_CHAN_WIDTH_80: 2633 - stats->bw_80_frames++; 2690 + mvm->drv_rx_stats.bw_80_frames++; 2634 2691 break; 2635 2692 default: 2636 2693 WARN_ONCE(1, "bad BW. rate 0x%x", rate); 2637 2694 } 2638 2695 2639 2696 if (rate & RATE_MCS_HT_MSK) { 2640 - stats->ht_frames++; 2697 + mvm->drv_rx_stats.ht_frames++; 2641 2698 mcs = rate & RATE_HT_MCS_RATE_CODE_MSK; 2642 2699 nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1; 2643 2700 } else if (rate & RATE_MCS_VHT_MSK) { 2644 - stats->vht_frames++; 2701 + mvm->drv_rx_stats.vht_frames++; 2645 2702 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; 2646 2703 nss = ((rate & RATE_VHT_MCS_NSS_MSK) >> 2647 2704 RATE_VHT_MCS_NSS_POS) + 1; 2648 2705 } else { 2649 - stats->legacy_frames++; 2706 + mvm->drv_rx_stats.legacy_frames++; 2650 2707 } 2651 2708 2652 2709 if (nss == 1) 2653 - stats->siso_frames++; 2710 + mvm->drv_rx_stats.siso_frames++; 2654 2711 else if (nss == 2) 2655 - stats->mimo2_frames++; 2712 + mvm->drv_rx_stats.mimo2_frames++; 2656 2713 2657 2714 if (rate & RATE_MCS_SGI_MSK) 2658 - stats->sgi_frames++; 2715 + mvm->drv_rx_stats.sgi_frames++; 2659 2716 else 2660 - stats->ngi_frames++; 2717 + mvm->drv_rx_stats.ngi_frames++; 2661 2718 2662 - stats->last_rates[stats->last_frame_idx] = rate; 2663 - stats->last_frame_idx = (stats->last_frame_idx + 1) % 2664 - ARRAY_SIZE(stats->last_rates); 2719 + mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate; 2720 + mvm->drv_rx_stats.last_frame_idx = 2721 + (mvm->drv_rx_stats.last_frame_idx + 1) % 2722 + ARRAY_SIZE(mvm->drv_rx_stats.last_rates); 2665 2723 2666 2724 spin_unlock(&mvm->drv_stats_lock); 2667 2725 } ··· 2762 2724 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); 2763 2725 2764 2726 /* TODO: should probably account for rx_highest for both HT/VHT */ 2765 - if (!vht_cap || !vht_cap->vht_supported) { 2766 - /* active_siso_rate mask includes 9 MBits (bit 5), 2767 - * and CCK (bits 0-3), supp_rates[] does not; 2768 - * shift to convert format, force 9 MBits off. 2769 - */ 2770 - lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; 2771 - lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; 2772 - lq_sta->active_siso_rate &= ~((u16)0x2); 2773 - lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; 2727 + if (!vht_cap || !vht_cap->vht_supported) 2728 + rs_ht_init(mvm, sta, lq_sta, ht_cap); 2729 + else 2730 + rs_vht_init(mvm, sta, lq_sta, vht_cap); 2774 2731 2775 - /* Same here */ 2776 - lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; 2777 - lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; 2778 - lq_sta->active_mimo2_rate &= ~((u16)0x2); 2779 - lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; 2780 - 2781 - lq_sta->is_vht = false; 2782 - if (mvm->cfg->ht_params->ldpc && 2783 - (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) 2784 - lq_sta->ldpc = true; 2785 - 2786 - if (mvm->cfg->ht_params->stbc && 2787 - (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && 2788 - (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) 2789 - lq_sta->stbc = true; 2790 - } else { 2791 - rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); 2792 - lq_sta->is_vht = true; 2793 - 2794 - if (mvm->cfg->ht_params->ldpc && 2795 - (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) 2796 - lq_sta->ldpc = true; 2797 - 2798 - if (mvm->cfg->ht_params->stbc && 2799 - (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && 2800 - (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)) 2801 - lq_sta->stbc = true; 2802 - } 2803 - 2804 - if (IWL_MVM_RS_DISABLE_MIMO) 2732 + if (IWL_MVM_RS_DISABLE_P2P_MIMO && sta_priv->vif->p2p) 2805 2733 lq_sta->active_mimo2_rate = 0; 2806 2734 2807 2735 lq_sta->max_legacy_rate_idx = ··· 2778 2774 rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate); 2779 2775 2780 2776 IWL_DEBUG_RATE(mvm, 2781 - "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC%d\n", 2777 + "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d\n", 2782 2778 lq_sta->active_legacy_rate, 2783 2779 lq_sta->active_siso_rate, 2784 2780 lq_sta->active_mimo2_rate, ··· 2797 2793 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2798 2794 lq_sta->is_agg = 0; 2799 2795 #ifdef CONFIG_IWLWIFI_DEBUGFS 2800 - iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats); 2796 + iwl_mvm_reset_frame_stats(mvm); 2801 2797 #endif 2802 2798 rs_initialize_lq(mvm, sta, lq_sta, band, init); 2803 2799 } ··· 2866 2862 int index = *rs_table_index; 2867 2863 2868 2864 for (i = 0; i < num_rates && index < end; i++) { 2869 - ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, rate)); 2870 - for (j = 0; j < num_retries && index < end; j++, index++) 2865 + for (j = 0; j < num_retries && index < end; j++, index++) { 2866 + ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, 2867 + rate)); 2871 2868 rs_table[index] = ucode_rate; 2872 - 2873 - if (toggle_ant) 2874 - rs_toggle_antenna(valid_tx_ant, rate); 2869 + if (toggle_ant) 2870 + rs_toggle_antenna(valid_tx_ant, rate); 2871 + } 2875 2872 2876 2873 prev_rate_idx = rate->index; 2877 2874 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate); ··· 2880 2875 break; 2881 2876 } 2882 2877 2883 - if (!bottom_reached) 2878 + if (!bottom_reached && !is_legacy(rate)) 2884 2879 rate->index = prev_rate_idx; 2885 2880 2886 2881 *rs_table_index = index; ··· 2916 2911 u8 valid_tx_ant = 0; 2917 2912 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; 2918 2913 bool toggle_ant = false; 2914 + bool stbc_allowed = false; 2919 2915 2920 2916 memcpy(&rate, initial_rate, sizeof(rate)); 2921 2917 2922 2918 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm); 2923 - rate.stbc = rs_stbc_allow(mvm, sta, lq_sta); 2919 + 2920 + stbc_allowed = rs_stbc_allow(mvm, sta, lq_sta); 2921 + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS) { 2922 + u32 ss_params = RS_SS_PARAMS_VALID; 2923 + 2924 + if (stbc_allowed) 2925 + ss_params |= RS_SS_STBC_ALLOWED; 2926 + lq_cmd->ss_params = cpu_to_le32(ss_params); 2927 + } else { 2928 + /* TODO: remove old API when min FW API hits 14 */ 2929 + rate.stbc = stbc_allowed; 2930 + } 2924 2931 2925 2932 if (is_siso(&rate)) { 2926 2933 num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES; ··· 2942 2925 num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE; 2943 2926 } else { 2944 2927 num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES; 2945 - num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE; 2928 + num_retries = IWL_MVM_RS_INITIAL_LEGACY_RETRIES; 2946 2929 toggle_ant = true; 2947 2930 } 2948 2931 ··· 2958 2941 lq_cmd->mimo_delim = index; 2959 2942 } else if (is_legacy(&rate)) { 2960 2943 num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES; 2961 - num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE; 2944 + num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES; 2962 2945 } else { 2963 2946 WARN_ON_ONCE(1); 2964 2947 } ··· 2972 2955 rs_get_lower_rate_down_column(lq_sta, &rate); 2973 2956 2974 2957 num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES; 2975 - num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE; 2958 + num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES; 2976 2959 2977 2960 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, 2978 2961 num_rates, num_retries, valid_tx_ant,
+7 -3
drivers/net/wireless/iwlwifi/mvm/rx.c
··· 407 407 } 408 408 409 409 #ifdef CONFIG_IWLWIFI_DEBUGFS 410 - iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags, 410 + iwl_mvm_update_frame_stats(mvm, rate_n_flags, 411 411 rx_status->flag & RX_FLAG_AMPDU_DETAILS); 412 412 #endif 413 413 iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status, ··· 511 511 { 512 512 struct iwl_rx_packet *pkt = rxb_addr(rxb); 513 513 struct iwl_notif_statistics *stats = (void *)&pkt->data; 514 - struct mvm_statistics_general_common *common = &stats->general.common; 515 514 struct iwl_mvm_stat_data data = { 516 515 .stats = stats, 517 516 .mvm = mvm, 518 517 }; 519 518 520 - iwl_mvm_tt_temp_changed(mvm, le32_to_cpu(common->temperature)); 519 + /* Only handle rx statistics temperature changes if async temp 520 + * notifications are not supported 521 + */ 522 + if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_ASYNC_DTM)) 523 + iwl_mvm_tt_temp_changed(mvm, 524 + le32_to_cpu(stats->general.radio_temperature)); 521 525 522 526 iwl_mvm_update_rx_statistics(mvm, stats); 523 527
+73 -23
drivers/net/wireless/iwlwifi/mvm/scan.c
··· 173 173 * already included in the probe template, so we need to set only 174 174 * req->n_ssids - 1 bits in addition to the first bit. 175 175 */ 176 - static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) 176 + static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm, 177 + enum ieee80211_band band, int n_ssids) 177 178 { 179 + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) 180 + return 10; 178 181 if (band == IEEE80211_BAND_2GHZ) 179 182 return 20 + 3 * (n_ssids + 1); 180 183 return 10 + 2 * (n_ssids + 1); 181 184 } 182 185 183 - static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) 186 + static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm, 187 + enum ieee80211_band band) 184 188 { 189 + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) 190 + return 110; 185 191 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; 186 192 } 187 193 ··· 315 309 goto not_bound; 316 310 317 311 params->suspend_time = 30; 318 - params->max_out_time = 170; 312 + params->max_out_time = 120; 319 313 320 314 if (iwl_mvm_low_latency(mvm)) { 321 315 if (mvm->fw->ucode_capa.api[0] & 322 316 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) { 323 317 params->suspend_time = 105; 324 - params->max_out_time = 70; 325 318 /* 326 319 * If there is more than one active interface make 327 320 * passive scan more fragmented. 328 321 */ 329 322 frag_passive_dwell = (global_cnt < 2) ? 40 : 20; 323 + params->max_out_time = frag_passive_dwell; 330 324 } else { 331 325 params->suspend_time = 120; 332 326 params->max_out_time = 120; ··· 343 337 */ 344 338 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 345 339 u32 passive_dwell = 346 - iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); 340 + iwl_mvm_get_passive_dwell(mvm, 341 + IEEE80211_BAND_2GHZ); 347 342 params->max_out_time = passive_dwell; 348 343 } else { 349 344 params->passive_fragmented = true; ··· 361 354 params->dwell[band].passive = frag_passive_dwell; 362 355 else 363 356 params->dwell[band].passive = 364 - iwl_mvm_get_passive_dwell(band); 365 - params->dwell[band].active = iwl_mvm_get_active_dwell(band, 357 + iwl_mvm_get_passive_dwell(mvm, band); 358 + params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band, 366 359 n_ssids); 367 360 } 368 361 } ··· 540 533 541 534 IWL_DEBUG_SCAN(mvm, "Scan response received. status 0x%x\n", 542 535 le32_to_cpu(resp->status)); 536 + return 0; 537 + } 538 + 539 + int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 540 + struct iwl_rx_cmd_buffer *rxb, 541 + struct iwl_device_cmd *cmd) 542 + { 543 + struct iwl_rx_packet *pkt = rxb_addr(rxb); 544 + struct iwl_scan_complete_notif *notif = (void *)pkt->data; 545 + 546 + IWL_DEBUG_SCAN(mvm, 547 + "Scan offload iteration complete: status=0x%x scanned channels=%d\n", 548 + notif->status, notif->scanned_channels); 543 549 return 0; 544 550 } 545 551 ··· 1124 1104 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, 1125 1105 notify); 1126 1106 1107 + if (mvm->scan_status == IWL_MVM_SCAN_NONE) 1108 + return 0; 1109 + 1110 + if (iwl_mvm_is_radio_killed(mvm)) 1111 + goto out; 1112 + 1127 1113 if (mvm->scan_status != IWL_MVM_SCAN_SCHED && 1128 1114 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || 1129 1115 mvm->scan_status != IWL_MVM_SCAN_OS)) { ··· 1166 1140 if (mvm->scan_status == IWL_MVM_SCAN_OS) 1167 1141 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1168 1142 1143 + out: 1169 1144 mvm->scan_status = IWL_MVM_SCAN_NONE; 1170 1145 1171 1146 if (notify) { ··· 1323 1296 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1324 1297 cmd->iter_num = cpu_to_le32(1); 1325 1298 1326 - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && 1327 - mvm->last_ebs_successful) { 1328 - cmd->channel_opt[0].flags = 1329 - cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 1330 - IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1331 - IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 1332 - cmd->channel_opt[0].non_ebs_ratio = 1333 - cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); 1334 - cmd->channel_opt[1].flags = 1335 - cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 1336 - IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1337 - IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 1338 - cmd->channel_opt[1].non_ebs_ratio = 1339 - cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); 1340 - } 1341 - 1342 1299 if (iwl_mvm_rrm_scan_needed(mvm)) 1343 1300 cmd->scan_flags |= 1344 1301 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); ··· 1397 1386 cmd->schedule[1].iterations = 0; 1398 1387 cmd->schedule[1].full_scan_mul = 0; 1399 1388 1389 + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS && 1390 + mvm->last_ebs_successful) { 1391 + cmd->channel_opt[0].flags = 1392 + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 1393 + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1394 + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 1395 + cmd->channel_opt[0].non_ebs_ratio = 1396 + cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); 1397 + cmd->channel_opt[1].flags = 1398 + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 1399 + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1400 + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 1401 + cmd->channel_opt[1].non_ebs_ratio = 1402 + cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); 1403 + } 1404 + 1400 1405 for (i = 1; i <= req->req.n_ssids; i++) 1401 1406 ssid_bitmap |= BIT(i); 1402 1407 ··· 1485 1458 1486 1459 if (iwl_mvm_scan_pass_all(mvm, req)) 1487 1460 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; 1461 + else 1462 + flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH; 1488 1463 1489 1464 if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) 1490 1465 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; ··· 1496 1467 1497 1468 if (req->n_ssids == 0) 1498 1469 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; 1470 + 1471 + #ifdef CONFIG_IWLWIFI_DEBUGFS 1472 + if (mvm->scan_iter_notif_enabled) 1473 + flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE; 1474 + #endif 1499 1475 1500 1476 cmd->scan_flags |= cpu_to_le32(flags); 1501 1477 ··· 1517 1483 cmd->schedule[1].delay = cpu_to_le16(req->interval / MSEC_PER_SEC); 1518 1484 cmd->schedule[1].iterations = 0xff; 1519 1485 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; 1486 + 1487 + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && 1488 + mvm->last_ebs_successful) { 1489 + cmd->channel_opt[0].flags = 1490 + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 1491 + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1492 + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 1493 + cmd->channel_opt[0].non_ebs_ratio = 1494 + cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); 1495 + cmd->channel_opt[1].flags = 1496 + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | 1497 + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | 1498 + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); 1499 + cmd->channel_opt[1].non_ebs_ratio = 1500 + cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); 1501 + } 1520 1502 1521 1503 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, 1522 1504 ssid_bitmap, cmd);
+7 -6
drivers/net/wireless/iwlwifi/mvm/sta.c
··· 250 250 251 251 /* disable the TDLS STA-specific queues */ 252 252 sta_msk = mvmsta->tfd_queue_msk; 253 - for_each_set_bit(i, &sta_msk, sizeof(sta_msk)) 254 - iwl_mvm_disable_txq(mvm, i); 253 + for_each_set_bit(i, &sta_msk, sizeof(sta_msk) * BITS_PER_BYTE) 254 + iwl_mvm_disable_txq(mvm, i, 0); 255 255 } 256 256 257 257 int iwl_mvm_add_sta(struct iwl_mvm *mvm, ··· 464 464 if (mvm->tfd_drained[sta_id]) { 465 465 unsigned long i, msk = mvm->tfd_drained[sta_id]; 466 466 467 - for_each_set_bit(i, &msk, sizeof(msk)) 468 - iwl_mvm_disable_txq(mvm, i); 467 + for_each_set_bit(i, &msk, sizeof(msk) * BITS_PER_BYTE) 468 + iwl_mvm_disable_txq(mvm, i, 0); 469 469 470 470 mvm->tfd_drained[sta_id] = 0; 471 471 IWL_DEBUG_TDLS(mvm, "Drained sta %d, with queues %ld\n", ··· 1058 1058 1059 1059 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); 1060 1060 1061 - iwl_mvm_disable_txq(mvm, txq_id); 1061 + iwl_mvm_disable_txq(mvm, txq_id, 0); 1062 1062 return 0; 1063 1063 case IWL_AGG_STARTING: 1064 1064 case IWL_EMPTYING_HW_QUEUE_ADDBA: ··· 1116 1116 1117 1117 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); 1118 1118 1119 - iwl_mvm_disable_txq(mvm, tid_data->txq_id); 1119 + iwl_mvm_disable_txq(mvm, tid_data->txq_id, 0); 1120 1120 } 1121 1121 1122 1122 mvm->queue_to_mac80211[tid_data->txq_id] = ··· 1196 1196 break; 1197 1197 case WLAN_CIPHER_SUITE_WEP104: 1198 1198 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_13BYTES); 1199 + /* fall through */ 1199 1200 case WLAN_CIPHER_SUITE_WEP40: 1200 1201 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP); 1201 1202 memcpy(cmd.key + 3, keyconf->key, keyconf->keylen);
+23 -6
drivers/net/wireless/iwlwifi/mvm/tx.c
··· 90 90 91 91 if (ieee80211_is_probe_resp(fc)) 92 92 tx_flags |= TX_CMD_FLG_TSF; 93 - else if (ieee80211_is_back_req(fc)) 94 - tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; 95 93 96 94 if (ieee80211_has_morefrags(fc)) 97 95 tx_flags |= TX_CMD_FLG_MORE_FRAG; ··· 98 100 u8 *qc = ieee80211_get_qos_ctl(hdr); 99 101 tx_cmd->tid_tspec = qc[0] & 0xf; 100 102 tx_flags &= ~TX_CMD_FLG_SEQ_CTL; 103 + } else if (ieee80211_is_back_req(fc)) { 104 + struct ieee80211_bar *bar = (void *)skb->data; 105 + u16 control = le16_to_cpu(bar->control); 106 + 107 + tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; 108 + tx_cmd->tid_tspec = (control & 109 + IEEE80211_BAR_CTRL_TID_INFO_MASK) >> 110 + IEEE80211_BAR_CTRL_TID_INFO_SHIFT; 111 + WARN_ON_ONCE(tx_cmd->tid_tspec >= IWL_MAX_TID_COUNT); 101 112 } else { 102 113 tx_cmd->tid_tspec = IWL_TID_NON_QOS; 103 114 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) ··· 115 108 tx_flags &= ~TX_CMD_FLG_SEQ_CTL; 116 109 } 117 110 118 - /* tid_tspec will default to 0 = BE when QOS isn't enabled */ 119 - ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; 111 + /* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */ 112 + if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT) 113 + ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; 114 + else 115 + ac = tid_to_mac80211_ac[0]; 116 + 120 117 tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) << 121 118 TX_CMD_FLG_BT_PRIO_POS; 122 119 ··· 507 496 IWL_DEBUG_TX_QUEUES(mvm, 508 497 "Can continue DELBA flow ssn = next_recl = %d\n", 509 498 tid_data->next_reclaimed); 510 - iwl_mvm_disable_txq(mvm, tid_data->txq_id); 499 + iwl_mvm_disable_txq(mvm, tid_data->txq_id, CMD_ASYNC); 511 500 tid_data->state = IWL_AGG_OFF; 512 501 /* 513 502 * we can't hold the mutex - but since we are after a sequence ··· 667 656 668 657 /* Single frame failure in an AMPDU queue => send BAR */ 669 658 if (txq_id >= mvm->first_agg_queue && 670 - !(info->flags & IEEE80211_TX_STAT_ACK)) 659 + !(info->flags & IEEE80211_TX_STAT_ACK) && 660 + !(info->flags & IEEE80211_TX_STAT_TX_FILTERED)) 671 661 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 672 662 673 663 /* W/A FW bug: seq_ctl is wrong when the status isn't success */ ··· 930 918 931 919 sta_id = ba_notif->sta_id; 932 920 tid = ba_notif->tid; 921 + 922 + if (WARN_ONCE(sta_id >= IWL_MVM_STATION_COUNT || 923 + tid >= IWL_MAX_TID_COUNT, 924 + "sta_id %d tid %d", sta_id, tid)) 925 + return 0; 933 926 934 927 rcu_read_lock(); 935 928
+34 -35
drivers/net/wireless/iwlwifi/mvm/utils.c
··· 533 533 void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 534 534 const struct iwl_trans_txq_scd_cfg *cfg) 535 535 { 536 - if (iwl_mvm_is_dqa_supported(mvm)) { 537 - struct iwl_scd_txq_cfg_cmd cmd = { 538 - .scd_queue = queue, 539 - .enable = 1, 540 - .window = cfg->frame_limit, 541 - .sta_id = cfg->sta_id, 542 - .ssn = cpu_to_le16(ssn), 543 - .tx_fifo = cfg->fifo, 544 - .aggregate = cfg->aggregate, 545 - .flags = IWL_SCD_FLAGS_DQA_ENABLED, 546 - .tid = cfg->tid, 547 - .control = IWL_SCD_CONTROL_SET_SSN, 548 - }; 549 - int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, 550 - sizeof(cmd), &cmd); 551 - if (ret) 552 - IWL_ERR(mvm, 553 - "Failed to configure queue %d on FIFO %d\n", 554 - queue, cfg->fifo); 536 + struct iwl_scd_txq_cfg_cmd cmd = { 537 + .scd_queue = queue, 538 + .enable = 1, 539 + .window = cfg->frame_limit, 540 + .sta_id = cfg->sta_id, 541 + .ssn = cpu_to_le16(ssn), 542 + .tx_fifo = cfg->fifo, 543 + .aggregate = cfg->aggregate, 544 + .tid = cfg->tid, 545 + }; 546 + 547 + if (!iwl_mvm_is_scd_cfg_supported(mvm)) { 548 + iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, cfg); 549 + return; 555 550 } 556 551 557 - iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, 558 - iwl_mvm_is_dqa_supported(mvm) ? NULL : cfg); 552 + iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL); 553 + WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd), 554 + "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo); 559 555 } 560 556 561 - void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue) 557 + void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags) 562 558 { 563 - iwl_trans_txq_disable(mvm->trans, queue, 564 - !iwl_mvm_is_dqa_supported(mvm)); 559 + struct iwl_scd_txq_cfg_cmd cmd = { 560 + .scd_queue = queue, 561 + .enable = 0, 562 + }; 563 + int ret; 565 564 566 - if (iwl_mvm_is_dqa_supported(mvm)) { 567 - struct iwl_scd_txq_cfg_cmd cmd = { 568 - .scd_queue = queue, 569 - .enable = 0, 570 - }; 571 - int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, CMD_ASYNC, 572 - sizeof(cmd), &cmd); 573 - if (ret) 574 - IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n", 575 - queue, ret); 565 + if (!iwl_mvm_is_scd_cfg_supported(mvm)) { 566 + iwl_trans_txq_disable(mvm->trans, queue, true); 567 + return; 576 568 } 569 + 570 + iwl_trans_txq_disable(mvm->trans, queue, false); 571 + ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags, 572 + sizeof(cmd), &cmd); 573 + if (ret) 574 + IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n", 575 + queue, ret); 577 576 } 578 577 579 578 /** ··· 664 665 if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1) 665 666 return false; 666 667 667 - if (!mvm->cfg->rx_with_siso_diversity) 668 + if (mvm->cfg->rx_with_siso_diversity) 668 669 return false; 669 670 670 671 ieee80211_iterate_active_interfaces_atomic(
+5 -1
drivers/net/wireless/iwlwifi/pcie/drv.c
··· 415 415 {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, 416 416 {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, 417 417 {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, 418 + {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)}, 419 + {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)}, 418 420 #endif /* CONFIG_IWLMVM */ 419 421 420 422 {0} ··· 529 527 else if (cfg == &iwl7265_n_cfg) 530 528 cfg_7265d = &iwl7265d_n_cfg; 531 529 if (cfg_7265d && 532 - (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) 530 + (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) { 533 531 cfg = cfg_7265d; 532 + iwl_trans->cfg = cfg_7265d; 533 + } 534 534 #endif 535 535 536 536 pci_set_drvdata(pdev, iwl_trans);
+7 -4
drivers/net/wireless/iwlwifi/pcie/trans.c
··· 722 722 723 723 *first_ucode_section = last_read_idx; 724 724 725 + if (cpu == 1) 726 + iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFF); 727 + else 728 + iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF); 729 + 725 730 return 0; 726 731 } 727 732 ··· 916 911 if (trans->dbg_dest_tlv) 917 912 iwl_pcie_apply_destination(trans); 918 913 919 - /* Notify FW loading is done */ 920 - iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF); 921 - 922 914 /* wait for image verification to complete */ 923 915 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, 924 916 LMPM_SECURE_BOOT_STATUS_SUCCESS, ··· 984 982 985 983 /* Load the given image to the HW */ 986 984 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && 987 - (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP)) 985 + (CSR_HW_REV_STEP(trans->hw_rev) != SILICON_A_STEP)) 988 986 return iwl_pcie_load_given_ucode_8000b(trans, fw); 989 987 else 990 988 return iwl_pcie_load_given_ucode(trans, fw); ··· 2350 2348 trans_pcie->trans = trans; 2351 2349 spin_lock_init(&trans_pcie->irq_lock); 2352 2350 spin_lock_init(&trans_pcie->reg_lock); 2351 + spin_lock_init(&trans_pcie->ref_lock); 2353 2352 init_waitqueue_head(&trans_pcie->ucode_write_waitq); 2354 2353 2355 2354 err = pci_enable_device(pdev);
+10 -4
drivers/net/wireless/iwlwifi/pcie/tx.c
··· 1190 1190 * Assumes that ssn_idx is valid (!= 0xFFF) */ 1191 1191 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); 1192 1192 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); 1193 + iwl_write_direct32(trans, HBUS_TARG_WRPTR, 1194 + (ssn & 0xff) | (txq_id << 8)); 1193 1195 1194 1196 if (cfg) { 1195 1197 u8 frame_limit = cfg->frame_limit; 1196 1198 1197 - iwl_write_direct32(trans, HBUS_TARG_WRPTR, 1198 - (ssn & 0xff) | (txq_id << 8)); 1199 1199 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); 1200 1200 1201 1201 /* Set up Tx window size and frame limit for this queue */ ··· 1220 1220 if (txq_id == trans_pcie->cmd_queue && 1221 1221 trans_pcie->scd_set_active) 1222 1222 iwl_scd_enable_set_active(trans, BIT(txq_id)); 1223 + 1224 + IWL_DEBUG_TX_QUEUES(trans, 1225 + "Activate queue %d on FIFO %d WrPtr: %d\n", 1226 + txq_id, fifo, ssn & 0xff); 1227 + } else { 1228 + IWL_DEBUG_TX_QUEUES(trans, 1229 + "Activate queue %d WrPtr: %d\n", 1230 + txq_id, ssn & 0xff); 1223 1231 } 1224 1232 1225 1233 trans_pcie->txq[txq_id].active = true; 1226 - IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", 1227 - txq_id, fifo, ssn & 0xff); 1228 1234 } 1229 1235 1230 1236 void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,