1 /*
2 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /*
19 * DOC: contains interface manager public api
20 */
21 #include "wlan_objmgr_psoc_obj.h"
22 #include "wlan_objmgr_vdev_obj.h"
23 #include "wlan_if_mgr_public_struct.h"
24 #include "wlan_if_mgr_ap.h"
25 #include "wlan_if_mgr_roam.h"
26 #include "wlan_policy_mgr_api.h"
27 #include "wlan_if_mgr_main.h"
28 #include "wlan_p2p_cfg_api.h"
29 #include "wlan_tdls_api.h"
30 #include "wlan_p2p_api.h"
31 #include "wlan_mlme_vdev_mgr_interface.h"
32 #include "wlan_p2p_ucfg_api.h"
33 #include "wlan_vdev_mgr_utils_api.h"
34 #include "wlan_tdls_tgt_api.h"
35 #include "wlan_policy_mgr_ll_sap.h"
36
if_mgr_ap_start_bss(struct wlan_objmgr_vdev * vdev,struct if_mgr_event_data * event_data)37 QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev,
38 struct if_mgr_event_data *event_data)
39 {
40 struct wlan_objmgr_psoc *psoc;
41 struct wlan_objmgr_pdev *pdev;
42 QDF_STATUS status;
43
44 pdev = wlan_vdev_get_pdev(vdev);
45 if (!pdev)
46 return QDF_STATUS_E_FAILURE;
47
48 psoc = wlan_pdev_get_psoc(pdev);
49 if (!psoc)
50 return QDF_STATUS_E_FAILURE;
51
52 wlan_tdls_notify_start_bss(psoc, vdev);
53
54 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE ||
55 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
56 wlan_handle_emlsr_sta_concurrency(psoc, true, false);
57
58 if (policy_mgr_is_hw_mode_change_in_progress(psoc)) {
59 if (!QDF_IS_STATUS_SUCCESS(
60 policy_mgr_wait_for_connection_update(psoc))) {
61 ifmgr_err("qdf wait for event failed!!");
62 return QDF_STATUS_E_FAILURE;
63 }
64 }
65 if (policy_mgr_is_chan_switch_in_progress(psoc)) {
66 status = policy_mgr_wait_chan_switch_complete_evt(psoc);
67 if (!QDF_IS_STATUS_SUCCESS(status)) {
68 ifmgr_err("qdf wait for csa event failed!!");
69 return QDF_STATUS_E_FAILURE;
70 }
71 }
72
73 if (policy_mgr_is_sta_active_connection_exists(psoc))
74 /* Disable Roaming on all vdev's before starting bss */
75 if_mgr_disable_roaming(pdev, vdev, RSO_START_BSS);
76
77 /* abort p2p roc before starting the BSS for sync event */
78 ucfg_p2p_cleanup_roc_by_psoc(psoc);
79
80 return QDF_STATUS_SUCCESS;
81 }
82
83 QDF_STATUS
if_mgr_ap_start_bss_complete(struct wlan_objmgr_vdev * vdev,struct if_mgr_event_data * event_data)84 if_mgr_ap_start_bss_complete(struct wlan_objmgr_vdev *vdev,
85 struct if_mgr_event_data *event_data)
86 {
87 struct wlan_objmgr_psoc *psoc;
88 struct wlan_objmgr_pdev *pdev;
89
90 pdev = wlan_vdev_get_pdev(vdev);
91 if (!pdev)
92 return QDF_STATUS_E_FAILURE;
93
94 psoc = wlan_pdev_get_psoc(pdev);
95 if (!psoc)
96 return QDF_STATUS_E_FAILURE;
97
98 /*
99 * Due to audio share glitch with P2P GO caused by
100 * roam scan on concurrent interface, disable
101 * roaming if "p2p_disable_roam" ini is enabled.
102 * Donot re-enable roaming again on other STA interface
103 * if p2p GO is active on any vdev.
104 */
105 if (cfg_p2p_is_roam_config_disabled(psoc) &&
106 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) {
107 ifmgr_debug("p2p go mode, keep roam disabled");
108 } else {
109 /* Enable Roaming after start bss in case of failure/success */
110 if_mgr_enable_roaming(pdev, vdev, RSO_START_BSS);
111 }
112 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
113 policy_mgr_check_sap_go_force_scc(psoc, vdev,
114 CSA_REASON_GO_BSS_STARTED);
115 ifmgr_debug("check for SAP restart");
116
117 if (policy_mgr_is_vdev_ll_lt_sap(psoc, wlan_vdev_get_id(vdev)))
118 policy_mgr_ll_lt_sap_restart_concurrent_sap(psoc, true);
119 else
120 policy_mgr_check_concurrent_intf_and_restart_sap(
121 psoc,
122 wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev));
123 /*
124 * Enable TDLS again on concurrent STA
125 */
126 if (event_data && QDF_IS_STATUS_ERROR(event_data->status))
127 wlan_tdls_notify_start_bss_failure(psoc);
128
129 return QDF_STATUS_SUCCESS;
130 }
131
if_mgr_ap_stop_bss(struct wlan_objmgr_vdev * vdev,struct if_mgr_event_data * event_data)132 QDF_STATUS if_mgr_ap_stop_bss(struct wlan_objmgr_vdev *vdev,
133 struct if_mgr_event_data *event_data)
134 {
135 return QDF_STATUS_SUCCESS;
136 }
137
138 QDF_STATUS
if_mgr_ap_stop_bss_complete(struct wlan_objmgr_vdev * vdev,struct if_mgr_event_data * event_data)139 if_mgr_ap_stop_bss_complete(struct wlan_objmgr_vdev *vdev,
140 struct if_mgr_event_data *event_data)
141 {
142 struct wlan_objmgr_psoc *psoc;
143 struct wlan_objmgr_pdev *pdev;
144 uint8_t mcc_scc_switch;
145
146 pdev = wlan_vdev_get_pdev(vdev);
147 if (!pdev)
148 return QDF_STATUS_E_FAILURE;
149
150 psoc = wlan_pdev_get_psoc(pdev);
151 if (!psoc)
152 return QDF_STATUS_E_FAILURE;
153
154 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE ||
155 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
156 wlan_handle_emlsr_sta_concurrency(psoc, false, true);
157 /*
158 * Due to audio share glitch with P2P GO caused by
159 * roam scan on concurrent interface, disable
160 * roaming if "p2p_disable_roam" ini is enabled.
161 * Re-enable roaming on other STA interface if p2p GO
162 * is active on any vdev.
163 */
164 if (cfg_p2p_is_roam_config_disabled(psoc) &&
165 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) {
166 ifmgr_debug("p2p go disconnected enable roam");
167 if_mgr_enable_roaming(pdev, vdev, RSO_START_BSS);
168 }
169
170 ifmgr_debug("SAP/P2P-GO is stopped, re-enable roaming if it's stopped due to SAP/P2P-GO CSA");
171 if_mgr_enable_roaming(pdev, vdev, RSO_SAP_CHANNEL_CHANGE);
172
173 policy_mgr_get_mcc_scc_switch(psoc, &mcc_scc_switch);
174 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE &&
175 mcc_scc_switch == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)
176 policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
177
178 if (policy_mgr_is_vdev_ll_lt_sap(psoc, wlan_vdev_get_id(vdev)))
179 policy_mgr_ll_lt_sap_restart_concurrent_sap(psoc, false);
180
181 return QDF_STATUS_SUCCESS;
182 }
183
184 QDF_STATUS
if_mgr_ap_csa_complete(struct wlan_objmgr_vdev * vdev,struct if_mgr_event_data * event_data)185 if_mgr_ap_csa_complete(struct wlan_objmgr_vdev *vdev,
186 struct if_mgr_event_data *event_data)
187 {
188 struct wlan_objmgr_psoc *psoc;
189 struct wlan_objmgr_pdev *pdev;
190 QDF_STATUS status = QDF_STATUS_SUCCESS;
191
192 pdev = wlan_vdev_get_pdev(vdev);
193 if (!pdev)
194 return QDF_STATUS_E_FAILURE;
195
196 psoc = wlan_pdev_get_psoc(pdev);
197 if (!psoc)
198 return QDF_STATUS_E_FAILURE;
199
200 status = wlan_p2p_check_and_force_scc_go_plus_go(psoc, vdev);
201 if (QDF_IS_STATUS_ERROR(status))
202 ifmgr_err("force scc failure with status: %d", status);
203
204 wlan_tdls_notify_channel_switch_complete(psoc, wlan_vdev_get_id(vdev));
205
206 return status;
207 }
208
209 QDF_STATUS
if_mgr_ap_csa_start(struct wlan_objmgr_vdev * vdev,struct if_mgr_event_data * event_data)210 if_mgr_ap_csa_start(struct wlan_objmgr_vdev *vdev,
211 struct if_mgr_event_data *event_data)
212 {
213 struct wlan_objmgr_psoc *psoc;
214 struct wlan_objmgr_pdev *pdev;
215 enum QDF_OPMODE op_mode;
216
217 op_mode = wlan_vdev_mlme_get_opmode(vdev);
218 if (op_mode != QDF_SAP_MODE && op_mode != QDF_P2P_GO_MODE)
219 return QDF_STATUS_SUCCESS;
220
221 pdev = wlan_vdev_get_pdev(vdev);
222 if (!pdev)
223 return QDF_STATUS_E_FAILURE;
224
225 psoc = wlan_pdev_get_psoc(pdev);
226 if (!psoc)
227 return QDF_STATUS_E_FAILURE;
228
229 /*
230 * Disable TDLS off-channel before VDEV restart
231 */
232 wlan_tdls_notify_channel_switch_start(psoc, vdev);
233
234 return QDF_STATUS_SUCCESS;
235 }
236