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