xref: /wlan-dirver/qca-wifi-host-cmn/target_if/spatial_reuse/src/target_if_spatial_reuse.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
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 #include <target_if_spatial_reuse.h>
20 #include <wlan_lmac_if_def.h>
21 #include <wmi_unified_api.h>
22 #include <wmi_unified_vdev_api.h>
23 #include <target_if_vdev_mgr_tx_ops.h>
24 #include <init_deinit_lmac.h>
25 #include <wlan_vdev_mlme_api.h>
26 
27 static QDF_STATUS spatial_reuse_send_cfg(struct wlan_objmgr_vdev *vdev,
28 					 uint8_t sr_ctrl,
29 					 uint8_t non_srg_max_pd_offset)
30 {
31 	struct pdev_params pparam;
32 	wmi_unified_t wmi_handle;
33 
34 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
35 	if (!wmi_handle) {
36 		mlme_err("Failed to get WMI handle!");
37 		return QDF_STATUS_E_INVAL;
38 	}
39 
40 	qdf_mem_zero(&pparam, sizeof(pparam));
41 	pparam.param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;
42 	if (!(sr_ctrl & NON_SRG_PD_SR_DISALLOWED) &&
43 	    (sr_ctrl & NON_SRG_OFFSET_PRESENT)) {
44 		QDF_SET_BITS(pparam.param_value, NON_SRG_SPR_ENABLE_POS,
45 			     NON_SRG_SPR_ENABLE_SIZE, NON_SRG_SPR_ENABLE);
46 		QDF_SET_BITS(pparam.param_value, SR_PARAM_VAL_DBM_POS,
47 			     NON_SRG_PARAM_VAL_DBM_SIZE,
48 			     SR_PARAM_VAL_DBM_UNIT);
49 		QDF_SET_BITS(pparam.param_value, NON_SRG_MAX_PD_OFFSET_POS,
50 			     NON_SRG_MAX_PD_OFFSET_SIZE,
51 			     non_srg_max_pd_offset);
52 	}
53 
54 	return wmi_unified_pdev_param_send(wmi_handle, &pparam,
55 					   WILDCARD_PDEV_ID);
56 }
57 
58 static QDF_STATUS
59 spatial_reuse_send_sr_prohibit_cfg(struct wlan_objmgr_vdev *vdev,
60 				   bool he_siga_va15_allowed)
61 {
62 	struct sr_prohibit_param srp_param;
63 	wmi_unified_t wmi_handle;
64 
65 	wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
66 	if (!wmi_handle) {
67 		mlme_err("Failed to get WMI handle!");
68 		return QDF_STATUS_E_INVAL;
69 	}
70 
71 	srp_param.vdev_id = wlan_vdev_get_id(vdev);
72 	srp_param.sr_he_siga_val15_allowed = he_siga_va15_allowed;
73 
74 	return wmi_unified_vdev_param_sr_prohibit_send(wmi_handle, &srp_param);
75 }
76 
77 #ifdef OBSS_PD
78 static QDF_STATUS
79 spatial_reuse_send_bss_color_bit_map(struct wlan_objmgr_vdev *vdev,
80 				     struct wlan_objmgr_pdev *pdev)
81 {
82 	uint64_t srg_color_bit_map = 0;
83 	uint32_t bit_map_0 = 0;
84 	uint32_t bit_map_1 = 0;
85 	struct wmi_unified *wmi_handle;
86 	QDF_STATUS status = QDF_STATUS_SUCCESS;
87 
88 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
89 	if (!wmi_handle)
90 		return QDF_STATUS_E_INVAL;
91 
92 	wlan_vdev_obj_lock(vdev);
93 	wlan_vdev_mlme_get_srg_bss_color_bit_map(vdev, &srg_color_bit_map);
94 	wlan_vdev_obj_unlock(vdev);
95 	bit_map_0 = (uint32_t) srg_color_bit_map;
96 	bit_map_1 = (uint32_t) (srg_color_bit_map >> 32);
97 
98 	status = wmi_unified_send_self_srg_bss_color_bitmap_set_cmd(
99 					wmi_handle, bit_map_0, bit_map_1,
100 					pdev->pdev_objmgr.wlan_pdev_id);
101 	return status;
102 }
103 
104 static QDF_STATUS
105 spatial_reuse_send_partial_bssid_bit_map(struct wlan_objmgr_vdev *vdev,
106 					 struct wlan_objmgr_pdev *pdev)
107 {
108 	uint64_t partial_bssid_bit_map = 0;
109 	uint32_t bit_map_0 = 0;
110 	uint32_t bit_map_1 = 0;
111 	struct wmi_unified *wmi_handle;
112 	QDF_STATUS status = QDF_STATUS_SUCCESS;
113 
114 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
115 	if (!wmi_handle)
116 		return QDF_STATUS_E_INVAL;
117 
118 	wlan_vdev_obj_lock(vdev);
119 	wlan_vdev_mlme_get_srg_partial_bssid_bit_map(vdev,
120 						     &partial_bssid_bit_map);
121 	wlan_vdev_obj_unlock(vdev);
122 	bit_map_0 = (uint32_t) partial_bssid_bit_map;
123 	bit_map_1 = (uint32_t) (partial_bssid_bit_map >> 32);
124 
125 	status = wmi_unified_send_self_srg_partial_bssid_bitmap_set_cmd(
126 					wmi_handle, bit_map_0, bit_map_1,
127 					pdev->pdev_objmgr.wlan_pdev_id);
128 	return status;
129 }
130 #else
131 static QDF_STATUS
132 spatial_reuse_send_bss_color_bit_map(struct wlan_objmgr_vdev *vdev,
133 				     struct wlan_objmgr_pdev *pdev)
134 {
135 	return QDF_STATUS_SUCCESS;
136 }
137 
138 static QDF_STATUS
139 spatial_reuse_send_partial_bssid_bit_map(struct wlan_objmgr_vdev *vdev,
140 					 struct wlan_objmgr_pdev *pdev)
141 {
142 	return QDF_STATUS_SUCCESS;
143 }
144 #endif
145 
146 static QDF_STATUS
147 spatial_reuse_send_pd_threshold(struct wlan_objmgr_pdev *pdev,
148 				uint8_t vdev_id,
149 				uint32_t val)
150 {
151 	struct vdev_set_params vdev_param;
152 	struct wmi_unified *wmi_handle;
153 	bool sr_supported;
154 
155 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
156 	if (!wmi_handle)
157 		return QDF_STATUS_E_INVAL;
158 
159 	sr_supported =
160 		wmi_service_enabled(wmi_handle,
161 				    wmi_service_srg_srp_spatial_reuse_support);
162 
163 	if (sr_supported) {
164 		qdf_mem_zero(&vdev_param, sizeof(vdev_param));
165 		vdev_param.vdev_id = vdev_id;
166 		vdev_param.param_id = WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;
167 		vdev_param.param_value = val;
168 		return wmi_unified_vdev_set_param_send(wmi_handle, &vdev_param);
169 	} else {
170 		mlme_debug("Target doesn't support SR operations");
171 	}
172 	return QDF_STATUS_SUCCESS;
173 }
174 
175 /**
176  * spatial_reuse_set_sr_enable_disable: To send wmi command to enable/disable SR
177  *
178  * @vdev: object manager vdev
179  * @pdev: object manager pdev
180  * @is_sr_enable: sr enable/disable
181  * @pd_threshold: pd threshold
182  *
183  * Return: Success/Failure
184  */
185 static QDF_STATUS
186 spatial_reuse_set_sr_enable_disable(struct wlan_objmgr_vdev *vdev,
187 				    struct wlan_objmgr_pdev *pdev,
188 				    bool is_sr_enable, int32_t pd_threshold)
189 {
190 	uint32_t val = 0;
191 	uint8_t sr_ctrl;
192 	struct wlan_objmgr_psoc *psoc;
193 	QDF_STATUS status = QDF_STATUS_SUCCESS;
194 
195 	psoc = wlan_pdev_get_psoc(pdev);
196 	if (!psoc)
197 		return QDF_STATUS_E_NOENT;
198 
199 	sr_ctrl = wlan_vdev_mlme_get_sr_ctrl(vdev);
200 	if ((!(sr_ctrl & NON_SRG_PD_SR_DISALLOWED) &&
201 	    (sr_ctrl & NON_SRG_OFFSET_PRESENT)) ||
202 	    (sr_ctrl & SRG_INFO_PRESENT)) {
203 		if (is_sr_enable) {
204 			wlan_mlme_update_sr_data(vdev, &val, pd_threshold,
205 						 is_sr_enable);
206 			wlan_vdev_obj_lock(vdev);
207 			wlan_vdev_mlme_set_he_spr_enabled(vdev, true);
208 			wlan_vdev_obj_unlock(vdev);
209 		} else {
210 			wlan_vdev_obj_lock(vdev);
211 			wlan_vdev_mlme_set_he_spr_enabled(vdev, false);
212 			wlan_vdev_obj_unlock(vdev);
213 		}
214 
215 		mlme_debug("srp param val: %u, enable: %d",
216 			   val, is_sr_enable);
217 		if (is_sr_enable) {
218 			status = spatial_reuse_send_bss_color_bit_map(vdev,
219 								      pdev);
220 			if (status != QDF_STATUS_SUCCESS)
221 				return status;
222 			status = spatial_reuse_send_partial_bssid_bit_map(vdev,
223 									  pdev);
224 			if (status != QDF_STATUS_SUCCESS)
225 				return status;
226 		}
227 		status =
228 		spatial_reuse_send_pd_threshold(pdev, vdev->vdev_objmgr.vdev_id,
229 						val);
230 		if (status != QDF_STATUS_SUCCESS)
231 			return status;
232 	} else {
233 		mlme_debug("Spatial reuse not enabled");
234 	}
235 
236 	return status;
237 }
238 
239 void target_if_spatial_reuse_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
240 {
241 	tx_ops->spatial_reuse_tx_ops.send_cfg = spatial_reuse_send_cfg;
242 	tx_ops->spatial_reuse_tx_ops.send_sr_prohibit_cfg =
243 					spatial_reuse_send_sr_prohibit_cfg;
244 	tx_ops->spatial_reuse_tx_ops.target_if_set_sr_enable_disable =
245 					spatial_reuse_set_sr_enable_disable;
246 }
247