xref: /wlan-dirver/qca-wifi-host-cmn/target_if/dp/src/target_if_dp.c (revision ccf6794c7efeda37a9772e5eb4d4dab2ab5af07a)
1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021 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 /**
21  * DOC: defines DP interaction with FW using WMI
22  */
23 
24 #include <qdf_status.h>
25 #include "target_if_dp.h"
26 #include <init_deinit_lmac.h>
27 
28 void
29 target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc *psoc,
30 				   uint8_t pdev_id, uint8_t *peer_macaddr,
31 				   uint8_t vdev_id,
32 				   bool hash_based, uint8_t ring_num,
33 				   uint8_t lmac_peer_id_msb)
34 {
35 	uint32_t value;
36 	struct peer_set_params param;
37 	struct wmi_unified *pdev_wmi_handle;
38 	struct wlan_objmgr_pdev *pdev =
39 		wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
40 					   pdev_id, WLAN_PDEV_TARGET_IF_ID);
41 
42 	if (!pdev) {
43 		target_if_err("pdev with id %d is NULL", pdev_id);
44 		return;
45 	}
46 
47 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
48 	if (!pdev_wmi_handle) {
49 		wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
50 		target_if_err("pdev wmi handle NULL");
51 		return;
52 	}
53 
54 	qdf_mem_zero(&param, sizeof(param));
55 
56 	/* TODO: Need bit definitions for ring number and hash based routing
57 	 * fields in common wmi header file
58 	 */
59 	value = ((hash_based) ? 1 : 0) | (ring_num << 1);
60 
61 	if (lmac_peer_id_msb)
62 		QDF_SET_BITS(value, PEER_ROUTING_LMAC_ID_INDEX,
63 			     PEER_ROUTING_LMAC_ID_BITS, lmac_peer_id_msb);
64 
65 	param.param_id = WMI_HOST_PEER_SET_DEFAULT_ROUTING;
66 	param.vdev_id = vdev_id;
67 	param.param_value = value;
68 
69 	if (wmi_set_peer_param_send(pdev_wmi_handle, peer_macaddr, &param)) {
70 		target_if_err("Unable to set default routing for peer "
71 				QDF_MAC_ADDR_FMT,
72 				QDF_MAC_ADDR_REF(peer_macaddr));
73 	}
74 	wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
75 }
76 
77 #ifdef SERIALIZE_QUEUE_SETUP
78 static QDF_STATUS
79 target_if_rx_reorder_queue_setup(struct scheduler_msg *msg)
80 {
81 	struct rx_reorder_queue_setup_params param;
82 	struct wmi_unified *pdev_wmi_handle;
83 	struct reorder_q_setup *q_params;
84 	QDF_STATUS status;
85 	struct wlan_objmgr_pdev *pdev;
86 	struct wlan_objmgr_psoc *psoc;
87 
88 	if (!(msg->bodyptr)) {
89 		target_if_err("rx_reorder: Invalid message body");
90 		return QDF_STATUS_E_INVAL;
91 	}
92 
93 	q_params = msg->bodyptr;
94 	psoc = (struct wlan_objmgr_psoc *)q_params->psoc;
95 
96 	pdev = wlan_objmgr_get_pdev_by_id(psoc, q_params->pdev_id,
97 					  WLAN_PDEV_TARGET_IF_ID);
98 
99 	if (!pdev) {
100 		target_if_err("pdev with id %d is NULL", q_params->pdev_id);
101 		return QDF_STATUS_E_INVAL;
102 	}
103 
104 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
105 	if (!pdev_wmi_handle) {
106 		target_if_err("pdev wmi handle NULL");
107 		status = QDF_STATUS_E_FAILURE;
108 		goto out;
109 	}
110 
111 	param.tid = q_params->tid;
112 	param.vdev_id = q_params->vdev_id;
113 	param.peer_macaddr = q_params->peer_mac;
114 	param.hw_qdesc_paddr_lo = q_params->hw_qdesc_paddr & 0xffffffff;
115 	param.hw_qdesc_paddr_hi = (uint64_t)q_params->hw_qdesc_paddr >> 32;
116 	param.queue_no = q_params->queue_no;
117 	param.ba_window_size_valid = q_params->ba_window_size_valid;
118 	param.ba_window_size = q_params->ba_window_size;
119 
120 	status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle,
121 							      &param);
122 out:
123 	wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
124 	qdf_mem_free(q_params);
125 
126 	return status;
127 }
128 
129 QDF_STATUS
130 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
131 				      uint8_t pdev_id,
132 				      uint8_t vdev_id, uint8_t *peer_macaddr,
133 				      qdf_dma_addr_t hw_qdesc, int tid,
134 				      uint16_t queue_no,
135 				      uint8_t ba_window_size_valid,
136 				      uint16_t ba_window_size)
137 {
138 	struct scheduler_msg msg = {0};
139 	struct reorder_q_setup *q_params;
140 	QDF_STATUS status;
141 
142 	q_params = qdf_mem_malloc(sizeof(*q_params));
143 	if (!q_params)
144 		return QDF_STATUS_E_NOMEM;
145 
146 	q_params->psoc = psoc;
147 	q_params->vdev_id = vdev_id;
148 	q_params->pdev_id = pdev_id;
149 	q_params->hw_qdesc_paddr = hw_qdesc;
150 	q_params->tid = tid;
151 	q_params->queue_no = queue_no;
152 	q_params->ba_window_size_valid = ba_window_size_valid;
153 	q_params->ba_window_size = ba_window_size;
154 	qdf_mem_copy(q_params->peer_mac, peer_macaddr, QDF_MAC_ADDR_SIZE);
155 
156 	msg.bodyptr = q_params;
157 	msg.callback = target_if_rx_reorder_queue_setup;
158 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
159 					QDF_MODULE_ID_TARGET_IF,
160 					QDF_MODULE_ID_TARGET_IF, &msg);
161 
162 	if (status != QDF_STATUS_SUCCESS)
163 		qdf_mem_free(q_params);
164 
165 	return status;
166 }
167 
168 #else
169 
170 QDF_STATUS
171 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
172 				      uint8_t pdev_id,
173 				      uint8_t vdev_id, uint8_t *peer_macaddr,
174 				      qdf_dma_addr_t hw_qdesc, int tid,
175 				      uint16_t queue_no,
176 				      uint8_t ba_window_size_valid,
177 				      uint16_t ba_window_size)
178 {
179 	struct rx_reorder_queue_setup_params param;
180 	struct wmi_unified *pdev_wmi_handle;
181 	QDF_STATUS status;
182 	struct wlan_objmgr_pdev *pdev =
183 		wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
184 					   pdev_id, WLAN_PDEV_TARGET_IF_ID);
185 
186 	if (!pdev) {
187 		target_if_err("pdev with id %d is NULL", pdev_id);
188 		return QDF_STATUS_E_INVAL;
189 	}
190 
191 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
192 	if (!pdev_wmi_handle) {
193 		wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
194 		target_if_err("pdev wmi handle NULL");
195 		return QDF_STATUS_E_FAILURE;
196 	}
197 	param.tid = tid;
198 	param.vdev_id = vdev_id;
199 	param.peer_macaddr = peer_macaddr;
200 	param.hw_qdesc_paddr_lo = hw_qdesc & 0xffffffff;
201 	param.hw_qdesc_paddr_hi = (uint64_t)hw_qdesc >> 32;
202 	param.queue_no = queue_no;
203 	param.ba_window_size_valid = ba_window_size_valid;
204 	param.ba_window_size = ba_window_size;
205 
206 	status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle,
207 							      &param);
208 	wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
209 
210 	return status;
211 }
212 #endif
213 
214 QDF_STATUS
215 target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_psoc *psoc,
216 				       uint8_t pdev_id,
217 				       uint8_t vdev_id, uint8_t *peer_macaddr,
218 				       uint32_t peer_tid_bitmap)
219 {
220 	struct rx_reorder_queue_remove_params param;
221 	struct wmi_unified *pdev_wmi_handle;
222 	QDF_STATUS status;
223 	struct wlan_objmgr_pdev *pdev =
224 		wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
225 					   pdev_id, WLAN_PDEV_TARGET_IF_ID);
226 
227 	if (!pdev) {
228 		target_if_err("pdev with id %d is NULL", pdev_id);
229 		return QDF_STATUS_E_INVAL;
230 	}
231 
232 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
233 	if (!pdev_wmi_handle) {
234 		wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
235 		target_if_err("pdev wmi handle NULL");
236 		return QDF_STATUS_E_FAILURE;
237 	}
238 	param.vdev_id = vdev_id;
239 	param.peer_macaddr = peer_macaddr;
240 	param.peer_tid_bitmap = peer_tid_bitmap;
241 	status = wmi_unified_peer_rx_reorder_queue_remove_send(pdev_wmi_handle,
242 							       &param);
243 	wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
244 
245 	return status;
246 }
247 
248 QDF_STATUS
249 target_if_lro_hash_config(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id,
250 			  struct cdp_lro_hash_config *lro_hash_cfg)
251 {
252 	struct wmi_lro_config_cmd_t wmi_lro_cmd = {0};
253 	struct wmi_unified *pdev_wmi_handle;
254 	QDF_STATUS status;
255 	struct wlan_objmgr_pdev *pdev =
256 		wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
257 					   pdev_id, WLAN_PDEV_TARGET_IF_ID);
258 
259 	if (!pdev) {
260 		target_if_err("pdev with id %d is NULL", pdev_id);
261 		return QDF_STATUS_E_INVAL;
262 	}
263 
264 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
265 	if (!lro_hash_cfg || !pdev_wmi_handle) {
266 		wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
267 		target_if_err("wmi_handle: 0x%pK, lro_hash_cfg: 0x%pK",
268 			      pdev_wmi_handle, lro_hash_cfg);
269 		return QDF_STATUS_E_FAILURE;
270 	}
271 
272 	wmi_lro_cmd.lro_enable = lro_hash_cfg->lro_enable;
273 	wmi_lro_cmd.tcp_flag = lro_hash_cfg->tcp_flag;
274 	wmi_lro_cmd.tcp_flag_mask = lro_hash_cfg->tcp_flag_mask;
275 	wmi_lro_cmd.pdev_id = pdev_id;
276 
277 	qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv4,
278 		     lro_hash_cfg->toeplitz_hash_ipv4,
279 		     LRO_IPV4_SEED_ARR_SZ * sizeof(uint32_t));
280 
281 	qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv6,
282 		     lro_hash_cfg->toeplitz_hash_ipv6,
283 		     LRO_IPV6_SEED_ARR_SZ * sizeof(uint32_t));
284 
285 	status = wmi_unified_lro_config_cmd(pdev_wmi_handle,
286 					    &wmi_lro_cmd);
287 	wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
288 
289 	return status;
290 }
291