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