Procházet zdrojové kódy

qcacld-3.0: Check vdev max limit before creating

Firmware allocates memory as part of WMI_INIT_CMDID based on number of
STA vdevs and max number of vdevs. If we try to create more then
max limit then firmware will crash.
Added check to check for max limit before creating the interface.

Change-Id: I3e73c9f1b3c925465452a23ea5f25f47e4eb1ada
CRs-Fixed: 2468171
Rachit Kankane před 5 roky
rodič
revize
33bf18f2ef
1 změnil soubory, kde provedl 26 přidání a 0 odebrání
  1. 26 0
      core/hdd/src/wlan_hdd_main.c

+ 26 - 0
core/hdd/src/wlan_hdd_main.c

@@ -5096,6 +5096,19 @@ static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
 	osif_vdev_sync_op_stop(vdev_sync);
 	osif_vdev_sync_op_stop(vdev_sync);
 }
 }
 
 
+static u8 hdd_get_mode_specific_interface_count(struct hdd_context *hdd_ctx,
+						enum QDF_OPMODE mode)
+{
+	struct hdd_adapter *adapter = NULL;
+	u8 intf_count = 0;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode == mode)
+			intf_count++;
+	}
+	return intf_count;
+}
+
 /**
 /**
  * hdd_open_adapter() - open and setup the hdd adatper
  * hdd_open_adapter() - open and setup the hdd adatper
  * @hdd_ctx: global hdd context
  * @hdd_ctx: global hdd context
@@ -5118,6 +5131,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio
 {
 {
 	struct net_device *ndev = NULL;
 	struct net_device *ndev = NULL;
 	struct hdd_adapter *adapter = NULL;
 	struct hdd_adapter *adapter = NULL;
+	u8 intf_count = 0;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 
 
 	if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
 	if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
@@ -5163,6 +5177,18 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio
 				return NULL;
 				return NULL;
 			}
 			}
 		}
 		}
+		/* Check for max no of supported VDEVs before creating
+		 * another one.
+		 */
+		intf_count = hdd_get_mode_specific_interface_count(
+								hdd_ctx,
+								session_type);
+		if (CFG_TGT_DEFAULT_MAX_STA_VDEVS &&
+		    (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS)) {
+			hdd_err("Max limit reached sta vdev-current %d max %d",
+				intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS);
+			return NULL;
+		}
 
 
 	/* fall through */
 	/* fall through */
 	case QDF_P2P_CLIENT_MODE:
 	case QDF_P2P_CLIENT_MODE: