wlan: Host changes to support different BI for MCC

When P2P interface is already up, STA is not able to associate to AP MCC
scenario

Change-Id: Idc75f198438b5cf3b96a8a27cbbdcb6121197cf5
CR-Fixed: 412554
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 2dfdca5..507eb6e 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -1343,10 +1343,17 @@
  * Allow GO in MCC mode to accept different beacon interval than STA's.
  * Added for Wi-Fi Cert. 5.1.12
  * Default: Disable
+ * If gAllowMCCGODiffBI = 1  // Set to 1 for WFA certification. GO Beacon interval is not changed. MCC GO 
+*                                             doesn't work well in optimized way. In worst scenario, it may invite STA 
+*                                            disconnection.
+ * gAllowMCCGODiffBI = 2     //If set to 2 workaround 1 disassoc all the clients 
+ *                             and update beacon Interval
+ * gAllowMCCGODiffBI = 3     //If set to 3 tear down the P2P link in auto/ 
+ *                             Non-autonomous -GO case
  */
 #define CFG_ALLOW_MCC_GO_DIFF_BI_NAME           "gAllowMCCGODiffBI"
 #define CFG_ALLOW_MCC_GO_DIFF_BI_MIN            ( 0 )
-#define CFG_ALLOW_MCC_GO_DIFF_BI_MAX            ( 1 )
+#define CFG_ALLOW_MCC_GO_DIFF_BI_MAX            ( 3 )
 #define CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT        ( 0 ) 
 
 /*
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 87e3624..e8014ca 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -1596,9 +1596,9 @@
              VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, 
              CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT, 
              CFG_ALLOW_MCC_GO_DIFF_BI_MIN, 
-             CFG_ALLOW_MCC_GO_DIFF_BI_MAX ),             
+             CFG_ALLOW_MCC_GO_DIFF_BI_MAX ),
 
- REG_VARIABLE( CFG_THERMAL_MIGRATION_ENABLE_NAME, WLAN_PARAM_Integer,
+REG_VARIABLE( CFG_THERMAL_MIGRATION_ENABLE_NAME, WLAN_PARAM_Integer,
               hdd_config_t, thermalMitigationEnable, 
               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, 
               CFG_THERMAL_MIGRATION_ENABLE_DEFAULT, 
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 75f0d53..9d08a5a 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -341,6 +341,76 @@
     EXIT();
 }
 
+VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
+{
+    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
+    ptSapContext  pSapCtx = NULL;
+    eHalStatus halStatus = eHAL_STATUS_FAILURE;
+    v_PVOID_t hHal = NULL;
+
+    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+               "%s: UPDATE Beacon Params", __func__);
+
+    if(VOS_STA_SAP_MODE == vos_get_conparam ( )){
+        pSapCtx = VOS_GET_SAP_CB(pVosContext);
+        if ( NULL == pSapCtx )
+        {
+            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+                       "%s: Invalid SAP pointer from pvosGCtx", __func__);
+            return VOS_STATUS_E_FAULT;
+        }
+
+        hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx);
+        if ( NULL == hHal ){
+            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+                       "%s: Invalid HAL pointer from pvosGCtx", __func__);
+            return VOS_STATUS_E_FAULT;
+        }
+        halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId);
+        if(halStatus == eHAL_STATUS_FAILURE ){
+            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+                       "%s: Failed to update Beacon Params", __func__);
+            return VOS_STATUS_E_FAILURE;
+        }
+    }
+    return VOS_STATUS_SUCCESS;
+}
+
+void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback)
+{
+    v_U8_t staId = 0;
+    struct net_device *dev;
+    dev = (struct net_device *)usrDataForCallback;
+
+    hddLog(LOGE, FL("Clearing all the STA entry....\n"));
+    for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
+    {
+        if ( pHostapdAdapter->aStaInfo[staId].isUsed && 
+           ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId))
+        {
+            //Disconnect all the stations
+            hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
+        }
+    }
+}
+
+static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback)
+{
+    struct net_device *dev;
+    VOS_STATUS status = VOS_STATUS_SUCCESS;
+    dev = (struct net_device *)usrDataForCallback;
+    ENTER();
+    if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) 
+    {
+        if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) )
+        {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!"));
+        }
+        clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
+    }
+    EXIT();
+    return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
+}
 
 VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
 {
@@ -627,6 +697,8 @@
                             GFP_KERNEL);
 #endif
 #endif
+            //Update the beacon Interval if it is P2P GO
+            hdd_change_mcc_go_beacon_interval(pHostapdAdapter);
             break;
         case eSAP_WPS_PBC_PROBE_REQ_EVENT:
         {
@@ -714,6 +786,16 @@
             break;
         case eSAP_STA_ASSOC_IND:
             return VOS_STATUS_SUCCESS;
+
+        case eSAP_DISCONNECT_ALL_P2P_CLIENT:
+            hddLog(LOG1, FL(" Disconnecting all the P2P Clients....\n"));
+            hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
+            return VOS_STATUS_SUCCESS;
+
+        case eSAP_MAC_TRIG_STOP_BSS_EVENT :
+            hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
+            return VOS_STATUS_SUCCESS;
+
         default:
             hddLog(LOG1,"SAP message is not handled\n");
             goto stopbss;
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index decfe98..55c9ae4 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -3684,6 +3684,16 @@
     tANI_U8        ssidHidden;     // Hide SSID
 } tSirUpdateParams, *tpSirUpdateParams;
 
+//Beacon Interval
+typedef struct sSirChangeBIParams
+{
+    tANI_U16       messageType;     
+    tANI_U16       length;
+    tANI_U16       beaconInterval; // Beacon Interval
+    tSirMacAddr    bssId;
+    tANI_U8        sessionId;      // Session ID
+} tSirChangeBIParams, *tpSirChangeBIParams;
+
 #define SIR_WPS_UUID_LEN 16
 #define SIR_WPS_PBC_WALK_TIME   120  // 120 Second
 
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 9ef410d..8ebe5d0 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -219,6 +219,7 @@
     eWNI_SME_SET_APWPARSNIEs_REQ,
     eWNI_SME_UPPER_LAYER_ASSOC_CNF,
     eWNI_SME_HIDE_SSID_REQ,
+    eWNI_SME_CHNG_MCC_BEACON_INTERVAL,
 #endif
 #ifdef WLAN_FEATURE_P2P
     eWNI_SME_REMAIN_ON_CHANNEL_REQ,
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index da5ea6a..56fa94b 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1369,6 +1369,7 @@
         case eWNI_SME_HIDE_SSID_REQ:
         case eWNI_SME_GET_WPSPBC_SESSION_REQ:
         case eWNI_SME_SET_APWPARSNIEs_REQ:
+        case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
 #endif
 #if defined WLAN_FEATURE_VOWIFI
         case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 20401df..1fa471e 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -4436,6 +4436,62 @@
     return;
 } /*** end __limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/
 
+/*
+Update the beacon Interval dynamically if beaconInterval is different in MCC 
+*/
+static void
+__limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tpSirChangeBIParams     pChangeBIParams;
+    tpPESession             psessionEntry;
+    tANI_U8  sessionId = 0;
+    tUpdateBeaconParams beaconParams;
+
+    PELOG1(limLog(pMac, LOG1,
+           FL("received Update Beacon Interval message\n")););
+    
+    if(pMsgBuf == NULL)
+    {
+        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+        return;
+    }
+
+    pChangeBIParams = (tpSirChangeBIParams)pMsgBuf;
+
+    if((psessionEntry = peFindSessionByBssid(pMac, pChangeBIParams->bssId, &sessionId)) == NULL)
+    {
+        limLog(pMac, LOGE, FL("Session does not exist for given BSSID\n"));
+        return;
+    }
+
+    /*Update sessionEntry Beacon Interval*/
+    if(psessionEntry->beaconParams.beaconInterval != 
+                                        pChangeBIParams->beaconInterval )
+    {
+       psessionEntry->beaconParams.beaconInterval = pChangeBIParams->beaconInterval;
+    }
+
+    /*Update sch beaconInterval*/
+    if(pMac->sch.schObject.gSchBeaconInterval != 
+                                        pChangeBIParams->beaconInterval )
+    {
+        pMac->sch.schObject.gSchBeaconInterval = pChangeBIParams->beaconInterval;
+
+        PELOG1(limLog(pMac, LOG1,
+               FL("LIM send update BeaconInterval Indication : %d"),pChangeBIParams->beaconInterval););
+
+        /* Update beacon */
+        schSetFixedBeaconFields(pMac, psessionEntry);
+
+        //Set change in beacon Interval
+        beaconParams.beaconInterval = pChangeBIParams->beaconInterval;
+        beaconParams.paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED;
+        limSendBeaconParams(pMac, &beaconParams, psessionEntry);
+    }
+
+    return;
+} /*** end __limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/
+
 #endif
 
 
@@ -4989,6 +5045,11 @@
         case eWNI_SME_SET_APWPARSNIEs_REQ:
               __limProcessSmeSetWPARSNIEs(pMac, pMsgBuf);        
               break;
+
+        case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
+             //Update the beaconInterval
+             __limProcessSmeChangeBI(pMac, pMsgBuf );
+             break;
 #endif            
             
 #if defined WLAN_FEATURE_VOWIFI 
diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h
index 56f33b5..0eb9cbb 100644
--- a/CORE/SAP/inc/sapApi.h
+++ b/CORE/SAP/inc/sapApi.h
@@ -190,6 +190,8 @@
     eSAP_INDICATE_MGMT_FRAME,
     eSAP_REMAIN_CHAN_READY,
     eSAP_SEND_ACTION_CNF,
+    eSAP_DISCONNECT_ALL_P2P_CLIENT,
+    eSAP_MAC_TRIG_STOP_BSS_EVENT,
 #endif
     eSAP_UNKNOWN_STA_JOIN, /* Event send when a STA in neither white list or black list tries to associate in softap mode */
     eSAP_MAX_ASSOC_EXCEEDED, /* Event send when a new STA is rejected association since softAP max assoc limit has reached */
diff --git a/CORE/SAP/src/sapApiLinkCntl.c b/CORE/SAP/src/sapApiLinkCntl.c
index 26d879b..13ec941 100644
--- a/CORE/SAP/src/sapApiLinkCntl.c
+++ b/CORE/SAP/src/sapApiLinkCntl.c
@@ -382,6 +382,19 @@
                             (v_PVOID_t)(( roamResult == eCSR_ROAM_RESULT_NONE) ?
                             eSAP_STATUS_SUCCESS : eSAP_STATUS_FAILURE));
             break;
+
+       case eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS:
+            sapSignalHDDevent(sapContext, pCsrRoamInfo, 
+                            eSAP_DISCONNECT_ALL_P2P_CLIENT, 
+                            (v_PVOID_t) eSAP_STATUS_SUCCESS );
+            break;
+            
+       case eCSR_ROAM_SEND_P2P_STOP_BSS:
+           VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Received stopbss", __func__);
+           sapSignalHDDevent(sapContext, pCsrRoamInfo, 
+                            eSAP_MAC_TRIG_STOP_BSS_EVENT, 
+                            (v_PVOID_t) eSAP_STATUS_SUCCESS );
+        break;
 #endif
 
         default:
diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c
index 0d937a0..9cbffce 100644
--- a/CORE/SAP/src/sapFsm.c
+++ b/CORE/SAP/src/sapFsm.c
@@ -670,6 +670,23 @@
             sapApAppEvent.sapHddEventCode = eSAP_SEND_ACTION_CNF;
             sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context;
             break;
+
+       case eSAP_DISCONNECT_ALL_P2P_CLIENT:
+            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+                             "In %s, SAP event callback event = %s",
+                            __func__, "eSAP_DISCONNECT_ALL_P2P_CLIENT");
+            sapApAppEvent.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
+            sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context;
+            break;
+
+       case eSAP_MAC_TRIG_STOP_BSS_EVENT :
+            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+                             "In %s, SAP event callback event = %s",
+                            __func__, "eSAP_MAC_TRIG_STOP_BSS_EVENT");
+            sapApAppEvent.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
+            sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context;
+            break;
+
 #endif
 
         case eSAP_UNKNOWN_STA_JOIN:
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 735817f..f6fdf3b 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -418,6 +418,10 @@
 #ifdef FEATURE_WLAN_LFR
     eCSR_ROAM_PMK_NOTIFY,
 #endif
+    eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, //Disaconnect all the clients
+    eCSR_ROAM_SEND_P2P_STOP_BSS, //Stopbss triggered from SME due to different 
+                                 // beacon interval
+
 }eRoamCmdStatus;
 
 
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 559318b..e33225b 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -345,6 +345,8 @@
     tVOS_CON_MODE       bssPersona;
     tANI_U16            nRSNIELength;  //The byte count in the pRSNIE, if 0, pRSNIE is ignored.
     tANI_U8             *pRSNIE;     //If not null, it has the IE byte stream for RSN
+    tANI_BOOLEAN        updatebeaconInterval; //Flag used to indicate update 
+                                             // beaconInterval 
 }tCsrRoamStartBssParams;
 
 
@@ -495,8 +497,8 @@
     tANI_BOOLEAN shortSlotTime;
     tANI_BOOLEAN ProprietaryRatesEnabled;
     tANI_BOOLEAN  fenableMCCMode;
-    tANI_BOOLEAN  fAllowMCCGODiffBI;
     tANI_U16 TxRate;
+    tANI_U8  fAllowMCCGODiffBI;
     tANI_U8 AdHocChannel24;
     tANI_U8 AdHocChannel5G;
     tANI_U32 impsSleepTime;     //in units of microseconds
diff --git a/CORE/SME/inc/csrSupport.h b/CORE/SME/inc/csrSupport.h
index e4fa512..139e549 100644
--- a/CORE/SME/inc/csrSupport.h
+++ b/CORE/SME/inc/csrSupport.h
@@ -803,8 +803,11 @@
 csrIsconcurrentsessionValid(tpAniSirGlobal pMac,tANI_U32 cursessionId,
                                  tVOS_CON_MODE currBssPersona);
 
-//BeaconInterval valiadation for MCC support
-eHalStatus csrValidateBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, 
+//Update beaconInterval for P2P-GO case if it is different 
+eHalStatus csrUpdatep2pBeaconInterval(tpAniSirGlobal pMac);
+
+//BeaconInterval validation for MCC support
+eHalStatus csrValidateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, 
                                      tANI_U16 *beaconInterval, tANI_U32 cursessionId,
                                      tVOS_CON_MODE currBssPersona);
 
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 4ccd8b5..37f9900 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -1595,9 +1595,9 @@
 
     \param pAPWPSIES - pointer to a caller allocated object of tCsrRoamAPWPSIES
 
-    \return eHalStatus – SUCCESS – Roam callback will be called indicate actually results
+    \return eHalStatus – SUCCESS – Roam callback will be called indicate actually results
 
-                         FAILURE or RESOURCES – The API finished and failed.
+                         FAILURE or RESOURCES – The API finished and failed.
 
   -------------------------------------------------------------------------------*/
 
@@ -1611,13 +1611,26 @@
 
     \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs
 
-    \return eHalStatus – SUCCESS – 
+    \return eHalStatus – SUCCESS – 
 
-                         FAILURE or RESOURCES – The API finished and failed.
+                         FAILURE or RESOURCES – The API finished and failed.
 
   -------------------------------------------------------------------------------*/
 eHalStatus sme_RoamUpdateAPWPARSNIEs(tHalHandle hHal, tANI_U8 sessionId, tSirRSNie * pAPSirRSNie);
 
+/* ---------------------------------------------------------------------------
+
+    sme_ChangeMCCBeaconInterval
+
+    \brief To update P2P-GO's beacon Interval. 
+
+    \return eHalStatus – SUCCESS 
+                       – FAILURE or RESOURCES 
+                       – The API finished and failed.
+  -------------------------------------------------------------------------------*/
+eHalStatus sme_ChangeMCCBeaconInterval(tHalHandle hHal, tANI_U8 sessionId);
+
+
 #endif
 
 /* ---------------------------------------------------------------------------
@@ -1625,9 +1638,8 @@
   \brief API to send the btAMPstate to FW
   \param  hHal - The handle returned by macOpen.
   \param  btAmpEvent -- btAMP event
-  \return eHalStatus – SUCCESS –
-
-                         FAILURE or RESOURCES – The API finished and failed.
+  \return eHalStatus – SUCCESS –
+                         FAILURE or RESOURCES – The API finished and failed.
 
 --------------------------------------------------------------------------- */
 
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index d8778f2..91f20ef 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -12073,6 +12073,49 @@
     } while( 0 );
     return( status );
 }
+
+eHalStatus
+csrSendChngMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U32 sessionId)
+{
+    tpSirChangeBIParams pMsg;
+    tANI_U16 len = 0;
+    eHalStatus status   = eHAL_STATUS_SUCCESS;
+    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
+
+    if(!pSession)
+    {
+        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
+        return eHAL_STATUS_FAILURE;
+    }
+
+    //NO need to update the Beacon Params if update beacon parameter flag is not set
+    if(!pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval )
+        return eHAL_STATUS_SUCCESS;
+
+    pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval =  eANI_BOOLEAN_FALSE;
+
+     /* Create the message and send to lim */
+     len = sizeof(tSirChangeBIParams); 
+     status = palAllocateMemory( pMac->hHdd, (void **)&pMsg, len );
+     if(HAL_STATUS_SUCCESS(status))
+     {
+         palZeroMemory(pMac->hHdd, pMsg, sizeof(tSirChangeBIParams) );
+         pMsg->messageType     = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
+         pMsg->length          = len;
+
+        // bssId
+        palCopyMemory( pMac->hHdd, (tSirMacAddr *)pMsg->bssId, &pSession->selfMacAddr, sizeof(tSirMacAddr) );
+        smsLog( pMac, LOG1, FL("CSR Attempting to change BI for Bssid= %02x-%02x-%02x-%02x-%02x-%02x "), 
+                  pMsg->bssId[ 0 ], pMsg->bssId[ 1 ], pMsg->bssId[ 2 ],
+                  pMsg->bssId[ 3 ], pMsg->bssId[ 4 ], pMsg->bssId[ 5 ] );
+        pMsg->sessionId       = sessionId;
+        smsLog(pMac, LOG1, FL("  session %d BeaconInterval %d\n"), sessionId, pMac->roam.roamSession[sessionId].bssParams.beaconInterval);
+        pMsg->beaconInterval = pMac->roam.roamSession[sessionId].bssParams.beaconInterval; 
+        status = palSendMBMessage(pMac->hHdd, pMsg);
+    }
+     return status;
+}
+
 #endif
 eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode )
 {
@@ -12465,7 +12508,7 @@
                                    pParam->bssPersona) 
                                    == eHAL_STATUS_SUCCESS )
         {    
-           csrValidateBeaconInterval(pMac, pParam->operationChn, &wTmp, sessionId,
+           csrValidateMCCBeaconInterval(pMac, pParam->operationChn, &wTmp, sessionId,
                                       pParam->bssPersona);
            //Update the beacon Interval 
            pParam->beaconInterval = wTmp;
diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h
index 682c969..5864512 100644
--- a/CORE/SME/src/csr/csrInsideApi.h
+++ b/CORE/SME/src/csr/csrInsideApi.h
@@ -903,7 +903,16 @@
                                         
 eHalStatus csrSendMBGetWPSPBCSessions( tpAniSirGlobal pMac, tANI_U32 sessionId,
                             tSirMacAddr bssId, void *pUsrContext, void *pfnSapEventCallback,v_MACADDR_t pRemoveMac);
-                            
+
+/* ---------------------------------------------------------------------------
+    \fn csrSendChngMCCBeaconInterval
+    \brief csr function that HDD calls to send Update beacon interval
+    \param sessionId - session Id for Soft AP
+    \return eHalStatus
+  ---------------------------------------------------------------------------*/
+eHalStatus
+csrSendChngMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U32 sessionId);
+
 #endif
 #ifdef FEATURE_WLAN_BTAMP_UT_RF
 eHalStatus csrRoamStartJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval);
diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c
index a3365c9..77e468f 100644
--- a/CORE/SME/src/csr/csrUtil.c
+++ b/CORE/SME/src/csr/csrUtil.c
@@ -1712,7 +1712,7 @@
                                        pSession->pCurRoamProfile->csrPersona) 
                                        == eHAL_STATUS_SUCCESS )
             {
-                if(csrValidateBeaconInterval( pMac, pBssDesc->channelId, 
+                if(csrValidateMCCBeaconInterval( pMac, pBssDesc->channelId, 
                                &pBssDesc->beaconInterval, sessionId, 
                                pSession->pCurRoamProfile->csrPersona) 
                                != eHAL_STATUS_SUCCESS)
@@ -2783,14 +2783,86 @@
 
 }
 
-eHalStatus csrValidateBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, 
-                                     tANI_U16 *beaconInterval, tANI_U32 cursessionId,
-                                     tVOS_CON_MODE currBssPersona)
+eHalStatus csrUpdateMCCp2pBeaconInterval(tpAniSirGlobal pMac)
 {
     tANI_U32 sessionId = 0;
 
     //If MCC is not supported just break and return SUCCESS
-    if ( !IS_MCC_SUPPORTED && !pMac->roam.configParam.fenableMCCMode){
+    if ( !pMac->roam.configParam.fenableMCCMode){
+        return eHAL_STATUS_FAILURE;
+    }
+
+    for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
+    {
+        /* If GO in MCC support different beacon interval, 
+         * change the BI of the P2P-GO */
+        if((pMac->roam.roamSession[sessionId].bssParams.bssPersona
+                              == VOS_P2P_GO_MODE) &&
+           (pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval ))
+        {
+            return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, eCSR_ROAM_RESULT_NONE);
+        }
+    }
+    return eHAL_STATUS_FAILURE;
+}
+
+tANI_U16 csrCalculateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U16 sta_bi, tANI_U16 go_gbi)
+{
+    tANI_U8 num_beacons = 0;
+    tANI_U8 is_multiple = 0;
+    tANI_U16 go_cbi = 0;
+    tANI_U16 go_fbi = 0;
+    tANI_U16 sta_cbi = 0;
+
+    //If GO's given beacon Interval is less than 100 
+    if(go_gbi < 100)
+       go_cbi = 100;
+    //if GO's given beacon Interval is greater than or equal to 100
+    else
+       go_cbi = 100 + (go_gbi % 100);
+
+    // check, if either one is multiple of another
+    if (sta_bi > go_cbi)
+    {
+        is_multiple = !(sta_bi % go_cbi);
+    }
+    else
+    {
+        is_multiple = !(go_cbi % sta_bi);
+    }
+    // if it is multiple, then accept GO’s beacon interval range [100,199] as it  is
+    if(is_multiple)
+    {
+        return go_cbi;
+    }
+    //else , if it is not multiple, then then check for number of beacons to be 
+    //inserted based on sta BI
+    num_beacons = sta_bi / 100;
+    if(num_beacons)
+    { 
+        // GO’s final beacon interval will be aligned to sta beacon interval, but 
+        //in the range of [100, 199].
+        sta_cbi = sta_bi / num_beacons;
+        go_fbi = sta_cbi;
+    }
+    else
+    {
+        // if STA beacon interval is less than 100, use GO’s change bacon interval 
+        //instead of updating to STA’s beacon interval.
+        go_fbi = go_cbi;
+    }
+    return go_fbi;
+}
+
+eHalStatus csrValidateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, 
+                                     tANI_U16 *beaconInterval, tANI_U32 cursessionId,
+                                     tVOS_CON_MODE currBssPersona)
+{
+    tANI_U32 sessionId = 0;
+    tANI_U16 new_beaconInterval = 0;
+  
+    //If MCC is not supported just break
+    if (!pMac->roam.configParam.fenableMCCMode){
         return eHAL_STATUS_FAILURE;
     }
 
@@ -2827,17 +2899,47 @@
                     else if(pMac->roam.roamSession[sessionId].bssParams.bssPersona
                                       == VOS_P2P_GO_MODE) //Check for P2P go scenario
                     {
-                        /* if GO in MCC support different beacon interval, return success */
-                        if ( pMac->roam.configParam.fAllowMCCGODiffBI == TRUE)
-                            return eHAL_STATUS_SUCCESS;
-                        
-                        if ((pMac->roam.roamSession[sessionId].bssParams.operationChn 
+                        /* if GO in MCC support different beacon interval, 
+                         * change the BI of the P2P-GO */
+                       if ((pMac->roam.roamSession[sessionId].bssParams.operationChn 
                                 != channelId ) &&
-                            (pMac->roam.roamSession[sessionId].bssParams.beaconInterval 
+                           (pMac->roam.roamSession[sessionId].bssParams.beaconInterval 
                                 != *beaconInterval))
-                        {
-                            smsLog(pMac, LOGE, FL("BeaconInteval is different cannot connect to prefered AP...\n"));
-                            return eHAL_STATUS_FAILURE;
+                       {
+                           /* if GO in MCC support different beacon interval, return success */
+                           if ( pMac->roam.configParam.fAllowMCCGODiffBI == 0x01)
+                           {
+                               return eHAL_STATUS_SUCCESS;
+                           }
+                           // Send only Broadcast disassoc and update beaconInterval
+                           else if(pMac->roam.configParam.fAllowMCCGODiffBI == 0x02)
+                           {
+                               //Check to pass the right beacon Interval
+                               new_beaconInterval = csrCalculateMCCBeaconInterval(pMac, *beaconInterval, 
+                                                         pMac->roam.roamSession[sessionId].bssParams.beaconInterval);
+                               smsLog(pMac, LOG1, FL(" Peer AP BI : %d, new Beacon Interval: %d\n"),*beaconInterval,new_beaconInterval );
+                               //Update the becon Interval
+                               if(*beaconInterval != new_beaconInterval )
+                               {
+                                   //Update the beaconInterval now
+                                   smsLog(pMac, LOG1, FL(" Beacon Interval got changed\n"));
+                                   pMac->roam.roamSession[sessionId].bssParams.beaconInterval = new_beaconInterval;
+                                   pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_TRUE;
+                                   csrUpdateMCCp2pBeaconInterval(pMac);
+                               }
+                               return eHAL_STATUS_SUCCESS;
+                           }
+                           //Disconnect the P2P session
+                           else if(pMac->roam.configParam.fAllowMCCGODiffBI == 0x03)
+                           {
+                               pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval =  eANI_BOOLEAN_FALSE;
+                               return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SEND_P2P_STOP_BSS, eCSR_ROAM_RESULT_NONE);
+                           }
+                           else
+                           {
+                               smsLog(pMac, LOGE, FL("BeaconInteval is different cannot connect to prefered AP...\n"));
+                               return eHAL_STATUS_FAILURE;
+                           }
                         }
                     }
                     break;
@@ -2876,10 +2978,11 @@
                     break;
 
                 case VOS_P2P_GO_MODE :
+                {
                     if(pMac->roam.roamSession[sessionId].pCurRoamProfile  && 
                       ((pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona 
-                            == VOS_P2P_CLIENT_MODE)
-                     || (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona 
+                            == VOS_P2P_CLIENT_MODE) ||
+                      (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona 
                             == VOS_STA_MODE))) //check for P2P_client scenario
                     {
                         if ((pMac->roam.roamSession[sessionId].connectedProfile.operationChannel 
@@ -2901,12 +3004,17 @@
                              * Updated beaconInterval should be used only when we are starting a new BSS 
                              * not incase of client or STA case
                              */
-                            *beaconInterval = 
-                                pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval;
+                            //Calculate beacon Interval for P2P-GO incase of MCC
+                            new_beaconInterval = csrCalculateMCCBeaconInterval(pMac, 
+                                                pMac->roam.roamSession[sessionId].bssParams.beaconInterval,
+                                                *beaconInterval );
+                            if(*beaconInterval != new_beaconInterval)
+                                *beaconInterval = new_beaconInterval;
                             return eHAL_STATUS_SUCCESS;
                          }
                     }
-                    break;
+                }
+                break;
 
                 default :
                     smsLog(pMac, LOG1, FL(" Persona not supported : %d\n"),currBssPersona);
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 961189f..16f8aff 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -5049,7 +5049,35 @@
    return (status);
 }
 #endif
+/* ---------------------------------------------------------------------------
 
+    \fn sme_ChangeMCCBeaconInterval
+
+    \brief To update P2P-GO beaconInterval. This function should be called after 
+    disassociating all the station is done 
+    This is an asynchronous API.
+
+    \param 
+
+    \return eHalStatus – SUCCESS 
+                       – FAILURE or RESOURCES 
+                       – The API finished and failed.
+
+  -------------------------------------------------------------------------------*/
+eHalStatus sme_ChangeMCCBeaconInterval(tHalHandle hHal, tANI_U8 sessionId)
+{
+   eHalStatus status = eHAL_STATUS_FAILURE;
+   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+
+   smsLog(pMac, LOG1, FL("Update Beacon PARAMS \n"));
+   status = sme_AcquireGlobalLock( &pMac->sme );
+   if ( HAL_STATUS_SUCCESS( status ) )
+   {
+      status = csrSendChngMCCBeaconInterval( pMac, sessionId);
+      sme_ReleaseGlobalLock( &pMac->sme );
+   }
+   return (status);
+}
 
 /*-------------------------------------------------------------------------------*