1 /*
2  * Copyright (c) 2017-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  * DOC: target_if_pmo_lphb.c
21  *
22  * Target interface file for pmo component to
23  * send lphb offload related cmd and process event.
24  */
25 #ifdef FEATURE_WLAN_LPHB
26 
27 #include "target_if.h"
28 #include "target_if_pmo.h"
29 #include "wmi_unified_pmo_api.h"
30 
target_if_pmo_send_lphb_enable(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_enable_req * ts_lphb_enable)31 QDF_STATUS target_if_pmo_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
32 			struct pmo_lphb_enable_req *ts_lphb_enable)
33 {
34 	wmi_hb_set_enable_cmd_fixed_param hb_enable_fp;
35 	wmi_unified_t wmi_handle;
36 
37 	if (!ts_lphb_enable) {
38 		target_if_err("LPHB Enable configuration is NULL");
39 		return QDF_STATUS_E_FAILURE;
40 	}
41 
42 	target_if_info("PMO_HB_SET_ENABLE enable=%d, item=%d, session=%d",
43 		ts_lphb_enable->enable,
44 		ts_lphb_enable->item, ts_lphb_enable->session);
45 
46 	if ((ts_lphb_enable->item != 1) && (ts_lphb_enable->item != 2)) {
47 		target_if_err("LPHB configuration wrong item %d",
48 			ts_lphb_enable->item);
49 		return QDF_STATUS_E_FAILURE;
50 	}
51 
52 	/* fill in values */
53 	hb_enable_fp.vdev_id = ts_lphb_enable->session;
54 	hb_enable_fp.enable = ts_lphb_enable->enable;
55 	hb_enable_fp.item = ts_lphb_enable->item;
56 	hb_enable_fp.session = ts_lphb_enable->session;
57 
58 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
59 	if (!wmi_handle) {
60 		target_if_err("Invalid wmi handle");
61 		return QDF_STATUS_E_INVAL;
62 	}
63 
64 	return wmi_unified_lphb_config_hbenable_cmd(wmi_handle, &hb_enable_fp);
65 }
66 
target_if_pmo_send_lphb_tcp_params(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_tcp_params * ts_lphb_tcp_param)67 QDF_STATUS target_if_pmo_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
68 			struct pmo_lphb_tcp_params *ts_lphb_tcp_param)
69 {
70 	wmi_hb_set_tcp_params_cmd_fixed_param hb_tcp_params_fp = {0};
71 	wmi_unified_t wmi_handle;
72 
73 	if (!ts_lphb_tcp_param) {
74 		target_if_err("TCP params LPHB configuration is NULL");
75 		return QDF_STATUS_E_FAILURE;
76 	}
77 
78 	target_if_info("PMO --> WMI_HB_SET_TCP_PARAMS srv_ip=%08x, "
79 		"dev_ip=%08x, src_port=%d, dst_port=%d, timeout=%d, "
80 		"session=%d, gateway_mac= "QDF_MAC_ADDR_FMT", time_period_sec=%d,"
81 		"tcp_sn=%d", ts_lphb_tcp_param->srv_ip,
82 		ts_lphb_tcp_param->dev_ip, ts_lphb_tcp_param->src_port,
83 		ts_lphb_tcp_param->dst_port, ts_lphb_tcp_param->timeout,
84 		ts_lphb_tcp_param->session,
85 		QDF_MAC_ADDR_REF(ts_lphb_tcp_param->gateway_mac.bytes),
86 		ts_lphb_tcp_param->time_period_sec, ts_lphb_tcp_param->tcp_sn);
87 
88 	/* fill in values */
89 	hb_tcp_params_fp.vdev_id = ts_lphb_tcp_param->session;
90 	hb_tcp_params_fp.srv_ip = ts_lphb_tcp_param->srv_ip;
91 	hb_tcp_params_fp.dev_ip = ts_lphb_tcp_param->dev_ip;
92 	hb_tcp_params_fp.seq = ts_lphb_tcp_param->tcp_sn;
93 	hb_tcp_params_fp.src_port = ts_lphb_tcp_param->src_port;
94 	hb_tcp_params_fp.dst_port = ts_lphb_tcp_param->dst_port;
95 	hb_tcp_params_fp.interval = ts_lphb_tcp_param->time_period_sec;
96 	hb_tcp_params_fp.timeout = ts_lphb_tcp_param->timeout;
97 	hb_tcp_params_fp.session = ts_lphb_tcp_param->session;
98 	WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_tcp_param->gateway_mac.bytes,
99 				   &hb_tcp_params_fp.gateway_mac);
100 
101 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
102 	if (!wmi_handle) {
103 		target_if_err("Invalid wmi handle");
104 		return QDF_STATUS_E_INVAL;
105 	}
106 
107 	return wmi_unified_lphb_config_tcp_params_cmd(wmi_handle,
108 						      &hb_tcp_params_fp);
109 }
110 
target_if_pmo_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_tcp_filter_req * ts_lphb_tcp_filter)111 QDF_STATUS target_if_pmo_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
112 			struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter)
113 {
114 	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param hb_tcp_filter_fp = {0};
115 	wmi_unified_t wmi_handle;
116 
117 	if (!ts_lphb_tcp_filter) {
118 		target_if_err("TCP PKT FILTER LPHB configuration is NULL");
119 		return QDF_STATUS_E_FAILURE;
120 	}
121 
122 	target_if_info("SET_TCP_PKT_FILTER length=%d, offset=%d, session=%d, "
123 		"filter=%2x:%2x:%2x:%2x:%2x:%2x ...",
124 		ts_lphb_tcp_filter->length, ts_lphb_tcp_filter->offset,
125 		ts_lphb_tcp_filter->session, ts_lphb_tcp_filter->filter[0],
126 		ts_lphb_tcp_filter->filter[1], ts_lphb_tcp_filter->filter[2],
127 		ts_lphb_tcp_filter->filter[3], ts_lphb_tcp_filter->filter[4],
128 		ts_lphb_tcp_filter->filter[5]);
129 
130 	/* fill in values */
131 	hb_tcp_filter_fp.vdev_id = ts_lphb_tcp_filter->session;
132 	hb_tcp_filter_fp.length = ts_lphb_tcp_filter->length;
133 	hb_tcp_filter_fp.offset = ts_lphb_tcp_filter->offset;
134 	hb_tcp_filter_fp.session = ts_lphb_tcp_filter->session;
135 	memcpy((void *)&hb_tcp_filter_fp.filter,
136 	       (void *)&ts_lphb_tcp_filter->filter,
137 	       WMI_WLAN_HB_MAX_FILTER_SIZE);
138 
139 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
140 	if (!wmi_handle) {
141 		target_if_err("Invalid wmi handle");
142 		return QDF_STATUS_E_INVAL;
143 	}
144 
145 	return wmi_unified_lphb_config_tcp_pkt_filter_cmd(wmi_handle,
146 							  &hb_tcp_filter_fp);
147 }
148 
target_if_pmo_send_lphb_udp_params(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_udp_params * ts_lphb_udp_param)149 QDF_STATUS target_if_pmo_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
150 			struct pmo_lphb_udp_params *ts_lphb_udp_param)
151 {
152 	wmi_hb_set_udp_params_cmd_fixed_param hb_udp_params_fp = {0};
153 	wmi_unified_t wmi_handle;
154 
155 	if (!ts_lphb_udp_param) {
156 		target_if_err("UDP param for LPHB configuration is NULL");
157 		return QDF_STATUS_E_FAILURE;
158 	}
159 
160 	target_if_info("HB_SET_UDP_PARAMS srv_ip=%d, dev_ip=%d, src_port=%d, "
161 		"dst_port=%d, interval=%d, timeout=%d, session=%d, "
162 		"gateway_mac= "QDF_MAC_ADDR_FMT,
163 		ts_lphb_udp_param->srv_ip, ts_lphb_udp_param->dev_ip,
164 		ts_lphb_udp_param->src_port, ts_lphb_udp_param->dst_port,
165 		ts_lphb_udp_param->interval, ts_lphb_udp_param->timeout,
166 		ts_lphb_udp_param->session,
167 		QDF_MAC_ADDR_REF(ts_lphb_udp_param->gateway_mac.bytes));
168 
169 	/* fill in values */
170 	hb_udp_params_fp.vdev_id = ts_lphb_udp_param->session;
171 	hb_udp_params_fp.srv_ip = ts_lphb_udp_param->srv_ip;
172 	hb_udp_params_fp.dev_ip = ts_lphb_udp_param->dev_ip;
173 	hb_udp_params_fp.src_port = ts_lphb_udp_param->src_port;
174 	hb_udp_params_fp.dst_port = ts_lphb_udp_param->dst_port;
175 	hb_udp_params_fp.interval = ts_lphb_udp_param->interval;
176 	hb_udp_params_fp.timeout = ts_lphb_udp_param->timeout;
177 	hb_udp_params_fp.session = ts_lphb_udp_param->session;
178 	WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_udp_param->gateway_mac.bytes,
179 				   &hb_udp_params_fp.gateway_mac);
180 
181 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
182 	if (!wmi_handle) {
183 		target_if_err("Invalid wmi handle");
184 		return QDF_STATUS_E_INVAL;
185 	}
186 
187 	return wmi_unified_lphb_config_udp_params_cmd(wmi_handle,
188 						      &hb_udp_params_fp);
189 }
190 
191 /**
192  * target_if_pmo_send_lphb_udp_pkt_filter() - Send LPHB udp pkt filter req
193  * @psoc: objmgr psoc handle
194  * @ts_lphb_udp_filter: lphb udp filter request which needs to configure in fwr
195  *
196  * Return: QDF status
197  */
target_if_pmo_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_udp_filter_req * ts_lphb_udp_filter)198 QDF_STATUS target_if_pmo_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
199 			struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter)
200 {
201 	wmi_hb_set_udp_pkt_filter_cmd_fixed_param hb_udp_filter_fp = {0};
202 	wmi_unified_t wmi_handle;
203 
204 	if (!ts_lphb_udp_filter) {
205 		target_if_err("LPHB UDP packet filter configuration is NULL");
206 		return QDF_STATUS_E_FAILURE;
207 	}
208 
209 	target_if_info("SET_UDP_PKT_FILTER length=%d, offset=%d, session=%d, "
210 		"filter=%2x:%2x:%2x:%2x:%2x:%2x ...",
211 		ts_lphb_udp_filter->length, ts_lphb_udp_filter->offset,
212 		ts_lphb_udp_filter->session, ts_lphb_udp_filter->filter[0],
213 		ts_lphb_udp_filter->filter[1], ts_lphb_udp_filter->filter[2],
214 		ts_lphb_udp_filter->filter[3], ts_lphb_udp_filter->filter[4],
215 		ts_lphb_udp_filter->filter[5]);
216 
217 	/* fill in values */
218 	hb_udp_filter_fp.vdev_id = ts_lphb_udp_filter->session;
219 	hb_udp_filter_fp.length = ts_lphb_udp_filter->length;
220 	hb_udp_filter_fp.offset = ts_lphb_udp_filter->offset;
221 	hb_udp_filter_fp.session = ts_lphb_udp_filter->session;
222 	qdf_mem_copy(&hb_udp_filter_fp.filter, &ts_lphb_udp_filter->filter,
223 		     WMI_WLAN_HB_MAX_FILTER_SIZE);
224 
225 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
226 	if (!wmi_handle) {
227 		target_if_err("Invalid wmi handle");
228 		return QDF_STATUS_E_INVAL;
229 	}
230 
231 	return wmi_unified_lphb_config_udp_pkt_filter_cmd(wmi_handle,
232 							  &hb_udp_filter_fp);
233 }
234 
target_if_pmo_lphb_evt_handler(struct wlan_objmgr_psoc * psoc,uint8_t * event)235 QDF_STATUS target_if_pmo_lphb_evt_handler(struct wlan_objmgr_psoc *psoc,
236 		uint8_t *event)
237 {
238 	wmi_hb_ind_event_fixed_param *hb_fp;
239 	struct pmo_lphb_rsp *slphb_indication = NULL;
240 	QDF_STATUS qdf_status;
241 
242 	TARGET_IF_ENTER();
243 	if (!psoc) {
244 		target_if_err("psoc ptr is NULL");
245 		qdf_status = QDF_STATUS_E_NULL_VALUE;
246 		goto out;
247 	}
248 
249 	hb_fp = (wmi_hb_ind_event_fixed_param *) event;
250 	if (!hb_fp) {
251 		target_if_err("Invalid wmi_hb_ind_event_fixed_param buffer");
252 		qdf_status = QDF_STATUS_E_INVAL;
253 		goto out;
254 	}
255 
256 	target_if_debug("lphb indication received with\n"
257 		  "vdev_id=%d, session=%d, reason=%d",
258 		hb_fp->vdev_id, hb_fp->session, hb_fp->reason);
259 
260 	slphb_indication = (struct pmo_lphb_rsp *)qdf_mem_malloc(
261 				sizeof(struct pmo_lphb_rsp));
262 	if (!slphb_indication) {
263 		qdf_status = QDF_STATUS_E_NOMEM;
264 		goto out;
265 	}
266 
267 	slphb_indication->session_idx = hb_fp->session;
268 	slphb_indication->protocol_type = hb_fp->reason;
269 	slphb_indication->event_reason = hb_fp->reason;
270 
271 	qdf_status = pmo_tgt_lphb_rsp_evt(psoc, slphb_indication);
272 	if (qdf_status != QDF_STATUS_SUCCESS)
273 		target_if_err("Failed to lphb_rsp_event");
274 out:
275 	if (slphb_indication)
276 		qdf_mem_free(slphb_indication);
277 
278 	return qdf_status;
279 }
280 #endif
281 
282