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