1 /* 2 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "iot_sim_cmn_api_i.h" 19 #include "iot_sim_defs_i.h" 20 #include "wlan_iot_sim_tgt_api.h" 21 #include <qdf_mem.h> 22 #include <qdf_types.h> 23 #include <qdf_util.h> 24 #include <qdf_str.h> 25 #include <qdf_delayed_work.h> 26 #include <wmi_unified_param.h> 27 #include <wlan_iot_sim_utils_api.h> 28 #include <wlan_lmac_if_api.h> 29 #include <wlan_objmgr_peer_obj.h> 30 31 /* 32 * iot_sim_oper_to_str - function to return iot sim operation string 33 * @oper: iot sim operation 34 * 35 * Return: string pointer 36 */ 37 uint8_t * 38 iot_sim_oper_to_str(enum iot_sim_operations oper) 39 { 40 switch (oper) { 41 case CONTENT_CHANGE: 42 return "content change"; 43 case DELAY: 44 return "delay"; 45 case DROP: 46 return "drop"; 47 default: 48 return "invalid"; 49 } 50 } 51 52 /* 53 * iot_sim_convert_offset_to_hex_str - function to convert offset into binary 54 * @offset: user provided offset value while action frame rule deletion 55 * @hex: buffer to store converted value 56 * @count: size of hex buffer 57 * 58 * Return: string pointer 59 */ 60 QDF_STATUS 61 iot_sim_convert_offset_to_hex_str(uint16_t offset, uint8_t *hex, int8_t count) 62 { 63 uint8_t temp[5]; 64 int ret; 65 66 snprintf(temp, sizeof(temp), "%04u", offset); 67 68 ret = qdf_hex_str_to_binary(hex, temp, count); 69 if (ret == -1) { 70 iot_sim_err("offset to hex conversion failed"); 71 return QDF_STATUS_E_FAILURE; 72 } 73 74 return QDF_STATUS_SUCCESS; 75 } 76 77 /* 78 * iot_sim_parse_action_frame - function to parse action frame to decode 79 * category and action code 80 * 81 * @length: length for content provided by user 82 * @offset: offset provided by user 83 * @content: user provided content 84 * @category: buffer to store iot specific category code 85 * @action: buffer to store iot specific action code 86 * 87 * Return: QDF_STATUS_SUCCESS on success otherwise failure 88 */ 89 QDF_STATUS 90 iot_sim_parse_action_frame(uint16_t length, uint16_t offset, uint8_t *content, 91 uint8_t *category, uint8_t *action) 92 { 93 QDF_STATUS status = QDF_STATUS_SUCCESS; 94 uint8_t hex[2], *ptr = NULL; 95 96 if (!length) { 97 status = iot_sim_convert_offset_to_hex_str(offset, hex, 98 sizeof(hex)); 99 if (QDF_IS_STATUS_ERROR(status)) 100 return status; 101 102 /* Offset represet category type and action type */ 103 status = iot_sim_get_index_for_action_frm(hex, category, 104 action, false); 105 if (status == QDF_STATUS_E_FAULT) { 106 iot_sim_err("Get indices for action failed"); 107 return status; 108 } 109 } else if (length && content) { 110 /* if offset is zero, move ptr post header */ 111 if (offset == 0) { 112 ptr = content + sizeof(struct ieee80211_frame); 113 } else if (offset == sizeof(struct ieee80211_frame)) { 114 ptr = content; 115 } else { 116 iot_sim_err("wrong offset for action frame content"); 117 return QDF_STATUS_E_FAILURE; 118 } 119 status = iot_sim_get_index_for_action_frm(ptr, category, 120 action, false); 121 } 122 return status; 123 } 124 125 /* 126 * iot_sim_find_peer_from_mac - function to find the iot sim peer data 127 * based on the mac address provided 128 * 129 * @isc: iot_sim pdev private object 130 * @mac: mac address of the peer 131 * 132 * Return: iot_sim_rule_per_peer reference if exists else NULL 133 */ 134 struct iot_sim_rule_per_peer * 135 iot_sim_find_peer_from_mac(struct iot_sim_context *isc, 136 struct qdf_mac_addr *mac) 137 { 138 struct iot_sim_rule_per_peer *peer_rule = NULL; 139 qdf_list_node_t *node = NULL, *next_node = NULL; 140 141 if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) 142 return &isc->bcast_peer; 143 else { 144 if (qdf_list_empty(&isc->peer_list)) { 145 iot_sim_debug("peer_list empty"); 146 return NULL; 147 } 148 149 qdf_spin_lock_bh(&isc->iot_sim_lock); 150 if (QDF_STATUS_SUCCESS != 151 qdf_list_peek_front(&isc->peer_list, &next_node)) { 152 qdf_spin_unlock_bh(&isc->iot_sim_lock); 153 iot_sim_err("Failed to get peer rule from peer_list"); 154 return NULL; 155 } 156 157 do { 158 node = next_node; 159 peer_rule = 160 qdf_container_of(node, 161 struct iot_sim_rule_per_peer, 162 node); 163 if (qdf_is_macaddr_equal(&peer_rule->addr, mac)) { 164 qdf_spin_unlock_bh(&isc->iot_sim_lock); 165 return peer_rule; 166 } 167 } while (QDF_STATUS_SUCCESS == 168 qdf_list_peek_next(&isc->peer_list, node, &next_node)); 169 170 qdf_spin_unlock_bh(&isc->iot_sim_lock); 171 iot_sim_debug("Failed to find peer"); 172 } 173 174 return NULL; 175 } 176 177 /* 178 * iot_sim_add_peer - function to add the iot sim peer data 179 * 180 * @isc: iot_sim pdev private object 181 * @mac: mac address of the peer 182 * 183 * Return: iot_sim_rule_per_peer reference 184 */ 185 struct iot_sim_rule_per_peer * 186 iot_sim_add_peer(struct iot_sim_context *isc, struct qdf_mac_addr *mac) 187 { 188 struct iot_sim_rule_per_peer *peer_rule = NULL; 189 QDF_STATUS status; 190 191 if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) { 192 iot_sim_err("called iot_sim_add_peer for broadcast address"); 193 return &isc->bcast_peer; 194 } 195 196 qdf_spin_lock_bh(&isc->iot_sim_lock); 197 if (qdf_list_size(&isc->peer_list) < MAX_PEER_COUNT) { 198 peer_rule = qdf_mem_malloc(sizeof 199 (struct iot_sim_rule_per_peer)); 200 if (!peer_rule) { 201 iot_sim_err("Memory alloc failed for peer: " 202 QDF_MAC_ADDR_FMT, 203 QDF_MAC_ADDR_REF(mac->bytes)); 204 goto rel_lock; 205 } 206 207 qdf_copy_macaddr(&peer_rule->addr, mac); 208 status = qdf_list_insert_back(&isc->peer_list, 209 &peer_rule->node); 210 if (QDF_IS_STATUS_ERROR(status)) { 211 iot_sim_err("peer_list enqueue failed for peer " 212 QDF_MAC_ADDR_FMT, 213 QDF_MAC_ADDR_REF(mac->bytes)); 214 qdf_mem_free(peer_rule); 215 peer_rule = NULL; 216 } 217 } else { 218 iot_sim_err("peer_list already reached max limit"); 219 } 220 221 rel_lock: 222 qdf_spin_unlock_bh(&isc->iot_sim_lock); 223 return peer_rule; 224 } 225 226 /* 227 * iot_sim_remove_peer - function to remove the iot sim peer data 228 * 229 * @isc: iot_sim pdev private object 230 * @mac: mac address of the peer 231 * 232 * Return: void 233 */ 234 void iot_sim_remove_peer(struct iot_sim_context *isc, 235 struct iot_sim_rule_per_peer *peer_rule) 236 { 237 qdf_spin_lock_bh(&isc->iot_sim_lock); 238 qdf_list_remove_node(&isc->peer_list, &peer_rule->node); 239 qdf_spin_unlock_bh(&isc->iot_sim_lock); 240 } 241 242 /* 243 * iot_sim_validate_content - function to validate frame content. User provided 244 * content must be either full frame or full frame 245 * body or valid TLV formatted data. 246 * @buf: pointer to frame content in binary format 247 * @total_len: length of content 248 * @offset: offset provided by user 249 * 250 * Return: QDF_STATUS_SUCCESS on success 251 * QDF_STATUS_E_FAULT on failure 252 */ 253 static QDF_STATUS 254 iot_sim_validate_content(uint8_t *buf, 255 uint16_t total_len, 256 uint16_t offset) 257 { 258 char *ie = buf; 259 uint32_t len = 0, i = 0; 260 uint32_t fb = sizeof(struct ieee80211_frame); 261 262 if (offset == 0 || offset == fb) { 263 /* Replace the entire content set by user */ 264 return QDF_STATUS_SUCCESS; 265 } 266 267 /* Check for malformed IEs and proper IE 268 * boundaries in user content 269 */ 270 for (i = 0; i < total_len;) { 271 /* TLV: T(1) + L(1) + V(L)*/ 272 len = (1 + 1 + ie[1]); 273 i += len; 274 ie += len; 275 } 276 277 if (i == total_len) 278 return QDF_STATUS_SUCCESS; 279 280 iot_sim_err("iot_sim: cnt(bin) len:%u IE Parsed len:%u", 281 total_len, 282 i); 283 284 return QDF_STATUS_E_INVAL; 285 } 286 287 /* 288 * iot_sim_handle_frame_content - function to process frame content provided 289 * by user. This function will convert the ascii 290 * string into binary string and validate the 291 * content. 292 * @isc: iot sim context 293 * @pos: position to the frame content in the user buffer 294 * @storage: storage to store frame content after processing 295 * @offset: user provided offset 296 * @len: length of the user provided content in bytes 297 * 298 * Return: QDF_STATUS_SUCCESS on success 299 * QDF_STATUS_E_FAULT on hex str to binary conversion failure 300 * QDF_STATUS_E_NOMEM on memory allocation failure 301 */ 302 QDF_STATUS 303 iot_sim_handle_frame_content(struct iot_sim_context *isc, 304 const char *pos, 305 uint8_t **storage, 306 uint16_t offset, 307 uint16_t len) 308 { 309 QDF_STATUS status = QDF_STATUS_E_FAILURE; 310 int ret; 311 312 *storage = qdf_mem_malloc(len); 313 if (!*storage) { 314 iot_sim_err("iot_sim:storage allocation failed"); 315 return QDF_STATUS_E_NOMEM; 316 } 317 318 ret = qdf_hex_str_to_binary(*storage, pos, len); 319 if (ret == -1) { 320 iot_sim_err("iot_sim:hex2bin conversion failed"); 321 status = QDF_STATUS_E_FAULT; 322 goto error; 323 } 324 325 status = iot_sim_validate_content(*storage, len, offset); 326 if (QDF_IS_STATUS_ERROR(status)) { 327 iot_sim_err("iot_sim:User Content Invalid"); 328 goto error; 329 } 330 331 return QDF_STATUS_SUCCESS; 332 333 error: 334 qdf_mem_free(*storage); 335 *storage = NULL; 336 return status; 337 } 338 339 /* 340 * iot_sim_parse_user_input_content_change - function to parse user input into 341 * predefined format for content 342 * change operation. All arguments 343 * passed will be filled upon success 344 * @isc: iot sim context 345 * @userbuf: local copy of user input 346 * @count: length of userbuf 347 * @t_st: address of type variable 348 * @seq: address of seq variable 349 * @offset: address of offset variable 350 * @length: address of length variable 351 * @content: double pointer to storage to store frame content after processing 352 * @addr: pointer to mac address 353 * 354 * @storage: storage to store frame content after processing 355 * @offset: user provided offset 356 * @len: length of the user provided content in bytes 357 * 358 * Return: QDF_STATUS_SUCCESS on success 359 * QDF_STATUS_E_FAILURE otherwise 360 */ 361 QDF_STATUS 362 iot_sim_parse_user_input_content_change(struct iot_sim_context *isc, 363 char *userbuf, ssize_t count, 364 uint8_t *t_st, uint16_t *seq, 365 uint16_t *offset, uint16_t *length, 366 uint8_t **content, 367 struct qdf_mac_addr *addr) 368 { 369 QDF_STATUS status = QDF_STATUS_E_FAILURE; 370 char *argv[6], *delim = " ", *substr; 371 int argc = -1, ret = 0; 372 373 qdf_mem_zero(argv, sizeof(argv)); 374 userbuf = qdf_str_trim(userbuf); 375 376 while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) { 377 if (!isspace(*substr) && *substr != '\0') 378 argv[++argc] = substr; 379 if (argc >= 5) 380 break; 381 } 382 383 if (argc < 3) { 384 iot_sim_err("Invalid argument count %d", (argc + 1)); 385 return status; 386 } 387 388 if (!argv[0] || !argv[1] || !argv[2] || !argv[3]) { 389 iot_sim_err("One or more arguments are null"); 390 return status; 391 } 392 393 ret = kstrtou8(argv[0], 16, t_st); 394 if (ret) 395 goto err; 396 ret = kstrtou16(argv[1], 10, seq); 397 if (ret) 398 goto err; 399 ret = kstrtou16(argv[2], 10, offset); 400 if (ret) 401 goto err; 402 ret = kstrtou16(argv[3], 10, length); 403 if (ret) 404 goto err; 405 /* 406 * User can send content change data in following format: 407 * 1. Add rule for specific peer 408 * <t_st> <seq> <offset> <length> <content> <MAC> 409 * 2. Add rule for broadcast peer 410 * <t_st> <seq> <offset> <length> <content> 411 * 3. Remove rule for specific peer 412 * <t_st> <seq> <offset> <length> <MAC> 413 * 4. Remove rule for broadcast peer 414 * <t_st> <seq> <offset> <length> 415 */ 416 417 /* 418 * If length is 0, this implies remove the rule 419 */ 420 if (!*length) { 421 /* 422 * 1. Ignore the frame content 423 * 2. argv[4] is not null, then it must be a valid mac 424 * If argv[4] is null, then set 'addr' as null 425 */ 426 *content = NULL; 427 if (argv[4]) { 428 status = qdf_mac_parse(argv[4], addr); 429 if (QDF_IS_STATUS_ERROR(status)) 430 iot_sim_err("iot_sim: argv4 is invalid mac for 0 len"); 431 } else { 432 qdf_mem_zero(addr, QDF_MAC_ADDR_SIZE); 433 status = QDF_STATUS_SUCCESS; 434 } 435 /* 436 * No need to parse further just return. 437 */ 438 return status; 439 } 440 441 /* 442 * If argv[4] is valid, this implies frame content 443 */ 444 if (argv[4]) { 445 status = iot_sim_handle_frame_content(isc, argv[4], 446 content, *offset, 447 *length); 448 if (QDF_IS_STATUS_ERROR(status)) 449 return status; 450 } 451 452 /* 453 * If argv[5] is valid, this must be mac address 454 */ 455 if (argv[5]) { 456 status = qdf_mac_parse(argv[5], addr); 457 if (QDF_IS_STATUS_ERROR(status)) 458 qdf_mem_free(content); 459 } 460 461 return status; 462 err: 463 iot_sim_err("kstrtoXX failed: %d", ret); 464 return status; 465 } 466 467 /* 468 * iot_sim_get_index_for_action_frm - function to convert 802.11 action frame 469 * category and action code into iot sim 470 * specific code. 471 * 472 * @frm: buf containing 802.11 action/category codes 473 * @cat_type: buf to hold converted category code 474 * @act_type: buf to hold converted action code 475 * @rx: TRUE if its getting called in the rx path 476 * 477 * Return: QDF_STATUS_SUCCESS on success, failure otherwise 478 */ 479 QDF_STATUS 480 iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat_type, 481 uint8_t *act_type, bool rx) 482 { 483 uint8_t category, action; 484 485 category = ((struct ieee80211_action *)(frm))->ia_category; 486 action = ((struct ieee80211_action *)(frm))->ia_action; 487 488 iot_sim_info("category %x action %x", category, action); 489 490 switch (category) { 491 case IEEE80211_ACTION_CAT_BA: 492 switch (action) { 493 case IEEE80211_ACTION_BA_ADDBA_REQUEST: 494 if (rx) { 495 *cat_type = CAT_BA; 496 *act_type = action; 497 498 } else { 499 *cat_type = category; 500 *act_type = action; 501 } 502 break; 503 case IEEE80211_ACTION_BA_ADDBA_RESPONSE: 504 case IEEE80211_ACTION_BA_DELBA: 505 *cat_type = CAT_BA; 506 *act_type = action; 507 break; 508 default: 509 return QDF_STATUS_E_FAULT; 510 } 511 break; 512 case IEEE80211_ACTION_CAT_SA_QUERY: 513 switch (action) { 514 case IEEE80211_ACTION_SA_QUERY_REQUEST: 515 case IEEE80211_ACTION_SA_QUERY_RESPONSE: 516 *cat_type = CAT_SA_QUERY; 517 *act_type = action; 518 break; 519 default: 520 return QDF_STATUS_E_FAULT; 521 } 522 break; 523 case IEEE80211_ACTION_CAT_RADIO: 524 *cat_type = CAT_RADIO; 525 *act_type = action; 526 break; 527 case IEEE80211_ACTION_CAT_FAST_BSS_TRNST: 528 *cat_type = CAT_FAST_BSS_TRNST; 529 *act_type = action; 530 break; 531 case IEEE80211_ACTION_CAT_SPECTRUM: 532 *cat_type = CAT_SPECTRUM; 533 *act_type = action; 534 break; 535 case IEEE80211_ACTION_CAT_QOS: 536 *cat_type = CAT_QOS; 537 *act_type = action; 538 break; 539 case IEEE80211_ACTION_CAT_DLS: 540 *cat_type = CAT_DLS; 541 *act_type = action; 542 break; 543 case IEEE80211_ACTION_CAT_HT: 544 *cat_type = CAT_HT; 545 *act_type = action; 546 break; 547 case IEEE80211_ACTION_CAT_WNM: 548 *cat_type = CAT_WNM; 549 *act_type = action; 550 break; 551 case IEEE80211_ACTION_CAT_VHT: 552 *cat_type = CAT_VHT; 553 *act_type = action; 554 break; 555 default: 556 return QDF_STATUS_E_FAULT; 557 } 558 559 return QDF_STATUS_SUCCESS; 560 } 561 562 /* 563 * iot_sim_action_frame_supported_by_fw - function to find if action frame is 564 * supported by fw or not 565 * @category: iot_sim specific category code 566 * @action: iot_sim specific action code 567 * 568 * Return: true if supported else false 569 */ 570 bool 571 iot_sim_action_frame_supported_by_fw(uint8_t category, uint8_t action) 572 { 573 switch (category) { 574 case IEEE80211_ACTION_CAT_BA: 575 switch (action) { 576 case IEEE80211_ACTION_BA_ADDBA_REQUEST: 577 return true; 578 default: 579 return false; 580 } 581 default: 582 return false; 583 } 584 } 585 586 /* 587 * iot_sim_frame_supported_by_fw - function to find if frame is supported by fw 588 * @type: 802.11 frame type 589 * @subtype: 802.11 frame subtype 590 * 591 * Return: true if supported else false 592 */ 593 bool 594 iot_sim_frame_supported_by_fw(uint8_t type, uint8_t subtype, bool action) 595 { 596 if (action) 597 return iot_sim_action_frame_supported_by_fw(type, subtype); 598 599 switch (type << IEEE80211_FC0_TYPE_SHIFT) { 600 case IEEE80211_FC0_TYPE_MGT: 601 switch (subtype << IEEE80211_FC0_SUBTYPE_SHIFT) { 602 case IEEE80211_FC0_SUBTYPE_BEACON: 603 return true; 604 default: 605 return false; 606 } 607 case IEEE80211_FC0_TYPE_CTL: 608 switch (subtype << IEEE80211_FC0_SUBTYPE_SHIFT) { 609 case IEEE80211_FC0_SUBTYPE_TRIGGER: 610 case IEEE80211_FC0_SUBTYPE_BAR: 611 case IEEE80211_FC0_SUBTYPE_CTS: 612 case IEEE80211_FC0_SUBTYPE_ACK: 613 case IEEE80211_FC0_SUBTYPE_NDPA: 614 return true; 615 default: 616 return false; 617 } 618 case IEEE80211_FC0_TYPE_DATA: 619 switch (subtype << IEEE80211_FC0_SUBTYPE_SHIFT) { 620 default: 621 return true; 622 } 623 default: 624 return false; 625 } 626 } 627 628 /* 629 * iot_sim_remap_type_subtype - function to convert rules for response 630 * type frame into request type. This is 631 * used for drop/delay operation. This function 632 * will update the passed type and subtype value. 633 * 634 * @type: 802.11 frame type 635 * @subtype: 802.11 frame subtype 636 * @seq: authentication sequence number, mostly 0 for non-authentication frame 637 * @action: flag to indicate action frame 638 * 639 * Return: QDF_STATUS_SUCCESS 640 */ 641 QDF_STATUS 642 iot_sim_remap_type_subtype(uint8_t *type, uint8_t *subtype, 643 uint16_t *seq, bool action) 644 { 645 if (action) { 646 switch (*type) { 647 case CAT_BA: 648 switch (*subtype) { 649 case IEEE80211_ACTION_BA_ADDBA_RESPONSE: 650 *subtype = IEEE80211_ACTION_BA_ADDBA_REQUEST; 651 break; 652 default: 653 break; 654 } 655 break; 656 default: 657 break; 658 } 659 return QDF_STATUS_SUCCESS; 660 } 661 662 switch (*type << IEEE80211_FC0_TYPE_SHIFT) { 663 case IEEE80211_FC0_TYPE_MGT: 664 switch (*subtype << IEEE80211_FC0_SUBTYPE_SHIFT) { 665 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 666 *subtype = IEEE80211_FC0_SUBTYPE_ASSOC_REQ; 667 *subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT; 668 break; 669 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: 670 *subtype = IEEE80211_FC0_SUBTYPE_REASSOC_REQ; 671 *subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT; 672 break; 673 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 674 *subtype = IEEE80211_FC0_SUBTYPE_PROBE_REQ; 675 *subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT; 676 break; 677 case IEEE80211_FC0_SUBTYPE_AUTH: 678 *subtype = IEEE80211_FC0_SUBTYPE_AUTH; 679 *subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT; 680 /* If auth response (auth seq num 2) is marked as 681 * drop, then drop the auth request (auth seq num 1) 682 */ 683 if (*seq == IEEE80211_AUTH_OPEN_RESPONSE) 684 *seq = IEEE80211_AUTH_OPEN_REQUEST; 685 break; 686 default: 687 break; 688 } 689 default: 690 break; 691 } 692 693 return QDF_STATUS_SUCCESS; 694 } 695 696 /* 697 * iot_sim_send_rule_to_fw - function to send iot_sim rule to fw 698 * 699 * @isc: iot sim context 700 * @oper: iot sim operation 701 * @mac: peer mac address 702 * @type: 802.11 frame type 703 * @subtype: 802.11 frame subtype 704 * @seq: authentication sequence number, mostly 0 for non-authentication frame 705 * @offset: user provided offset 706 * @frm: user provided frame content 707 * @length: length of frm 708 * @action: flag to indicate action frame 709 * @drop: flag to indicate set drop rule 710 * @clear: flag to indicate set rule or clear 711 * 712 * Return: QDF_STATUS_SUCCESS 713 */ 714 QDF_STATUS 715 iot_sim_send_rule_to_fw(struct iot_sim_context *isc, 716 enum iot_sim_operations oper, 717 struct qdf_mac_addr *mac, 718 uint8_t type, uint8_t subtype, 719 uint16_t seq, uint16_t offset, 720 uint8_t *frm, uint16_t len, 721 bool action, bool clear) 722 { 723 struct simulation_test_params param; 724 725 if (oper != DELAY && FRAME_TYPE_IS_BEACON(type, subtype) && offset) { 726 iot_sim_info("Beacon update from offset:%d", offset); 727 return QDF_STATUS_E_NOSUPPORT; 728 } 729 730 if (iot_sim_frame_supported_by_fw(type, subtype, action)) { 731 qdf_mem_zero(¶m, sizeof(struct simulation_test_params)); 732 param.pdev_id = wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj); 733 qdf_mem_copy(param.peer_mac, mac, QDF_MAC_ADDR_SIZE); 734 param.test_cmd_type = oper; 735 /* subtype_cmd: Set subcmd based on action and clear flag */ 736 if (action) { 737 if (clear) 738 param.test_subcmd_type = DEL_RULE_ACTION; 739 else 740 param.test_subcmd_type = ADD_RULE_ACTION; 741 } else { 742 if (clear) 743 param.test_subcmd_type = DEL_RULE; 744 else 745 param.test_subcmd_type = ADD_RULE; 746 } 747 param.frame_type = type; 748 param.frame_subtype = subtype; 749 param.seq = seq; 750 param.offset = offset; 751 param.frame_length = len; 752 param.buf_len = len; 753 param.bufp = frm; 754 if (QDF_IS_STATUS_ERROR(tgt_send_simulation_cmd(isc->pdev_obj, 755 ¶m))) 756 iot_sim_err("Sending del rule to fw failed!"); 757 758 if (FRAME_TYPE_IS_BEACON(type, subtype) && clear) 759 return QDF_STATUS_E_NOSUPPORT; 760 761 return QDF_STATUS_SUCCESS; 762 } 763 764 return QDF_STATUS_E_NOSUPPORT; 765 } 766 767 /* 768 * iot_sim_del_rule - function to delete iot_sim rule 769 * 770 * @s_e: address of seq for which rule to be removed 771 * @f_e: address of the rule present in s_e to be removed 772 * @oper: iot sim operation 773 * 774 * Return: QDF_STATUS_SUCCESS 775 */ 776 QDF_STATUS 777 iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e, 778 struct iot_sim_rule **f_e, 779 enum iot_sim_operations oper, 780 struct iot_sim_context *isc) 781 { 782 if (oper == CONTENT_CHANGE) { 783 qdf_mem_free((*f_e)->frm_content); 784 (*f_e)->frm_content = NULL; 785 } else if (oper == DROP) { 786 (*f_e)->drop = false; 787 } else if (oper == DELAY) { 788 if (!qdf_delayed_work_stop((*f_e)->dwork)) { 789 iot_sim_err("delayed work is in running state"); 790 /* iot_sim_lock need to be released for the delay */ 791 /* work callback to complete execution */ 792 /* Hence releasing the lock */ 793 qdf_spin_unlock_bh(&isc->iot_sim_lock); 794 /* iot_sim_delay_lock will be freed only after delay */ 795 /* work callback execution completion */ 796 qdf_spin_lock_bh(&(*f_e)->iot_sim_delay_lock); 797 qdf_spin_lock_bh(&isc->iot_sim_lock); 798 qdf_delayed_work_stop_sync((*f_e)->dwork); 799 qdf_spin_unlock_bh(&(*f_e)->iot_sim_delay_lock); 800 } 801 802 qdf_delayed_work_destroy((*f_e)->dwork); 803 qdf_spinlock_destroy(&(*f_e)->iot_sim_delay_lock); 804 qdf_mem_free((*f_e)->dwork->context); 805 qdf_mem_free((*f_e)->dwork); 806 qdf_nbuf_free((*f_e)->nbuf_list[0]); 807 (*f_e)->nbuf_list[0] = NULL; 808 if ((*f_e)->peer) { 809 wlan_objmgr_peer_release_ref((*f_e)->peer, 810 WLAN_IOT_SIM_ID); 811 (*f_e)->peer = NULL; 812 } 813 qdf_nbuf_free((*f_e)->nbuf_list[1]); 814 (*f_e)->nbuf_list[1] = NULL; 815 (*f_e)->sec_buf = NULL; 816 qdf_mem_free((*f_e)->rx_param); 817 (*f_e)->rx_param = NULL; 818 } 819 820 if (qdf_test_bit(oper, (unsigned long *) 821 &(*f_e)->rule_bitmap)) { 822 (*s_e)->use_count--; 823 qdf_clear_bit(oper, (unsigned long *) 824 &(*f_e)->rule_bitmap); 825 } 826 827 if (!(*f_e)->rule_bitmap) { 828 qdf_mem_free(*f_e); 829 *f_e = NULL; 830 } 831 if ((*s_e)->use_count == 0) { 832 qdf_mem_free(*s_e); 833 *s_e = NULL; 834 } 835 return QDF_STATUS_SUCCESS; 836 } 837 838 /* 839 * iot_sim_delete_rule_for_mac - function to delete content change rule 840 * for given peer mac 841 * @isc: iot sim context 842 * @oper: iot sim operation 843 * @seq: authentication sequence number, mostly 0 for non-authentication frame 844 * @type: 802.11 frame type 845 * @subtype: 802.11 frame subtype 846 * @mac: peer mac address 847 * @action: action frame or not 848 * 849 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise 850 */ 851 QDF_STATUS 852 iot_sim_delete_rule_for_mac(struct iot_sim_context *isc, 853 enum iot_sim_operations oper, 854 uint16_t seq, uint8_t type, 855 uint8_t subtype, 856 struct qdf_mac_addr *mac, 857 bool action) 858 { 859 QDF_STATUS status = QDF_STATUS_SUCCESS; 860 struct iot_sim_rule_per_seq **s_e; 861 struct iot_sim_rule **f_e; 862 struct iot_sim_rule_per_peer *peer; 863 bool peer_remove = 1, broadcast_peer = 0; 864 uint8_t i; 865 866 if (qdf_is_macaddr_zero(mac)) 867 iot_sim_info("Rule deletion for all peers"); 868 else 869 iot_sim_info("Rule deletion for " QDF_MAC_ADDR_FMT, 870 QDF_MAC_ADDR_REF(mac->bytes)); 871 872 iot_sim_debug("oper:%s seq: %hu %s:%hu/%hu", 873 iot_sim_oper_to_str(oper), seq, 874 action ? "category/action code" : "type/subtype", 875 type, subtype); 876 877 if (!isc) { 878 iot_sim_err("iot_sim: isc is null"); 879 return QDF_STATUS_E_FAILURE; 880 } 881 882 if (oper == DROP || oper == DELAY) 883 iot_sim_remap_type_subtype(&type, &subtype, &seq, action); 884 885 if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) { 886 peer = &isc->bcast_peer; 887 broadcast_peer = 1; 888 } else 889 peer = iot_sim_find_peer_from_mac(isc, mac); 890 if (peer) { 891 qdf_spin_lock_bh(&isc->iot_sim_lock); 892 s_e = &peer->rule_per_seq[seq]; 893 if (!*s_e) { 894 qdf_spin_unlock_bh(&isc->iot_sim_lock); 895 return QDF_STATUS_SUCCESS; 896 } 897 898 if (action) 899 f_e = &((*s_e)->rule_per_action_frm[type][subtype]); 900 else 901 f_e = &((*s_e)->rule_per_type[type][subtype]); 902 903 if (*f_e) 904 status = iot_sim_del_rule(s_e, f_e, oper, isc); 905 906 for (i = 0; i < MAX_SEQ; i++) 907 if (peer->rule_per_seq[i]) 908 peer_remove = 0; 909 qdf_spin_unlock_bh(&isc->iot_sim_lock); 910 if (!broadcast_peer && peer_remove) { 911 iot_sim_remove_peer(isc, peer); 912 qdf_mem_free(peer); 913 } 914 } 915 916 return status; 917 } 918 919 /* 920 * iot_sim_delay_cb - Delayed work callback function 921 * to process delayed frames 922 * 923 * @context: Delayed work callback context 924 * 925 * Return: void 926 */ 927 static void iot_sim_delay_cb(void *ctxt) 928 { 929 struct wlan_objmgr_psoc *psoc = NULL; 930 struct iot_sim_cb_context *context = ctxt; 931 uint8_t *buf; 932 struct ieee80211_frame *wh; 933 struct qdf_mac_addr *mac_addr; 934 struct mgmt_rx_event_params *param = context->piot_sim_rule->rx_param; 935 struct wlan_objmgr_peer **peer = &context->piot_sim_rule->peer; 936 937 qdf_spin_lock_bh(&context->piot_sim_rule->iot_sim_delay_lock); 938 qdf_spin_lock_bh(&context->isc->iot_sim_lock); 939 psoc = wlan_pdev_get_psoc(context->isc->pdev_obj); 940 context->piot_sim_rule->sec_buf = context->piot_sim_rule->nbuf_list[0]; 941 qdf_spin_unlock_bh(&context->isc->iot_sim_lock); 942 mgmt_txrx_rx_handler(psoc, context->piot_sim_rule->sec_buf, 943 context->piot_sim_rule->rx_param); 944 qdf_spin_lock_bh(&context->isc->iot_sim_lock); 945 if (*peer) { 946 wlan_objmgr_peer_release_ref(*peer, WLAN_IOT_SIM_ID); 947 *peer = NULL; 948 } 949 if (context->piot_sim_rule->nbuf_list[1]) { 950 context->piot_sim_rule->nbuf_list[0] = 951 context->piot_sim_rule->nbuf_list[1]; 952 buf = qdf_nbuf_data(context->piot_sim_rule->nbuf_list[0]); 953 wh = (struct ieee80211_frame *)buf; 954 mac_addr = (struct qdf_mac_addr *)wh->i_addr2; 955 *peer = wlan_objmgr_get_peer(psoc, param->pdev_id, 956 (uint8_t *)mac_addr, 957 WLAN_IOT_SIM_ID); 958 959 if (!qdf_delayed_work_start(context->piot_sim_rule->dwork, 960 context-> 961 piot_sim_rule->delay_dur)) { 962 iot_sim_err("delayed_work_start failed"); 963 qdf_nbuf_free(context->piot_sim_rule->nbuf_list[0]); 964 if (*peer) { 965 wlan_objmgr_peer_release_ref(*peer, 966 WLAN_IOT_SIM_ID); 967 *peer = NULL; 968 } 969 qdf_mem_free(context->piot_sim_rule-> 970 rx_param->rx_params); 971 qdf_mem_free(context->piot_sim_rule->rx_param); 972 context->piot_sim_rule->nbuf_list[0] = NULL; 973 context->piot_sim_rule->rx_param = NULL; 974 } 975 context->piot_sim_rule->nbuf_list[1] = NULL; 976 } else { 977 context->piot_sim_rule->nbuf_list[0] = NULL; 978 qdf_mem_free(context->piot_sim_rule->rx_param->rx_params); 979 qdf_mem_free(context->piot_sim_rule->rx_param); 980 context->piot_sim_rule->rx_param = NULL; 981 } 982 983 qdf_spin_unlock_bh(&context->isc->iot_sim_lock); 984 qdf_spin_unlock_bh(&context->piot_sim_rule->iot_sim_delay_lock); 985 } 986 987 /* 988 * iot_sim_add_rule - function to add iot_sim rule 989 * 990 * @s_e: address of seq for which rule to be added 991 * @f_e: address of the rule present in s_e to be added 992 * @oper: iot sim operation 993 * @frm: user provided frame content 994 * @offset: user provided offset 995 * @len: length of the user provided frame content 996 * @isc: iot sim context 997 * 998 * Return: QDF_STATUS_SUCCESS 999 */ 1000 QDF_STATUS 1001 iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e, 1002 struct iot_sim_rule **f_e, 1003 enum iot_sim_operations oper, 1004 uint8_t *frm, uint16_t offset, uint16_t len, 1005 struct iot_sim_context *isc) 1006 { 1007 struct iot_sim_cb_context *cb_context; 1008 1009 if (!*f_e) { 1010 *f_e = qdf_mem_malloc(sizeof(struct iot_sim_rule)); 1011 if (!*f_e) { 1012 iot_sim_err("can't allocate f_e"); 1013 return QDF_STATUS_E_NOMEM; 1014 } 1015 } 1016 1017 if (oper == CONTENT_CHANGE) { 1018 (*f_e)->frm_content = qdf_mem_malloc(len); 1019 if (!((*f_e)->frm_content)) 1020 return QDF_STATUS_E_NOMEM; 1021 qdf_mem_copy((*f_e)->frm_content, frm, len); 1022 (*f_e)->len = len; 1023 (*f_e)->offset = offset; 1024 } else if (oper == DROP) { 1025 (*f_e)->drop = true; 1026 } else if (oper == DELAY) { 1027 (*f_e)->delay_dur = offset; 1028 (*f_e)->dwork = qdf_mem_malloc(sizeof(struct qdf_delayed_work)); 1029 if (!(*f_e)->dwork) { 1030 iot_sim_err("can't allocate dwork"); 1031 return QDF_STATUS_E_NOMEM; 1032 } 1033 1034 cb_context = qdf_mem_malloc(sizeof(struct iot_sim_cb_context)); 1035 if (!cb_context) { 1036 iot_sim_err("can't allocate cb_context"); 1037 qdf_mem_free((*f_e)->dwork); 1038 return QDF_STATUS_E_NOMEM; 1039 } 1040 1041 cb_context->isc = isc; 1042 cb_context->piot_sim_rule = *f_e; 1043 if (QDF_STATUS_SUCCESS != 1044 qdf_delayed_work_create((*f_e)->dwork, iot_sim_delay_cb, 1045 cb_context)) { 1046 iot_sim_err("delayed_work_create failed"); 1047 qdf_mem_free(cb_context); 1048 qdf_mem_free((*f_e)->dwork); 1049 return QDF_STATUS_E_NOMEM; 1050 } 1051 1052 (*f_e)->nbuf_list[0] = NULL; 1053 (*f_e)->nbuf_list[1] = NULL; 1054 (*f_e)->peer = NULL; 1055 iot_sim_err("delayed_work_created"); 1056 qdf_spinlock_create(&((*f_e)->iot_sim_delay_lock)); 1057 } 1058 1059 (*s_e)->use_count++; 1060 qdf_set_bit(oper, (unsigned long *) 1061 &(*f_e)->rule_bitmap); 1062 1063 return QDF_STATUS_SUCCESS; 1064 } 1065 1066 /* 1067 * iot_sim_add_rule_for_mac - function to add content change rule 1068 * for given peer mac 1069 * @isc: iot sim context 1070 * @oper: iot sim operation 1071 * @mac: peer mac address 1072 * @type: 802.11 frame type 1073 * @subtype: 802.11 frame subtype 1074 * @seq: authentication sequence number, mostly 0 for non-authentication frame 1075 * @offset: user provided offset 1076 * @frm: user provided frame content 1077 * @len: length of frm 1078 * @action: boolean to indicate action frame 1079 * 1080 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise 1081 */ 1082 QDF_STATUS 1083 iot_sim_add_rule_for_mac(struct iot_sim_context *isc, 1084 enum iot_sim_operations oper, 1085 struct qdf_mac_addr *mac, 1086 uint8_t type, uint8_t subtype, 1087 uint16_t seq, uint16_t offset, 1088 uint8_t *frm, uint16_t len, 1089 uint16_t drop, bool action) 1090 { 1091 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1092 struct iot_sim_rule_per_peer *peer; 1093 struct iot_sim_rule_per_seq **s_e = NULL; 1094 struct iot_sim_rule **f_e = NULL; 1095 1096 if (!isc) { 1097 iot_sim_err("iot_sim: isc is null"); 1098 return status; 1099 } 1100 1101 status = iot_sim_delete_rule_for_mac(isc, oper, seq, 1102 type, subtype, mac, 1103 action); 1104 if (status == QDF_STATUS_E_FAILURE) { 1105 iot_sim_err("iot_sim: Rule removed - Fail"); 1106 return status; 1107 } 1108 1109 if (oper == DROP || oper == DELAY) 1110 iot_sim_remap_type_subtype(&type, &subtype, &seq, action); 1111 1112 peer = iot_sim_find_peer_from_mac(isc, mac); 1113 if (!peer) 1114 peer = iot_sim_add_peer(isc, mac); 1115 if (peer) { 1116 qdf_spin_lock_bh(&isc->iot_sim_lock); 1117 s_e = &peer->rule_per_seq[seq]; 1118 if (!*s_e) { 1119 *s_e = qdf_mem_malloc(sizeof(struct 1120 iot_sim_rule_per_seq)); 1121 if (!*s_e) { 1122 iot_sim_err("can't allocate s_e"); 1123 qdf_spin_unlock_bh(&isc->iot_sim_lock); 1124 return QDF_STATUS_E_NOMEM; 1125 } 1126 } 1127 1128 if (action) 1129 f_e = &((*s_e)->rule_per_action_frm[type][subtype]); 1130 else 1131 f_e = &((*s_e)->rule_per_type[type][subtype]); 1132 1133 if (qdf_is_macaddr_zero(mac)) 1134 iot_sim_info("Rule addition for all peers"); 1135 else 1136 iot_sim_info("Rule addition for " QDF_MAC_ADDR_FMT, 1137 QDF_MAC_ADDR_REF(mac->bytes)); 1138 1139 iot_sim_info("oper:%s seq: %hu %s:%hu/%hu delay:%hu", 1140 iot_sim_oper_to_str(oper), seq, 1141 action ? "category/action code" : "type/subtype", 1142 type, subtype, drop); 1143 1144 if (oper == DELAY) 1145 offset = drop; 1146 1147 status = iot_sim_add_rule(s_e, f_e, oper, frm, 1148 offset, len, isc); 1149 qdf_spin_unlock_bh(&isc->iot_sim_lock); 1150 } else { 1151 /* TBD: clear the rules for peer with address 'mac'*/ 1152 } 1153 1154 return status; 1155 } 1156 1157 /* 1158 * IOT SIM User Command Format 1159 * 1160 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1161 * | FrmType/subtype | Seq | Offset | Length | content | Mac Addr | 1162 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1163 * | 1Byte | 2Byte | 2Bytes | 2Bytes | Length | 6 Bytes | 1164 * 1165 */ 1166 1167 /* 1168 * iot_sim_debug_content_change_write - Write Handler for content change 1169 * operation 1170 * @file: debugfs file pointer 1171 * @buf: buf of user input 1172 * @count: buf count 1173 * @ppos: offset on file 1174 * 1175 * Return: character read on success, failure otherwise 1176 */ 1177 static ssize_t 1178 iot_sim_debug_content_change_write(struct file *file, 1179 const char __user *buf, 1180 size_t count, loff_t *ppos) 1181 { 1182 QDF_STATUS status = QDF_STATUS_SUCCESS; 1183 unsigned char t_st, type, subtype, *content = NULL; 1184 uint16_t offset = 0, length = 0, seq = 0; 1185 char *locbuf = NULL; 1186 enum iot_sim_operations oper = CONTENT_CHANGE; 1187 struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT; 1188 struct iot_sim_context *isc = 1189 ((struct seq_file *)file->private_data)->private; 1190 uint8_t action = 0, category = 0; 1191 bool is_action = 0, clear = false; 1192 mlme_pdev_ext_t *ext = NULL; 1193 1194 if ((!buf) || (count > USER_BUF_LEN) || (count < 7)) 1195 return -EFAULT; 1196 1197 locbuf = qdf_mem_malloc(USER_BUF_LEN + 1); 1198 if (!locbuf) 1199 return -ENOMEM; 1200 1201 if (copy_from_user(locbuf, buf, count)) { 1202 qdf_mem_free(locbuf); 1203 return -EFAULT; 1204 } 1205 1206 status = iot_sim_parse_user_input_content_change(isc, locbuf, count, 1207 &t_st, &seq, &offset, 1208 &length, &content, 1209 &mac_addr); 1210 if (QDF_IS_STATUS_ERROR(status)) 1211 goto free; 1212 1213 type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT; 1214 subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK); 1215 subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT; 1216 1217 if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ) 1218 goto free; 1219 1220 if (FRAME_TYPE_IS_ACTION(type, subtype)) { 1221 status = iot_sim_parse_action_frame(length, offset, content, 1222 &category, &action); 1223 if (QDF_IS_STATUS_ERROR(status)) 1224 goto free; 1225 1226 is_action = 1; 1227 type = category; 1228 subtype = action; 1229 } 1230 1231 clear = length ? false : true; 1232 status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype, 1233 seq, offset, content, length, 1234 is_action, clear); 1235 if (QDF_IS_STATUS_SUCCESS(status)) 1236 goto free; 1237 1238 /* check for rule removal */ 1239 if (!length || !content) { 1240 status = iot_sim_delete_rule_for_mac(isc, oper, seq, 1241 type, subtype, 1242 &mac_addr, 1243 is_action); 1244 1245 } else { 1246 status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr, 1247 type, subtype, seq, offset, 1248 content, length, 0, 1249 is_action); 1250 } 1251 if (QDF_IS_STATUS_SUCCESS(status)) { 1252 iot_sim_err("iot_sim: Content Change Operation - success"); 1253 if (FRAME_TYPE_IS_BEACON(type, subtype)) { 1254 if (isc->bcn_buf && (!length || !content)) { 1255 qdf_nbuf_free(isc->bcn_buf); 1256 isc->bcn_buf = NULL; 1257 } 1258 ext = wlan_pdev_mlme_get_ext_hdl(isc->pdev_obj); 1259 if (ext) { 1260 isc->iot_sim_update_beacon_trigger(ext); 1261 iot_sim_info("Beacon update triggered"); 1262 } else { 1263 iot_sim_err("mlme_pdev_ext is null"); 1264 } 1265 } 1266 } else { 1267 iot_sim_err("iot_sim: Content Change Operation - Fail"); 1268 } 1269 free: 1270 qdf_mem_free(content); 1271 qdf_mem_free(locbuf); 1272 return count; 1273 } 1274 1275 /* 1276 * iot_sim_parse_user_input_delay - function to parse user input into 1277 * predefined format for delay operation. 1278 * All arguments passed will be filled 1279 * upon success 1280 * @isc: iot sim context 1281 * @userbuf: local copy of user input 1282 * @count: length of userbuf 1283 * @t_st: address of type variable 1284 * @seq: address of seq variable 1285 * @cat_type: 802.11 action frame category code 1286 * @act_type: 802.11 action frame action code 1287 * @delay: address of delay variable 1288 * @addr: pointer to mac address 1289 * 1290 * Return: QDF_STATUS_SUCCESS on success 1291 * QDF_STATUS_E_FAILURE otherwise 1292 */ 1293 QDF_STATUS 1294 iot_sim_parse_user_input_delay(struct iot_sim_context *isc, 1295 char *userbuf, ssize_t count, 1296 uint8_t *t_st, uint16_t *seq, 1297 uint8_t *cat_type, uint8_t *act_type, 1298 uint16_t *delay, struct qdf_mac_addr *addr) 1299 { 1300 QDF_STATUS status = QDF_STATUS_SUCCESS; 1301 char *argv[6], *delim = " ", *substr; 1302 int argc = -1, ret = 0; 1303 1304 qdf_mem_zero(argv, sizeof(argv)); 1305 userbuf = qdf_str_trim(userbuf); 1306 1307 while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) { 1308 if (!isspace(*substr) && *substr != '\0') 1309 argv[++argc] = substr; 1310 if (argc >= 5) 1311 break; 1312 } 1313 1314 if (argc < 3) { 1315 iot_sim_err("Invalid argument count %d", (argc + 1)); 1316 return status; 1317 } 1318 1319 if (!argv[0] || !argv[1] || !argv[2] || !argv[3] || !argv[4]) { 1320 iot_sim_err("One or more arguments are null"); 1321 return status; 1322 } 1323 /* 1324 * User can send delay data in following format: 1325 * 1. Add delay rule for specific peer 1326 * <t_st> <seq> <category_type> <action_type> <delay> <MAC> 1327 * 2. Remove delay rule for specific peer 1328 * <t_st> <seq> <category_type> <action_type> <delay> <MAC> 1329 */ 1330 1331 ret = kstrtou8(argv[0], 16, t_st); 1332 if (ret) 1333 goto err; 1334 ret = kstrtou16(argv[1], 10, seq); 1335 if (ret) 1336 goto err; 1337 ret = kstrtou8(argv[2], 10, cat_type); 1338 if (ret) 1339 goto err; 1340 ret = kstrtou8(argv[3], 10, act_type); 1341 if (ret) 1342 goto err; 1343 ret = kstrtou16(argv[4], 10, delay); 1344 if (ret) 1345 goto err; 1346 1347 /* 1348 * If argv[5] is valid, this must be mac address 1349 */ 1350 if (argv[5]) 1351 status = qdf_mac_parse(argv[5], addr); 1352 1353 iot_sim_err("delay rule mac address " QDF_MAC_ADDR_FMT, 1354 QDF_MAC_ADDR_REF(addr->bytes)); 1355 1356 return status; 1357 err: 1358 iot_sim_err("kstrtoXX failed: %d", ret); 1359 return QDF_STATUS_E_FAILURE; 1360 } 1361 1362 /* 1363 * iot_sim_debug_delay_write - Write Handler for delay operation 1364 * @file: debugfs file pointer 1365 * @buf: buf of user input 1366 * @count: buf count 1367 * @ppos: offset on file 1368 * 1369 * Return: character read 1370 */ 1371 static ssize_t 1372 iot_sim_debug_delay_write(struct file *file, 1373 const char __user *buf, 1374 size_t count, loff_t *ppos) 1375 { 1376 QDF_STATUS status = QDF_STATUS_SUCCESS; 1377 unsigned char t_st, type, subtype; 1378 uint16_t seq = 0; 1379 char *locbuf = NULL; 1380 enum iot_sim_operations oper = DELAY; 1381 struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT; 1382 struct iot_sim_context *isc = 1383 ((struct seq_file *)file->private_data)->private; 1384 uint8_t action = 0, category = 0, tmp[2]; 1385 bool is_action = false, clear = false; 1386 uint16_t delay = 0; 1387 1388 if ((!buf) || (count > USER_BUF_LEN_DELAY) || (count < 6)) 1389 return -EFAULT; 1390 1391 locbuf = qdf_mem_malloc(USER_BUF_LEN_DELAY + 1); 1392 if (!locbuf) 1393 return -ENOMEM; 1394 1395 if (copy_from_user(locbuf, buf, count)) { 1396 qdf_mem_free(locbuf); 1397 return -EFAULT; 1398 } 1399 1400 status = iot_sim_parse_user_input_delay(isc, locbuf, count, 1401 &t_st, &seq, &category, 1402 &action, &delay, &mac_addr); 1403 if (QDF_IS_STATUS_ERROR(status)) { 1404 iot_sim_err("iot_sim_parse_user_input_delay failed"); 1405 goto free; 1406 } 1407 iot_sim_err("Delay rule t_st:%d, seq:%hu cat_type:%d, act_type:%d, delay:%hu", 1408 t_st, seq, category, action, delay); 1409 1410 type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT; 1411 subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK); 1412 subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT; 1413 1414 if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ) 1415 goto free; 1416 1417 if (FRAME_TYPE_IS_ACTION(type, subtype)) { 1418 tmp[0] = category; 1419 tmp[1] = action; 1420 /* 1421 * convert 802.11 category and action code to iot sim codes 1422 */ 1423 status = iot_sim_get_index_for_action_frm(tmp, &category, 1424 &action, false); 1425 if (QDF_IS_STATUS_ERROR(status)) 1426 goto free; 1427 1428 is_action = 1; 1429 type = category; 1430 subtype = action; 1431 } 1432 1433 clear = delay ? false : true; 1434 status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype, 1435 seq, delay, NULL, 0, is_action, clear); 1436 if (QDF_IS_STATUS_SUCCESS(status)) 1437 goto free; 1438 1439 /* check for rule removal */ 1440 if (!delay) { 1441 status = iot_sim_delete_rule_for_mac(isc, oper, seq, 1442 type, subtype, 1443 &mac_addr, 1444 is_action); 1445 } else { 1446 status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr, 1447 type, subtype, seq, 0, 1448 NULL, 0, delay, is_action); 1449 } 1450 if (QDF_IS_STATUS_SUCCESS(status)) 1451 iot_sim_debug("iot_sim: Rule update Delay Operation - Success"); 1452 else 1453 iot_sim_err("iot_sim: Rule update Delay Operation - Fail"); 1454 free: 1455 qdf_mem_free(locbuf); 1456 return count; 1457 } 1458 1459 /* 1460 * iot_sim_parse_user_input_drop - function to parse user input into 1461 * predefined format for drop operation. 1462 * All arguments passed will be filled 1463 * upon success 1464 * @isc: iot sim context 1465 * @userbuf: local copy of user input 1466 * @count: length of userbuf 1467 * @t_st: address of type variable 1468 * @seq: address of seq variable 1469 * @cat_type: 802.11 action frame category code 1470 * @act_type: 802.11 action frame action code 1471 * @drop: address of drop variable to specify drop the frame or not 1472 * @addr: pointer to mac address 1473 * 1474 * Return: QDF_STATUS_SUCCESS on success 1475 * QDF_STATUS_E_FAILURE otherwise 1476 */ 1477 QDF_STATUS 1478 iot_sim_parse_user_input_drop(struct iot_sim_context *isc, 1479 char *userbuf, ssize_t count, 1480 uint8_t *t_st, uint16_t *seq, 1481 uint8_t *cat_type, uint8_t *act_type, 1482 uint8_t *drop, struct qdf_mac_addr *addr) 1483 { 1484 QDF_STATUS status = QDF_STATUS_SUCCESS; 1485 char *argv[6], *delim = " ", *substr; 1486 int argc = -1, ret = 0; 1487 1488 qdf_mem_zero(argv, sizeof(argv)); 1489 userbuf = qdf_str_trim(userbuf); 1490 1491 while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) { 1492 if (!isspace(*substr) && *substr != '\0') 1493 argv[++argc] = substr; 1494 if (argc >= 5) 1495 break; 1496 } 1497 1498 if (argc < 3) { 1499 iot_sim_err("Invalid argument count %d", (argc + 1)); 1500 return status; 1501 } 1502 1503 if (!argv[0] || !argv[1] || !argv[2] || !argv[3] || !argv[4]) { 1504 iot_sim_err("One or more arguments are null"); 1505 return status; 1506 } 1507 /* 1508 * User can send drop data in following format: 1509 * 1. Add drop rule for specific peer 1510 * <t_st> <seq> <category_type> <action_type> <drop> <MAC> 1511 * 2. Add drop rule for broadcast peer 1512 * <t_st> <seq> <category_type> <action_type> <drop> 1513 * 3. Remove drop rule for specific peer 1514 * <t_st> <seq> <category_type> <action_type> <drop> <MAC> 1515 * 4. Remove drop rule for broadcast peer 1516 * <t_st> <seq> <category_type> <action_type> <drop> <BCAST_MAC> 1517 * 5. Remove drop rule for all peer 1518 * <t_st> <seq> <category_type> <action_type> <drop> 1519 */ 1520 1521 ret = kstrtou8(argv[0], 16, t_st); 1522 if (ret) 1523 goto err; 1524 ret = kstrtou16(argv[1], 10, seq); 1525 if (ret) 1526 goto err; 1527 ret = kstrtou8(argv[2], 10, cat_type); 1528 if (ret) 1529 goto err; 1530 ret = kstrtou8(argv[3], 10, act_type); 1531 if (ret) 1532 goto err; 1533 ret = kstrtou8(argv[4], 10, drop); 1534 if (ret) 1535 goto err; 1536 1537 /* 1538 * If argv[5] is valid, this must be mac address 1539 */ 1540 if (argv[5]) 1541 status = qdf_mac_parse(argv[5], addr); 1542 1543 iot_sim_err("drop rule mac address " QDF_MAC_ADDR_FMT, 1544 QDF_MAC_ADDR_REF(addr->bytes)); 1545 1546 return status; 1547 err: 1548 iot_sim_err("kstrtoXX failed: %d", ret); 1549 return QDF_STATUS_E_FAILURE; 1550 } 1551 1552 /* 1553 * iot_sim_debug_drop_write - Write Handler for drop operation 1554 * @file: debugfs file pointer 1555 * @buf: buf of user input 1556 * @count: buf count 1557 * @ppos: offset on file 1558 * 1559 * Return: character read 1560 */ 1561 static ssize_t 1562 iot_sim_debug_drop_write(struct file *file, 1563 const char __user *buf, 1564 size_t count, loff_t *ppos) 1565 { 1566 QDF_STATUS status = QDF_STATUS_SUCCESS; 1567 unsigned char t_st, type, subtype; 1568 uint16_t seq = 0; 1569 char *locbuf = NULL; 1570 enum iot_sim_operations oper = DROP; 1571 struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT; 1572 struct iot_sim_context *isc = 1573 ((struct seq_file *)file->private_data)->private; 1574 uint8_t action = 0, category = 0, tmp[2], drop = 0; 1575 bool is_action = false, clear = false; 1576 1577 if ((!buf) || (count > USER_BUF_LEN_DROP) || (count < 6)) 1578 return -EFAULT; 1579 1580 locbuf = qdf_mem_malloc(USER_BUF_LEN_DROP + 1); 1581 if (!locbuf) 1582 return -ENOMEM; 1583 1584 if (copy_from_user(locbuf, buf, count)) { 1585 qdf_mem_free(locbuf); 1586 return -EFAULT; 1587 } 1588 1589 status = iot_sim_parse_user_input_drop(isc, locbuf, count, 1590 &t_st, &seq, &category, 1591 &action, &drop, &mac_addr); 1592 if (QDF_IS_STATUS_ERROR(status)) 1593 goto free; 1594 1595 type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT; 1596 subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK); 1597 subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT; 1598 1599 if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ) 1600 goto free; 1601 1602 if (FRAME_TYPE_IS_ACTION(type, subtype)) { 1603 tmp[0] = category; 1604 tmp[1] = action; 1605 /* 1606 * convert 802.11 category and action code to iot sim codes 1607 */ 1608 status = iot_sim_get_index_for_action_frm(tmp, &category, 1609 &action, false); 1610 if (QDF_IS_STATUS_ERROR(status)) 1611 goto free; 1612 1613 is_action = 1; 1614 type = category; 1615 subtype = action; 1616 } 1617 1618 clear = drop ? false : true; 1619 status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype, 1620 seq, 0, NULL, 0, is_action, clear); 1621 if (QDF_IS_STATUS_SUCCESS(status)) 1622 goto free; 1623 1624 /* check for rule removal */ 1625 if (!drop) { 1626 status = iot_sim_delete_rule_for_mac(isc, oper, seq, 1627 type, subtype, 1628 &mac_addr, 1629 is_action); 1630 } else { 1631 status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr, 1632 type, subtype, seq, 0, 1633 NULL, 0, drop, is_action); 1634 } 1635 if (QDF_IS_STATUS_SUCCESS(status)) 1636 iot_sim_debug("iot_sim: Rule update Drop Operation - Success"); 1637 else 1638 iot_sim_err("iot_sim: Rule update Drop Operation - Fail"); 1639 free: 1640 qdf_mem_free(locbuf); 1641 return count; 1642 } 1643 1644 /* 1645 * debug_iot_sim_##func_base##_show() - debugfs functions to display content 1646 * dummy function 1647 * Return: success 1648 */ 1649 #define GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(func_base) \ 1650 static int iot_sim_debug_##func_base##_show(struct seq_file *m, \ 1651 void *v) \ 1652 { \ 1653 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); \ 1654 } 1655 1656 GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(content_change); 1657 GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(delay); 1658 GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(drop); 1659 1660 /* 1661 * debug_##func_base##_open() - Open debugfs entry for respective command 1662 * and event buffer. 1663 * 1664 * @inode: node for debug dir entry 1665 * @file: file handler 1666 * 1667 * Return: open status 1668 */ 1669 #define GENERATE_DEBUG_IOT_SIM_STRUCTS(func_base) \ 1670 static int debug_##func_base##_open(struct inode *inode, \ 1671 struct file *file) \ 1672 { \ 1673 return single_open(file, iot_sim_debug_##func_base##_show, \ 1674 inode->i_private); \ 1675 } \ 1676 \ 1677 static const struct file_operations debug_##func_base##_ops = { \ 1678 .open = debug_##func_base##_open, \ 1679 .read = seq_read, \ 1680 .llseek = seq_lseek, \ 1681 .write = iot_sim_debug_##func_base##_write, \ 1682 .release = single_release, \ 1683 } 1684 1685 GENERATE_DEBUG_IOT_SIM_STRUCTS(content_change); 1686 GENERATE_DEBUG_IOT_SIM_STRUCTS(drop); 1687 GENERATE_DEBUG_IOT_SIM_STRUCTS(delay); 1688 1689 /* Structure to maintain debug information */ 1690 struct iot_sim_dbgfs_file { 1691 const char *name; 1692 const struct file_operations *ops; 1693 }; 1694 1695 #define DEBUG_IOT_SIM(func_base) { .name = #func_base, \ 1696 .ops = &debug_##func_base##_ops \ 1697 } 1698 1699 struct iot_sim_dbgfs_file iot_sim_dbgfs_files[IOT_SIM_DEBUGFS_FILE_NUM] = { 1700 DEBUG_IOT_SIM(content_change), 1701 DEBUG_IOT_SIM(drop), 1702 DEBUG_IOT_SIM(delay), 1703 }; 1704 1705 /** 1706 * iot_sim_debugfs_deinit() - Deinit functions to remove debugfs directory and 1707 * it's file enteries. 1708 * @isc: iot_sim context 1709 * 1710 * Return: init status 1711 */ 1712 static QDF_STATUS 1713 iot_sim_debugfs_deinit(struct iot_sim_context *isc) 1714 { 1715 qdf_debugfs_remove_dir_recursive(isc->iot_sim_dbgfs_ctx.iot_sim_dir_de); 1716 1717 return QDF_STATUS_SUCCESS; 1718 } 1719 1720 /* 1721 * iot_sim_remove_all_oper_rules - Function to remove all configured rules 1722 * for given operation 1723 * 1724 * @isc: iot sim context 1725 * @oper: iot sim operation 1726 * 1727 * Return: void 1728 */ 1729 static void 1730 iot_sim_remove_all_oper_rules(struct iot_sim_context *isc, 1731 enum iot_sim_operations oper) 1732 { 1733 uint16_t seq; 1734 uint8_t type, subtype, category = 0, action = 0; 1735 struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT; 1736 1737 for (seq = 0; seq < MAX_SEQ; seq++) { 1738 /* Remove rules for non-action type frames */ 1739 for (type = 0; type < N_FRAME_TYPE; type++) 1740 for (subtype = 0; subtype < N_FRAME_SUBTYPE; subtype++) 1741 iot_sim_delete_rule_for_mac(isc, oper, seq, 1742 type, subtype, 1743 &zero_mac_addr, 0); 1744 /* Remove rules for action frames */ 1745 for (category = 0; category < IOT_SIM_MAX_CAT; category++) 1746 for (action = 0; action < MAX_ACTION; action++) 1747 iot_sim_delete_rule_for_mac(isc, oper, seq, 1748 category, action, 1749 &zero_mac_addr, 1); 1750 } 1751 } 1752 1753 /* 1754 * iot_sim_remove_all_rules - Function to remove all configured rules 1755 * 1756 * @isc: iot sim context 1757 * 1758 * Return: void 1759 */ 1760 static void 1761 iot_sim_remove_all_rules(struct iot_sim_context *isc) 1762 { 1763 enum iot_sim_operations oper; 1764 1765 if (!isc) 1766 return; 1767 1768 for (oper = CONTENT_CHANGE; oper < IOT_SIM_MAX_OPERATION; oper++) 1769 iot_sim_remove_all_oper_rules(isc, oper); 1770 } 1771 1772 /** 1773 * iot_sim_debugfs_init() - debugfs functions to create debugfs directory and to 1774 * create debugfs enteries. 1775 * @isc: iot_sim context 1776 * 1777 * Return: init status 1778 */ 1779 static QDF_STATUS 1780 iot_sim_debugfs_init(struct iot_sim_context *isc) 1781 { 1782 struct dentry *dbgfs_dir = NULL; 1783 struct dentry *de = NULL; 1784 uint8_t i, pdev_id; 1785 char buf[32]; 1786 1787 if (!isc) 1788 return QDF_STATUS_E_FAILURE; 1789 1790 pdev_id = wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj); 1791 1792 qdf_mem_zero(buf, sizeof(buf)); 1793 snprintf(buf, sizeof(buf), "iot_sim_pdev%u", pdev_id); 1794 1795 dbgfs_dir = qdf_debugfs_create_dir(buf, NULL); 1796 isc->iot_sim_dbgfs_ctx.iot_sim_dir_de = dbgfs_dir; 1797 1798 if (!isc->iot_sim_dbgfs_ctx.iot_sim_dir_de) { 1799 iot_sim_err("dbgfs dir creation failed for pdev%u", pdev_id); 1800 return QDF_STATUS_E_FAILURE; 1801 } 1802 1803 for (i = 0; i < IOT_SIM_DEBUGFS_FILE_NUM; ++i) { 1804 de = qdf_debugfs_create_entry(iot_sim_dbgfs_files[i].name, 1805 IOT_SIM_DBG_FILE_PERM, 1806 dbgfs_dir, isc, 1807 iot_sim_dbgfs_files[i].ops); 1808 1809 if (!de) { 1810 iot_sim_err("dbgfs file creation failed for pdev%u", 1811 pdev_id); 1812 goto out; 1813 } 1814 isc->iot_sim_dbgfs_ctx.iot_sim_file_de[i] = de; 1815 } 1816 1817 return QDF_STATUS_SUCCESS; 1818 1819 out: 1820 qdf_debugfs_remove_dir_recursive(dbgfs_dir); 1821 qdf_mem_set(isc->iot_sim_dbgfs_ctx.iot_sim_file_de, 1822 sizeof(isc->iot_sim_dbgfs_ctx.iot_sim_file_de), 0); 1823 1824 return QDF_STATUS_E_FAILURE; 1825 } 1826 1827 QDF_STATUS 1828 wlan_iot_sim_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg) 1829 { 1830 struct iot_sim_context *isc = NULL; 1831 1832 if (!pdev) { 1833 iot_sim_err("pdev is NULL"); 1834 return QDF_STATUS_E_NULL_VALUE; 1835 } 1836 1837 isc = qdf_mem_malloc(sizeof(struct iot_sim_context)); 1838 if (!isc) 1839 return QDF_STATUS_E_NOMEM; 1840 1841 isc->pdev_obj = pdev; 1842 1843 if (QDF_IS_STATUS_ERROR(iot_sim_debugfs_init(isc))) { 1844 qdf_mem_free(isc); 1845 iot_sim_info("iot_sim debugfs file creation failed"); 1846 return QDF_STATUS_E_FAILURE; 1847 } 1848 1849 qdf_set_macaddr_broadcast(&isc->bcast_peer.addr); 1850 qdf_spinlock_create(&isc->iot_sim_lock); 1851 qdf_list_create(&isc->peer_list, 2); 1852 isc->bcn_buf = NULL; 1853 1854 wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_IOT_SIM_COMP, 1855 (void *)isc, QDF_STATUS_SUCCESS); 1856 1857 iot_sim_debug("iot_sim component pdev%u object created", 1858 wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj)); 1859 1860 return QDF_STATUS_SUCCESS; 1861 } 1862 1863 QDF_STATUS 1864 wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, 1865 void *arg) 1866 { 1867 struct iot_sim_context *isc = NULL; 1868 1869 if (!pdev) { 1870 iot_sim_err("pdev is NULL"); 1871 return QDF_STATUS_E_NULL_VALUE; 1872 } 1873 1874 isc = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1875 WLAN_IOT_SIM_COMP); 1876 if (isc) { 1877 wlan_objmgr_pdev_component_obj_detach(pdev, 1878 WLAN_IOT_SIM_COMP, 1879 (void *)isc); 1880 /* Deinitilise function pointers from iot_sim context */ 1881 iot_sim_debugfs_deinit(isc); 1882 iot_sim_remove_all_rules(isc); 1883 qdf_list_destroy(&isc->peer_list); 1884 if (isc->bcn_buf) 1885 qdf_nbuf_free(isc->bcn_buf); 1886 qdf_spinlock_destroy(&isc->iot_sim_lock); 1887 qdf_mem_free(isc); 1888 } 1889 iot_sim_debug("iot_sim component pdev%u object destroyed", 1890 wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj)); 1891 1892 return QDF_STATUS_SUCCESS; 1893 } 1894 1895