Browse Source

qcacmn: Selective peer discon during non-DFS to DFS

Disconnect only non ML peers in CSA from non-DFS channel to DFS channel,
while keeping all MLO peers connected.

Change-Id: I7e8347cf4692b16b84ffbce4b102dd2f23bb70f0
CRs-Fixed: 3394219
Krunalsinh Padhar 2 years ago
parent
commit
6d5fea01f7

+ 82 - 12
umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h

@@ -237,6 +237,11 @@
 /* MLO link removal is in progress on this VDEV */
 #define WLAN_VDEV_OP_MLO_LINK_REMOVAL_IN_PROGRESS 0x01000000
 
+ /* flag to indicate disconnect only legacy peers due to moving to DFS channel
+  * from non-DFS channel
+  */
+#define WLAN_VDEV_OP_MLME_LEGACY_PEER_DISCON_TRIG 0x02000000
+
  /* CAPABILITY: IBSS available */
 #define WLAN_VDEV_C_IBSS                    0x00000001
 /* CAPABILITY: HOSTAP avail */
@@ -379,18 +384,19 @@ struct wlan_objmgr_vdev_nif {
 
 /**
  *  struct wlan_objmgr_vdev_objmgr - vdev object manager sub structure
- *  @vdev_id:           VDEV id
- *  @print_cnt:         Count to throttle Logical delete prints
- *  @self_peer:         Self PEER
- *  @bss_peer:          BSS PEER
- *  @wlan_peer_list:    PEER list
- *  @wlan_pdev:         PDEV pointer
- *  @wlan_peer_count:   Peer count
- *  @max_peer_count:    Max Peer count
- *  @c_flags:           creation specific flags
- *  @ref_cnt:           Ref count
- *  @ref_id_dbg:        Array to track Ref count
- *  @trace:             Trace ref and deref
+ *  @vdev_id:            VDEV id
+ *  @print_cnt:          Count to throttle Logical delete prints
+ *  @self_peer:          Self PEER
+ *  @bss_peer:           BSS PEER
+ *  @wlan_peer_list:     PEER list
+ *  @wlan_pdev:          PDEV pointer
+ *  @wlan_peer_count:    Peer count
+ *  @wlan_ml_peer_count: Multilink Peer count
+ *  @max_peer_count:     Max Peer count
+ *  @c_flags:            creation specific flags
+ *  @ref_cnt:            Ref count
+ *  @ref_id_dbg:         Array to track Ref count
+ *  @trace:              Trace ref and deref
  */
 struct wlan_objmgr_vdev_objmgr {
 	uint8_t vdev_id;
@@ -400,6 +406,9 @@ struct wlan_objmgr_vdev_objmgr {
 	qdf_list_t wlan_peer_list;
 	struct wlan_objmgr_pdev *wlan_pdev;
 	uint16_t wlan_peer_count;
+#ifdef WLAN_FEATURE_11BE_MLO
+	uint16_t wlan_ml_peer_count;
+#endif
 	uint16_t max_peer_count;
 	uint32_t c_flags;
 	qdf_atomic_t ref_cnt;
@@ -1565,6 +1574,29 @@ static inline uint16_t wlan_vdev_get_peer_count(struct wlan_objmgr_vdev *vdev)
 	return vdev->vdev_objmgr.wlan_peer_count;
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * wlan_vdev_get_legacy_peer_count() - get vdev peer count
+ * @vdev: VDEV object
+ *
+ * API to get legacy peer count from VDEV
+ *
+ * Return: peer_count - vdev's peer count
+ */
+static inline uint16_t wlan_vdev_get_legacy_peer_count(
+					struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_objmgr.wlan_peer_count -
+	       vdev->vdev_objmgr.wlan_ml_peer_count;
+}
+#else
+static inline uint16_t wlan_vdev_get_legacy_peer_count(
+					struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_objmgr.wlan_peer_count;
+}
+#endif
+
 /**
  * wlan_vdev_mlme_is_ap() - Check whether @vdev is an AP or not
  * @vdev: VDEV object
@@ -2098,4 +2130,42 @@ QDF_STATUS wlan_vdev_get_bss_peer_mld_mac(struct wlan_objmgr_vdev *vdev,
 					  struct qdf_mac_addr *mld_mac);
 #endif
 
+/**
+ * wlan_objmgr_vdev_set_ml_peer_count() - set ml_peer_count value
+ * @vdev: vdev object pointer
+ * @ml_peer_count: ml peer count to be set
+ *
+ * Return: void
+ */
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline void
+wlan_objmgr_vdev_set_ml_peer_count(struct wlan_objmgr_vdev *vdev,
+				   uint16_t ml_peer_count)
+{
+	vdev->vdev_objmgr.wlan_ml_peer_count = ml_peer_count;
+}
+#else
+static inline void
+wlan_objmgr_vdev_set_ml_peer_count(struct wlan_objmgr_vdev *vdev,
+				   uint16_t ml_peer_count)
+{
+}
+#endif
+
+/**
+ * wlan_mlo_peer_delete_is_not_allowed()
+ * @vdev: VDEV object
+ *
+ * API to check if WLAN_VDEV_OP_MLME_LEGACY_PEER_DISCON_TRIG is set therefore
+ * whether mlo peer delete should be allowed or not
+ *
+ * Return: True if MLO peer delete is not allowed, otherwise false.
+ */
+static inline bool wlan_mlo_peer_delete_is_not_allowed(
+		struct wlan_objmgr_vdev *vdev)
+{
+	return wlan_vdev_mlme_op_flags_get(vdev,
+				WLAN_VDEV_OP_MLME_LEGACY_PEER_DISCON_TRIG);
+}
+
 #endif /* _WLAN_OBJMGR_VDEV_OBJ_H_*/

+ 1 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

@@ -225,6 +225,7 @@ struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create(
 
 	/* peer count to 0 */
 	vdev->vdev_objmgr.wlan_peer_count = 0;
+	wlan_objmgr_vdev_set_ml_peer_count(vdev, 0);
 	qdf_atomic_init(&vdev->vdev_objmgr.ref_cnt);
 	vdev->vdev_objmgr.print_cnt = 0;
 	wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);

+ 2 - 1
umac/mlme/include/wlan_vdev_mlme.h

@@ -759,7 +759,8 @@ struct vdev_mlme_ops {
 				uint16_t event_data_len, void *event_data);
 	QDF_STATUS (*mlme_vdev_disconnect_peers)(
 				struct vdev_mlme_obj *vdev_mlme,
-				uint16_t event_data_len, void *event_data);
+				uint16_t event_data_len, void *event_data,
+				bool discon_legacy_only);
 	QDF_STATUS (*mlme_vdev_dfs_cac_timer_stop)(
 				struct vdev_mlme_obj *vdev_mlme,
 				uint16_t event_data_len, void *event_data);

+ 3 - 0
umac/mlme/mlme_objmgr/dispatcher/inc/wlan_vdev_mlme_main.h

@@ -134,6 +134,8 @@ enum wlan_vdev_state {
  * @WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE:   MLO mgr triggers this event for the mlo
  *                                       sap in vdev wait up state, if all the
  *                                       links finish vdev start rsp.
+ * @WLAN_VDEV_SM_EV_SUSPEND_CSA_RESTART: Invoke peer deletion for only legacy
+ *					 peers
  */
 enum wlan_vdev_sm_evt {
 	WLAN_VDEV_SM_EV_START = 0,
@@ -168,6 +170,7 @@ enum wlan_vdev_sm_evt {
 	WLAN_VDEV_SM_EV_STOP_REQ = 29,
 	WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED = 30,
 	WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE = 31,
+	WLAN_VDEV_SM_EV_SUSPEND_CSA_RESTART = 32,
 };
 
 /**

+ 13 - 6
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c

@@ -388,8 +388,8 @@ static bool mlme_vdev_state_dfs_cac_wait_event(void *ctx, uint16_t event,
 		/* stop the CAC timer, then notify state machine */
 		mlme_vdev_dfs_cac_timer_stop(vdev_mlme, event_data_len,
 					     event_data);
-		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP);
-		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ,
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
+		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_DOWN,
 					   event_data_len, event_data);
 		status = true;
 		break;
@@ -1180,7 +1180,7 @@ static bool mlme_vdev_subst_suspend_suspend_down_event(void *ctx,
 	case WLAN_VDEV_SM_EV_DOWN:
 	case WLAN_VDEV_SM_EV_RESTART_REQ_FAIL:
 		mlme_vdev_disconnect_peers(vdev_mlme,
-					   event_data_len, event_data);
+					   event_data_len, event_data, false);
 		status = true;
 		break;
 
@@ -1258,7 +1258,7 @@ static bool mlme_vdev_subst_suspend_suspend_restart_event(void *ctx,
 	switch (event) {
 	case WLAN_VDEV_SM_EV_SUSPEND_RESTART:
 		mlme_vdev_disconnect_peers(vdev_mlme,
-					   event_data_len, event_data);
+					   event_data_len, event_data, false);
 		status = true;
 		break;
 
@@ -1286,6 +1286,12 @@ static bool mlme_vdev_subst_suspend_suspend_restart_event(void *ctx,
 		status = true;
 		break;
 
+	case WLAN_VDEV_SM_EV_SUSPEND_CSA_RESTART:
+		mlme_vdev_disconnect_peers(vdev_mlme,
+					   event_data_len, event_data, true);
+		status = true;
+		break;
+
 	default:
 		status = false;
 		break;
@@ -1351,7 +1357,7 @@ static bool mlme_vdev_subst_suspend_host_restart_event(void *ctx,
 	switch (event) {
 	case WLAN_VDEV_SM_EV_HOST_RESTART:
 		mlme_vdev_disconnect_peers(vdev_mlme,
-					   event_data_len, event_data);
+					   event_data_len, event_data, false);
 		status = true;
 		break;
 
@@ -1476,7 +1482,7 @@ static bool mlme_vdev_subst_suspend_csa_restart_event(void *ctx,
 				(vdev_mlme,
 				 WLAN_VDEV_SS_SUSPEND_SUSPEND_RESTART);
 			mlme_vdev_sm_deliver_event
-				(vdev_mlme, WLAN_VDEV_SM_EV_SUSPEND_RESTART,
+				(vdev_mlme, WLAN_VDEV_SM_EV_SUSPEND_CSA_RESTART,
 				 event_data_len, event_data);
 		}
 		status = true;
@@ -2000,6 +2006,7 @@ static const char *vdev_sm_event_names[] = {
 	"EV_STOP_REQ",
 	"EV_CHAN_SWITCH_DISABLED",
 	"EV_MLO_SYNC_COMPLETE",
+	"EV_SUSPEND_CSA_RESTART"
 };
 
 struct wlan_sm_state_info sm_info[] = {

+ 6 - 2
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h

@@ -426,6 +426,8 @@ QDF_STATUS mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme,
  * @vdev_mlme:  VDEV MLME comp object
  * @event_data_len: data size
  * @event_data: event data
+ * @discon_legacy_only: flag indicating that only legacy peer to be
+ * disconnected
  *
  * API trigger stations disconnection with AP VDEV or AP disconnection with STA
  * VDEV
@@ -435,13 +437,15 @@ QDF_STATUS mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme,
  */
 static inline QDF_STATUS mlme_vdev_disconnect_peers(
 				struct vdev_mlme_obj *vdev_mlme,
-				uint16_t event_data_len, void *event_data)
+				uint16_t event_data_len, void *event_data,
+				bool discon_legacy_only)
 {
 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
 
 	if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_disconnect_peers)
 		ret = vdev_mlme->ops->mlme_vdev_disconnect_peers(
-					vdev_mlme, event_data_len, event_data);
+					vdev_mlme, event_data_len, event_data,
+					discon_legacy_only);
 
 	return ret;
 }

+ 5 - 0
umac/mlo_mgr/src/wlan_mlo_mgr_peer.c

@@ -633,6 +633,7 @@ static QDF_STATUS mlo_peer_attach_link_peer(
 			break;
 		}
 		peer_entry->link_peer = link_peer;
+		vdev->vdev_objmgr.wlan_ml_peer_count++;
 		qdf_copy_macaddr(&peer_entry->link_addr,
 				 (struct qdf_mac_addr *)&link_peer->macaddr[0]);
 
@@ -727,6 +728,7 @@ static QDF_STATUS mlo_peer_detach_link_peer(
 	struct wlan_mlo_link_peer_entry *peer_entry;
 	QDF_STATUS status = QDF_STATUS_E_RESOURCES;
 	uint16_t i;
+	struct wlan_objmgr_vdev *vdev;
 
 	mlo_peer_lock_acquire(ml_peer);
 
@@ -742,6 +744,9 @@ static QDF_STATUS mlo_peer_detach_link_peer(
 			qdf_nbuf_free(peer_entry->assoc_rsp_buf);
 			peer_entry->assoc_rsp_buf = NULL;
 		}
+		vdev =  wlan_peer_get_vdev(link_peer);
+		if (vdev)
+			vdev->vdev_objmgr.wlan_ml_peer_count--;
 
 		wlan_objmgr_peer_release_ref(link_peer, WLAN_MLO_MGR_ID);
 		peer_entry->link_peer = NULL;