1 /* 2 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <osdep.h> 20 #include "wmi.h" 21 #include "wmi_unified_priv.h" 22 #include "wmi_unified_pmo_api.h" 23 24 #ifdef FEATURE_WLAN_D0WOW 25 /** 26 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 27 * @param wmi_handle: handle to WMI. 28 * @mac_id: radio context 29 * 30 * Return: 0 on success and error code on failure. 31 */ 32 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 33 uint8_t mac_id) 34 { 35 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 36 wmi_buf_t buf; 37 int32_t len; 38 QDF_STATUS status; 39 40 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 41 42 buf = wmi_buf_alloc(wmi_handle, len); 43 if (!buf) { 44 return QDF_STATUS_E_NOMEM; 45 } 46 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 47 WMITLV_SET_HDR(&cmd->tlv_header, 48 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 49 WMITLV_GET_STRUCT_TLVLEN 50 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 51 52 cmd->enable = true; 53 54 wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0); 55 status = wmi_unified_cmd_send(wmi_handle, buf, len, 56 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 57 if (QDF_IS_STATUS_ERROR(status)) 58 wmi_buf_free(buf); 59 60 return status; 61 } 62 63 /** 64 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 65 * @param wmi_handle: handle to WMI. 66 * @mac_id: radio context 67 * 68 * Return: 0 on success and error code on failure. 69 */ 70 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 71 uint8_t mac_id) 72 { 73 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 74 wmi_buf_t buf; 75 int32_t len; 76 QDF_STATUS status; 77 78 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 79 80 buf = wmi_buf_alloc(wmi_handle, len); 81 if (!buf) { 82 return QDF_STATUS_E_NOMEM; 83 } 84 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 85 WMITLV_SET_HDR(&cmd->tlv_header, 86 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 87 WMITLV_GET_STRUCT_TLVLEN 88 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 89 90 cmd->enable = false; 91 92 wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0); 93 status = wmi_unified_cmd_send(wmi_handle, buf, len, 94 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 95 if (QDF_IS_STATUS_ERROR(status)) 96 wmi_buf_free(buf); 97 98 return status; 99 } 100 101 void wmi_d0wow_attach_tlv(struct wmi_unified *wmi_handle) 102 { 103 struct wmi_ops *ops = wmi_handle->ops; 104 105 ops->send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv; 106 ops->send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv; 107 } 108 #endif /* FEATURE_WLAN_D0WOW */ 109 110 /** 111 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 112 * @wmi_handle: wmi handle 113 * @vdev_id: vdev id 114 * @bitmap: Event bitmap 115 * @enable: enable/disable 116 * 117 * Return: CDF status 118 */ 119 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 120 uint32_t vdev_id, 121 uint32_t *bitmap, 122 bool enable) 123 { 124 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 125 uint16_t len; 126 wmi_buf_t buf; 127 int ret; 128 129 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 130 buf = wmi_buf_alloc(wmi_handle, len); 131 if (!buf) { 132 return QDF_STATUS_E_NOMEM; 133 } 134 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 135 WMITLV_SET_HDR(&cmd->tlv_header, 136 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 137 WMITLV_GET_STRUCT_TLVLEN 138 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 139 cmd->vdev_id = vdev_id; 140 cmd->is_add = enable; 141 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 142 WMI_WOW_MAX_EVENT_BM_LEN); 143 144 wmi_debug("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 145 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 146 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 147 148 wmi_mtrace(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, cmd->vdev_id, 0); 149 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 150 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 151 if (ret) { 152 wmi_err("Failed to config wow wakeup event"); 153 wmi_buf_free(buf); 154 return QDF_STATUS_E_FAILURE; 155 } 156 157 return QDF_STATUS_SUCCESS; 158 } 159 160 /** 161 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 162 * @wmi_handle: wmi handle 163 * @vdev_id: vdev id 164 * @ptrn_id: pattern id 165 * @ptrn: pattern 166 * @ptrn_len: pattern length 167 * @ptrn_offset: pattern offset 168 * @mask: mask 169 * @mask_len: mask length 170 * @user: true for user configured pattern and false for default pattern 171 * @default_patterns: default patterns 172 * 173 * Return: CDF status 174 */ 175 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 176 uint8_t vdev_id, uint8_t ptrn_id, 177 const uint8_t *ptrn, uint8_t ptrn_len, 178 uint8_t ptrn_offset, const uint8_t *mask, 179 uint8_t mask_len, bool user, 180 uint8_t default_patterns) 181 { 182 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 183 WOW_BITMAP_PATTERN_T *bitmap_pattern; 184 wmi_buf_t buf; 185 uint8_t *buf_ptr; 186 int32_t len; 187 int ret; 188 189 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 190 WMI_TLV_HDR_SIZE + 191 1 * sizeof(WOW_BITMAP_PATTERN_T) + 192 WMI_TLV_HDR_SIZE + 193 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 194 WMI_TLV_HDR_SIZE + 195 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 196 WMI_TLV_HDR_SIZE + 197 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 198 WMI_TLV_HDR_SIZE + 199 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 200 201 buf = wmi_buf_alloc(wmi_handle, len); 202 if (!buf) { 203 return QDF_STATUS_E_NOMEM; 204 } 205 206 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 207 buf_ptr = (uint8_t *) cmd; 208 209 WMITLV_SET_HDR(&cmd->tlv_header, 210 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 211 WMITLV_GET_STRUCT_TLVLEN 212 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 213 cmd->vdev_id = vdev_id; 214 cmd->pattern_id = ptrn_id; 215 216 cmd->pattern_type = WOW_BITMAP_PATTERN; 217 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 218 219 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 220 sizeof(WOW_BITMAP_PATTERN_T)); 221 buf_ptr += WMI_TLV_HDR_SIZE; 222 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 223 224 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 225 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 226 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 227 228 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 229 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 230 231 bitmap_pattern->pattern_offset = ptrn_offset; 232 bitmap_pattern->pattern_len = ptrn_len; 233 234 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 235 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 236 237 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 238 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 239 240 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 241 bitmap_pattern->pattern_id = ptrn_id; 242 243 wmi_debug("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 244 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 245 bitmap_pattern->pattern_offset, user); 246 wmi_debug("Pattern: "); 247 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 248 &bitmap_pattern->patternbuf[0], 249 bitmap_pattern->pattern_len); 250 251 wmi_debug("Mask: "); 252 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 253 &bitmap_pattern->bitmaskbuf[0], 254 bitmap_pattern->pattern_len); 255 256 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 257 258 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 259 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 260 buf_ptr += WMI_TLV_HDR_SIZE; 261 262 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 263 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 264 buf_ptr += WMI_TLV_HDR_SIZE; 265 266 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 267 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 268 buf_ptr += WMI_TLV_HDR_SIZE; 269 270 /* Fill TLV for pattern_info_timeout but no data. */ 271 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 272 buf_ptr += WMI_TLV_HDR_SIZE; 273 274 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 275 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 276 buf_ptr += WMI_TLV_HDR_SIZE; 277 *(uint32_t *) buf_ptr = 0; 278 279 wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 280 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 281 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 282 if (ret) { 283 wmi_err("Failed to send wow ptrn to fw"); 284 wmi_buf_free(buf); 285 return QDF_STATUS_E_FAILURE; 286 } 287 288 return QDF_STATUS_SUCCESS; 289 } 290 291 /** 292 * fill_arp_offload_params_tlv() - Fill ARP offload data 293 * @wmi_handle: wmi handle 294 * @offload_req: offload request 295 * @buf_ptr: buffer pointer 296 * 297 * To fill ARP offload data to firmware 298 * when target goes to wow mode. 299 * 300 * Return: None 301 */ 302 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 303 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 304 { 305 306 int i; 307 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 308 bool enable_or_disable = offload_req->enable; 309 310 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 311 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 312 *buf_ptr += WMI_TLV_HDR_SIZE; 313 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 314 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 315 WMITLV_SET_HDR(&arp_tuple->tlv_header, 316 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 317 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 318 319 /* Fill data for ARP and NS in the first tupple for LA */ 320 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 321 /* Copy the target ip addr and flags */ 322 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 323 qdf_mem_copy(&arp_tuple->target_ipaddr, 324 offload_req->host_ipv4_addr, 325 WMI_IPV4_ADDR_LEN); 326 wmi_debug("ARPOffload IP4 address: %pI4", 327 offload_req->host_ipv4_addr); 328 } 329 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 330 } 331 } 332 333 #ifdef WLAN_NS_OFFLOAD 334 /** 335 * fill_ns_offload_params_tlv() - Fill NS offload data 336 * @wmi|_handle: wmi handle 337 * @offload_req: offload request 338 * @buf_ptr: buffer pointer 339 * 340 * To fill NS offload data to firmware 341 * when target goes to wow mode. 342 * 343 * Return: None 344 */ 345 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 346 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 347 { 348 349 int i; 350 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 351 352 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 353 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 354 *buf_ptr += WMI_TLV_HDR_SIZE; 355 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 356 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 357 WMITLV_SET_HDR(&ns_tuple->tlv_header, 358 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 359 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 360 361 /* 362 * Fill data only for NS offload in the first ARP tuple for LA 363 */ 364 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 365 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 366 /* Copy the target/solicitation/remote ip addr */ 367 if (ns_req->target_ipv6_addr_valid[i]) 368 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 369 &ns_req->target_ipv6_addr[i], 370 sizeof(WMI_IPV6_ADDR)); 371 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 372 &ns_req->self_ipv6_addr[i], 373 sizeof(WMI_IPV6_ADDR)); 374 if (ns_req->target_ipv6_addr_ac_type[i]) { 375 ns_tuple->flags |= 376 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 377 } 378 wmi_debug("Index %d NS solicitedIp %pI6, targetIp %pI6", 379 i, &ns_req->self_ipv6_addr[i], 380 &ns_req->target_ipv6_addr[i]); 381 382 /* target MAC is optional, check if it is valid, 383 * if this is not valid, the target will use the known 384 * local MAC address rather than the tuple 385 */ 386 WMI_CHAR_ARRAY_TO_MAC_ADDR( 387 ns_req->self_macaddr.bytes, 388 &ns_tuple->target_mac); 389 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 390 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 391 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 392 } 393 } 394 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 395 } 396 } 397 398 /** 399 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 400 * @wmi: wmi handle 401 * @offload_req: offload request 402 * @buf_ptr: buffer pointer 403 * 404 * To fill extended NS offload extended data to firmware 405 * when target goes to wow mode. 406 * 407 * Return: None 408 */ 409 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 410 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 411 { 412 int i; 413 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 414 uint32_t count, num_ns_ext_tuples; 415 416 count = ns_req->num_ns_offload_count; 417 num_ns_ext_tuples = ns_req->num_ns_offload_count - 418 WMI_MAX_NS_OFFLOADS; 419 420 /* Populate extended NS offload tuples */ 421 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 422 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 423 *buf_ptr += WMI_TLV_HDR_SIZE; 424 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 425 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 426 WMITLV_SET_HDR(&ns_tuple->tlv_header, 427 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 428 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 429 430 /* 431 * Fill data only for NS offload in the first ARP tuple for LA 432 */ 433 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 434 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 435 /* Copy the target/solicitation/remote ip addr */ 436 if (ns_req->target_ipv6_addr_valid[i]) 437 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 438 &ns_req->target_ipv6_addr[i], 439 sizeof(WMI_IPV6_ADDR)); 440 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 441 &ns_req->self_ipv6_addr[i], 442 sizeof(WMI_IPV6_ADDR)); 443 if (ns_req->target_ipv6_addr_ac_type[i]) { 444 ns_tuple->flags |= 445 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 446 } 447 wmi_debug("Index %d NS solicitedIp %pI6, targetIp %pI6", 448 i, &ns_req->self_ipv6_addr[i], 449 &ns_req->target_ipv6_addr[i]); 450 451 /* target MAC is optional, check if it is valid, 452 * if this is not valid, the target will use the 453 * known local MAC address rather than the tuple 454 */ 455 WMI_CHAR_ARRAY_TO_MAC_ADDR( 456 ns_req->self_macaddr.bytes, 457 &ns_tuple->target_mac); 458 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 459 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 460 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 461 } 462 } 463 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 464 } 465 } 466 #else 467 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 468 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 469 { 470 } 471 472 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 473 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 474 { 475 } 476 #endif 477 478 /** 479 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 480 * @wma: wmi handle 481 * @arp_offload_req: arp offload request 482 * @ns_offload_req: ns offload request 483 * @arp_only: flag 484 * 485 * To configure ARP NS off load data to firmware 486 * when target goes to wow mode. 487 * 488 * Return: QDF Status 489 */ 490 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 491 struct pmo_arp_offload_params *arp_offload_req, 492 struct pmo_ns_offload_params *ns_offload_req, 493 uint8_t vdev_id) 494 { 495 int32_t res; 496 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 497 uint8_t *buf_ptr; 498 wmi_buf_t buf; 499 int32_t len; 500 uint32_t count = 0, num_ns_ext_tuples = 0; 501 502 count = ns_offload_req->num_ns_offload_count; 503 504 /* 505 * TLV place holder size for array of NS tuples 506 * TLV place holder size for array of ARP tuples 507 */ 508 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 509 WMI_TLV_HDR_SIZE + 510 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 511 WMI_TLV_HDR_SIZE + 512 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 513 514 /* 515 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 516 * extra length for extended NS offload tuples which follows ARP offload 517 * tuples. Host needs to fill this structure in following format: 518 * 2 NS ofload tuples 519 * 2 ARP offload tuples 520 * N numbers of extended NS offload tuples if HDD has given more than 521 * 2 NS offload addresses 522 */ 523 if (count > WMI_MAX_NS_OFFLOADS) { 524 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 525 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 526 * sizeof(WMI_NS_OFFLOAD_TUPLE); 527 } 528 529 buf = wmi_buf_alloc(wmi_handle, len); 530 if (!buf) { 531 return QDF_STATUS_E_NOMEM; 532 } 533 534 buf_ptr = (uint8_t *) wmi_buf_data(buf); 535 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 536 WMITLV_SET_HDR(&cmd->tlv_header, 537 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 538 WMITLV_GET_STRUCT_TLVLEN 539 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 540 cmd->flags = 0; 541 cmd->vdev_id = vdev_id; 542 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 543 544 wmi_debug("ARP NS Offload vdev_id: %d", cmd->vdev_id); 545 546 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 547 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 548 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 549 if (num_ns_ext_tuples) 550 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 551 552 wmi_mtrace(WMI_SET_ARP_NS_OFFLOAD_CMDID, cmd->vdev_id, 0); 553 res = wmi_unified_cmd_send(wmi_handle, buf, len, 554 WMI_SET_ARP_NS_OFFLOAD_CMDID); 555 if (res) { 556 wmi_err("Failed to enable ARP NDP/NSffload"); 557 wmi_buf_free(buf); 558 return QDF_STATUS_E_FAILURE; 559 } 560 561 return QDF_STATUS_SUCCESS; 562 } 563 564 /** 565 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 566 * @wmi_handle: wmi handle 567 * @vdev_id: vdev id 568 * @multicastAddr: mcast address 569 * @clearList: clear list flag 570 * 571 * Return: QDF_STATUS_SUCCESS for success or error code 572 */ 573 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 574 uint8_t vdev_id, 575 struct qdf_mac_addr multicast_addr, 576 bool clearList) 577 { 578 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 579 wmi_buf_t buf; 580 int err; 581 582 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 583 if (!buf) { 584 return QDF_STATUS_E_NOMEM; 585 } 586 587 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 588 qdf_mem_zero(cmd, sizeof(*cmd)); 589 590 WMITLV_SET_HDR(&cmd->tlv_header, 591 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 592 WMITLV_GET_STRUCT_TLVLEN 593 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 594 cmd->action = 595 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 596 cmd->vdev_id = vdev_id; 597 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 598 599 wmi_debug("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: "QDF_MAC_ADDR_FMT, 600 cmd->action, vdev_id, clearList, 601 QDF_MAC_ADDR_REF(multicast_addr.bytes)); 602 603 wmi_mtrace(WMI_SET_MCASTBCAST_FILTER_CMDID, cmd->vdev_id, 0); 604 err = wmi_unified_cmd_send(wmi_handle, buf, 605 sizeof(*cmd), 606 WMI_SET_MCASTBCAST_FILTER_CMDID); 607 if (err) { 608 wmi_err("Failed to send set_param cmd"); 609 wmi_buf_free(buf); 610 return QDF_STATUS_E_FAILURE; 611 } 612 613 return QDF_STATUS_SUCCESS; 614 } 615 616 /** 617 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 618 * command to fw 619 * @wmi_handle: wmi handle 620 * @vdev_id: vdev id 621 * @mcast_filter_params: mcast filter params 622 * 623 * Return: QDF_STATUS_SUCCESS for success or error code 624 */ 625 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 626 wmi_unified_t wmi_handle, 627 uint8_t vdev_id, 628 struct pmo_mcast_filter_params *filter_param) 629 630 { 631 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 632 uint8_t *buf_ptr; 633 wmi_buf_t buf; 634 int err; 635 int i; 636 uint8_t *mac_addr_src_ptr = NULL; 637 wmi_mac_addr *mac_addr_dst_ptr; 638 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 639 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 640 641 buf = wmi_buf_alloc(wmi_handle, len); 642 if (!buf) { 643 return QDF_STATUS_E_NOMEM; 644 } 645 646 buf_ptr = (uint8_t *) wmi_buf_data(buf); 647 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 648 wmi_buf_data(buf); 649 qdf_mem_zero(cmd, sizeof(*cmd)); 650 651 WMITLV_SET_HDR(&cmd->tlv_header, 652 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 653 WMITLV_GET_STRUCT_TLVLEN 654 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 655 cmd->operation = 656 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 657 : WMI_MULTIPLE_MCAST_FILTER_ADD); 658 cmd->vdev_id = vdev_id; 659 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 660 661 buf_ptr += sizeof(*cmd); 662 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 663 sizeof(wmi_mac_addr) * 664 filter_param->multicast_addr_cnt); 665 666 if (filter_param->multicast_addr_cnt == 0) 667 goto send_cmd; 668 669 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 670 mac_addr_dst_ptr = (wmi_mac_addr *) 671 (buf_ptr + WMI_TLV_HDR_SIZE); 672 673 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 674 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 675 mac_addr_src_ptr += ATH_MAC_LEN; 676 mac_addr_dst_ptr++; 677 } 678 679 send_cmd: 680 wmi_mtrace(WMI_SET_MULTIPLE_MCAST_FILTER_CMDID, cmd->vdev_id, 0); 681 err = wmi_unified_cmd_send(wmi_handle, buf, 682 len, 683 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 684 if (err) { 685 wmi_err("Failed to send set_param cmd"); 686 wmi_buf_free(buf); 687 return QDF_STATUS_E_FAILURE; 688 } 689 690 return QDF_STATUS_SUCCESS; 691 } 692 693 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 694 struct pmo_hw_filter_params *req) 695 { 696 QDF_STATUS status; 697 wmi_hw_data_filter_cmd_fixed_param *cmd; 698 wmi_buf_t wmi_buf; 699 700 if (!req) { 701 wmi_err("req is null"); 702 return QDF_STATUS_E_INVAL; 703 } 704 705 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 706 if (!wmi_buf) { 707 return QDF_STATUS_E_NOMEM; 708 } 709 710 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 711 WMITLV_SET_HDR(&cmd->tlv_header, 712 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 713 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 714 cmd->vdev_id = req->vdev_id; 715 cmd->enable = req->enable; 716 /* Set all modes in case of disable */ 717 if (!cmd->enable) 718 cmd->hw_filter_bitmap = ((uint32_t)~0U); 719 else 720 cmd->hw_filter_bitmap = req->mode_bitmap; 721 722 wmi_debug("Send %s hw filter mode: 0x%X for vdev id %d", 723 req->enable ? "enable" : "disable", req->mode_bitmap, 724 req->vdev_id); 725 726 wmi_mtrace(WMI_HW_DATA_FILTER_CMDID, cmd->vdev_id, 0); 727 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 728 WMI_HW_DATA_FILTER_CMDID); 729 if (QDF_IS_STATUS_ERROR(status)) { 730 wmi_err("Failed to configure hw filter"); 731 wmi_buf_free(wmi_buf); 732 } 733 734 return status; 735 } 736 737 static void 738 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd, 739 uint8_t vdev_id, 740 struct pmo_gtk_req *params) 741 { 742 uint8_t *buf_ptr; 743 wmi_gtk_offload_fils_tlv_param *ext_param; 744 745 buf_ptr = (uint8_t *) cmd + sizeof(*cmd); 746 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 747 sizeof(*ext_param)); 748 buf_ptr += WMI_TLV_HDR_SIZE; 749 750 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 751 WMITLV_SET_HDR(&ext_param->tlv_header, 752 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 753 WMITLV_GET_STRUCT_TLVLEN( 754 wmi_gtk_offload_fils_tlv_param)); 755 ext_param->vdev_id = vdev_id; 756 ext_param->flags = cmd->flags; 757 ext_param->kek_len = params->kek_len; 758 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 759 qdf_mem_copy(ext_param->KCK, params->kck, 760 WMI_GTK_OFFLOAD_KCK_BYTES); 761 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 762 GTK_REPLAY_COUNTER_BYTES); 763 } 764 765 /** 766 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 767 * @wmi_handle: wmi handle 768 * @vdev_id: vdev id 769 * @params: GTK offload parameters 770 * 771 * Return: CDF status 772 */ 773 static 774 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 775 struct pmo_gtk_req *params, 776 bool enable_offload, 777 uint32_t gtk_offload_opcode) 778 { 779 int len; 780 wmi_buf_t buf; 781 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 782 QDF_STATUS status = QDF_STATUS_SUCCESS; 783 784 len = sizeof(*cmd); 785 786 if (params->is_fils_connection) 787 len += WMI_TLV_HDR_SIZE + 788 sizeof(wmi_gtk_offload_fils_tlv_param); 789 790 /* alloc wmi buffer */ 791 buf = wmi_buf_alloc(wmi_handle, len); 792 if (!buf) { 793 status = QDF_STATUS_E_NOMEM; 794 goto out; 795 } 796 797 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 798 WMITLV_SET_HDR(&cmd->tlv_header, 799 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 800 WMITLV_GET_STRUCT_TLVLEN 801 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 802 803 cmd->vdev_id = vdev_id; 804 805 /* Request target to enable GTK offload */ 806 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 807 cmd->flags = gtk_offload_opcode; 808 809 /* Copy the keys and replay counter */ 810 qdf_mem_copy(cmd->KCK, params->kck, sizeof(cmd->KCK)); 811 qdf_mem_copy(cmd->KEK, params->kek, sizeof(cmd->KEK)); 812 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 813 GTK_REPLAY_COUNTER_BYTES); 814 } else { 815 cmd->flags = gtk_offload_opcode; 816 } 817 if (params->is_fils_connection) 818 fill_fils_tlv_params(cmd, vdev_id, params); 819 820 wmi_debug("VDEVID: %d, GTK_FLAGS: x%x kek len %d", 821 vdev_id, cmd->flags, params->kek_len); 822 /* send the wmi command */ 823 wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0); 824 if (wmi_unified_cmd_send(wmi_handle, buf, len, 825 WMI_GTK_OFFLOAD_CMDID)) { 826 wmi_err("Failed to send WMI_GTK_OFFLOAD_CMDID"); 827 wmi_buf_free(buf); 828 status = QDF_STATUS_E_FAILURE; 829 } 830 831 out: 832 return status; 833 } 834 835 /** 836 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 837 * @wmi_handle: wmi handle 838 * @params: GTK offload params 839 * 840 * Return: CDF status 841 */ 842 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 843 wmi_unified_t wmi_handle, 844 uint8_t vdev_id, 845 uint64_t offload_req_opcode) 846 { 847 int len; 848 wmi_buf_t buf; 849 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 850 QDF_STATUS status = QDF_STATUS_SUCCESS; 851 852 len = sizeof(*cmd); 853 854 /* alloc wmi buffer */ 855 buf = wmi_buf_alloc(wmi_handle, len); 856 if (!buf) { 857 status = QDF_STATUS_E_NOMEM; 858 goto out; 859 } 860 861 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 862 WMITLV_SET_HDR(&cmd->tlv_header, 863 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 864 WMITLV_GET_STRUCT_TLVLEN 865 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 866 867 /* Request for GTK offload status */ 868 cmd->flags = offload_req_opcode; 869 cmd->vdev_id = vdev_id; 870 871 /* send the wmi command */ 872 wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0); 873 if (wmi_unified_cmd_send(wmi_handle, buf, len, 874 WMI_GTK_OFFLOAD_CMDID)) { 875 wmi_err("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 876 wmi_buf_free(buf); 877 status = QDF_STATUS_E_FAILURE; 878 } 879 880 out: 881 return status; 882 } 883 884 /** 885 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 886 * @wmi_handle: wmi handle 887 * @vdev_id: vdev id 888 * @action: true for enable else false 889 * 890 * To enable enhance multicast offload to firmware 891 * when target goes to wow mode. 892 * 893 * Return: QDF Status 894 */ 895 896 static 897 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 898 wmi_unified_t wmi_handle, 899 uint8_t vdev_id, bool action) 900 { 901 QDF_STATUS status; 902 wmi_buf_t buf; 903 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 904 905 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 906 if (!buf) { 907 return QDF_STATUS_E_NOMEM; 908 } 909 910 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 911 wmi_buf_data(buf); 912 913 WMITLV_SET_HDR(&cmd->tlv_header, 914 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 915 WMITLV_GET_STRUCT_TLVLEN( 916 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 917 918 cmd->vdev_id = vdev_id; 919 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 920 ENHANCED_MCAST_FILTER_ENABLED); 921 wmi_debug("config enhance multicast offload action %d for vdev %d", 922 action, vdev_id); 923 wmi_mtrace(WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID, cmd->vdev_id, 0); 924 status = wmi_unified_cmd_send(wmi_handle, buf, 925 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 926 if (status != QDF_STATUS_SUCCESS) { 927 wmi_buf_free(buf); 928 wmi_err("Failed to send ENHANCED_MCAST_FILTER_CMDID"); 929 } 930 931 return status; 932 } 933 934 /** 935 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 936 * @wmi_handle: wmi handle 937 * @param evt_buf: pointer to event buffer 938 * @param hdr: Pointer to hold header 939 * @param bufp: Pointer to hold pointer to rx param buffer 940 * 941 * Return: QDF_STATUS_SUCCESS for success or error code 942 */ 943 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 944 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 945 { 946 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 947 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 948 949 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 950 if (!param_buf) { 951 wmi_err("gtk param_buf is NULL"); 952 return QDF_STATUS_E_INVAL; 953 } 954 955 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 956 wmi_err("Invalid length for GTK status"); 957 return QDF_STATUS_E_INVAL; 958 } 959 960 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 961 param_buf->fixed_param; 962 963 if (fixed_param->vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { 964 wmi_err_rl("Invalid vdev_id %u", fixed_param->vdev_id); 965 return QDF_STATUS_E_INVAL; 966 } 967 968 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 969 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 970 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 971 qdf_mem_copy(>k_rsp_param->replay_counter, 972 &fixed_param->replay_counter, 973 GTK_REPLAY_COUNTER_BYTES); 974 975 return QDF_STATUS_SUCCESS; 976 977 } 978 979 #ifdef FEATURE_WLAN_RA_FILTERING 980 /** 981 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 982 * @wmi_handle: wmi handle 983 * @vdev_id: vdev id 984 * 985 * Return: CDF status 986 */ 987 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 988 uint8_t vdev_id, 989 uint8_t default_pattern, 990 uint16_t rate_limit_interval) 991 { 992 993 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 994 wmi_buf_t buf; 995 uint8_t *buf_ptr; 996 int32_t len; 997 int ret; 998 999 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 1000 WMI_TLV_HDR_SIZE + 1001 0 * sizeof(WOW_BITMAP_PATTERN_T) + 1002 WMI_TLV_HDR_SIZE + 1003 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 1004 WMI_TLV_HDR_SIZE + 1005 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 1006 WMI_TLV_HDR_SIZE + 1007 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 1008 WMI_TLV_HDR_SIZE + 1009 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 1010 1011 buf = wmi_buf_alloc(wmi_handle, len); 1012 if (!buf) { 1013 return QDF_STATUS_E_NOMEM; 1014 } 1015 1016 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 1017 buf_ptr = (uint8_t *) cmd; 1018 1019 WMITLV_SET_HDR(&cmd->tlv_header, 1020 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 1021 WMITLV_GET_STRUCT_TLVLEN 1022 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 1023 cmd->vdev_id = vdev_id; 1024 cmd->pattern_id = default_pattern, 1025 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 1026 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 1027 1028 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 1029 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1030 buf_ptr += WMI_TLV_HDR_SIZE; 1031 1032 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 1033 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1034 buf_ptr += WMI_TLV_HDR_SIZE; 1035 1036 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 1037 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1038 buf_ptr += WMI_TLV_HDR_SIZE; 1039 1040 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 1041 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1042 buf_ptr += WMI_TLV_HDR_SIZE; 1043 1044 /* Fill TLV for pattern_info_timeout but no data. */ 1045 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 1046 buf_ptr += WMI_TLV_HDR_SIZE; 1047 1048 /* Fill TLV for ra_ratelimit_interval. */ 1049 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 1050 buf_ptr += WMI_TLV_HDR_SIZE; 1051 1052 *((uint32_t *) buf_ptr) = rate_limit_interval; 1053 1054 wmi_debug("send RA rate limit [%d] to fw vdev = %d", 1055 rate_limit_interval, vdev_id); 1056 1057 wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 1058 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1059 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 1060 if (ret) { 1061 wmi_err("Failed to send RA rate limit to fw"); 1062 wmi_buf_free(buf); 1063 return QDF_STATUS_E_FAILURE; 1064 } 1065 1066 return QDF_STATUS_SUCCESS; 1067 } 1068 1069 void wmi_ra_filtering_attach_tlv(struct wmi_unified *wmi_handle) 1070 { 1071 struct wmi_ops *ops = wmi_handle->ops; 1072 1073 ops->send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv; 1074 } 1075 #endif /* FEATURE_WLAN_RA_FILTERING */ 1076 1077 /** 1078 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 1079 * @wmi_handle: wmi handler 1080 * @action_params: pointer to action_params 1081 * 1082 * Return: 0 for success, otherwise appropriate error code 1083 */ 1084 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 1085 struct pmo_action_wakeup_set_params *action_params) 1086 { 1087 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 1088 wmi_buf_t buf; 1089 int i; 1090 int32_t err; 1091 uint32_t len = 0, *cmd_args; 1092 uint8_t *buf_ptr; 1093 1094 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 1095 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 1096 buf = wmi_buf_alloc(wmi_handle, len); 1097 if (!buf) { 1098 return QDF_STATUS_E_NOMEM; 1099 } 1100 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 1101 buf_ptr = (uint8_t *)cmd; 1102 WMITLV_SET_HDR(&cmd->tlv_header, 1103 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 1104 WMITLV_GET_STRUCT_TLVLEN( 1105 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 1106 1107 cmd->vdev_id = action_params->vdev_id; 1108 cmd->operation = action_params->operation; 1109 1110 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 1111 cmd->action_category_map[i] = 1112 action_params->action_category_map[i]; 1113 1114 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 1115 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1116 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 1117 buf_ptr += WMI_TLV_HDR_SIZE; 1118 cmd_args = (uint32_t *) buf_ptr; 1119 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 1120 cmd_args[i] = action_params->action_per_category[i]; 1121 1122 wmi_mtrace(WMI_WOW_SET_ACTION_WAKE_UP_CMDID, cmd->vdev_id, 0); 1123 err = wmi_unified_cmd_send(wmi_handle, buf, 1124 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 1125 if (err) { 1126 wmi_err("Failed to send ap_ps_egap cmd"); 1127 wmi_buf_free(buf); 1128 return QDF_STATUS_E_FAILURE; 1129 } 1130 1131 return QDF_STATUS_SUCCESS; 1132 } 1133 1134 #ifdef FEATURE_WLAN_LPHB 1135 /** 1136 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 1137 * @wmi_handle: wmi handle 1138 * @lphb_conf_req: configuration info 1139 * 1140 * Return: CDF status 1141 */ 1142 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 1143 wmi_hb_set_enable_cmd_fixed_param *params) 1144 { 1145 QDF_STATUS status; 1146 wmi_buf_t buf = NULL; 1147 uint8_t *buf_ptr; 1148 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 1149 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 1150 1151 buf = wmi_buf_alloc(wmi_handle, len); 1152 if (!buf) { 1153 return QDF_STATUS_E_NOMEM; 1154 } 1155 1156 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1157 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 1158 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 1159 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 1160 WMITLV_GET_STRUCT_TLVLEN 1161 (wmi_hb_set_enable_cmd_fixed_param)); 1162 1163 /* fill in values */ 1164 hb_enable_fp->vdev_id = params->session; 1165 hb_enable_fp->enable = params->enable; 1166 hb_enable_fp->item = params->item; 1167 hb_enable_fp->session = params->session; 1168 1169 wmi_mtrace(WMI_HB_SET_ENABLE_CMDID, NO_SESSION, 0); 1170 status = wmi_unified_cmd_send(wmi_handle, buf, 1171 len, WMI_HB_SET_ENABLE_CMDID); 1172 if (QDF_IS_STATUS_ERROR(status)) { 1173 wmi_err("cmd_send WMI_HB_SET_ENABLE returned Error %d", 1174 status); 1175 wmi_buf_free(buf); 1176 } 1177 1178 return status; 1179 } 1180 1181 /** 1182 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 1183 * @wmi_handle: wmi handle 1184 * @lphb_conf_req: lphb config request 1185 * 1186 * Return: CDF status 1187 */ 1188 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 1189 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 1190 { 1191 QDF_STATUS status; 1192 wmi_buf_t buf = NULL; 1193 uint8_t *buf_ptr; 1194 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 1195 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 1196 1197 buf = wmi_buf_alloc(wmi_handle, len); 1198 if (!buf) { 1199 return QDF_STATUS_E_NOMEM; 1200 } 1201 1202 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1203 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 1204 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 1205 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 1206 WMITLV_GET_STRUCT_TLVLEN 1207 (wmi_hb_set_tcp_params_cmd_fixed_param)); 1208 1209 /* fill in values */ 1210 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 1211 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 1212 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 1213 hb_tcp_params_fp->seq = lphb_conf_req->seq; 1214 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 1215 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 1216 hb_tcp_params_fp->interval = lphb_conf_req->interval; 1217 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 1218 hb_tcp_params_fp->session = lphb_conf_req->session; 1219 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 1220 &lphb_conf_req->gateway_mac, 1221 sizeof(hb_tcp_params_fp->gateway_mac)); 1222 1223 wmi_mtrace(WMI_HB_SET_TCP_PARAMS_CMDID, NO_SESSION, 0); 1224 status = wmi_unified_cmd_send(wmi_handle, buf, 1225 len, WMI_HB_SET_TCP_PARAMS_CMDID); 1226 if (QDF_IS_STATUS_ERROR(status)) { 1227 wmi_err("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 1228 status); 1229 wmi_buf_free(buf); 1230 } 1231 1232 return status; 1233 } 1234 1235 /** 1236 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 1237 * @wmi_handle: wmi handle 1238 * @lphb_conf_req: lphb config request 1239 * 1240 * Return: CDF status 1241 */ 1242 static 1243 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 1244 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 1245 { 1246 QDF_STATUS status; 1247 wmi_buf_t buf = NULL; 1248 uint8_t *buf_ptr; 1249 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 1250 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 1251 1252 buf = wmi_buf_alloc(wmi_handle, len); 1253 if (!buf) { 1254 return QDF_STATUS_E_NOMEM; 1255 } 1256 1257 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1258 hb_tcp_filter_fp = 1259 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 1260 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 1261 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 1262 WMITLV_GET_STRUCT_TLVLEN 1263 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 1264 1265 /* fill in values */ 1266 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 1267 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 1268 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 1269 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 1270 memcpy((void *)&hb_tcp_filter_fp->filter, 1271 (void *)&g_hb_tcp_filter_fp->filter, 1272 WMI_WLAN_HB_MAX_FILTER_SIZE); 1273 1274 wmi_mtrace(WMI_HB_SET_TCP_PKT_FILTER_CMDID, NO_SESSION, 0); 1275 status = wmi_unified_cmd_send(wmi_handle, buf, 1276 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 1277 if (QDF_IS_STATUS_ERROR(status)) { 1278 wmi_err("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 1279 status); 1280 wmi_buf_free(buf); 1281 } 1282 1283 return status; 1284 } 1285 1286 /** 1287 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 1288 * @wmi_handle: wmi handle 1289 * @lphb_conf_req: lphb config request 1290 * 1291 * Return: CDF status 1292 */ 1293 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 1294 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 1295 { 1296 QDF_STATUS status; 1297 wmi_buf_t buf = NULL; 1298 uint8_t *buf_ptr; 1299 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 1300 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 1301 1302 buf = wmi_buf_alloc(wmi_handle, len); 1303 if (!buf) { 1304 return QDF_STATUS_E_NOMEM; 1305 } 1306 1307 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1308 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 1309 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 1310 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 1311 WMITLV_GET_STRUCT_TLVLEN 1312 (wmi_hb_set_udp_params_cmd_fixed_param)); 1313 1314 /* fill in values */ 1315 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 1316 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 1317 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 1318 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 1319 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 1320 hb_udp_params_fp->interval = lphb_conf_req->interval; 1321 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 1322 hb_udp_params_fp->session = lphb_conf_req->session; 1323 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 1324 &lphb_conf_req->gateway_mac, 1325 sizeof(lphb_conf_req->gateway_mac)); 1326 1327 wmi_mtrace(WMI_HB_SET_UDP_PARAMS_CMDID, NO_SESSION, 0); 1328 status = wmi_unified_cmd_send(wmi_handle, buf, 1329 len, WMI_HB_SET_UDP_PARAMS_CMDID); 1330 if (QDF_IS_STATUS_ERROR(status)) { 1331 wmi_err("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 1332 status); 1333 wmi_buf_free(buf); 1334 } 1335 1336 return status; 1337 } 1338 1339 /** 1340 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 1341 * @wmi_handle: wmi handle 1342 * @lphb_conf_req: lphb config request 1343 * 1344 * Return: CDF status 1345 */ 1346 static 1347 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 1348 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 1349 { 1350 QDF_STATUS status; 1351 wmi_buf_t buf = NULL; 1352 uint8_t *buf_ptr; 1353 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 1354 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 1355 1356 buf = wmi_buf_alloc(wmi_handle, len); 1357 if (!buf) { 1358 return QDF_STATUS_E_NOMEM; 1359 } 1360 1361 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1362 hb_udp_filter_fp = 1363 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 1364 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 1365 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 1366 WMITLV_GET_STRUCT_TLVLEN 1367 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 1368 1369 /* fill in values */ 1370 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 1371 hb_udp_filter_fp->length = lphb_conf_req->length; 1372 hb_udp_filter_fp->offset = lphb_conf_req->offset; 1373 hb_udp_filter_fp->session = lphb_conf_req->session; 1374 memcpy((void *)&hb_udp_filter_fp->filter, 1375 (void *)&lphb_conf_req->filter, 1376 WMI_WLAN_HB_MAX_FILTER_SIZE); 1377 1378 wmi_mtrace(WMI_HB_SET_UDP_PKT_FILTER_CMDID, NO_SESSION, 0); 1379 status = wmi_unified_cmd_send(wmi_handle, buf, 1380 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 1381 if (QDF_IS_STATUS_ERROR(status)) { 1382 wmi_err("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 1383 status); 1384 wmi_buf_free(buf); 1385 } 1386 1387 return status; 1388 } 1389 1390 void wmi_lphb_attach_tlv(struct wmi_unified *wmi_handle) 1391 { 1392 struct wmi_ops *ops = wmi_handle->ops; 1393 1394 ops->send_lphb_config_hbenable_cmd = 1395 send_lphb_config_hbenable_cmd_tlv; 1396 ops->send_lphb_config_tcp_params_cmd = 1397 send_lphb_config_tcp_params_cmd_tlv; 1398 ops->send_lphb_config_tcp_pkt_filter_cmd = 1399 send_lphb_config_tcp_pkt_filter_cmd_tlv; 1400 ops->send_lphb_config_udp_params_cmd = 1401 send_lphb_config_udp_params_cmd_tlv; 1402 ops->send_lphb_config_udp_pkt_filter_cmd = 1403 send_lphb_config_udp_pkt_filter_cmd_tlv; 1404 } 1405 #endif /* FEATURE_WLAN_LPHB */ 1406 1407 #ifdef WLAN_FEATURE_PACKET_FILTERING 1408 /** 1409 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 1410 * @wmi_handle: wmi handle 1411 * @vdev_id: vdev id 1412 * @enable: Flag to enable/disable packet filter 1413 * 1414 * Return: QDF_STATUS_SUCCESS for success or error code 1415 */ 1416 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 1417 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 1418 { 1419 int32_t len; 1420 int ret = 0; 1421 wmi_buf_t buf; 1422 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 1423 1424 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 1425 1426 buf = wmi_buf_alloc(wmi_handle, len); 1427 if (!buf) { 1428 return QDF_STATUS_E_NOMEM; 1429 } 1430 1431 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 1432 WMITLV_SET_HDR(&cmd->tlv_header, 1433 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 1434 WMITLV_GET_STRUCT_TLVLEN( 1435 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 1436 1437 cmd->vdev_id = vdev_id; 1438 if (enable) 1439 cmd->enable = PACKET_FILTER_SET_ENABLE; 1440 else 1441 cmd->enable = PACKET_FILTER_SET_DISABLE; 1442 1443 wmi_err("Packet filter enable %d for vdev_id %d", cmd->enable, vdev_id); 1444 1445 wmi_mtrace(WMI_PACKET_FILTER_ENABLE_CMDID, cmd->vdev_id, 0); 1446 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1447 WMI_PACKET_FILTER_ENABLE_CMDID); 1448 if (ret) { 1449 wmi_err("Failed to send packet filter wmi cmd to fw"); 1450 wmi_buf_free(buf); 1451 } 1452 1453 return ret; 1454 } 1455 1456 /** 1457 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 1458 * @wmi_handle: wmi handle 1459 * @vdev_id: vdev id 1460 * @rcv_filter_param: Packet filter parameters 1461 * @filter_id: Filter id 1462 * @enable: Flag to add/delete packet filter configuration 1463 * 1464 * Return: QDF_STATUS_SUCCESS for success or error code 1465 */ 1466 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 1467 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 1468 uint8_t filter_id, bool enable) 1469 { 1470 int len, i; 1471 int err = 0; 1472 wmi_buf_t buf; 1473 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 1474 1475 /* allocate the memory */ 1476 len = sizeof(*cmd); 1477 buf = wmi_buf_alloc(wmi_handle, len); 1478 if (!buf) { 1479 return QDF_STATUS_E_NOMEM; 1480 } 1481 1482 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 1483 WMITLV_SET_HDR(&cmd->tlv_header, 1484 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 1485 WMITLV_GET_STRUCT_TLVLEN 1486 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 1487 1488 cmd->vdev_id = vdev_id; 1489 cmd->filter_id = filter_id; 1490 if (enable) 1491 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 1492 else 1493 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 1494 1495 if (enable) { 1496 cmd->num_params = QDF_MIN( 1497 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 1498 rcv_filter_param->num_params); 1499 cmd->filter_type = rcv_filter_param->filter_type; 1500 cmd->coalesce_time = rcv_filter_param->coalesce_time; 1501 1502 for (i = 0; i < cmd->num_params; i++) { 1503 cmd->paramsData[i].proto_type = 1504 rcv_filter_param->params_data[i].protocol_layer; 1505 cmd->paramsData[i].cmp_type = 1506 rcv_filter_param->params_data[i].compare_flag; 1507 cmd->paramsData[i].data_length = 1508 rcv_filter_param->params_data[i].data_length; 1509 cmd->paramsData[i].data_offset = 1510 rcv_filter_param->params_data[i].data_offset; 1511 memcpy(&cmd->paramsData[i].compareData, 1512 rcv_filter_param->params_data[i].compare_data, 1513 sizeof(cmd->paramsData[i].compareData)); 1514 memcpy(&cmd->paramsData[i].dataMask, 1515 rcv_filter_param->params_data[i].data_mask, 1516 sizeof(cmd->paramsData[i].dataMask)); 1517 } 1518 } 1519 1520 wmi_err("Packet filter action %d filter with id: %d, num_params=%d", 1521 cmd->filter_action, cmd->filter_id, cmd->num_params); 1522 /* send the command along with data */ 1523 wmi_mtrace(WMI_PACKET_FILTER_CONFIG_CMDID, cmd->vdev_id, 0); 1524 err = wmi_unified_cmd_send(wmi_handle, buf, len, 1525 WMI_PACKET_FILTER_CONFIG_CMDID); 1526 if (err) { 1527 wmi_err("Failed to send pkt_filter cmd"); 1528 wmi_buf_free(buf); 1529 return QDF_STATUS_E_FAILURE; 1530 } 1531 1532 return QDF_STATUS_SUCCESS; 1533 } 1534 1535 void wmi_packet_filtering_attach_tlv(struct wmi_unified *wmi_handle) 1536 { 1537 struct wmi_ops *ops = wmi_handle->ops; 1538 1539 ops->send_enable_disable_packet_filter_cmd = 1540 send_enable_disable_packet_filter_cmd_tlv; 1541 ops->send_config_packet_filter_cmd = 1542 send_config_packet_filter_cmd_tlv; 1543 } 1544 #endif /* WLAN_FEATURE_PACKET_FILTERING */ 1545 1546 /** 1547 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 1548 * @wmi_handle: wmi handle 1549 * @ptrn_id: pattern id 1550 * @vdev_id: vdev id 1551 * 1552 * Return: CDF status 1553 */ 1554 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 1555 uint8_t ptrn_id, 1556 uint8_t vdev_id) 1557 { 1558 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 1559 wmi_buf_t buf; 1560 int32_t len; 1561 int ret; 1562 1563 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 1564 1565 buf = wmi_buf_alloc(wmi_handle, len); 1566 if (!buf) { 1567 return QDF_STATUS_E_NOMEM; 1568 } 1569 1570 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 1571 1572 WMITLV_SET_HDR(&cmd->tlv_header, 1573 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 1574 WMITLV_GET_STRUCT_TLVLEN( 1575 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 1576 cmd->vdev_id = vdev_id; 1577 cmd->pattern_id = ptrn_id; 1578 cmd->pattern_type = WOW_BITMAP_PATTERN; 1579 1580 wmi_mtrace(WMI_WOW_DEL_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 1581 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1582 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 1583 if (ret) { 1584 wmi_err("Failed to delete wow ptrn from fw"); 1585 wmi_buf_free(buf); 1586 return QDF_STATUS_E_FAILURE; 1587 } 1588 1589 return QDF_STATUS_SUCCESS; 1590 } 1591 1592 #ifdef WMI_HOST_WAKEUP_OVER_QMI 1593 static inline 1594 QDF_STATUS wmi_unified_cmd_send_chk(struct wmi_unified *wmi_handle, 1595 wmi_buf_t buf, 1596 uint32_t buflen, uint32_t cmd_id) 1597 { 1598 wmi_debug("Send WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID over QMI"); 1599 return wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 1600 buflen, cmd_id); 1601 } 1602 #else 1603 static inline 1604 QDF_STATUS wmi_unified_cmd_send_chk(struct wmi_unified *wmi_handle, 1605 wmi_buf_t buf, 1606 uint32_t buflen, uint32_t cmd_id) 1607 { 1608 return wmi_unified_cmd_send(wmi_handle, buf, 1609 buflen, cmd_id); 1610 } 1611 #endif 1612 1613 /** 1614 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 1615 * @wmi_handle: wmi handle 1616 * 1617 * Sends host wakeup indication to FW. On receiving this indication, 1618 * FW will come out of WOW. 1619 * 1620 * Return: CDF status 1621 */ 1622 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 1623 { 1624 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 1625 wmi_buf_t buf; 1626 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 1627 int32_t len; 1628 int ret; 1629 1630 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 1631 1632 buf = wmi_buf_alloc(wmi_handle, len); 1633 if (!buf) { 1634 return QDF_STATUS_E_NOMEM; 1635 } 1636 1637 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 1638 wmi_buf_data(buf); 1639 WMITLV_SET_HDR(&cmd->tlv_header, 1640 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 1641 WMITLV_GET_STRUCT_TLVLEN 1642 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 1643 1644 wmi_mtrace(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, NO_SESSION, 0); 1645 ret = wmi_unified_cmd_send_chk(wmi_handle, buf, len, 1646 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 1647 if (ret) { 1648 wmi_err("Failed to send host wakeup indication to fw"); 1649 wmi_buf_free(buf); 1650 return QDF_STATUS_E_FAILURE; 1651 } 1652 1653 return qdf_status; 1654 } 1655 1656 /** 1657 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 1658 * will wake up host after specified time is elapsed 1659 * @wmi_handle: wmi handle 1660 * @vdev_id: vdev id 1661 * @cookie: value to identify reason why host set up wake call. 1662 * @time: time in ms 1663 * 1664 * Return: QDF status 1665 */ 1666 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 1667 uint8_t vdev_id, uint32_t cookie, uint32_t time) 1668 { 1669 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 1670 wmi_buf_t buf; 1671 uint8_t *buf_ptr; 1672 int32_t len; 1673 int ret; 1674 1675 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 1676 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 1677 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 1678 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 1679 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 1680 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 1681 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 1682 1683 buf = wmi_buf_alloc(wmi_handle, len); 1684 if (!buf) { 1685 return QDF_STATUS_E_NOMEM; 1686 } 1687 1688 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 1689 buf_ptr = (uint8_t *) cmd; 1690 1691 WMITLV_SET_HDR(&cmd->tlv_header, 1692 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 1693 WMITLV_GET_STRUCT_TLVLEN 1694 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 1695 cmd->vdev_id = vdev_id; 1696 cmd->pattern_id = cookie, 1697 cmd->pattern_type = WOW_TIMER_PATTERN; 1698 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 1699 1700 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 1701 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1702 buf_ptr += WMI_TLV_HDR_SIZE; 1703 1704 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 1705 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1706 buf_ptr += WMI_TLV_HDR_SIZE; 1707 1708 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 1709 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1710 buf_ptr += WMI_TLV_HDR_SIZE; 1711 1712 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 1713 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 1714 buf_ptr += WMI_TLV_HDR_SIZE; 1715 1716 /* Fill TLV for pattern_info_timeout, and time value */ 1717 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 1718 buf_ptr += WMI_TLV_HDR_SIZE; 1719 *((uint32_t *) buf_ptr) = time; 1720 buf_ptr += sizeof(uint32_t); 1721 1722 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 1723 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 1724 buf_ptr += WMI_TLV_HDR_SIZE; 1725 *((uint32_t *) buf_ptr) = 0; 1726 1727 wmi_debug("send wake timer pattern with time[%d] to fw vdev = %d", 1728 time, vdev_id); 1729 1730 wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 1731 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1732 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 1733 if (ret) { 1734 wmi_err("Failed to send wake timer pattern to fw"); 1735 wmi_buf_free(buf); 1736 return QDF_STATUS_E_FAILURE; 1737 } 1738 1739 return QDF_STATUS_SUCCESS; 1740 } 1741 1742 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT 1743 /** 1744 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 1745 * @wmi_handle: wmi handle 1746 * @params: ext wow params 1747 * 1748 * Return:0 for success or error code 1749 */ 1750 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 1751 struct ext_wow_params *params) 1752 { 1753 wmi_extwow_enable_cmd_fixed_param *cmd; 1754 wmi_buf_t buf; 1755 int32_t len; 1756 int ret; 1757 1758 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 1759 buf = wmi_buf_alloc(wmi_handle, len); 1760 if (!buf) { 1761 return QDF_STATUS_E_NOMEM; 1762 } 1763 1764 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1765 1766 WMITLV_SET_HDR(&cmd->tlv_header, 1767 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 1768 WMITLV_GET_STRUCT_TLVLEN 1769 (wmi_extwow_enable_cmd_fixed_param)); 1770 1771 cmd->vdev_id = params->vdev_id; 1772 cmd->type = params->type; 1773 cmd->wakeup_pin_num = params->wakeup_pin_num; 1774 1775 wmi_debug("vdev_id %d type %d Wakeup_pin_num %x", 1776 cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 1777 1778 wmi_mtrace(WMI_EXTWOW_ENABLE_CMDID, cmd->vdev_id, 0); 1779 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1780 WMI_EXTWOW_ENABLE_CMDID); 1781 if (ret) { 1782 wmi_err("Failed to set EXTWOW Enable"); 1783 wmi_buf_free(buf); 1784 return QDF_STATUS_E_FAILURE; 1785 } 1786 1787 return QDF_STATUS_SUCCESS; 1788 1789 } 1790 1791 /** 1792 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 1793 * @wmi_handle: wmi handle 1794 * @appType2Params: app type2 params 1795 * 1796 * Return: CDF status 1797 */ 1798 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 1799 struct app_type2_params *appType2Params) 1800 { 1801 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 1802 wmi_buf_t buf; 1803 int32_t len; 1804 int ret; 1805 1806 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 1807 buf = wmi_buf_alloc(wmi_handle, len); 1808 if (!buf) { 1809 return QDF_STATUS_E_NOMEM; 1810 } 1811 1812 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 1813 wmi_buf_data(buf); 1814 1815 WMITLV_SET_HDR(&cmd->tlv_header, 1816 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 1817 WMITLV_GET_STRUCT_TLVLEN 1818 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 1819 1820 cmd->vdev_id = appType2Params->vdev_id; 1821 1822 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 1823 cmd->rc4_key_len = appType2Params->rc4_key_len; 1824 1825 cmd->ip_id = appType2Params->ip_id; 1826 cmd->ip_device_ip = appType2Params->ip_device_ip; 1827 cmd->ip_server_ip = appType2Params->ip_server_ip; 1828 1829 cmd->tcp_src_port = appType2Params->tcp_src_port; 1830 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 1831 cmd->tcp_seq = appType2Params->tcp_seq; 1832 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 1833 1834 cmd->keepalive_init = appType2Params->keepalive_init; 1835 cmd->keepalive_min = appType2Params->keepalive_min; 1836 cmd->keepalive_max = appType2Params->keepalive_max; 1837 cmd->keepalive_inc = appType2Params->keepalive_inc; 1838 1839 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 1840 &cmd->gateway_mac); 1841 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 1842 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 1843 1844 wmi_debug("vdev_id %d gateway_mac "QDF_MAC_ADDR_FMT" " 1845 "rc4_key %.16s rc4_key_len %u " 1846 "ip_id %x ip_device_ip %x ip_server_ip %x " 1847 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 1848 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 1849 "keepalive_max %u keepalive_inc %u " 1850 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 1851 cmd->vdev_id, 1852 QDF_MAC_ADDR_REF(appType2Params->gateway_mac.bytes), 1853 cmd->rc4_key, cmd->rc4_key_len, 1854 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 1855 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 1856 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 1857 cmd->keepalive_max, cmd->keepalive_inc, 1858 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 1859 1860 wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, cmd->vdev_id, 0); 1861 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1862 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 1863 if (ret) { 1864 wmi_err("Failed to set APP TYPE2 PARAMS"); 1865 wmi_buf_free(buf); 1866 return QDF_STATUS_E_FAILURE; 1867 } 1868 1869 return QDF_STATUS_SUCCESS; 1870 1871 } 1872 1873 /** 1874 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 1875 * @wmi_handle: wmi handle 1876 * @app_type1_params: app type1 params 1877 * 1878 * Return: CDF status 1879 */ 1880 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 1881 struct app_type1_params *app_type1_params) 1882 { 1883 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 1884 wmi_buf_t buf; 1885 int32_t len; 1886 int ret; 1887 1888 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 1889 buf = wmi_buf_alloc(wmi_handle, len); 1890 if (!buf) { 1891 return QDF_STATUS_E_NOMEM; 1892 } 1893 1894 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 1895 wmi_buf_data(buf); 1896 1897 WMITLV_SET_HDR(&cmd->tlv_header, 1898 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 1899 WMITLV_GET_STRUCT_TLVLEN 1900 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 1901 1902 cmd->vdev_id = app_type1_params->vdev_id; 1903 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 1904 &cmd->wakee_mac); 1905 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 1906 cmd->ident_len = app_type1_params->id_length; 1907 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 1908 cmd->passwd_len = app_type1_params->pass_length; 1909 1910 wmi_debug("vdev_id %d wakee_mac_addr "QDF_MAC_ADDR_FMT" " 1911 "identification_id %.8s id_length %u " 1912 "password %.16s pass_length %u", 1913 cmd->vdev_id, 1914 QDF_MAC_ADDR_REF(app_type1_params->wakee_mac_addr.bytes), 1915 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 1916 1917 wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, cmd->vdev_id, 0); 1918 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1919 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 1920 if (ret) { 1921 wmi_err("Failed to set APP TYPE1 PARAMS"); 1922 wmi_buf_free(buf); 1923 return QDF_STATUS_E_FAILURE; 1924 } 1925 1926 return QDF_STATUS_SUCCESS; 1927 } 1928 1929 void wmi_extwow_attach_tlv(struct wmi_unified *wmi_handle) 1930 { 1931 struct wmi_ops *ops = wmi_handle->ops; 1932 1933 ops->send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv; 1934 ops->send_set_app_type2_params_in_fw_cmd = 1935 send_set_app_type2_params_in_fw_cmd_tlv; 1936 ops->send_app_type1_params_in_fw_cmd = 1937 send_app_type1_params_in_fw_cmd_tlv; 1938 } 1939 #endif /* WLAN_FEATURE_EXTWOW_SUPPORT */ 1940 1941 void wmi_pmo_attach_tlv(wmi_unified_t wmi_handle) 1942 { 1943 struct wmi_ops *ops = wmi_handle->ops; 1944 1945 ops->send_add_wow_wakeup_event_cmd = 1946 send_add_wow_wakeup_event_cmd_tlv; 1947 ops->send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv; 1948 ops->send_enable_arp_ns_offload_cmd = 1949 send_enable_arp_ns_offload_cmd_tlv; 1950 ops->send_add_clear_mcbc_filter_cmd = 1951 send_add_clear_mcbc_filter_cmd_tlv; 1952 ops->send_multiple_add_clear_mcbc_filter_cmd = 1953 send_multiple_add_clear_mcbc_filter_cmd_tlv; 1954 ops->send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv; 1955 ops->send_gtk_offload_cmd = send_gtk_offload_cmd_tlv; 1956 ops->send_process_gtk_offload_getinfo_cmd = 1957 send_process_gtk_offload_getinfo_cmd_tlv; 1958 ops->send_enable_enhance_multicast_offload_cmd = 1959 send_enable_enhance_multicast_offload_tlv; 1960 ops->extract_gtk_rsp_event = extract_gtk_rsp_event_tlv; 1961 ops->send_action_frame_patterns_cmd = 1962 send_action_frame_patterns_cmd_tlv; 1963 ops->send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv; 1964 ops->send_host_wakeup_ind_to_fw_cmd = 1965 send_host_wakeup_ind_to_fw_cmd_tlv; 1966 ops->send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv; 1967 1968 wmi_d0wow_attach_tlv(wmi_handle); 1969 wmi_ra_filtering_attach_tlv(wmi_handle); 1970 wmi_lphb_attach_tlv(wmi_handle); 1971 wmi_packet_filtering_attach_tlv(wmi_handle); 1972 wmi_extwow_attach_tlv(wmi_handle); 1973 } 1974