qcacmn: Account for temporary peers created in object manager

The wlan_max_peer count in the object manager currently
includes the count of temporary peers and actual peers
created on the target, and this could be used to limit the
actual numbers of peers created.

The result is that, for a given number of
peers configured the object manager limits
counting temporary peer also and not actual peers alone.

Indicate the count of actual peers and temporary peers
separately, to appropriately limit actual peers created.

Change-Id: Ia1593d702949853ad26756f167988ec70279eb87
CRs-Fixed: 2228250
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index 9dbd55f..85c7b2d 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -34,6 +34,11 @@
 #define WLAN_UMAC_PDEV_MAX_VDEVS 17
 /* Max no. of Peers, a device can support */
 #define WLAN_UMAC_PSOC_MAX_PEERS (1024 + WLAN_UMAC_PSOC_MAX_VDEVS)
+/* Max no. of Temporary Peers, a pdev can support */
+#define WLAN_MAX_PDEV_TEMP_PEERS 128
+/* Max no. of Temporary Peers, a psoc can support */
+#define WLAN_MAX_PSOC_TEMP_PEERS \
+		(WLAN_MAX_PDEV_TEMP_PEERS * WLAN_UMAC_MAX_PDEVS)
 
 /* Max length of a SSID */
 #define WLAN_SSID_MAX_LEN 32
diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h
index 210bf59..4616a63 100644
--- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h
+++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h
@@ -149,6 +149,7 @@
  * @wlan_vdev_list:    List maintains the VDEVs created on this PDEV
  * @wlan_peer_count:   Peer count
  * @max_peer_count:    Max Peer count
+ * @temp_peer_count:   Temporary peer count
  * @wlan_psoc:         back pointer to PSOC, its attached to
  * @ref_cnt:           Ref count
  * @ref_id_dbg:        Array to track Ref count
@@ -161,6 +162,7 @@
 	qdf_list_t wlan_vdev_list;
 	uint16_t wlan_peer_count;
 	uint16_t max_peer_count;
+	uint16_t temp_peer_count;
 	struct wlan_objmgr_psoc *wlan_psoc;
 	qdf_atomic_t ref_cnt;
 	qdf_atomic_t ref_id_dbg[WLAN_REF_ID_MAX];
@@ -842,6 +844,20 @@
 }
 
 /**
+ * wlan_pdev_get_temp_peer_count() - get pdev temporary peer count
+ * @pdev: PDEV object
+ *
+ * API to get temporary peer count from PDEV
+ *
+ * Return: temp_peer_count - pdev's temporary peer count
+ */
+static inline uint16_t wlan_pdev_get_temp_peer_count(struct wlan_objmgr_pdev *pdev)
+{
+	return pdev->pdev_objmgr.temp_peer_count;
+}
+
+
+/**
  * wlan_pdev_incr_peer_count() - increment pdev peer count
  * @pdev: PDEV object
  *
@@ -868,6 +884,32 @@
 }
 
 /**
+ * wlan_pdev_incr_temp_peer_count() - increment temporary pdev peer count
+ * @pdev: PDEV object
+ *
+ * API to increment temporary  peer count of PDEV by 1
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_incr_temp_peer_count(struct wlan_objmgr_pdev *pdev)
+{
+	pdev->pdev_objmgr.temp_peer_count++;
+}
+
+/**
+ * wlan_pdev_decr_temp_peer_count() - decrement pdev temporary peer count
+ * @pdev: PDEV object
+ *
+ * API to decrement temporary peer count of PDEV by 1
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_decr_temp_peer_count(struct wlan_objmgr_pdev *pdev)
+{
+	pdev->pdev_objmgr.temp_peer_count--;
+}
+
+/**
  * wlan_pdev_get_vdev_count() - get PDEV vdev count
  * @pdev: PDEV object
  *
diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h
index eecea41..7b44bb6 100644
--- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h
+++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h
@@ -247,6 +247,7 @@
  * @print_cnt:            Count to throttle Logical delete prints
  * @wlan_peer_count:      PEER count
  * @max_peer_count:       Max no. of peers supported by this PSOC
+ * @temp_peer_count:      Temporary peer count
  * @wlan_pdev_list[]:     PDEV list
  * @wlan_vdev_list[]:     VDEV list
  * @wlan_vdev_id_map[]:   VDEV id map, to allocate free ids
@@ -264,6 +265,7 @@
 	uint8_t print_cnt;
 	uint16_t wlan_peer_count;
 	uint16_t max_peer_count;
+	uint16_t temp_peer_count;
 	struct wlan_objmgr_pdev *wlan_pdev_list[WLAN_UMAC_MAX_PDEVS];
 	struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_PSOC_MAX_VDEVS];
 	uint32_t wlan_vdev_id_map[2];
diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c
index 9b02022..9e1f555 100644
--- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c
+++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c
@@ -130,6 +130,7 @@
 	pdev->pdev_objmgr.wlan_vdev_count = 0;
 	pdev->pdev_objmgr.max_vdev_count = WLAN_UMAC_PDEV_MAX_VDEVS;
 	pdev->pdev_objmgr.wlan_peer_count = 0;
+	pdev->pdev_objmgr.temp_peer_count = 0;
 	pdev->pdev_objmgr.max_peer_count = wlan_psoc_get_max_peer_count(psoc);
 	/* Save HDD/OSIF pointer */
 	pdev->pdev_nif.pdev_ospriv = osdev_priv;
diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c
index c3ceac3..65f0863 100644
--- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c
+++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c
@@ -77,7 +77,8 @@
 	qdf_spinlock_create(&peer_list->peer_list_lock);
 	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
 		qdf_list_create(&peer_list->peer_hash[i],
-				WLAN_UMAC_PSOC_MAX_PEERS);
+			WLAN_UMAC_PSOC_MAX_PEERS +
+			WLAN_MAX_PSOC_TEMP_PEERS);
 }
 
 static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list)
@@ -129,6 +130,7 @@
 	objmgr->wlan_vdev_count = 0;
 	objmgr->max_vdev_count = WLAN_UMAC_PSOC_MAX_VDEVS;
 	objmgr->wlan_peer_count = 0;
+	objmgr->temp_peer_count = 0;
 	objmgr->max_peer_count = WLAN_UMAC_PSOC_MAX_PEERS;
 	qdf_atomic_init(&objmgr->ref_cnt);
 	objmgr->print_cnt = 0;
@@ -1494,11 +1496,21 @@
 
 	wlan_psoc_obj_lock(psoc);
 	objmgr = &psoc->soc_objmgr;
-	/* Max peer limit is reached, return failure */
-	if (objmgr->wlan_peer_count >= wlan_psoc_get_max_peer_count(psoc)) {
-		wlan_psoc_obj_unlock(psoc);
-		return QDF_STATUS_E_FAILURE;
+	/* Max temporary peer limit is reached, return failure */
+	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) {
+		if (objmgr->temp_peer_count >= WLAN_MAX_PSOC_TEMP_PEERS) {
+			wlan_psoc_obj_unlock(psoc);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		/* Max peer limit is reached, return failure */
+		if (objmgr->wlan_peer_count
+			>= wlan_psoc_get_max_peer_count(psoc)) {
+			wlan_psoc_obj_unlock(psoc);
+			return QDF_STATUS_E_FAILURE;
+		}
 	}
+
 	/* Derive hash index from mac address */
 	hash_index = WLAN_PEER_HASH(peer->macaddr);
 	peer_list = &objmgr->peer_list;
@@ -1510,7 +1522,11 @@
 							peer);
 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
 	/* Increment peer count */
-	objmgr->wlan_peer_count++;
+	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
+		objmgr->temp_peer_count++;
+	else
+		objmgr->wlan_peer_count++;
+
 	wlan_psoc_obj_unlock(psoc);
 
 	return QDF_STATUS_SUCCESS;
@@ -1547,7 +1563,10 @@
 	}
 	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
 	/* Decrement peer count */
-	objmgr->wlan_peer_count--;
+	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
+		objmgr->temp_peer_count--;
+	else
+		objmgr->wlan_peer_count--;
 	wlan_psoc_obj_unlock(psoc);
 
 	return QDF_STATUS_SUCCESS;
diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c
index 3109e76..359ac48 100644
--- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c
+++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c
@@ -215,7 +215,8 @@
 
 	/* Initialize peer list */
 	qdf_list_create(&vdev->vdev_objmgr.wlan_peer_list,
-			vdev->vdev_objmgr.max_peer_count);
+			vdev->vdev_objmgr.max_peer_count +
+			WLAN_MAX_PDEV_TEMP_PEERS);
 	/* TODO init other parameters */
 
 	/* Invoke registered create handlers */
@@ -646,21 +647,35 @@
 
 	wlan_vdev_obj_lock(vdev);
 	pdev = wlan_vdev_get_pdev(vdev);
-	/* If Max peer count exceeds, return failure */
-	if (objmgr->wlan_peer_count >= objmgr->max_peer_count) {
-		wlan_vdev_obj_unlock(vdev);
-		return QDF_STATUS_E_FAILURE;
+	/* If Max VDEV peer count exceeds, return failure */
+	if (peer->peer_mlme.peer_type != WLAN_PEER_STA_TEMP) {
+		if (objmgr->wlan_peer_count >= objmgr->max_peer_count) {
+			wlan_vdev_obj_unlock(vdev);
+			return QDF_STATUS_E_FAILURE;
+		}
 	}
 	wlan_vdev_obj_unlock(vdev);
 
+	/* If Max PDEV peer count exceeds, return failure */
 	wlan_pdev_obj_lock(pdev);
-	if (wlan_pdev_get_peer_count(pdev) >=
+	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) {
+		if (wlan_pdev_get_temp_peer_count(pdev) >=
+			WLAN_MAX_PDEV_TEMP_PEERS) {
+			wlan_pdev_obj_unlock(pdev);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		if (wlan_pdev_get_peer_count(pdev) >=
 			wlan_pdev_get_max_peer_count(pdev)) {
-		wlan_pdev_obj_unlock(pdev);
-		return QDF_STATUS_E_FAILURE;
+			wlan_pdev_obj_unlock(pdev);
+			return QDF_STATUS_E_FAILURE;
+		}
 	}
 
-	wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev));
+	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
+		wlan_pdev_incr_temp_peer_count(wlan_vdev_get_pdev(vdev));
+	else
+		wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev));
 	wlan_pdev_obj_unlock(pdev);
 
 	wlan_vdev_obj_lock(vdev);
@@ -744,7 +759,10 @@
 	wlan_vdev_obj_unlock(vdev);
 
 	wlan_pdev_obj_lock(pdev);
-	wlan_pdev_decr_peer_count(pdev);
+	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
+		wlan_pdev_decr_temp_peer_count(pdev);
+	else
+		wlan_pdev_decr_peer_count(pdev);
 	wlan_pdev_obj_unlock(pdev);
 
 	/* decrement vdev ref count after peer released its reference */