1 /* 2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <osdep.h> 21 #include <wmi.h> 22 #include <wmi_unified_priv.h> 23 #include <wmi_unified_interop_issues_ap_api.h> 24 25 /** 26 * extract_interop_issues_ap_ev_param_tlv() - extract info from event 27 * @wmi_handle: wmi handle 28 * @evt_buf: pointer to event buffer 29 * @data: Pointer to hold interop issues ap info 30 * 31 * Return: QDF_STATUS_SUCCESS for success or error code 32 */ 33 static QDF_STATUS 34 extract_interop_issues_ap_ev_param_tlv(wmi_unified_t wmi_handle, void *evt_buf, 35 struct wlan_interop_issues_ap_event *data) 36 { 37 wmi_pdev_rap_info_event_fixed_param *fixed_param; 38 WMI_PDEV_RAP_INFO_EVENTID_param_tlvs *param_buf = 39 (WMI_PDEV_RAP_INFO_EVENTID_param_tlvs *)evt_buf; 40 41 if (!param_buf) { 42 wmi_err_rl("Invalid param_buf"); 43 return -EINVAL; 44 } 45 46 fixed_param = param_buf->fixed_param; 47 if (!fixed_param) { 48 wmi_err_rl("Invalid fixed_praram"); 49 return -EINVAL; 50 } 51 52 if (fixed_param->type != WMI_ROGUE_AP_ON_STA_PS) { 53 wmi_err_rl("Invalid type"); 54 return -EINVAL; 55 } 56 57 data->pdev_id = fixed_param->pdev_id; 58 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_param->bssid, data->rap_addr.bytes); 59 60 return QDF_STATUS_SUCCESS; 61 } 62 63 /** 64 * send_set_rap_ps_cmd_tlv() - set interop issues ap mac address in fw 65 * @wmi_handle: wmi handle 66 * @rap: interop issues ap info 67 * 68 * Return: QDF_STATUS_SUCCESS for success or error code 69 */ 70 static QDF_STATUS 71 send_set_rap_ps_cmd_tlv(wmi_unified_t wmi_handle, 72 struct wlan_interop_issues_ap_info *rap) 73 { 74 wmi_pdev_set_rap_config_fixed_param *cmd; 75 wmi_pdev_set_rap_config_on_sta_ps_tlv_param *param; 76 uint8_t *buf_ptr; 77 wmi_buf_t buf; 78 uint32_t ret; 79 uint32_t len, count; 80 qdf_size_t i; 81 82 count = rap->count; 83 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*param) * count; 84 buf = wmi_buf_alloc(wmi_handle, len); 85 if (!buf) 86 return QDF_STATUS_E_FAILURE; 87 88 buf_ptr = wmi_buf_data(buf); 89 cmd = (wmi_pdev_set_rap_config_fixed_param *)buf_ptr; 90 91 WMITLV_SET_HDR(&cmd->tlv_header, 92 WMITLV_TAG_STRUC_wmi_pdev_set_rap_config_fixed_param, 93 WMITLV_GET_STRUCT_TLVLEN 94 (wmi_pdev_set_rap_config_fixed_param)); 95 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 96 wmi_handle, 97 WMI_HOST_PDEV_ID_SOC); 98 99 cmd->type = WMI_ROGUE_AP_ON_STA_PS; 100 if (rap->detect_enable) 101 cmd->sta_ps_detection_enabled = 1; 102 else 103 cmd->sta_ps_detection_enabled = 0; 104 105 buf_ptr += sizeof(*cmd); 106 107 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 108 sizeof(wmi_pdev_set_rap_config_on_sta_ps_tlv_param) * count); 109 buf_ptr += WMI_TLV_HDR_SIZE; 110 111 for (i = 0; i < count; i++) { 112 param = (wmi_pdev_set_rap_config_on_sta_ps_tlv_param *)buf_ptr; 113 WMITLV_SET_HDR(¶m->tlv_header, 114 WMITLV_TAG_STRUC_wmi_pdev_set_rap_config_on_sta_ps_tlv_param, 115 WMITLV_GET_STRUCT_TLVLEN 116 (wmi_pdev_set_rap_config_on_sta_ps_tlv_param)); 117 WMI_CHAR_ARRAY_TO_MAC_ADDR(rap->rap_items[i].bytes, 118 ¶m->bssid); 119 buf_ptr += sizeof(*param); 120 } 121 122 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 123 WMI_PDEV_SET_RAP_CONFIG_CMDID); 124 if (ret) { 125 wmi_buf_free(buf); 126 return QDF_STATUS_E_FAILURE; 127 } 128 129 return QDF_STATUS_SUCCESS; 130 } 131 132 void wmi_interop_issues_ap_attach_tlv(wmi_unified_t wmi_handle) 133 { 134 struct wmi_ops *ops = wmi_handle->ops; 135 136 ops->extract_interop_issues_ap_ev_param = 137 extract_interop_issues_ap_ev_param_tlv; 138 ops->send_set_rap_ps_cmd = send_set_rap_ps_cmd_tlv; 139 } 140