|
@@ -21,7 +21,9 @@
|
|
|
#include "wlan_objmgr_pdev_obj.h"
|
|
|
#include "wlan_objmgr_vdev_obj.h"
|
|
|
#include "wlan_policy_mgr_api.h"
|
|
|
+#include "wlan_policy_mgr_i.h"
|
|
|
#include "wlan_if_mgr_roam.h"
|
|
|
+#include "wlan_if_mgr_public_struct.h"
|
|
|
#include "wlan_cm_roam_api.h"
|
|
|
#include "wlan_if_mgr_main.h"
|
|
|
#include "wlan_p2p_ucfg_api.h"
|
|
@@ -164,3 +166,82 @@ QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect(
|
|
|
|
|
|
return status;
|
|
|
}
|
|
|
+
|
|
|
+static void if_mgr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
|
|
|
+ void *object, void *arg)
|
|
|
+{
|
|
|
+ struct bssid_search_arg *bssid_arg = arg;
|
|
|
+ struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
|
|
|
+ struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
|
|
|
+ struct wlan_objmgr_peer *peer = objmgr->bss_peer;
|
|
|
+
|
|
|
+ if (WLAN_ADDR_EQ(bssid_arg->peer_addr.bytes,
|
|
|
+ wlan_peer_get_macaddr(peer)))
|
|
|
+ bssid_arg->vdev_id = wlan_vdev_get_id(vdev);
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct if_mgr_event_data *event_data)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_psoc *psoc;
|
|
|
+ struct wlan_objmgr_pdev *pdev;
|
|
|
+ enum QDF_OPMODE op_mode;
|
|
|
+ enum policy_mgr_con_mode mode;
|
|
|
+ struct bssid_search_arg bssid_arg;
|
|
|
+ uint32_t chan_freq = event_data->validate_bss_info.chan_freq;
|
|
|
+
|
|
|
+ op_mode = wlan_vdev_mlme_get_opmode(vdev);
|
|
|
+
|
|
|
+ pdev = wlan_vdev_get_pdev(vdev);
|
|
|
+ if (!pdev)
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+ psoc = wlan_pdev_get_psoc(pdev);
|
|
|
+ if (!psoc)
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Ignore the BSS if any other vdev is already connected to it.
|
|
|
+ */
|
|
|
+ qdf_copy_macaddr(&bssid_arg.peer_addr,
|
|
|
+ &event_data->validate_bss_info.peer_addr);
|
|
|
+ bssid_arg.vdev_id = WLAN_INVALID_VDEV_ID;
|
|
|
+ wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
|
|
|
+ if_mgr_get_vdev_id_from_bssid,
|
|
|
+ &bssid_arg, 0,
|
|
|
+ WLAN_IF_MGR_ID);
|
|
|
+
|
|
|
+ if (bssid_arg.vdev_id != WLAN_INVALID_VDEV_ID) {
|
|
|
+ ifmgr_info("vdev_id %d already connected to "QDF_MAC_ADDR_FMT". select next bss for vdev_id %d",
|
|
|
+ bssid_arg.vdev_id,
|
|
|
+ QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes),
|
|
|
+ wlan_vdev_get_id(vdev));
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If concurrency enabled take the concurrent connected channel first.
|
|
|
+ * Valid multichannel concurrent sessions exempted
|
|
|
+ */
|
|
|
+ mode = policy_mgr_convert_device_mode_to_qdf_type(op_mode);
|
|
|
+ /* If concurrency is not allowed select next bss */
|
|
|
+ if (!policy_mgr_is_concurrency_allowed(psoc, mode, chan_freq,
|
|
|
+ HW_MODE_20_MHZ)) {
|
|
|
+ ifmgr_info("Concurrency not allowed for this channel freq %d bssid "QDF_MAC_ADDR_FMT", selecting next",
|
|
|
+ chan_freq, QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * check if channel is allowed for current hw mode, if not fetch
|
|
|
+ * next BSS.
|
|
|
+ */
|
|
|
+ if (!policy_mgr_is_hwmode_set_for_given_chnl(psoc, chan_freq)) {
|
|
|
+ ifmgr_info("HW mode isn't properly set, freq %d BSSID "QDF_MAC_ADDR_FMT,
|
|
|
+ chan_freq,
|
|
|
+ QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|