1 /* 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2018-2019, 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 /* set the default max assoc sta to max supported by driver */ 28 uint max_assoc_sta = WIL6210_MAX_CID; 29 module_param(max_assoc_sta, uint, 0444); 30 MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP"); 31 32 int agg_wsize; /* = 0; */ 33 module_param(agg_wsize, int, 0644); 34 MODULE_PARM_DESC(agg_wsize, " Window size for Tx Block Ack after connect;" 35 " 0 - use default; < 0 - don't auto-establish"); 36 37 u8 led_id = WIL_LED_INVALID_ID; 38 module_param(led_id, byte, 0444); 39 MODULE_PARM_DESC(led_id, 40 " 60G device led enablement. Set the led ID (0-2) to enable"); 41 42 #define WIL_WAIT_FOR_SUSPEND_RESUME_COMP 200 43 #define WIL_WMI_PCP_STOP_TO_MS 5000 44 45 /** 46 * WMI event receiving - theory of operations 47 * 48 * When firmware about to report WMI event, it fills memory area 49 * in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for 50 * the misc IRQ, function @wmi_recv_cmd called by thread IRQ handler. 51 * 52 * @wmi_recv_cmd reads event, allocates memory chunk and attaches it to the 53 * event list @wil->pending_wmi_ev. Then, work queue @wil->wmi_wq wakes up 54 * and handles events within the @wmi_event_worker. Every event get detached 55 * from list, processed and deleted. 56 * 57 * Purpose for this mechanism is to release IRQ thread; otherwise, 58 * if WMI event handling involves another WMI command flow, this 2-nd flow 59 * won't be completed because of blocked IRQ thread. 60 */ 61 62 /** 63 * Addressing - theory of operations 64 * 65 * There are several buses present on the WIL6210 card. 66 * Same memory areas are visible at different address on 67 * the different busses. There are 3 main bus masters: 68 * - MAC CPU (ucode) 69 * - User CPU (firmware) 70 * - AHB (host) 71 * 72 * On the PCI bus, there is one BAR (BAR0) of 2Mb size, exposing 73 * AHB addresses starting from 0x880000 74 * 75 * Internally, firmware uses addresses that allow faster access but 76 * are invisible from the host. To read from these addresses, alternative 77 * AHB address must be used. 78 */ 79 80 /** 81 * @sparrow_fw_mapping provides memory remapping table for sparrow 82 * 83 * array size should be in sync with the declaration in the wil6210.h 84 * 85 * Sparrow memory mapping: 86 * Linker address PCI/Host address 87 * 0x880000 .. 0xa80000 2Mb BAR0 88 * 0x800000 .. 0x808000 0x900000 .. 0x908000 32k DCCM 89 * 0x840000 .. 0x860000 0x908000 .. 0x928000 128k PERIPH 90 */ 91 const struct fw_map sparrow_fw_mapping[] = { 92 /* FW code RAM 256k */ 93 {0x000000, 0x040000, 0x8c0000, "fw_code", true, true}, 94 /* FW data RAM 32k */ 95 {0x800000, 0x808000, 0x900000, "fw_data", true, true}, 96 /* periph data 128k */ 97 {0x840000, 0x860000, 0x908000, "fw_peri", true, true}, 98 /* various RGF 40k */ 99 {0x880000, 0x88a000, 0x880000, "rgf", true, true}, 100 /* AGC table 4k */ 101 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true, true}, 102 /* Pcie_ext_rgf 4k */ 103 {0x88b000, 0x88c000, 0x88b000, "rgf_ext", true, true}, 104 /* mac_ext_rgf 512b */ 105 {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext", true, true}, 106 /* upper area 548k */ 107 {0x8c0000, 0x949000, 0x8c0000, "upper", true, true}, 108 /* UCODE areas - accessible by debugfs blobs but not by 109 * wmi_addr_remap. UCODE areas MUST be added AFTER FW areas! 110 */ 111 /* ucode code RAM 128k */ 112 {0x000000, 0x020000, 0x920000, "uc_code", false, false}, 113 /* ucode data RAM 16k */ 114 {0x800000, 0x804000, 0x940000, "uc_data", false, false}, 115 }; 116 117 /** 118 * @sparrow_d0_mac_rgf_ext - mac_rgf_ext section for Sparrow D0 119 * it is a bit larger to support extra features 120 */ 121 const struct fw_map sparrow_d0_mac_rgf_ext = { 122 0x88c000, 0x88c500, 0x88c000, "mac_rgf_ext", true, true 123 }; 124 125 /** 126 * @talyn_fw_mapping provides memory remapping table for Talyn 127 * 128 * array size should be in sync with the declaration in the wil6210.h 129 * 130 * Talyn memory mapping: 131 * Linker address PCI/Host address 132 * 0x880000 .. 0xc80000 4Mb BAR0 133 * 0x800000 .. 0x820000 0xa00000 .. 0xa20000 128k DCCM 134 * 0x840000 .. 0x858000 0xa20000 .. 0xa38000 96k PERIPH 135 */ 136 const struct fw_map talyn_fw_mapping[] = { 137 /* FW code RAM 1M */ 138 {0x000000, 0x100000, 0x900000, "fw_code", true, true}, 139 /* FW data RAM 128k */ 140 {0x800000, 0x820000, 0xa00000, "fw_data", true, true}, 141 /* periph. data RAM 96k */ 142 {0x840000, 0x858000, 0xa20000, "fw_peri", true, true}, 143 /* various RGF 40k */ 144 {0x880000, 0x88a000, 0x880000, "rgf", true, true}, 145 /* AGC table 4k */ 146 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true, true}, 147 /* Pcie_ext_rgf 4k */ 148 {0x88b000, 0x88c000, 0x88b000, "rgf_ext", true, true}, 149 /* mac_ext_rgf 1344b */ 150 {0x88c000, 0x88c540, 0x88c000, "mac_rgf_ext", true, true}, 151 /* ext USER RGF 4k */ 152 {0x88d000, 0x88e000, 0x88d000, "ext_user_rgf", true, true}, 153 /* OTP 4k */ 154 {0x8a0000, 0x8a1000, 0x8a0000, "otp", true, false}, 155 /* DMA EXT RGF 64k */ 156 {0x8b0000, 0x8c0000, 0x8b0000, "dma_ext_rgf", true, true}, 157 /* upper area 1536k */ 158 {0x900000, 0xa80000, 0x900000, "upper", true, true}, 159 /* UCODE areas - accessible by debugfs blobs but not by 160 * wmi_addr_remap. UCODE areas MUST be added AFTER FW areas! 161 */ 162 /* ucode code RAM 256k */ 163 {0x000000, 0x040000, 0xa38000, "uc_code", false, false}, 164 /* ucode data RAM 32k */ 165 {0x800000, 0x808000, 0xa78000, "uc_data", false, false}, 166 }; 167 168 /** 169 * @talyn_mb_fw_mapping provides memory remapping table for Talyn-MB 170 * 171 * array size should be in sync with the declaration in the wil6210.h 172 * 173 * Talyn MB memory mapping: 174 * Linker address PCI/Host address 175 * 0x880000 .. 0xc80000 4Mb BAR0 176 * 0x800000 .. 0x820000 0xa00000 .. 0xa20000 128k DCCM 177 * 0x840000 .. 0x858000 0xa20000 .. 0xa38000 96k PERIPH 178 */ 179 const struct fw_map talyn_mb_fw_mapping[] = { 180 /* FW code RAM 768k */ 181 {0x000000, 0x0c0000, 0x900000, "fw_code", true, true}, 182 /* FW data RAM 128k */ 183 {0x800000, 0x820000, 0xa00000, "fw_data", true, true}, 184 /* periph. data RAM 96k */ 185 {0x840000, 0x858000, 0xa20000, "fw_peri", true, true}, 186 /* various RGF 40k */ 187 {0x880000, 0x88a000, 0x880000, "rgf", true, true}, 188 /* AGC table 4k */ 189 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true, true}, 190 /* Pcie_ext_rgf 4k */ 191 {0x88b000, 0x88c000, 0x88b000, "rgf_ext", true, true}, 192 /* mac_ext_rgf 2256b */ 193 {0x88c000, 0x88c8d0, 0x88c000, "mac_rgf_ext", true, true}, 194 /* ext USER RGF 4k */ 195 {0x88d000, 0x88e000, 0x88d000, "ext_user_rgf", true, true}, 196 /* SEC PKA 16k */ 197 {0x890000, 0x894000, 0x890000, "sec_pka", true, true}, 198 /* SEC KDF RGF 3096b */ 199 {0x898000, 0x898c18, 0x898000, "sec_kdf_rgf", true, true}, 200 /* SEC MAIN 2124b */ 201 {0x89a000, 0x89a84c, 0x89a000, "sec_main", true, true}, 202 /* OTP 4k */ 203 {0x8a0000, 0x8a1000, 0x8a0000, "otp", true, false}, 204 /* DMA EXT RGF 64k */ 205 {0x8b0000, 0x8c0000, 0x8b0000, "dma_ext_rgf", true, true}, 206 /* DUM USER RGF 528b */ 207 {0x8c0000, 0x8c0210, 0x8c0000, "dum_user_rgf", true, true}, 208 /* DMA OFU 296b */ 209 {0x8c2000, 0x8c2128, 0x8c2000, "dma_ofu", true, true}, 210 /* ucode debug 4k */ 211 {0x8c3000, 0x8c4000, 0x8c3000, "ucode_debug", true, true}, 212 /* upper area 1536k */ 213 {0x900000, 0xa80000, 0x900000, "upper", true, true}, 214 /* UCODE areas - accessible by debugfs blobs but not by 215 * wmi_addr_remap. UCODE areas MUST be added AFTER FW areas! 216 */ 217 /* ucode code RAM 256k */ 218 {0x000000, 0x040000, 0xa38000, "uc_code", false, false}, 219 /* ucode data RAM 32k */ 220 {0x800000, 0x808000, 0xa78000, "uc_data", false, false}, 221 }; 222 223 struct fw_map fw_mapping[MAX_FW_MAPPING_TABLE_SIZE]; 224 225 struct blink_on_off_time led_blink_time[] = { 226 {WIL_LED_BLINK_ON_SLOW_MS, WIL_LED_BLINK_OFF_SLOW_MS}, 227 {WIL_LED_BLINK_ON_MED_MS, WIL_LED_BLINK_OFF_MED_MS}, 228 {WIL_LED_BLINK_ON_FAST_MS, WIL_LED_BLINK_OFF_FAST_MS}, 229 }; 230 231 struct auth_no_hdr { 232 __le16 auth_alg; 233 __le16 auth_transaction; 234 __le16 status_code; 235 /* possibly followed by Challenge text */ 236 u8 variable[0]; 237 } __packed; 238 239 u8 led_polarity = LED_POLARITY_LOW_ACTIVE; 240 241 /** 242 * return AHB address for given firmware internal (linker) address 243 * @x - internal address 244 * If address have no valid AHB mapping, return 0 245 */ 246 static u32 wmi_addr_remap(u32 x) 247 { 248 uint i; 249 250 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { 251 if (fw_mapping[i].fw && 252 ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to))) 253 return x + fw_mapping[i].host - fw_mapping[i].from; 254 } 255 256 return 0; 257 } 258 259 /** 260 * find fw_mapping entry by section name 261 * @section - section name 262 * 263 * Return pointer to section or NULL if not found 264 */ 265 struct fw_map *wil_find_fw_mapping(const char *section) 266 { 267 int i; 268 269 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) 270 if (fw_mapping[i].name && 271 !strcmp(section, fw_mapping[i].name)) 272 return &fw_mapping[i]; 273 274 return NULL; 275 } 276 277 /** 278 * Check address validity for WMI buffer; remap if needed 279 * @ptr - internal (linker) fw/ucode address 280 * @size - if non zero, validate the block does not 281 * exceed the device memory (bar) 282 * 283 * Valid buffer should be DWORD aligned 284 * 285 * return address for accessing buffer from the host; 286 * if buffer is not valid, return NULL. 287 */ 288 void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr_, u32 size) 289 { 290 u32 off; 291 u32 ptr = le32_to_cpu(ptr_); 292 293 if (ptr % 4) 294 return NULL; 295 296 ptr = wmi_addr_remap(ptr); 297 if (ptr < WIL6210_FW_HOST_OFF) 298 return NULL; 299 300 off = HOSTADDR(ptr); 301 if (off > wil->bar_size - 4) 302 return NULL; 303 if (size && ((off + size > wil->bar_size) || (off + size < off))) 304 return NULL; 305 306 return wil->csr + off; 307 } 308 309 void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) 310 { 311 return wmi_buffer_block(wil, ptr_, 0); 312 } 313 314 /** 315 * Check address validity 316 */ 317 void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr) 318 { 319 u32 off; 320 321 if (ptr % 4) 322 return NULL; 323 324 if (ptr < WIL6210_FW_HOST_OFF) 325 return NULL; 326 327 off = HOSTADDR(ptr); 328 if (off > wil->bar_size - 4) 329 return NULL; 330 331 return wil->csr + off; 332 } 333 334 int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, 335 struct wil6210_mbox_hdr *hdr) 336 { 337 void __iomem *src = wmi_buffer(wil, ptr); 338 339 if (!src) 340 return -EINVAL; 341 342 wil_memcpy_fromio_32(hdr, src, sizeof(*hdr)); 343 344 return 0; 345 } 346 347 static const char *cmdid2name(u16 cmdid) 348 { 349 switch (cmdid) { 350 case WMI_NOTIFY_REQ_CMDID: 351 return "WMI_NOTIFY_REQ_CMD"; 352 case WMI_START_SCAN_CMDID: 353 return "WMI_START_SCAN_CMD"; 354 case WMI_CONNECT_CMDID: 355 return "WMI_CONNECT_CMD"; 356 case WMI_DISCONNECT_CMDID: 357 return "WMI_DISCONNECT_CMD"; 358 case WMI_SW_TX_REQ_CMDID: 359 return "WMI_SW_TX_REQ_CMD"; 360 case WMI_GET_RF_SECTOR_PARAMS_CMDID: 361 return "WMI_GET_RF_SECTOR_PARAMS_CMD"; 362 case WMI_SET_RF_SECTOR_PARAMS_CMDID: 363 return "WMI_SET_RF_SECTOR_PARAMS_CMD"; 364 case WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID: 365 return "WMI_GET_SELECTED_RF_SECTOR_INDEX_CMD"; 366 case WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID: 367 return "WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD"; 368 case WMI_BRP_SET_ANT_LIMIT_CMDID: 369 return "WMI_BRP_SET_ANT_LIMIT_CMD"; 370 case WMI_TOF_SESSION_START_CMDID: 371 return "WMI_TOF_SESSION_START_CMD"; 372 case WMI_AOA_MEAS_CMDID: 373 return "WMI_AOA_MEAS_CMD"; 374 case WMI_PMC_CMDID: 375 return "WMI_PMC_CMD"; 376 case WMI_TOF_GET_TX_RX_OFFSET_CMDID: 377 return "WMI_TOF_GET_TX_RX_OFFSET_CMD"; 378 case WMI_TOF_SET_TX_RX_OFFSET_CMDID: 379 return "WMI_TOF_SET_TX_RX_OFFSET_CMD"; 380 case WMI_VRING_CFG_CMDID: 381 return "WMI_VRING_CFG_CMD"; 382 case WMI_BCAST_VRING_CFG_CMDID: 383 return "WMI_BCAST_VRING_CFG_CMD"; 384 case WMI_TRAFFIC_SUSPEND_CMDID: 385 return "WMI_TRAFFIC_SUSPEND_CMD"; 386 case WMI_TRAFFIC_RESUME_CMDID: 387 return "WMI_TRAFFIC_RESUME_CMD"; 388 case WMI_ECHO_CMDID: 389 return "WMI_ECHO_CMD"; 390 case WMI_SET_MAC_ADDRESS_CMDID: 391 return "WMI_SET_MAC_ADDRESS_CMD"; 392 case WMI_LED_CFG_CMDID: 393 return "WMI_LED_CFG_CMD"; 394 case WMI_PCP_START_CMDID: 395 return "WMI_PCP_START_CMD"; 396 case WMI_PCP_STOP_CMDID: 397 return "WMI_PCP_STOP_CMD"; 398 case WMI_SET_SSID_CMDID: 399 return "WMI_SET_SSID_CMD"; 400 case WMI_GET_SSID_CMDID: 401 return "WMI_GET_SSID_CMD"; 402 case WMI_SET_PCP_CHANNEL_CMDID: 403 return "WMI_SET_PCP_CHANNEL_CMD"; 404 case WMI_GET_PCP_CHANNEL_CMDID: 405 return "WMI_GET_PCP_CHANNEL_CMD"; 406 case WMI_P2P_CFG_CMDID: 407 return "WMI_P2P_CFG_CMD"; 408 case WMI_PORT_ALLOCATE_CMDID: 409 return "WMI_PORT_ALLOCATE_CMD"; 410 case WMI_PORT_DELETE_CMDID: 411 return "WMI_PORT_DELETE_CMD"; 412 case WMI_START_LISTEN_CMDID: 413 return "WMI_START_LISTEN_CMD"; 414 case WMI_START_SEARCH_CMDID: 415 return "WMI_START_SEARCH_CMD"; 416 case WMI_DISCOVERY_STOP_CMDID: 417 return "WMI_DISCOVERY_STOP_CMD"; 418 case WMI_DELETE_CIPHER_KEY_CMDID: 419 return "WMI_DELETE_CIPHER_KEY_CMD"; 420 case WMI_ADD_CIPHER_KEY_CMDID: 421 return "WMI_ADD_CIPHER_KEY_CMD"; 422 case WMI_SET_APPIE_CMDID: 423 return "WMI_SET_APPIE_CMD"; 424 case WMI_CFG_RX_CHAIN_CMDID: 425 return "WMI_CFG_RX_CHAIN_CMD"; 426 case WMI_TEMP_SENSE_CMDID: 427 return "WMI_TEMP_SENSE_CMD"; 428 case WMI_DEL_STA_CMDID: 429 return "WMI_DEL_STA_CMD"; 430 case WMI_DISCONNECT_STA_CMDID: 431 return "WMI_DISCONNECT_STA_CMD"; 432 case WMI_RING_BA_EN_CMDID: 433 return "WMI_RING_BA_EN_CMD"; 434 case WMI_RING_BA_DIS_CMDID: 435 return "WMI_RING_BA_DIS_CMD"; 436 case WMI_RCP_DELBA_CMDID: 437 return "WMI_RCP_DELBA_CMD"; 438 case WMI_RCP_ADDBA_RESP_CMDID: 439 return "WMI_RCP_ADDBA_RESP_CMD"; 440 case WMI_RCP_ADDBA_RESP_EDMA_CMDID: 441 return "WMI_RCP_ADDBA_RESP_EDMA_CMD"; 442 case WMI_PS_DEV_PROFILE_CFG_CMDID: 443 return "WMI_PS_DEV_PROFILE_CFG_CMD"; 444 case WMI_SET_MGMT_RETRY_LIMIT_CMDID: 445 return "WMI_SET_MGMT_RETRY_LIMIT_CMD"; 446 case WMI_GET_MGMT_RETRY_LIMIT_CMDID: 447 return "WMI_GET_MGMT_RETRY_LIMIT_CMD"; 448 case WMI_ABORT_SCAN_CMDID: 449 return "WMI_ABORT_SCAN_CMD"; 450 case WMI_NEW_STA_CMDID: 451 return "WMI_NEW_STA_CMD"; 452 case WMI_SET_THERMAL_THROTTLING_CFG_CMDID: 453 return "WMI_SET_THERMAL_THROTTLING_CFG_CMD"; 454 case WMI_GET_THERMAL_THROTTLING_CFG_CMDID: 455 return "WMI_GET_THERMAL_THROTTLING_CFG_CMD"; 456 case WMI_LINK_MAINTAIN_CFG_WRITE_CMDID: 457 return "WMI_LINK_MAINTAIN_CFG_WRITE_CMD"; 458 case WMI_LO_POWER_CALIB_FROM_OTP_CMDID: 459 return "WMI_LO_POWER_CALIB_FROM_OTP_CMD"; 460 case WMI_START_SCHED_SCAN_CMDID: 461 return "WMI_START_SCHED_SCAN_CMD"; 462 case WMI_STOP_SCHED_SCAN_CMDID: 463 return "WMI_STOP_SCHED_SCAN_CMD"; 464 case WMI_TX_STATUS_RING_ADD_CMDID: 465 return "WMI_TX_STATUS_RING_ADD_CMD"; 466 case WMI_RX_STATUS_RING_ADD_CMDID: 467 return "WMI_RX_STATUS_RING_ADD_CMD"; 468 case WMI_TX_DESC_RING_ADD_CMDID: 469 return "WMI_TX_DESC_RING_ADD_CMD"; 470 case WMI_RX_DESC_RING_ADD_CMDID: 471 return "WMI_RX_DESC_RING_ADD_CMD"; 472 case WMI_BCAST_DESC_RING_ADD_CMDID: 473 return "WMI_BCAST_DESC_RING_ADD_CMD"; 474 case WMI_CFG_DEF_RX_OFFLOAD_CMDID: 475 return "WMI_CFG_DEF_RX_OFFLOAD_CMD"; 476 case WMI_LINK_STATS_CMDID: 477 return "WMI_LINK_STATS_CMD"; 478 case WMI_SW_TX_REQ_EXT_CMDID: 479 return "WMI_SW_TX_REQ_EXT_CMDID"; 480 case WMI_FT_AUTH_CMDID: 481 return "WMI_FT_AUTH_CMD"; 482 case WMI_FT_REASSOC_CMDID: 483 return "WMI_FT_REASSOC_CMD"; 484 case WMI_UPDATE_FT_IES_CMDID: 485 return "WMI_UPDATE_FT_IES_CMD"; 486 case WMI_RBUFCAP_CFG_CMDID: 487 return "WMI_RBUFCAP_CFG_CMD"; 488 case WMI_TEMP_SENSE_ALL_CMDID: 489 return "WMI_TEMP_SENSE_ALL_CMDID"; 490 default: 491 return "Untracked CMD"; 492 } 493 } 494 495 static const char *eventid2name(u16 eventid) 496 { 497 switch (eventid) { 498 case WMI_NOTIFY_REQ_DONE_EVENTID: 499 return "WMI_NOTIFY_REQ_DONE_EVENT"; 500 case WMI_DISCONNECT_EVENTID: 501 return "WMI_DISCONNECT_EVENT"; 502 case WMI_SW_TX_COMPLETE_EVENTID: 503 return "WMI_SW_TX_COMPLETE_EVENT"; 504 case WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID: 505 return "WMI_GET_RF_SECTOR_PARAMS_DONE_EVENT"; 506 case WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID: 507 return "WMI_SET_RF_SECTOR_PARAMS_DONE_EVENT"; 508 case WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID: 509 return "WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT"; 510 case WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID: 511 return "WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT"; 512 case WMI_BRP_SET_ANT_LIMIT_EVENTID: 513 return "WMI_BRP_SET_ANT_LIMIT_EVENT"; 514 case WMI_FW_READY_EVENTID: 515 return "WMI_FW_READY_EVENT"; 516 case WMI_TRAFFIC_RESUME_EVENTID: 517 return "WMI_TRAFFIC_RESUME_EVENT"; 518 case WMI_TOF_GET_TX_RX_OFFSET_EVENTID: 519 return "WMI_TOF_GET_TX_RX_OFFSET_EVENT"; 520 case WMI_TOF_SET_TX_RX_OFFSET_EVENTID: 521 return "WMI_TOF_SET_TX_RX_OFFSET_EVENT"; 522 case WMI_VRING_CFG_DONE_EVENTID: 523 return "WMI_VRING_CFG_DONE_EVENT"; 524 case WMI_READY_EVENTID: 525 return "WMI_READY_EVENT"; 526 case WMI_RX_MGMT_PACKET_EVENTID: 527 return "WMI_RX_MGMT_PACKET_EVENT"; 528 case WMI_TX_MGMT_PACKET_EVENTID: 529 return "WMI_TX_MGMT_PACKET_EVENT"; 530 case WMI_SCAN_COMPLETE_EVENTID: 531 return "WMI_SCAN_COMPLETE_EVENT"; 532 case WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENTID: 533 return "WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENT"; 534 case WMI_CONNECT_EVENTID: 535 return "WMI_CONNECT_EVENT"; 536 case WMI_EAPOL_RX_EVENTID: 537 return "WMI_EAPOL_RX_EVENT"; 538 case WMI_BA_STATUS_EVENTID: 539 return "WMI_BA_STATUS_EVENT"; 540 case WMI_RCP_ADDBA_REQ_EVENTID: 541 return "WMI_RCP_ADDBA_REQ_EVENT"; 542 case WMI_DELBA_EVENTID: 543 return "WMI_DELBA_EVENT"; 544 case WMI_RING_EN_EVENTID: 545 return "WMI_RING_EN_EVENT"; 546 case WMI_DATA_PORT_OPEN_EVENTID: 547 return "WMI_DATA_PORT_OPEN_EVENT"; 548 case WMI_AOA_MEAS_EVENTID: 549 return "WMI_AOA_MEAS_EVENT"; 550 case WMI_TOF_SESSION_END_EVENTID: 551 return "WMI_TOF_SESSION_END_EVENT"; 552 case WMI_TOF_GET_CAPABILITIES_EVENTID: 553 return "WMI_TOF_GET_CAPABILITIES_EVENT"; 554 case WMI_TOF_SET_LCR_EVENTID: 555 return "WMI_TOF_SET_LCR_EVENT"; 556 case WMI_TOF_SET_LCI_EVENTID: 557 return "WMI_TOF_SET_LCI_EVENT"; 558 case WMI_TOF_FTM_PER_DEST_RES_EVENTID: 559 return "WMI_TOF_FTM_PER_DEST_RES_EVENT"; 560 case WMI_TOF_CHANNEL_INFO_EVENTID: 561 return "WMI_TOF_CHANNEL_INFO_EVENT"; 562 case WMI_TRAFFIC_SUSPEND_EVENTID: 563 return "WMI_TRAFFIC_SUSPEND_EVENT"; 564 case WMI_ECHO_RSP_EVENTID: 565 return "WMI_ECHO_RSP_EVENT"; 566 case WMI_LED_CFG_DONE_EVENTID: 567 return "WMI_LED_CFG_DONE_EVENT"; 568 case WMI_PCP_STARTED_EVENTID: 569 return "WMI_PCP_STARTED_EVENT"; 570 case WMI_PCP_STOPPED_EVENTID: 571 return "WMI_PCP_STOPPED_EVENT"; 572 case WMI_GET_SSID_EVENTID: 573 return "WMI_GET_SSID_EVENT"; 574 case WMI_GET_PCP_CHANNEL_EVENTID: 575 return "WMI_GET_PCP_CHANNEL_EVENT"; 576 case WMI_P2P_CFG_DONE_EVENTID: 577 return "WMI_P2P_CFG_DONE_EVENT"; 578 case WMI_PORT_ALLOCATED_EVENTID: 579 return "WMI_PORT_ALLOCATED_EVENT"; 580 case WMI_PORT_DELETED_EVENTID: 581 return "WMI_PORT_DELETED_EVENT"; 582 case WMI_LISTEN_STARTED_EVENTID: 583 return "WMI_LISTEN_STARTED_EVENT"; 584 case WMI_SEARCH_STARTED_EVENTID: 585 return "WMI_SEARCH_STARTED_EVENT"; 586 case WMI_DISCOVERY_STOPPED_EVENTID: 587 return "WMI_DISCOVERY_STOPPED_EVENT"; 588 case WMI_CFG_RX_CHAIN_DONE_EVENTID: 589 return "WMI_CFG_RX_CHAIN_DONE_EVENT"; 590 case WMI_TEMP_SENSE_DONE_EVENTID: 591 return "WMI_TEMP_SENSE_DONE_EVENT"; 592 case WMI_RCP_ADDBA_RESP_SENT_EVENTID: 593 return "WMI_RCP_ADDBA_RESP_SENT_EVENT"; 594 case WMI_PS_DEV_PROFILE_CFG_EVENTID: 595 return "WMI_PS_DEV_PROFILE_CFG_EVENT"; 596 case WMI_SET_MGMT_RETRY_LIMIT_EVENTID: 597 return "WMI_SET_MGMT_RETRY_LIMIT_EVENT"; 598 case WMI_GET_MGMT_RETRY_LIMIT_EVENTID: 599 return "WMI_GET_MGMT_RETRY_LIMIT_EVENT"; 600 case WMI_SET_THERMAL_THROTTLING_CFG_EVENTID: 601 return "WMI_SET_THERMAL_THROTTLING_CFG_EVENT"; 602 case WMI_GET_THERMAL_THROTTLING_CFG_EVENTID: 603 return "WMI_GET_THERMAL_THROTTLING_CFG_EVENT"; 604 case WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID: 605 return "WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENT"; 606 case WMI_LO_POWER_CALIB_FROM_OTP_EVENTID: 607 return "WMI_LO_POWER_CALIB_FROM_OTP_EVENT"; 608 case WMI_START_SCHED_SCAN_EVENTID: 609 return "WMI_START_SCHED_SCAN_EVENT"; 610 case WMI_STOP_SCHED_SCAN_EVENTID: 611 return "WMI_STOP_SCHED_SCAN_EVENT"; 612 case WMI_SCHED_SCAN_RESULT_EVENTID: 613 return "WMI_SCHED_SCAN_RESULT_EVENT"; 614 case WMI_TX_STATUS_RING_CFG_DONE_EVENTID: 615 return "WMI_TX_STATUS_RING_CFG_DONE_EVENT"; 616 case WMI_RX_STATUS_RING_CFG_DONE_EVENTID: 617 return "WMI_RX_STATUS_RING_CFG_DONE_EVENT"; 618 case WMI_TX_DESC_RING_CFG_DONE_EVENTID: 619 return "WMI_TX_DESC_RING_CFG_DONE_EVENT"; 620 case WMI_RX_DESC_RING_CFG_DONE_EVENTID: 621 return "WMI_RX_DESC_RING_CFG_DONE_EVENT"; 622 case WMI_CFG_DEF_RX_OFFLOAD_DONE_EVENTID: 623 return "WMI_CFG_DEF_RX_OFFLOAD_DONE_EVENT"; 624 case WMI_LINK_STATS_CONFIG_DONE_EVENTID: 625 return "WMI_LINK_STATS_CONFIG_DONE_EVENT"; 626 case WMI_LINK_STATS_EVENTID: 627 return "WMI_LINK_STATS_EVENT"; 628 case WMI_COMMAND_NOT_SUPPORTED_EVENTID: 629 return "WMI_COMMAND_NOT_SUPPORTED_EVENT"; 630 case WMI_FT_AUTH_STATUS_EVENTID: 631 return "WMI_FT_AUTH_STATUS_EVENT"; 632 case WMI_FT_REASSOC_STATUS_EVENTID: 633 return "WMI_FT_REASSOC_STATUS_EVENT"; 634 case WMI_RBUFCAP_CFG_EVENTID: 635 return "WMI_RBUFCAP_CFG_EVENT"; 636 case WMI_TEMP_SENSE_ALL_DONE_EVENTID: 637 return "WMI_TEMP_SENSE_ALL_DONE_EVENTID"; 638 default: 639 return "Untracked EVENT"; 640 } 641 } 642 643 static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, 644 void *buf, u16 len) 645 { 646 struct { 647 struct wil6210_mbox_hdr hdr; 648 struct wmi_cmd_hdr wmi; 649 } __packed cmd = { 650 .hdr = { 651 .type = WIL_MBOX_HDR_TYPE_WMI, 652 .flags = 0, 653 .len = cpu_to_le16(sizeof(cmd.wmi) + len), 654 }, 655 .wmi = { 656 .mid = mid, 657 .command_id = cpu_to_le16(cmdid), 658 }, 659 }; 660 struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx; 661 struct wil6210_mbox_ring_desc d_head; 662 u32 next_head; 663 void __iomem *dst; 664 void __iomem *head = wmi_addr(wil, r->head); 665 uint retry; 666 int rc = 0; 667 668 if (len > r->entry_size - sizeof(cmd)) { 669 wil_err(wil, "WMI size too large: %d bytes, max is %d\n", 670 (int)(sizeof(cmd) + len), r->entry_size); 671 return -ERANGE; 672 } 673 674 might_sleep(); 675 676 if (!test_bit(wil_status_fwready, wil->status)) { 677 wil_err(wil, "WMI: cannot send command while FW not ready\n"); 678 return -EAGAIN; 679 } 680 681 /* Allow sending only suspend / resume commands during susepnd flow */ 682 if ((test_bit(wil_status_suspending, wil->status) || 683 test_bit(wil_status_suspended, wil->status) || 684 test_bit(wil_status_resuming, wil->status)) && 685 ((cmdid != WMI_TRAFFIC_SUSPEND_CMDID) && 686 (cmdid != WMI_TRAFFIC_RESUME_CMDID))) { 687 wil_err(wil, "WMI: reject send_command during suspend\n"); 688 return -EINVAL; 689 } 690 691 if (!head) { 692 wil_err(wil, "WMI head is garbage: 0x%08x\n", r->head); 693 return -EINVAL; 694 } 695 696 wil_halp_vote(wil); 697 698 /* read Tx head till it is not busy */ 699 for (retry = 5; retry > 0; retry--) { 700 wil_memcpy_fromio_32(&d_head, head, sizeof(d_head)); 701 if (d_head.sync == 0) 702 break; 703 msleep(20); 704 } 705 if (d_head.sync != 0) { 706 wil_err(wil, "WMI head busy\n"); 707 rc = -EBUSY; 708 goto out; 709 } 710 /* next head */ 711 next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size); 712 wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head); 713 /* wait till FW finish with previous command */ 714 for (retry = 5; retry > 0; retry--) { 715 if (!test_bit(wil_status_fwready, wil->status)) { 716 wil_err(wil, "WMI: cannot send command while FW not ready\n"); 717 rc = -EAGAIN; 718 goto out; 719 } 720 r->tail = wil_r(wil, RGF_MBOX + 721 offsetof(struct wil6210_mbox_ctl, tx.tail)); 722 if (next_head != r->tail) 723 break; 724 msleep(20); 725 } 726 if (next_head == r->tail) { 727 wil_err(wil, "WMI ring full\n"); 728 rc = -EBUSY; 729 goto out; 730 } 731 dst = wmi_buffer(wil, d_head.addr); 732 if (!dst) { 733 wil_err(wil, "invalid WMI buffer: 0x%08x\n", 734 le32_to_cpu(d_head.addr)); 735 rc = -EAGAIN; 736 goto out; 737 } 738 cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); 739 /* set command */ 740 wil_dbg_wmi(wil, "sending %s (0x%04x) [%d] mid %d\n", 741 cmdid2name(cmdid), cmdid, len, mid); 742 wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, 743 sizeof(cmd), true); 744 wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, 745 len, true); 746 wil_memcpy_toio_32(dst, &cmd, sizeof(cmd)); 747 wil_memcpy_toio_32(dst + sizeof(cmd), buf, len); 748 /* mark entry as full */ 749 wil_w(wil, r->head + offsetof(struct wil6210_mbox_ring_desc, sync), 1); 750 /* advance next ptr */ 751 wil_w(wil, RGF_MBOX + offsetof(struct wil6210_mbox_ctl, tx.head), 752 r->head = next_head); 753 754 trace_wil6210_wmi_cmd(&cmd.wmi, buf, len); 755 756 /* interrupt to FW */ 757 wil_w(wil, RGF_USER_USER_ICR + offsetof(struct RGF_ICR, ICS), 758 SW_INT_MBOX); 759 760 out: 761 wil_halp_unvote(wil); 762 return rc; 763 } 764 765 int wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len) 766 { 767 int rc; 768 769 mutex_lock(&wil->wmi_mutex); 770 rc = __wmi_send(wil, cmdid, mid, buf, len); 771 mutex_unlock(&wil->wmi_mutex); 772 773 return rc; 774 } 775 776 /*=== Event handlers ===*/ 777 static void wmi_evt_ready(struct wil6210_vif *vif, int id, void *d, int len) 778 { 779 struct wil6210_priv *wil = vif_to_wil(vif); 780 struct wiphy *wiphy = wil_to_wiphy(wil); 781 struct wmi_ready_event *evt = d; 782 u8 fw_max_assoc_sta; 783 784 wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n", 785 wil->fw_version, le32_to_cpu(evt->sw_version), 786 evt->mac, evt->numof_additional_mids); 787 if (evt->numof_additional_mids + 1 < wil->max_vifs) { 788 wil_err(wil, "FW does not support enough MIDs (need %d)", 789 wil->max_vifs - 1); 790 return; /* FW load will fail after timeout */ 791 } 792 /* ignore MAC address, we already have it from the boot loader */ 793 strlcpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version)); 794 795 if (len > offsetof(struct wmi_ready_event, rfc_read_calib_result)) { 796 wil_dbg_wmi(wil, "rfc calibration result %d\n", 797 evt->rfc_read_calib_result); 798 wil->fw_calib_result = evt->rfc_read_calib_result; 799 } 800 801 fw_max_assoc_sta = WIL6210_RX_DESC_MAX_CID; 802 if (len > offsetof(struct wmi_ready_event, max_assoc_sta) && 803 evt->max_assoc_sta > 0) { 804 fw_max_assoc_sta = evt->max_assoc_sta; 805 wil_dbg_wmi(wil, "fw reported max assoc sta %d\n", 806 fw_max_assoc_sta); 807 808 if (fw_max_assoc_sta > WIL6210_MAX_CID) { 809 wil_dbg_wmi(wil, 810 "fw max assoc sta %d exceeds max driver supported %d\n", 811 fw_max_assoc_sta, WIL6210_MAX_CID); 812 fw_max_assoc_sta = WIL6210_MAX_CID; 813 } 814 } 815 816 wil->max_assoc_sta = min_t(uint, max_assoc_sta, fw_max_assoc_sta); 817 wil_dbg_wmi(wil, "setting max assoc sta to %d\n", wil->max_assoc_sta); 818 819 wil_set_recovery_state(wil, fw_recovery_idle); 820 set_bit(wil_status_fwready, wil->status); 821 /* let the reset sequence continue */ 822 complete(&wil->wmi_ready); 823 } 824 825 static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len) 826 { 827 struct wil6210_priv *wil = vif_to_wil(vif); 828 struct wmi_rx_mgmt_packet_event *data = d; 829 struct wiphy *wiphy = wil_to_wiphy(wil); 830 struct ieee80211_mgmt *rx_mgmt_frame = 831 (struct ieee80211_mgmt *)data->payload; 832 int flen = len - offsetof(struct wmi_rx_mgmt_packet_event, payload); 833 int ch_no; 834 u32 freq; 835 struct ieee80211_channel *channel; 836 s32 signal; 837 __le16 fc; 838 u32 d_len; 839 u16 d_status; 840 841 if (flen < 0) { 842 wil_err(wil, "MGMT Rx: short event, len %d\n", len); 843 return; 844 } 845 846 d_len = le32_to_cpu(data->info.len); 847 if (d_len != flen) { 848 wil_err(wil, 849 "MGMT Rx: length mismatch, d_len %d should be %d\n", 850 d_len, flen); 851 return; 852 } 853 854 ch_no = data->info.channel + 1; 855 freq = ieee80211_channel_to_frequency(ch_no, NL80211_BAND_60GHZ); 856 channel = ieee80211_get_channel(wiphy, freq); 857 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities)) 858 signal = 100 * data->info.rssi; 859 else 860 signal = data->info.sqi; 861 d_status = le16_to_cpu(data->info.status); 862 fc = rx_mgmt_frame->frame_control; 863 864 wil_dbg_wmi(wil, "MGMT Rx: channel %d MCS %d RSSI %d SQI %d%%\n", 865 data->info.channel, data->info.mcs, data->info.rssi, 866 data->info.sqi); 867 wil_dbg_wmi(wil, "status 0x%04x len %d fc 0x%04x\n", d_status, d_len, 868 le16_to_cpu(fc)); 869 wil_dbg_wmi(wil, "qid %d mid %d cid %d\n", 870 data->info.qid, data->info.mid, data->info.cid); 871 wil_hex_dump_wmi("MGMT Rx ", DUMP_PREFIX_OFFSET, 16, 1, rx_mgmt_frame, 872 d_len, true); 873 874 if (!channel) { 875 wil_err(wil, "Frame on unsupported channel\n"); 876 return; 877 } 878 879 if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { 880 struct cfg80211_bss *bss; 881 u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp); 882 u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info); 883 u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int); 884 const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable; 885 size_t ie_len = d_len - offsetof(struct ieee80211_mgmt, 886 u.beacon.variable); 887 wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap); 888 wil_dbg_wmi(wil, "TSF : 0x%016llx\n", tsf); 889 wil_dbg_wmi(wil, "Beacon interval : %d\n", bi); 890 wil_hex_dump_wmi("IE ", DUMP_PREFIX_OFFSET, 16, 1, ie_buf, 891 ie_len, true); 892 893 wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap); 894 895 bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, 896 d_len, signal, GFP_KERNEL); 897 if (bss) { 898 wil_dbg_wmi(wil, "Added BSS %pM\n", 899 rx_mgmt_frame->bssid); 900 cfg80211_put_bss(wiphy, bss); 901 } else { 902 wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); 903 } 904 } else { 905 mutex_lock(&wil->vif_mutex); 906 cfg80211_rx_mgmt(vif_to_radio_wdev(wil, vif), freq, signal, 907 (void *)rx_mgmt_frame, d_len, 0); 908 mutex_unlock(&wil->vif_mutex); 909 } 910 } 911 912 static void wmi_evt_tx_mgmt(struct wil6210_vif *vif, int id, void *d, int len) 913 { 914 struct wmi_tx_mgmt_packet_event *data = d; 915 struct ieee80211_mgmt *mgmt_frame = 916 (struct ieee80211_mgmt *)data->payload; 917 int flen = len - offsetof(struct wmi_tx_mgmt_packet_event, payload); 918 919 wil_hex_dump_wmi("MGMT Tx ", DUMP_PREFIX_OFFSET, 16, 1, mgmt_frame, 920 flen, true); 921 } 922 923 static void wmi_evt_scan_complete(struct wil6210_vif *vif, int id, 924 void *d, int len) 925 { 926 struct wil6210_priv *wil = vif_to_wil(vif); 927 928 mutex_lock(&wil->vif_mutex); 929 if (vif->scan_request) { 930 struct wmi_scan_complete_event *data = d; 931 int status = le32_to_cpu(data->status); 932 struct cfg80211_scan_info info = { 933 .aborted = ((status != WMI_SCAN_SUCCESS) && 934 (status != WMI_SCAN_ABORT_REJECTED)), 935 }; 936 937 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status); 938 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", 939 vif->scan_request, info.aborted); 940 del_timer_sync(&vif->scan_timer); 941 cfg80211_scan_done(vif->scan_request, &info); 942 if (vif->mid == 0) 943 wil->radio_wdev = wil->main_ndev->ieee80211_ptr; 944 vif->scan_request = NULL; 945 wake_up_interruptible(&wil->wq); 946 if (vif->p2p.pending_listen_wdev) { 947 wil_dbg_misc(wil, "Scheduling delayed listen\n"); 948 schedule_work(&vif->p2p.delayed_listen_work); 949 } 950 } else { 951 wil_err(wil, "SCAN_COMPLETE while not scanning\n"); 952 } 953 mutex_unlock(&wil->vif_mutex); 954 } 955 956 static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len) 957 { 958 struct wil6210_priv *wil = vif_to_wil(vif); 959 struct net_device *ndev = vif_to_ndev(vif); 960 struct wireless_dev *wdev = vif_to_wdev(vif); 961 struct wmi_connect_event *evt = d; 962 int ch; /* channel number */ 963 struct station_info *sinfo; 964 u8 *assoc_req_ie, *assoc_resp_ie; 965 size_t assoc_req_ielen, assoc_resp_ielen; 966 /* capinfo(u16) + listen_interval(u16) + IEs */ 967 const size_t assoc_req_ie_offset = sizeof(u16) * 2; 968 /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */ 969 const size_t assoc_resp_ie_offset = sizeof(u16) * 3; 970 int rc; 971 972 if (len < sizeof(*evt)) { 973 wil_err(wil, "Connect event too short : %d bytes\n", len); 974 return; 975 } 976 if (len != sizeof(*evt) + evt->beacon_ie_len + evt->assoc_req_len + 977 evt->assoc_resp_len) { 978 wil_err(wil, 979 "Connect event corrupted : %d != %d + %d + %d + %d\n", 980 len, (int)sizeof(*evt), evt->beacon_ie_len, 981 evt->assoc_req_len, evt->assoc_resp_len); 982 return; 983 } 984 if (evt->cid >= wil->max_assoc_sta) { 985 wil_err(wil, "Connect CID invalid : %d\n", evt->cid); 986 return; 987 } 988 989 ch = evt->channel + 1; 990 wil_info(wil, "Connect %pM channel [%d] cid %d aid %d\n", 991 evt->bssid, ch, evt->cid, evt->aid); 992 wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1, 993 evt->assoc_info, len - sizeof(*evt), true); 994 995 /* figure out IE's */ 996 assoc_req_ie = &evt->assoc_info[evt->beacon_ie_len + 997 assoc_req_ie_offset]; 998 assoc_req_ielen = evt->assoc_req_len - assoc_req_ie_offset; 999 if (evt->assoc_req_len <= assoc_req_ie_offset) { 1000 assoc_req_ie = NULL; 1001 assoc_req_ielen = 0; 1002 } 1003 1004 assoc_resp_ie = &evt->assoc_info[evt->beacon_ie_len + 1005 evt->assoc_req_len + 1006 assoc_resp_ie_offset]; 1007 assoc_resp_ielen = evt->assoc_resp_len - assoc_resp_ie_offset; 1008 if (evt->assoc_resp_len <= assoc_resp_ie_offset) { 1009 assoc_resp_ie = NULL; 1010 assoc_resp_ielen = 0; 1011 } 1012 1013 if (test_bit(wil_status_resetting, wil->status) || 1014 !test_bit(wil_status_fwready, wil->status)) { 1015 wil_err(wil, "status_resetting, cancel connect event, CID %d\n", 1016 evt->cid); 1017 /* no need for cleanup, wil_reset will do that */ 1018 return; 1019 } 1020 1021 mutex_lock(&wil->mutex); 1022 1023 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 1024 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 1025 if (!test_bit(wil_vif_fwconnecting, vif->status)) { 1026 wil_err(wil, "Not in connecting state\n"); 1027 mutex_unlock(&wil->mutex); 1028 return; 1029 } 1030 del_timer_sync(&vif->connect_timer); 1031 } else if ((wdev->iftype == NL80211_IFTYPE_AP) || 1032 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { 1033 if (wil->sta[evt->cid].status != wil_sta_unused) { 1034 wil_err(wil, "AP: Invalid status %d for CID %d\n", 1035 wil->sta[evt->cid].status, evt->cid); 1036 mutex_unlock(&wil->mutex); 1037 return; 1038 } 1039 } 1040 1041 ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid); 1042 wil->sta[evt->cid].mid = vif->mid; 1043 wil->sta[evt->cid].status = wil_sta_conn_pending; 1044 1045 rc = wil_ring_init_tx(vif, evt->cid); 1046 if (rc) { 1047 wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n", 1048 evt->cid, rc); 1049 wmi_disconnect_sta(vif, wil->sta[evt->cid].addr, 1050 WLAN_REASON_UNSPECIFIED, false); 1051 } else { 1052 wil_info(wil, "successful connection to CID %d\n", evt->cid); 1053 } 1054 1055 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 1056 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 1057 if (rc) { 1058 netif_carrier_off(ndev); 1059 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); 1060 wil_err(wil, "cfg80211_connect_result with failure\n"); 1061 cfg80211_connect_result(ndev, evt->bssid, NULL, 0, 1062 NULL, 0, 1063 WLAN_STATUS_UNSPECIFIED_FAILURE, 1064 GFP_KERNEL); 1065 goto out; 1066 } else { 1067 struct wiphy *wiphy = wil_to_wiphy(wil); 1068 1069 cfg80211_ref_bss(wiphy, vif->bss); 1070 cfg80211_connect_bss(ndev, evt->bssid, vif->bss, 1071 assoc_req_ie, assoc_req_ielen, 1072 assoc_resp_ie, assoc_resp_ielen, 1073 WLAN_STATUS_SUCCESS, GFP_KERNEL, 1074 NL80211_TIMEOUT_UNSPECIFIED); 1075 } 1076 vif->bss = NULL; 1077 } else if ((wdev->iftype == NL80211_IFTYPE_AP) || 1078 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { 1079 1080 if (rc) { 1081 if (disable_ap_sme) 1082 /* notify new_sta has failed */ 1083 cfg80211_del_sta(ndev, evt->bssid, GFP_KERNEL); 1084 goto out; 1085 } 1086 1087 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); 1088 if (!sinfo) { 1089 rc = -ENOMEM; 1090 goto out; 1091 } 1092 1093 sinfo->generation = wil->sinfo_gen++; 1094 1095 if (assoc_req_ie) { 1096 sinfo->assoc_req_ies = assoc_req_ie; 1097 sinfo->assoc_req_ies_len = assoc_req_ielen; 1098 } 1099 1100 cfg80211_new_sta(ndev, evt->bssid, sinfo, GFP_KERNEL); 1101 1102 kfree(sinfo); 1103 } else { 1104 wil_err(wil, "unhandled iftype %d for CID %d\n", wdev->iftype, 1105 evt->cid); 1106 goto out; 1107 } 1108 1109 wil->sta[evt->cid].status = wil_sta_connected; 1110 wil->sta[evt->cid].aid = evt->aid; 1111 if (!test_and_set_bit(wil_vif_fwconnected, vif->status)) 1112 atomic_inc(&wil->connected_vifs); 1113 wil_update_net_queues_bh(wil, vif, NULL, false); 1114 1115 out: 1116 if (rc) { 1117 wil->sta[evt->cid].status = wil_sta_unused; 1118 wil->sta[evt->cid].mid = U8_MAX; 1119 } 1120 clear_bit(wil_vif_fwconnecting, vif->status); 1121 mutex_unlock(&wil->mutex); 1122 } 1123 1124 static void wmi_evt_disconnect(struct wil6210_vif *vif, int id, 1125 void *d, int len) 1126 { 1127 struct wil6210_priv *wil = vif_to_wil(vif); 1128 struct wmi_disconnect_event *evt = d; 1129 u16 reason_code = le16_to_cpu(evt->protocol_reason_status); 1130 1131 wil_info(wil, "Disconnect %pM reason [proto %d wmi %d]\n", 1132 evt->bssid, reason_code, evt->disconnect_reason); 1133 1134 wil->sinfo_gen++; 1135 1136 if (test_bit(wil_status_resetting, wil->status) || 1137 !test_bit(wil_status_fwready, wil->status)) { 1138 wil_err(wil, "status_resetting, cancel disconnect event\n"); 1139 /* no need for cleanup, wil_reset will do that */ 1140 return; 1141 } 1142 1143 mutex_lock(&wil->mutex); 1144 wil6210_disconnect_complete(vif, evt->bssid, reason_code); 1145 if (disable_ap_sme) { 1146 struct wireless_dev *wdev = vif_to_wdev(vif); 1147 struct net_device *ndev = vif_to_ndev(vif); 1148 1149 /* disconnect event in disable_ap_sme mode means link loss */ 1150 switch (wdev->iftype) { 1151 /* AP-like interface */ 1152 case NL80211_IFTYPE_AP: 1153 case NL80211_IFTYPE_P2P_GO: 1154 /* notify hostapd about link loss */ 1155 cfg80211_cqm_pktloss_notify(ndev, evt->bssid, 0, 1156 GFP_KERNEL); 1157 break; 1158 default: 1159 break; 1160 } 1161 } 1162 mutex_unlock(&wil->mutex); 1163 } 1164 1165 /* 1166 * Firmware reports EAPOL frame using WME event. 1167 * Reconstruct Ethernet frame and deliver it via normal Rx 1168 */ 1169 static void wmi_evt_eapol_rx(struct wil6210_vif *vif, int id, void *d, int len) 1170 { 1171 struct wil6210_priv *wil = vif_to_wil(vif); 1172 struct net_device *ndev = vif_to_ndev(vif); 1173 struct wmi_eapol_rx_event *evt = d; 1174 u16 eapol_len = le16_to_cpu(evt->eapol_len); 1175 int sz = eapol_len + ETH_HLEN; 1176 struct sk_buff *skb; 1177 struct ethhdr *eth; 1178 int cid; 1179 struct wil_net_stats *stats = NULL; 1180 1181 wil_dbg_wmi(wil, "EAPOL len %d from %pM MID %d\n", eapol_len, 1182 evt->src_mac, vif->mid); 1183 1184 cid = wil_find_cid(wil, vif->mid, evt->src_mac); 1185 if (cid >= 0) 1186 stats = &wil->sta[cid].stats; 1187 1188 if (eapol_len > 196) { /* TODO: revisit size limit */ 1189 wil_err(wil, "EAPOL too large\n"); 1190 return; 1191 } 1192 1193 skb = alloc_skb(sz, GFP_KERNEL); 1194 if (!skb) { 1195 wil_err(wil, "Failed to allocate skb\n"); 1196 return; 1197 } 1198 1199 eth = skb_put(skb, ETH_HLEN); 1200 ether_addr_copy(eth->h_dest, ndev->dev_addr); 1201 ether_addr_copy(eth->h_source, evt->src_mac); 1202 eth->h_proto = cpu_to_be16(ETH_P_PAE); 1203 skb_put_data(skb, evt->eapol, eapol_len); 1204 skb->protocol = eth_type_trans(skb, ndev); 1205 if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) { 1206 ndev->stats.rx_packets++; 1207 ndev->stats.rx_bytes += sz; 1208 if (stats) { 1209 stats->rx_packets++; 1210 stats->rx_bytes += sz; 1211 } 1212 } else { 1213 ndev->stats.rx_dropped++; 1214 if (stats) 1215 stats->rx_dropped++; 1216 } 1217 } 1218 1219 static void wmi_evt_ring_en(struct wil6210_vif *vif, int id, void *d, int len) 1220 { 1221 struct wil6210_priv *wil = vif_to_wil(vif); 1222 struct wmi_ring_en_event *evt = d; 1223 u8 vri = evt->ring_index; 1224 struct wireless_dev *wdev = vif_to_wdev(vif); 1225 struct wil_sta_info *sta; 1226 u8 cid; 1227 struct key_params params; 1228 1229 wil_dbg_wmi(wil, "Enable vring %d MID %d\n", vri, vif->mid); 1230 1231 if (vri >= ARRAY_SIZE(wil->ring_tx)) { 1232 wil_err(wil, "Enable for invalid vring %d\n", vri); 1233 return; 1234 } 1235 1236 if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme || 1237 test_bit(wil_vif_ft_roam, vif->status)) 1238 /* in AP mode with disable_ap_sme that is not FT, 1239 * this is done by wil_cfg80211_change_station() 1240 */ 1241 wil->ring_tx_data[vri].dot1x_open = true; 1242 if (vri == vif->bcast_ring) /* no BA for bcast */ 1243 return; 1244 1245 cid = wil->ring2cid_tid[vri][0]; 1246 if (!wil_cid_valid(wil, cid)) { 1247 wil_err(wil, "invalid cid %d for vring %d\n", cid, vri); 1248 return; 1249 } 1250 1251 /* In FT mode we get key but not store it as it is received 1252 * before WMI_CONNECT_EVENT received from FW. 1253 * wil_set_crypto_rx is called here to reset the security PN 1254 */ 1255 sta = &wil->sta[cid]; 1256 if (test_bit(wil_vif_ft_roam, vif->status)) { 1257 memset(¶ms, 0, sizeof(params)); 1258 wil_set_crypto_rx(0, WMI_KEY_USE_PAIRWISE, sta, ¶ms); 1259 if (wdev->iftype != NL80211_IFTYPE_AP) 1260 clear_bit(wil_vif_ft_roam, vif->status); 1261 } 1262 1263 if (agg_wsize >= 0) 1264 wil_addba_tx_request(wil, vri, agg_wsize); 1265 } 1266 1267 static void wmi_evt_ba_status(struct wil6210_vif *vif, int id, 1268 void *d, int len) 1269 { 1270 struct wil6210_priv *wil = vif_to_wil(vif); 1271 struct wmi_ba_status_event *evt = d; 1272 struct wil_ring_tx_data *txdata; 1273 1274 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d AMSDU%s\n", 1275 evt->ringid, 1276 evt->status == WMI_BA_AGREED ? "OK" : "N/A", 1277 evt->agg_wsize, __le16_to_cpu(evt->ba_timeout), 1278 evt->amsdu ? "+" : "-"); 1279 1280 if (evt->ringid >= WIL6210_MAX_TX_RINGS) { 1281 wil_err(wil, "invalid ring id %d\n", evt->ringid); 1282 return; 1283 } 1284 1285 if (evt->status != WMI_BA_AGREED) { 1286 evt->ba_timeout = 0; 1287 evt->agg_wsize = 0; 1288 evt->amsdu = 0; 1289 } 1290 1291 txdata = &wil->ring_tx_data[evt->ringid]; 1292 1293 txdata->agg_timeout = le16_to_cpu(evt->ba_timeout); 1294 txdata->agg_wsize = evt->agg_wsize; 1295 txdata->agg_amsdu = evt->amsdu; 1296 txdata->addba_in_progress = false; 1297 } 1298 1299 static void wmi_evt_addba_rx_req(struct wil6210_vif *vif, int id, 1300 void *d, int len) 1301 { 1302 struct wil6210_priv *wil = vif_to_wil(vif); 1303 u8 cid, tid; 1304 struct wmi_rcp_addba_req_event *evt = d; 1305 1306 if (evt->cidxtid != CIDXTID_EXTENDED_CID_TID) { 1307 parse_cidxtid(evt->cidxtid, &cid, &tid); 1308 } else { 1309 cid = evt->cid; 1310 tid = evt->tid; 1311 } 1312 wil_addba_rx_request(wil, vif->mid, cid, tid, evt->dialog_token, 1313 evt->ba_param_set, evt->ba_timeout, 1314 evt->ba_seq_ctrl); 1315 } 1316 1317 static void wmi_evt_delba(struct wil6210_vif *vif, int id, void *d, int len) 1318 __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) 1319 { 1320 struct wil6210_priv *wil = vif_to_wil(vif); 1321 struct wmi_delba_event *evt = d; 1322 u8 cid, tid; 1323 u16 reason = __le16_to_cpu(evt->reason); 1324 struct wil_sta_info *sta; 1325 struct wil_tid_ampdu_rx *r; 1326 1327 might_sleep(); 1328 1329 if (evt->cidxtid != CIDXTID_EXTENDED_CID_TID) { 1330 parse_cidxtid(evt->cidxtid, &cid, &tid); 1331 } else { 1332 cid = evt->cid; 1333 tid = evt->tid; 1334 } 1335 wil_dbg_wmi(wil, "DELBA MID %d CID %d TID %d from %s reason %d\n", 1336 vif->mid, cid, tid, 1337 evt->from_initiator ? "originator" : "recipient", 1338 reason); 1339 if (!evt->from_initiator) { 1340 int i; 1341 /* find Tx vring it belongs to */ 1342 for (i = 0; i < ARRAY_SIZE(wil->ring2cid_tid); i++) { 1343 if (wil->ring2cid_tid[i][0] == cid && 1344 wil->ring2cid_tid[i][1] == tid) { 1345 struct wil_ring_tx_data *txdata = 1346 &wil->ring_tx_data[i]; 1347 1348 wil_dbg_wmi(wil, "DELBA Tx vring %d\n", i); 1349 txdata->agg_timeout = 0; 1350 txdata->agg_wsize = 0; 1351 txdata->addba_in_progress = false; 1352 1353 break; /* max. 1 matching ring */ 1354 } 1355 } 1356 if (i >= ARRAY_SIZE(wil->ring2cid_tid)) 1357 wil_err(wil, "DELBA: unable to find Tx vring\n"); 1358 return; 1359 } 1360 1361 sta = &wil->sta[cid]; 1362 1363 spin_lock_bh(&sta->tid_rx_lock); 1364 1365 r = sta->tid_rx[tid]; 1366 sta->tid_rx[tid] = NULL; 1367 wil_tid_ampdu_rx_free(wil, r); 1368 1369 spin_unlock_bh(&sta->tid_rx_lock); 1370 } 1371 1372 static void 1373 wmi_evt_sched_scan_result(struct wil6210_vif *vif, int id, void *d, int len) 1374 { 1375 struct wil6210_priv *wil = vif_to_wil(vif); 1376 struct wmi_sched_scan_result_event *data = d; 1377 struct wiphy *wiphy = wil_to_wiphy(wil); 1378 struct ieee80211_mgmt *rx_mgmt_frame = 1379 (struct ieee80211_mgmt *)data->payload; 1380 int flen = len - offsetof(struct wmi_sched_scan_result_event, payload); 1381 int ch_no; 1382 u32 freq; 1383 struct ieee80211_channel *channel; 1384 s32 signal; 1385 __le16 fc; 1386 u32 d_len; 1387 struct cfg80211_bss *bss; 1388 1389 if (flen < 0) { 1390 wil_err(wil, "sched scan result event too short, len %d\n", 1391 len); 1392 return; 1393 } 1394 1395 d_len = le32_to_cpu(data->info.len); 1396 if (d_len != flen) { 1397 wil_err(wil, 1398 "sched scan result length mismatch, d_len %d should be %d\n", 1399 d_len, flen); 1400 return; 1401 } 1402 1403 fc = rx_mgmt_frame->frame_control; 1404 if (!ieee80211_is_probe_resp(fc)) { 1405 wil_err(wil, "sched scan result invalid frame, fc 0x%04x\n", 1406 fc); 1407 return; 1408 } 1409 1410 ch_no = data->info.channel + 1; 1411 freq = ieee80211_channel_to_frequency(ch_no, NL80211_BAND_60GHZ); 1412 channel = ieee80211_get_channel(wiphy, freq); 1413 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities)) 1414 signal = 100 * data->info.rssi; 1415 else 1416 signal = data->info.sqi; 1417 1418 wil_dbg_wmi(wil, "sched scan result: channel %d MCS %d RSSI %d\n", 1419 data->info.channel, data->info.mcs, data->info.rssi); 1420 wil_dbg_wmi(wil, "len %d qid %d mid %d cid %d\n", 1421 d_len, data->info.qid, data->info.mid, data->info.cid); 1422 wil_hex_dump_wmi("PROBE ", DUMP_PREFIX_OFFSET, 16, 1, rx_mgmt_frame, 1423 d_len, true); 1424 1425 if (!channel) { 1426 wil_err(wil, "Frame on unsupported channel\n"); 1427 return; 1428 } 1429 1430 bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, 1431 d_len, signal, GFP_KERNEL); 1432 if (bss) { 1433 wil_dbg_wmi(wil, "Added BSS %pM\n", rx_mgmt_frame->bssid); 1434 cfg80211_put_bss(wiphy, bss); 1435 } else { 1436 wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); 1437 } 1438 1439 cfg80211_sched_scan_results(wiphy, 0); 1440 } 1441 1442 static void wil_link_stats_store_basic(struct wil6210_vif *vif, 1443 struct wmi_link_stats_basic *basic) 1444 { 1445 struct wil6210_priv *wil = vif_to_wil(vif); 1446 u8 cid = basic->cid; 1447 struct wil_sta_info *sta; 1448 1449 if (cid < 0 || cid >= wil->max_assoc_sta) { 1450 wil_err(wil, "invalid cid %d\n", cid); 1451 return; 1452 } 1453 1454 sta = &wil->sta[cid]; 1455 sta->fw_stats_basic = *basic; 1456 } 1457 1458 static void wil_link_stats_store_global(struct wil6210_vif *vif, 1459 struct wmi_link_stats_global *global) 1460 { 1461 struct wil6210_priv *wil = vif_to_wil(vif); 1462 1463 wil->fw_stats_global.stats = *global; 1464 } 1465 1466 static void wmi_link_stats_parse(struct wil6210_vif *vif, u64 tsf, 1467 bool has_next, void *payload, 1468 size_t payload_size) 1469 { 1470 struct wil6210_priv *wil = vif_to_wil(vif); 1471 size_t hdr_size = sizeof(struct wmi_link_stats_record); 1472 size_t stats_size, record_size, expected_size; 1473 struct wmi_link_stats_record *hdr; 1474 1475 if (payload_size < hdr_size) { 1476 wil_err(wil, "link stats wrong event size %zu\n", payload_size); 1477 return; 1478 } 1479 1480 while (payload_size >= hdr_size) { 1481 hdr = payload; 1482 stats_size = le16_to_cpu(hdr->record_size); 1483 record_size = hdr_size + stats_size; 1484 1485 if (payload_size < record_size) { 1486 wil_err(wil, "link stats payload ended unexpectedly, size %zu < %zu\n", 1487 payload_size, record_size); 1488 return; 1489 } 1490 1491 switch (hdr->record_type_id) { 1492 case WMI_LINK_STATS_TYPE_BASIC: 1493 expected_size = sizeof(struct wmi_link_stats_basic); 1494 if (stats_size < expected_size) { 1495 wil_err(wil, "link stats invalid basic record size %zu < %zu\n", 1496 stats_size, expected_size); 1497 return; 1498 } 1499 if (vif->fw_stats_ready) { 1500 /* clean old statistics */ 1501 vif->fw_stats_tsf = 0; 1502 vif->fw_stats_ready = 0; 1503 } 1504 1505 wil_link_stats_store_basic(vif, payload + hdr_size); 1506 1507 if (!has_next) { 1508 vif->fw_stats_tsf = tsf; 1509 vif->fw_stats_ready = 1; 1510 } 1511 1512 break; 1513 case WMI_LINK_STATS_TYPE_GLOBAL: 1514 expected_size = sizeof(struct wmi_link_stats_global); 1515 if (stats_size < sizeof(struct wmi_link_stats_global)) { 1516 wil_err(wil, "link stats invalid global record size %zu < %zu\n", 1517 stats_size, expected_size); 1518 return; 1519 } 1520 1521 if (wil->fw_stats_global.ready) { 1522 /* clean old statistics */ 1523 wil->fw_stats_global.tsf = 0; 1524 wil->fw_stats_global.ready = 0; 1525 } 1526 1527 wil_link_stats_store_global(vif, payload + hdr_size); 1528 1529 if (!has_next) { 1530 wil->fw_stats_global.tsf = tsf; 1531 wil->fw_stats_global.ready = 1; 1532 } 1533 1534 break; 1535 default: 1536 break; 1537 } 1538 1539 /* skip to next record */ 1540 payload += record_size; 1541 payload_size -= record_size; 1542 } 1543 } 1544 1545 static void 1546 wmi_evt_link_stats(struct wil6210_vif *vif, int id, void *d, int len) 1547 { 1548 struct wil6210_priv *wil = vif_to_wil(vif); 1549 struct wmi_link_stats_event *evt = d; 1550 size_t payload_size; 1551 1552 if (len < offsetof(struct wmi_link_stats_event, payload)) { 1553 wil_err(wil, "stats event way too short %d\n", len); 1554 return; 1555 } 1556 payload_size = le16_to_cpu(evt->payload_size); 1557 if (len < sizeof(struct wmi_link_stats_event) + payload_size) { 1558 wil_err(wil, "stats event too short %d\n", len); 1559 return; 1560 } 1561 1562 wmi_link_stats_parse(vif, le64_to_cpu(evt->tsf), evt->has_next, 1563 evt->payload, payload_size); 1564 } 1565 1566 /** 1567 * find cid and ringid for the station vif 1568 * 1569 * return error, if other interfaces are used or ring was not found 1570 */ 1571 static int wil_find_cid_ringid_sta(struct wil6210_priv *wil, 1572 struct wil6210_vif *vif, 1573 int *cid, 1574 int *ringid) 1575 { 1576 struct wil_ring *ring; 1577 struct wil_ring_tx_data *txdata; 1578 int min_ring_id = wil_get_min_tx_ring_id(wil); 1579 int i; 1580 u8 lcid; 1581 1582 if (!(vif->wdev.iftype == NL80211_IFTYPE_STATION || 1583 vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) { 1584 wil_err(wil, "invalid interface type %d\n", vif->wdev.iftype); 1585 return -EINVAL; 1586 } 1587 1588 /* In the STA mode, it is expected to have only one ring 1589 * for the AP we are connected to. 1590 * find it and return the cid associated with it. 1591 */ 1592 for (i = min_ring_id; i < WIL6210_MAX_TX_RINGS; i++) { 1593 ring = &wil->ring_tx[i]; 1594 txdata = &wil->ring_tx_data[i]; 1595 if (!ring->va || !txdata->enabled || txdata->mid != vif->mid) 1596 continue; 1597 1598 lcid = wil->ring2cid_tid[i][0]; 1599 if (lcid >= wil->max_assoc_sta) /* skip BCAST */ 1600 continue; 1601 1602 wil_dbg_wmi(wil, "find sta -> ringid %d cid %d\n", i, lcid); 1603 *cid = lcid; 1604 *ringid = i; 1605 return 0; 1606 } 1607 1608 wil_dbg_wmi(wil, "find sta cid while no rings active?\n"); 1609 1610 return -ENOENT; 1611 } 1612 1613 static void 1614 wmi_evt_auth_status(struct wil6210_vif *vif, int id, void *d, int len) 1615 { 1616 struct wil6210_priv *wil = vif_to_wil(vif); 1617 struct net_device *ndev = vif_to_ndev(vif); 1618 struct wmi_ft_auth_status_event *data = d; 1619 int ie_len = len - offsetof(struct wmi_ft_auth_status_event, ie_info); 1620 int rc, cid = 0, ringid = 0; 1621 struct cfg80211_ft_event_params ft; 1622 u16 d_len; 1623 /* auth_alg(u16) + auth_transaction(u16) + status_code(u16) */ 1624 const size_t auth_ie_offset = sizeof(u16) * 3; 1625 struct auth_no_hdr *auth = (struct auth_no_hdr *)data->ie_info; 1626 1627 /* check the status */ 1628 if (ie_len >= 0 && data->status != WMI_FW_STATUS_SUCCESS) { 1629 wil_err(wil, "FT: auth failed. status %d\n", data->status); 1630 goto fail; 1631 } 1632 1633 if (ie_len < auth_ie_offset) { 1634 wil_err(wil, "FT: auth event too short, len %d\n", len); 1635 goto fail; 1636 } 1637 1638 d_len = le16_to_cpu(data->ie_len); 1639 if (d_len != ie_len) { 1640 wil_err(wil, 1641 "FT: auth ie length mismatch, d_len %d should be %d\n", 1642 d_len, ie_len); 1643 goto fail; 1644 } 1645 1646 if (!test_bit(wil_vif_ft_roam, wil->status)) { 1647 wil_err(wil, "FT: Not in roaming state\n"); 1648 goto fail; 1649 } 1650 1651 if (le16_to_cpu(auth->auth_transaction) != 2) { 1652 wil_err(wil, "FT: auth error. auth_transaction %d\n", 1653 le16_to_cpu(auth->auth_transaction)); 1654 goto fail; 1655 } 1656 1657 if (le16_to_cpu(auth->auth_alg) != WLAN_AUTH_FT) { 1658 wil_err(wil, "FT: auth error. auth_alg %d\n", 1659 le16_to_cpu(auth->auth_alg)); 1660 goto fail; 1661 } 1662 1663 wil_dbg_wmi(wil, "FT: Auth to %pM successfully\n", data->mac_addr); 1664 wil_hex_dump_wmi("FT Auth ies : ", DUMP_PREFIX_OFFSET, 16, 1, 1665 data->ie_info, d_len, true); 1666 1667 /* find cid and ringid */ 1668 rc = wil_find_cid_ringid_sta(wil, vif, &cid, &ringid); 1669 if (rc) { 1670 wil_err(wil, "No valid cid found\n"); 1671 goto fail; 1672 } 1673 1674 if (vif->privacy) { 1675 /* For secure assoc, remove old keys */ 1676 rc = wmi_del_cipher_key(vif, 0, wil->sta[cid].addr, 1677 WMI_KEY_USE_PAIRWISE); 1678 if (rc) { 1679 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n"); 1680 goto fail; 1681 } 1682 rc = wmi_del_cipher_key(vif, 0, wil->sta[cid].addr, 1683 WMI_KEY_USE_RX_GROUP); 1684 if (rc) { 1685 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n"); 1686 goto fail; 1687 } 1688 } 1689 1690 memset(&ft, 0, sizeof(ft)); 1691 ft.ies = data->ie_info + auth_ie_offset; 1692 ft.ies_len = d_len - auth_ie_offset; 1693 ft.target_ap = data->mac_addr; 1694 cfg80211_ft_event(ndev, &ft); 1695 1696 return; 1697 1698 fail: 1699 wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID); 1700 } 1701 1702 static void 1703 wmi_evt_reassoc_status(struct wil6210_vif *vif, int id, void *d, int len) 1704 { 1705 struct wil6210_priv *wil = vif_to_wil(vif); 1706 struct net_device *ndev = vif_to_ndev(vif); 1707 struct wiphy *wiphy = wil_to_wiphy(wil); 1708 struct wmi_ft_reassoc_status_event *data = d; 1709 int ies_len = len - offsetof(struct wmi_ft_reassoc_status_event, 1710 ie_info); 1711 int rc = -ENOENT, cid = 0, ringid = 0; 1712 int ch; /* channel number (primary) */ 1713 size_t assoc_req_ie_len = 0, assoc_resp_ie_len = 0; 1714 u8 *assoc_req_ie = NULL, *assoc_resp_ie = NULL; 1715 /* capinfo(u16) + listen_interval(u16) + current_ap mac addr + IEs */ 1716 const size_t assoc_req_ie_offset = sizeof(u16) * 2 + ETH_ALEN; 1717 /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */ 1718 const size_t assoc_resp_ie_offset = sizeof(u16) * 3; 1719 u16 d_len; 1720 int freq; 1721 struct cfg80211_roam_info info; 1722 1723 if (ies_len < 0) { 1724 wil_err(wil, "ft reassoc event too short, len %d\n", len); 1725 goto fail; 1726 } 1727 1728 wil_dbg_wmi(wil, "Reasoc Status event: status=%d, aid=%d", 1729 data->status, data->aid); 1730 wil_dbg_wmi(wil, " mac_addr=%pM, beacon_ie_len=%d", 1731 data->mac_addr, data->beacon_ie_len); 1732 wil_dbg_wmi(wil, " reassoc_req_ie_len=%d, reassoc_resp_ie_len=%d", 1733 le16_to_cpu(data->reassoc_req_ie_len), 1734 le16_to_cpu(data->reassoc_resp_ie_len)); 1735 1736 d_len = le16_to_cpu(data->beacon_ie_len) + 1737 le16_to_cpu(data->reassoc_req_ie_len) + 1738 le16_to_cpu(data->reassoc_resp_ie_len); 1739 if (d_len != ies_len) { 1740 wil_err(wil, 1741 "ft reassoc ie length mismatch, d_len %d should be %d\n", 1742 d_len, ies_len); 1743 goto fail; 1744 } 1745 1746 /* check the status */ 1747 if (data->status != WMI_FW_STATUS_SUCCESS) { 1748 wil_err(wil, "ft reassoc failed. status %d\n", data->status); 1749 goto fail; 1750 } 1751 1752 /* find cid and ringid */ 1753 rc = wil_find_cid_ringid_sta(wil, vif, &cid, &ringid); 1754 if (rc) { 1755 wil_err(wil, "No valid cid found\n"); 1756 goto fail; 1757 } 1758 1759 ch = data->channel + 1; 1760 wil_info(wil, "FT: Roam %pM channel [%d] cid %d aid %d\n", 1761 data->mac_addr, ch, cid, data->aid); 1762 1763 wil_hex_dump_wmi("reassoc AI : ", DUMP_PREFIX_OFFSET, 16, 1, 1764 data->ie_info, len - sizeof(*data), true); 1765 1766 /* figure out IE's */ 1767 if (le16_to_cpu(data->reassoc_req_ie_len) > assoc_req_ie_offset) { 1768 assoc_req_ie = &data->ie_info[assoc_req_ie_offset]; 1769 assoc_req_ie_len = le16_to_cpu(data->reassoc_req_ie_len) - 1770 assoc_req_ie_offset; 1771 } 1772 if (le16_to_cpu(data->reassoc_resp_ie_len) <= assoc_resp_ie_offset) { 1773 wil_err(wil, "FT: reassoc resp ie len is too short, len %d\n", 1774 le16_to_cpu(data->reassoc_resp_ie_len)); 1775 goto fail; 1776 } 1777 1778 assoc_resp_ie = &data->ie_info[le16_to_cpu(data->reassoc_req_ie_len) + 1779 assoc_resp_ie_offset]; 1780 assoc_resp_ie_len = le16_to_cpu(data->reassoc_resp_ie_len) - 1781 assoc_resp_ie_offset; 1782 1783 if (test_bit(wil_status_resetting, wil->status) || 1784 !test_bit(wil_status_fwready, wil->status)) { 1785 wil_err(wil, "FT: status_resetting, cancel reassoc event\n"); 1786 /* no need for cleanup, wil_reset will do that */ 1787 return; 1788 } 1789 1790 mutex_lock(&wil->mutex); 1791 1792 /* ring modify to set the ring for the roamed AP settings */ 1793 wil_dbg_wmi(wil, 1794 "ft modify tx config for connection CID %d ring %d\n", 1795 cid, ringid); 1796 1797 rc = wil->txrx_ops.tx_ring_modify(vif, ringid, cid, 0); 1798 if (rc) { 1799 wil_err(wil, "modify TX for CID %d MID %d ring %d failed (%d)\n", 1800 cid, vif->mid, ringid, rc); 1801 mutex_unlock(&wil->mutex); 1802 goto fail; 1803 } 1804 1805 /* Update the driver STA members with the new bss */ 1806 wil->sta[cid].aid = data->aid; 1807 wil->sta[cid].stats.ft_roams++; 1808 ether_addr_copy(wil->sta[cid].addr, vif->bss->bssid); 1809 mutex_unlock(&wil->mutex); 1810 del_timer_sync(&vif->connect_timer); 1811 1812 cfg80211_ref_bss(wiphy, vif->bss); 1813 freq = ieee80211_channel_to_frequency(ch, NL80211_BAND_60GHZ); 1814 1815 memset(&info, 0, sizeof(info)); 1816 info.channel = ieee80211_get_channel(wiphy, freq); 1817 info.bss = vif->bss; 1818 info.req_ie = assoc_req_ie; 1819 info.req_ie_len = assoc_req_ie_len; 1820 info.resp_ie = assoc_resp_ie; 1821 info.resp_ie_len = assoc_resp_ie_len; 1822 cfg80211_roamed(ndev, &info, GFP_KERNEL); 1823 vif->bss = NULL; 1824 1825 return; 1826 1827 fail: 1828 wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID); 1829 } 1830 1831 /** 1832 * Some events are ignored for purpose; and need not be interpreted as 1833 * "unhandled events" 1834 */ 1835 static void wmi_evt_ignore(struct wil6210_vif *vif, int id, void *d, int len) 1836 { 1837 struct wil6210_priv *wil = vif_to_wil(vif); 1838 1839 wil_dbg_wmi(wil, "Ignore event 0x%04x len %d\n", id, len); 1840 } 1841 1842 static const struct { 1843 int eventid; 1844 void (*handler)(struct wil6210_vif *vif, 1845 int eventid, void *data, int data_len); 1846 } wmi_evt_handlers[] = { 1847 {WMI_READY_EVENTID, wmi_evt_ready}, 1848 {WMI_FW_READY_EVENTID, wmi_evt_ignore}, 1849 {WMI_RX_MGMT_PACKET_EVENTID, wmi_evt_rx_mgmt}, 1850 {WMI_TX_MGMT_PACKET_EVENTID, wmi_evt_tx_mgmt}, 1851 {WMI_SCAN_COMPLETE_EVENTID, wmi_evt_scan_complete}, 1852 {WMI_CONNECT_EVENTID, wmi_evt_connect}, 1853 {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, 1854 {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, 1855 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status}, 1856 {WMI_RCP_ADDBA_REQ_EVENTID, wmi_evt_addba_rx_req}, 1857 {WMI_DELBA_EVENTID, wmi_evt_delba}, 1858 {WMI_RING_EN_EVENTID, wmi_evt_ring_en}, 1859 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_ignore}, 1860 {WMI_SCHED_SCAN_RESULT_EVENTID, wmi_evt_sched_scan_result}, 1861 {WMI_LINK_STATS_EVENTID, wmi_evt_link_stats}, 1862 {WMI_FT_AUTH_STATUS_EVENTID, wmi_evt_auth_status}, 1863 {WMI_FT_REASSOC_STATUS_EVENTID, wmi_evt_reassoc_status}, 1864 }; 1865 1866 /* 1867 * Run in IRQ context 1868 * Extract WMI command from mailbox. Queue it to the @wil->pending_wmi_ev 1869 * that will be eventually handled by the @wmi_event_worker in the thread 1870 * context of thread "wil6210_wmi" 1871 */ 1872 void wmi_recv_cmd(struct wil6210_priv *wil) 1873 { 1874 struct wil6210_mbox_ring_desc d_tail; 1875 struct wil6210_mbox_hdr hdr; 1876 struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx; 1877 struct pending_wmi_event *evt; 1878 u8 *cmd; 1879 void __iomem *src; 1880 ulong flags; 1881 unsigned n; 1882 unsigned int num_immed_reply = 0; 1883 1884 if (!test_bit(wil_status_mbox_ready, wil->status)) { 1885 wil_err(wil, "Reset in progress. Cannot handle WMI event\n"); 1886 return; 1887 } 1888 1889 if (test_bit(wil_status_suspended, wil->status)) { 1890 wil_err(wil, "suspended. cannot handle WMI event\n"); 1891 return; 1892 } 1893 1894 for (n = 0;; n++) { 1895 u16 len; 1896 bool q; 1897 bool immed_reply = false; 1898 1899 r->head = wil_r(wil, RGF_MBOX + 1900 offsetof(struct wil6210_mbox_ctl, rx.head)); 1901 if (r->tail == r->head) 1902 break; 1903 1904 wil_dbg_wmi(wil, "Mbox head %08x tail %08x\n", 1905 r->head, r->tail); 1906 /* read cmd descriptor from tail */ 1907 wil_memcpy_fromio_32(&d_tail, wil->csr + HOSTADDR(r->tail), 1908 sizeof(struct wil6210_mbox_ring_desc)); 1909 if (d_tail.sync == 0) { 1910 wil_err(wil, "Mbox evt not owned by FW?\n"); 1911 break; 1912 } 1913 1914 /* read cmd header from descriptor */ 1915 if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) { 1916 wil_err(wil, "Mbox evt at 0x%08x?\n", 1917 le32_to_cpu(d_tail.addr)); 1918 break; 1919 } 1920 len = le16_to_cpu(hdr.len); 1921 wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n", 1922 le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type), 1923 hdr.flags); 1924 1925 /* read cmd buffer from descriptor */ 1926 src = wmi_buffer(wil, d_tail.addr) + 1927 sizeof(struct wil6210_mbox_hdr); 1928 evt = kmalloc(ALIGN(offsetof(struct pending_wmi_event, 1929 event.wmi) + len, 4), 1930 GFP_KERNEL); 1931 if (!evt) 1932 break; 1933 1934 evt->event.hdr = hdr; 1935 cmd = (void *)&evt->event.wmi; 1936 wil_memcpy_fromio_32(cmd, src, len); 1937 /* mark entry as empty */ 1938 wil_w(wil, r->tail + 1939 offsetof(struct wil6210_mbox_ring_desc, sync), 0); 1940 /* indicate */ 1941 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) && 1942 (len >= sizeof(struct wmi_cmd_hdr))) { 1943 struct wmi_cmd_hdr *wmi = &evt->event.wmi; 1944 u16 id = le16_to_cpu(wmi->command_id); 1945 u8 mid = wmi->mid; 1946 u32 tstamp = le32_to_cpu(wmi->fw_timestamp); 1947 if (test_bit(wil_status_resuming, wil->status)) { 1948 if (id == WMI_TRAFFIC_RESUME_EVENTID) 1949 clear_bit(wil_status_resuming, 1950 wil->status); 1951 else 1952 wil_err(wil, 1953 "WMI evt %d while resuming\n", 1954 id); 1955 } 1956 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 1957 if (wil->reply_id && wil->reply_id == id && 1958 wil->reply_mid == mid) { 1959 if (wil->reply_buf) { 1960 memcpy(wil->reply_buf, wmi, 1961 min(len, wil->reply_size)); 1962 immed_reply = true; 1963 } 1964 if (id == WMI_TRAFFIC_SUSPEND_EVENTID) { 1965 wil_dbg_wmi(wil, 1966 "set suspend_resp_rcvd\n"); 1967 wil->suspend_resp_rcvd = true; 1968 } 1969 } 1970 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 1971 1972 wil_dbg_wmi(wil, "recv %s (0x%04x) MID %d @%d msec\n", 1973 eventid2name(id), id, wmi->mid, tstamp); 1974 trace_wil6210_wmi_event(wmi, &wmi[1], 1975 len - sizeof(*wmi)); 1976 } 1977 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1, 1978 &evt->event.hdr, sizeof(hdr) + len, true); 1979 1980 /* advance tail */ 1981 r->tail = r->base + ((r->tail - r->base + 1982 sizeof(struct wil6210_mbox_ring_desc)) % r->size); 1983 wil_w(wil, RGF_MBOX + 1984 offsetof(struct wil6210_mbox_ctl, rx.tail), r->tail); 1985 1986 if (immed_reply) { 1987 wil_dbg_wmi(wil, "recv_cmd: Complete WMI 0x%04x\n", 1988 wil->reply_id); 1989 kfree(evt); 1990 num_immed_reply++; 1991 complete(&wil->wmi_call); 1992 } else { 1993 /* add to the pending list */ 1994 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 1995 list_add_tail(&evt->list, &wil->pending_wmi_ev); 1996 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 1997 q = queue_work(wil->wmi_wq, &wil->wmi_event_worker); 1998 wil_dbg_wmi(wil, "queue_work -> %d\n", q); 1999 } 2000 } 2001 /* normally, 1 event per IRQ should be processed */ 2002 wil_dbg_wmi(wil, "recv_cmd: -> %d events queued, %d completed\n", 2003 n - num_immed_reply, num_immed_reply); 2004 } 2005 2006 int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len, 2007 u16 reply_id, void *reply, u16 reply_size, int to_msec) 2008 { 2009 int rc; 2010 unsigned long remain; 2011 ulong flags; 2012 2013 mutex_lock(&wil->wmi_mutex); 2014 2015 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 2016 wil->reply_id = reply_id; 2017 wil->reply_mid = mid; 2018 wil->reply_buf = reply; 2019 wil->reply_size = reply_size; 2020 reinit_completion(&wil->wmi_call); 2021 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 2022 2023 rc = __wmi_send(wil, cmdid, mid, buf, len); 2024 if (rc) 2025 goto out; 2026 2027 remain = wait_for_completion_timeout(&wil->wmi_call, 2028 msecs_to_jiffies(to_msec)); 2029 if (0 == remain) { 2030 wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n", 2031 cmdid, reply_id, to_msec); 2032 rc = -ETIME; 2033 } else { 2034 wil_dbg_wmi(wil, 2035 "wmi_call(0x%04x->0x%04x) completed in %d msec\n", 2036 cmdid, reply_id, 2037 to_msec - jiffies_to_msecs(remain)); 2038 } 2039 2040 out: 2041 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 2042 wil->reply_id = 0; 2043 wil->reply_mid = U8_MAX; 2044 wil->reply_buf = NULL; 2045 wil->reply_size = 0; 2046 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 2047 2048 mutex_unlock(&wil->wmi_mutex); 2049 2050 return rc; 2051 } 2052 2053 int wmi_echo(struct wil6210_priv *wil) 2054 { 2055 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2056 struct wmi_echo_cmd cmd = { 2057 .value = cpu_to_le32(0x12345678), 2058 }; 2059 2060 return wmi_call(wil, WMI_ECHO_CMDID, vif->mid, &cmd, sizeof(cmd), 2061 WMI_ECHO_RSP_EVENTID, NULL, 0, 2062 WIL_WMI_CALL_GENERAL_TO_MS); 2063 } 2064 2065 int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) 2066 { 2067 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2068 struct wmi_set_mac_address_cmd cmd; 2069 2070 ether_addr_copy(cmd.mac, addr); 2071 2072 wil_dbg_wmi(wil, "Set MAC %pM\n", addr); 2073 2074 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, vif->mid, 2075 &cmd, sizeof(cmd)); 2076 } 2077 2078 int wmi_led_cfg(struct wil6210_priv *wil, bool enable) 2079 { 2080 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2081 int rc = 0; 2082 struct wmi_led_cfg_cmd cmd = { 2083 .led_mode = enable, 2084 .id = led_id, 2085 .slow_blink_cfg.blink_on = 2086 cpu_to_le32(led_blink_time[WIL_LED_TIME_SLOW].on_ms), 2087 .slow_blink_cfg.blink_off = 2088 cpu_to_le32(led_blink_time[WIL_LED_TIME_SLOW].off_ms), 2089 .medium_blink_cfg.blink_on = 2090 cpu_to_le32(led_blink_time[WIL_LED_TIME_MED].on_ms), 2091 .medium_blink_cfg.blink_off = 2092 cpu_to_le32(led_blink_time[WIL_LED_TIME_MED].off_ms), 2093 .fast_blink_cfg.blink_on = 2094 cpu_to_le32(led_blink_time[WIL_LED_TIME_FAST].on_ms), 2095 .fast_blink_cfg.blink_off = 2096 cpu_to_le32(led_blink_time[WIL_LED_TIME_FAST].off_ms), 2097 .led_polarity = led_polarity, 2098 }; 2099 struct { 2100 struct wmi_cmd_hdr wmi; 2101 struct wmi_led_cfg_done_event evt; 2102 } __packed reply = { 2103 .evt = {.status = cpu_to_le32(WMI_FW_STATUS_FAILURE)}, 2104 }; 2105 2106 if (led_id == WIL_LED_INVALID_ID) 2107 goto out; 2108 2109 if (led_id > WIL_LED_MAX_ID) { 2110 wil_err(wil, "Invalid led id %d\n", led_id); 2111 rc = -EINVAL; 2112 goto out; 2113 } 2114 2115 wil_dbg_wmi(wil, 2116 "%s led %d\n", 2117 enable ? "enabling" : "disabling", led_id); 2118 2119 rc = wmi_call(wil, WMI_LED_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), 2120 WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply), 2121 WIL_WMI_CALL_GENERAL_TO_MS); 2122 if (rc) 2123 goto out; 2124 2125 if (reply.evt.status) { 2126 wil_err(wil, "led %d cfg failed with status %d\n", 2127 led_id, le32_to_cpu(reply.evt.status)); 2128 rc = -EINVAL; 2129 } 2130 2131 out: 2132 return rc; 2133 } 2134 2135 int wmi_rbufcap_cfg(struct wil6210_priv *wil, bool enable, u16 threshold) 2136 { 2137 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2138 int rc; 2139 2140 struct wmi_rbufcap_cfg_cmd cmd = { 2141 .enable = enable, 2142 .rx_desc_threshold = cpu_to_le16(threshold), 2143 }; 2144 struct { 2145 struct wmi_cmd_hdr wmi; 2146 struct wmi_rbufcap_cfg_event evt; 2147 } __packed reply = { 2148 .evt = {.status = WMI_FW_STATUS_FAILURE}, 2149 }; 2150 2151 rc = wmi_call(wil, WMI_RBUFCAP_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), 2152 WMI_RBUFCAP_CFG_EVENTID, &reply, sizeof(reply), 2153 WIL_WMI_CALL_GENERAL_TO_MS); 2154 if (rc) 2155 return rc; 2156 2157 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 2158 wil_err(wil, "RBUFCAP_CFG failed. status %d\n", 2159 reply.evt.status); 2160 rc = -EINVAL; 2161 } 2162 2163 return rc; 2164 } 2165 2166 int wmi_pcp_start(struct wil6210_vif *vif, 2167 int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go) 2168 { 2169 struct wil6210_priv *wil = vif_to_wil(vif); 2170 int rc; 2171 2172 struct wmi_pcp_start_cmd cmd = { 2173 .bcon_interval = cpu_to_le16(bi), 2174 .network_type = wmi_nettype, 2175 .disable_sec_offload = 1, 2176 .channel = chan - 1, 2177 .pcp_max_assoc_sta = wil->max_assoc_sta, 2178 .hidden_ssid = hidden_ssid, 2179 .is_go = is_go, 2180 .ap_sme_offload_mode = disable_ap_sme ? 2181 WMI_AP_SME_OFFLOAD_PARTIAL : 2182 WMI_AP_SME_OFFLOAD_FULL, 2183 .abft_len = wil->abft_len, 2184 }; 2185 struct { 2186 struct wmi_cmd_hdr wmi; 2187 struct wmi_pcp_started_event evt; 2188 } __packed reply = { 2189 .evt = {.status = WMI_FW_STATUS_FAILURE}, 2190 }; 2191 2192 if (!vif->privacy) 2193 cmd.disable_sec = 1; 2194 2195 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || 2196 (cmd.pcp_max_assoc_sta <= 0)) { 2197 wil_err(wil, "unexpected max_assoc_sta %d\n", 2198 cmd.pcp_max_assoc_sta); 2199 return -EOPNOTSUPP; 2200 } 2201 2202 if (disable_ap_sme && 2203 !test_bit(WMI_FW_CAPABILITY_AP_SME_OFFLOAD_PARTIAL, 2204 wil->fw_capabilities)) { 2205 wil_err(wil, "disable_ap_sme not supported by FW\n"); 2206 return -EOPNOTSUPP; 2207 } 2208 2209 /* 2210 * Processing time may be huge, in case of secure AP it takes about 2211 * 3500ms for FW to start AP 2212 */ 2213 rc = wmi_call(wil, WMI_PCP_START_CMDID, vif->mid, &cmd, sizeof(cmd), 2214 WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000); 2215 if (rc) 2216 return rc; 2217 2218 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) 2219 rc = -EINVAL; 2220 2221 if (wmi_nettype != WMI_NETTYPE_P2P) 2222 /* Don't fail due to error in the led configuration */ 2223 wmi_led_cfg(wil, true); 2224 2225 return rc; 2226 } 2227 2228 int wmi_pcp_stop(struct wil6210_vif *vif) 2229 { 2230 struct wil6210_priv *wil = vif_to_wil(vif); 2231 int rc; 2232 2233 rc = wmi_led_cfg(wil, false); 2234 if (rc) 2235 return rc; 2236 2237 return wmi_call(wil, WMI_PCP_STOP_CMDID, vif->mid, NULL, 0, 2238 WMI_PCP_STOPPED_EVENTID, NULL, 0, 2239 WIL_WMI_PCP_STOP_TO_MS); 2240 } 2241 2242 int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid) 2243 { 2244 struct wil6210_priv *wil = vif_to_wil(vif); 2245 struct wmi_set_ssid_cmd cmd = { 2246 .ssid_len = cpu_to_le32(ssid_len), 2247 }; 2248 2249 if (ssid_len > sizeof(cmd.ssid)) 2250 return -EINVAL; 2251 2252 memcpy(cmd.ssid, ssid, ssid_len); 2253 2254 return wmi_send(wil, WMI_SET_SSID_CMDID, vif->mid, &cmd, sizeof(cmd)); 2255 } 2256 2257 int wmi_get_ssid(struct wil6210_vif *vif, u8 *ssid_len, void *ssid) 2258 { 2259 struct wil6210_priv *wil = vif_to_wil(vif); 2260 int rc; 2261 struct { 2262 struct wmi_cmd_hdr wmi; 2263 struct wmi_set_ssid_cmd cmd; 2264 } __packed reply; 2265 int len; /* reply.cmd.ssid_len in CPU order */ 2266 2267 memset(&reply, 0, sizeof(reply)); 2268 2269 rc = wmi_call(wil, WMI_GET_SSID_CMDID, vif->mid, NULL, 0, 2270 WMI_GET_SSID_EVENTID, &reply, sizeof(reply), 2271 WIL_WMI_CALL_GENERAL_TO_MS); 2272 if (rc) 2273 return rc; 2274 2275 len = le32_to_cpu(reply.cmd.ssid_len); 2276 if (len > sizeof(reply.cmd.ssid)) 2277 return -EINVAL; 2278 2279 *ssid_len = len; 2280 memcpy(ssid, reply.cmd.ssid, len); 2281 2282 return 0; 2283 } 2284 2285 int wmi_set_channel(struct wil6210_priv *wil, int channel) 2286 { 2287 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2288 struct wmi_set_pcp_channel_cmd cmd = { 2289 .channel = channel - 1, 2290 }; 2291 2292 return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, vif->mid, 2293 &cmd, sizeof(cmd)); 2294 } 2295 2296 int wmi_get_channel(struct wil6210_priv *wil, int *channel) 2297 { 2298 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2299 int rc; 2300 struct { 2301 struct wmi_cmd_hdr wmi; 2302 struct wmi_set_pcp_channel_cmd cmd; 2303 } __packed reply; 2304 2305 memset(&reply, 0, sizeof(reply)); 2306 2307 rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, vif->mid, NULL, 0, 2308 WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 2309 WIL_WMI_CALL_GENERAL_TO_MS); 2310 if (rc) 2311 return rc; 2312 2313 if (reply.cmd.channel > 3) 2314 return -EINVAL; 2315 2316 *channel = reply.cmd.channel + 1; 2317 2318 return 0; 2319 } 2320 2321 int wmi_p2p_cfg(struct wil6210_vif *vif, int channel, int bi) 2322 { 2323 struct wil6210_priv *wil = vif_to_wil(vif); 2324 int rc; 2325 struct wmi_p2p_cfg_cmd cmd = { 2326 .discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER, 2327 .bcon_interval = cpu_to_le16(bi), 2328 .channel = channel - 1, 2329 }; 2330 struct { 2331 struct wmi_cmd_hdr wmi; 2332 struct wmi_p2p_cfg_done_event evt; 2333 } __packed reply = { 2334 .evt = {.status = WMI_FW_STATUS_FAILURE}, 2335 }; 2336 2337 wil_dbg_wmi(wil, "sending WMI_P2P_CFG_CMDID\n"); 2338 2339 rc = wmi_call(wil, WMI_P2P_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), 2340 WMI_P2P_CFG_DONE_EVENTID, &reply, sizeof(reply), 300); 2341 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 2342 wil_err(wil, "P2P_CFG failed. status %d\n", reply.evt.status); 2343 rc = -EINVAL; 2344 } 2345 2346 return rc; 2347 } 2348 2349 int wmi_start_listen(struct wil6210_vif *vif) 2350 { 2351 struct wil6210_priv *wil = vif_to_wil(vif); 2352 int rc; 2353 struct { 2354 struct wmi_cmd_hdr wmi; 2355 struct wmi_listen_started_event evt; 2356 } __packed reply = { 2357 .evt = {.status = WMI_FW_STATUS_FAILURE}, 2358 }; 2359 2360 wil_dbg_wmi(wil, "sending WMI_START_LISTEN_CMDID\n"); 2361 2362 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, vif->mid, NULL, 0, 2363 WMI_LISTEN_STARTED_EVENTID, &reply, sizeof(reply), 300); 2364 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 2365 wil_err(wil, "device failed to start listen. status %d\n", 2366 reply.evt.status); 2367 rc = -EINVAL; 2368 } 2369 2370 return rc; 2371 } 2372 2373 int wmi_start_search(struct wil6210_vif *vif) 2374 { 2375 struct wil6210_priv *wil = vif_to_wil(vif); 2376 int rc; 2377 struct { 2378 struct wmi_cmd_hdr wmi; 2379 struct wmi_search_started_event evt; 2380 } __packed reply = { 2381 .evt = {.status = WMI_FW_STATUS_FAILURE}, 2382 }; 2383 2384 wil_dbg_wmi(wil, "sending WMI_START_SEARCH_CMDID\n"); 2385 2386 rc = wmi_call(wil, WMI_START_SEARCH_CMDID, vif->mid, NULL, 0, 2387 WMI_SEARCH_STARTED_EVENTID, &reply, sizeof(reply), 300); 2388 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 2389 wil_err(wil, "device failed to start search. status %d\n", 2390 reply.evt.status); 2391 rc = -EINVAL; 2392 } 2393 2394 return rc; 2395 } 2396 2397 int wmi_stop_discovery(struct wil6210_vif *vif) 2398 { 2399 struct wil6210_priv *wil = vif_to_wil(vif); 2400 int rc; 2401 2402 wil_dbg_wmi(wil, "sending WMI_DISCOVERY_STOP_CMDID\n"); 2403 2404 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0, 2405 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 2406 WIL_WMI_CALL_GENERAL_TO_MS); 2407 2408 if (rc) 2409 wil_err(wil, "Failed to stop discovery\n"); 2410 2411 return rc; 2412 } 2413 2414 int wmi_del_cipher_key(struct wil6210_vif *vif, u8 key_index, 2415 const void *mac_addr, int key_usage) 2416 { 2417 struct wil6210_priv *wil = vif_to_wil(vif); 2418 struct wmi_delete_cipher_key_cmd cmd = { 2419 .key_index = key_index, 2420 }; 2421 2422 if (mac_addr) 2423 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); 2424 2425 return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, vif->mid, 2426 &cmd, sizeof(cmd)); 2427 } 2428 2429 int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index, 2430 const void *mac_addr, int key_len, const void *key, 2431 int key_usage) 2432 { 2433 struct wil6210_priv *wil = vif_to_wil(vif); 2434 struct wmi_add_cipher_key_cmd cmd = { 2435 .key_index = key_index, 2436 .key_usage = key_usage, 2437 .key_len = key_len, 2438 }; 2439 2440 if (!key || (key_len > sizeof(cmd.key))) 2441 return -EINVAL; 2442 2443 memcpy(cmd.key, key, key_len); 2444 if (mac_addr) 2445 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); 2446 2447 return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, vif->mid, 2448 &cmd, sizeof(cmd)); 2449 } 2450 2451 int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie) 2452 { 2453 struct wil6210_priv *wil = vif_to_wil(vif); 2454 static const char *const names[] = { 2455 [WMI_FRAME_BEACON] = "BEACON", 2456 [WMI_FRAME_PROBE_REQ] = "PROBE_REQ", 2457 [WMI_FRAME_PROBE_RESP] = "WMI_FRAME_PROBE_RESP", 2458 [WMI_FRAME_ASSOC_REQ] = "WMI_FRAME_ASSOC_REQ", 2459 [WMI_FRAME_ASSOC_RESP] = "WMI_FRAME_ASSOC_RESP", 2460 }; 2461 int rc; 2462 u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; 2463 struct wmi_set_appie_cmd *cmd; 2464 2465 if (len < ie_len) { 2466 rc = -EINVAL; 2467 goto out; 2468 } 2469 2470 cmd = kzalloc(len, GFP_KERNEL); 2471 if (!cmd) { 2472 rc = -ENOMEM; 2473 goto out; 2474 } 2475 if (!ie) 2476 ie_len = 0; 2477 2478 cmd->mgmt_frm_type = type; 2479 /* BUG: FW API define ieLen as u8. Will fix FW */ 2480 cmd->ie_len = cpu_to_le16(ie_len); 2481 memcpy(cmd->ie_info, ie, ie_len); 2482 rc = wmi_send(wil, WMI_SET_APPIE_CMDID, vif->mid, cmd, len); 2483 kfree(cmd); 2484 out: 2485 if (rc) { 2486 const char *name = type < ARRAY_SIZE(names) ? 2487 names[type] : "??"; 2488 wil_err(wil, "set_ie(%d %s) failed : %d\n", type, name, rc); 2489 } 2490 2491 return rc; 2492 } 2493 2494 int wmi_update_ft_ies(struct wil6210_vif *vif, u16 ie_len, const void *ie) 2495 { 2496 struct wil6210_priv *wil = vif_to_wil(vif); 2497 u16 len; 2498 struct wmi_update_ft_ies_cmd *cmd; 2499 int rc; 2500 2501 if (!ie) 2502 ie_len = 0; 2503 2504 len = sizeof(struct wmi_update_ft_ies_cmd) + ie_len; 2505 if (len < ie_len) { 2506 wil_err(wil, "wraparound. ie len %d\n", ie_len); 2507 return -EINVAL; 2508 } 2509 2510 cmd = kzalloc(len, GFP_KERNEL); 2511 if (!cmd) { 2512 rc = -ENOMEM; 2513 goto out; 2514 } 2515 2516 cmd->ie_len = cpu_to_le16(ie_len); 2517 memcpy(cmd->ie_info, ie, ie_len); 2518 rc = wmi_send(wil, WMI_UPDATE_FT_IES_CMDID, vif->mid, cmd, len); 2519 kfree(cmd); 2520 2521 out: 2522 if (rc) 2523 wil_err(wil, "update ft ies failed : %d\n", rc); 2524 2525 return rc; 2526 } 2527 2528 /** 2529 * wmi_rxon - turn radio on/off 2530 * @on: turn on if true, off otherwise 2531 * 2532 * Only switch radio. Channel should be set separately. 2533 * No timeout for rxon - radio turned on forever unless some other call 2534 * turns it off 2535 */ 2536 int wmi_rxon(struct wil6210_priv *wil, bool on) 2537 { 2538 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2539 int rc; 2540 struct { 2541 struct wmi_cmd_hdr wmi; 2542 struct wmi_listen_started_event evt; 2543 } __packed reply = { 2544 .evt = {.status = WMI_FW_STATUS_FAILURE}, 2545 }; 2546 2547 wil_info(wil, "(%s)\n", on ? "on" : "off"); 2548 2549 if (on) { 2550 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, vif->mid, NULL, 0, 2551 WMI_LISTEN_STARTED_EVENTID, 2552 &reply, sizeof(reply), 2553 WIL_WMI_CALL_GENERAL_TO_MS); 2554 if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS)) 2555 rc = -EINVAL; 2556 } else { 2557 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0, 2558 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 2559 WIL_WMI_CALL_GENERAL_TO_MS); 2560 } 2561 2562 return rc; 2563 } 2564 2565 int wmi_rx_chain_add(struct wil6210_priv *wil, struct wil_ring *vring) 2566 { 2567 struct net_device *ndev = wil->main_ndev; 2568 struct wireless_dev *wdev = ndev->ieee80211_ptr; 2569 struct wil6210_vif *vif = ndev_to_vif(ndev); 2570 struct wmi_cfg_rx_chain_cmd cmd = { 2571 .action = WMI_RX_CHAIN_ADD, 2572 .rx_sw_ring = { 2573 .max_mpdu_size = cpu_to_le16( 2574 wil_mtu2macbuf(wil->rx_buf_len)), 2575 .ring_mem_base = cpu_to_le64(vring->pa), 2576 .ring_size = cpu_to_le16(vring->size), 2577 }, 2578 .mid = 0, /* TODO - what is it? */ 2579 .decap_trans_type = WMI_DECAP_TYPE_802_3, 2580 .reorder_type = WMI_RX_SW_REORDER, 2581 .host_thrsh = cpu_to_le16(rx_ring_overflow_thrsh), 2582 }; 2583 struct { 2584 struct wmi_cmd_hdr wmi; 2585 struct wmi_cfg_rx_chain_done_event evt; 2586 } __packed evt; 2587 int rc; 2588 2589 memset(&evt, 0, sizeof(evt)); 2590 2591 if (wdev->iftype == NL80211_IFTYPE_MONITOR) { 2592 struct ieee80211_channel *ch = wil->monitor_chandef.chan; 2593 2594 cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON); 2595 if (ch) 2596 cmd.sniffer_cfg.channel = ch->hw_value - 1; 2597 cmd.sniffer_cfg.phy_info_mode = 2598 cpu_to_le32(WMI_SNIFFER_PHY_INFO_DISABLED); 2599 cmd.sniffer_cfg.phy_support = 2600 cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL) 2601 ? WMI_SNIFFER_CP : WMI_SNIFFER_BOTH_PHYS); 2602 } else { 2603 /* Initialize offload (in non-sniffer mode). 2604 * Linux IP stack always calculates IP checksum 2605 * HW always calculate TCP/UDP checksum 2606 */ 2607 cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS); 2608 } 2609 2610 if (rx_align_2) 2611 cmd.l2_802_3_offload_ctrl |= 2612 L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK; 2613 2614 /* typical time for secure PCP is 840ms */ 2615 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, vif->mid, &cmd, sizeof(cmd), 2616 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); 2617 if (rc) 2618 return rc; 2619 2620 if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS) 2621 rc = -EINVAL; 2622 2623 vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr); 2624 2625 wil_dbg_misc(wil, "Rx init: status %d tail 0x%08x\n", 2626 le32_to_cpu(evt.evt.status), vring->hwtail); 2627 2628 return rc; 2629 } 2630 2631 int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) 2632 { 2633 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2634 int rc; 2635 struct wmi_temp_sense_cmd cmd = { 2636 .measure_baseband_en = cpu_to_le32(!!t_bb), 2637 .measure_rf_en = cpu_to_le32(!!t_rf), 2638 .measure_mode = cpu_to_le32(TEMPERATURE_MEASURE_NOW), 2639 }; 2640 struct { 2641 struct wmi_cmd_hdr wmi; 2642 struct wmi_temp_sense_done_event evt; 2643 } __packed reply; 2644 2645 memset(&reply, 0, sizeof(reply)); 2646 2647 rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, vif->mid, &cmd, sizeof(cmd), 2648 WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 2649 WIL_WMI_CALL_GENERAL_TO_MS); 2650 if (rc) 2651 return rc; 2652 2653 if (t_bb) 2654 *t_bb = le32_to_cpu(reply.evt.baseband_t1000); 2655 if (t_rf) 2656 *t_rf = le32_to_cpu(reply.evt.rf_t1000); 2657 2658 return 0; 2659 } 2660 2661 int wmi_get_all_temperatures(struct wil6210_priv *wil, 2662 struct wmi_temp_sense_all_done_event 2663 *sense_all_evt) 2664 { 2665 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2666 int rc; 2667 struct wmi_temp_sense_all_cmd cmd = { 2668 .measure_baseband_en = true, 2669 .measure_rf_en = true, 2670 .measure_mode = TEMPERATURE_MEASURE_NOW, 2671 }; 2672 struct { 2673 struct wmi_cmd_hdr wmi; 2674 struct wmi_temp_sense_all_done_event evt; 2675 } __packed reply; 2676 2677 if (!sense_all_evt) { 2678 wil_err(wil, "Invalid sense_all_evt value\n"); 2679 return -EINVAL; 2680 } 2681 2682 memset(&reply, 0, sizeof(reply)); 2683 reply.evt.status = WMI_FW_STATUS_FAILURE; 2684 rc = wmi_call(wil, WMI_TEMP_SENSE_ALL_CMDID, vif->mid, &cmd, 2685 sizeof(cmd), WMI_TEMP_SENSE_ALL_DONE_EVENTID, 2686 &reply, sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 2687 if (rc) 2688 return rc; 2689 2690 if (reply.evt.status == WMI_FW_STATUS_FAILURE) { 2691 wil_err(wil, "Failed geting TEMP_SENSE_ALL\n"); 2692 return -EINVAL; 2693 } 2694 2695 memcpy(sense_all_evt, &reply.evt, sizeof(reply.evt)); 2696 return 0; 2697 } 2698 2699 int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, u16 reason, 2700 bool del_sta) 2701 { 2702 struct wil6210_priv *wil = vif_to_wil(vif); 2703 int rc; 2704 struct wmi_disconnect_sta_cmd disc_sta_cmd = { 2705 .disconnect_reason = cpu_to_le16(reason), 2706 }; 2707 struct wmi_del_sta_cmd del_sta_cmd = { 2708 .disconnect_reason = cpu_to_le16(reason), 2709 }; 2710 struct { 2711 struct wmi_cmd_hdr wmi; 2712 struct wmi_disconnect_event evt; 2713 } __packed reply; 2714 2715 wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason); 2716 2717 memset(&reply, 0, sizeof(reply)); 2718 vif->locally_generated_disc = true; 2719 if (del_sta) { 2720 ether_addr_copy(del_sta_cmd.dst_mac, mac); 2721 rc = wmi_call(wil, WMI_DEL_STA_CMDID, vif->mid, &del_sta_cmd, 2722 sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID, 2723 &reply, sizeof(reply), 1000); 2724 } else { 2725 ether_addr_copy(disc_sta_cmd.dst_mac, mac); 2726 rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, vif->mid, 2727 &disc_sta_cmd, sizeof(disc_sta_cmd), 2728 WMI_DISCONNECT_EVENTID, 2729 &reply, sizeof(reply), 1000); 2730 } 2731 /* failure to disconnect in reasonable time treated as FW error */ 2732 if (rc) { 2733 wil_fw_error_recovery(wil); 2734 return rc; 2735 } 2736 wil->sinfo_gen++; 2737 2738 return 0; 2739 } 2740 2741 int wmi_addba(struct wil6210_priv *wil, u8 mid, 2742 u8 ringid, u8 size, u16 timeout) 2743 { 2744 u8 amsdu = wil->use_enhanced_dma_hw && wil->use_rx_hw_reordering && 2745 test_bit(WMI_FW_CAPABILITY_AMSDU, wil->fw_capabilities) && 2746 wil->amsdu_en; 2747 struct wmi_ring_ba_en_cmd cmd = { 2748 .ring_id = ringid, 2749 .agg_max_wsize = size, 2750 .ba_timeout = cpu_to_le16(timeout), 2751 .amsdu = amsdu, 2752 }; 2753 2754 wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d amsdu %d)\n", 2755 ringid, size, timeout, amsdu); 2756 2757 return wmi_send(wil, WMI_RING_BA_EN_CMDID, mid, &cmd, sizeof(cmd)); 2758 } 2759 2760 int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason) 2761 { 2762 struct wmi_ring_ba_dis_cmd cmd = { 2763 .ring_id = ringid, 2764 .reason = cpu_to_le16(reason), 2765 }; 2766 2767 wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason); 2768 2769 return wmi_send(wil, WMI_RING_BA_DIS_CMDID, mid, &cmd, sizeof(cmd)); 2770 } 2771 2772 int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid, u16 reason) 2773 { 2774 struct wmi_rcp_delba_cmd cmd = { 2775 .reason = cpu_to_le16(reason), 2776 }; 2777 2778 if (cid >= WIL6210_RX_DESC_MAX_CID) { 2779 cmd.cidxtid = CIDXTID_EXTENDED_CID_TID; 2780 cmd.cid = cid; 2781 cmd.tid = tid; 2782 } else { 2783 cmd.cidxtid = mk_cidxtid(cid, tid); 2784 } 2785 2786 wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cid, 2787 tid, reason); 2788 2789 return wmi_send(wil, WMI_RCP_DELBA_CMDID, mid, &cmd, sizeof(cmd)); 2790 } 2791 2792 int wmi_addba_rx_resp(struct wil6210_priv *wil, 2793 u8 mid, u8 cid, u8 tid, u8 token, 2794 u16 status, bool amsdu, u16 agg_wsize, u16 timeout) 2795 { 2796 int rc; 2797 struct wmi_rcp_addba_resp_cmd cmd = { 2798 .dialog_token = token, 2799 .status_code = cpu_to_le16(status), 2800 /* bit 0: A-MSDU supported 2801 * bit 1: policy (controlled by FW) 2802 * bits 2..5: TID 2803 * bits 6..15: buffer size 2804 */ 2805 .ba_param_set = cpu_to_le16((amsdu ? 1 : 0) | (tid << 2) | 2806 (agg_wsize << 6)), 2807 .ba_timeout = cpu_to_le16(timeout), 2808 }; 2809 struct { 2810 struct wmi_cmd_hdr wmi; 2811 struct wmi_rcp_addba_resp_sent_event evt; 2812 } __packed reply = { 2813 .evt = {.status = cpu_to_le16(WMI_FW_STATUS_FAILURE)}, 2814 }; 2815 2816 if (cid >= WIL6210_RX_DESC_MAX_CID) { 2817 cmd.cidxtid = CIDXTID_EXTENDED_CID_TID; 2818 cmd.cid = cid; 2819 cmd.tid = tid; 2820 } else { 2821 cmd.cidxtid = mk_cidxtid(cid, tid); 2822 } 2823 2824 wil_dbg_wmi(wil, 2825 "ADDBA response for MID %d CID %d TID %d size %d timeout %d status %d AMSDU%s\n", 2826 mid, cid, tid, agg_wsize, 2827 timeout, status, amsdu ? "+" : "-"); 2828 2829 rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, mid, &cmd, sizeof(cmd), 2830 WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), 2831 WIL_WMI_CALL_GENERAL_TO_MS); 2832 if (rc) 2833 return rc; 2834 2835 if (reply.evt.status) { 2836 wil_err(wil, "ADDBA response failed with status %d\n", 2837 le16_to_cpu(reply.evt.status)); 2838 rc = -EINVAL; 2839 } 2840 2841 return rc; 2842 } 2843 2844 int wmi_addba_rx_resp_edma(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid, 2845 u8 token, u16 status, bool amsdu, u16 agg_wsize, 2846 u16 timeout) 2847 { 2848 int rc; 2849 struct wmi_rcp_addba_resp_edma_cmd cmd = { 2850 .cid = cid, 2851 .tid = tid, 2852 .dialog_token = token, 2853 .status_code = cpu_to_le16(status), 2854 /* bit 0: A-MSDU supported 2855 * bit 1: policy (controlled by FW) 2856 * bits 2..5: TID 2857 * bits 6..15: buffer size 2858 */ 2859 .ba_param_set = cpu_to_le16((amsdu ? 1 : 0) | (tid << 2) | 2860 (agg_wsize << 6)), 2861 .ba_timeout = cpu_to_le16(timeout), 2862 /* route all the connections to status ring 0 */ 2863 .status_ring_id = WIL_DEFAULT_RX_STATUS_RING_ID, 2864 }; 2865 struct { 2866 struct wmi_cmd_hdr wmi; 2867 struct wmi_rcp_addba_resp_sent_event evt; 2868 } __packed reply = { 2869 .evt = {.status = cpu_to_le16(WMI_FW_STATUS_FAILURE)}, 2870 }; 2871 2872 wil_dbg_wmi(wil, 2873 "ADDBA response for CID %d TID %d size %d timeout %d status %d AMSDU%s, sring_id %d\n", 2874 cid, tid, agg_wsize, timeout, status, amsdu ? "+" : "-", 2875 WIL_DEFAULT_RX_STATUS_RING_ID); 2876 2877 rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_EDMA_CMDID, mid, &cmd, 2878 sizeof(cmd), WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, 2879 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 2880 if (rc) 2881 return rc; 2882 2883 if (reply.evt.status) { 2884 wil_err(wil, "ADDBA response failed with status %d\n", 2885 le16_to_cpu(reply.evt.status)); 2886 rc = -EINVAL; 2887 } 2888 2889 return rc; 2890 } 2891 2892 int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, 2893 enum wmi_ps_profile_type ps_profile) 2894 { 2895 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2896 int rc; 2897 struct wmi_ps_dev_profile_cfg_cmd cmd = { 2898 .ps_profile = ps_profile, 2899 }; 2900 struct { 2901 struct wmi_cmd_hdr wmi; 2902 struct wmi_ps_dev_profile_cfg_event evt; 2903 } __packed reply = { 2904 .evt = {.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR)}, 2905 }; 2906 u32 status; 2907 2908 wil_dbg_wmi(wil, "Setting ps dev profile %d\n", ps_profile); 2909 2910 rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, vif->mid, 2911 &cmd, sizeof(cmd), 2912 WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply), 2913 WIL_WMI_CALL_GENERAL_TO_MS); 2914 if (rc) 2915 return rc; 2916 2917 status = le32_to_cpu(reply.evt.status); 2918 2919 if (status != WMI_PS_CFG_CMD_STATUS_SUCCESS) { 2920 wil_err(wil, "ps dev profile cfg failed with status %d\n", 2921 status); 2922 rc = -EINVAL; 2923 } 2924 2925 return rc; 2926 } 2927 2928 int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) 2929 { 2930 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2931 int rc; 2932 struct wmi_set_mgmt_retry_limit_cmd cmd = { 2933 .mgmt_retry_limit = retry_short, 2934 }; 2935 struct { 2936 struct wmi_cmd_hdr wmi; 2937 struct wmi_set_mgmt_retry_limit_event evt; 2938 } __packed reply = { 2939 .evt = {.status = WMI_FW_STATUS_FAILURE}, 2940 }; 2941 2942 wil_dbg_wmi(wil, "Setting mgmt retry short %d\n", retry_short); 2943 2944 if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities)) 2945 return -ENOTSUPP; 2946 2947 rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, vif->mid, 2948 &cmd, sizeof(cmd), 2949 WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), 2950 WIL_WMI_CALL_GENERAL_TO_MS); 2951 if (rc) 2952 return rc; 2953 2954 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 2955 wil_err(wil, "set mgmt retry limit failed with status %d\n", 2956 reply.evt.status); 2957 rc = -EINVAL; 2958 } 2959 2960 return rc; 2961 } 2962 2963 int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) 2964 { 2965 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 2966 int rc; 2967 struct { 2968 struct wmi_cmd_hdr wmi; 2969 struct wmi_get_mgmt_retry_limit_event evt; 2970 } __packed reply; 2971 2972 wil_dbg_wmi(wil, "getting mgmt retry short\n"); 2973 2974 if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities)) 2975 return -ENOTSUPP; 2976 2977 memset(&reply, 0, sizeof(reply)); 2978 rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, vif->mid, NULL, 0, 2979 WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), 2980 WIL_WMI_CALL_GENERAL_TO_MS); 2981 if (rc) 2982 return rc; 2983 2984 if (retry_short) 2985 *retry_short = reply.evt.mgmt_retry_limit; 2986 2987 return 0; 2988 } 2989 2990 int wmi_abort_scan(struct wil6210_vif *vif) 2991 { 2992 struct wil6210_priv *wil = vif_to_wil(vif); 2993 int rc; 2994 2995 wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n"); 2996 2997 rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, vif->mid, NULL, 0); 2998 if (rc) 2999 wil_err(wil, "Failed to abort scan (%d)\n", rc); 3000 3001 return rc; 3002 } 3003 3004 int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid) 3005 { 3006 struct wil6210_priv *wil = vif_to_wil(vif); 3007 int rc; 3008 struct wmi_new_sta_cmd cmd = { 3009 .aid = aid, 3010 }; 3011 3012 wil_dbg_wmi(wil, "new sta %pM, aid %d\n", mac, aid); 3013 3014 ether_addr_copy(cmd.dst_mac, mac); 3015 3016 rc = wmi_send(wil, WMI_NEW_STA_CMDID, vif->mid, &cmd, sizeof(cmd)); 3017 if (rc) 3018 wil_err(wil, "Failed to send new sta (%d)\n", rc); 3019 3020 return rc; 3021 } 3022 3023 void wmi_event_flush(struct wil6210_priv *wil) 3024 { 3025 ulong flags; 3026 struct pending_wmi_event *evt, *t; 3027 3028 wil_dbg_wmi(wil, "event_flush\n"); 3029 3030 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 3031 3032 list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) { 3033 list_del(&evt->list); 3034 kfree(evt); 3035 } 3036 3037 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 3038 } 3039 3040 static const char *suspend_status2name(u8 status) 3041 { 3042 switch (status) { 3043 case WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE: 3044 return "LINK_NOT_IDLE"; 3045 case WMI_TRAFFIC_SUSPEND_REJECTED_DISCONNECT: 3046 return "DISCONNECT"; 3047 case WMI_TRAFFIC_SUSPEND_REJECTED_OTHER: 3048 return "OTHER"; 3049 default: 3050 return "Untracked status"; 3051 } 3052 } 3053 3054 int wmi_suspend(struct wil6210_priv *wil) 3055 { 3056 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 3057 int rc; 3058 struct wmi_traffic_suspend_cmd cmd = { 3059 .wakeup_trigger = wil->wakeup_trigger, 3060 }; 3061 struct { 3062 struct wmi_cmd_hdr wmi; 3063 struct wmi_traffic_suspend_event evt; 3064 } __packed reply = { 3065 .evt = {.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE}, 3066 }; 3067 3068 u32 suspend_to = WIL_WAIT_FOR_SUSPEND_RESUME_COMP; 3069 3070 wil->suspend_resp_rcvd = false; 3071 wil->suspend_resp_comp = false; 3072 3073 rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, vif->mid, 3074 &cmd, sizeof(cmd), 3075 WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply), 3076 suspend_to); 3077 if (rc) { 3078 wil_err(wil, "wmi_call for suspend req failed, rc=%d\n", rc); 3079 if (rc == -ETIME) 3080 /* wmi_call TO */ 3081 wil->suspend_stats.rejected_by_device++; 3082 else 3083 wil->suspend_stats.rejected_by_host++; 3084 goto out; 3085 } 3086 3087 wil_dbg_wmi(wil, "waiting for suspend_response_completed\n"); 3088 3089 rc = wait_event_interruptible_timeout(wil->wq, 3090 wil->suspend_resp_comp, 3091 msecs_to_jiffies(suspend_to)); 3092 if (rc == 0) { 3093 wil_err(wil, "TO waiting for suspend_response_completed\n"); 3094 if (wil->suspend_resp_rcvd) 3095 /* Device responded but we TO due to another reason */ 3096 wil->suspend_stats.rejected_by_host++; 3097 else 3098 wil->suspend_stats.rejected_by_device++; 3099 rc = -EBUSY; 3100 goto out; 3101 } 3102 3103 wil_dbg_wmi(wil, "suspend_response_completed rcvd\n"); 3104 if (reply.evt.status != WMI_TRAFFIC_SUSPEND_APPROVED) { 3105 wil_dbg_pm(wil, "device rejected the suspend, %s\n", 3106 suspend_status2name(reply.evt.status)); 3107 wil->suspend_stats.rejected_by_device++; 3108 } 3109 rc = reply.evt.status; 3110 3111 out: 3112 wil->suspend_resp_rcvd = false; 3113 wil->suspend_resp_comp = false; 3114 3115 return rc; 3116 } 3117 3118 static void resume_triggers2string(u32 triggers, char *string, int str_size) 3119 { 3120 string[0] = '\0'; 3121 3122 if (!triggers) { 3123 strlcat(string, " UNKNOWN", str_size); 3124 return; 3125 } 3126 3127 if (triggers & WMI_RESUME_TRIGGER_HOST) 3128 strlcat(string, " HOST", str_size); 3129 3130 if (triggers & WMI_RESUME_TRIGGER_UCAST_RX) 3131 strlcat(string, " UCAST_RX", str_size); 3132 3133 if (triggers & WMI_RESUME_TRIGGER_BCAST_RX) 3134 strlcat(string, " BCAST_RX", str_size); 3135 3136 if (triggers & WMI_RESUME_TRIGGER_WMI_EVT) 3137 strlcat(string, " WMI_EVT", str_size); 3138 3139 if (triggers & WMI_RESUME_TRIGGER_DISCONNECT) 3140 strlcat(string, " DISCONNECT", str_size); 3141 } 3142 3143 int wmi_resume(struct wil6210_priv *wil) 3144 { 3145 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 3146 int rc; 3147 char string[100]; 3148 struct { 3149 struct wmi_cmd_hdr wmi; 3150 struct wmi_traffic_resume_event evt; 3151 } __packed reply = { 3152 .evt = {.status = WMI_TRAFFIC_RESUME_FAILED, 3153 .resume_triggers = 3154 cpu_to_le32(WMI_RESUME_TRIGGER_UNKNOWN)}, 3155 }; 3156 3157 rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, vif->mid, NULL, 0, 3158 WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply), 3159 WIL_WAIT_FOR_SUSPEND_RESUME_COMP); 3160 if (rc) 3161 return rc; 3162 resume_triggers2string(le32_to_cpu(reply.evt.resume_triggers), string, 3163 sizeof(string)); 3164 wil_dbg_pm(wil, "device resume %s, resume triggers:%s (0x%x)\n", 3165 reply.evt.status ? "failed" : "passed", string, 3166 le32_to_cpu(reply.evt.resume_triggers)); 3167 3168 return reply.evt.status; 3169 } 3170 3171 int wmi_port_allocate(struct wil6210_priv *wil, u8 mid, 3172 const u8 *mac, enum nl80211_iftype iftype) 3173 { 3174 int rc; 3175 struct wmi_port_allocate_cmd cmd = { 3176 .mid = mid, 3177 }; 3178 struct { 3179 struct wmi_cmd_hdr wmi; 3180 struct wmi_port_allocated_event evt; 3181 } __packed reply = { 3182 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3183 }; 3184 3185 wil_dbg_misc(wil, "port allocate, mid %d iftype %d, mac %pM\n", 3186 mid, iftype, mac); 3187 3188 ether_addr_copy(cmd.mac, mac); 3189 switch (iftype) { 3190 case NL80211_IFTYPE_STATION: 3191 cmd.port_role = WMI_PORT_STA; 3192 break; 3193 case NL80211_IFTYPE_AP: 3194 cmd.port_role = WMI_PORT_AP; 3195 break; 3196 case NL80211_IFTYPE_P2P_CLIENT: 3197 cmd.port_role = WMI_PORT_P2P_CLIENT; 3198 break; 3199 case NL80211_IFTYPE_P2P_GO: 3200 cmd.port_role = WMI_PORT_P2P_GO; 3201 break; 3202 /* what about monitor??? */ 3203 default: 3204 wil_err(wil, "unsupported iftype: %d\n", iftype); 3205 return -EINVAL; 3206 } 3207 3208 rc = wmi_call(wil, WMI_PORT_ALLOCATE_CMDID, mid, 3209 &cmd, sizeof(cmd), 3210 WMI_PORT_ALLOCATED_EVENTID, &reply, 3211 sizeof(reply), 300); 3212 if (rc) { 3213 wil_err(wil, "failed to allocate port, status %d\n", rc); 3214 return rc; 3215 } 3216 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3217 wil_err(wil, "WMI_PORT_ALLOCATE returned status %d\n", 3218 reply.evt.status); 3219 return -EINVAL; 3220 } 3221 3222 return 0; 3223 } 3224 3225 int wmi_port_delete(struct wil6210_priv *wil, u8 mid) 3226 { 3227 int rc; 3228 struct wmi_port_delete_cmd cmd = { 3229 .mid = mid, 3230 }; 3231 struct { 3232 struct wmi_cmd_hdr wmi; 3233 struct wmi_port_deleted_event evt; 3234 } __packed reply = { 3235 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3236 }; 3237 3238 wil_dbg_misc(wil, "port delete, mid %d\n", mid); 3239 3240 rc = wmi_call(wil, WMI_PORT_DELETE_CMDID, mid, 3241 &cmd, sizeof(cmd), 3242 WMI_PORT_DELETED_EVENTID, &reply, 3243 sizeof(reply), 2000); 3244 if (rc) { 3245 wil_err(wil, "failed to delete port, status %d\n", rc); 3246 return rc; 3247 } 3248 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3249 wil_err(wil, "WMI_PORT_DELETE returned status %d\n", 3250 reply.evt.status); 3251 return -EINVAL; 3252 } 3253 3254 return 0; 3255 } 3256 3257 static bool wmi_evt_call_handler(struct wil6210_vif *vif, int id, 3258 void *d, int len) 3259 { 3260 uint i; 3261 3262 for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) { 3263 if (wmi_evt_handlers[i].eventid == id) { 3264 wmi_evt_handlers[i].handler(vif, id, d, len); 3265 return true; 3266 } 3267 } 3268 3269 return false; 3270 } 3271 3272 static void wmi_event_handle(struct wil6210_priv *wil, 3273 struct wil6210_mbox_hdr *hdr) 3274 { 3275 u16 len = le16_to_cpu(hdr->len); 3276 struct wil6210_vif *vif; 3277 3278 if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) && 3279 (len >= sizeof(struct wmi_cmd_hdr))) { 3280 struct wmi_cmd_hdr *wmi = (void *)(&hdr[1]); 3281 void *evt_data = (void *)(&wmi[1]); 3282 u16 id = le16_to_cpu(wmi->command_id); 3283 u8 mid = wmi->mid; 3284 3285 wil_dbg_wmi(wil, "Handle %s (0x%04x) (reply_id 0x%04x,%d)\n", 3286 eventid2name(id), id, wil->reply_id, 3287 wil->reply_mid); 3288 3289 if (mid == MID_BROADCAST) 3290 mid = 0; 3291 if (mid >= GET_MAX_VIFS(wil)) { 3292 wil_dbg_wmi(wil, "invalid mid %d, event skipped\n", 3293 mid); 3294 return; 3295 } 3296 vif = wil->vifs[mid]; 3297 if (!vif) { 3298 wil_dbg_wmi(wil, "event for empty VIF(%d), skipped\n", 3299 mid); 3300 return; 3301 } 3302 3303 /* check if someone waits for this event */ 3304 if (wil->reply_id && wil->reply_id == id && 3305 wil->reply_mid == mid) { 3306 if (wil->reply_buf) { 3307 /* event received while wmi_call is waiting 3308 * with a buffer. Such event should be handled 3309 * in wmi_recv_cmd function. Handling the event 3310 * here means a previous wmi_call was timeout. 3311 * Drop the event and do not handle it. 3312 */ 3313 wil_err(wil, 3314 "Old event (%d, %s) while wmi_call is waiting. Drop it and Continue waiting\n", 3315 id, eventid2name(id)); 3316 return; 3317 } 3318 3319 wmi_evt_call_handler(vif, id, evt_data, 3320 len - sizeof(*wmi)); 3321 wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n", 3322 id); 3323 complete(&wil->wmi_call); 3324 return; 3325 } 3326 /* unsolicited event */ 3327 /* search for handler */ 3328 if (!wmi_evt_call_handler(vif, id, evt_data, 3329 len - sizeof(*wmi))) { 3330 wil_info(wil, "Unhandled event 0x%04x\n", id); 3331 } 3332 } else { 3333 wil_err(wil, "Unknown event type\n"); 3334 print_hex_dump(KERN_ERR, "evt?? ", DUMP_PREFIX_OFFSET, 16, 1, 3335 hdr, sizeof(*hdr) + len, true); 3336 } 3337 } 3338 3339 /* 3340 * Retrieve next WMI event from the pending list 3341 */ 3342 static struct list_head *next_wmi_ev(struct wil6210_priv *wil) 3343 { 3344 ulong flags; 3345 struct list_head *ret = NULL; 3346 3347 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 3348 3349 if (!list_empty(&wil->pending_wmi_ev)) { 3350 ret = wil->pending_wmi_ev.next; 3351 list_del(ret); 3352 } 3353 3354 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 3355 3356 return ret; 3357 } 3358 3359 /* 3360 * Handler for the WMI events 3361 */ 3362 void wmi_event_worker(struct work_struct *work) 3363 { 3364 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 3365 wmi_event_worker); 3366 struct pending_wmi_event *evt; 3367 struct list_head *lh; 3368 3369 wil_dbg_wmi(wil, "event_worker: Start\n"); 3370 while ((lh = next_wmi_ev(wil)) != NULL) { 3371 evt = list_entry(lh, struct pending_wmi_event, list); 3372 wmi_event_handle(wil, &evt->event.hdr); 3373 kfree(evt); 3374 } 3375 wil_dbg_wmi(wil, "event_worker: Finished\n"); 3376 } 3377 3378 bool wil_is_wmi_idle(struct wil6210_priv *wil) 3379 { 3380 ulong flags; 3381 struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx; 3382 bool rc = false; 3383 3384 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 3385 3386 /* Check if there are pending WMI events in the events queue */ 3387 if (!list_empty(&wil->pending_wmi_ev)) { 3388 wil_dbg_pm(wil, "Pending WMI events in queue\n"); 3389 goto out; 3390 } 3391 3392 /* Check if there is a pending WMI call */ 3393 if (wil->reply_id) { 3394 wil_dbg_pm(wil, "Pending WMI call\n"); 3395 goto out; 3396 } 3397 3398 /* Check if there are pending RX events in mbox */ 3399 r->head = wil_r(wil, RGF_MBOX + 3400 offsetof(struct wil6210_mbox_ctl, rx.head)); 3401 if (r->tail != r->head) 3402 wil_dbg_pm(wil, "Pending WMI mbox events\n"); 3403 else 3404 rc = true; 3405 3406 out: 3407 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 3408 return rc; 3409 } 3410 3411 static void 3412 wmi_sched_scan_set_ssids(struct wil6210_priv *wil, 3413 struct wmi_start_sched_scan_cmd *cmd, 3414 struct cfg80211_ssid *ssids, int n_ssids, 3415 struct cfg80211_match_set *match_sets, 3416 int n_match_sets) 3417 { 3418 int i; 3419 3420 if (n_match_sets > WMI_MAX_PNO_SSID_NUM) { 3421 wil_dbg_wmi(wil, "too many match sets (%d), use first %d\n", 3422 n_match_sets, WMI_MAX_PNO_SSID_NUM); 3423 n_match_sets = WMI_MAX_PNO_SSID_NUM; 3424 } 3425 cmd->num_of_ssids = n_match_sets; 3426 3427 for (i = 0; i < n_match_sets; i++) { 3428 struct wmi_sched_scan_ssid_match *wmi_match = 3429 &cmd->ssid_for_match[i]; 3430 struct cfg80211_match_set *cfg_match = &match_sets[i]; 3431 int j; 3432 3433 wmi_match->ssid_len = cfg_match->ssid.ssid_len; 3434 memcpy(wmi_match->ssid, cfg_match->ssid.ssid, 3435 min_t(u8, wmi_match->ssid_len, WMI_MAX_SSID_LEN)); 3436 wmi_match->rssi_threshold = S8_MIN; 3437 if (cfg_match->rssi_thold >= S8_MIN && 3438 cfg_match->rssi_thold <= S8_MAX) 3439 wmi_match->rssi_threshold = cfg_match->rssi_thold; 3440 3441 for (j = 0; j < n_ssids; j++) 3442 if (wmi_match->ssid_len == ssids[j].ssid_len && 3443 memcmp(wmi_match->ssid, ssids[j].ssid, 3444 wmi_match->ssid_len) == 0) 3445 wmi_match->add_ssid_to_probe = true; 3446 } 3447 } 3448 3449 static void 3450 wmi_sched_scan_set_channels(struct wil6210_priv *wil, 3451 struct wmi_start_sched_scan_cmd *cmd, 3452 u32 n_channels, 3453 struct ieee80211_channel **channels) 3454 { 3455 int i; 3456 3457 if (n_channels > WMI_MAX_CHANNEL_NUM) { 3458 wil_dbg_wmi(wil, "too many channels (%d), use first %d\n", 3459 n_channels, WMI_MAX_CHANNEL_NUM); 3460 n_channels = WMI_MAX_CHANNEL_NUM; 3461 } 3462 cmd->num_of_channels = n_channels; 3463 3464 for (i = 0; i < n_channels; i++) { 3465 struct ieee80211_channel *cfg_chan = channels[i]; 3466 3467 cmd->channel_list[i] = cfg_chan->hw_value - 1; 3468 } 3469 } 3470 3471 static void 3472 wmi_sched_scan_set_plans(struct wil6210_priv *wil, 3473 struct wmi_start_sched_scan_cmd *cmd, 3474 struct cfg80211_sched_scan_plan *scan_plans, 3475 int n_scan_plans) 3476 { 3477 int i; 3478 3479 if (n_scan_plans > WMI_MAX_PLANS_NUM) { 3480 wil_dbg_wmi(wil, "too many plans (%d), use first %d\n", 3481 n_scan_plans, WMI_MAX_PLANS_NUM); 3482 n_scan_plans = WMI_MAX_PLANS_NUM; 3483 } 3484 3485 for (i = 0; i < n_scan_plans; i++) { 3486 struct cfg80211_sched_scan_plan *cfg_plan = &scan_plans[i]; 3487 3488 cmd->scan_plans[i].interval_sec = 3489 cpu_to_le16(cfg_plan->interval); 3490 cmd->scan_plans[i].num_of_iterations = 3491 cpu_to_le16(cfg_plan->iterations); 3492 } 3493 } 3494 3495 int wmi_start_sched_scan(struct wil6210_priv *wil, 3496 struct cfg80211_sched_scan_request *request) 3497 { 3498 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 3499 int rc; 3500 struct wmi_start_sched_scan_cmd cmd = { 3501 .min_rssi_threshold = S8_MIN, 3502 .initial_delay_sec = cpu_to_le16(request->delay), 3503 }; 3504 struct { 3505 struct wmi_cmd_hdr wmi; 3506 struct wmi_start_sched_scan_event evt; 3507 } __packed reply = { 3508 .evt = {.result = WMI_PNO_REJECT}, 3509 }; 3510 3511 if (!test_bit(WMI_FW_CAPABILITY_PNO, wil->fw_capabilities)) 3512 return -ENOTSUPP; 3513 3514 if (request->min_rssi_thold >= S8_MIN && 3515 request->min_rssi_thold <= S8_MAX) 3516 cmd.min_rssi_threshold = request->min_rssi_thold; 3517 3518 wmi_sched_scan_set_ssids(wil, &cmd, request->ssids, request->n_ssids, 3519 request->match_sets, request->n_match_sets); 3520 wmi_sched_scan_set_channels(wil, &cmd, 3521 request->n_channels, request->channels); 3522 wmi_sched_scan_set_plans(wil, &cmd, 3523 request->scan_plans, request->n_scan_plans); 3524 3525 rc = wmi_call(wil, WMI_START_SCHED_SCAN_CMDID, vif->mid, 3526 &cmd, sizeof(cmd), 3527 WMI_START_SCHED_SCAN_EVENTID, &reply, sizeof(reply), 3528 WIL_WMI_CALL_GENERAL_TO_MS); 3529 if (rc) 3530 return rc; 3531 3532 if (reply.evt.result != WMI_PNO_SUCCESS) { 3533 wil_err(wil, "start sched scan failed, result %d\n", 3534 reply.evt.result); 3535 return -EINVAL; 3536 } 3537 3538 return 0; 3539 } 3540 3541 int wmi_stop_sched_scan(struct wil6210_priv *wil) 3542 { 3543 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 3544 int rc; 3545 struct { 3546 struct wmi_cmd_hdr wmi; 3547 struct wmi_stop_sched_scan_event evt; 3548 } __packed reply = { 3549 .evt = {.result = WMI_PNO_REJECT}, 3550 }; 3551 3552 if (!test_bit(WMI_FW_CAPABILITY_PNO, wil->fw_capabilities)) 3553 return -ENOTSUPP; 3554 3555 rc = wmi_call(wil, WMI_STOP_SCHED_SCAN_CMDID, vif->mid, NULL, 0, 3556 WMI_STOP_SCHED_SCAN_EVENTID, &reply, sizeof(reply), 3557 WIL_WMI_CALL_GENERAL_TO_MS); 3558 if (rc) 3559 return rc; 3560 3561 if (reply.evt.result != WMI_PNO_SUCCESS) { 3562 wil_err(wil, "stop sched scan failed, result %d\n", 3563 reply.evt.result); 3564 return -EINVAL; 3565 } 3566 3567 return 0; 3568 } 3569 3570 int wmi_mgmt_tx(struct wil6210_vif *vif, const u8 *buf, size_t len) 3571 { 3572 size_t total; 3573 struct wil6210_priv *wil = vif_to_wil(vif); 3574 struct ieee80211_mgmt *mgmt_frame = (void *)buf; 3575 struct wmi_sw_tx_req_cmd *cmd; 3576 struct { 3577 struct wmi_cmd_hdr wmi; 3578 struct wmi_sw_tx_complete_event evt; 3579 } __packed evt = { 3580 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3581 }; 3582 int rc; 3583 3584 wil_dbg_misc(wil, "mgmt_tx mid %d\n", vif->mid); 3585 wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf, 3586 len, true); 3587 3588 if (len < sizeof(struct ieee80211_hdr_3addr)) 3589 return -EINVAL; 3590 3591 total = sizeof(*cmd) + len; 3592 if (total < len) { 3593 wil_err(wil, "mgmt_tx invalid len %zu\n", len); 3594 return -EINVAL; 3595 } 3596 3597 cmd = kmalloc(total, GFP_KERNEL); 3598 if (!cmd) 3599 return -ENOMEM; 3600 3601 memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN); 3602 cmd->len = cpu_to_le16(len); 3603 memcpy(cmd->payload, buf, len); 3604 3605 rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, vif->mid, cmd, total, 3606 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); 3607 if (!rc && evt.evt.status != WMI_FW_STATUS_SUCCESS) { 3608 wil_dbg_wmi(wil, "mgmt_tx failed with status %d\n", 3609 evt.evt.status); 3610 rc = -EAGAIN; 3611 } 3612 3613 kfree(cmd); 3614 3615 return rc; 3616 } 3617 3618 int wmi_mgmt_tx_ext(struct wil6210_vif *vif, const u8 *buf, size_t len, 3619 u8 channel, u16 duration_ms) 3620 { 3621 size_t total; 3622 struct wil6210_priv *wil = vif_to_wil(vif); 3623 struct ieee80211_mgmt *mgmt_frame = (void *)buf; 3624 struct wmi_sw_tx_req_ext_cmd *cmd; 3625 struct { 3626 struct wmi_cmd_hdr wmi; 3627 struct wmi_sw_tx_complete_event evt; 3628 } __packed evt = { 3629 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3630 }; 3631 int rc; 3632 3633 wil_dbg_wmi(wil, "mgmt_tx_ext mid %d channel %d duration %d\n", 3634 vif->mid, channel, duration_ms); 3635 wil_hex_dump_wmi("mgmt_tx_ext frame ", DUMP_PREFIX_OFFSET, 16, 1, buf, 3636 len, true); 3637 3638 if (len < sizeof(struct ieee80211_hdr_3addr)) { 3639 wil_err(wil, "short frame. len %zu\n", len); 3640 return -EINVAL; 3641 } 3642 3643 total = sizeof(*cmd) + len; 3644 if (total < len) { 3645 wil_err(wil, "mgmt_tx_ext invalid len %zu\n", len); 3646 return -EINVAL; 3647 } 3648 3649 cmd = kzalloc(total, GFP_KERNEL); 3650 if (!cmd) 3651 return -ENOMEM; 3652 3653 memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN); 3654 cmd->len = cpu_to_le16(len); 3655 memcpy(cmd->payload, buf, len); 3656 cmd->channel = channel - 1; 3657 cmd->duration_ms = cpu_to_le16(duration_ms); 3658 3659 rc = wmi_call(wil, WMI_SW_TX_REQ_EXT_CMDID, vif->mid, cmd, total, 3660 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); 3661 if (!rc && evt.evt.status != WMI_FW_STATUS_SUCCESS) { 3662 wil_dbg_wmi(wil, "mgmt_tx_ext failed with status %d\n", 3663 evt.evt.status); 3664 rc = -EAGAIN; 3665 } 3666 3667 kfree(cmd); 3668 3669 return rc; 3670 } 3671 3672 int wil_wmi_tx_sring_cfg(struct wil6210_priv *wil, int ring_id) 3673 { 3674 int rc; 3675 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); 3676 struct wil_status_ring *sring = &wil->srings[ring_id]; 3677 struct wmi_tx_status_ring_add_cmd cmd = { 3678 .ring_cfg = { 3679 .ring_size = cpu_to_le16(sring->size), 3680 }, 3681 .irq_index = WIL_TX_STATUS_IRQ_IDX 3682 }; 3683 struct { 3684 struct wmi_cmd_hdr hdr; 3685 struct wmi_tx_status_ring_cfg_done_event evt; 3686 } __packed reply = { 3687 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3688 }; 3689 3690 cmd.ring_cfg.ring_id = ring_id; 3691 3692 cmd.ring_cfg.ring_mem_base = cpu_to_le64(sring->pa); 3693 rc = wmi_call(wil, WMI_TX_STATUS_RING_ADD_CMDID, vif->mid, &cmd, 3694 sizeof(cmd), WMI_TX_STATUS_RING_CFG_DONE_EVENTID, 3695 &reply, sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3696 if (rc) { 3697 wil_err(wil, "TX_STATUS_RING_ADD_CMD failed, rc %d\n", rc); 3698 return rc; 3699 } 3700 3701 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3702 wil_err(wil, "TX_STATUS_RING_ADD_CMD failed, status %d\n", 3703 reply.evt.status); 3704 return -EINVAL; 3705 } 3706 3707 sring->hwtail = le32_to_cpu(reply.evt.ring_tail_ptr); 3708 3709 return 0; 3710 } 3711 3712 int wil_wmi_cfg_def_rx_offload(struct wil6210_priv *wil, u16 max_rx_pl_per_desc) 3713 { 3714 struct net_device *ndev = wil->main_ndev; 3715 struct wil6210_vif *vif = ndev_to_vif(ndev); 3716 int rc; 3717 struct wmi_cfg_def_rx_offload_cmd cmd = { 3718 .max_msdu_size = cpu_to_le16(wil_mtu2macbuf(WIL_MAX_ETH_MTU)), 3719 .max_rx_pl_per_desc = cpu_to_le16(max_rx_pl_per_desc), 3720 .decap_trans_type = WMI_DECAP_TYPE_802_3, 3721 .l2_802_3_offload_ctrl = 0, 3722 .l3_l4_ctrl = 1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS, 3723 }; 3724 struct { 3725 struct wmi_cmd_hdr hdr; 3726 struct wmi_cfg_def_rx_offload_done_event evt; 3727 } __packed reply = { 3728 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3729 }; 3730 3731 rc = wmi_call(wil, WMI_CFG_DEF_RX_OFFLOAD_CMDID, vif->mid, &cmd, 3732 sizeof(cmd), WMI_CFG_DEF_RX_OFFLOAD_DONE_EVENTID, &reply, 3733 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3734 if (rc) { 3735 wil_err(wil, "WMI_CFG_DEF_RX_OFFLOAD_CMD failed, rc %d\n", rc); 3736 return rc; 3737 } 3738 3739 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3740 wil_err(wil, "WMI_CFG_DEF_RX_OFFLOAD_CMD failed, status %d\n", 3741 reply.evt.status); 3742 return -EINVAL; 3743 } 3744 3745 return 0; 3746 } 3747 3748 int wil_wmi_rx_sring_add(struct wil6210_priv *wil, u16 ring_id) 3749 { 3750 struct net_device *ndev = wil->main_ndev; 3751 struct wil6210_vif *vif = ndev_to_vif(ndev); 3752 struct wil_status_ring *sring = &wil->srings[ring_id]; 3753 int rc; 3754 struct wmi_rx_status_ring_add_cmd cmd = { 3755 .ring_cfg = { 3756 .ring_size = cpu_to_le16(sring->size), 3757 .ring_id = ring_id, 3758 }, 3759 .rx_msg_type = wil->use_compressed_rx_status ? 3760 WMI_RX_MSG_TYPE_COMPRESSED : 3761 WMI_RX_MSG_TYPE_EXTENDED, 3762 .irq_index = WIL_RX_STATUS_IRQ_IDX, 3763 }; 3764 struct { 3765 struct wmi_cmd_hdr hdr; 3766 struct wmi_rx_status_ring_cfg_done_event evt; 3767 } __packed reply = { 3768 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3769 }; 3770 3771 cmd.ring_cfg.ring_mem_base = cpu_to_le64(sring->pa); 3772 rc = wmi_call(wil, WMI_RX_STATUS_RING_ADD_CMDID, vif->mid, &cmd, 3773 sizeof(cmd), WMI_RX_STATUS_RING_CFG_DONE_EVENTID, &reply, 3774 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3775 if (rc) { 3776 wil_err(wil, "RX_STATUS_RING_ADD_CMD failed, rc %d\n", rc); 3777 return rc; 3778 } 3779 3780 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3781 wil_err(wil, "RX_STATUS_RING_ADD_CMD failed, status %d\n", 3782 reply.evt.status); 3783 return -EINVAL; 3784 } 3785 3786 sring->hwtail = le32_to_cpu(reply.evt.ring_tail_ptr); 3787 3788 return 0; 3789 } 3790 3791 int wil_wmi_rx_desc_ring_add(struct wil6210_priv *wil, int status_ring_id) 3792 { 3793 struct net_device *ndev = wil->main_ndev; 3794 struct wil6210_vif *vif = ndev_to_vif(ndev); 3795 struct wil_ring *ring = &wil->ring_rx; 3796 int rc; 3797 struct wmi_rx_desc_ring_add_cmd cmd = { 3798 .ring_cfg = { 3799 .ring_size = cpu_to_le16(ring->size), 3800 .ring_id = WIL_RX_DESC_RING_ID, 3801 }, 3802 .status_ring_id = status_ring_id, 3803 .irq_index = WIL_RX_STATUS_IRQ_IDX, 3804 }; 3805 struct { 3806 struct wmi_cmd_hdr hdr; 3807 struct wmi_rx_desc_ring_cfg_done_event evt; 3808 } __packed reply = { 3809 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3810 }; 3811 3812 cmd.ring_cfg.ring_mem_base = cpu_to_le64(ring->pa); 3813 cmd.sw_tail_host_addr = cpu_to_le64(ring->edma_rx_swtail.pa); 3814 rc = wmi_call(wil, WMI_RX_DESC_RING_ADD_CMDID, vif->mid, &cmd, 3815 sizeof(cmd), WMI_RX_DESC_RING_CFG_DONE_EVENTID, &reply, 3816 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3817 if (rc) { 3818 wil_err(wil, "WMI_RX_DESC_RING_ADD_CMD failed, rc %d\n", rc); 3819 return rc; 3820 } 3821 3822 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3823 wil_err(wil, "WMI_RX_DESC_RING_ADD_CMD failed, status %d\n", 3824 reply.evt.status); 3825 return -EINVAL; 3826 } 3827 3828 ring->hwtail = le32_to_cpu(reply.evt.ring_tail_ptr); 3829 3830 return 0; 3831 } 3832 3833 int wil_wmi_tx_desc_ring_add(struct wil6210_vif *vif, int ring_id, int cid, 3834 int tid) 3835 { 3836 struct wil6210_priv *wil = vif_to_wil(vif); 3837 int sring_id = wil->tx_sring_idx; /* there is only one TX sring */ 3838 int rc; 3839 struct wil_ring *ring = &wil->ring_tx[ring_id]; 3840 struct wil_ring_tx_data *txdata = &wil->ring_tx_data[ring_id]; 3841 struct wmi_tx_desc_ring_add_cmd cmd = { 3842 .ring_cfg = { 3843 .ring_size = cpu_to_le16(ring->size), 3844 .ring_id = ring_id, 3845 }, 3846 .status_ring_id = sring_id, 3847 .cid = cid, 3848 .tid = tid, 3849 .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, 3850 .max_msdu_size = cpu_to_le16(wil_mtu2macbuf(mtu_max)), 3851 .schd_params = { 3852 .priority = cpu_to_le16(0), 3853 .timeslot_us = cpu_to_le16(0xfff), 3854 } 3855 }; 3856 struct { 3857 struct wmi_cmd_hdr hdr; 3858 struct wmi_tx_desc_ring_cfg_done_event evt; 3859 } __packed reply = { 3860 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3861 }; 3862 3863 cmd.ring_cfg.ring_mem_base = cpu_to_le64(ring->pa); 3864 rc = wmi_call(wil, WMI_TX_DESC_RING_ADD_CMDID, vif->mid, &cmd, 3865 sizeof(cmd), WMI_TX_DESC_RING_CFG_DONE_EVENTID, &reply, 3866 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3867 if (rc) { 3868 wil_err(wil, "WMI_TX_DESC_RING_ADD_CMD failed, rc %d\n", rc); 3869 return rc; 3870 } 3871 3872 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3873 wil_err(wil, "WMI_TX_DESC_RING_ADD_CMD failed, status %d\n", 3874 reply.evt.status); 3875 return -EINVAL; 3876 } 3877 3878 spin_lock_bh(&txdata->lock); 3879 ring->hwtail = le32_to_cpu(reply.evt.ring_tail_ptr); 3880 txdata->mid = vif->mid; 3881 txdata->enabled = 1; 3882 spin_unlock_bh(&txdata->lock); 3883 3884 return 0; 3885 } 3886 3887 int wil_wmi_bcast_desc_ring_add(struct wil6210_vif *vif, int ring_id) 3888 { 3889 struct wil6210_priv *wil = vif_to_wil(vif); 3890 struct wil_ring *ring = &wil->ring_tx[ring_id]; 3891 int rc; 3892 struct wmi_bcast_desc_ring_add_cmd cmd = { 3893 .ring_cfg = { 3894 .ring_size = cpu_to_le16(ring->size), 3895 .ring_id = ring_id, 3896 }, 3897 .max_msdu_size = cpu_to_le16(wil_mtu2macbuf(mtu_max)), 3898 .status_ring_id = wil->tx_sring_idx, 3899 .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, 3900 }; 3901 struct { 3902 struct wmi_cmd_hdr hdr; 3903 struct wmi_rx_desc_ring_cfg_done_event evt; 3904 } __packed reply = { 3905 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3906 }; 3907 struct wil_ring_tx_data *txdata = &wil->ring_tx_data[ring_id]; 3908 3909 cmd.ring_cfg.ring_mem_base = cpu_to_le64(ring->pa); 3910 rc = wmi_call(wil, WMI_BCAST_DESC_RING_ADD_CMDID, vif->mid, &cmd, 3911 sizeof(cmd), WMI_TX_DESC_RING_CFG_DONE_EVENTID, &reply, 3912 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3913 if (rc) { 3914 wil_err(wil, "WMI_BCAST_DESC_RING_ADD_CMD failed, rc %d\n", rc); 3915 return rc; 3916 } 3917 3918 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3919 wil_err(wil, "Broadcast Tx config failed, status %d\n", 3920 reply.evt.status); 3921 return -EINVAL; 3922 } 3923 3924 spin_lock_bh(&txdata->lock); 3925 ring->hwtail = le32_to_cpu(reply.evt.ring_tail_ptr); 3926 txdata->mid = vif->mid; 3927 txdata->enabled = 1; 3928 spin_unlock_bh(&txdata->lock); 3929 3930 return 0; 3931 } 3932 3933 int wmi_link_stats_cfg(struct wil6210_vif *vif, u32 type, u8 cid, u32 interval) 3934 { 3935 struct wil6210_priv *wil = vif_to_wil(vif); 3936 struct wmi_link_stats_cmd cmd = { 3937 .record_type_mask = cpu_to_le32(type), 3938 .cid = cid, 3939 .action = WMI_LINK_STATS_SNAPSHOT, 3940 .interval_msec = cpu_to_le32(interval), 3941 }; 3942 struct { 3943 struct wmi_cmd_hdr wmi; 3944 struct wmi_link_stats_config_done_event evt; 3945 } __packed reply = { 3946 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3947 }; 3948 int rc; 3949 3950 rc = wmi_call(wil, WMI_LINK_STATS_CMDID, vif->mid, &cmd, sizeof(cmd), 3951 WMI_LINK_STATS_CONFIG_DONE_EVENTID, &reply, 3952 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3953 if (rc) { 3954 wil_err(wil, "WMI_LINK_STATS_CMDID failed, rc %d\n", rc); 3955 return rc; 3956 } 3957 3958 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3959 wil_err(wil, "Link statistics config failed, status %d\n", 3960 reply.evt.status); 3961 return -EINVAL; 3962 } 3963 3964 return 0; 3965 } 3966