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