1 /* 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <linux/moduleparam.h> 19 #include <linux/etherdevice.h> 20 #include <linux/if_arp.h> 21 22 #include "wil6210.h" 23 #include "txrx.h" 24 #include "wmi.h" 25 #include "trace.h" 26 27 static uint max_assoc_sta = WIL6210_MAX_CID; 28 module_param(max_assoc_sta, uint, 0644); 29 MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP"); 30 31 int agg_wsize; /* = 0; */ 32 module_param(agg_wsize, int, 0644); 33 MODULE_PARM_DESC(agg_wsize, " Window size for Tx Block Ack after connect;" 34 " 0 - use default; < 0 - don't auto-establish"); 35 36 u8 led_id = WIL_LED_INVALID_ID; 37 module_param(led_id, byte, 0444); 38 MODULE_PARM_DESC(led_id, 39 " 60G device led enablement. Set the led ID (0-2) to enable"); 40 41 #define WIL_WAIT_FOR_SUSPEND_RESUME_COMP 200 42 #define WIL_WMI_CALL_GENERAL_TO_MS 100 43 44 /** 45 * WMI event receiving - theory of operations 46 * 47 * When firmware about to report WMI event, it fills memory area 48 * in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for 49 * the misc IRQ, function @wmi_recv_cmd called by thread IRQ handler. 50 * 51 * @wmi_recv_cmd reads event, allocates memory chunk and attaches it to the 52 * event list @wil->pending_wmi_ev. Then, work queue @wil->wmi_wq wakes up 53 * and handles events within the @wmi_event_worker. Every event get detached 54 * from list, processed and deleted. 55 * 56 * Purpose for this mechanism is to release IRQ thread; otherwise, 57 * if WMI event handling involves another WMI command flow, this 2-nd flow 58 * won't be completed because of blocked IRQ thread. 59 */ 60 61 /** 62 * Addressing - theory of operations 63 * 64 * There are several buses present on the WIL6210 card. 65 * Same memory areas are visible at different address on 66 * the different busses. There are 3 main bus masters: 67 * - MAC CPU (ucode) 68 * - User CPU (firmware) 69 * - AHB (host) 70 * 71 * On the PCI bus, there is one BAR (BAR0) of 2Mb size, exposing 72 * AHB addresses starting from 0x880000 73 * 74 * Internally, firmware uses addresses that allow faster access but 75 * are invisible from the host. To read from these addresses, alternative 76 * AHB address must be used. 77 */ 78 79 /** 80 * @sparrow_fw_mapping provides memory remapping table for sparrow 81 * 82 * array size should be in sync with the declaration in the wil6210.h 83 * 84 * Sparrow memory mapping: 85 * Linker address PCI/Host address 86 * 0x880000 .. 0xa80000 2Mb BAR0 87 * 0x800000 .. 0x808000 0x900000 .. 0x908000 32k DCCM 88 * 0x840000 .. 0x860000 0x908000 .. 0x928000 128k PERIPH 89 */ 90 const struct fw_map sparrow_fw_mapping[] = { 91 /* FW code RAM 256k */ 92 {0x000000, 0x040000, 0x8c0000, "fw_code", true}, 93 /* FW data RAM 32k */ 94 {0x800000, 0x808000, 0x900000, "fw_data", true}, 95 /* periph data 128k */ 96 {0x840000, 0x860000, 0x908000, "fw_peri", true}, 97 /* various RGF 40k */ 98 {0x880000, 0x88a000, 0x880000, "rgf", true}, 99 /* AGC table 4k */ 100 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true}, 101 /* Pcie_ext_rgf 4k */ 102 {0x88b000, 0x88c000, 0x88b000, "rgf_ext", true}, 103 /* mac_ext_rgf 512b */ 104 {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext", true}, 105 /* upper area 548k */ 106 {0x8c0000, 0x949000, 0x8c0000, "upper", true}, 107 /* UCODE areas - accessible by debugfs blobs but not by 108 * wmi_addr_remap. UCODE areas MUST be added AFTER FW areas! 109 */ 110 /* ucode code RAM 128k */ 111 {0x000000, 0x020000, 0x920000, "uc_code", false}, 112 /* ucode data RAM 16k */ 113 {0x800000, 0x804000, 0x940000, "uc_data", false}, 114 }; 115 116 /** 117 * @sparrow_d0_mac_rgf_ext - mac_rgf_ext section for Sparrow D0 118 * it is a bit larger to support extra features 119 */ 120 const struct fw_map sparrow_d0_mac_rgf_ext = { 121 0x88c000, 0x88c500, 0x88c000, "mac_rgf_ext", true 122 }; 123 124 /** 125 * @talyn_fw_mapping provides memory remapping table for Talyn 126 * 127 * array size should be in sync with the declaration in the wil6210.h 128 * 129 * Talyn memory mapping: 130 * Linker address PCI/Host address 131 * 0x880000 .. 0xc80000 4Mb BAR0 132 * 0x800000 .. 0x820000 0xa00000 .. 0xa20000 128k DCCM 133 * 0x840000 .. 0x858000 0xa20000 .. 0xa38000 96k PERIPH 134 */ 135 const struct fw_map talyn_fw_mapping[] = { 136 /* FW code RAM 1M */ 137 {0x000000, 0x100000, 0x900000, "fw_code", true}, 138 /* FW data RAM 128k */ 139 {0x800000, 0x820000, 0xa00000, "fw_data", true}, 140 /* periph. data RAM 96k */ 141 {0x840000, 0x858000, 0xa20000, "fw_peri", true}, 142 /* various RGF 40k */ 143 {0x880000, 0x88a000, 0x880000, "rgf", true}, 144 /* AGC table 4k */ 145 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true}, 146 /* Pcie_ext_rgf 4k */ 147 {0x88b000, 0x88c000, 0x88b000, "rgf_ext", true}, 148 /* mac_ext_rgf 1344b */ 149 {0x88c000, 0x88c540, 0x88c000, "mac_rgf_ext", true}, 150 /* ext USER RGF 4k */ 151 {0x88d000, 0x88e000, 0x88d000, "ext_user_rgf", true}, 152 /* OTP 4k */ 153 {0x8a0000, 0x8a1000, 0x8a0000, "otp", true}, 154 /* DMA EXT RGF 64k */ 155 {0x8b0000, 0x8c0000, 0x8b0000, "dma_ext_rgf", true}, 156 /* upper area 1536k */ 157 {0x900000, 0xa80000, 0x900000, "upper", true}, 158 /* UCODE areas - accessible by debugfs blobs but not by 159 * wmi_addr_remap. UCODE areas MUST be added AFTER FW areas! 160 */ 161 /* ucode code RAM 256k */ 162 {0x000000, 0x040000, 0xa38000, "uc_code", false}, 163 /* ucode data RAM 32k */ 164 {0x800000, 0x808000, 0xa78000, "uc_data", false}, 165 }; 166 167 struct fw_map fw_mapping[MAX_FW_MAPPING_TABLE_SIZE]; 168 169 struct blink_on_off_time led_blink_time[] = { 170 {WIL_LED_BLINK_ON_SLOW_MS, WIL_LED_BLINK_OFF_SLOW_MS}, 171 {WIL_LED_BLINK_ON_MED_MS, WIL_LED_BLINK_OFF_MED_MS}, 172 {WIL_LED_BLINK_ON_FAST_MS, WIL_LED_BLINK_OFF_FAST_MS}, 173 }; 174 175 u8 led_polarity = LED_POLARITY_LOW_ACTIVE; 176 177 /** 178 * return AHB address for given firmware internal (linker) address 179 * @x - internal address 180 * If address have no valid AHB mapping, return 0 181 */ 182 static u32 wmi_addr_remap(u32 x) 183 { 184 uint i; 185 186 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { 187 if (fw_mapping[i].fw && 188 ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to))) 189 return x + fw_mapping[i].host - fw_mapping[i].from; 190 } 191 192 return 0; 193 } 194 195 /** 196 * find fw_mapping entry by section name 197 * @section - section name 198 * 199 * Return pointer to section or NULL if not found 200 */ 201 struct fw_map *wil_find_fw_mapping(const char *section) 202 { 203 int i; 204 205 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) 206 if (fw_mapping[i].name && 207 !strcmp(section, fw_mapping[i].name)) 208 return &fw_mapping[i]; 209 210 return NULL; 211 } 212 213 /** 214 * Check address validity for WMI buffer; remap if needed 215 * @ptr - internal (linker) fw/ucode address 216 * @size - if non zero, validate the block does not 217 * exceed the device memory (bar) 218 * 219 * Valid buffer should be DWORD aligned 220 * 221 * return address for accessing buffer from the host; 222 * if buffer is not valid, return NULL. 223 */ 224 void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr_, u32 size) 225 { 226 u32 off; 227 u32 ptr = le32_to_cpu(ptr_); 228 229 if (ptr % 4) 230 return NULL; 231 232 ptr = wmi_addr_remap(ptr); 233 if (ptr < WIL6210_FW_HOST_OFF) 234 return NULL; 235 236 off = HOSTADDR(ptr); 237 if (off > wil->bar_size - 4) 238 return NULL; 239 if (size && ((off + size > wil->bar_size) || (off + size < off))) 240 return NULL; 241 242 return wil->csr + off; 243 } 244 245 void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) 246 { 247 return wmi_buffer_block(wil, ptr_, 0); 248 } 249 250 /** 251 * Check address validity 252 */ 253 void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr) 254 { 255 u32 off; 256 257 if (ptr % 4) 258 return NULL; 259 260 if (ptr < WIL6210_FW_HOST_OFF) 261 return NULL; 262 263 off = HOSTADDR(ptr); 264 if (off > wil->bar_size - 4) 265 return NULL; 266 267 return wil->csr + off; 268 } 269 270 int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, 271 struct wil6210_mbox_hdr *hdr) 272 { 273 void __iomem *src = wmi_buffer(wil, ptr); 274 275 if (!src) 276 return -EINVAL; 277 278 wil_memcpy_fromio_32(hdr, src, sizeof(*hdr)); 279 280 return 0; 281 } 282 283 static const char *cmdid2name(u16 cmdid) 284 { 285 switch (cmdid) { 286 case WMI_NOTIFY_REQ_CMDID: 287 return "WMI_NOTIFY_REQ_CMD"; 288 case WMI_START_SCAN_CMDID: 289 return "WMI_START_SCAN_CMD"; 290 case WMI_CONNECT_CMDID: 291 return "WMI_CONNECT_CMD"; 292 case WMI_DISCONNECT_CMDID: 293 return "WMI_DISCONNECT_CMD"; 294 case WMI_SW_TX_REQ_CMDID: 295 return "WMI_SW_TX_REQ_CMD"; 296 case WMI_GET_RF_SECTOR_PARAMS_CMDID: 297 return "WMI_GET_RF_SECTOR_PARAMS_CMD"; 298 case WMI_SET_RF_SECTOR_PARAMS_CMDID: 299 return "WMI_SET_RF_SECTOR_PARAMS_CMD"; 300 case WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID: 301 return "WMI_GET_SELECTED_RF_SECTOR_INDEX_CMD"; 302 case WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID: 303 return "WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD"; 304 case WMI_BRP_SET_ANT_LIMIT_CMDID: 305 return "WMI_BRP_SET_ANT_LIMIT_CMD"; 306 case WMI_TOF_SESSION_START_CMDID: 307 return "WMI_TOF_SESSION_START_CMD"; 308 case WMI_AOA_MEAS_CMDID: 309 return "WMI_AOA_MEAS_CMD"; 310 case WMI_PMC_CMDID: 311 return "WMI_PMC_CMD"; 312 case WMI_TOF_GET_TX_RX_OFFSET_CMDID: 313 return "WMI_TOF_GET_TX_RX_OFFSET_CMD"; 314 case WMI_TOF_SET_TX_RX_OFFSET_CMDID: 315 return "WMI_TOF_SET_TX_RX_OFFSET_CMD"; 316 case WMI_VRING_CFG_CMDID: 317 return "WMI_VRING_CFG_CMD"; 318 case WMI_BCAST_VRING_CFG_CMDID: 319 return "WMI_BCAST_VRING_CFG_CMD"; 320 case WMI_TRAFFIC_SUSPEND_CMDID: 321 return "WMI_TRAFFIC_SUSPEND_CMD"; 322 case WMI_TRAFFIC_RESUME_CMDID: 323 return "WMI_TRAFFIC_RESUME_CMD"; 324 case WMI_ECHO_CMDID: 325 return "WMI_ECHO_CMD"; 326 case WMI_SET_MAC_ADDRESS_CMDID: 327 return "WMI_SET_MAC_ADDRESS_CMD"; 328 case WMI_LED_CFG_CMDID: 329 return "WMI_LED_CFG_CMD"; 330 case WMI_PCP_START_CMDID: 331 return "WMI_PCP_START_CMD"; 332 case WMI_PCP_STOP_CMDID: 333 return "WMI_PCP_STOP_CMD"; 334 case WMI_SET_SSID_CMDID: 335 return "WMI_SET_SSID_CMD"; 336 case WMI_GET_SSID_CMDID: 337 return "WMI_GET_SSID_CMD"; 338 case WMI_SET_PCP_CHANNEL_CMDID: 339 return "WMI_SET_PCP_CHANNEL_CMD"; 340 case WMI_GET_PCP_CHANNEL_CMDID: 341 return "WMI_GET_PCP_CHANNEL_CMD"; 342 case WMI_P2P_CFG_CMDID: 343 return "WMI_P2P_CFG_CMD"; 344 case WMI_START_LISTEN_CMDID: 345 return "WMI_START_LISTEN_CMD"; 346 case WMI_START_SEARCH_CMDID: 347 return "WMI_START_SEARCH_CMD"; 348 case WMI_DISCOVERY_STOP_CMDID: 349 return "WMI_DISCOVERY_STOP_CMD"; 350 case WMI_DELETE_CIPHER_KEY_CMDID: 351 return "WMI_DELETE_CIPHER_KEY_CMD"; 352 case WMI_ADD_CIPHER_KEY_CMDID: 353 return "WMI_ADD_CIPHER_KEY_CMD"; 354 case WMI_SET_APPIE_CMDID: 355 return "WMI_SET_APPIE_CMD"; 356 case WMI_CFG_RX_CHAIN_CMDID: 357 return "WMI_CFG_RX_CHAIN_CMD"; 358 case WMI_TEMP_SENSE_CMDID: 359 return "WMI_TEMP_SENSE_CMD"; 360 case WMI_DEL_STA_CMDID: 361 return "WMI_DEL_STA_CMD"; 362 case WMI_DISCONNECT_STA_CMDID: 363 return "WMI_DISCONNECT_STA_CMD"; 364 case WMI_VRING_BA_EN_CMDID: 365 return "WMI_VRING_BA_EN_CMD"; 366 case WMI_VRING_BA_DIS_CMDID: 367 return "WMI_VRING_BA_DIS_CMD"; 368 case WMI_RCP_DELBA_CMDID: 369 return "WMI_RCP_DELBA_CMD"; 370 case WMI_RCP_ADDBA_RESP_CMDID: 371 return "WMI_RCP_ADDBA_RESP_CMD"; 372 case WMI_PS_DEV_PROFILE_CFG_CMDID: 373 return "WMI_PS_DEV_PROFILE_CFG_CMD"; 374 case WMI_SET_MGMT_RETRY_LIMIT_CMDID: 375 return "WMI_SET_MGMT_RETRY_LIMIT_CMD"; 376 case WMI_GET_MGMT_RETRY_LIMIT_CMDID: 377 return "WMI_GET_MGMT_RETRY_LIMIT_CMD"; 378 case WMI_ABORT_SCAN_CMDID: 379 return "WMI_ABORT_SCAN_CMD"; 380 case WMI_NEW_STA_CMDID: 381 return "WMI_NEW_STA_CMD"; 382 case WMI_SET_THERMAL_THROTTLING_CFG_CMDID: 383 return "WMI_SET_THERMAL_THROTTLING_CFG_CMD"; 384 case WMI_GET_THERMAL_THROTTLING_CFG_CMDID: 385 return "WMI_GET_THERMAL_THROTTLING_CFG_CMD"; 386 case WMI_LINK_MAINTAIN_CFG_WRITE_CMDID: 387 return "WMI_LINK_MAINTAIN_CFG_WRITE_CMD"; 388 case WMI_LO_POWER_CALIB_FROM_OTP_CMDID: 389 return "WMI_LO_POWER_CALIB_FROM_OTP_CMD"; 390 case WMI_START_SCHED_SCAN_CMDID: 391 return "WMI_START_SCHED_SCAN_CMD"; 392 case WMI_STOP_SCHED_SCAN_CMDID: 393 return "WMI_STOP_SCHED_SCAN_CMD"; 394 default: 395 return "Untracked CMD"; 396 } 397 } 398 399 static const char *eventid2name(u16 eventid) 400 { 401 switch (eventid) { 402 case WMI_NOTIFY_REQ_DONE_EVENTID: 403 return "WMI_NOTIFY_REQ_DONE_EVENT"; 404 case WMI_DISCONNECT_EVENTID: 405 return "WMI_DISCONNECT_EVENT"; 406 case WMI_SW_TX_COMPLETE_EVENTID: 407 return "WMI_SW_TX_COMPLETE_EVENT"; 408 case WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID: 409 return "WMI_GET_RF_SECTOR_PARAMS_DONE_EVENT"; 410 case WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID: 411 return "WMI_SET_RF_SECTOR_PARAMS_DONE_EVENT"; 412 case WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID: 413 return "WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT"; 414 case WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID: 415 return "WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT"; 416 case WMI_BRP_SET_ANT_LIMIT_EVENTID: 417 return "WMI_BRP_SET_ANT_LIMIT_EVENT"; 418 case WMI_FW_READY_EVENTID: 419 return "WMI_FW_READY_EVENT"; 420 case WMI_TRAFFIC_RESUME_EVENTID: 421 return "WMI_TRAFFIC_RESUME_EVENT"; 422 case WMI_TOF_GET_TX_RX_OFFSET_EVENTID: 423 return "WMI_TOF_GET_TX_RX_OFFSET_EVENT"; 424 case WMI_TOF_SET_TX_RX_OFFSET_EVENTID: 425 return "WMI_TOF_SET_TX_RX_OFFSET_EVENT"; 426 case WMI_VRING_CFG_DONE_EVENTID: 427 return "WMI_VRING_CFG_DONE_EVENT"; 428 case WMI_READY_EVENTID: 429 return "WMI_READY_EVENT"; 430 case WMI_RX_MGMT_PACKET_EVENTID: 431 return "WMI_RX_MGMT_PACKET_EVENT"; 432 case WMI_TX_MGMT_PACKET_EVENTID: 433 return "WMI_TX_MGMT_PACKET_EVENT"; 434 case WMI_SCAN_COMPLETE_EVENTID: 435 return "WMI_SCAN_COMPLETE_EVENT"; 436 case WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENTID: 437 return "WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENT"; 438 case WMI_CONNECT_EVENTID: 439 return "WMI_CONNECT_EVENT"; 440 case WMI_EAPOL_RX_EVENTID: 441 return "WMI_EAPOL_RX_EVENT"; 442 case WMI_BA_STATUS_EVENTID: 443 return "WMI_BA_STATUS_EVENT"; 444 case WMI_RCP_ADDBA_REQ_EVENTID: 445 return "WMI_RCP_ADDBA_REQ_EVENT"; 446 case WMI_DELBA_EVENTID: 447 return "WMI_DELBA_EVENT"; 448 case WMI_VRING_EN_EVENTID: 449 return "WMI_VRING_EN_EVENT"; 450 case WMI_DATA_PORT_OPEN_EVENTID: 451 return "WMI_DATA_PORT_OPEN_EVENT"; 452 case WMI_AOA_MEAS_EVENTID: 453 return "WMI_AOA_MEAS_EVENT"; 454 case WMI_TOF_SESSION_END_EVENTID: 455 return "WMI_TOF_SESSION_END_EVENT"; 456 case WMI_TOF_GET_CAPABILITIES_EVENTID: 457 return "WMI_TOF_GET_CAPABILITIES_EVENT"; 458 case WMI_TOF_SET_LCR_EVENTID: 459 return "WMI_TOF_SET_LCR_EVENT"; 460 case WMI_TOF_SET_LCI_EVENTID: 461 return "WMI_TOF_SET_LCI_EVENT"; 462 case WMI_TOF_FTM_PER_DEST_RES_EVENTID: 463 return "WMI_TOF_FTM_PER_DEST_RES_EVENT"; 464 case WMI_TOF_CHANNEL_INFO_EVENTID: 465 return "WMI_TOF_CHANNEL_INFO_EVENT"; 466 case WMI_TRAFFIC_SUSPEND_EVENTID: 467 return "WMI_TRAFFIC_SUSPEND_EVENT"; 468 case WMI_ECHO_RSP_EVENTID: 469 return "WMI_ECHO_RSP_EVENT"; 470 case WMI_LED_CFG_DONE_EVENTID: 471 return "WMI_LED_CFG_DONE_EVENT"; 472 case WMI_PCP_STARTED_EVENTID: 473 return "WMI_PCP_STARTED_EVENT"; 474 case WMI_PCP_STOPPED_EVENTID: 475 return "WMI_PCP_STOPPED_EVENT"; 476 case WMI_GET_SSID_EVENTID: 477 return "WMI_GET_SSID_EVENT"; 478 case WMI_GET_PCP_CHANNEL_EVENTID: 479 return "WMI_GET_PCP_CHANNEL_EVENT"; 480 case WMI_P2P_CFG_DONE_EVENTID: 481 return "WMI_P2P_CFG_DONE_EVENT"; 482 case WMI_LISTEN_STARTED_EVENTID: 483 return "WMI_LISTEN_STARTED_EVENT"; 484 case WMI_SEARCH_STARTED_EVENTID: 485 return "WMI_SEARCH_STARTED_EVENT"; 486 case WMI_DISCOVERY_STOPPED_EVENTID: 487 return "WMI_DISCOVERY_STOPPED_EVENT"; 488 case WMI_CFG_RX_CHAIN_DONE_EVENTID: 489 return "WMI_CFG_RX_CHAIN_DONE_EVENT"; 490 case WMI_TEMP_SENSE_DONE_EVENTID: 491 return "WMI_TEMP_SENSE_DONE_EVENT"; 492 case WMI_RCP_ADDBA_RESP_SENT_EVENTID: 493 return "WMI_RCP_ADDBA_RESP_SENT_EVENT"; 494 case WMI_PS_DEV_PROFILE_CFG_EVENTID: 495 return "WMI_PS_DEV_PROFILE_CFG_EVENT"; 496 case WMI_SET_MGMT_RETRY_LIMIT_EVENTID: 497 return "WMI_SET_MGMT_RETRY_LIMIT_EVENT"; 498 case WMI_GET_MGMT_RETRY_LIMIT_EVENTID: 499 return "WMI_GET_MGMT_RETRY_LIMIT_EVENT"; 500 case WMI_SET_THERMAL_THROTTLING_CFG_EVENTID: 501 return "WMI_SET_THERMAL_THROTTLING_CFG_EVENT"; 502 case WMI_GET_THERMAL_THROTTLING_CFG_EVENTID: 503 return "WMI_GET_THERMAL_THROTTLING_CFG_EVENT"; 504 case WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID: 505 return "WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENT"; 506 case WMI_LO_POWER_CALIB_FROM_OTP_EVENTID: 507 return "WMI_LO_POWER_CALIB_FROM_OTP_EVENT"; 508 case WMI_START_SCHED_SCAN_EVENTID: 509 return "WMI_START_SCHED_SCAN_EVENT"; 510 case WMI_STOP_SCHED_SCAN_EVENTID: 511 return "WMI_STOP_SCHED_SCAN_EVENT"; 512 case WMI_SCHED_SCAN_RESULT_EVENTID: 513 return "WMI_SCHED_SCAN_RESULT_EVENT"; 514 default: 515 return "Untracked EVENT"; 516 } 517 } 518 519 static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) 520 { 521 struct { 522 struct wil6210_mbox_hdr hdr; 523 struct wmi_cmd_hdr wmi; 524 } __packed cmd = { 525 .hdr = { 526 .type = WIL_MBOX_HDR_TYPE_WMI, 527 .flags = 0, 528 .len = cpu_to_le16(sizeof(cmd.wmi) + len), 529 }, 530 .wmi = { 531 .mid = 0, 532 .command_id = cpu_to_le16(cmdid), 533 }, 534 }; 535 struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx; 536 struct wil6210_mbox_ring_desc d_head; 537 u32 next_head; 538 void __iomem *dst; 539 void __iomem *head = wmi_addr(wil, r->head); 540 uint retry; 541 int rc = 0; 542 543 if (len > r->entry_size - sizeof(cmd)) { 544 wil_err(wil, "WMI size too large: %d bytes, max is %d\n", 545 (int)(sizeof(cmd) + len), r->entry_size); 546 return -ERANGE; 547 } 548 549 might_sleep(); 550 551 if (!test_bit(wil_status_fwready, wil->status)) { 552 wil_err(wil, "WMI: cannot send command while FW not ready\n"); 553 return -EAGAIN; 554 } 555 556 /* Allow sending only suspend / resume commands during susepnd flow */ 557 if ((test_bit(wil_status_suspending, wil->status) || 558 test_bit(wil_status_suspended, wil->status) || 559 test_bit(wil_status_resuming, wil->status)) && 560 ((cmdid != WMI_TRAFFIC_SUSPEND_CMDID) && 561 (cmdid != WMI_TRAFFIC_RESUME_CMDID))) { 562 wil_err(wil, "WMI: reject send_command during suspend\n"); 563 return -EINVAL; 564 } 565 566 if (!head) { 567 wil_err(wil, "WMI head is garbage: 0x%08x\n", r->head); 568 return -EINVAL; 569 } 570 571 wil_halp_vote(wil); 572 573 /* read Tx head till it is not busy */ 574 for (retry = 5; retry > 0; retry--) { 575 wil_memcpy_fromio_32(&d_head, head, sizeof(d_head)); 576 if (d_head.sync == 0) 577 break; 578 msleep(20); 579 } 580 if (d_head.sync != 0) { 581 wil_err(wil, "WMI head busy\n"); 582 rc = -EBUSY; 583 goto out; 584 } 585 /* next head */ 586 next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size); 587 wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head); 588 /* wait till FW finish with previous command */ 589 for (retry = 5; retry > 0; retry--) { 590 if (!test_bit(wil_status_fwready, wil->status)) { 591 wil_err(wil, "WMI: cannot send command while FW not ready\n"); 592 rc = -EAGAIN; 593 goto out; 594 } 595 r->tail = wil_r(wil, RGF_MBOX + 596 offsetof(struct wil6210_mbox_ctl, tx.tail)); 597 if (next_head != r->tail) 598 break; 599 msleep(20); 600 } 601 if (next_head == r->tail) { 602 wil_err(wil, "WMI ring full\n"); 603 rc = -EBUSY; 604 goto out; 605 } 606 dst = wmi_buffer(wil, d_head.addr); 607 if (!dst) { 608 wil_err(wil, "invalid WMI buffer: 0x%08x\n", 609 le32_to_cpu(d_head.addr)); 610 rc = -EAGAIN; 611 goto out; 612 } 613 cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); 614 /* set command */ 615 wil_dbg_wmi(wil, "sending %s (0x%04x) [%d]\n", 616 cmdid2name(cmdid), cmdid, len); 617 wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, 618 sizeof(cmd), true); 619 wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, 620 len, true); 621 wil_memcpy_toio_32(dst, &cmd, sizeof(cmd)); 622 wil_memcpy_toio_32(dst + sizeof(cmd), buf, len); 623 /* mark entry as full */ 624 wil_w(wil, r->head + offsetof(struct wil6210_mbox_ring_desc, sync), 1); 625 /* advance next ptr */ 626 wil_w(wil, RGF_MBOX + offsetof(struct wil6210_mbox_ctl, tx.head), 627 r->head = next_head); 628 629 trace_wil6210_wmi_cmd(&cmd.wmi, buf, len); 630 631 /* interrupt to FW */ 632 wil_w(wil, RGF_USER_USER_ICR + offsetof(struct RGF_ICR, ICS), 633 SW_INT_MBOX); 634 635 out: 636 wil_halp_unvote(wil); 637 return rc; 638 } 639 640 int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) 641 { 642 int rc; 643 644 mutex_lock(&wil->wmi_mutex); 645 rc = __wmi_send(wil, cmdid, buf, len); 646 mutex_unlock(&wil->wmi_mutex); 647 648 return rc; 649 } 650 651 /*=== Event handlers ===*/ 652 static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) 653 { 654 struct wireless_dev *wdev = wil->wdev; 655 struct wmi_ready_event *evt = d; 656 657 wil->n_mids = evt->numof_additional_mids; 658 659 wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n", 660 wil->fw_version, le32_to_cpu(evt->sw_version), 661 evt->mac, wil->n_mids); 662 /* ignore MAC address, we already have it from the boot loader */ 663 strlcpy(wdev->wiphy->fw_version, wil->fw_version, 664 sizeof(wdev->wiphy->fw_version)); 665 666 if (len > offsetof(struct wmi_ready_event, rfc_read_calib_result)) { 667 wil_dbg_wmi(wil, "rfc calibration result %d\n", 668 evt->rfc_read_calib_result); 669 wil->fw_calib_result = evt->rfc_read_calib_result; 670 } 671 wil_set_recovery_state(wil, fw_recovery_idle); 672 set_bit(wil_status_fwready, wil->status); 673 /* let the reset sequence continue */ 674 complete(&wil->wmi_ready); 675 } 676 677 static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) 678 { 679 struct wmi_rx_mgmt_packet_event *data = d; 680 struct wiphy *wiphy = wil_to_wiphy(wil); 681 struct ieee80211_mgmt *rx_mgmt_frame = 682 (struct ieee80211_mgmt *)data->payload; 683 int flen = len - offsetof(struct wmi_rx_mgmt_packet_event, payload); 684 int ch_no; 685 u32 freq; 686 struct ieee80211_channel *channel; 687 s32 signal; 688 __le16 fc; 689 u32 d_len; 690 u16 d_status; 691 692 if (flen < 0) { 693 wil_err(wil, "MGMT Rx: short event, len %d\n", len); 694 return; 695 } 696 697 d_len = le32_to_cpu(data->info.len); 698 if (d_len != flen) { 699 wil_err(wil, 700 "MGMT Rx: length mismatch, d_len %d should be %d\n", 701 d_len, flen); 702 return; 703 } 704 705 ch_no = data->info.channel + 1; 706 freq = ieee80211_channel_to_frequency(ch_no, NL80211_BAND_60GHZ); 707 channel = ieee80211_get_channel(wiphy, freq); 708 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities)) 709 signal = 100 * data->info.rssi; 710 else 711 signal = data->info.sqi; 712 d_status = le16_to_cpu(data->info.status); 713 fc = rx_mgmt_frame->frame_control; 714 715 wil_dbg_wmi(wil, "MGMT Rx: channel %d MCS %d RSSI %d SQI %d%%\n", 716 data->info.channel, data->info.mcs, data->info.rssi, 717 data->info.sqi); 718 wil_dbg_wmi(wil, "status 0x%04x len %d fc 0x%04x\n", d_status, d_len, 719 le16_to_cpu(fc)); 720 wil_dbg_wmi(wil, "qid %d mid %d cid %d\n", 721 data->info.qid, data->info.mid, data->info.cid); 722 wil_hex_dump_wmi("MGMT Rx ", DUMP_PREFIX_OFFSET, 16, 1, rx_mgmt_frame, 723 d_len, true); 724 725 if (!channel) { 726 wil_err(wil, "Frame on unsupported channel\n"); 727 return; 728 } 729 730 if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { 731 struct cfg80211_bss *bss; 732 u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp); 733 u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info); 734 u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int); 735 const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable; 736 size_t ie_len = d_len - offsetof(struct ieee80211_mgmt, 737 u.beacon.variable); 738 wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap); 739 wil_dbg_wmi(wil, "TSF : 0x%016llx\n", tsf); 740 wil_dbg_wmi(wil, "Beacon interval : %d\n", bi); 741 wil_hex_dump_wmi("IE ", DUMP_PREFIX_OFFSET, 16, 1, ie_buf, 742 ie_len, true); 743 744 wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap); 745 746 bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, 747 d_len, signal, GFP_KERNEL); 748 if (bss) { 749 wil_dbg_wmi(wil, "Added BSS %pM\n", 750 rx_mgmt_frame->bssid); 751 cfg80211_put_bss(wiphy, bss); 752 } else { 753 wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); 754 } 755 } else { 756 mutex_lock(&wil->p2p_wdev_mutex); 757 cfg80211_rx_mgmt(wil->radio_wdev, freq, signal, 758 (void *)rx_mgmt_frame, d_len, 0); 759 mutex_unlock(&wil->p2p_wdev_mutex); 760 } 761 } 762 763 static void wmi_evt_tx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) 764 { 765 struct wmi_tx_mgmt_packet_event *data = d; 766 struct ieee80211_mgmt *mgmt_frame = 767 (struct ieee80211_mgmt *)data->payload; 768 int flen = len - offsetof(struct wmi_tx_mgmt_packet_event, payload); 769 770 wil_hex_dump_wmi("MGMT Tx ", DUMP_PREFIX_OFFSET, 16, 1, mgmt_frame, 771 flen, true); 772 } 773 774 static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, 775 void *d, int len) 776 { 777 mutex_lock(&wil->p2p_wdev_mutex); 778 if (wil->scan_request) { 779 struct wmi_scan_complete_event *data = d; 780 int status = le32_to_cpu(data->status); 781 struct cfg80211_scan_info info = { 782 .aborted = ((status != WMI_SCAN_SUCCESS) && 783 (status != WMI_SCAN_ABORT_REJECTED)), 784 }; 785 786 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status); 787 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", 788 wil->scan_request, info.aborted); 789 del_timer_sync(&wil->scan_timer); 790 cfg80211_scan_done(wil->scan_request, &info); 791 wil->radio_wdev = wil->wdev; 792 wil->scan_request = NULL; 793 wake_up_interruptible(&wil->wq); 794 if (wil->p2p.pending_listen_wdev) { 795 wil_dbg_misc(wil, "Scheduling delayed listen\n"); 796 schedule_work(&wil->p2p.delayed_listen_work); 797 } 798 } else { 799 wil_err(wil, "SCAN_COMPLETE while not scanning\n"); 800 } 801 mutex_unlock(&wil->p2p_wdev_mutex); 802 } 803 804 static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) 805 { 806 struct net_device *ndev = wil_to_ndev(wil); 807 struct wireless_dev *wdev = wil->wdev; 808 struct wmi_connect_event *evt = d; 809 int ch; /* channel number */ 810 struct station_info sinfo; 811 u8 *assoc_req_ie, *assoc_resp_ie; 812 size_t assoc_req_ielen, assoc_resp_ielen; 813 /* capinfo(u16) + listen_interval(u16) + IEs */ 814 const size_t assoc_req_ie_offset = sizeof(u16) * 2; 815 /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */ 816 const size_t assoc_resp_ie_offset = sizeof(u16) * 3; 817 int rc; 818 819 if (len < sizeof(*evt)) { 820 wil_err(wil, "Connect event too short : %d bytes\n", len); 821 return; 822 } 823 if (len != sizeof(*evt) + evt->beacon_ie_len + evt->assoc_req_len + 824 evt->assoc_resp_len) { 825 wil_err(wil, 826 "Connect event corrupted : %d != %d + %d + %d + %d\n", 827 len, (int)sizeof(*evt), evt->beacon_ie_len, 828 evt->assoc_req_len, evt->assoc_resp_len); 829 return; 830 } 831 if (evt->cid >= WIL6210_MAX_CID) { 832 wil_err(wil, "Connect CID invalid : %d\n", evt->cid); 833 return; 834 } 835 836 ch = evt->channel + 1; 837 wil_info(wil, "Connect %pM channel [%d] cid %d aid %d\n", 838 evt->bssid, ch, evt->cid, evt->aid); 839 wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1, 840 evt->assoc_info, len - sizeof(*evt), true); 841 842 /* figure out IE's */ 843 assoc_req_ie = &evt->assoc_info[evt->beacon_ie_len + 844 assoc_req_ie_offset]; 845 assoc_req_ielen = evt->assoc_req_len - assoc_req_ie_offset; 846 if (evt->assoc_req_len <= assoc_req_ie_offset) { 847 assoc_req_ie = NULL; 848 assoc_req_ielen = 0; 849 } 850 851 assoc_resp_ie = &evt->assoc_info[evt->beacon_ie_len + 852 evt->assoc_req_len + 853 assoc_resp_ie_offset]; 854 assoc_resp_ielen = evt->assoc_resp_len - assoc_resp_ie_offset; 855 if (evt->assoc_resp_len <= assoc_resp_ie_offset) { 856 assoc_resp_ie = NULL; 857 assoc_resp_ielen = 0; 858 } 859 860 if (test_bit(wil_status_resetting, wil->status) || 861 !test_bit(wil_status_fwready, wil->status)) { 862 wil_err(wil, "status_resetting, cancel connect event, CID %d\n", 863 evt->cid); 864 /* no need for cleanup, wil_reset will do that */ 865 return; 866 } 867 868 mutex_lock(&wil->mutex); 869 870 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 871 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 872 if (!test_bit(wil_status_fwconnecting, wil->status)) { 873 wil_err(wil, "Not in connecting state\n"); 874 mutex_unlock(&wil->mutex); 875 return; 876 } 877 del_timer_sync(&wil->connect_timer); 878 } else if ((wdev->iftype == NL80211_IFTYPE_AP) || 879 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { 880 if (wil->sta[evt->cid].status != wil_sta_unused) { 881 wil_err(wil, "AP: Invalid status %d for CID %d\n", 882 wil->sta[evt->cid].status, evt->cid); 883 mutex_unlock(&wil->mutex); 884 return; 885 } 886 } 887 888 ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid); 889 wil->sta[evt->cid].status = wil_sta_conn_pending; 890 891 rc = wil_tx_init(wil, evt->cid); 892 if (rc) { 893 wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n", 894 evt->cid, rc); 895 wmi_disconnect_sta(wil, wil->sta[evt->cid].addr, 896 WLAN_REASON_UNSPECIFIED, false, false); 897 } else { 898 wil_info(wil, "successful connection to CID %d\n", evt->cid); 899 } 900 901 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 902 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 903 if (rc) { 904 netif_carrier_off(ndev); 905 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); 906 wil_err(wil, "cfg80211_connect_result with failure\n"); 907 cfg80211_connect_result(ndev, evt->bssid, NULL, 0, 908 NULL, 0, 909 WLAN_STATUS_UNSPECIFIED_FAILURE, 910 GFP_KERNEL); 911 goto out; 912 } else { 913 struct wiphy *wiphy = wil_to_wiphy(wil); 914 915 cfg80211_ref_bss(wiphy, wil->bss); 916 cfg80211_connect_bss(ndev, evt->bssid, wil->bss, 917 assoc_req_ie, assoc_req_ielen, 918 assoc_resp_ie, assoc_resp_ielen, 919 WLAN_STATUS_SUCCESS, GFP_KERNEL, 920 NL80211_TIMEOUT_UNSPECIFIED); 921 } 922 wil->bss = NULL; 923 } else if ((wdev->iftype == NL80211_IFTYPE_AP) || 924 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { 925 if (rc) { 926 if (disable_ap_sme) 927 /* notify new_sta has failed */ 928 cfg80211_del_sta(ndev, evt->bssid, GFP_KERNEL); 929 goto out; 930 } 931 932 memset(&sinfo, 0, sizeof(sinfo)); 933 934 sinfo.generation = wil->sinfo_gen++; 935 936 if (assoc_req_ie) { 937 sinfo.assoc_req_ies = assoc_req_ie; 938 sinfo.assoc_req_ies_len = assoc_req_ielen; 939 } 940 941 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); 942 } else { 943 wil_err(wil, "unhandled iftype %d for CID %d\n", wdev->iftype, 944 evt->cid); 945 goto out; 946 } 947 948 wil->sta[evt->cid].status = wil_sta_connected; 949 wil->sta[evt->cid].aid = evt->aid; 950 set_bit(wil_status_fwconnected, wil->status); 951 wil_update_net_queues_bh(wil, NULL, false); 952 953 out: 954 if (rc) 955 wil->sta[evt->cid].status = wil_sta_unused; 956 clear_bit(wil_status_fwconnecting, wil->status); 957 mutex_unlock(&wil->mutex); 958 } 959 960 static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, 961 void *d, int len) 962 { 963 struct wmi_disconnect_event *evt = d; 964 u16 reason_code = le16_to_cpu(evt->protocol_reason_status); 965 966 wil_info(wil, "Disconnect %pM reason [proto %d wmi %d]\n", 967 evt->bssid, reason_code, evt->disconnect_reason); 968 969 wil->sinfo_gen++; 970 971 if (test_bit(wil_status_resetting, wil->status) || 972 !test_bit(wil_status_fwready, wil->status)) { 973 wil_err(wil, "status_resetting, cancel disconnect event\n"); 974 /* no need for cleanup, wil_reset will do that */ 975 return; 976 } 977 978 mutex_lock(&wil->mutex); 979 wil6210_disconnect(wil, evt->bssid, reason_code, true); 980 mutex_unlock(&wil->mutex); 981 } 982 983 /* 984 * Firmware reports EAPOL frame using WME event. 985 * Reconstruct Ethernet frame and deliver it via normal Rx 986 */ 987 static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, 988 void *d, int len) 989 { 990 struct net_device *ndev = wil_to_ndev(wil); 991 struct wmi_eapol_rx_event *evt = d; 992 u16 eapol_len = le16_to_cpu(evt->eapol_len); 993 int sz = eapol_len + ETH_HLEN; 994 struct sk_buff *skb; 995 struct ethhdr *eth; 996 int cid; 997 struct wil_net_stats *stats = NULL; 998 999 wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len, 1000 evt->src_mac); 1001 1002 cid = wil_find_cid(wil, evt->src_mac); 1003 if (cid >= 0) 1004 stats = &wil->sta[cid].stats; 1005 1006 if (eapol_len > 196) { /* TODO: revisit size limit */ 1007 wil_err(wil, "EAPOL too large\n"); 1008 return; 1009 } 1010 1011 skb = alloc_skb(sz, GFP_KERNEL); 1012 if (!skb) { 1013 wil_err(wil, "Failed to allocate skb\n"); 1014 return; 1015 } 1016 1017 eth = skb_put(skb, ETH_HLEN); 1018 ether_addr_copy(eth->h_dest, ndev->dev_addr); 1019 ether_addr_copy(eth->h_source, evt->src_mac); 1020 eth->h_proto = cpu_to_be16(ETH_P_PAE); 1021 skb_put_data(skb, evt->eapol, eapol_len); 1022 skb->protocol = eth_type_trans(skb, ndev); 1023 if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) { 1024 ndev->stats.rx_packets++; 1025 ndev->stats.rx_bytes += sz; 1026 if (stats) { 1027 stats->rx_packets++; 1028 stats->rx_bytes += sz; 1029 } 1030 } else { 1031 ndev->stats.rx_dropped++; 1032 if (stats) 1033 stats->rx_dropped++; 1034 } 1035 } 1036 1037 static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len) 1038 { 1039 struct wmi_vring_en_event *evt = d; 1040 u8 vri = evt->vring_index; 1041 struct wireless_dev *wdev = wil_to_wdev(wil); 1042 1043 wil_dbg_wmi(wil, "Enable vring %d\n", vri); 1044 1045 if (vri >= ARRAY_SIZE(wil->vring_tx)) { 1046 wil_err(wil, "Enable for invalid vring %d\n", vri); 1047 return; 1048 } 1049 1050 if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme) 1051 /* in AP mode with disable_ap_sme, this is done by 1052 * wil_cfg80211_change_station() 1053 */ 1054 wil->vring_tx_data[vri].dot1x_open = true; 1055 if (vri == wil->bcast_vring) /* no BA for bcast */ 1056 return; 1057 if (agg_wsize >= 0) 1058 wil_addba_tx_request(wil, vri, agg_wsize); 1059 } 1060 1061 static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, 1062 int len) 1063 { 1064 struct wmi_ba_status_event *evt = d; 1065 struct vring_tx_data *txdata; 1066 1067 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d AMSDU%s\n", 1068 evt->ringid, 1069 evt->status == WMI_BA_AGREED ? "OK" : "N/A", 1070 evt->agg_wsize, __le16_to_cpu(evt->ba_timeout), 1071 evt->amsdu ? "+" : "-"); 1072 1073 if (evt->ringid >= WIL6210_MAX_TX_RINGS) { 1074 wil_err(wil, "invalid ring id %d\n", evt->ringid); 1075 return; 1076 } 1077 1078 if (evt->status != WMI_BA_AGREED) { 1079 evt->ba_timeout = 0; 1080 evt->agg_wsize = 0; 1081 evt->amsdu = 0; 1082 } 1083 1084 txdata = &wil->vring_tx_data[evt->ringid]; 1085 1086 txdata->agg_timeout = le16_to_cpu(evt->ba_timeout); 1087 txdata->agg_wsize = evt->agg_wsize; 1088 txdata->agg_amsdu = evt->amsdu; 1089 txdata->addba_in_progress = false; 1090 } 1091 1092 static void wmi_evt_addba_rx_req(struct wil6210_priv *wil, int id, void *d, 1093 int len) 1094 { 1095 struct wmi_rcp_addba_req_event *evt = d; 1096 1097 wil_addba_rx_request(wil, evt->cidxtid, evt->dialog_token, 1098 evt->ba_param_set, evt->ba_timeout, 1099 evt->ba_seq_ctrl); 1100 } 1101 1102 static void wmi_evt_delba(struct wil6210_priv *wil, int id, void *d, int len) 1103 __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) 1104 { 1105 struct wmi_delba_event *evt = d; 1106 u8 cid, tid; 1107 u16 reason = __le16_to_cpu(evt->reason); 1108 struct wil_sta_info *sta; 1109 struct wil_tid_ampdu_rx *r; 1110 1111 might_sleep(); 1112 parse_cidxtid(evt->cidxtid, &cid, &tid); 1113 wil_dbg_wmi(wil, "DELBA CID %d TID %d from %s reason %d\n", 1114 cid, tid, 1115 evt->from_initiator ? "originator" : "recipient", 1116 reason); 1117 if (!evt->from_initiator) { 1118 int i; 1119 /* find Tx vring it belongs to */ 1120 for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) { 1121 if ((wil->vring2cid_tid[i][0] == cid) && 1122 (wil->vring2cid_tid[i][1] == tid)) { 1123 struct vring_tx_data *txdata = 1124 &wil->vring_tx_data[i]; 1125 1126 wil_dbg_wmi(wil, "DELBA Tx vring %d\n", i); 1127 txdata->agg_timeout = 0; 1128 txdata->agg_wsize = 0; 1129 txdata->addba_in_progress = false; 1130 1131 break; /* max. 1 matching ring */ 1132 } 1133 } 1134 if (i >= ARRAY_SIZE(wil->vring2cid_tid)) 1135 wil_err(wil, "DELBA: unable to find Tx vring\n"); 1136 return; 1137 } 1138 1139 sta = &wil->sta[cid]; 1140 1141 spin_lock_bh(&sta->tid_rx_lock); 1142 1143 r = sta->tid_rx[tid]; 1144 sta->tid_rx[tid] = NULL; 1145 wil_tid_ampdu_rx_free(wil, r); 1146 1147 spin_unlock_bh(&sta->tid_rx_lock); 1148 } 1149 1150 static void 1151 wmi_evt_sched_scan_result(struct wil6210_priv *wil, int id, void *d, int len) 1152 { 1153 struct wmi_sched_scan_result_event *data = d; 1154 struct wiphy *wiphy = wil_to_wiphy(wil); 1155 struct ieee80211_mgmt *rx_mgmt_frame = 1156 (struct ieee80211_mgmt *)data->payload; 1157 int flen = len - offsetof(struct wmi_sched_scan_result_event, payload); 1158 int ch_no; 1159 u32 freq; 1160 struct ieee80211_channel *channel; 1161 s32 signal; 1162 __le16 fc; 1163 u32 d_len; 1164 struct cfg80211_bss *bss; 1165 1166 if (flen < 0) { 1167 wil_err(wil, "sched scan result event too short, len %d\n", 1168 len); 1169 return; 1170 } 1171 1172 d_len = le32_to_cpu(data->info.len); 1173 if (d_len != flen) { 1174 wil_err(wil, 1175 "sched scan result length mismatch, d_len %d should be %d\n", 1176 d_len, flen); 1177 return; 1178 } 1179 1180 fc = rx_mgmt_frame->frame_control; 1181 if (!ieee80211_is_probe_resp(fc)) { 1182 wil_err(wil, "sched scan result invalid frame, fc 0x%04x\n", 1183 fc); 1184 return; 1185 } 1186 1187 ch_no = data->info.channel + 1; 1188 freq = ieee80211_channel_to_frequency(ch_no, NL80211_BAND_60GHZ); 1189 channel = ieee80211_get_channel(wiphy, freq); 1190 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities)) 1191 signal = 100 * data->info.rssi; 1192 else 1193 signal = data->info.sqi; 1194 1195 wil_dbg_wmi(wil, "sched scan result: channel %d MCS %d RSSI %d\n", 1196 data->info.channel, data->info.mcs, data->info.rssi); 1197 wil_dbg_wmi(wil, "len %d qid %d mid %d cid %d\n", 1198 d_len, data->info.qid, data->info.mid, data->info.cid); 1199 wil_hex_dump_wmi("PROBE ", DUMP_PREFIX_OFFSET, 16, 1, rx_mgmt_frame, 1200 d_len, true); 1201 1202 if (!channel) { 1203 wil_err(wil, "Frame on unsupported channel\n"); 1204 return; 1205 } 1206 1207 bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, 1208 d_len, signal, GFP_KERNEL); 1209 if (bss) { 1210 wil_dbg_wmi(wil, "Added BSS %pM\n", rx_mgmt_frame->bssid); 1211 cfg80211_put_bss(wiphy, bss); 1212 } else { 1213 wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); 1214 } 1215 1216 cfg80211_sched_scan_results(wiphy, 0); 1217 } 1218 1219 /** 1220 * Some events are ignored for purpose; and need not be interpreted as 1221 * "unhandled events" 1222 */ 1223 static void wmi_evt_ignore(struct wil6210_priv *wil, int id, void *d, int len) 1224 { 1225 wil_dbg_wmi(wil, "Ignore event 0x%04x len %d\n", id, len); 1226 } 1227 1228 static const struct { 1229 int eventid; 1230 void (*handler)(struct wil6210_priv *wil, int eventid, 1231 void *data, int data_len); 1232 } wmi_evt_handlers[] = { 1233 {WMI_READY_EVENTID, wmi_evt_ready}, 1234 {WMI_FW_READY_EVENTID, wmi_evt_ignore}, 1235 {WMI_RX_MGMT_PACKET_EVENTID, wmi_evt_rx_mgmt}, 1236 {WMI_TX_MGMT_PACKET_EVENTID, wmi_evt_tx_mgmt}, 1237 {WMI_SCAN_COMPLETE_EVENTID, wmi_evt_scan_complete}, 1238 {WMI_CONNECT_EVENTID, wmi_evt_connect}, 1239 {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, 1240 {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, 1241 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status}, 1242 {WMI_RCP_ADDBA_REQ_EVENTID, wmi_evt_addba_rx_req}, 1243 {WMI_DELBA_EVENTID, wmi_evt_delba}, 1244 {WMI_VRING_EN_EVENTID, wmi_evt_vring_en}, 1245 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_ignore}, 1246 {WMI_SCHED_SCAN_RESULT_EVENTID, wmi_evt_sched_scan_result}, 1247 }; 1248 1249 /* 1250 * Run in IRQ context 1251 * Extract WMI command from mailbox. Queue it to the @wil->pending_wmi_ev 1252 * that will be eventually handled by the @wmi_event_worker in the thread 1253 * context of thread "wil6210_wmi" 1254 */ 1255 void wmi_recv_cmd(struct wil6210_priv *wil) 1256 { 1257 struct wil6210_mbox_ring_desc d_tail; 1258 struct wil6210_mbox_hdr hdr; 1259 struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx; 1260 struct pending_wmi_event *evt; 1261 u8 *cmd; 1262 void __iomem *src; 1263 ulong flags; 1264 unsigned n; 1265 unsigned int num_immed_reply = 0; 1266 1267 if (!test_bit(wil_status_mbox_ready, wil->status)) { 1268 wil_err(wil, "Reset in progress. Cannot handle WMI event\n"); 1269 return; 1270 } 1271 1272 if (test_bit(wil_status_suspended, wil->status)) { 1273 wil_err(wil, "suspended. cannot handle WMI event\n"); 1274 return; 1275 } 1276 1277 for (n = 0;; n++) { 1278 u16 len; 1279 bool q; 1280 bool immed_reply = false; 1281 1282 r->head = wil_r(wil, RGF_MBOX + 1283 offsetof(struct wil6210_mbox_ctl, rx.head)); 1284 if (r->tail == r->head) 1285 break; 1286 1287 wil_dbg_wmi(wil, "Mbox head %08x tail %08x\n", 1288 r->head, r->tail); 1289 /* read cmd descriptor from tail */ 1290 wil_memcpy_fromio_32(&d_tail, wil->csr + HOSTADDR(r->tail), 1291 sizeof(struct wil6210_mbox_ring_desc)); 1292 if (d_tail.sync == 0) { 1293 wil_err(wil, "Mbox evt not owned by FW?\n"); 1294 break; 1295 } 1296 1297 /* read cmd header from descriptor */ 1298 if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) { 1299 wil_err(wil, "Mbox evt at 0x%08x?\n", 1300 le32_to_cpu(d_tail.addr)); 1301 break; 1302 } 1303 len = le16_to_cpu(hdr.len); 1304 wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n", 1305 le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type), 1306 hdr.flags); 1307 1308 /* read cmd buffer from descriptor */ 1309 src = wmi_buffer(wil, d_tail.addr) + 1310 sizeof(struct wil6210_mbox_hdr); 1311 evt = kmalloc(ALIGN(offsetof(struct pending_wmi_event, 1312 event.wmi) + len, 4), 1313 GFP_KERNEL); 1314 if (!evt) 1315 break; 1316 1317 evt->event.hdr = hdr; 1318 cmd = (void *)&evt->event.wmi; 1319 wil_memcpy_fromio_32(cmd, src, len); 1320 /* mark entry as empty */ 1321 wil_w(wil, r->tail + 1322 offsetof(struct wil6210_mbox_ring_desc, sync), 0); 1323 /* indicate */ 1324 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) && 1325 (len >= sizeof(struct wmi_cmd_hdr))) { 1326 struct wmi_cmd_hdr *wmi = &evt->event.wmi; 1327 u16 id = le16_to_cpu(wmi->command_id); 1328 u32 tstamp = le32_to_cpu(wmi->fw_timestamp); 1329 if (test_bit(wil_status_resuming, wil->status)) { 1330 if (id == WMI_TRAFFIC_RESUME_EVENTID) 1331 clear_bit(wil_status_resuming, 1332 wil->status); 1333 else 1334 wil_err(wil, 1335 "WMI evt %d while resuming\n", 1336 id); 1337 } 1338 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 1339 if (wil->reply_id && wil->reply_id == id) { 1340 if (wil->reply_buf) { 1341 memcpy(wil->reply_buf, wmi, 1342 min(len, wil->reply_size)); 1343 immed_reply = true; 1344 } 1345 if (id == WMI_TRAFFIC_SUSPEND_EVENTID) { 1346 wil_dbg_wmi(wil, 1347 "set suspend_resp_rcvd\n"); 1348 wil->suspend_resp_rcvd = true; 1349 } 1350 } 1351 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 1352 1353 wil_dbg_wmi(wil, "recv %s (0x%04x) MID %d @%d msec\n", 1354 eventid2name(id), id, wmi->mid, tstamp); 1355 trace_wil6210_wmi_event(wmi, &wmi[1], 1356 len - sizeof(*wmi)); 1357 } 1358 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1, 1359 &evt->event.hdr, sizeof(hdr) + len, true); 1360 1361 /* advance tail */ 1362 r->tail = r->base + ((r->tail - r->base + 1363 sizeof(struct wil6210_mbox_ring_desc)) % r->size); 1364 wil_w(wil, RGF_MBOX + 1365 offsetof(struct wil6210_mbox_ctl, rx.tail), r->tail); 1366 1367 if (immed_reply) { 1368 wil_dbg_wmi(wil, "recv_cmd: Complete WMI 0x%04x\n", 1369 wil->reply_id); 1370 kfree(evt); 1371 num_immed_reply++; 1372 complete(&wil->wmi_call); 1373 } else { 1374 /* add to the pending list */ 1375 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 1376 list_add_tail(&evt->list, &wil->pending_wmi_ev); 1377 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 1378 q = queue_work(wil->wmi_wq, &wil->wmi_event_worker); 1379 wil_dbg_wmi(wil, "queue_work -> %d\n", q); 1380 } 1381 } 1382 /* normally, 1 event per IRQ should be processed */ 1383 wil_dbg_wmi(wil, "recv_cmd: -> %d events queued, %d completed\n", 1384 n - num_immed_reply, num_immed_reply); 1385 } 1386 1387 int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 1388 u16 reply_id, void *reply, u8 reply_size, int to_msec) 1389 { 1390 int rc; 1391 unsigned long remain; 1392 1393 mutex_lock(&wil->wmi_mutex); 1394 1395 spin_lock(&wil->wmi_ev_lock); 1396 wil->reply_id = reply_id; 1397 wil->reply_buf = reply; 1398 wil->reply_size = reply_size; 1399 reinit_completion(&wil->wmi_call); 1400 spin_unlock(&wil->wmi_ev_lock); 1401 1402 rc = __wmi_send(wil, cmdid, buf, len); 1403 if (rc) 1404 goto out; 1405 1406 remain = wait_for_completion_timeout(&wil->wmi_call, 1407 msecs_to_jiffies(to_msec)); 1408 if (0 == remain) { 1409 wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n", 1410 cmdid, reply_id, to_msec); 1411 rc = -ETIME; 1412 } else { 1413 wil_dbg_wmi(wil, 1414 "wmi_call(0x%04x->0x%04x) completed in %d msec\n", 1415 cmdid, reply_id, 1416 to_msec - jiffies_to_msecs(remain)); 1417 } 1418 1419 out: 1420 spin_lock(&wil->wmi_ev_lock); 1421 wil->reply_id = 0; 1422 wil->reply_buf = NULL; 1423 wil->reply_size = 0; 1424 spin_unlock(&wil->wmi_ev_lock); 1425 1426 mutex_unlock(&wil->wmi_mutex); 1427 1428 return rc; 1429 } 1430 1431 int wmi_echo(struct wil6210_priv *wil) 1432 { 1433 struct wmi_echo_cmd cmd = { 1434 .value = cpu_to_le32(0x12345678), 1435 }; 1436 1437 return wmi_call(wil, WMI_ECHO_CMDID, &cmd, sizeof(cmd), 1438 WMI_ECHO_RSP_EVENTID, NULL, 0, 50); 1439 } 1440 1441 int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) 1442 { 1443 struct wmi_set_mac_address_cmd cmd; 1444 1445 ether_addr_copy(cmd.mac, addr); 1446 1447 wil_dbg_wmi(wil, "Set MAC %pM\n", addr); 1448 1449 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); 1450 } 1451 1452 int wmi_led_cfg(struct wil6210_priv *wil, bool enable) 1453 { 1454 int rc = 0; 1455 struct wmi_led_cfg_cmd cmd = { 1456 .led_mode = enable, 1457 .id = led_id, 1458 .slow_blink_cfg.blink_on = 1459 cpu_to_le32(led_blink_time[WIL_LED_TIME_SLOW].on_ms), 1460 .slow_blink_cfg.blink_off = 1461 cpu_to_le32(led_blink_time[WIL_LED_TIME_SLOW].off_ms), 1462 .medium_blink_cfg.blink_on = 1463 cpu_to_le32(led_blink_time[WIL_LED_TIME_MED].on_ms), 1464 .medium_blink_cfg.blink_off = 1465 cpu_to_le32(led_blink_time[WIL_LED_TIME_MED].off_ms), 1466 .fast_blink_cfg.blink_on = 1467 cpu_to_le32(led_blink_time[WIL_LED_TIME_FAST].on_ms), 1468 .fast_blink_cfg.blink_off = 1469 cpu_to_le32(led_blink_time[WIL_LED_TIME_FAST].off_ms), 1470 .led_polarity = led_polarity, 1471 }; 1472 struct { 1473 struct wmi_cmd_hdr wmi; 1474 struct wmi_led_cfg_done_event evt; 1475 } __packed reply; 1476 1477 if (led_id == WIL_LED_INVALID_ID) 1478 goto out; 1479 1480 if (led_id > WIL_LED_MAX_ID) { 1481 wil_err(wil, "Invalid led id %d\n", led_id); 1482 rc = -EINVAL; 1483 goto out; 1484 } 1485 1486 wil_dbg_wmi(wil, 1487 "%s led %d\n", 1488 enable ? "enabling" : "disabling", led_id); 1489 1490 rc = wmi_call(wil, WMI_LED_CFG_CMDID, &cmd, sizeof(cmd), 1491 WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply), 1492 100); 1493 if (rc) 1494 goto out; 1495 1496 if (reply.evt.status) { 1497 wil_err(wil, "led %d cfg failed with status %d\n", 1498 led_id, le32_to_cpu(reply.evt.status)); 1499 rc = -EINVAL; 1500 } 1501 1502 out: 1503 return rc; 1504 } 1505 1506 int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, 1507 u8 chan, u8 hidden_ssid, u8 is_go) 1508 { 1509 int rc; 1510 1511 struct wmi_pcp_start_cmd cmd = { 1512 .bcon_interval = cpu_to_le16(bi), 1513 .network_type = wmi_nettype, 1514 .disable_sec_offload = 1, 1515 .channel = chan - 1, 1516 .pcp_max_assoc_sta = max_assoc_sta, 1517 .hidden_ssid = hidden_ssid, 1518 .is_go = is_go, 1519 .disable_ap_sme = disable_ap_sme, 1520 .abft_len = wil->abft_len, 1521 }; 1522 struct { 1523 struct wmi_cmd_hdr wmi; 1524 struct wmi_pcp_started_event evt; 1525 } __packed reply; 1526 1527 if (!wil->privacy) 1528 cmd.disable_sec = 1; 1529 1530 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || 1531 (cmd.pcp_max_assoc_sta <= 0)) { 1532 wil_info(wil, 1533 "Requested connection limit %u, valid values are 1 - %d. Setting to %d\n", 1534 max_assoc_sta, WIL6210_MAX_CID, WIL6210_MAX_CID); 1535 cmd.pcp_max_assoc_sta = WIL6210_MAX_CID; 1536 } 1537 1538 if (disable_ap_sme && 1539 !test_bit(WMI_FW_CAPABILITY_DISABLE_AP_SME, 1540 wil->fw_capabilities)) { 1541 wil_err(wil, "disable_ap_sme not supported by FW\n"); 1542 return -EOPNOTSUPP; 1543 } 1544 1545 /* 1546 * Processing time may be huge, in case of secure AP it takes about 1547 * 3500ms for FW to start AP 1548 */ 1549 rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd), 1550 WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000); 1551 if (rc) 1552 return rc; 1553 1554 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) 1555 rc = -EINVAL; 1556 1557 if (wmi_nettype != WMI_NETTYPE_P2P) 1558 /* Don't fail due to error in the led configuration */ 1559 wmi_led_cfg(wil, true); 1560 1561 return rc; 1562 } 1563 1564 int wmi_pcp_stop(struct wil6210_priv *wil) 1565 { 1566 int rc; 1567 1568 rc = wmi_led_cfg(wil, false); 1569 if (rc) 1570 return rc; 1571 1572 return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0, 1573 WMI_PCP_STOPPED_EVENTID, NULL, 0, 20); 1574 } 1575 1576 int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) 1577 { 1578 struct wmi_set_ssid_cmd cmd = { 1579 .ssid_len = cpu_to_le32(ssid_len), 1580 }; 1581 1582 if (ssid_len > sizeof(cmd.ssid)) 1583 return -EINVAL; 1584 1585 memcpy(cmd.ssid, ssid, ssid_len); 1586 1587 return wmi_send(wil, WMI_SET_SSID_CMDID, &cmd, sizeof(cmd)); 1588 } 1589 1590 int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid) 1591 { 1592 int rc; 1593 struct { 1594 struct wmi_cmd_hdr wmi; 1595 struct wmi_set_ssid_cmd cmd; 1596 } __packed reply; 1597 int len; /* reply.cmd.ssid_len in CPU order */ 1598 1599 rc = wmi_call(wil, WMI_GET_SSID_CMDID, NULL, 0, WMI_GET_SSID_EVENTID, 1600 &reply, sizeof(reply), 20); 1601 if (rc) 1602 return rc; 1603 1604 len = le32_to_cpu(reply.cmd.ssid_len); 1605 if (len > sizeof(reply.cmd.ssid)) 1606 return -EINVAL; 1607 1608 *ssid_len = len; 1609 memcpy(ssid, reply.cmd.ssid, len); 1610 1611 return 0; 1612 } 1613 1614 int wmi_set_channel(struct wil6210_priv *wil, int channel) 1615 { 1616 struct wmi_set_pcp_channel_cmd cmd = { 1617 .channel = channel - 1, 1618 }; 1619 1620 return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, &cmd, sizeof(cmd)); 1621 } 1622 1623 int wmi_get_channel(struct wil6210_priv *wil, int *channel) 1624 { 1625 int rc; 1626 struct { 1627 struct wmi_cmd_hdr wmi; 1628 struct wmi_set_pcp_channel_cmd cmd; 1629 } __packed reply; 1630 1631 rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, NULL, 0, 1632 WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20); 1633 if (rc) 1634 return rc; 1635 1636 if (reply.cmd.channel > 3) 1637 return -EINVAL; 1638 1639 *channel = reply.cmd.channel + 1; 1640 1641 return 0; 1642 } 1643 1644 int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi) 1645 { 1646 int rc; 1647 struct wmi_p2p_cfg_cmd cmd = { 1648 .discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER, 1649 .bcon_interval = cpu_to_le16(bi), 1650 .channel = channel - 1, 1651 }; 1652 struct { 1653 struct wmi_cmd_hdr wmi; 1654 struct wmi_p2p_cfg_done_event evt; 1655 } __packed reply; 1656 1657 wil_dbg_wmi(wil, "sending WMI_P2P_CFG_CMDID\n"); 1658 1659 rc = wmi_call(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd), 1660 WMI_P2P_CFG_DONE_EVENTID, &reply, sizeof(reply), 300); 1661 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 1662 wil_err(wil, "P2P_CFG failed. status %d\n", reply.evt.status); 1663 rc = -EINVAL; 1664 } 1665 1666 return rc; 1667 } 1668 1669 int wmi_start_listen(struct wil6210_priv *wil) 1670 { 1671 int rc; 1672 struct { 1673 struct wmi_cmd_hdr wmi; 1674 struct wmi_listen_started_event evt; 1675 } __packed reply; 1676 1677 wil_dbg_wmi(wil, "sending WMI_START_LISTEN_CMDID\n"); 1678 1679 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0, 1680 WMI_LISTEN_STARTED_EVENTID, &reply, sizeof(reply), 300); 1681 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 1682 wil_err(wil, "device failed to start listen. status %d\n", 1683 reply.evt.status); 1684 rc = -EINVAL; 1685 } 1686 1687 return rc; 1688 } 1689 1690 int wmi_start_search(struct wil6210_priv *wil) 1691 { 1692 int rc; 1693 struct { 1694 struct wmi_cmd_hdr wmi; 1695 struct wmi_search_started_event evt; 1696 } __packed reply; 1697 1698 wil_dbg_wmi(wil, "sending WMI_START_SEARCH_CMDID\n"); 1699 1700 rc = wmi_call(wil, WMI_START_SEARCH_CMDID, NULL, 0, 1701 WMI_SEARCH_STARTED_EVENTID, &reply, sizeof(reply), 300); 1702 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 1703 wil_err(wil, "device failed to start search. status %d\n", 1704 reply.evt.status); 1705 rc = -EINVAL; 1706 } 1707 1708 return rc; 1709 } 1710 1711 int wmi_stop_discovery(struct wil6210_priv *wil) 1712 { 1713 int rc; 1714 1715 wil_dbg_wmi(wil, "sending WMI_DISCOVERY_STOP_CMDID\n"); 1716 1717 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0, 1718 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 100); 1719 1720 if (rc) 1721 wil_err(wil, "Failed to stop discovery\n"); 1722 1723 return rc; 1724 } 1725 1726 int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, 1727 const void *mac_addr, int key_usage) 1728 { 1729 struct wmi_delete_cipher_key_cmd cmd = { 1730 .key_index = key_index, 1731 }; 1732 1733 if (mac_addr) 1734 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); 1735 1736 return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); 1737 } 1738 1739 int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, 1740 const void *mac_addr, int key_len, const void *key, 1741 int key_usage) 1742 { 1743 struct wmi_add_cipher_key_cmd cmd = { 1744 .key_index = key_index, 1745 .key_usage = key_usage, 1746 .key_len = key_len, 1747 }; 1748 1749 if (!key || (key_len > sizeof(cmd.key))) 1750 return -EINVAL; 1751 1752 memcpy(cmd.key, key, key_len); 1753 if (mac_addr) 1754 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); 1755 1756 return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); 1757 } 1758 1759 int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) 1760 { 1761 static const char *const names[] = { 1762 [WMI_FRAME_BEACON] = "BEACON", 1763 [WMI_FRAME_PROBE_REQ] = "PROBE_REQ", 1764 [WMI_FRAME_PROBE_RESP] = "WMI_FRAME_PROBE_RESP", 1765 [WMI_FRAME_ASSOC_REQ] = "WMI_FRAME_ASSOC_REQ", 1766 [WMI_FRAME_ASSOC_RESP] = "WMI_FRAME_ASSOC_RESP", 1767 }; 1768 int rc; 1769 u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; 1770 struct wmi_set_appie_cmd *cmd; 1771 1772 if (len < ie_len) { 1773 rc = -EINVAL; 1774 goto out; 1775 } 1776 1777 cmd = kzalloc(len, GFP_KERNEL); 1778 if (!cmd) { 1779 rc = -ENOMEM; 1780 goto out; 1781 } 1782 if (!ie) 1783 ie_len = 0; 1784 1785 cmd->mgmt_frm_type = type; 1786 /* BUG: FW API define ieLen as u8. Will fix FW */ 1787 cmd->ie_len = cpu_to_le16(ie_len); 1788 memcpy(cmd->ie_info, ie, ie_len); 1789 rc = wmi_send(wil, WMI_SET_APPIE_CMDID, cmd, len); 1790 kfree(cmd); 1791 out: 1792 if (rc) { 1793 const char *name = type < ARRAY_SIZE(names) ? 1794 names[type] : "??"; 1795 wil_err(wil, "set_ie(%d %s) failed : %d\n", type, name, rc); 1796 } 1797 1798 return rc; 1799 } 1800 1801 /** 1802 * wmi_rxon - turn radio on/off 1803 * @on: turn on if true, off otherwise 1804 * 1805 * Only switch radio. Channel should be set separately. 1806 * No timeout for rxon - radio turned on forever unless some other call 1807 * turns it off 1808 */ 1809 int wmi_rxon(struct wil6210_priv *wil, bool on) 1810 { 1811 int rc; 1812 struct { 1813 struct wmi_cmd_hdr wmi; 1814 struct wmi_listen_started_event evt; 1815 } __packed reply; 1816 1817 wil_info(wil, "(%s)\n", on ? "on" : "off"); 1818 1819 if (on) { 1820 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0, 1821 WMI_LISTEN_STARTED_EVENTID, 1822 &reply, sizeof(reply), 100); 1823 if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS)) 1824 rc = -EINVAL; 1825 } else { 1826 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0, 1827 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20); 1828 } 1829 1830 return rc; 1831 } 1832 1833 int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) 1834 { 1835 struct wireless_dev *wdev = wil->wdev; 1836 struct net_device *ndev = wil_to_ndev(wil); 1837 struct wmi_cfg_rx_chain_cmd cmd = { 1838 .action = WMI_RX_CHAIN_ADD, 1839 .rx_sw_ring = { 1840 .max_mpdu_size = cpu_to_le16( 1841 wil_mtu2macbuf(wil->rx_buf_len)), 1842 .ring_mem_base = cpu_to_le64(vring->pa), 1843 .ring_size = cpu_to_le16(vring->size), 1844 }, 1845 .mid = 0, /* TODO - what is it? */ 1846 .decap_trans_type = WMI_DECAP_TYPE_802_3, 1847 .reorder_type = WMI_RX_SW_REORDER, 1848 .host_thrsh = cpu_to_le16(rx_ring_overflow_thrsh), 1849 }; 1850 struct { 1851 struct wmi_cmd_hdr wmi; 1852 struct wmi_cfg_rx_chain_done_event evt; 1853 } __packed evt; 1854 int rc; 1855 1856 if (wdev->iftype == NL80211_IFTYPE_MONITOR) { 1857 struct ieee80211_channel *ch = wil->monitor_chandef.chan; 1858 1859 cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON); 1860 if (ch) 1861 cmd.sniffer_cfg.channel = ch->hw_value - 1; 1862 cmd.sniffer_cfg.phy_info_mode = 1863 cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP); 1864 cmd.sniffer_cfg.phy_support = 1865 cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL) 1866 ? WMI_SNIFFER_CP : WMI_SNIFFER_BOTH_PHYS); 1867 } else { 1868 /* Initialize offload (in non-sniffer mode). 1869 * Linux IP stack always calculates IP checksum 1870 * HW always calculate TCP/UDP checksum 1871 */ 1872 cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS); 1873 } 1874 1875 if (rx_align_2) 1876 cmd.l2_802_3_offload_ctrl |= 1877 L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK; 1878 1879 /* typical time for secure PCP is 840ms */ 1880 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), 1881 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); 1882 if (rc) 1883 return rc; 1884 1885 vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr); 1886 1887 wil_dbg_misc(wil, "Rx init: status %d tail 0x%08x\n", 1888 le32_to_cpu(evt.evt.status), vring->hwtail); 1889 1890 if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS) 1891 rc = -EINVAL; 1892 1893 return rc; 1894 } 1895 1896 int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) 1897 { 1898 int rc; 1899 struct wmi_temp_sense_cmd cmd = { 1900 .measure_baseband_en = cpu_to_le32(!!t_bb), 1901 .measure_rf_en = cpu_to_le32(!!t_rf), 1902 .measure_mode = cpu_to_le32(TEMPERATURE_MEASURE_NOW), 1903 }; 1904 struct { 1905 struct wmi_cmd_hdr wmi; 1906 struct wmi_temp_sense_done_event evt; 1907 } __packed reply; 1908 1909 rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, &cmd, sizeof(cmd), 1910 WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100); 1911 if (rc) 1912 return rc; 1913 1914 if (t_bb) 1915 *t_bb = le32_to_cpu(reply.evt.baseband_t1000); 1916 if (t_rf) 1917 *t_rf = le32_to_cpu(reply.evt.rf_t1000); 1918 1919 return 0; 1920 } 1921 1922 int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, 1923 u16 reason, bool full_disconnect, bool del_sta) 1924 { 1925 int rc; 1926 u16 reason_code; 1927 struct wmi_disconnect_sta_cmd disc_sta_cmd = { 1928 .disconnect_reason = cpu_to_le16(reason), 1929 }; 1930 struct wmi_del_sta_cmd del_sta_cmd = { 1931 .disconnect_reason = cpu_to_le16(reason), 1932 }; 1933 struct { 1934 struct wmi_cmd_hdr wmi; 1935 struct wmi_disconnect_event evt; 1936 } __packed reply; 1937 1938 wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason); 1939 1940 wil->locally_generated_disc = true; 1941 if (del_sta) { 1942 ether_addr_copy(del_sta_cmd.dst_mac, mac); 1943 rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd, 1944 sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID, 1945 &reply, sizeof(reply), 1000); 1946 } else { 1947 ether_addr_copy(disc_sta_cmd.dst_mac, mac); 1948 rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &disc_sta_cmd, 1949 sizeof(disc_sta_cmd), WMI_DISCONNECT_EVENTID, 1950 &reply, sizeof(reply), 1000); 1951 } 1952 /* failure to disconnect in reasonable time treated as FW error */ 1953 if (rc) { 1954 wil_fw_error_recovery(wil); 1955 return rc; 1956 } 1957 1958 if (full_disconnect) { 1959 /* call event handler manually after processing wmi_call, 1960 * to avoid deadlock - disconnect event handler acquires 1961 * wil->mutex while it is already held here 1962 */ 1963 reason_code = le16_to_cpu(reply.evt.protocol_reason_status); 1964 1965 wil_dbg_wmi(wil, "Disconnect %pM reason [proto %d wmi %d]\n", 1966 reply.evt.bssid, reason_code, 1967 reply.evt.disconnect_reason); 1968 1969 wil->sinfo_gen++; 1970 wil6210_disconnect(wil, reply.evt.bssid, reason_code, true); 1971 } 1972 return 0; 1973 } 1974 1975 int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout) 1976 { 1977 struct wmi_vring_ba_en_cmd cmd = { 1978 .ringid = ringid, 1979 .agg_max_wsize = size, 1980 .ba_timeout = cpu_to_le16(timeout), 1981 .amsdu = 0, 1982 }; 1983 1984 wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d)\n", ringid, size, 1985 timeout); 1986 1987 return wmi_send(wil, WMI_VRING_BA_EN_CMDID, &cmd, sizeof(cmd)); 1988 } 1989 1990 int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason) 1991 { 1992 struct wmi_vring_ba_dis_cmd cmd = { 1993 .ringid = ringid, 1994 .reason = cpu_to_le16(reason), 1995 }; 1996 1997 wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason); 1998 1999 return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, &cmd, sizeof(cmd)); 2000 } 2001 2002 int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason) 2003 { 2004 struct wmi_rcp_delba_cmd cmd = { 2005 .cidxtid = cidxtid, 2006 .reason = cpu_to_le16(reason), 2007 }; 2008 2009 wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf, 2010 (cidxtid >> 4) & 0xf, reason); 2011 2012 return wmi_send(wil, WMI_RCP_DELBA_CMDID, &cmd, sizeof(cmd)); 2013 } 2014 2015 int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, 2016 u16 status, bool amsdu, u16 agg_wsize, u16 timeout) 2017 { 2018 int rc; 2019 struct wmi_rcp_addba_resp_cmd cmd = { 2020 .cidxtid = mk_cidxtid(cid, tid), 2021 .dialog_token = token, 2022 .status_code = cpu_to_le16(status), 2023 /* bit 0: A-MSDU supported 2024 * bit 1: policy (should be 0 for us) 2025 * bits 2..5: TID 2026 * bits 6..15: buffer size 2027 */ 2028 .ba_param_set = cpu_to_le16((amsdu ? 1 : 0) | (tid << 2) | 2029 (agg_wsize << 6)), 2030 .ba_timeout = cpu_to_le16(timeout), 2031 }; 2032 struct { 2033 struct wmi_cmd_hdr wmi; 2034 struct wmi_rcp_addba_resp_sent_event evt; 2035 } __packed reply; 2036 2037 wil_dbg_wmi(wil, 2038 "ADDBA response for CID %d TID %d size %d timeout %d status %d AMSDU%s\n", 2039 cid, tid, agg_wsize, timeout, status, amsdu ? "+" : "-"); 2040 2041 rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, &cmd, sizeof(cmd), 2042 WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), 2043 100); 2044 if (rc) 2045 return rc; 2046 2047 if (reply.evt.status) { 2048 wil_err(wil, "ADDBA response failed with status %d\n", 2049 le16_to_cpu(reply.evt.status)); 2050 rc = -EINVAL; 2051 } 2052 2053 return rc; 2054 } 2055 2056 int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, 2057 enum wmi_ps_profile_type ps_profile) 2058 { 2059 int rc; 2060 struct wmi_ps_dev_profile_cfg_cmd cmd = { 2061 .ps_profile = ps_profile, 2062 }; 2063 struct { 2064 struct wmi_cmd_hdr wmi; 2065 struct wmi_ps_dev_profile_cfg_event evt; 2066 } __packed reply; 2067 u32 status; 2068 2069 wil_dbg_wmi(wil, "Setting ps dev profile %d\n", ps_profile); 2070 2071 reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR); 2072 2073 rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, &cmd, sizeof(cmd), 2074 WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply), 2075 100); 2076 if (rc) 2077 return rc; 2078 2079 status = le32_to_cpu(reply.evt.status); 2080 2081 if (status != WMI_PS_CFG_CMD_STATUS_SUCCESS) { 2082 wil_err(wil, "ps dev profile cfg failed with status %d\n", 2083 status); 2084 rc = -EINVAL; 2085 } 2086 2087 return rc; 2088 } 2089 2090 int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) 2091 { 2092 int rc; 2093 struct wmi_set_mgmt_retry_limit_cmd cmd = { 2094 .mgmt_retry_limit = retry_short, 2095 }; 2096 struct { 2097 struct wmi_cmd_hdr wmi; 2098 struct wmi_set_mgmt_retry_limit_event evt; 2099 } __packed reply; 2100 2101 wil_dbg_wmi(wil, "Setting mgmt retry short %d\n", retry_short); 2102 2103 if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities)) 2104 return -ENOTSUPP; 2105 2106 reply.evt.status = WMI_FW_STATUS_FAILURE; 2107 2108 rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, &cmd, sizeof(cmd), 2109 WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), 2110 100); 2111 if (rc) 2112 return rc; 2113 2114 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 2115 wil_err(wil, "set mgmt retry limit failed with status %d\n", 2116 reply.evt.status); 2117 rc = -EINVAL; 2118 } 2119 2120 return rc; 2121 } 2122 2123 int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) 2124 { 2125 int rc; 2126 struct { 2127 struct wmi_cmd_hdr wmi; 2128 struct wmi_get_mgmt_retry_limit_event evt; 2129 } __packed reply; 2130 2131 wil_dbg_wmi(wil, "getting mgmt retry short\n"); 2132 2133 if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities)) 2134 return -ENOTSUPP; 2135 2136 reply.evt.mgmt_retry_limit = 0; 2137 rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, NULL, 0, 2138 WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), 2139 100); 2140 if (rc) 2141 return rc; 2142 2143 if (retry_short) 2144 *retry_short = reply.evt.mgmt_retry_limit; 2145 2146 return 0; 2147 } 2148 2149 int wmi_abort_scan(struct wil6210_priv *wil) 2150 { 2151 int rc; 2152 2153 wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n"); 2154 2155 rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, NULL, 0); 2156 if (rc) 2157 wil_err(wil, "Failed to abort scan (%d)\n", rc); 2158 2159 return rc; 2160 } 2161 2162 int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid) 2163 { 2164 int rc; 2165 struct wmi_new_sta_cmd cmd = { 2166 .aid = aid, 2167 }; 2168 2169 wil_dbg_wmi(wil, "new sta %pM, aid %d\n", mac, aid); 2170 2171 ether_addr_copy(cmd.dst_mac, mac); 2172 2173 rc = wmi_send(wil, WMI_NEW_STA_CMDID, &cmd, sizeof(cmd)); 2174 if (rc) 2175 wil_err(wil, "Failed to send new sta (%d)\n", rc); 2176 2177 return rc; 2178 } 2179 2180 void wmi_event_flush(struct wil6210_priv *wil) 2181 { 2182 ulong flags; 2183 struct pending_wmi_event *evt, *t; 2184 2185 wil_dbg_wmi(wil, "event_flush\n"); 2186 2187 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 2188 2189 list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) { 2190 list_del(&evt->list); 2191 kfree(evt); 2192 } 2193 2194 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 2195 } 2196 2197 static const char *suspend_status2name(u8 status) 2198 { 2199 switch (status) { 2200 case WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE: 2201 return "LINK_NOT_IDLE"; 2202 default: 2203 return "Untracked status"; 2204 } 2205 } 2206 2207 int wmi_suspend(struct wil6210_priv *wil) 2208 { 2209 int rc; 2210 struct wmi_traffic_suspend_cmd cmd = { 2211 .wakeup_trigger = wil->wakeup_trigger, 2212 }; 2213 struct { 2214 struct wmi_cmd_hdr wmi; 2215 struct wmi_traffic_suspend_event evt; 2216 } __packed reply; 2217 u32 suspend_to = WIL_WAIT_FOR_SUSPEND_RESUME_COMP; 2218 2219 wil->suspend_resp_rcvd = false; 2220 wil->suspend_resp_comp = false; 2221 2222 reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE; 2223 2224 rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, &cmd, sizeof(cmd), 2225 WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply), 2226 suspend_to); 2227 if (rc) { 2228 wil_err(wil, "wmi_call for suspend req failed, rc=%d\n", rc); 2229 if (rc == -ETIME) 2230 /* wmi_call TO */ 2231 wil->suspend_stats.rejected_by_device++; 2232 else 2233 wil->suspend_stats.rejected_by_host++; 2234 goto out; 2235 } 2236 2237 wil_dbg_wmi(wil, "waiting for suspend_response_completed\n"); 2238 2239 rc = wait_event_interruptible_timeout(wil->wq, 2240 wil->suspend_resp_comp, 2241 msecs_to_jiffies(suspend_to)); 2242 if (rc == 0) { 2243 wil_err(wil, "TO waiting for suspend_response_completed\n"); 2244 if (wil->suspend_resp_rcvd) 2245 /* Device responded but we TO due to another reason */ 2246 wil->suspend_stats.rejected_by_host++; 2247 else 2248 wil->suspend_stats.rejected_by_device++; 2249 rc = -EBUSY; 2250 goto out; 2251 } 2252 2253 wil_dbg_wmi(wil, "suspend_response_completed rcvd\n"); 2254 if (reply.evt.status != WMI_TRAFFIC_SUSPEND_APPROVED) { 2255 wil_dbg_pm(wil, "device rejected the suspend, %s\n", 2256 suspend_status2name(reply.evt.status)); 2257 wil->suspend_stats.rejected_by_device++; 2258 } 2259 rc = reply.evt.status; 2260 2261 out: 2262 wil->suspend_resp_rcvd = false; 2263 wil->suspend_resp_comp = false; 2264 2265 return rc; 2266 } 2267 2268 static void resume_triggers2string(u32 triggers, char *string, int str_size) 2269 { 2270 string[0] = '\0'; 2271 2272 if (!triggers) { 2273 strlcat(string, " UNKNOWN", str_size); 2274 return; 2275 } 2276 2277 if (triggers & WMI_RESUME_TRIGGER_HOST) 2278 strlcat(string, " HOST", str_size); 2279 2280 if (triggers & WMI_RESUME_TRIGGER_UCAST_RX) 2281 strlcat(string, " UCAST_RX", str_size); 2282 2283 if (triggers & WMI_RESUME_TRIGGER_BCAST_RX) 2284 strlcat(string, " BCAST_RX", str_size); 2285 2286 if (triggers & WMI_RESUME_TRIGGER_WMI_EVT) 2287 strlcat(string, " WMI_EVT", str_size); 2288 } 2289 2290 int wmi_resume(struct wil6210_priv *wil) 2291 { 2292 int rc; 2293 char string[100]; 2294 struct { 2295 struct wmi_cmd_hdr wmi; 2296 struct wmi_traffic_resume_event evt; 2297 } __packed reply; 2298 2299 reply.evt.status = WMI_TRAFFIC_RESUME_FAILED; 2300 reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN; 2301 2302 rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, NULL, 0, 2303 WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply), 2304 WIL_WAIT_FOR_SUSPEND_RESUME_COMP); 2305 if (rc) 2306 return rc; 2307 resume_triggers2string(le32_to_cpu(reply.evt.resume_triggers), string, 2308 sizeof(string)); 2309 wil_dbg_pm(wil, "device resume %s, resume triggers:%s (0x%x)\n", 2310 reply.evt.status ? "failed" : "passed", string, 2311 le32_to_cpu(reply.evt.resume_triggers)); 2312 2313 return reply.evt.status; 2314 } 2315 2316 static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id, 2317 void *d, int len) 2318 { 2319 uint i; 2320 2321 for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) { 2322 if (wmi_evt_handlers[i].eventid == id) { 2323 wmi_evt_handlers[i].handler(wil, id, d, len); 2324 return true; 2325 } 2326 } 2327 2328 return false; 2329 } 2330 2331 static void wmi_event_handle(struct wil6210_priv *wil, 2332 struct wil6210_mbox_hdr *hdr) 2333 { 2334 u16 len = le16_to_cpu(hdr->len); 2335 2336 if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) && 2337 (len >= sizeof(struct wmi_cmd_hdr))) { 2338 struct wmi_cmd_hdr *wmi = (void *)(&hdr[1]); 2339 void *evt_data = (void *)(&wmi[1]); 2340 u16 id = le16_to_cpu(wmi->command_id); 2341 2342 wil_dbg_wmi(wil, "Handle %s (0x%04x) (reply_id 0x%04x)\n", 2343 eventid2name(id), id, wil->reply_id); 2344 /* check if someone waits for this event */ 2345 if (wil->reply_id && wil->reply_id == id) { 2346 WARN_ON(wil->reply_buf); 2347 wmi_evt_call_handler(wil, id, evt_data, 2348 len - sizeof(*wmi)); 2349 wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n", 2350 id); 2351 complete(&wil->wmi_call); 2352 return; 2353 } 2354 /* unsolicited event */ 2355 /* search for handler */ 2356 if (!wmi_evt_call_handler(wil, id, evt_data, 2357 len - sizeof(*wmi))) { 2358 wil_info(wil, "Unhandled event 0x%04x\n", id); 2359 } 2360 } else { 2361 wil_err(wil, "Unknown event type\n"); 2362 print_hex_dump(KERN_ERR, "evt?? ", DUMP_PREFIX_OFFSET, 16, 1, 2363 hdr, sizeof(*hdr) + len, true); 2364 } 2365 } 2366 2367 /* 2368 * Retrieve next WMI event from the pending list 2369 */ 2370 static struct list_head *next_wmi_ev(struct wil6210_priv *wil) 2371 { 2372 ulong flags; 2373 struct list_head *ret = NULL; 2374 2375 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 2376 2377 if (!list_empty(&wil->pending_wmi_ev)) { 2378 ret = wil->pending_wmi_ev.next; 2379 list_del(ret); 2380 } 2381 2382 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 2383 2384 return ret; 2385 } 2386 2387 /* 2388 * Handler for the WMI events 2389 */ 2390 void wmi_event_worker(struct work_struct *work) 2391 { 2392 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 2393 wmi_event_worker); 2394 struct pending_wmi_event *evt; 2395 struct list_head *lh; 2396 2397 wil_dbg_wmi(wil, "event_worker: Start\n"); 2398 while ((lh = next_wmi_ev(wil)) != NULL) { 2399 evt = list_entry(lh, struct pending_wmi_event, list); 2400 wmi_event_handle(wil, &evt->event.hdr); 2401 kfree(evt); 2402 } 2403 wil_dbg_wmi(wil, "event_worker: Finished\n"); 2404 } 2405 2406 bool wil_is_wmi_idle(struct wil6210_priv *wil) 2407 { 2408 ulong flags; 2409 struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx; 2410 bool rc = false; 2411 2412 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 2413 2414 /* Check if there are pending WMI events in the events queue */ 2415 if (!list_empty(&wil->pending_wmi_ev)) { 2416 wil_dbg_pm(wil, "Pending WMI events in queue\n"); 2417 goto out; 2418 } 2419 2420 /* Check if there is a pending WMI call */ 2421 if (wil->reply_id) { 2422 wil_dbg_pm(wil, "Pending WMI call\n"); 2423 goto out; 2424 } 2425 2426 /* Check if there are pending RX events in mbox */ 2427 r->head = wil_r(wil, RGF_MBOX + 2428 offsetof(struct wil6210_mbox_ctl, rx.head)); 2429 if (r->tail != r->head) 2430 wil_dbg_pm(wil, "Pending WMI mbox events\n"); 2431 else 2432 rc = true; 2433 2434 out: 2435 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 2436 return rc; 2437 } 2438 2439 static void 2440 wmi_sched_scan_set_ssids(struct wil6210_priv *wil, 2441 struct wmi_start_sched_scan_cmd *cmd, 2442 struct cfg80211_ssid *ssids, int n_ssids, 2443 struct cfg80211_match_set *match_sets, 2444 int n_match_sets) 2445 { 2446 int i; 2447 2448 if (n_match_sets > WMI_MAX_PNO_SSID_NUM) { 2449 wil_dbg_wmi(wil, "too many match sets (%d), use first %d\n", 2450 n_match_sets, WMI_MAX_PNO_SSID_NUM); 2451 n_match_sets = WMI_MAX_PNO_SSID_NUM; 2452 } 2453 cmd->num_of_ssids = n_match_sets; 2454 2455 for (i = 0; i < n_match_sets; i++) { 2456 struct wmi_sched_scan_ssid_match *wmi_match = 2457 &cmd->ssid_for_match[i]; 2458 struct cfg80211_match_set *cfg_match = &match_sets[i]; 2459 int j; 2460 2461 wmi_match->ssid_len = cfg_match->ssid.ssid_len; 2462 memcpy(wmi_match->ssid, cfg_match->ssid.ssid, 2463 min_t(u8, wmi_match->ssid_len, WMI_MAX_SSID_LEN)); 2464 wmi_match->rssi_threshold = S8_MIN; 2465 if (cfg_match->rssi_thold >= S8_MIN && 2466 cfg_match->rssi_thold <= S8_MAX) 2467 wmi_match->rssi_threshold = cfg_match->rssi_thold; 2468 2469 for (j = 0; j < n_ssids; j++) 2470 if (wmi_match->ssid_len == ssids[j].ssid_len && 2471 memcmp(wmi_match->ssid, ssids[j].ssid, 2472 wmi_match->ssid_len) == 0) 2473 wmi_match->add_ssid_to_probe = true; 2474 } 2475 } 2476 2477 static void 2478 wmi_sched_scan_set_channels(struct wil6210_priv *wil, 2479 struct wmi_start_sched_scan_cmd *cmd, 2480 u32 n_channels, 2481 struct ieee80211_channel **channels) 2482 { 2483 int i; 2484 2485 if (n_channels > WMI_MAX_CHANNEL_NUM) { 2486 wil_dbg_wmi(wil, "too many channels (%d), use first %d\n", 2487 n_channels, WMI_MAX_CHANNEL_NUM); 2488 n_channels = WMI_MAX_CHANNEL_NUM; 2489 } 2490 cmd->num_of_channels = n_channels; 2491 2492 for (i = 0; i < n_channels; i++) { 2493 struct ieee80211_channel *cfg_chan = channels[i]; 2494 2495 cmd->channel_list[i] = cfg_chan->hw_value - 1; 2496 } 2497 } 2498 2499 static void 2500 wmi_sched_scan_set_plans(struct wil6210_priv *wil, 2501 struct wmi_start_sched_scan_cmd *cmd, 2502 struct cfg80211_sched_scan_plan *scan_plans, 2503 int n_scan_plans) 2504 { 2505 int i; 2506 2507 if (n_scan_plans > WMI_MAX_PLANS_NUM) { 2508 wil_dbg_wmi(wil, "too many plans (%d), use first %d\n", 2509 n_scan_plans, WMI_MAX_PLANS_NUM); 2510 n_scan_plans = WMI_MAX_PLANS_NUM; 2511 } 2512 2513 for (i = 0; i < n_scan_plans; i++) { 2514 struct cfg80211_sched_scan_plan *cfg_plan = &scan_plans[i]; 2515 2516 cmd->scan_plans[i].interval_sec = 2517 cpu_to_le16(cfg_plan->interval); 2518 cmd->scan_plans[i].num_of_iterations = 2519 cpu_to_le16(cfg_plan->iterations); 2520 } 2521 } 2522 2523 int wmi_start_sched_scan(struct wil6210_priv *wil, 2524 struct cfg80211_sched_scan_request *request) 2525 { 2526 int rc; 2527 struct wmi_start_sched_scan_cmd cmd = { 2528 .min_rssi_threshold = S8_MIN, 2529 .initial_delay_sec = cpu_to_le16(request->delay), 2530 }; 2531 struct { 2532 struct wmi_cmd_hdr wmi; 2533 struct wmi_start_sched_scan_event evt; 2534 } __packed reply; 2535 2536 if (!test_bit(WMI_FW_CAPABILITY_PNO, wil->fw_capabilities)) 2537 return -ENOTSUPP; 2538 2539 if (request->min_rssi_thold >= S8_MIN && 2540 request->min_rssi_thold <= S8_MAX) 2541 cmd.min_rssi_threshold = request->min_rssi_thold; 2542 2543 wmi_sched_scan_set_ssids(wil, &cmd, request->ssids, request->n_ssids, 2544 request->match_sets, request->n_match_sets); 2545 wmi_sched_scan_set_channels(wil, &cmd, 2546 request->n_channels, request->channels); 2547 wmi_sched_scan_set_plans(wil, &cmd, 2548 request->scan_plans, request->n_scan_plans); 2549 2550 reply.evt.result = WMI_PNO_REJECT; 2551 2552 rc = wmi_call(wil, WMI_START_SCHED_SCAN_CMDID, &cmd, sizeof(cmd), 2553 WMI_START_SCHED_SCAN_EVENTID, &reply, sizeof(reply), 2554 WIL_WMI_CALL_GENERAL_TO_MS); 2555 if (rc) 2556 return rc; 2557 2558 if (reply.evt.result != WMI_PNO_SUCCESS) { 2559 wil_err(wil, "start sched scan failed, result %d\n", 2560 reply.evt.result); 2561 return -EINVAL; 2562 } 2563 2564 return 0; 2565 } 2566 2567 int wmi_stop_sched_scan(struct wil6210_priv *wil) 2568 { 2569 int rc; 2570 struct { 2571 struct wmi_cmd_hdr wmi; 2572 struct wmi_stop_sched_scan_event evt; 2573 } __packed reply; 2574 2575 if (!test_bit(WMI_FW_CAPABILITY_PNO, wil->fw_capabilities)) 2576 return -ENOTSUPP; 2577 2578 reply.evt.result = WMI_PNO_REJECT; 2579 2580 rc = wmi_call(wil, WMI_STOP_SCHED_SCAN_CMDID, NULL, 0, 2581 WMI_STOP_SCHED_SCAN_EVENTID, &reply, sizeof(reply), 2582 WIL_WMI_CALL_GENERAL_TO_MS); 2583 if (rc) 2584 return rc; 2585 2586 if (reply.evt.result != WMI_PNO_SUCCESS) { 2587 wil_err(wil, "stop sched scan failed, result %d\n", 2588 reply.evt.result); 2589 return -EINVAL; 2590 } 2591 2592 return 0; 2593 } 2594