1 /*
2 * Copyright (c) 2022-2023 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
spatial_reuse_send_cfg(struct wlan_objmgr_vdev * vdev,uint8_t sr_ctrl,uint8_t non_srg_max_pd_offset)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
spatial_reuse_send_sr_prohibit_cfg(struct wlan_objmgr_vdev * vdev,bool he_siga_va15_allowed)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
spatial_reuse_send_bss_color_bit_map(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_pdev * pdev)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
spatial_reuse_send_partial_bssid_bit_map(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_pdev * pdev)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
spatial_reuse_send_bss_color_bit_map(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_pdev * pdev)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
spatial_reuse_send_partial_bssid_bit_map(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_pdev * pdev)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
spatial_reuse_send_pd_threshold(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,uint32_t val)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 * @vdev: object manager vdev
178 * @pdev: object manager pdev
179 * @is_sr_enable: sr enable/disable
180 * @srg_pd_threshold: SRG pd threshold
181 * @non_srg_pd_threshold: NON-SRG pd threshold
182 *
183 * Return: Success/Failure
184 */
185 static QDF_STATUS
spatial_reuse_set_sr_enable_disable(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_pdev * pdev,bool is_sr_enable,int32_t srg_pd_threshold,int32_t non_srg_pd_threshold)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 srg_pd_threshold,
189 int32_t non_srg_pd_threshold)
190 {
191 uint32_t val = 0;
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 if (is_sr_enable) {
200 wlan_mlme_update_sr_data(vdev, &val, srg_pd_threshold,
201 non_srg_pd_threshold,
202 is_sr_enable);
203 wlan_vdev_obj_lock(vdev);
204 wlan_vdev_mlme_set_he_spr_enabled(vdev, true);
205 wlan_vdev_obj_unlock(vdev);
206 } else {
207 wlan_vdev_obj_lock(vdev);
208 wlan_vdev_mlme_set_he_spr_enabled(vdev, false);
209 wlan_vdev_obj_unlock(vdev);
210 }
211
212 mlme_debug("srp param val: %x, enable: %d",
213 val, is_sr_enable);
214 if (is_sr_enable) {
215 status = spatial_reuse_send_bss_color_bit_map(vdev, pdev);
216 if (status != QDF_STATUS_SUCCESS)
217 return status;
218 status = spatial_reuse_send_partial_bssid_bit_map(vdev, pdev);
219 if (status != QDF_STATUS_SUCCESS)
220 return status;
221 }
222 status = spatial_reuse_send_pd_threshold(pdev,
223 vdev->vdev_objmgr.vdev_id,
224 val);
225 if (status != QDF_STATUS_SUCCESS)
226 return status;
227
228 return status;
229 }
230
target_if_spatial_reuse_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)231 void target_if_spatial_reuse_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
232 {
233 tx_ops->spatial_reuse_tx_ops.send_cfg = spatial_reuse_send_cfg;
234 tx_ops->spatial_reuse_tx_ops.send_sr_prohibit_cfg =
235 spatial_reuse_send_sr_prohibit_cfg;
236 tx_ops->spatial_reuse_tx_ops.target_if_set_sr_enable_disable =
237 spatial_reuse_set_sr_enable_disable;
238 tx_ops->spatial_reuse_tx_ops.target_if_sr_update =
239 spatial_reuse_send_pd_threshold;
240 }
241