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