diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index db4fec04cca1..4debe991a033 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -4466,4 +4466,13 @@ void hdd_init_start_completion(void); */ int hdd_update_phymode(struct hdd_adapter *adapter, eCsrPhyMode phymode, enum band_info band, uint32_t chwidth); + +/** + * hdd_max_sta_vdev_count_reached() - check sta vdev count + * @hdd_ctx: global hdd context + * + * Return: true if vdev limit reached + */ +bool hdd_max_sta_vdev_count_reached(struct hdd_context *hdd_ctx); + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 472cc18368e9..5e672f63d277 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -16603,6 +16603,13 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, qdf_opmode_str(adapter->device_mode), qdf_opmode_str(new_mode)); + if ((new_mode == QDF_STA_MODE || new_mode == QDF_P2P_CLIENT_MODE) && + (adapter->device_mode != QDF_STA_MODE && + adapter->device_mode != QDF_P2P_CLIENT_MODE)) { + if (hdd_max_sta_vdev_count_reached(adapter->hdd_ctx)) + return -EINVAL; + } + errno = hdd_trigger_psoc_idle_restart(hdd_ctx); if (errno) { hdd_err("Failed to restart psoc; errno:%d", errno); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 9269b0d7b1da..850bdc529ba5 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -6044,6 +6044,27 @@ static u8 hdd_get_mode_specific_interface_count(struct hdd_context *hdd_ctx, return intf_count; } +bool hdd_max_sta_vdev_count_reached(struct hdd_context *hdd_ctx) +{ + u8 intf_count; + + /* + * Check for max no of supported STA/P2PCLI VDEVs before + * creating another one. + */ + intf_count = hdd_get_mode_specific_interface_count(hdd_ctx, + QDF_STA_MODE); + intf_count += hdd_get_mode_specific_interface_count(hdd_ctx, + QDF_P2P_CLIENT_MODE); + 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 true; + } + return false; +} + /** * hdd_open_adapter() - open and setup the hdd adatper * @hdd_ctx: global hdd context @@ -6066,7 +6087,6 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio { struct net_device *ndev = NULL; struct hdd_adapter *adapter = NULL; - u8 intf_count = 0; QDF_STATUS status = QDF_STATUS_E_FAILURE; if (hdd_ctx->current_intf_count >= WLAN_MAX_VDEVS) { @@ -6116,19 +6136,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio /* fall through */ case QDF_P2P_CLIENT_MODE: - /* Check for max no of supported STA/P2PCLI VDEVs before - * creating another one. - */ - intf_count += hdd_get_mode_specific_interface_count(hdd_ctx, - QDF_STA_MODE); - intf_count += hdd_get_mode_specific_interface_count(hdd_ctx, - QDF_P2P_CLIENT_MODE); - 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); + if (hdd_max_sta_vdev_count_reached(hdd_ctx)) return NULL; - } /* fall through */ case QDF_P2P_DEVICE_MODE: