xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_fwol_tlv.c (revision 503663c6daafffe652fa360bde17243568cd6d2a)
1 /*
2  * Copyright (c) 2019 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 "wlan_fwol_public_structs.h"
23 #include "wmi_unified_fwol_api.h"
24 
25 #ifdef WLAN_FEATURE_ELNA
26 /**
27  * send_set_elna_bypass_cmd_tlv() - send set elna bypass cmd to fw
28  * @wmi_handle: wmi handle
29  * @req: set eLNA bypass request
30  *
31  * Send WMI_SET_ELNA_BYPASS_CMDID to fw.
32  *
33  * Return: QDF_STATUS
34  */
35 static QDF_STATUS
36 send_set_elna_bypass_cmd_tlv(wmi_unified_t wmi_handle,
37 			     struct set_elna_bypass_request *req)
38 {
39 	wmi_buf_t buf;
40 	wmi_set_elna_bypass_cmd_fixed_param *cmd;
41 	uint16_t len = sizeof(*cmd);
42 	QDF_STATUS ret;
43 
44 	buf = wmi_buf_alloc(wmi_handle, len);
45 	if (!buf) {
46 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
47 		return QDF_STATUS_E_NOMEM;
48 	}
49 
50 	cmd = (wmi_set_elna_bypass_cmd_fixed_param *)wmi_buf_data(buf);
51 	WMITLV_SET_HDR(&cmd->tlv_header,
52 		       WMITLV_TAG_STRUC_wmi_set_elna_bypass_cmd_fixed_param,
53 		       WMITLV_GET_STRUCT_TLVLEN
54 		       (wmi_set_elna_bypass_cmd_fixed_param));
55 	cmd->vdev_id = req->vdev_id;
56 	cmd->en_dis = req->en_dis;
57 	wmi_mtrace(WMI_SET_ELNA_BYPASS_CMDID, req->vdev_id, req->en_dis);
58 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
59 				   WMI_SET_ELNA_BYPASS_CMDID);
60 	if (QDF_IS_STATUS_ERROR(ret)) {
61 		WMI_LOGE("Failed to send set param command ret = %d", ret);
62 		wmi_buf_free(buf);
63 	}
64 
65 	return ret;
66 }
67 
68 /**
69  * send_get_elna_bypass_cmd_tlv() - send get elna bypass cmd to fw
70  * @wmi_handle: wmi handle
71  * @req: get eLNA bypass request
72  *
73  * Send WMI_GET_ELNA_BYPASS_CMDID to fw.
74  *
75  * Return: QDF_STATUS
76  */
77 static QDF_STATUS
78 send_get_elna_bypass_cmd_tlv(wmi_unified_t wmi_handle,
79 			     struct get_elna_bypass_request *req)
80 {
81 	wmi_buf_t buf;
82 	wmi_get_elna_bypass_cmd_fixed_param *cmd;
83 	uint16_t len = sizeof(*cmd);
84 	QDF_STATUS ret;
85 
86 	buf = wmi_buf_alloc(wmi_handle, len);
87 	if (!buf) {
88 		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
89 		return QDF_STATUS_E_NOMEM;
90 	}
91 
92 	cmd = (wmi_get_elna_bypass_cmd_fixed_param *)wmi_buf_data(buf);
93 	WMITLV_SET_HDR(&cmd->tlv_header,
94 		       WMITLV_TAG_STRUC_wmi_get_elna_bypass_cmd_fixed_param,
95 		       WMITLV_GET_STRUCT_TLVLEN
96 		       (wmi_get_elna_bypass_cmd_fixed_param));
97 	cmd->vdev_id = req->vdev_id;
98 	wmi_mtrace(WMI_GET_ELNA_BYPASS_CMDID, req->vdev_id, 0);
99 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
100 				   WMI_GET_ELNA_BYPASS_CMDID);
101 	if (QDF_IS_STATUS_ERROR(ret)) {
102 		WMI_LOGE("Failed to send set param command ret = %d", ret);
103 		wmi_buf_free(buf);
104 	}
105 
106 	return ret;
107 }
108 
109 /**
110  * extract_get_elna_bypass_resp_tlv() - Extract WMI get eLNA bypass response
111  * @wmi_handle: wmi handle
112  * @resp_buf: response buffer
113  * @resp: get eLNA bypass response
114  *
115  * Extract WMI get eLNA bypass response from firmware.
116  *
117  * Return: QDF_STATUS
118  */
119 static QDF_STATUS
120 extract_get_elna_bypass_resp_tlv(struct wmi_unified *wmi_handle, void *resp_buf,
121 				 struct get_elna_bypass_response *resp)
122 {
123 	WMI_GET_ELNA_BYPASS_EVENTID_param_tlvs *param_buf;
124 	wmi_get_elna_bypass_event_fixed_param *evt;
125 
126 	param_buf = resp_buf;
127 	evt = param_buf->fixed_param;
128 	if (!evt) {
129 		WMI_LOGE("Invalid get elna bypass event");
130 		return QDF_STATUS_E_INVAL;
131 	}
132 
133 	WMI_LOGD("Get elna bypass %d from vdev %d", evt->en_dis, evt->vdev_id);
134 
135 	resp->vdev_id = evt->vdev_id;
136 	resp->en_dis = evt->en_dis;
137 
138 	return QDF_STATUS_SUCCESS;
139 }
140 #endif /* WLAN_FEATURE_ELNA */
141 
142 #ifdef WLAN_FEATURE_ELNA
143 static void wmi_fwol_attach_elna_tlv(struct wmi_ops *ops)
144 {
145 	ops->send_set_elna_bypass_cmd = send_set_elna_bypass_cmd_tlv;
146 	ops->send_get_elna_bypass_cmd = send_get_elna_bypass_cmd_tlv;
147 	ops->extract_get_elna_bypass_resp = extract_get_elna_bypass_resp_tlv;
148 }
149 #else
150 static void wmi_fwol_attach_elna_tlv(struct wmi_ops *ops)
151 {
152 }
153 #endif /* WLAN_FEATURE_ELNA */
154 
155 void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle)
156 {
157 	struct wmi_ops *ops = wmi_handle->ops;
158 
159 	wmi_fwol_attach_elna_tlv(ops);
160 }
161