wlan: HDD_VOSS: Restrict creation of multi-port concurrency
Checks are added to restrict the creation of multi-port concurrency.
As of now, only two-port concurrency is supported; if there exists
a 2-port concurrency then the third connection is not allowed.
However, it does not restrict the creation of interface.
For example:
1. STA + P2P (GO/CLI) connection exists and then new
connection establishment is not allowed.
2. STA + SAP connection exists and then new
connection establishment is not allowed.
3. P2P GO + P2P CLI connection exists and then new
connection establishment is not allowed.
4. STA + ADHOC connection exists and then new
connection establishment is not allowed.
In the above example combinations, if any of the existing connection
is disconneted, then next connection is allowed.
CRs-fixed: 669604
Change-Id: Ib9e62953f38b274086115ae6a956ecd7a3973b0b
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 25971ca..c31e88e 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -631,6 +631,15 @@
if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */
{
+ /* In case of roaming ; We are not doing disconnect.
+ * If disconnect is not being done for roam; We will not
+ * decrease count for Active sessions. We should not increase active
+ * active session in case of roaming.
+ */
+ if(pHddStaCtx->ft_carrier_on == FALSE)
+ {
+ wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode);
+ }
memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId, sizeof(pCsrRoamInfo->pBssDesc->bssId));
type = WLAN_STA_ASSOC_DONE_IND;
@@ -676,6 +685,7 @@
}
else if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) // IBss Associated
{
+ wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode);
memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId, ETH_ALEN);
type = WLAN_STA_ASSOC_DONE_IND;
pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR"\n",
@@ -805,13 +815,15 @@
__func__);
hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
/* If only STA mode is on */
- if((pHddCtx->concurrency_mode <= 1) && (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
+ if((pHddCtx->concurrency_mode <= 1) &&
+ (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <= 1))
{
pHddCtx->isAmpAllowed = VOS_TRUE;
}
hdd_clearRoamProfileIe( pAdapter );
hdd_wmm_init( pAdapter );
+ wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
// indicate 'disconnect' status to wpa_supplicant...
hdd_SendAssociationEvent(dev,pRoamInfo);
@@ -874,8 +886,8 @@
if(NULL != pHddCtx)
{
//Only P2P Client is there Enable Bmps back
- if((0 == pHddCtx->no_of_sessions[VOS_STA_SAP_MODE]) &&
- (0 == pHddCtx->no_of_sessions[VOS_P2P_GO_MODE]))
+ if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) &&
+ (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE]))
{
if (pHddCtx->hdd_wlan_suspended)
{
@@ -1115,24 +1127,22 @@
{
unsigned int len = 0;
u8 *pFTAssocRsp = NULL;
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
v_U8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
tANI_U32 rspRsnLength = 0;
struct ieee80211_channel *chan;
- if (!rspRsnIe)
- {
+ if (!rspRsnIe) {
hddLog(LOGE, "%s: Unable to allocate RSN IE", __func__);
return;
}
- if (pCsrRoamInfo == NULL)
- {
+ if (pCsrRoamInfo == NULL) {
hddLog(LOGE, "%s: Invalid CSR roam info", __func__);
goto done;
}
- if (pCsrRoamInfo->nAssocRspLength == 0)
- {
+ if (pCsrRoamInfo->nAssocRspLength == 0) {
hddLog(LOGE, "%s: Invalid assoc response length", __func__);
goto done;
}
@@ -1148,6 +1158,16 @@
(unsigned int)pFTAssocRsp[0],
(unsigned int)pFTAssocRsp[1]);
+ /* Active session count is decremented upon disconnection, but during
+ * roaming, there is no disconnect indication and hence active session
+ * count is not decremented.
+ * After roaming is completed, active session count is incremented
+ * as a part of connect indication but effectively after roaming the
+ * active session count should still be the same and hence upon
+ * successful reassoc decrement the active session count here */
+
+ wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
+
// Send the Assoc Resp, the supplicant needs this for initial Auth.
len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
rspRsnLength = len;
@@ -1533,7 +1553,8 @@
__func__);
hdd_connSetConnectionState( pHddStaCtx, eConnectionState_NotConnected);
}
- if((pHddCtx->concurrency_mode <= 1) && (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
+ if((pHddCtx->concurrency_mode <= 1) &&
+ (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
{
pHddCtx->isAmpAllowed = VOS_TRUE;
}
@@ -1546,7 +1567,7 @@
// Enable BMPS/IMPS in case P2P_CLIENT disconnected
if(((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
(WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) &&
- (vos_concurrent_sessions_running()))
+ (vos_concurrent_open_sessions_running()))
{
//Enable BMPS only of other Session is P2P Client
hdd_context_t *pHddCtx = NULL;
@@ -1559,8 +1580,8 @@
if(NULL != pHddCtx)
{
//Only P2P Client is there Enable Bmps back
- if((0 == pHddCtx->no_of_sessions[VOS_STA_SAP_MODE]) &&
- (0 == pHddCtx->no_of_sessions[VOS_P2P_GO_MODE]))
+ if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) &&
+ (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE]))
{
if (pHddCtx->hdd_wlan_suspended)
{
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index b8c60be..fec4e0e 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -3076,6 +3076,13 @@
CFG_ENABLE_CH_AVOID_DEFAULT,
CFG_ENABLE_CH_AVOID_MIN,
CFG_ENABLE_CH_AVOID_MAX ),
+
+ REG_VARIABLE(CFG_MAX_CONCURRENT_CONNECTIONS_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, gMaxConcurrentActiveSessions,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MAX_CONCURRENT_CONNECTIONS_DEFAULT,
+ CFG_MAX_CONCURRENT_CONNECTIONS_MIN,
+ CFG_MAX_CONCURRENT_CONNECTIONS_MAX ),
};
/*
@@ -3457,6 +3464,7 @@
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdTriggerThreshold] Value = [%u]",pHddCtx->cfg_ini->gAsdTriggerThreshold);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdRTTRssiHystThreshold]Value = [%u]",pHddCtx->cfg_ini->gAsdRTTRssiHystThreshold);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gRoamtoDFSChannel] Value = [%u] ",pHddCtx->cfg_ini->allowDFSChannelRoam);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gMaxConcurrentActiveSessions] Value = [%u] ", pHddCtx->cfg_ini->gMaxConcurrentActiveSessions);
}
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index de5bc84..4ad62e6 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -5721,6 +5721,11 @@
return 0;
}
+ if (vos_max_concurrent_connections_reached()) {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
+ return -EINVAL;
+ }
+
pConfig->persona = pHostapdAdapter->device_mode;
pSapEventCallback = hdd_hostapd_SAPEventCB;
@@ -5745,6 +5750,7 @@
}
set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
+ wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
#ifdef WLAN_FEATURE_P2P_DEBUG
if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
@@ -5798,6 +5804,11 @@
return status;
}
+ if (vos_max_concurrent_connections_reached()) {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
+ return -EINVAL;
+ }
+
if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
|| (pAdapter->device_mode == WLAN_HDD_P2P_GO)
)
@@ -6004,6 +6015,8 @@
}
}
clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
+ /* BSS stopped, clear the active sessions for this device mode */
+ wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
}
mutex_unlock(&pHddCtx->sap_lock);
@@ -6312,6 +6325,10 @@
__func__, hdd_device_modetoString(pAdapter->device_mode),
pAdapter->device_mode);
+ if (vos_max_concurrent_connections_reached()) {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
+ return -EINVAL;
+ }
pConfig = pHddCtx->cfg_ini;
wdev = ndev->ieee80211_ptr;
@@ -6676,7 +6693,7 @@
#ifdef WLAN_BTAMP_FEATURE
if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
- (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
+ (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
{
//we are ok to do AMP
pHddCtx->isAmpAllowed = VOS_TRUE;
@@ -10109,9 +10126,8 @@
}
/*
- * FUNCTION: __wlan_hdd_cfg80211_set_privacy
- * This function is used to initialize the security
- * parameters during connect operation.
+ * FUNCTION: __wlan_hdd_cfg80211_connect
+ * This function is used to start the association process
*/
static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
struct net_device *ndev,
@@ -10138,7 +10154,7 @@
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: HDD context is null", __func__);
- return VOS_STATUS_E_FAILURE;
+ return -EINVAL;
}
status = wlan_hdd_validate_context(pHddCtx);
@@ -10150,6 +10166,11 @@
return status;
}
+ if (vos_max_concurrent_connections_reached()) {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
+ return -ECONNREFUSED;
+ }
+
#ifdef WLAN_BTAMP_FEATURE
//Infra connect not supported when AMP traffic is on.
if( VOS_TRUE == WLANBAP_AmpSessionOn() )
@@ -10163,9 +10184,9 @@
//If Device Mode is Station Concurrent Sessions Exit BMps
//P2P Mode will be taken care in Open/close adapter
if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
- (vos_concurrent_sessions_running()))
- {
- exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
+ (vos_concurrent_open_sessions_running())) {
+ exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
+ WLAN_HDD_INFRA_STATION);
}
/*Try disconnecting if already in connected state*/
@@ -10212,8 +10233,7 @@
//ReEnable Bmps and Imps back
hdd_enable_bmps_imps(pHddCtx);
}
-
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
return status;
}
pHddCtx->isAmpAllowed = VOS_FALSE;
@@ -10571,6 +10591,11 @@
return -EIO;
}
+ if (vos_max_concurrent_connections_reached()) {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
+ return -ECONNREFUSED;
+ }
+
/*Try disconnecting if already in connected state*/
status = wlan_hdd_try_disconnect(pAdapter);
if ( 0 > status)
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index ee79d45..60567dc 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -478,8 +478,8 @@
ENTER();
-#ifdef DISABLE_CONCURRENCY_AUTOSAVE
- if (vos_concurrent_sessions_running())
+#ifdef DISABLE_CONCURRENCY_AUTOSAVE
+ if (vos_concurrent_open_sessions_running())
{
/*
This timer routine is going to be called only when AP
@@ -571,9 +571,19 @@
static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
{
struct net_device *dev;
+ hdd_context_t *pHddCtx = NULL;
VOS_STATUS status = VOS_STATUS_SUCCESS;
dev = (struct net_device *)usrDataForCallback;
ENTER();
+
+ pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
+ status = wlan_hdd_validate_context(pHddCtx);
+
+ if (0 != status) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
+ return status;
+ }
+
if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
{
if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
@@ -581,6 +591,7 @@
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
}
clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
+ wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
}
EXIT();
return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
@@ -2900,7 +2911,18 @@
{
hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
VOS_STATUS status = VOS_STATUS_SUCCESS;
+ hdd_context_t *pHddCtx = NULL;
+
ENTER();
+
+ pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
+ status = wlan_hdd_validate_context(pHddCtx);
+
+ if (0 != status) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
+ return status;
+ }
+
if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
{
if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
@@ -2917,6 +2939,7 @@
}
}
clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
+ wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode);
}
EXIT();
return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 5aed533..d919ca1 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -6549,9 +6549,9 @@
/* If there is a single session of STA/P2P client, re-enable BMPS */
- if ((!vos_concurrent_sessions_running()) &&
- ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
- (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
+ if ((!vos_concurrent_open_sessions_running()) &&
+ ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
+ (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
{
if (pHddCtx->hdd_wlan_suspended)
{
@@ -6804,6 +6804,7 @@
hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
}
clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
+ wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
if (eHAL_STATUS_FAILURE ==
ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
@@ -9753,14 +9754,15 @@
case VOS_P2P_GO_MODE:
case VOS_STA_SAP_MODE:
pHddCtx->concurrency_mode |= (1 << mode);
- pHddCtx->no_of_sessions[mode]++;
+ pHddCtx->no_of_open_sessions[mode]++;
break;
default:
break;
-
}
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
- __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
+ "Number of open sessions for mode %d = %d"),
+ pHddCtx->concurrency_mode, mode,
+ pHddCtx->no_of_open_sessions[mode]);
}
@@ -9772,15 +9774,82 @@
case VOS_P2P_CLIENT_MODE:
case VOS_P2P_GO_MODE:
case VOS_STA_SAP_MODE:
- pHddCtx->no_of_sessions[mode]--;
- if (!(pHddCtx->no_of_sessions[mode]))
- pHddCtx->concurrency_mode &= (~(1 << mode));
+ pHddCtx->no_of_open_sessions[mode]--;
+ if (!(pHddCtx->no_of_open_sessions[mode]))
+ pHddCtx->concurrency_mode &= (~(1 << mode));
break;
default:
break;
}
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
- __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
+ "Number of open sessions for mode %d = %d"),
+ pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
+
+}
+/**---------------------------------------------------------------------------
+ *
+ * \brief wlan_hdd_incr_active_session()
+ *
+ * This function increments the number of active sessions
+ * maintained per device mode
+ * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
+ * Incase of SAP/P2P GO upon bss start it is incremented
+ *
+ * \param pHddCtx - HDD Context
+ * \param mode - device mode
+ *
+ * \return - None
+ *
+ * --------------------------------------------------------------------------*/
+void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
+{
+ switch (mode) {
+ case VOS_STA_MODE:
+ case VOS_P2P_CLIENT_MODE:
+ case VOS_P2P_GO_MODE:
+ case VOS_STA_SAP_MODE:
+ pHddCtx->no_of_active_sessions[mode]++;
+ break;
+ default:
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
+ break;
+ }
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
+ mode,
+ pHddCtx->no_of_active_sessions[mode]);
+}
+
+/**---------------------------------------------------------------------------
+ *
+ * \brief wlan_hdd_decr_active_session()
+ *
+ * This function decrements the number of active sessions
+ * maintained per device mode
+ * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
+ * Incase of SAP/P2P GO upon bss stop it is decremented
+ *
+ * \param pHddCtx - HDD Context
+ * \param mode - device mode
+ *
+ * \return - None
+ *
+ * --------------------------------------------------------------------------*/
+void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
+{
+ switch (mode) {
+ case VOS_STA_MODE:
+ case VOS_P2P_CLIENT_MODE:
+ case VOS_P2P_GO_MODE:
+ case VOS_STA_SAP_MODE:
+ pHddCtx->no_of_active_sessions[mode]--;
+ break;
+ default:
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
+ break;
+ }
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
+ mode,
+ pHddCtx->no_of_active_sessions[mode]);
}
/**---------------------------------------------------------------------------