xref: /wlan-dirver/qca-wifi-host-cmn/target_if/dp/src/target_if_dp.c (revision 11f5a63a6cbdda84849a730de22f0a71e635d58c)
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 /**
20  * DOC: defines DP interaction with FW using WMI
21  */
22 
23 #include <qdf_status.h>
24 #include "target_if_dp.h"
25 #include <init_deinit_lmac.h>
26 
27 void
28 target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_pdev *pdev,
29 				   uint8_t *peer_macaddr, uint8_t vdev_id,
30 				   bool hash_based, uint8_t ring_num)
31 {
32 	uint32_t value;
33 	struct peer_set_params param;
34 	struct wmi_unified *pdev_wmi_handle;
35 
36 	pdev_wmi_handle =
37 		lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev);
38 	if (!pdev_wmi_handle) {
39 		target_if_err("pdev wmi handle NULL");
40 		return;
41 	}
42 
43 	qdf_mem_zero(&param, sizeof(param));
44 
45 	/* TODO: Need bit definitions for ring number and hash based routing
46 	 * fields in common wmi header file
47 	 */
48 	value = ((hash_based) ? 1 : 0) | (ring_num << 1);
49 
50 	param.param_id = WMI_HOST_PEER_SET_DEFAULT_ROUTING;
51 	param.vdev_id = vdev_id;
52 	param.param_value = value;
53 
54 	if (wmi_set_peer_param_send(pdev_wmi_handle, peer_macaddr, &param)) {
55 		target_if_err("Unable to set default routing for peer "
56 				QDF_MAC_ADDR_STR,
57 				QDF_MAC_ADDR_ARRAY(peer_macaddr));
58 	}
59 }
60 
61 #ifdef SERIALIZE_QUEUE_SETUP
62 static QDF_STATUS
63 target_if_rx_reorder_queue_setup(struct scheduler_msg *msg)
64 {
65 	struct rx_reorder_queue_setup_params param;
66 	struct wmi_unified *pdev_wmi_handle;
67 	struct reorder_q_setup *q_params;
68 	struct cdp_ctrl_objmgr_pdev *pdev;
69 	QDF_STATUS status;
70 
71 	if (!(msg->bodyptr)) {
72 		target_if_err("rx_reorder: Invalid message body");
73 		return QDF_STATUS_E_INVAL;
74 	}
75 
76 	q_params = msg->bodyptr;
77 	pdev = q_params->pdev;
78 	pdev_wmi_handle =
79 		lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev);
80 	if (!pdev_wmi_handle) {
81 		target_if_err("pdev wmi handle NULL");
82 		status = QDF_STATUS_E_FAILURE;
83 		goto out;
84 	}
85 
86 	param.tid = q_params->tid;
87 	param.vdev_id = q_params->vdev_id;
88 	param.peer_macaddr = q_params->peer_mac;
89 	param.hw_qdesc_paddr_lo = q_params->hw_qdesc_paddr & 0xffffffff;
90 	param.hw_qdesc_paddr_hi = (uint64_t)q_params->hw_qdesc_paddr >> 32;
91 	param.queue_no = q_params->queue_no;
92 	param.ba_window_size_valid = q_params->ba_window_size_valid;
93 	param.ba_window_size = q_params->ba_window_size;
94 
95 	status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle,
96 							      &param);
97 out:
98 	qdf_mem_free(q_params);
99 
100 	return status;
101 }
102 
103 QDF_STATUS
104 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev,
105 				      uint8_t vdev_id, uint8_t *peer_macaddr,
106 				      qdf_dma_addr_t hw_qdesc, int tid,
107 				      uint16_t queue_no,
108 				      uint8_t ba_window_size_valid,
109 				      uint16_t ba_window_size)
110 {
111 	struct scheduler_msg msg = {0};
112 	struct reorder_q_setup *q_params;
113 	QDF_STATUS status;
114 
115 	q_params = qdf_mem_malloc(sizeof(*q_params));
116 	if (!q_params)
117 		return QDF_STATUS_E_NOMEM;
118 
119 	q_params->pdev = pdev;
120 	q_params->vdev_id = vdev_id;
121 	q_params->hw_qdesc_paddr = hw_qdesc;
122 	q_params->tid = tid;
123 	q_params->queue_no = queue_no;
124 	q_params->ba_window_size_valid = ba_window_size_valid;
125 	q_params->ba_window_size = ba_window_size;
126 	qdf_mem_copy(q_params->peer_mac, peer_macaddr, QDF_MAC_ADDR_SIZE);
127 
128 	msg.bodyptr = q_params;
129 	msg.callback = target_if_rx_reorder_queue_setup;
130 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
131 					QDF_MODULE_ID_TARGET_IF,
132 					QDF_MODULE_ID_TARGET_IF, &msg);
133 
134 	if (status != QDF_STATUS_SUCCESS)
135 		qdf_mem_free(q_params);
136 
137 	return status;
138 }
139 
140 #else
141 
142 QDF_STATUS
143 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev,
144 				      uint8_t vdev_id, uint8_t *peer_macaddr,
145 				      qdf_dma_addr_t hw_qdesc, int tid,
146 				      uint16_t queue_no,
147 				      uint8_t ba_window_size_valid,
148 				      uint16_t ba_window_size)
149 {
150 	struct rx_reorder_queue_setup_params param;
151 	struct wmi_unified *pdev_wmi_handle;
152 
153 	pdev_wmi_handle =
154 		lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev);
155 	if (!pdev_wmi_handle) {
156 		target_if_err("pdev wmi handle NULL");
157 		return QDF_STATUS_E_FAILURE;
158 	}
159 	param.tid = tid;
160 	param.vdev_id = vdev_id;
161 	param.peer_macaddr = peer_macaddr;
162 	param.hw_qdesc_paddr_lo = hw_qdesc & 0xffffffff;
163 	param.hw_qdesc_paddr_hi = (uint64_t)hw_qdesc >> 32;
164 	param.queue_no = queue_no;
165 	param.ba_window_size_valid = ba_window_size_valid;
166 	param.ba_window_size = ba_window_size;
167 
168 	return wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle,
169 							    &param);
170 }
171 #endif
172 
173 QDF_STATUS
174 target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_pdev *pdev,
175 				       uint8_t vdev_id, uint8_t *peer_macaddr,
176 				       uint32_t peer_tid_bitmap)
177 {
178 	struct rx_reorder_queue_remove_params param;
179 	struct wmi_unified *pdev_wmi_handle;
180 
181 	pdev_wmi_handle =
182 		lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev);
183 	if (!pdev_wmi_handle) {
184 		target_if_err("pdev wmi handle NULL");
185 		return QDF_STATUS_E_FAILURE;
186 	}
187 	param.vdev_id = vdev_id;
188 	param.peer_macaddr = peer_macaddr;
189 	param.peer_tid_bitmap = peer_tid_bitmap;
190 	return wmi_unified_peer_rx_reorder_queue_remove_send(pdev_wmi_handle,
191 							     &param);
192 }
193 
194 QDF_STATUS
195 target_if_lro_hash_config(struct cdp_ctrl_objmgr_pdev *pdev,
196 			  struct cdp_lro_hash_config *lro_hash_cfg)
197 {
198 	struct wmi_lro_config_cmd_t wmi_lro_cmd = {0};
199 	struct wmi_unified *pdev_wmi_handle;
200 
201 	pdev_wmi_handle =
202 		lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev);
203 	if (!lro_hash_cfg || !pdev_wmi_handle) {
204 		target_if_err("wmi_handle: 0x%pK, lro_hash_cfg: 0x%pK",
205 			      pdev_wmi_handle, lro_hash_cfg);
206 		return QDF_STATUS_E_FAILURE;
207 	}
208 
209 	wmi_lro_cmd.lro_enable = lro_hash_cfg->lro_enable;
210 	wmi_lro_cmd.tcp_flag = lro_hash_cfg->tcp_flag;
211 	wmi_lro_cmd.tcp_flag_mask = lro_hash_cfg->tcp_flag_mask;
212 	wmi_lro_cmd.pdev_id =
213 		lmac_get_pdev_idx((struct wlan_objmgr_pdev *)pdev);
214 
215 	qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv4,
216 		     lro_hash_cfg->toeplitz_hash_ipv4,
217 		     LRO_IPV4_SEED_ARR_SZ * sizeof(uint32_t));
218 
219 	qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv6,
220 		     lro_hash_cfg->toeplitz_hash_ipv6,
221 		     LRO_IPV6_SEED_ARR_SZ * sizeof(uint32_t));
222 
223 	return wmi_unified_lro_config_cmd(pdev_wmi_handle,
224 					  &wmi_lro_cmd);
225 }
226