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