Wlan: Extended IBSS feature on prima

Changes to enable extended IBSS feature on prima open
source branch.

Change-Id: Iacaad2627d241fa6b71717d0cfbba960f0fd5d5f
CRs-Fixed: 766181
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h
index 3cad4c0..35930df 100644
--- a/CORE/HDD/inc/wlan_hdd_assoc.h
+++ b/CORE/HDD/inc/wlan_hdd_assoc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -42,6 +42,12 @@
 /* Timeout (in ms) for Link to Up before Registering Station */
 #define ASSOC_LINKUP_TIMEOUT 60
 #define IBSS_BROADCAST_STAID 0
+
+#ifdef WLAN_FEATURE_RMC
+/* Timeout in ms for peer info request commpletion */
+#define IBSS_PEER_INFO_REQ_TIMOEUT 1000
+#endif
+
 typedef enum 
 {
    /** Not associated in Infra or participating in an IBSS / Ad-hoc network.*/
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 3c2f719..abd5e67 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -1169,7 +1169,6 @@
  */
 #define QCA_NL80211_VENDOR_ID                0x001374
 
-
 #ifdef FEATURE_WLAN_CH_AVOID
 #define HDD_MAX_AVOID_FREQ_RANGES   15
 typedef struct sHddAvoidFreqRange
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 174822d..8060e44 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -663,6 +663,7 @@
     HDD_SSR_DISABLED,
 }e_hdd_ssr_required;
 
+#ifdef WLAN_FEATURE_RMC
 /*---------------------------------------------------------------------------
   hdd_ibss_peer_info_params_t
 ---------------------------------------------------------------------------*/
@@ -721,6 +722,7 @@
     /** Peer Info parameters */
     hdd_ibss_peer_info_params_t  ibssPeerList[HDD_MAX_NUM_IBSS_STA];
 }hdd_ibss_peer_info_t;
+#endif
 
 struct hdd_station_ctx
 {
@@ -749,8 +751,9 @@
 
    /*Save the wep/wpa-none keys*/
    tCsrRoamSetKey ibss_enc_key;
-
+#ifdef WLAN_FEATURE_RMC
    hdd_ibss_peer_info_t ibss_peer_info;
+#endif
 
    v_BOOL_t hdd_ReassocScenario;
 
@@ -1043,6 +1046,11 @@
    struct completion tdls_link_establish_req_comp;
    eHalStatus tdlsAddStaStatus;
 #endif
+
+#ifdef WLAN_FEATURE_RMC
+   struct completion ibss_peer_info_comp;
+#endif /* WLAN_FEATURE_RMC */
+
    /* Track whether the linkup handling is needed  */
    v_BOOL_t isLinkUpSvcNeeded;
 
@@ -1761,6 +1769,10 @@
 void hdd_ipv6_notifier_work_queue(struct work_struct *work);
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+v_MACADDR_t* hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter, v_U8_t staIdx);
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef CONFIG_ENABLE_LINUX_REG
 void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx);
 #endif
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 2bd0bff..5ae44ba 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -2127,6 +2127,11 @@
                       __func__, pAdapter->dev->name);
                return;
             }
+#ifdef WLAN_FEATURE_RMC
+            netif_carrier_on(pAdapter->dev);
+            hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
+            netif_tx_start_all_queues(pAdapter->dev);
+#endif
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
             chan_no = pRoamInfo->pBssDesc->channelId;
 
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index add3012..e29cd9f 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -15131,6 +15131,9 @@
     tCsrRoamProfile *pRoamProfile;
     hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
     int status;
+#ifdef WLAN_FEATURE_RMC
+    tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
+#endif
 
     ENTER();
 
@@ -15163,6 +15166,41 @@
         return -EINVAL;
     }
 
+#ifdef WLAN_FEATURE_RMC
+    /* Clearing add IE of beacon */
+    if (ccmCfgSetStr(pHddCtx->hHal,
+        WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
+        WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
+        NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
+    {
+        hddLog (VOS_TRACE_LEVEL_ERROR,
+                "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
+        return -EINVAL;
+    }
+    if (ccmCfgSetInt(pHddCtx->hHal,
+        WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
+        eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
+    {
+        hddLog (VOS_TRACE_LEVEL_ERROR,
+                "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
+                __func__);
+        return -EINVAL;
+    }
+
+    // Reset WNI_CFG_PROBE_RSP Flags
+    wlan_hdd_reset_prob_rspies(pAdapter);
+
+    if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
+                     WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
+                     eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
+    {
+        hddLog (VOS_TRACE_LEVEL_ERROR,
+                "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
+                __func__);
+        return -EINVAL;
+    }
+#endif
+
     /* Issue Disconnect request */
     INIT_COMPLETION(pAdapter->disconnect_comp_var);
     sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
@@ -18441,7 +18479,6 @@
     hddLog(VOS_TRACE_LEVEL_INFO,
            "tdls send discover req: "MAC_ADDRESS_STR,
            MAC_ADDR_ARRAY(peer));
-
 #if TDLS_MGMT_VERSION2
     return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
                             WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
old mode 100755
new mode 100644
index b406b41..91f7e5f
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -176,6 +176,15 @@
 #define SIZE_OF_SETROAMMODE             11    /* size of SETROAMMODE */
 #define SIZE_OF_GETROAMMODE             11    /* size of GETROAMMODE */
 
+#ifdef WLAN_FEATURE_RMC
+/*
+ * Ibss prop IE from command will be of size:
+ * size  = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
+ * OUI_DATA should be at least 3 bytes long
+ */
+#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
+#endif
+
 #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
 #define TID_MIN_VALUE 0
 #define TID_MAX_VALUE 15
@@ -191,6 +200,16 @@
 #define WLAN_MAX_BUF_SIZE 1024
 #define WLAN_PRIV_DATA_MAX_LEN    8192
 
+/*
+ * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
+ * we will split the printing.
+ */
+#define NUM_OF_STA_DATA_TO_PRINT 16
+
+#ifdef WLAN_FEATURE_RMC
+#define WLAN_NLINK_CESIUM 30
+#endif
+
 //wait time for beacon miss rate.
 #define BCN_MISS_RATE_TIME 500
 
@@ -203,6 +222,22 @@
 static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
 static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
 static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
+
+#ifdef WLAN_FEATURE_RMC
+static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
+
+static int hdd_open_cesium_nl_sock(void);
+static void hdd_close_cesium_nl_sock(void);
+static struct sock *cesium_nl_srv_sock;
+static v_U16_t cesium_pid;
+
+static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
+                                          tANI_U8 *tx_fail_count,
+                                          tANI_U16 *pid);
+
+static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
+
+#endif /* WLAN_FEATURE_RMC */
 void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
 void hdd_set_wlan_suspend_mode(bool suspend);
 
@@ -724,6 +759,486 @@
 
 }
 
+#ifdef WLAN_FEATURE_RMC
+static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
+{
+    tANI_U8 *inPtr = pValue;
+    int tempInt;
+    int v = 0;
+    char buf[32];
+    *pRmcEnable = 0;
+
+    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+    /*no argument after the command*/
+    if (NULL == inPtr)
+    {
+        return 0;
+    }
+
+    /*no space after the command*/
+    else if (SPACE_ASCII_VALUE != *inPtr)
+    {
+        return 0;
+    }
+
+    /*removing empty spaces*/
+    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;
+
+    /*no argument followed by spaces*/
+    if ('\0' == *inPtr)
+    {
+        return 0;
+    }
+
+    /* getting the first argument which enables or disables RMC
+         * for input IP v4 address*/
+    sscanf(inPtr, "%32s ", buf);
+    v = kstrtos32(buf, 10, &tempInt);
+    if ( v < 0)
+    {
+       return -EINVAL;
+    }
+
+    *pRmcEnable = tempInt;
+
+    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+       "ucRmcEnable: %d", *pRmcEnable);
+
+    return 0;
+}
+
+/* Function header left blank Intentionally */
+static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
+           tANI_U32 *pActionPeriod)
+{
+    tANI_U8 *inPtr = pValue;
+    int tempInt;
+    int v = 0;
+    char buf[32];
+    *pActionPeriod = 0;
+
+    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+    /*no argument after the command*/
+    if (NULL == inPtr)
+    {
+        return -EINVAL;
+    }
+
+    /*no space after the command*/
+    else if (SPACE_ASCII_VALUE != *inPtr)
+    {
+        return -EINVAL;
+    }
+
+    /*removing empty spaces*/
+    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;
+
+    /*no argument followed by spaces*/
+    if ('\0' == *inPtr)
+    {
+        return 0;
+    }
+
+    /* getting the first argument which enables or disables RMC
+         * for input IP v4 address*/
+    sscanf(inPtr, "%32s ", buf);
+    v = kstrtos32(buf, 10, &tempInt);
+    if ( v < 0)
+    {
+       return -EINVAL;
+    }
+
+    /* Range checking for passed paramter */
+    if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
+        tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
+    {
+       return -EINVAL;
+    }
+
+    *pActionPeriod = tempInt;
+
+    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+       "uActionPeriod: %d", *pActionPeriod);
+
+    return 0;
+}
+
+/* Function header left blank Intentionally */
+static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
+           tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
+{
+    tANI_U8 *inPtr = pValue;
+    int tempInt;
+    int v = 0;
+    char buf[32];
+    *pRate = 0;
+    *pTxFlags = 0;
+
+    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+    /*no argument after the command*/
+    if (NULL == inPtr)
+    {
+        return -EINVAL;
+    }
+
+    /*no space after the command*/
+    else if (SPACE_ASCII_VALUE != *inPtr)
+    {
+        return -EINVAL;
+    }
+
+    /*removing empty spaces*/
+    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr)) inPtr++;
+
+    /*no argument followed by spaces*/
+    if ('\0' == *inPtr)
+    {
+        return 0;
+    }
+
+    /*
+     * getting the first argument which sets multicast rate.
+     */
+    sscanf(inPtr, "%32s ", buf);
+    v = kstrtos32(buf, 10, &tempInt);
+    if ( v < 0)
+        {
+       return -EINVAL;
+        }
+
+    /*
+     * Validate the multicast rate.
+     */
+    switch (tempInt)
+        {
+        default:
+            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
+            "Unsupported rate: %d", tempInt);
+            return -EINVAL;
+        case 0:
+        case 6:
+        case 9:
+        case 12:
+        case 18:
+        case 24:
+        case 36:
+        case 48:
+        case 54:
+            *pTxFlags = eHAL_TX_RATE_LEGACY;
+            *pRate = tempInt * 10;
+            break;
+        case 65:
+            *pTxFlags = eHAL_TX_RATE_HT20;
+            *pRate = tempInt * 10;
+            break;
+        case 72:
+            *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
+            *pRate = 722; /* fractional rate 72.2 Mbps */
+            break;
+    }
+
+    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+       "Rate: %d", *pRate);
+
+    return 0;
+}
+
+/**---------------------------------------------------------------------------
+
+  \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
+  Peer Info request
+
+  This is an asynchronous callback function from SME when the peer info
+  is received
+
+  \pUserData -> Adapter private data
+  \pPeerInfoRsp -> Peer info response
+
+  \return - 0 for success non-zero for failure
+  --------------------------------------------------------------------------*/
+static void
+hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
+{
+   hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
+   tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
+   hdd_station_ctx_t *pStaCtx;
+   v_U8_t   i;
+
+   /*Sanity check*/
+   if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
+        {
+      hddLog(LOGE,
+         FL("invalid adapter or adapter has invalid magic"));
+      return;
+   }
+
+   pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+   if (NULL != pStaCtx && NULL != pPeerInfo &&
+       eHAL_STATUS_SUCCESS == pPeerInfo->status)
+   {
+      pStaCtx->ibss_peer_info.status = pPeerInfo->status;
+      pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
+
+      /* Paranoia check */
+      if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
+      {
+         for (i = 0; i < pPeerInfo->numPeers; i++)
+         {
+            memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
+                   &pPeerInfo->peerInfoParams[i],
+                   sizeof(hdd_ibss_peer_info_params_t));
+         }
+         hddLog(LOG1,
+            FL("Peer Info copied in HDD"));
+      }
+      else
+      {
+         hddLog(LOGE,
+               FL(" Number of peers %d returned is more than limit %d"),
+               pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
+      }
+   }
+   else
+   {
+      hddLog(LOG1,
+           FL("peerInfo returned is NULL"));
+   }
+
+   complete(&pAdapter->ibss_peer_info_comp);
+}
+
+/**---------------------------------------------------------------------------
+
+  \brief hdd_cfg80211_get_ibss_peer_info_all() -
+
+  Request function to get IBSS peer info from lower layers
+
+  \pAdapter -> Adapter context
+
+  \return - 0 for success non-zero for failure
+  --------------------------------------------------------------------------*/
+static
+VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
+{
+   tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
+   long status;
+   VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
+
+   INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
+
+   retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
+                                    hdd_cfg80211_get_ibss_peer_info_cb,
+                                    VOS_TRUE, 0xFF);
+
+   if (VOS_STATUS_SUCCESS == retStatus)
+   {
+      status = wait_for_completion_interruptible_timeout
+               (&pAdapter->ibss_peer_info_comp,
+                msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+
+      /* status will be 0 if timed out */
+      if (status <= 0)
+      {
+         hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
+                __func__, status);
+         retStatus = VOS_STATUS_E_FAILURE;
+         return retStatus;
+      }
+   }
+   else
+   {
+      hddLog(VOS_TRACE_LEVEL_WARN,
+             "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
+   }
+
+   return retStatus;
+}
+
+/**---------------------------------------------------------------------------
+
+  \brief hdd_cfg80211_get_ibss_peer_info() -
+
+  Request function to get IBSS peer info from lower layers
+
+  \pAdapter -> Adapter context
+  \staIdx -> Sta index for which the peer info is requested
+
+  \return - 0 for success non-zero for failure
+  --------------------------------------------------------------------------*/
+static VOS_STATUS
+hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
+{
+    long status;
+    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
+    VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
+
+    INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
+
+    retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
+                                     hdd_cfg80211_get_ibss_peer_info_cb,
+                                     VOS_FALSE, staIdx);
+
+    if (VOS_STATUS_SUCCESS == retStatus)
+    {
+       status = wait_for_completion_interruptible_timeout
+                (&pAdapter->ibss_peer_info_comp,
+                msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+
+       /* status = 0 on timeout */
+       if (status <= 0)
+       {
+          hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
+                  __func__, status);
+          retStatus = VOS_STATUS_E_FAILURE;
+          return retStatus;
+       }
+    }
+    else
+    {
+       hddLog(VOS_TRACE_LEVEL_WARN,
+              "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
+    }
+
+    return retStatus;
+}
+
+/* Function header left blank Intentionally */
+VOS_STATUS
+hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
+{
+    tANI_U8 *inPtr = pValue;
+    inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+
+    /*no argument after the command*/
+    if (NULL == inPtr)
+    {
+        return VOS_STATUS_E_FAILURE;;
+    }
+
+    /*no space after the command*/
+    else if (SPACE_ASCII_VALUE != *inPtr)
+    {
+        return VOS_STATUS_E_FAILURE;;
+    }
+
+    /*removing empty spaces*/
+    while ((SPACE_ASCII_VALUE  == *inPtr) && ('\0' !=  *inPtr) ) inPtr++;
+
+    /*no argument followed by spaces*/
+    if ('\0' == *inPtr)
+    {
+        return VOS_STATUS_E_FAILURE;;
+    }
+
+    /*getting the first argument ie the peer mac address */
+    if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
+        inPtr[11] != ':' || inPtr[14] != ':')
+    {
+       return VOS_STATUS_E_FAILURE;;
+    }
+    sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
+                  (unsigned int *)&pPeerMacAddr->bytes[0],
+                  (unsigned int *)&pPeerMacAddr->bytes[1],
+                  (unsigned int *)&pPeerMacAddr->bytes[2],
+                  (unsigned int *)&pPeerMacAddr->bytes[3],
+                  (unsigned int *)&pPeerMacAddr->bytes[4],
+                  (unsigned int *)&pPeerMacAddr->bytes[5]);
+
+    /* The command buffer seems to be fine */
+    return VOS_STATUS_SUCCESS;
+}
+
+/* Function header left blank Intentionally */
+static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
+                                               tANI_U32 limit)
+{
+   tANI_U8 len;
+   tANI_U8 data;
+
+   /* skip white space */
+   while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
+   {
+      command++;
+      limit--;
+   }
+
+   /* skip element id  and element length */
+   len = 2;
+
+   /* extract oui */
+   while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
+          (limit > 1))
+   {
+      /* Convert ASCII to decimal */
+      data = ((*command -'0') << 4) | (*(command + 1) - '0');
+      ie[len++] = data;
+      command += 2;
+      limit -= 2;
+   }
+
+   /* skip white space */
+   while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
+   {
+      command++;
+      limit--;
+   }
+
+   /* extract data */
+   while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
+         (limit > 1))
+   {
+      /* Convert ASCII to decimal */
+      data = ((*command -'0') << 4) | (*(command + 1) - '0');
+      ie[len++] = data;
+      command += 2;
+      limit -= 2;
+   }
+
+   /* fill element id and element length */
+   ie[0] = IE_EID_VENDOR;
+   ie[1] = len - 2;
+
+   return len;
+}
+
+static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
+{
+   tANI_U32 ieLenPresent = 0;
+   int left = addIeLen;
+   v_U8_t *ptr = addIePtr;
+   v_U8_t elem_id,elem_len;
+
+   while(left >= 2)
+   {
+      elem_id  =  ptr[0];
+      elem_len =  ptr[1];
+      left -= 2;
+      if(elem_len > left)
+      {
+         hddLog(LOGE,
+             FL("****Invalid elem_len=%d left=%d*****"),
+                                           elem_len,left);
+         return 0;
+      }
+      if ((elem_id == IE_EID_VENDOR) &&
+               (left >= WPA_OUI_TYPE_SIZE))
+      {
+         if (!memcmp(&ptr[2], WPA_OUI_TYPE,
+                          WPA_OUI_TYPE_SIZE))
+         {
+             ieLenPresent += elem_len + 2;
+             return ieLenPresent;
+         }
+      }
+      ieLenPresent += (elem_len + 2);
+      left -= elem_len;
+      ptr += (elem_len + 2);
+    }
+    return 0;
+}
+
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
 
 /**---------------------------------------------------------------------------
@@ -888,19 +1403,13 @@
     tANI_U8 *inPtr = pValue;
     tANI_U8 val = 0;
     tANI_U8 lastArg = 0;
-    tANI_U32 nScanFreq;
+    tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
     tANI_U32 nMscan;
-    tANI_U32 nBestN;
-    tANI_U8  ucRfBand;
-    tANI_U32 nRtt;
+    tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
+    tANI_U8  ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
+    tANI_U32 nRtt = 0;
     tANI_U32 temp;
 
-    /*initialize default values*/
-    nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
-    ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
-    nRtt = 0;
-    nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
-
     /*go to space after WLS_BATCHING_SET command*/
     inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
     /*no argument after the command*/
@@ -1630,11 +2139,11 @@
                 rc = wait_for_completion_timeout(
                      &pAdapter->hdd_get_batch_scan_req_var,
                      msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
-                if (0 == rc)
+                if (0 >= rc)
                 {
                     VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                    "%s: Timeout waiting to fetch batch scan rsp from fw",
-                    __func__);
+                           "%s: wait on hdd_get_batch_scan_req_var failed %ld",
+                             __func__, rc);
                     return -EFAULT;
                 }
             }
@@ -1701,7 +2210,6 @@
    return 0;
 } /*End of hdd_return_batch_scan_rsp_to_user*/
 
-
 /**---------------------------------------------------------------------------
 
   \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
@@ -4132,6 +4640,703 @@
            ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
        }
 #endif
+#ifdef WLAN_FEATURE_RMC
+       else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
+                (WLAN_HDD_IBSS == pAdapter->device_mode))
+       {
+           int i = 0;
+           tANI_U8 *ibss_ie;
+           tANI_U32 command_len;
+           tANI_U8 *value = command;
+           tHalHandle hHal = pHddCtx->hHal;
+           tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+           tANI_U32 ibss_ie_length;
+           tANI_U32 len, present;
+           tANI_U8 *addIE;
+           tANI_U8 *addIEData;
+
+           hddLog(LOG1,
+                     FL(" received command %s"),((char *) value));
+           /* validate argument of command */
+           if (strlen(value) <= 21)
+           {
+               hddLog(LOGE,
+                   FL("No arguements in command length %zu"), strlen(value));
+              ret = -EFAULT;
+              goto exit;
+           }
+
+           /* moving to arguments of commands */
+           value = value + 21;
+           command_len = strlen(value);
+
+           /* oui_data can't be less than 3 bytes */
+           if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
+           {
+               hddLog(LOGE,
+                     FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
+                     command_len);
+              ret = -EFAULT;
+              goto exit;
+           }
+           ibss_ie = vos_mem_malloc(command_len);
+           if (!ibss_ie) {
+               hddLog(LOGE,
+                     FL("Could not allocate memory for command length %d"),
+                     command_len);
+              ret = -ENOMEM;
+              goto exit;
+           }
+           vos_mem_zero(ibss_ie, command_len);
+
+           ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
+                                                                  command_len);
+           if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
+               hddLog(LOGE, FL("Could not parse command %s return length %d"),
+                     value, ibss_ie_length);
+                 ret = -EFAULT;
+              vos_mem_free(ibss_ie);
+                 goto exit;
+              }
+
+           hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
+           while (i < ibss_ie_length)
+              hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
+
+           /* Populate Vendor IE in Beacon */
+           if ((ccmCfgGetInt(hHal,
+                             WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
+                             &present)) != eHAL_STATUS_SUCCESS)
+           {
+              hddLog(LOGE,
+                FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
+              ret = -EFAULT;
+              vos_mem_free(ibss_ie);
+              goto exit;
+           }
+
+           addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
+           if (!addIE) {
+              hddLog(LOGE,
+                     FL("Could not allocate memory for command length %d"),
+                     command_len);
+              vos_mem_free(ibss_ie);
+              ret = -ENOMEM;
+              goto exit;
+           }
+           vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
+
+           if (present)
+           {
+              if ((wlan_cfgGetStrLen(pMac,
+                      WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
+              {
+                 hddLog(LOGE,
+                   FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
+                 ret = -EFAULT;
+                 vos_mem_free(ibss_ie);
+                 vos_mem_free(addIE);
+                 goto exit;
+              }
+
+              if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
+                ((len + ibss_ie_length) <=
+                                    WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
+              {
+                 if ((ccmCfgGetStr(hHal,
+                        WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
+                        != eHAL_STATUS_SUCCESS)
+                 {
+                    hddLog(LOGE,
+                      FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
+                    ret = -EFAULT;
+                    vos_mem_free(ibss_ie);
+                    vos_mem_free(addIE);
+                    goto exit;
+                 }
+                 else
+                 {
+                    /* Curruntly only WPA IE is added before Vendor IE
+                     * so we can blindly place the Vendor IE after WPA
+                     * IE. If no WPA IE found replace all with Vendor IE.
+                     */
+                    len = hdd_find_ibss_wpa_ie_pos(addIE, len);
+                 }
+              }
+              else
+              {
+                 hddLog(LOGE,
+                    FL("IE len exceed limit len %d,ibss_ie_length %d "),
+                    len, ibss_ie_length);
+                 ret = -EFAULT;
+                 vos_mem_free(addIE);
+                 vos_mem_free(ibss_ie);
+                 goto exit;
+              }
+           }
+           else {
+              len = 0;
+           }
+
+           vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
+           len += ibss_ie_length;
+
+           if (ccmCfgSetStr(hHal,
+               WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
+               eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
+           {
+              hddLog(LOGE,
+                  FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
+              ret = -EFAULT;
+              vos_mem_free(ibss_ie);
+              vos_mem_free(addIE);
+              goto exit;
+           }
+           vos_mem_free(addIE);
+           if (ccmCfgSetInt(hHal,
+               WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
+               eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
+           {
+              hddLog(LOGE,
+                 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
+              ret = -EFAULT;
+              vos_mem_free(ibss_ie);
+              goto exit;
+           }
+
+           /* Populate Vendor IE in probe resp */
+           if ((ccmCfgGetInt(hHal,
+                             WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
+                             &present)) != eHAL_STATUS_SUCCESS)
+           {
+               hddLog(LOGE,
+                   FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
+               ret = -EFAULT;
+               vos_mem_free(ibss_ie);
+               goto exit;
+           }
+
+           addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
+           if (!addIEData) {
+              hddLog(LOGE,
+                     FL("Could not allocate memory for command length %d"),
+                     command_len);
+              vos_mem_free(ibss_ie);
+              ret = -ENOMEM;
+              goto exit;
+           }
+           vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
+
+           if (present) {
+              if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
+                                      WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
+                 hddLog(LOGE,
+                     FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
+                 ret = -EFAULT;
+                 vos_mem_free(ibss_ie);
+                 vos_mem_free(addIEData);
+                 goto exit;
+              }
+              if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
+                 (ibss_ie_length + len) <=
+                                   WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
+
+                 if ((ccmCfgGetStr(hHal,
+                         WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
+                         != eHAL_STATUS_SUCCESS) {
+                    hddLog(LOGE,
+                     FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
+                    ret = -EFAULT;
+                    vos_mem_free(ibss_ie);
+                    vos_mem_free(addIEData);
+                    goto exit;
+                 }
+                 else {
+                    /* Curruntly only WPA IE is added before Vendor IE
+                     * so we can blindly place the Vendor IE after WPA
+                     * IE. If no WPA IE found replace all with Vendor IE.
+                     */
+                    len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
+                 }
+              }
+              else
+              {
+                 hddLog(LOGE,
+                    FL("IE len exceed limit len %d,ibss_ie_length %d "),
+                    len, ibss_ie_length);
+                 ret = -EFAULT;
+                 vos_mem_free(addIEData);
+                 vos_mem_free(ibss_ie);
+                 goto exit;
+              }
+           } /* probe rsp ADD IE present */
+           else {
+              /* probe rsp add IE is not present */
+              len = 0;
+           }
+
+           vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
+           len += ibss_ie_length;
+
+           vos_mem_free(ibss_ie);
+
+           if (ccmCfgSetStr(hHal,
+                               WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
+                               (tANI_U8*)(addIEData),
+                               len, NULL,
+                               eANI_BOOLEAN_FALSE)
+                               == eHAL_STATUS_FAILURE) {
+              hddLog(LOGE,
+                  FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
+              ret = -EFAULT;
+              vos_mem_free(addIEData);
+              goto exit;
+           }
+           vos_mem_free(addIEData);
+           if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
+                            WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
+                           eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
+           {
+              hddLog(LOGE,
+                  FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
+              ret = -EFAULT;
+              goto exit;
+           }
+        }
+       else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
+       {
+          tANI_U8 *value = command;
+          tANI_U8 ucRmcEnable = 0;
+          int  status;
+
+          if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
+              (WLAN_HDD_SOFTAP != pAdapter->device_mode))
+          {
+             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "Received SETRMCENABLE command in invalid mode %d "
+                "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
+                pAdapter->device_mode);
+             ret = -EINVAL;
+             goto exit;
+          }
+
+          status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
+          if (status)
+          {
+             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "Invalid SETRMCENABLE command ");
+             ret = -EINVAL;
+             goto exit;
+          }
+
+          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+               "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
+
+          if (TRUE == ucRmcEnable)
+          {
+              status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
+                         pAdapter->sessionId );
+          }
+          else if(FALSE == ucRmcEnable)
+          {
+              status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
+                         pAdapter->sessionId );
+          }
+          else
+          {
+             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "Invalid SETRMCENABLE command %d", ucRmcEnable);
+             ret = -EINVAL;
+             goto exit;
+          }
+
+          if (VOS_STATUS_SUCCESS != status)
+          {
+              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
+                 status);
+              ret = -EINVAL;
+              goto exit;
+          }
+       }
+       else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
+       {
+          tANI_U8 *value = command;
+          tANI_U32 uActionPeriod = 0;
+          int  status;
+
+          if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
+              (WLAN_HDD_SOFTAP != pAdapter->device_mode))
+          {
+             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "Received SETRMC command in invalid mode %d "
+                "SETRMC command is only allowed in IBSS or SOFTAP mode",
+                pAdapter->device_mode);
+             ret = -EINVAL;
+             goto exit;
+          }
+
+          status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
+          if (status)
+          {
+             VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "Invalid SETRMCACTIONPERIOD command ");
+             ret = -EINVAL;
+             goto exit;
+          }
+
+          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+               "%s: uActionPeriod %d ", __func__, uActionPeriod);
+
+          if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
+                 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
+          {
+              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
+              ret = -EINVAL;
+              goto exit;
+          }
+
+      }
+      else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
+      {
+         /* Peer Info All Command */
+         int status = eHAL_STATUS_SUCCESS;
+         hdd_station_ctx_t *pHddStaCtx = NULL;
+         char *extra = NULL;
+         int idx = 0, length = 0;
+         v_MACADDR_t *macAddr;
+         v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
+
+         if (WLAN_HDD_IBSS == pAdapter->device_mode)
+         {
+            pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+         }
+         else
+         {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                      "%s: pAdapter is not valid for this device mode",
+                      __func__);
+            ret = -EINVAL;
+            goto exit;
+         }
+
+         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                 "%s: Received GETIBSSPEERINFOALL Command", __func__);
+
+
+         /* Handle the command */
+         status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
+         if (VOS_STATUS_SUCCESS == status)
+         {
+            /* The variable extra needed to be allocated on the heap since
+             * amount of memory required to copy the data for 32 devices
+             * exceeds the size of 1024 bytes of default stack size. On
+             * 64 bit devices, the default max stack size of 2048 bytes
+             */
+            extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
+
+            if (NULL == extra)
+            {
+               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                         "%s:kmalloc failed", __func__);
+               ret = -EINVAL;
+               goto exit;
+            }
+
+            /* Copy number of stations */
+            length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
+                             pHddStaCtx->ibss_peer_info.numIBSSPeers);
+            numOfBytestoPrint = length;
+            for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
+            {
+               macAddr =
+                       hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
+                                         pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
+               if (NULL != macAddr)
+               {
+                  txRateMbps =
+                     ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
+
+                  length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
+                                  "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
+                                  macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
+                                  macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
+                                  (int)txRateMbps,
+                                  (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
+               }
+               else
+               {
+                  VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                             "%s: MAC ADDR is NULL for staIdx: %d", __func__,
+                             pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
+               }
+
+               /*
+                * VOS_TRACE() macro has limitation of 512 bytes for the print
+                * buffer. Hence printing the data in two chunks. The first chunk
+                * will have the data for 16 devices and the second chunk will
+                * have the rest.
+                */
+               if (idx < NUM_OF_STA_DATA_TO_PRINT)
+               {
+                   numOfBytestoPrint = length;
+               }
+            }
+
+            /*
+             * Copy the data back into buffer, if the data to copy is
+             * morethan 512 bytes than we will split the data and do
+             * it in two shots
+             */
+            if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
+            {
+               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                          "%s: Copy into user data buffer failed ", __func__);
+               ret = -EFAULT;
+               kfree(extra);
+               goto exit;
+            }
+            priv_data.buf[numOfBytestoPrint] = '\0';
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
+                      "%s", priv_data.buf);
+
+            if (length > numOfBytestoPrint)
+            {
+                if (copy_to_user(priv_data.buf + numOfBytestoPrint,
+                                 extra + numOfBytestoPrint,
+                                 length - numOfBytestoPrint + 1))
+                {
+                    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                              "%s: Copy into user data buffer failed ", __func__);
+                    ret = -EFAULT;
+                    kfree(extra);
+                    goto exit;
+                }
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
+                          "%s", &priv_data.buf[numOfBytestoPrint]);
+            }
+
+            /* Free temporary buffer */
+            kfree(extra);
+         }
+
+         else
+         {
+            /* Command failed, log error */
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                      "%s: GETIBSSPEERINFOALL command failed with status code %d",
+                      __func__, status);
+            ret = -EINVAL;
+            goto exit;
+         }
+         ret = 0;
+      }
+      else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
+      {
+         /* Peer Info <Peer Addr> command */
+         tANI_U8 *value = command;
+         VOS_STATUS status;
+         hdd_station_ctx_t *pHddStaCtx = NULL;
+         char extra[128] = { 0 };
+         v_U32_t length = 0;
+         v_U8_t staIdx = 0;
+         v_U32_t txRateMbps = 0;
+         v_MACADDR_t peerMacAddr;
+
+         if (WLAN_HDD_IBSS == pAdapter->device_mode)
+         {
+            pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+         }
+         else
+         {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                      "%s: pAdapter is not valid for this device mode",
+                      __func__);
+            ret = -EINVAL;
+            goto exit;
+         }
+
+         /* if there are no peers, no need to continue with the command */
+         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                 "%s: Received GETIBSSPEERINFO Command", __func__);
+
+         if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
+         {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                      "%s:No IBSS Peers coalesced", __func__);
+            ret = -EINVAL;
+            goto exit;
+         }
+
+         /* Parse the incoming command buffer */
+         status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
+         if (VOS_STATUS_SUCCESS != status)
+         {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                      "%s: Invalid GETIBSSPEERINFO command", __func__);
+            ret = -EINVAL;
+            goto exit;
+         }
+
+         /* Get station index for the peer mac address */
+         hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
+
+         if (staIdx > HDD_MAX_NUM_IBSS_STA)
+         {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                      "%s: Invalid StaIdx %d returned", __func__, staIdx);
+            ret = -EINVAL;
+            goto exit;
+         }
+
+         /* Handle the command */
+         status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
+         if (VOS_STATUS_SUCCESS == status)
+         {
+            v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
+            txRateMbps = (txRate * 500 * 1000)/1000000;
+
+            length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
+                            (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
+
+            /* Copy the data back into buffer */
+            if (copy_to_user(priv_data.buf, &extra, length+ 1))
+            {
+               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                  "%s: copy data to user buffer failed GETIBSSPEERINFO command",
+                  __func__);
+               ret = -EFAULT;
+               goto exit;
+            }
+         }
+         else
+         {
+            /* Command failed, log error */
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                      "%s: GETIBSSPEERINFO command failed with status code %d",
+                      __func__, status);
+            ret = -EINVAL;
+            goto exit;
+         }
+
+         /* Success ! */
+         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
+                   "%s", priv_data.buf);
+         ret = 0;
+       }
+       else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
+       {
+          tANI_U8 *value = command;
+          tANI_U32 uRate = 0;
+          tTxrateinfoflags txFlags = 0;
+          tSirRateUpdateInd *rateUpdateParams;
+          int  status;
+
+          if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
+              (WLAN_HDD_SOFTAP != pAdapter->device_mode))
+           {
+              VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "Received SETRMCTXRATE command in invalid mode %d "
+                "SETRMC command is only allowed in IBSS or SOFTAP mode",
+                pAdapter->device_mode);
+              ret = -EINVAL;
+              goto exit;
+           }
+
+          status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
+          if (status)
+           {
+               VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "Invalid SETRMCTXRATE command ");
+               ret = -EINVAL;
+               goto exit;
+           }
+
+          rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
+          if (NULL == rateUpdateParams)
+           {
+             ret = -EINVAL;
+             goto exit;
+           }
+
+          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+               "%s: uRate %d ", __func__, uRate);
+
+          vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
+
+          /* -1 implies ignore this param */
+          rateUpdateParams->ucastDataRate = -1;
+
+          /*
+           * Fill the user specifieed RMC rate param
+           * and the derived tx flags.
+           */
+          rateUpdateParams->rmcDataRate = uRate;
+          rateUpdateParams->rmcDataRateTxFlag = txFlags;
+
+          status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
+       }
+       else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
+       {
+           char *value;
+           tANI_U8 tx_fail_count = 0;
+           tANI_U16 pid = 0;
+
+           value = command;
+
+           ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
+
+           if (0 != ret)
+           {
+              hddLog(VOS_TRACE_LEVEL_INFO,
+                     "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
+                     __func__);
+              goto exit;
+           }
+
+           hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
+                   __func__, tx_fail_count, pid);
+
+           if (0 == tx_fail_count)
+           {
+               // Disable TX Fail Indication
+               if (eHAL_STATUS_SUCCESS  ==
+                   sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
+                                                 tx_fail_count,
+                                                 NULL))
+               {
+                   cesium_pid = 0;
+           }
+               else
+               {
+                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                             "%s: failed to disable TX Fail Event ", __func__);
+                   ret = -EINVAL;
+       }
+           }
+           else
+       {
+               if (eHAL_STATUS_SUCCESS  ==
+                   sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
+                                                 tx_fail_count,
+                                           (void*)hdd_tx_fail_ind_callback))
+               {
+                   cesium_pid = pid;
+                   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                             "%s: Registered Cesium pid %u", __func__,
+                             cesium_pid);
+       }
+               else
+               {
+                   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                             "%s: Failed to enable TX Fail Monitoring", __func__);
+                   ret = -EINVAL;
+               }
+           }
+       }
+
+#endif /* WLAN_FEATURE_RMC */
 #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
        else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
        {
@@ -6010,6 +7215,193 @@
    }
 }
 
+#ifdef WLAN_FEATURE_RMC
+static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
+{
+   int payload_len;
+   struct sk_buff *skb;
+   struct nlmsghdr *nlh;
+   v_U8_t *data;
+
+   payload_len = ETH_ALEN;
+
+   if (0 == cesium_pid)
+   {
+      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
+             __func__);
+      return;
+   }
+
+   if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
+   {
+      hddLog(VOS_TRACE_LEVEL_ERROR,
+             "%s: nlmsg_new() failed for msg size[%d]",
+             __func__, NLMSG_SPACE(payload_len));
+      return;
+   }
+
+   nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
+
+   if (NULL == nlh)
+   {
+      hddLog(VOS_TRACE_LEVEL_ERROR,
+             "%s: nlmsg_put() failed for msg size[%d]",
+             __func__, NLMSG_SPACE(payload_len));
+
+      kfree_skb(skb);
+      return;
+   }
+
+   data = nlmsg_data(nlh);
+   memcpy(data, MacAddr, ETH_ALEN);
+
+   if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
+   {
+      hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
+                                       __func__, NLMSG_SPACE(payload_len));
+   }
+
+   return;
+}
+
+/**---------------------------------------------------------------------------
+     \brief hdd_ParseuserParams - return a pointer to the next argument
+
+     \return - status
+
+--------------------------------------------------------------------------*/
+static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
+{
+   tANI_U8 *pVal;
+
+   pVal = strchr(pValue, ' ');
+
+   if (NULL == pVal)
+   {
+      /* no argument remains */
+      return -EINVAL;
+   }
+   else if (SPACE_ASCII_VALUE != *pVal)
+   {
+      /* no space after the current argument */
+      return -EINVAL;
+   }
+
+   pVal++;
+
+   /* remove empty spaces */
+   while ((SPACE_ASCII_VALUE  == *pVal) && ('\0' !=  *pVal))
+   {
+      pVal++;
+   }
+
+   /* no argument followed by spaces */
+   if ('\0' == *pVal)
+   {
+      return -EINVAL;
+   }
+
+   *ppArg = pVal;
+
+   return 0;
+}
+
+/**----------------------------------------------------------------------------
+     \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
+
+     \return - status
+
+------------------------------------------------------------------------------*/
+static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
+                                          tANI_U8 *tx_fail_count,
+                                          tANI_U16 *pid)
+{
+   tANI_U8 *param = NULL;
+   int ret;
+
+   ret = hdd_ParseUserParams(pValue, &param);
+
+   if (0 == ret && NULL != param)
+   {
+      if (1 != sscanf(param, "%hhu", tx_fail_count))
+      {
+         ret = -EINVAL;
+         goto done;
+      }
+   }
+   else
+   {
+      goto done;
+   }
+
+   if (0 == *tx_fail_count)
+   {
+      *pid = 0;
+      goto done;
+   }
+
+   pValue = param;
+   pValue++;
+
+   ret = hdd_ParseUserParams(pValue, &param);
+
+   if (0 == ret)
+   {
+      if (1 != sscanf(param, "%hu", pid))
+      {
+         ret = -EINVAL;
+         goto done;
+      }
+   }
+   else
+   {
+      goto done;
+   }
+
+done:
+   return ret;
+}
+
+static int hdd_open_cesium_nl_sock()
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
+   struct netlink_kernel_cfg cfg = {
+          .groups = WLAN_NLINK_MCAST_GRP_ID,
+          .input = NULL
+          };
+#endif
+   int ret = 0;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
+   cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+                                              THIS_MODULE,
+#endif
+                                              &cfg);
+#else
+   cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
+                                        WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
+#endif
+
+   if (cesium_nl_srv_sock == NULL)
+   {
+       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                 "NLINK:  cesium netlink_kernel_create failed");
+       ret = -ECONNREFUSED;
+   }
+
+   return ret;
+}
+
+static void hdd_close_cesium_nl_sock()
+{
+   if (NULL != cesium_nl_srv_sock)
+   {
+      netlink_kernel_release(cesium_nl_srv_sock);
+      cesium_nl_srv_sock = NULL;
+   }
+}
+#endif /* WLAN_FEATURE_RMC */
 /**---------------------------------------------------------------------------
 
     \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
@@ -8962,6 +10354,9 @@
    nl_srv_exit();
 #endif /* WLAN_KD_READY_NOTIFIER */
 
+#ifdef WLAN_FEATURE_RMC
+   hdd_close_cesium_nl_sock();
+#endif /* WLAN_FEATURE_RMC */
 
    hdd_close_all_adapters( pHddCtx );
 
@@ -10602,6 +11997,14 @@
    }
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+   if (hdd_open_cesium_nl_sock() < 0)
+   {
+      hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
+      goto err_reg_netdev;
+   }
+#endif
+
 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
    if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
    {
@@ -11753,6 +13156,7 @@
           * the driver.
           *
           */
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
          cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
 #else
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 16be32b..06adeef 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -225,7 +225,10 @@
 #define WE_GET_11W_INFO      9
 #endif
 #define WE_GET_STATES        10
-#define WE_GET_SNR           11
+#ifdef WLAN_FEATURE_RMC
+#define WE_GET_IBSS_STA_INFO 11
+#endif
+#define WE_GET_SNR           12
 
 #ifdef FEATURE_OEM_DATA_SUPPORT
 #define WE_GET_OEM_DATA_CAP  13
@@ -244,6 +247,9 @@
 #define WE_DISPLAY_DXE_SNAP_SHOT   7
 #define WE_SET_REASSOC_TRIGGER     8
 #define WE_DISPLAY_DATAPATH_SNAP_SHOT    9
+#ifdef WLAN_FEATURE_RMC
+#define WE_IBSS_GET_PEER_INFO_ALL 10
+#endif
 #define WE_STOP_OBSS_SCAN    11
 #define WE_DUMP_ROAM_TIMER_LOG     12
 #define WE_RESET_ROAM_TIMER_LOG    13
@@ -262,6 +268,9 @@
 #ifdef FEATURE_WLAN_TDLS
 #define WE_TDLS_CONFIG_PARAMS   5
 #endif
+#ifdef WLAN_FEATURE_RMC
+#define WE_IBSS_GET_PEER_INFO   6
+#endif
 
 #define WE_MTRACE_DUMP_CMD    8
 #define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD    9
@@ -562,6 +571,163 @@
     return;
 }
 
+#ifdef WLAN_FEATURE_RMC
+void hdd_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
+{
+   hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
+   tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
+   hdd_station_ctx_t *pStaCtx =  WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+   v_U8_t   i;
+
+   if (NULL != pPeerInfo && eHAL_STATUS_SUCCESS == pPeerInfo->status)
+   {
+      pStaCtx->ibss_peer_info.status = pPeerInfo->status;
+      pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
+      for (i = 0; i < pPeerInfo->numPeers; i++)
+      {
+         memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
+                &pPeerInfo->peerInfoParams[i], sizeof(hdd_ibss_peer_info_params_t));
+      }
+   }
+   else
+   {
+      hddLog(LOGE,
+            FL("PEER_INFO_CMD_STATUS is not SUCCESS"));
+   }
+
+   complete(&pAdapter->ibss_peer_info_comp);
+}
+
+v_MACADDR_t* hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter, v_U8_t staIdx)
+{
+   v_U8_t idx;
+   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+
+   for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
+   {
+      if ( 0 != pHddStaCtx->conn_info.staId[ idx ] &&
+           staIdx == pHddStaCtx->conn_info.staId[ idx ])
+      {
+         return (&pHddStaCtx->conn_info.peerMacAddress[ idx ]);
+      }
+   }
+   return NULL;
+}
+
+eHalStatus hdd_wlan_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
+{
+    eHalStatus status = eHAL_STATUS_FAILURE;
+    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
+    hdd_station_ctx_t *pStaCtx =  WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+    hdd_ibss_peer_info_t *pPeerInfo = &pStaCtx->ibss_peer_info;
+
+    status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
+                                     VOS_FALSE, staIdx);
+
+    INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
+
+    if (eHAL_STATUS_SUCCESS == status)
+    {
+       long ret;
+       ret  = wait_for_completion_interruptible_timeout
+                (&pAdapter->ibss_peer_info_comp,
+                msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+       if (ret <= 0)
+       {
+          hddLog(VOS_TRACE_LEVEL_ERROR,
+                  FL("failed wait on ibss_peer_info_comp %ld"), ret);
+          return eHAL_STATUS_FAILURE;
+       }
+
+       /** Print the peer info */
+       pr_info("pPeerInfo->numIBSSPeers = %d ", pPeerInfo->numIBSSPeers);
+       pr_info("============================================================");
+       {
+          v_MACADDR_t *macAddr = hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
+                                 staIdx);
+          v_U32_t  txRateMbps = ((pPeerInfo->ibssPeerList[0].txRate)*500*1000)/1000000;
+
+          if (NULL != macAddr)
+          {
+             pr_info("PEER ADDR :" MAC_ADDRESS_STR " TxRate: %d Mbps  RSSI: %d",
+                     MAC_ADDR_ARRAY(macAddr->bytes),
+                      (int)txRateMbps, (int)pPeerInfo->ibssPeerList[0].rssi);
+          }
+          else
+          {
+             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                       " ERROR: PEER MAC ADDRESS NOT FOUND ");
+          }
+       }
+    }
+    else
+    {
+       hddLog(VOS_TRACE_LEVEL_WARN,
+              "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
+    }
+
+    return status;
+}
+
+eHalStatus hdd_wlan_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
+{
+    eHalStatus status = eHAL_STATUS_FAILURE;
+    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
+    hdd_station_ctx_t *pStaCtx =  WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+    hdd_ibss_peer_info_t *pPeerInfo = &pStaCtx->ibss_peer_info;
+    int i;
+
+    status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
+                                     VOS_TRUE, 0xFF);
+    INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
+
+    if (eHAL_STATUS_SUCCESS == status)
+    {
+       long ret;
+       ret  = wait_for_completion_interruptible_timeout
+                (&pAdapter->ibss_peer_info_comp,
+                 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+       if (ret <= 0)
+       {
+          hddLog(VOS_TRACE_LEVEL_ERROR,
+                  FL("failed wait on ibss_peer_info_comp %ld"), ret);
+          return eHAL_STATUS_FAILURE;
+       }
+
+       /** Print the peer info */
+       pr_info("pPeerInfo->numIBSSPeers = %d ", (int)pPeerInfo->numIBSSPeers);
+       pr_info("============================================================");
+       for (i = 0; i < pPeerInfo->numIBSSPeers; i++)
+       {
+          v_U8_t staIdx = pPeerInfo->ibssPeerList[i].staIdx;
+          v_MACADDR_t *macAddr = hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
+                                                                       staIdx);
+          v_U32_t  txRateMbps = ((pPeerInfo->ibssPeerList[0].txRate)*500*1000)/1000000;
+
+          pr_info("STAIDX:%d ", (int)pPeerInfo->ibssPeerList[i].staIdx);
+          if (NULL != macAddr)
+          {
+             pr_info(" PEER ADDR :" MAC_ADDRESS_STR " TxRate: %d Mbps RSSI: %d",
+                     MAC_ADDR_ARRAY(macAddr->bytes),
+                     (int)txRateMbps, (int)pPeerInfo->ibssPeerList[i].rssi);
+          }
+          else
+          {
+             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                       " ERROR: PEER MAC ADDRESS NOT FOUND ");
+          }
+       }
+    }
+    else
+    {
+       hddLog(VOS_TRACE_LEVEL_WARN,
+              "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
+    }
+
+    return status;
+}
+#endif /* WLAN_FEATURE_RMC */
+
 int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
 {
     tHalHandle hHal;
@@ -7124,6 +7290,37 @@
            break;
        }
 #endif
+#ifdef WLAN_FEATURE_RMC
+        case WE_GET_IBSS_STA_INFO:
+        {
+            hdd_station_ctx_t *pHddStaCtx =
+                WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+            int idx = 0;
+            int length = 0, buf = 0;
+
+            for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++)
+            {
+               if (0 != pHddStaCtx->conn_info.staId[ idx ])
+               {
+                   buf = snprintf
+                             (
+                             (extra + length), WE_MAX_STR_LEN - length,
+                             "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n",
+                             pHddStaCtx->conn_info.staId[ idx ],
+                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[0],
+                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[1],
+                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[2],
+                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[3],
+                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[4],
+                             pHddStaCtx->conn_info.peerMacAddress[idx].bytes[5]
+                             );
+                   length += buf;
+               }
+            }
+            wrqu->data.length = strlen(extra)+1;
+            break;
+        }
+#endif
         case WE_GET_SNR:
         {
             v_S7_t s7snr = 0;
@@ -7253,6 +7450,13 @@
                  wlan_hdd_get_intf_addr( WLAN_HDD_GET_CTX(pAdapter) ),TRUE);
           break;
         }
+#ifdef WLAN_FEATURE_RMC
+        case WE_IBSS_GET_PEER_INFO_ALL:
+        {
+            hdd_wlan_get_ibss_peer_info_all(pAdapter);
+            break;
+        }
+#endif
         case WE_STOP_AP:
         {
            /*FIX ME: Need to be revisited if multiple SAPs to be supported */
@@ -7615,6 +7819,14 @@
 
             }
             break;
+#ifdef WLAN_FEATURE_RMC
+        case WE_IBSS_GET_PEER_INFO:
+             {
+                pr_info ( "Station ID = %d\n",apps_args[0]);
+                hdd_wlan_get_ibss_peer_info(pAdapter, apps_args[0]);
+             }
+              break;
+#endif
 
         case WE_P2P_NOA_CMD:
             {
@@ -10933,6 +11145,13 @@
         IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
         "getPMFInfo" },
 #endif
+#ifdef WLAN_FEATURE_RMC
+    {
+        WE_GET_IBSS_STA_INFO,
+        0,
+        IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
+        "getIbssSTAs" },
+#endif
     {   WE_GET_SNR,
         0,
         IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
@@ -10959,6 +11178,13 @@
         0,
         0,
         "initAP" },
+#ifdef WLAN_FEATURE_RMC
+    {
+        WE_IBSS_GET_PEER_INFO_ALL,
+        0,
+        0,
+       "ibssPeerInfoAll" },
+#endif
     {   WE_STOP_AP,
         0,
         0,
@@ -11028,6 +11254,12 @@
         IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
         0,
         "dump" },
+#ifdef WLAN_FEATURE_RMC
+    {   WE_IBSS_GET_PEER_INFO,
+        IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+        0,
+        "ibssPeerInfo" },
+#endif
 
     /* handlers for sub-ioctl */
     {   WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD,
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index be90e1f..d4e503e 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -92,6 +92,8 @@
 #endif
 #include "p2p_Api.h"
 
+#include "limRMC.h"
+
 #if defined WLAN_FEATURE_VOWIFI_11R
 #include <limFTDefs.h>
 #endif
@@ -1049,6 +1051,9 @@
     v_BOOL_t isTdlsPowerSaveProhibited;
 #endif
     tANI_U8 fScanOffload;
+#ifdef WLAN_FEATURE_RMC
+    tLimRmcContext  rmcContext;
+#endif /* WLAN_FEATURE_RMC */
     tANI_U8 isCoalesingInIBSSAllowed;
     tANI_U32 fEnableDebugLog;
     tANI_U32 fDeferIMPSTime;
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 6399687..ce299dd 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -2312,6 +2312,16 @@
 
 } tAniDHCPInd, *tpAniDHCPInd;
 
+#ifdef WLAN_FEATURE_RMC
+typedef struct sAniTXFailMonitorInd
+{
+    tANI_U16                msgType; // message type is same as the request type
+    tANI_U16                msgLen;  // length of the entire request
+    tANI_U8                 tx_fail_count;
+    void                    *txFailIndCallback;
+} tAniTXFailMonitorInd, *tpAniTXFailMonitorInd;
+#endif /* WLAN_FEATURE_RMC */
+
 typedef struct sAniSummaryStatsInfo
 {
     tANI_U32 retry_cnt[4];         //Total number of packets(per AC) that were successfully transmitted with retries
@@ -4674,10 +4684,10 @@
      * 0 implies MCAST RA, positive value implies fixed rate,
      * -1 implies ignore this param
      */
-    tANI_S32 reliableMcastDataRate;//unit Mbpsx10
+    tANI_S32 rmcDataRate;//unit Mbpsx10
 
     /* TX flag to differentiate between HT20, HT40 etc */
-    tTxrateinfoflags reliableMcastDataRateTxFlag;
+    tTxrateinfoflags rmcDataRateTxFlag;
 
     /*
      * MCAST(or BCAST) fixed data rate in 2.4 GHz, unit Mbpsx10,
@@ -4699,6 +4709,102 @@
 
 } tSirRateUpdateInd, *tpSirRateUpdateInd;
 
+#ifdef WLAN_FEATURE_RMC
+
+#define SIR_RMC_NUM_MAX_RULERS  8  /* HAL_NUM_MAX_RULERS */
+typedef struct sSirSetRMCReq
+{
+    tANI_U16       msgType;
+    tANI_U16       msgLen;
+    tSirMacAddr    mcastTransmitter;
+} tSirSetRMCReq, *tpSirSetRMCReq;
+
+typedef struct sSirRMCInfo
+{
+    tANI_U32      dialogToken;
+    tANI_U8       action;
+    tSirMacAddr   mcastRuler;
+} tSirRMCInfo, *tpSirRMCInfo;
+
+typedef struct sSirRmcRulerSelectInd
+{
+    tANI_U16      status;
+    tSirMacAddr   mcastTransmitter;
+    tSirMacAddr   mcastGroup;
+    tSirMacAddr   ruler[SIR_RMC_NUM_MAX_RULERS];
+} tSirRmcRulerSelectInd, *tpSirRmcRulerSelectInd;
+
+typedef struct sSirRmcBecomeRulerInd
+{
+    tANI_U16      status;
+    tSirMacAddr   mcastTransmitter;
+    tSirMacAddr   mcastGroup;
+} tSirRmcBecomeRulerInd, *tpSirRmcBecomeRulerInd;
+
+typedef struct sSirRmcRulerReq
+{
+    // Common for all types are requests
+    tANI_U16      msgType; // message type is same as the request type
+    tANI_U16      msgLen;  // length of the entire request
+    tANI_U8       cmd;     // tRulerReqCmdType
+    tSirMacAddr   mcastTransmitter;
+    tSirMacAddr   mcastGroup;
+    tSirMacAddr   blacklist[SIR_RMC_NUM_MAX_RULERS];
+} tSirRmcRulerReq, *tpSirRmcRulerReq;
+
+typedef struct sSirRmcUpdateInd
+{
+    // Common for all types are requests
+    tANI_U16      msgType;    // message type is same as the request type
+    tANI_U16      msgLen;     // length of the entire request
+    tANI_U8       indication; // trulerUpdateIndType
+    tANI_U8       role;       // tRoleType
+    tSirMacAddr   mcastTransmitter;
+    tSirMacAddr   mcastGroup;
+    tSirMacAddr   mcastRuler;
+    tSirMacAddr   ruler[SIR_RMC_NUM_MAX_RULERS];
+} tSirRmcUpdateInd, *tpSirRmcUpdateInd;
+
+/*---------------------------------------------------------------------------
+* tSirIbssGetPeerInfoReqParams
+*--------------------------------------------------------------------------*/
+typedef struct
+{
+    tANI_BOOLEAN    allPeerInfoReqd; // If set, all IBSS peers stats are reported
+    tANI_U8         staIdx;          // If allPeerInfoReqd is not set, only stats
+                                     // of peer with staIdx is reported
+}tSirIbssGetPeerInfoReqParams, *tpSirIbssGetPeerInfoReqParams;
+
+/*---------------------------------------------------------------------------
+* tSirIbssGetPeerInfoParams
+*--------------------------------------------------------------------------*/
+typedef struct
+{
+   tANI_U8  staIdx;      //StaIdx
+   tANI_U32 txRate;       //Tx Rate
+   tANI_U32 mcsIndex;    //MCS Index
+   tANI_U32 txRateFlags; //TxRate Flags
+   tANI_S8  rssi;        //RSSI
+}tSirIbssPeerInfoParams;
+
+typedef struct
+{
+   tANI_U32   status;
+   tANI_U8    numPeers;
+   tSirIbssPeerInfoParams  peerInfoParams[32];
+}tSirPeerInfoRspParams, *tpSirIbssPeerInfoRspParams;
+
+/*---------------------------------------------------------------------------
+* tSirIbssGetPeerInfoRspParams
+*--------------------------------------------------------------------------*/
+typedef struct
+{
+   tANI_U16   mesgType;
+   tANI_U16   mesgLen;
+   tSirPeerInfoRspParams ibssPeerInfoRspParams;
+} tSirIbssGetPeerInfoRspParams, *tpSirIbssGetPeerInfoRspParams;
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
 // Set batch scan resposne from FW
 typedef struct
diff --git a/CORE/MAC/inc/sirMacProtDef.h b/CORE/MAC/inc/sirMacProtDef.h
index bf8efd3..b635693 100644
--- a/CORE/MAC/inc/sirMacProtDef.h
+++ b/CORE/MAC/inc/sirMacProtDef.h
@@ -2448,6 +2448,18 @@
 } __ani_attr_packed tSirMacVendorSpecificFrameHdr, *tpSirMacVendorSpecificFrameHdr;
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+typedef __ani_attr_pre_packed struct sSirMacIbssExtNetworkFrameHdr
+{
+    tANI_U8    category;
+    tANI_U8    Oui[3];
+    tANI_U8    MagicCode[6];
+    tANI_U8    version;
+    tANI_U8    actionID;
+    tANI_U32   dialogToken;
+} __ani_attr_packed tSirMacIbssExtNetworkFrameHdr, *tpSirMacIbssExtNetworkFrameHdr;
+#endif /* WLAN_FEATURE_RMC */
+
 typedef __ani_attr_pre_packed struct sSirMacVendorSpecificPublicActionFrameHdr
 {
     tANI_U8    category;
@@ -2879,6 +2891,24 @@
 
 #define SIR_MAC_MIN_IE_LEN 2 // Minimum IE length for IE validation
 
+#ifdef WLAN_FEATURE_RMC
+
+// RMC action codes
+#define SIR_MAC_RMC_ENABLE_REQ                  0
+#define SIR_MAC_RMC_DISABLE_REQ                 1
+#define SIR_MAC_RMC_RULER_INFORM_SELECTED      2
+#define SIR_MAC_RMC_RULER_INFORM_CANCELLED     3
+
+// RMC protocol version
+#define SIR_MAC_RMC_VER 0x01
+
+// Organization Identifier
+#define SIR_MAC_RMC_OUI             "\x00\x16\x32"
+#define SIR_MAC_RMC_OUI_SIZE        3
+
+#define SIR_MAC_RMC_MCAST_ADDRESS  "\x01\x00\x5E\x00\x02\x0A"
+
+#endif /* WLAN_FEATURE_RMC */
 
 #define SIR_MAC_TI_TYPE_REASSOC_DEADLINE        1
 #define SIR_MAC_TI_TYPE_KEY_LIFETIME            2
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 466d8f9..4c22db5 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -359,7 +359,11 @@
 #ifdef FEATURE_WLAN_LPHB
     eWNI_SME_LPHB_IND,
 #endif /* FEATURE_WLAN_LPHB */
-
+#ifdef WLAN_FEATURE_RMC
+    eWNI_SME_ENABLE_RMC_REQ,
+    eWNI_SME_DISABLE_RMC_REQ,
+    eWNI_SME_IBSS_PEER_INFO_RSP,
+#endif /* WLAN_FEATURE_RMC */
     eWNI_SME_GET_TSM_STATS_REQ,
     eWNI_SME_GET_TSM_STATS_RSP,
     eWNI_SME_TSM_IE_IND,
diff --git a/CORE/MAC/inc/wniCfg.h b/CORE/MAC/inc/wniCfg.h
index d9e4e5a..441caf0 100644
--- a/CORE/MAC/inc/wniCfg.h
+++ b/CORE/MAC/inc/wniCfg.h
@@ -340,12 +340,12 @@
      WNI_CFG_FLEX_CONNECT_POWER_FACTOR,
      WNI_CFG_ANTENNA_DIVESITY,
      WNI_CFG_GO_LINK_MONITOR_TIMEOUT,
+     WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
      WNI_CFG_ATH_DISABLE,
      WNI_CFG_BTC_ACTIVE_WLAN_LEN,
      WNI_CFG_BTC_ACTIVE_BT_LEN,
      WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN,
      WNI_CFG_BTC_SAP_ACTIVE_BT_LEN,
-     WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
      WNI_CFG_ASD_PROBE_INTERVAL,
      WNI_CFG_ASD_TRIGGER_THRESHOLD,
      WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD,
@@ -1701,6 +1701,10 @@
 #define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMAX    50
 #define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STADEF    10
 
+#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN    100
+#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX    1000
+#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF    300
+
 #define WNI_CFG_ATH_DISABLE_STAMIN    0
 #define WNI_CFG_ATH_DISABLE_STAMAX    1
 #define WNI_CFG_ATH_DISABLE_STADEF    0
@@ -1721,10 +1725,6 @@
 #define WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STAMAX    250000
 #define WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STADEF    30000
 
-#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN    0
-#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX    4294967295
-#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF    300
-
 #define WNI_CFG_ASD_PROBE_INTERVAL_STAMIN    1
 #define WNI_CFG_ASD_PROBE_INTERVAL_STAMAX    500
 #define WNI_CFG_ASD_PROBE_INTERVAL_STADEF    50
diff --git a/CORE/MAC/src/cfg/cfgParamName.c b/CORE/MAC/src/cfg/cfgParamName.c
index b74ba4c..5fda170 100644
--- a/CORE/MAC/src/cfg/cfgParamName.c
+++ b/CORE/MAC/src/cfg/cfgParamName.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -341,12 +341,12 @@
     (unsigned char *)"FLEX_CONNECT_POWER_FACTOR",
     (unsigned char *)"ANTENNA_DIVESITY",
     (unsigned char *)"GO_LINK_MONITOR_TIMEOUT",
+    (unsigned char *)"RMC_ACTION_PERIOD_FREQUENCY",
     (unsigned char *)"ATH_DISABLE",
     (unsigned char *)"BTC_ACTIVE_WLAN_LEN",
     (unsigned char *)"BTC_ACTIVE_BT_LEN",
     (unsigned char *)"BTC_SAP_ACTIVE_WLAN_LEN",
     (unsigned char *)"BTC_SAP_ACTIVE_BT_LEN",
-    (unsigned char *)"RMC_ACTION_PERIOD_FREQUENCY",
     (unsigned char *)"ASD_PROBE_INTERVAL",
     (unsigned char *)"ASD_TRIGGER_THRESHOLD",
     (unsigned char *)"ASD_RTT_RSSI_HYST_THRESHOLD",
diff --git a/CORE/MAC/src/cfg/cfgProcMsg.c b/CORE/MAC/src/cfg/cfgProcMsg.c
index e25a798..ab7ed15 100644
--- a/CORE/MAC/src/cfg/cfgProcMsg.c
+++ b/CORE/MAC/src/cfg/cfgProcMsg.c
@@ -1440,6 +1440,12 @@
      WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMIN,
      WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMAX,
      WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STADEF},
+    {WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
+     CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL,
+     WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN,
+     WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX,
+     WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF},
+
     {WNI_CFG_ATH_DISABLE,
      CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
      WNI_CFG_ATH_DISABLE_STAMIN,
@@ -1465,11 +1471,6 @@
      WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STAMIN,
      WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STAMAX,
      WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STADEF},
-    {WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
-     CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL,
-     WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN,
-     4294967295u,
-     WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF},
     {WNI_CFG_ASD_PROBE_INTERVAL,
      CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL,
      WNI_CFG_ASD_PROBE_INTERVAL_STAMIN,
diff --git a/CORE/MAC/src/cfg/cfgUtil/cfg.txt b/CORE/MAC/src/cfg/cfgUtil/cfg.txt
index 87aba50..c08458f 100644
--- a/CORE/MAC/src/cfg/cfgUtil/cfg.txt
+++ b/CORE/MAC/src/cfg/cfgUtil/cfg.txt
@@ -1,5 +1,5 @@
  *
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -4601,7 +4601,18 @@
 *
 *
 
-* ATH Enable/Disable
+* RMC action period frequency (milli seconds)
+*
+WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY    I    4    7
+V    RW    NP
+HAL
+100   1000    300
+V    RW    NP
+HAL
+100   1000    300
+*
+*
+
 *
 WNI_CFG_ATH_DISABLE	I    4    7
 V    RW    NP
@@ -4658,18 +4669,6 @@
 *
 *
 
-* RMC action period frequency (milli seconds)
-*
-WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY    I    4    7
-V    RW    NP
-HAL
-0   0xFFFFFFFF    300
-V    RW    NP
-HAL
-0   0xFFFFFFFF    300
-*
-*
-
 * Rssi probe interval (milli seconds)
 *
 WNI_CFG_ASD_PROBE_INTERVAL    I    4    7
diff --git a/CORE/MAC/src/cfg/cfgUtil/dot11f.frms b/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
index 87bbc65..18c9889 100644
--- a/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
+++ b/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
@@ -419,6 +419,31 @@
     ouiSubtype, 1;
 }
 
+FF RMCOUI (3)
+{
+     oui[3];
+}
+
+FF MagicCode (6)
+{
+     magic[6];
+}
+
+FF RMCVersion (1)
+{
+     version, 1;
+}
+
+FF RMCDialogToken (4)
+{
+     token, 4;
+}
+
+FF Ruler (6)
+{
+     mac[6];
+}
+
 FF VhtMembershipStatusArray(8)                    // 8.4.1.51
 {
     membershipStatusArray[8];
@@ -4242,6 +4267,17 @@
     MANDIE  QosMapSet;
 }
 
+FRAME RMC
+{
+    FF     Category;
+    FF     RMCOUI;
+    FF     MagicCode;
+    FF     RMCVersion;
+    FF     Action;
+    FF     RMCDialogToken;
+    FF     Ruler;
+}
+
 FRAME VHTGidManagementActionFrame
 {
     FF     Category;
diff --git a/CORE/MAC/src/include/dot11f.h b/CORE/MAC/src/include/dot11f.h
index e08fd48..32e6981 100644
--- a/CORE/MAC/src/include/dot11f.h
+++ b/CORE/MAC/src/include/dot11f.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -30,7 +30,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Mon Nov 10 19:49:53 2014 from the following file(s):
+  * Wed Sep  9 10:17:04 2015 from the following file(s):
   *
   * dot11f.frms
   *
@@ -316,6 +316,16 @@
 
 void dot11fPackFfListenInterval(tpAniSirGlobal, tDot11fFfListenInterval*, tANI_U8*);
 
+typedef struct sDot11fFfMagicCode {
+    tANI_U8 magic[6];
+} tDot11fFfMagicCode;
+
+#define DOT11F_FF_MAGICCODE_LEN ( 6 )
+
+void dot11fUnpackFfMagicCode(tpAniSirGlobal, tANI_U8*, tDot11fFfMagicCode*);
+
+void dot11fPackFfMagicCode(tpAniSirGlobal, tDot11fFfMagicCode*, tANI_U8*);
+
 typedef struct sDot11fFfMaxTxPower {
     tANI_U8 maxTxPower;
 } tDot11fFfMaxTxPower;
@@ -388,6 +398,36 @@
 
 void dot11fPackFfRCPI(tpAniSirGlobal, tDot11fFfRCPI*, tANI_U8*);
 
+typedef struct sDot11fFfRMCDialogToken {
+    tANI_U32 token;
+} tDot11fFfRMCDialogToken;
+
+#define DOT11F_FF_RMCDIALOGTOKEN_LEN ( 4 )
+
+void dot11fUnpackFfRMCDialogToken(tpAniSirGlobal, tANI_U8*, tDot11fFfRMCDialogToken*);
+
+void dot11fPackFfRMCDialogToken(tpAniSirGlobal, tDot11fFfRMCDialogToken*, tANI_U8*);
+
+typedef struct sDot11fFfRMCOUI {
+    tANI_U8 oui[3];
+} tDot11fFfRMCOUI;
+
+#define DOT11F_FF_RMCOUI_LEN ( 3 )
+
+void dot11fUnpackFfRMCOUI(tpAniSirGlobal, tANI_U8*, tDot11fFfRMCOUI*);
+
+void dot11fPackFfRMCOUI(tpAniSirGlobal, tDot11fFfRMCOUI*, tANI_U8*);
+
+typedef struct sDot11fFfRMCVersion {
+    tANI_U8 version;
+} tDot11fFfRMCVersion;
+
+#define DOT11F_FF_RMCVERSION_LEN ( 1 )
+
+void dot11fUnpackFfRMCVersion(tpAniSirGlobal, tANI_U8*, tDot11fFfRMCVersion*);
+
+void dot11fPackFfRMCVersion(tpAniSirGlobal, tDot11fFfRMCVersion*, tANI_U8*);
+
 typedef struct sDot11fFfRSNI {
     tANI_U8 rsni;
 } tDot11fFfRSNI;
@@ -408,6 +448,16 @@
 
 void dot11fPackFfReason(tpAniSirGlobal, tDot11fFfReason*, tANI_U8*);
 
+typedef struct sDot11fFfRuler {
+    tANI_U8 mac[6];
+} tDot11fFfRuler;
+
+#define DOT11F_FF_RULER_LEN ( 6 )
+
+void dot11fUnpackFfRuler(tpAniSirGlobal, tANI_U8*, tDot11fFfRuler*);
+
+void dot11fPackFfRuler(tpAniSirGlobal, tDot11fFfRuler*, tANI_U8*);
+
 typedef struct sDot11fFfRxAntennaId {
     tANI_U8 antennaId;
 } tDot11fFfRxAntennaId;
@@ -7298,6 +7348,30 @@
 } /* End extern "C". */
 #endif /* C++ */
 
+typedef struct sDot11fRMC{
+    tDot11fFfCategory       Category;
+    tDot11fFfRMCOUI         RMCOUI;
+    tDot11fFfMagicCode      MagicCode;
+    tDot11fFfRMCVersion     RMCVersion;
+    tDot11fFfAction         Action;
+    tDot11fFfRMCDialogToken RMCDialogToken;
+    tDot11fFfRuler         Ruler;
+} tDot11fRMC;
+
+#define DOT11F_RMC ( 41 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+tANI_U32 dot11fUnpackRMC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRMC *pFrm);
+tANI_U32 dot11fPackRMC(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed);
+tANI_U32 dot11fGetPackedRMCSize(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U32 *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
 typedef struct sDot11fRadioMeasurementReport{
     tDot11fFfCategory          Category;
     tDot11fFfAction            Action;
@@ -7306,7 +7380,7 @@
     tDot11fIEMeasurementReport MeasurementReport[4];
 } tDot11fRadioMeasurementReport;
 
-#define DOT11F_RADIOMEASUREMENTREPORT ( 41 )
+#define DOT11F_RADIOMEASUREMENTREPORT ( 42 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7329,7 +7403,7 @@
     tDot11fIEMeasurementRequest MeasurementRequest[2];
 } tDot11fRadioMeasurementRequest;
 
-#define DOT11F_RADIOMEASUREMENTREQUEST ( 42 )
+#define DOT11F_RADIOMEASUREMENTREQUEST ( 43 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7380,7 +7454,7 @@
     tDot11fIEQosMapSet          QosMapSet;
 } tDot11fReAssocRequest;
 
-#define DOT11F_REASSOCREQUEST ( 43 )
+#define DOT11F_REASSOCREQUEST ( 44 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7430,7 +7504,7 @@
     tDot11fIEQosMapSet          QosMapSet;
 } tDot11fReAssocResponse;
 
-#define DOT11F_REASSOCRESPONSE ( 44 )
+#define DOT11F_REASSOCRESPONSE ( 45 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7450,7 +7524,7 @@
     tDot11fFfSMPowerModeSet SMPowerModeSet;
 } tDot11fSMPowerSave;
 
-#define DOT11F_SMPOWERSAVE ( 45 )
+#define DOT11F_SMPOWERSAVE ( 46 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7470,7 +7544,7 @@
     tDot11fFfTransactionId TransactionId;
 } tDot11fSaQueryReq;
 
-#define DOT11F_SAQUERYREQ ( 46 )
+#define DOT11F_SAQUERYREQ ( 47 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7490,7 +7564,7 @@
     tDot11fFfTransactionId TransactionId;
 } tDot11fSaQueryRsp;
 
-#define DOT11F_SAQUERYRSP ( 47 )
+#define DOT11F_SAQUERYRSP ( 48 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7511,7 +7585,7 @@
     tDot11fIELinkIdentifier LinkIdentifier;
 } tDot11fTDLSDisReq;
 
-#define DOT11F_TDLSDISREQ ( 48 )
+#define DOT11F_TDLSDISREQ ( 49 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7545,7 +7619,7 @@
     tDot11fIEVHTCaps              VHTCaps;
 } tDot11fTDLSDisRsp;
 
-#define DOT11F_TDLSDISRSP ( 49 )
+#define DOT11F_TDLSDISRSP ( 50 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7568,7 +7642,7 @@
     tDot11fIEPUBufferStatus PUBufferStatus;
 } tDot11fTDLSPeerTrafficInd;
 
-#define DOT11F_TDLSPEERTRAFFICIND ( 50 )
+#define DOT11F_TDLSPEERTRAFFICIND ( 51 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7589,7 +7663,7 @@
     tDot11fIELinkIdentifier LinkIdentifier;
 } tDot11fTDLSPeerTrafficRsp;
 
-#define DOT11F_TDLSPEERTRAFFICRSP ( 51 )
+#define DOT11F_TDLSPEERTRAFFICRSP ( 52 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7620,7 +7694,7 @@
     tDot11fIEOperatingMode        OperatingMode;
 } tDot11fTDLSSetupCnf;
 
-#define DOT11F_TDLSSETUPCNF ( 52 )
+#define DOT11F_TDLSSETUPCNF ( 53 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7658,7 +7732,7 @@
     tDot11fIEVHTCaps              VHTCaps;
 } tDot11fTDLSSetupReq;
 
-#define DOT11F_TDLSSETUPREQ ( 53 )
+#define DOT11F_TDLSSETUPREQ ( 54 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7698,7 +7772,7 @@
     tDot11fIEOperatingMode        OperatingMode;
 } tDot11fTDLSSetupRsp;
 
-#define DOT11F_TDLSSETUPRSP ( 54 )
+#define DOT11F_TDLSSETUPRSP ( 55 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7720,7 +7794,7 @@
     tDot11fIELinkIdentifier LinkIdentifier;
 } tDot11fTDLSTeardown;
 
-#define DOT11F_TDLSTEARDOWN ( 55 )
+#define DOT11F_TDLSTEARDOWN ( 56 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7741,7 +7815,7 @@
     tDot11fIETPCReport   TPCReport;
 } tDot11fTPCReport;
 
-#define DOT11F_TPCREPORT ( 56 )
+#define DOT11F_TPCREPORT ( 57 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7762,7 +7836,7 @@
     tDot11fIETPCRequest  TPCRequest;
 } tDot11fTPCRequest;
 
-#define DOT11F_TPCREQUEST ( 57 )
+#define DOT11F_TPCREQUEST ( 58 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7783,7 +7857,7 @@
     tDot11fFfVhtUserPositionArray     VhtUserPositionArray;
 } tDot11fVHTGidManagementActionFrame;
 
-#define DOT11F_VHTGIDMANAGEMENTACTIONFRAME ( 58 )
+#define DOT11F_VHTGIDMANAGEMENTACTIONFRAME ( 59 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7806,7 +7880,7 @@
     tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet;
 } tDot11fWMMAddTSRequest;
 
-#define DOT11F_WMMADDTSREQUEST ( 59 )
+#define DOT11F_WMMADDTSREQUEST ( 60 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7829,7 +7903,7 @@
     tDot11fIEESETrafStrmMet ESETrafStrmMet;
 } tDot11fWMMAddTSResponse;
 
-#define DOT11F_WMMADDTSRESPONSE ( 60 )
+#define DOT11F_WMMADDTSRESPONSE ( 61 )
 
 #ifdef __cplusplus
 extern "C" {
@@ -7851,7 +7925,7 @@
     tDot11fIEWMMTSPEC    WMMTSPEC;
 } tDot11fWMMDelTS;
 
-#define DOT11F_WMMDELTS ( 61 )
+#define DOT11F_WMMDELTS ( 62 )
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 1bb4a91..052e04d 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -636,35 +636,51 @@
 #define SIR_HAL_DHCP_STOP_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 205)
 #define SIR_HAL_IBSS_PEER_INACTIVITY_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 206)
 
-#define SIR_HAL_LPHB_WAIT_EXPIRE_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 207)
+#define SIR_HAL_LPHB_CONF_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 207)
+#define SIR_HAL_LPHB_WAIT_EXPIRE_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 208)
 
-#define SIR_HAL_ADD_PERIODIC_TX_PTRN_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 208)
-#define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 209)
+#define SIR_HAL_ADD_PERIODIC_TX_PTRN_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 209)
+#define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 210)
 
-#ifdef FEATURE_WLAN_BATCH_SCAN
-#define SIR_HAL_SET_BATCH_SCAN_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 210)
-#define SIR_HAL_SET_BATCH_SCAN_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 211)
-#define SIR_HAL_STOP_BATCH_SCAN_IND        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 212)
-#define SIR_HAL_TRIGGER_BATCH_SCAN_RESULT_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 213)
-#endif
+#ifdef WLAN_FEATURE_RMC
+#define SIR_HAL_RMC_BECOME_RULER          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 211)
+#define SIR_HAL_RMC_RULER_SELECT_RESP     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 212)
+#define SIR_HAL_RMC_RULER_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 213)
+#define SIR_HAL_RMC_UPDATE_IND             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 214)
+
+/* For IBSS peer info related messages */
+#define SIR_HAL_IBSS_PEER_INFO_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 215)
+#define SIR_HAL_IBSS_PEER_INFO_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 216)
+#endif /* WLAN_FEATURE_RMC */
 
 #define SIR_HAL_RATE_UPDATE_IND            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 217)
-#define SIR_HAL_START_SCAN_OFFLOAD_REQ     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 218)
-#define SIR_HAL_START_SCAN_OFFLOAD_RSP     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 219)
-#define SIR_HAL_UPDATE_CHAN_LIST_REQ       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 220)
 
-#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ \
-        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 221)
-#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_RSP \
-        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 222)
+#ifdef FEATURE_WLAN_BATCH_SCAN
+#define SIR_HAL_SET_BATCH_SCAN_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 218)
+#define SIR_HAL_SET_BATCH_SCAN_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 219)
+#define SIR_HAL_STOP_BATCH_SCAN_IND        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 220)
+#define SIR_HAL_TRIGGER_BATCH_SCAN_RESULT_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 221)
+#endif
 
+#define SIR_HAL_START_SCAN_OFFLOAD_REQ     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 223)
+#define SIR_HAL_START_SCAN_OFFLOAD_RSP     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 224)
+#define SIR_HAL_UPDATE_CHAN_LIST_REQ       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 225)
+
+#ifdef WLAN_FEATURE_RMC
+#define SIR_HAL_TX_FAIL_MONITOR_IND         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 226)
+#endif /* WLAN_FEATURE_RMC */
 
 /* OBSS Scan start Indication to FW*/
 #define SIR_HAL_HT40_OBSS_SCAN_IND      (SIR_HAL_ITC_MSG_TYPES_BEGIN +227)
 /* OBSS Scan stop Indication to FW*/
 #define SIR_HAL_HT40_OBSS_STOP_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN +228)
 
-#define SIR_HAL_BCN_MISS_RATE_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 229)
+#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ \
+        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 229)
+#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_RSP \
+        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 230)
+
+#define SIR_HAL_BCN_MISS_RATE_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 231)
 
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
 #define SIR_HAL_LL_STATS_CLEAR_REQ      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 232)
@@ -725,20 +741,18 @@
 #define SIR_HAL_MON_START_REQ               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 269)
 #define SIR_HAL_MON_STOP_REQ                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 270)
 #define SIR_HAL_FATAL_EVENT_LOGS_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 271)
-#define SIR_HAL_LPHB_CONF_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 272)
-#define SIR_HAL_SEND_LOG_DONE_IND            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 273)
-#define SIR_HAL_LOST_LINK_PARAMS_IND         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 274)
-#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 275)
-#define SIR_HAL_FW_MEM_DUMP_REQ              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 276)
-#define SIR_HAL_RSSI_MON_START_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 277)
-#define SIR_HAL_RSSI_MON_STOP_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 278)
-#define SIR_HAL_HIGH_PRIORITY_DATA_INFO_IND  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 279)
-
-#define SIR_HAL_WIFI_CONFIG_PARAMS           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 280)
-#define SIR_HAL_START_OEM_DATA_REQ_IND_NEW   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 281)
-#define SIR_HAL_START_OEM_DATA_RSP_IND_NEW   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 282)
-#define SIR_HAL_ANTENNA_DIVERSITY_SELECTION_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 283)
-#define SIR_HAL_MODIFY_ROAM_PARAMS_IND     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 284)
+#define SIR_HAL_SEND_LOG_DONE_IND            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 272)
+#define SIR_HAL_LOST_LINK_PARAMS_IND         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 273)
+#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 274)
+#define SIR_HAL_FW_MEM_DUMP_REQ              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 275)
+#define SIR_HAL_RSSI_MON_START_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 276)
+#define SIR_HAL_RSSI_MON_STOP_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 277)
+#define SIR_HAL_HIGH_PRIORITY_DATA_INFO_IND  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 278)
+#define SIR_HAL_WIFI_CONFIG_PARAMS           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 279)
+#define SIR_HAL_START_OEM_DATA_REQ_IND_NEW   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 280)
+#define SIR_HAL_START_OEM_DATA_RSP_IND_NEW   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 281)
+#define SIR_HAL_ANTENNA_DIVERSITY_SELECTION_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 282)
+#define SIR_HAL_MODIFY_ROAM_PARAMS_IND     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 283)
 #define SIR_HAL_MSG_TYPES_END              (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 // CFG message types
diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c
index 99969da..84bbedc 100644
--- a/CORE/MAC/src/pe/lim/limApi.c
+++ b/CORE/MAC/src/pe/lim/limApi.c
@@ -762,6 +762,10 @@
     limFTOpen(pMac);
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+    limRmcInit(pMac);
+#endif /* WLAN_FEATURE_RMC */
+
     vos_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue);
 
 #if 0
@@ -857,6 +861,10 @@
     limCleanupMlm(pMac);
     limCleanupLmm(pMac);
 
+#ifdef WLAN_FEATURE_RMC
+    limRmcCleanup(pMac);
+#endif /* WLAN_FEATURE_RMC */
+
     // free up preAuth table
     if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL)
     {
diff --git a/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c b/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c
index 51d5ed9..4ca42d3 100644
--- a/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c
+++ b/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -49,6 +49,9 @@
 #include "limSendMessages.h"
 #include "limSession.h"
 #include "limIbssPeerMgmt.h"
+#ifdef WLAN_FEATURE_RMC
+#include "limRMC.h"
+#endif
 
 
 /**
@@ -820,6 +823,10 @@
 limIbssDelete(
     tpAniSirGlobal pMac,tpPESession psessionEntry)
 {
+#ifdef WLAN_FEATURE_RMC
+    limRmcIbssDelete(pMac);
+#endif /* WLAN_FEATURE_RMC */
+
     limIbssDeleteAllPeers(pMac,psessionEntry);
 
     ibss_coalesce_free(pMac);
@@ -1177,6 +1184,10 @@
             ucUcastSig = pStaDs->ucUcastSig;
             ucBcastSig = pStaDs->ucBcastSig;
 
+#ifdef WLAN_FEATURE_RMC
+            limRmcTransmitterDelete(pMac, pStaDs->staAddr);
+#endif /* WLAN_FEATURE_RMC */
+
             /* Send DEL STA only if STA id is valid, mean ADD STA was
              * success.
              */
@@ -1277,6 +1288,11 @@
                            pStaDs->ucUcastSig, pStaDs->ucBcastSig,
                            eWNI_SME_IBSS_NEW_PEER_IND,
                            psessionEntry->smeSessionId);
+
+#ifdef WLAN_FEATURE_RMC
+    limRmcTriggerRulerSelection(pMac, psessionEntry->selfMacAddr);
+#endif
+
     vos_mem_free(pAddStaParams);
 
     return eSIR_SUCCESS;
@@ -1692,6 +1708,10 @@
                     ucUcastSig = pStaDs->ucUcastSig;
                     ucBcastSig = pStaDs->ucBcastSig;
 
+#ifdef WLAN_FEATURE_RMC
+                    limRmcTransmitterDelete(pMac, pStaDs->staAddr);
+#endif /* WLAN_FEATURE_RMC */
+
                     (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry);
                     limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx,psessionEntry);
                     limReleasePeerIdx(pMac, peerIdx, psessionEntry);
diff --git a/CORE/MAC/src/pe/lim/limLogDump.c b/CORE/MAC/src/pe/lim/limLogDump.c
index 8c642b8..9280c7d 100644
--- a/CORE/MAC/src/pe/lim/limLogDump.c
+++ b/CORE/MAC/src/pe/lim/limLogDump.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -57,6 +57,10 @@
 #endif
 #include "smeInside.h"
 #include "wlan_qct_wda.h"
+#ifdef WLAN_FEATURE_RMC
+#include "wlan_qct_tl.h"
+#include "limRMC.h"
+#endif
 #include "wlan_qct_wdi_dts.h"
 
 void WDA_TimerTrafficStatsInd(tWDA_CbContext *pWDA);
@@ -1208,7 +1212,7 @@
         state = (tSirMacHTMIMOPowerSaveState) arg1;
 
     pMBMsg = vos_mem_malloc(WNI_CFG_MB_HDR_LEN + sizeof(tSirMacHTMIMOPowerSaveState));
-    if(NULL == pMBMsg)
+    if (NULL == pMBMsg)
     {
         p += log_sprintf( pMac,p, "pMBMsg is NULL\n");
         return p;
@@ -2368,6 +2372,102 @@
 }
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+
+static char *
+dump_lim_enable_rmc_data_path
+(
+    tpAniSirGlobal pMac,
+    tANI_U32 arg1,
+    tANI_U32 arg2,
+    tANI_U32 arg3,
+    tANI_U32 arg4,
+    char *p
+)
+{
+    v_MACADDR_t rmcTransmitterAddr;
+    v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL);
+
+    rmcTransmitterAddr.bytes[0] = (tANI_U8)((arg1 & 0xFF000000) >> 24);
+    rmcTransmitterAddr.bytes[1] = (tANI_U8)((arg1 & 0x00FF0000) >> 16);
+    rmcTransmitterAddr.bytes[2] = (tANI_U8)((arg1 & 0x0000FF00) >>  8);
+    rmcTransmitterAddr.bytes[3] = (tANI_U8)((arg1 & 0x000000FF));
+    rmcTransmitterAddr.bytes[4] = (tANI_U8)((arg2 & 0xFF000000) >> 24);
+    rmcTransmitterAddr.bytes[5] = (tANI_U8)((arg2 & 0x00FF0000) >> 16);
+
+    limLog(pMac, LOGE,
+        FL("Enable RMC data path for MCAST transmitter:" MAC_ADDRESS_STR),
+        MAC_ADDR_ARRAY( rmcTransmitterAddr.bytes));
+
+    /*Input format is in MAC address fromat for example
+      iwpriv wlan0 dump 0xaabbccdd 0xeeff0000 translates into enable RMC for
+      MAC address 0xaa:0xbb:0xcc:0xdd:0xee:0xff*/
+
+    /*Enable TL data path*/
+    WLANTL_EnableRMC( pVosContext, &rmcTransmitterAddr );
+
+  return p;
+}
+
+static char *
+dump_lim_disable_rmc_data_path
+(
+    tpAniSirGlobal pMac,
+    tANI_U32 arg1,
+    tANI_U32 arg2,
+    tANI_U32 arg3,
+    tANI_U32 arg4,
+    char *p
+)
+{
+    v_MACADDR_t rmcTransmitterAddr;
+    v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL);
+
+    rmcTransmitterAddr.bytes[0] = (tANI_U8)((arg1 & 0xFF000000) >> 24);
+    rmcTransmitterAddr.bytes[1] = (tANI_U8)((arg1 & 0x00FF0000) >> 16);
+    rmcTransmitterAddr.bytes[2] = (tANI_U8)((arg1 & 0x0000FF00) >>  8);
+    rmcTransmitterAddr.bytes[3] = (tANI_U8)((arg1 & 0x000000FF));
+    rmcTransmitterAddr.bytes[4] = (tANI_U8)((arg2 & 0xFF000000) >> 24);
+    rmcTransmitterAddr.bytes[5] = (tANI_U8)((arg2 & 0x00FF0000) >> 16);
+
+
+    limLog(pMac, LOGE,
+        FL("Disable RMC data path for MCAST transmitter:" MAC_ADDRESS_STR),
+        MAC_ADDR_ARRAY( rmcTransmitterAddr.bytes));
+
+    /*Input format is in MAC address fromat for example
+      iwpriv wlan0 dump 0xaabbccdd 0xeeff0000 translates into enable RMC for
+      MAC address 0xaa:0xbb:0xcc:0xdd:0xee:0xff*/
+
+    /*Disable TL data path*/
+    WLANTL_DisableRMC( pVosContext, &rmcTransmitterAddr );
+
+    return p;
+}
+
+static char *
+dump_lim_rmc_status(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2,
+             tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+    limRmcDumpStatus(pMac);
+    return p;
+}
+
+static char *
+dump_set_mcast_dup_detect(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2,
+             tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+    v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL);
+    v_U8_t enable;
+
+    enable = (tANI_U8)arg1;
+
+    /* Enable or Disable Multicast Duplicate Detection */
+    WLANTL_SetMcastDuplicateDetection( pVosContext, enable);
+
+    return p;
+}
+#endif /* WLAN_FEATURE_RMC */
 
 static char *
 dump_set_max_probe_req(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2,
@@ -2467,7 +2567,17 @@
     {369,   "PE.LIM: pkts/rateIdx: iwpriv wlan0 dump 368 <staId> <boolean to flush counter>",    dump_lim_get_pkts_rcvd_per_rate_idx},
     {370,   "PE.LIM: pkts/rssi: : iwpriv wlan0 dump 369 <staId> <boolean to flush counter>",    dump_lim_get_pkts_rcvd_per_rssi_values},
 #endif
+#ifdef WLAN_FEATURE_RMC
+    {371,   "PE.LIM: Enable RMC data path in TL for input MCAST addr",
+        dump_lim_enable_rmc_data_path },
+    {372,   "PE.LIM: Disable RMC data path in TL for input MCAST addr",
+        dump_lim_disable_rmc_data_path },
+    {373,   "PE.LIM: Dump RMC transmitter and ruler status", dump_lim_rmc_status },
+#endif /* WLAN_FEATURE_RMC */
     {374,   "PE.LIM: MAS RX stats MAC eff <MAC eff in percentage>",  dump_limRateInfoBasedOnMacEff},
+#ifdef WLAN_FEATURE_RMC
+    {375,   "PE.LIM: Enable(1)/Disable(0) RMC duplicate detection", dump_set_mcast_dup_detect },
+#endif /* WLAN_FEATURE_RMC */
     {376,   "PE.LIM: max number of probe per scan", dump_set_max_probe_req },
 };
 
diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index ff2d70e..ddff1c1 100644
--- a/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -59,6 +59,9 @@
 #include "rrmApi.h"
 #endif
 #include "limSessionUtils.h"
+#ifdef WLAN_FEATURE_RMC
+#include "limRMC.h"
+#endif
 
 #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
 #include "eseApi.h"
@@ -2455,7 +2458,8 @@
         }
         break;
 #endif
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) \
+    || defined (WLAN_FEATURE_RMC)
         case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY:
             {
               tpSirMacVendorSpecificFrameHdr pVendorSpecific = (tpSirMacVendorSpecificFrameHdr) pActionHdr;
@@ -2479,6 +2483,57 @@
                                          pRxPacketInfo,
                                          psessionEntry, 0);
               }
+#if defined (WLAN_FEATURE_RMC)
+              else if ((eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) &&
+                  ((VOS_TRUE == vos_mem_compare(SIR_MAC_RMC_MCAST_ADDRESS,
+                    &pHdr->da[0], sizeof(tSirMacAddr))) ||
+                   (VOS_TRUE == vos_mem_compare(psessionEntry->selfMacAddr,
+                     &pHdr->da[0], sizeof(tSirMacAddr)))) &&
+                   vos_mem_compare(pVendorSpecific->Oui, SIR_MAC_RMC_OUI, 3))
+              {
+                  tANI_U8 MagicCode[] =
+                         { 0x4f, 0x58, 0x59, 0x47, 0x45, 0x4e };
+                  tpSirMacIbssExtNetworkFrameHdr pIbssExtHdr =
+                             (tpSirMacIbssExtNetworkFrameHdr) pActionHdr;
+
+                  if (vos_mem_compare(pIbssExtHdr->MagicCode,
+                      MagicCode, sizeof(MagicCode)) &&
+                      pIbssExtHdr->version == SIR_MAC_RMC_VER )
+                  {
+                      switch (pIbssExtHdr->actionID)
+                      {
+                          default:
+                              PELOGE(limLog(pMac, LOGE,
+                                 FL("Action RMC actionID %d not handled"),
+                                     pIbssExtHdr->actionID);)
+                              break;
+                          case SIR_MAC_RMC_RULER_INFORM_SELECTED:
+                              limLog(pMac, LOG1,
+                                 FL("Action RMC RULER_INFORM_SELECTED."));
+                              limProcessRMCMessages(pMac,
+                                 eLIM_RMC_OTA_RULER_INFORM_SELECTED,
+                                 (tANI_U32 *)pRxPacketInfo);
+                              break;
+                          case SIR_MAC_RMC_RULER_INFORM_CANCELLED:
+                              limLog(pMac, LOG1,
+                                 FL("Action RMC RULER_INFORM_CANCELLED."));
+                              limProcessRMCMessages(pMac,
+                                 eLIM_RMC_OTA_RULER_INFORM_CANCELLED,
+                                 (tANI_U32 *)pRxPacketInfo);
+                              break;
+                      }
+                  }
+                  else
+                  {
+                      limLog( pMac, LOG1,
+                         FL("Dropping the vendor specific action frame in IBSS "
+                             "mode because of Ibss Ext Magic mismatch "
+                             MAC_ADDRESS_STR " or Version mismatch = %d"),
+                             MAC_ADDR_ARRAY(pIbssExtHdr->MagicCode),
+                             pIbssExtHdr->version );
+                  }
+              }
+#endif /* WLAN_FEATURE_RMC */
               else
               {
                  limLog( pMac, LOG1,
@@ -2492,7 +2547,8 @@
               }
            }
            break;
-#endif
+#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE ||
+          FEATURE_WLAN_LFR || WLAN_FEATURE_RMC */
     case SIR_MAC_ACTION_PUBLIC_USAGE:
         switch(pActionHdr->actionID) {
         case SIR_MAC_ACTION_VENDOR_SPECIFIC:
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index a47669e..93cd651 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -75,6 +75,10 @@
 #include "wmmApsd.h"
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+#include "limRMC.h"
+#endif
+
 #include "vos_types.h"
 #include "vos_packet.h"
 #include "vos_memory.h"
@@ -1607,6 +1611,17 @@
             limMsg->bodyptr = NULL;
             break;
 
+#ifdef WLAN_FEATURE_RMC
+        case eWNI_SME_ENABLE_RMC_REQ:
+        case eWNI_SME_DISABLE_RMC_REQ:
+            /*
+             * These messages are from HDD
+             * No need to response to hdd
+             */
+            limProcessSmeReqMessages(pMac,limMsg);
+            break;
+#endif /* WLAN_FEATURE_RMC */
+
         case SIR_HAL_P2P_NOA_START_IND:
         {
             tpPESession psessionEntry = &pMac->lim.gpSession[0];
@@ -2292,6 +2307,28 @@
        limMsg->bodyptr = NULL;
        break;
     }
+#ifdef WLAN_FEATURE_RMC
+    case WDA_RMC_BECOME_RULER:
+        limProcessRMCMessages(pMac, eLIM_RMC_BECOME_RULER_RESP,
+                          (void *)limMsg->bodyptr);
+        vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+        limMsg->bodyptr = NULL;
+        break ;
+
+    case WDA_RMC_RULER_SELECT_RESP:
+        limProcessRMCMessages(pMac, eLIM_RMC_RULER_SELECT_RESP,
+                          (void *)limMsg->bodyptr);
+        vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+        limMsg->bodyptr = NULL;
+        break ;
+
+    case WDA_RMC_UPDATE_IND:
+        limProcessRMCMessages(pMac, eLIM_RMC_RULER_PICK_NEW,
+                          (void *)limMsg->bodyptr);
+        vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+        limMsg->bodyptr = NULL;
+        break ;
+#endif /* WLAN_FEATURE_RMC */
 
     case WDA_SPOOF_MAC_ADDR_RSP:
        limProcessMlmSpoofMacAddrRsp(pMac, (tSirRetStatus)limMsg->bodyval);
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 3a33168..f1378bf 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -59,6 +59,10 @@
 #include "limApi.h"
 #include "wmmApsd.h"
 
+#ifdef WLAN_FEATURE_RMC
+#include "limRMC.h"
+#endif
+
 #include "sapApi.h"
 
 #if defined WLAN_FEATURE_VOWIFI
@@ -5843,6 +5847,16 @@
             limSendSetTxPowerReq(pMac,  pMsgBuf);
             break ;
 
+#ifdef WLAN_FEATURE_RMC
+        case eWNI_SME_ENABLE_RMC_REQ:
+            limProcessRMCMessages(pMac, eLIM_RMC_ENABLE_REQ, pMsgBuf);
+            break ;
+
+        case eWNI_SME_DISABLE_RMC_REQ:
+            limProcessRMCMessages(pMac, eLIM_RMC_DISABLE_REQ, pMsgBuf);
+            break ;
+#endif /* WLAN_FEATURE_RMC */
+
         case eWNI_SME_MAC_SPOOF_ADDR_IND:
             __limProcessSmeSpoofMacAddrRequest(pMac,  pMsgBuf);
             break ;
diff --git a/CORE/MAC/src/pe/lim/limRMC.c b/CORE/MAC/src/pe/lim/limRMC.c
new file mode 100644
index 0000000..86b302e
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limRMC.c
@@ -0,0 +1,1382 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file limRMC.c contains the code
+ * for processing RMC messages
+ *
+ */
+#include "wniApi.h"
+#include "wniCfg.h"
+#include "cfgApi.h"
+#include "sirApi.h"
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limUtils.h"
+#include "limTimerUtils.h"
+#include "limSendMessages.h"
+#include "limSendMessages.h"
+#include "limSession.h"
+#include "limSessionUtils.h"
+#include "wlan_qct_wda.h"
+#include "wlan_qct_tli.h"
+#include "limRMC.h"
+
+#ifdef WLAN_FEATURE_RMC
+
+static tANI_U8
+__rmcGroupHashFunction(tSirMacAddr transmitter)
+{
+    tANI_U16 hash;
+
+    /*
+     * Generate a hash using transmitter address
+     */
+    hash = transmitter[0] + transmitter[1] + transmitter[2] +
+            transmitter[3] + transmitter[4] + transmitter[5];
+
+    return hash & (RMC_MCAST_GROUPS_HASH_SIZE - 1);
+}
+
+
+static tLimRmcGroupContext *
+__rmcGroupLookupHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
+{
+    tANI_U8 index;
+    tLimRmcGroupContext *entry;
+
+    index = __rmcGroupHashFunction(transmitter);
+
+    /* Pick the correct hash table based on role */
+    entry = pMac->rmcContext.rmcGroupRxHashTable[index];
+
+    PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Lookup:[%d] transmitter "
+                         MAC_ADDRESS_STR ), index,
+                         MAC_ADDR_ARRAY(transmitter));)
+    while (entry)
+    {
+        if (vos_mem_compare(transmitter, entry->transmitter,
+             sizeof(v_MACADDR_t)))
+        {
+            return entry;
+        }
+
+        entry = entry->next;
+    }
+
+    return NULL;
+}
+
+static tLimRmcGroupContext *
+__rmcGroupInsertHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
+{
+    tANI_U8 index;
+    tLimRmcGroupContext *entry;
+    tLimRmcGroupContext **head;
+
+    index = __rmcGroupHashFunction(transmitter);
+
+    PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:[%d] group " MAC_ADDRESS_STR
+                             " transmitter " MAC_ADDRESS_STR), index,
+                             MAC_ADDR_ARRAY(mcastGroupAddr),
+                             MAC_ADDR_ARRAY(transmitter));)
+
+    head = &pMac->rmcContext.rmcGroupRxHashTable[index];
+
+    entry = __rmcGroupLookupHashEntry(pMac, transmitter);
+
+    if (entry)
+    {
+        /* If the entry exists, return it at the end */
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:"
+                 MAC_ADDRESS_STR "exists"), MAC_ADDR_ARRAY(transmitter));)
+    }
+    else
+    {
+        entry = (tLimRmcGroupContext *)vos_mem_malloc(sizeof(*entry));
+
+        PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:new entry %p"), entry);)
+
+        if (entry)
+        {
+            vos_mem_copy(entry->transmitter, transmitter, sizeof(tSirMacAddr));
+            entry->isRuler = eRMC_IS_NOT_A_RULER;
+
+            /* chain this entry */
+            entry->next = *head;
+            *head = entry;
+        }
+        else
+        {
+            PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:" MAC_ADDRESS_STR
+                             " alloc failed"), MAC_ADDR_ARRAY(transmitter));)
+        }
+    }
+
+    return entry;
+}
+
+/**
+ *  __rmcGroupDeleteHashEntry()
+ *
+ *FUNCTION:
+ * This function is called to delete a RMC group entry
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *  Should be called with lkRmcLock held.
+ *
+ *NOTE:
+ * Make sure (for the transmitter role) that the entry is
+ * not in the Pending Response queue.
+ *
+ * @param  transmitter - address of multicast transmitter
+ *
+ * @return status
+ */
+static tSirRetStatus
+__rmcGroupDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
+{
+    tSirRetStatus status = eSIR_FAILURE;
+    tANI_U8 index;
+    tLimRmcGroupContext *entry, *prev, **head;
+
+    index = __rmcGroupHashFunction(transmitter);
+
+    head = &pMac->rmcContext.rmcGroupRxHashTable[index];
+    entry = *head;
+    prev = NULL;
+
+    while (entry)
+    {
+        if (vos_mem_compare(transmitter, entry->transmitter,
+             sizeof(v_MACADDR_t)))
+        {
+            if (*head == entry)
+            {
+                *head = entry->next;
+            }
+            else
+            {
+                prev->next = entry->next;
+            }
+
+            PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Delete: entry %p "
+                         " transmitter " MAC_ADDRESS_STR), entry
+                             MAC_ADDR_ARRAY(transmitter));)
+
+            /* free the group entry */
+            vos_mem_free(entry);
+
+            status = eSIR_SUCCESS;
+            break;
+        }
+
+        prev = entry;
+        entry = entry->next;
+    }
+
+    return status;
+}
+
+static void
+__rmcGroupDeleteAllEntries(tpAniSirGlobal pMac)
+{
+    tLimRmcGroupContext *entry, **head;
+    int index;
+
+    PELOG1(limLog(pMac, LOG1, FL("RMC: Hash_Delete_All"),);)
+
+    for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++)
+    {
+        head = &pMac->rmcContext.rmcGroupRxHashTable[index];
+
+        entry = *head;
+
+        while (entry)
+        {
+            *head = entry->next;
+            /* free the group entry */
+            vos_mem_free(entry);
+            entry = *head;
+        }
+    }
+}
+
+static void
+__limPostMsgRulerReq ( tpAniSirGlobal pMac,
+                        tANI_U8 cmd,
+                        tSirMacAddr mcastTransmitter)
+{
+    tSirMsgQ msg;
+    tSirRmcRulerReq *pRulerReq;
+
+    pRulerReq = vos_mem_malloc(sizeof(*pRulerReq));
+    if (NULL == pRulerReq)
+    {
+       limLog(pMac, LOGE, FL("AllocateMemory() failed"));
+       return;
+    }
+
+    pRulerReq->cmd = cmd;
+
+    vos_mem_copy(pRulerReq->mcastTransmitter, mcastTransmitter,
+                 sizeof(tSirMacAddr));
+
+    /* Initialize black list */
+    vos_mem_zero(pRulerReq->blacklist, sizeof(pRulerReq->blacklist));
+
+    if (eRMC_SUGGEST_RULER_CMD == cmd)
+    {
+        /* TODO - Set the black list. */
+    }
+
+    msg.type = WDA_RMC_RULER_REQ;
+    msg.bodyptr = pRulerReq;
+    msg.bodyval = 0;
+
+    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));
+    if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+    {
+        vos_mem_free(pRulerReq);
+        limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));
+    }
+
+    return;
+}
+
+static void
+__limPostMsgUpdateInd ( tpAniSirGlobal pMac,
+                        tANI_U8 indication,
+                        tANI_U8 role,
+                        tSirMacAddr mcastTransmitter,
+                        tSirMacAddr mcastRuler)
+{
+    tSirMsgQ msg;
+    tSirRmcUpdateInd *pUpdateInd;
+
+    pUpdateInd = vos_mem_malloc(sizeof(*pUpdateInd));
+    if ( NULL == pUpdateInd )
+    {
+       limLog(pMac, LOGE, FL("AllocateMemory() failed"));
+       return;
+    }
+
+    vos_mem_zero(pUpdateInd, sizeof(*pUpdateInd));
+
+    pUpdateInd->indication = indication;
+    pUpdateInd->role = role;
+
+    vos_mem_copy(pUpdateInd->mcastTransmitter,
+            mcastTransmitter, sizeof(tSirMacAddr));
+
+    vos_mem_copy(pUpdateInd->mcastRuler,
+            mcastRuler, sizeof(tSirMacAddr));
+
+    msg.type = WDA_RMC_UPDATE_IND;
+    msg.bodyptr = pUpdateInd;
+    msg.bodyval = 0;
+
+    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));
+    if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+    {
+        vos_mem_free(pUpdateInd);
+        limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));
+    }
+
+    return;
+}
+
+static char *
+__limRulerMessageToString(eRmcMessageType msgType)
+{
+    switch (msgType)
+    {
+        default:
+            return "Invalid";
+        case eLIM_RMC_ENABLE_REQ:
+            return "RMC_ENABLE_REQ";
+        case eLIM_RMC_DISABLE_REQ:
+            return "RMC_DISABLE_REQ";
+        case eLIM_RMC_RULER_SELECT_RESP:
+            return "RMC_RULER_SELECT_RESP";
+        case eLIM_RMC_RULER_PICK_NEW:
+            return "RMC_RULER_PICK_NEW";
+        case eLIM_RMC_OTA_RULER_INFORM_ACK:
+            return "RMC_OTA_RULER_INFORM_ACK";
+        case eLIM_RMC_OTA_RULER_INFORM_SELECTED:
+            return "RMC_OTA_RULER_INFORM_SELECTED";
+        case eLIM_RMC_BECOME_RULER_RESP:
+            return "RMC_BECOME_RULER_RESP";
+        case eLIM_RMC_OTA_RULER_INFORM_CANCELLED:
+            return "RMC_OTA_RULER_INFORM_CANCELLED";
+    }
+}
+
+static char *
+__limRulerStateToString(eRmcRulerState state)
+{
+    switch (state)
+    {
+        default:
+            return "Invalid";
+        case eRMC_IS_NOT_A_RULER:
+            return "Device Not a Ruler";
+        case eRMC_RULER_PENDING:
+            return "Pending firmware resp";
+        case eRMC_IS_A_RULER:
+            return "Device is Ruler";
+    }
+}
+
+static char *
+__limMcastTxStateToString(eRmcMcastTxState state)
+{
+    switch (state)
+    {
+        default:
+            return "Invalid";
+        case eRMC_RULER_NOT_SELECTED:
+            return "Not Selected";
+        case eRMC_RULER_ENABLE_REQUESTED:
+            return "Enable Requested";
+        case eRMC_RULER_OTA_REQUEST_SENT:
+            return "OTA Request Sent";
+        case eRMC_RULER_ACTIVE:
+            return "Active";
+    }
+}
+
+/**
+ * __rmcRulerSelectTimerHandler()
+ *
+ *FUNCTION:
+ * This function is called upon timer expiry.
+ *
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * Only one entry is processed for every invocation if this routine.
+ * This allows us to use a single timer and makes sure we do not
+ * timeout a request too early.
+ *
+ * @param  param - Message corresponding to the timer that expired
+ *
+ * @return None
+ */
+
+void
+__rmcRulerSelectTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+    tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+    tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
+    tSirRetStatus status;
+    tSirRMCInfo RMC;
+    tpPESession psessionEntry;
+    tANI_U32 cfgValue;
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE,
+             FL("RMC:__rmcRulerSelectTimerHandler:No active IBSS"));)
+        return;
+    }
+
+    if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
+                  &cfgValue) != eSIR_SUCCESS)
+    {
+        /**
+         * Could not get Action Period Frequency value
+         * from CFG. Log error.
+         */
+        limLog(pMac, LOGE, FL("could not retrieve ActionPeriodFrequency"));
+    }
+
+    cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+    if (pMac->rmcContext.rmcTimerValInTicks != cfgValue)
+    {
+        limLog(pMac, LOG1, FL("RMC RulerSelect timer value changed"));
+        if (tx_timer_change(&pMac->rmcContext.gRmcRulerSelectTimer,
+                 cfgValue, 0) != TX_SUCCESS)
+        {
+            limLog(pMac, LOGE,
+                FL("Unable to change RulerSelect Timer val"));
+        }
+        pMac->rmcContext.rmcTimerValInTicks = cfgValue;
+    }
+
+    /*
+     * If we are in the scanning state then we need to return
+     * from this function without any further processing
+     */
+    if (eLIM_HAL_SCANNING_STATE == pMac->lim.gLimHalScanState)
+    {
+        limLog(pMac, LOG1, FL("In scanning state, can't send action frm"));
+        if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer) !=
+            TX_SUCCESS)
+        {
+            limLog(pMac, LOGE, FL("In scanning state, "
+                                  "couldn't activate RMC RulerSelect timer"));
+        }
+        return;
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+             FL("__rmcRulerSelectTimerHandler lock acquire failed"));
+        if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS)
+        {
+            limLog(pMac, LOGE, FL("could not activate RMC RulerSelect timer"));
+        }
+        return;
+    }
+
+    vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler,
+                     sizeof(tSirMacAddr));
+
+    if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
+                            &pMac->rmcContext.ruler, sizeof(tSirMacAddr)))
+    {
+        limLog(pMac, LOG1,
+               FL("RMC Periodic Ruler_Select Ruler " MAC_ADDRESS_STR),
+                   MAC_ADDR_ARRAY(pMac->rmcContext.ruler));
+        /*
+         * Re-arm timer
+         */
+        if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!=
+            TX_SUCCESS)
+        {
+            limLog(pMac, LOGE, FL("could not activate RMC Response timer"));
+        }
+
+        if (!VOS_IS_STATUS_SUCCESS
+                (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+        {
+            limLog(pMac, LOGE,
+                FL("RMC: __rmcRulerSelectTimerHandler lock release failed"));
+        }
+    }
+    else
+    {
+        limLog(pMac, LOGE,
+               FL("RMC Deactivating timer because no ruler was selected"));
+
+        if (!VOS_IS_STATUS_SUCCESS
+                (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+        {
+            limLog(pMac, LOGE,
+                FL("RMC: __rmcRulerSelectTimerHandler lock release failed"));
+        }
+
+        return;
+    }
+
+    RMC.dialogToken = 0;
+    RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED;
+
+    status = limSendRMCActionFrame(pMac,
+                          SIR_MAC_RMC_MCAST_ADDRESS,
+                          &RMC,
+                          psessionEntry);
+
+    if (eSIR_FAILURE == status)
+    {
+        PELOGE(limLog(pMac, LOGE,
+         FL("RMC:__rmcRulerSelectTimerHandler Action frame send failed"));)
+    }
+
+    return;
+}
+
+static void
+__limProcessRMCEnableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf;
+    tpPESession psessionEntry;
+
+    if (!setRmcReq)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Enable:NULL message") );)
+        return;
+    }
+
+    pMac->rmcContext.rmcEnabled = TRUE;
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC:Enable RMC request no active IBSS"));)
+        pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
+        return;
+    }
+
+    /* Send RULER_REQ to f/w */
+    __limPostMsgRulerReq(pMac, eRMC_SUGGEST_RULER_CMD,
+                        setRmcReq->mcastTransmitter);
+
+    pMac->rmcContext.state = eRMC_RULER_ENABLE_REQUESTED;
+}
+
+static void
+__limProcessRMCDisableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tpPESession psessionEntry;
+    tSirRMCInfo RMC;
+    tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf;
+    tSirRetStatus status;
+    v_PVOID_t pvosGCtx;
+    VOS_STATUS vos_status;
+    v_MACADDR_t vosMcastTransmitter;
+
+    pMac->rmcContext.rmcEnabled = FALSE;
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:No active IBSS"));)
+        return;
+    }
+
+    if (!setRmcReq)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:NULL message") );)
+        return;
+    }
+
+    /* Cancel pending timer */
+    tx_timer_deactivate(&pMac->rmcContext.gRmcRulerSelectTimer);
+
+    vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
+    vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
+    vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
+    vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
+    vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
+    vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
+
+    pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
+    vos_status = WLANTL_DisableRMC(pvosGCtx, &vosMcastTransmitter);
+
+    if (VOS_STATUS_SUCCESS != vos_status)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: TL disable failed"));)
+    }
+
+    if (pMac->rmcContext.state == eRMC_RULER_ACTIVE)
+    {
+        RMC.dialogToken = 0;
+        RMC.action = SIR_MAC_RMC_RULER_INFORM_CANCELLED;
+        vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler, sizeof(tSirMacAddr));
+
+        status = limSendRMCActionFrame(pMac, pMac->rmcContext.ruler,
+                             &RMC, psessionEntry);
+        if (eSIR_FAILURE == status)
+        {
+            PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: Action frame send failed"));)
+        }
+
+        pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
+    }
+
+    __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED, eRMC_TRANSMITTER_ROLE,
+                         setRmcReq->mcastTransmitter, pMac->rmcContext.ruler);
+
+    vos_mem_zero(pMac->rmcContext.ruler, sizeof(tSirMacAddr));
+
+}
+
+static void
+__limProcessRMCRulerSelectResponse(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tSirRmcRulerSelectInd *pRmcRulerSelectInd;
+    tpPESession psessionEntry;
+    tSirRetStatus status;
+    v_PVOID_t pvosGCtx;
+    VOS_STATUS vos_status;
+    v_MACADDR_t vosMcastTransmitter;
+    tSirRMCInfo RMC;
+
+    if (NULL == pMsgBuf)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp:NULL message"));)
+        return;
+    }
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:No active IBSS"));)
+        pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
+        return;
+    }
+
+    pRmcRulerSelectInd = (tSirRmcRulerSelectInd *)pMsgBuf;
+
+    if (pMac->rmcContext.state != eRMC_RULER_ENABLE_REQUESTED)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp:Bad state %s"),
+                        __limMcastTxStateToString(pMac->rmcContext.state) );)
+        return;
+    }
+
+    if (pRmcRulerSelectInd->status)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:FW Status %d"),
+                        pRmcRulerSelectInd->status);)
+        pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
+        return;
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:lock acquire failed"));
+        pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
+        return;
+    }
+
+    vos_mem_copy(&pMac->rmcContext.ruler, &pRmcRulerSelectInd->ruler[0],
+                 sizeof(tSirMacAddr));
+
+    if (!VOS_IS_STATUS_SUCCESS
+            (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp: lock release failed"));
+    }
+
+    RMC.dialogToken = 0;
+    RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED;
+    vos_mem_copy(&RMC.mcastRuler, &pRmcRulerSelectInd->ruler[0],
+                 sizeof(tSirMacAddr));
+
+    PELOG1(limLog(pMac, LOG1, FL("RMC: Ruler_Select :ruler " MAC_ADDRESS_STR),
+             MAC_ADDR_ARRAY(pRmcRulerSelectInd->ruler[0]));)
+
+    status = limSendRMCActionFrame(pMac,
+                          SIR_MAC_RMC_MCAST_ADDRESS,
+                          &RMC,
+                          psessionEntry);
+
+    if (eSIR_FAILURE == status)
+    {
+        PELOGE(limLog(pMac, LOGE,
+         FL("RMC: Ruler_Select_Resp: Action send failed"));)
+    }
+
+    __limPostMsgUpdateInd(pMac, eRMC_RULER_ACCEPTED, eRMC_TRANSMITTER_ROLE,
+                 psessionEntry->selfMacAddr, pMac->rmcContext.ruler);
+
+    vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
+    vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
+    vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
+    vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
+    vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
+    vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
+
+    /* Enable TL */
+    pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
+    vos_status = WLANTL_EnableRMC(pvosGCtx, &vosMcastTransmitter);
+
+    pMac->rmcContext.state = eRMC_RULER_ACTIVE;
+
+    if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS)
+    {
+        limLog(pMac, LOGE,
+         FL("Ruler_Select_Resp:Activate RMC Response timer failed"));
+    }
+}
+
+static void
+__limProcessRMCRulerPickNew(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tSirRmcUpdateInd *pRmcUpdateInd;
+    tpPESession psessionEntry;
+    tSirRetStatus status;
+    tSirRMCInfo RMC;
+    v_PVOID_t pvosGCtx;
+    VOS_STATUS vos_status;
+    v_MACADDR_t vosMcastTransmitter;
+    tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
+
+    if (NULL == pMsgBuf)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Pick_New:NULL message"));)
+        return;
+    }
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Pick_New:No active IBSS"));)
+        return;
+    }
+
+    pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
+
+    pRmcUpdateInd = (tSirRmcUpdateInd *)pMsgBuf;
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE, FL("RMC:Ruler_Pick_New:lock acquire failed"));
+        return;
+    }
+
+
+    /* Fill out Action frame parameters */
+    RMC.dialogToken = 0;
+
+    if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
+                        &pRmcUpdateInd->mcastRuler,
+                        sizeof(tSirMacAddr)))
+    {
+
+        vos_mem_copy(&RMC.mcastRuler, &pRmcUpdateInd->mcastRuler,
+                     sizeof(tSirMacAddr));
+
+        RMC.action = SIR_MAC_RMC_RULER_INFORM_CANCELLED;
+        status = limSendRMCActionFrame(pMac,
+                         pRmcUpdateInd->mcastRuler,
+                         &RMC, psessionEntry);
+        if (eSIR_FAILURE == status)
+        {
+            PELOGE(limLog(pMac, LOGE,
+                FL("RMC:Ruler_Pick_New: Inform_Cancel Action send failed"));)
+            goto done;
+        }
+
+        vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
+        vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
+        vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
+        vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
+        vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
+        vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
+
+        vos_status = WLANTL_DisableRMC(pvosGCtx, &vosMcastTransmitter);
+
+        if (VOS_STATUS_SUCCESS != vos_status)
+        {
+            PELOGE(limLog(pMac, LOGE,
+                 FL("RMC:Ruler_Pick_New: TL disable failed"));)
+        }
+    }
+
+    vos_mem_copy(pMac->rmcContext.ruler, pRmcUpdateInd->ruler[0],
+                 sizeof(tSirMacAddr));
+
+    pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
+
+    if (VOS_TRUE == vos_mem_compare(&zeroMacAddr,
+                        pMac->rmcContext.ruler,
+                        sizeof(tSirMacAddr)))
+    {
+        PELOGE(limLog(pMac, LOGE,
+           FL("RMC:Ruler_Pick_New: No candidate rulers available"));)
+        goto done;
+    }
+
+
+    RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED;
+    vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler,
+                     sizeof(tSirMacAddr));
+    status = limSendRMCActionFrame(pMac, SIR_MAC_RMC_MCAST_ADDRESS,
+                         &RMC, psessionEntry);
+    if (eSIR_FAILURE == status)
+    {
+        PELOGE(limLog(pMac, LOGE,
+           FL("RMC:Ruler_Pick_New: Inform_Selected Action send failed"));)
+        goto done;
+    }
+
+    __limPostMsgUpdateInd(pMac, eRMC_RULER_ACCEPTED, eRMC_TRANSMITTER_ROLE,
+                         psessionEntry->selfMacAddr, pMac->rmcContext.ruler);
+
+    vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
+    vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
+    vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
+    vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
+    vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
+    vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
+
+    /* Enable TL */
+    vos_status = WLANTL_EnableRMC(pvosGCtx, &vosMcastTransmitter);
+
+    if (VOS_STATUS_SUCCESS != vos_status)
+    {
+        PELOGE(limLog(pMac, LOGE,
+            FL("RMC:Ruler_Pick_New: TL enable failed"));)
+        goto done;
+    }
+
+    pMac->rmcContext.state = eRMC_RULER_ACTIVE;
+
+    if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS)
+    {
+        limLog(pMac, LOGE,
+         FL("Ruler_Pick_New:Activate RMC Response timer failed"));
+    }
+
+done:
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+            FL("RMC: Ruler_Pick_New: lock release failed"));
+    }
+}
+
+static void
+__limProcessRMCRulerInformSelected(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tpSirMacMgmtHdr pHdr;
+    tANI_U8 *pFrameData;
+    tANI_U32 frameLen;
+    tLimRmcGroupContext *entry;
+    tpPESession psessionEntry;
+    tSirRetStatus status;
+
+    if (!pMsgBuf)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform:NULL msg"));)
+        return;
+    }
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:No active IBSS"));)
+        return;
+    }
+
+    /*
+     * Get the frame header
+     */
+    pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf);
+
+    frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf);
+    if (frameLen < sizeof(tSirMacIbssExtNetworkFrameHdr))
+    {
+        PELOGE(limLog(pMac, LOGE,
+             FL("RMC: Ruler_Inform:Bad length %d "), frameLen);)
+        return;
+    }
+
+    pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) +
+                    sizeof(tSirMacIbssExtNetworkFrameHdr);
+
+    if (!pFrameData)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform:NULL data"));)
+        return;
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:lock acquire failed"));
+        return;
+    }
+
+    /*
+     * Check if this transmitter exists in our database.
+     */
+    entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa);
+
+    if (VOS_FALSE == vos_mem_compare(pFrameData, psessionEntry->selfMacAddr,
+                                     sizeof(tSirMacAddr)))
+    {
+        if (entry)
+        {
+            PELOG1(limLog(pMac, LOG1,
+                 FL("RMC: Ruler_Inform: Ruler Cancelled"));)
+
+            __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED,
+                      eRMC_RULER_ROLE, pHdr->sa, psessionEntry->selfMacAddr);
+
+            /*
+             * Delete hash entry for this Group address.
+             */
+            status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa);
+            if (eSIR_FAILURE == status)
+            {
+                PELOGE(limLog(pMac, LOGE,
+                      FL("RMC: Ruler_Inform:hash delete failed"));)
+            }
+        }
+    }
+    else
+    {
+        if (NULL == entry)
+        {
+            /* Add the transmitter address to the hash */
+            entry = __rmcGroupInsertHashEntry(pMac, pHdr->sa);
+            if (entry)
+            {
+                if (entry->isRuler != eRMC_RULER_PENDING)
+                {
+                    __limPostMsgRulerReq(pMac, eRMC_BECOME_RULER_CMD,
+                                         pHdr->sa);
+                    entry->isRuler = eRMC_RULER_PENDING;
+                }
+            }
+            else
+            {
+                PELOGE(limLog(pMac, LOGE,
+                         FL("RMC: Ruler_Inform:Hash insert failed"));)
+            }
+
+        }
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+            FL("RMC: Ruler_Inform: lock release failed"));
+    }
+
+}
+
+static void
+__limProcessRMCBecomeRulerResp(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tSirRmcBecomeRulerInd *pRmcBecomeRulerInd;
+    tLimRmcGroupContext *entry;
+    tSirRetStatus status = eSIR_SUCCESS;
+
+    if (NULL == pMsgBuf)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp:NULL message"));)
+        return;
+    }
+
+    pRmcBecomeRulerInd = (tSirRmcBecomeRulerInd *)pMsgBuf;
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:lock acquire failed"));
+        return;
+    }
+
+    /*
+     * Find the entry for this Group Address.
+     */
+    entry = __rmcGroupLookupHashEntry(pMac,
+                  pRmcBecomeRulerInd->mcastTransmitter);
+    if (NULL == entry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp: No entry"));)
+        goto done;
+    }
+
+    if (pRmcBecomeRulerInd->status)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:FW Status %d"),
+                        pRmcBecomeRulerInd->status);)
+        status = eSIR_FAILURE;
+        goto done;
+    }
+
+    if (entry->isRuler != eRMC_RULER_PENDING)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp:Bad state: %s"),
+                        __limRulerStateToString(entry->isRuler) );)
+        status = eSIR_FAILURE;
+        goto done;
+    }
+
+    entry->isRuler = eRMC_IS_A_RULER;
+
+done:
+    if (eSIR_FAILURE == status)
+    {
+        status = __rmcGroupDeleteHashEntry(pMac,
+                       pRmcBecomeRulerInd->mcastTransmitter);
+        if (eSIR_FAILURE == status)
+        {
+            PELOGE(limLog(pMac, LOGE,
+                      FL("RMC: Become_Ruler_Resp:hash delete failed"));)
+        }
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+            FL("RMC: Become_Ruler_Resp: lock release failed"));
+    }
+
+    return;
+}
+
+static void
+__limProcessRMCRulerInformCancelled(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+    tpSirMacMgmtHdr pHdr;
+    tANI_U8 *pFrameData;
+    tANI_U32 frameLen;
+    tSirRetStatus status;
+    tLimRmcGroupContext *entry;
+    tpPESession psessionEntry;
+
+    if (!pMsgBuf)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel:NULL msg"));)
+        return;
+    }
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE,
+             FL("RMC:Ruler_Inform_Cancel:No active IBSS"));)
+        return;
+    }
+
+    pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf);
+
+    frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf);
+    if (frameLen < sizeof(tSirMacIbssExtNetworkFrameHdr))
+    {
+        PELOGE(limLog(pMac, LOGE,
+             FL("RMC: Ruler_Inform:Bad length %d "), frameLen);)
+        return;
+    }
+
+    pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) +
+                    sizeof(tSirMacIbssExtNetworkFrameHdr);
+
+    if (!pFrameData)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel:NULL data"));)
+        return;
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE, FL("RMC:Ruler_Inform_Cancel lock acquire failed"));
+        return;
+    }
+
+    /*
+     * Find the entry for this Group Address.
+     */
+    entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa);
+    if (NULL == entry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel: No entry"));)
+        goto done;
+    }
+
+    __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED,
+                     eRMC_RULER_ROLE, pHdr->sa, psessionEntry->selfMacAddr);
+
+    /*
+     * Delete hash entry for this Group address.
+     */
+    status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa);
+    if (eSIR_FAILURE == status)
+    {
+        PELOGE(limLog(pMac, LOGE,
+                  FL("RMC: Ruler_Inform_Cancel:hash delete failed"));)
+    }
+
+done:
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+            FL("RMC: Ruler_Inform_Cancel: lock release failed"));
+    }
+    return;
+}
+
+void
+limProcessRMCMessages(tpAniSirGlobal pMac, eRmcMessageType msgType,
+                      tANI_U32 *pMsgBuf)
+{
+
+    if (pMsgBuf == NULL)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: Buffer is Pointing to NULL"));)
+        return;
+    }
+
+    limLog(pMac, LOG1, FL("RMC: limProcessRMCMessages: %s"),
+                        __limRulerMessageToString(msgType));
+
+    switch (msgType)
+    {
+        case eLIM_RMC_ENABLE_REQ:
+            __limProcessRMCEnableRequest(pMac, pMsgBuf);
+            break;
+
+        case eLIM_RMC_DISABLE_REQ:
+            __limProcessRMCDisableRequest(pMac, pMsgBuf);
+            break;
+
+        case eLIM_RMC_RULER_SELECT_RESP:
+            __limProcessRMCRulerSelectResponse(pMac, pMsgBuf);
+            break;
+
+        case eLIM_RMC_RULER_PICK_NEW:
+            __limProcessRMCRulerPickNew(pMac, pMsgBuf);
+            break;
+
+        case eLIM_RMC_OTA_RULER_INFORM_SELECTED:
+            __limProcessRMCRulerInformSelected(pMac, pMsgBuf);
+            break;
+
+        case eLIM_RMC_BECOME_RULER_RESP:
+            __limProcessRMCBecomeRulerResp(pMac, pMsgBuf);
+            break;
+
+        case eLIM_RMC_OTA_RULER_INFORM_CANCELLED:
+            __limProcessRMCRulerInformCancelled(pMac, pMsgBuf);
+            break;
+
+
+        default:
+            break;
+    } // switch (msgType)
+    return;
+} /*** end limProcessRMCMessages() ***/
+
+void
+limRmcInit(tpAniSirGlobal pMac)
+{
+    tANI_U32 cfgValue;
+
+    if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
+                  &cfgValue) != eSIR_SUCCESS)
+    {
+        /**
+         * Could not get Action Period Frequency value
+         * from CFG. Log error.
+         */
+        limLog(pMac, LOGP, FL("could not retrieve ActionPeriodFrequency"));
+    }
+
+    cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+    vos_mem_zero(&pMac->rmcContext, sizeof(pMac->rmcContext));
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_init(&pMac->rmcContext.lkRmcLock)))
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC lock init failed!"));)
+    }
+
+    if (tx_timer_create(&pMac->rmcContext.gRmcRulerSelectTimer,
+                            "RMC RSP TIMEOUT",
+                            __rmcRulerSelectTimerHandler,
+                            0 /* param */,
+                            cfgValue, 0,
+                            TX_NO_ACTIVATE) != TX_SUCCESS)
+    {
+        limLog(pMac, LOGE, FL("could not create RMC response timer"));
+    }
+
+    pMac->rmcContext.rmcTimerValInTicks = cfgValue;
+}
+
+void
+limRmcCleanup(tpAniSirGlobal pMac)
+{
+    limRmcIbssDelete(pMac);
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_destroy(&pMac->rmcContext.lkRmcLock)))
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC lock destroy failed!"));)
+    }
+
+    tx_timer_delete(&pMac->rmcContext.gRmcRulerSelectTimer);
+}
+
+void
+limRmcTransmitterDelete(tpAniSirGlobal pMac, tSirMacAddr transmitter)
+{
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+             FL("RMC: limRMCTransmitterDelete lock acquire failed"));
+        return;
+    }
+
+    __rmcGroupDeleteHashEntry(pMac, transmitter);
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+            FL("RMC: limRMCTransmitterDelete lock release failed"));
+    }
+
+    limLog(pMac, LOG1, FL("RMC: limRmcTransmitterDelete complete"));
+}
+
+void
+limRmcIbssDelete(tpAniSirGlobal pMac)
+{
+    tpPESession psessionEntry;
+    tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
+
+    /*
+     * This API relies on a single active IBSS session.
+     */
+    psessionEntry = limIsIBSSSessionActive(pMac);
+    if (NULL == psessionEntry)
+    {
+        PELOGE(limLog(pMac, LOGE, FL("RMC: limRmcIbssDelete:No active IBSS"));)
+        return;
+    }
+
+    if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
+                            &pMac->rmcContext.ruler, sizeof(tSirMacAddr)))
+    {
+        __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED,
+                         eRMC_TRANSMITTER_ROLE, psessionEntry->selfMacAddr,
+                         pMac->rmcContext.ruler);
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+             FL("RMC: limRmcIbssDelete lock acquire failed"));
+        return;
+    }
+
+    /* Cancel pending timer */
+    tx_timer_deactivate(&pMac->rmcContext.gRmcRulerSelectTimer);
+
+    /* Delete all entries from Ruler database. */
+    __rmcGroupDeleteAllEntries(pMac);
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+            FL("RMC: limRmcIbssDelete lock release failed"));
+    }
+
+    limLog(pMac, LOG1, FL("RMC: limRmcIbssDelete complete"));
+}
+
+void
+limRmcDumpStatus(tpAniSirGlobal pMac)
+{
+    tLimRmcGroupContext *entry;
+    int index, count;
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+             FL("RMC: limRmcDumpStatus lock acquire failed"));
+        return;
+    }
+
+
+    limLog(pMac, LOGE, FL(" ----- RMC Transmitter Information ----- \n"));
+    limLog(pMac, LOGE,
+         FL("   Ruler Address   |  RMC State \n"));
+
+    if (pMac->rmcContext.state != eRMC_RULER_NOT_SELECTED)
+    {
+        limLog(pMac,LOGE, FL( MAC_ADDRESS_STR " | %s\n"),
+                         MAC_ADDR_ARRAY(pMac->rmcContext.ruler),
+                        __limMcastTxStateToString(pMac->rmcContext.state));
+    }
+
+    limLog( pMac,LOGE, FL(" ----- RMC Ruler Information ----- \n"));
+    limLog( pMac,LOGE, FL("  Transmitter Address\n"));
+
+    count = 0;
+    for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++)
+    {
+        entry = pMac->rmcContext.rmcGroupRxHashTable[index];
+
+        while (entry)
+        {
+            count++;
+            limLog( pMac,LOGE, FL("%d. " MAC_ADDRESS_STR " \n"),
+                    count, MAC_ADDR_ARRAY(entry->transmitter));
+            entry = entry->next;
+        }
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
+    {
+        limLog(pMac, LOGE,
+            FL("RMC: limRmcDumpStatus lock release failed"));
+    }
+
+    return;
+
+}
+
+VOS_STATUS
+limRmcTriggerRulerSelection(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+    if ((TRUE == pMac->rmcContext.rmcEnabled) &&
+        (eRMC_RULER_NOT_SELECTED == pMac->rmcContext.state))
+    {
+        limLog(pMac, LOG1,
+          FL("Ruler selection trigerred in FW"));
+
+        __limPostMsgRulerReq(pMac, eRMC_SUGGEST_RULER_CMD, macAddr);
+
+        pMac->rmcContext.state = eRMC_RULER_ENABLE_REQUESTED;
+
+        return VOS_STATUS_SUCCESS;
+    }
+    else
+    {
+        limLog(pMac, LOG1,
+          FL("Could not trigger ruler selection: RMC state %d rmcEnabled %d"),
+          pMac->rmcContext.state, pMac->rmcContext.rmcEnabled);
+
+        return VOS_STATUS_E_FAILURE;
+    }
+}
+
+#endif /* WLAN_FEATURE_RMC */
diff --git a/CORE/MAC/src/pe/lim/limRMC.h b/CORE/MAC/src/pe/lim/limRMC.h
new file mode 100644
index 0000000..1ebf0de
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limRMC.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * Date:          08/15/13
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_RMC_H
+#define __LIM_RMC_H
+
+#ifdef WLAN_FEATURE_RMC
+
+typedef enum {
+    eLIM_RMC_ENABLE_REQ = 0,
+    eLIM_RMC_DISABLE_REQ = 1,
+    eLIM_RMC_BECOME_RULER_RESP = 2,
+    eLIM_RMC_RULER_SELECT_RESP = 3,
+    eLIM_RMC_RULER_PICK_NEW = 4,
+    eLIM_RMC_OTA_RULER_INFORM_CANCELLED = 5,
+    eLIM_RMC_OTA_RULER_INFORM_ACK = 6,
+    eLIM_RMC_OTA_RULER_INFORM_SELECTED = 7,
+} eRmcMessageType;
+
+typedef enum {
+    eRMC_RULER_NOT_SELECTED     = 0,
+    eRMC_RULER_ENABLE_REQUESTED = 1,
+    eRMC_RULER_OTA_REQUEST_SENT = 2,
+    eRMC_RULER_ACTIVE           = 3,
+} eRmcMcastTxState;
+
+typedef enum {
+    eRMC_IS_NOT_A_RULER = 0,
+    eRMC_RULER_PENDING = 1,
+    eRMC_IS_A_RULER = 2,
+} eRmcRulerState;
+
+enum {
+    eRMC_SUGGEST_RULER_CMD = 0,
+    eRMC_BECOME_RULER_CMD  = 1,
+};
+
+enum {
+    eRMC_RULER_ACCEPTED  = 0,     //Host-->FW
+    eRMC_RULER_CANCELLED = 1,     //Host-->FW
+    eRMC_RULER_PICK_NEW  = 2,     //FW-->Host
+};
+
+/* tRoleType; */
+typedef enum
+{
+    eRMC_RULER_ROLE,
+    eRMC_TRANSMITTER_ROLE,
+} eRmcRole;
+
+#define RMC_MCAST_GROUPS_HASH_SIZE 32
+
+typedef struct sLimRmcGroupContext
+{
+    tSirMacAddr          transmitter;
+    eRmcRulerState      isRuler;
+    struct sLimRmcGroupContext *next;
+} tLimRmcGroupContext, *tpLimRmcGroupContext;
+
+typedef struct sLimRmcContext
+{
+    tANI_BOOLEAN         rmcEnabled;
+    tSirMacAddr          ruler;
+    eRmcMcastTxState     state;
+    TX_TIMER             gRmcRulerSelectTimer;
+    tANI_U32             rmcTimerValInTicks;
+    vos_lock_t           lkRmcLock;
+    tLimRmcGroupContext *rmcGroupRxHashTable[RMC_MCAST_GROUPS_HASH_SIZE];
+} tLimRmcContext, *tpLimRmcContext;
+
+
+void limRmcInit(tpAniSirGlobal pMac);
+void limRmcCleanup(tpAniSirGlobal pMac);
+void limRmcTransmitterDelete(tpAniSirGlobal pMac, tSirMacAddr transmitter);
+void limRmcIbssDelete(tpAniSirGlobal pMac);
+void limRmcDumpStatus(tpAniSirGlobal pMac);
+
+VOS_STATUS
+limRmcTriggerRulerSelection(tpAniSirGlobal pMac, tSirMacAddr macAddr);
+#endif /* WLAN_FEATURE_RMC */
+
+#endif /*  __LIM_RMC_H */
diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index 8d40677..ab8e86c 100644
--- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -7026,3 +7026,140 @@
    return nSirStatus;
 } // End limSendSaQueryResponseFrame
 #endif
+
+#ifdef WLAN_FEATURE_RMC
+tSirRetStatus
+limSendRMCActionFrame(tpAniSirGlobal  pMac,
+                        tSirMacAddr   peerMacAddr,
+                        tSirRMCInfo  *pRMC,
+                        tpPESession   psessionEntry)
+{
+    tSirRetStatus    nSirStatus;
+    tANI_U8         *pFrame;
+    tDot11fRMC       RMC;
+    tANI_U32         nPayload, nBytes, nStatus;
+    tpSirMacMgmtHdr  pMacHdr;
+    void            *pPacket;
+    eHalStatus       halstatus;
+    tANI_U8          txFlag = 0;
+    tANI_U8 MagicCode[] = { 0x4f, 0x58, 0x59, 0x47, 0x45, 0x4e };
+
+    if (NULL == psessionEntry)
+    {
+       return eSIR_FAILURE;
+    }
+
+    vos_mem_set(( tANI_U8* )&RMC, sizeof( RMC ), 0);
+
+    RMC.Action.action     = pRMC->action;
+    RMC.RMCDialogToken.token = pRMC->dialogToken;
+    RMC.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
+    RMC.RMCVersion.version = SIR_MAC_RMC_VER;
+
+    vos_mem_copy(&RMC.RMCOUI.oui, SIR_MAC_RMC_OUI, SIR_MAC_RMC_OUI_SIZE);
+    vos_mem_copy(&RMC.MagicCode.magic, MagicCode, sizeof(MagicCode));
+
+    vos_mem_copy(&RMC.Ruler.mac, pRMC->mcastRuler, sizeof(tSirMacAddr));
+
+    nStatus = dot11fGetPackedRMCSize( pMac, &RMC, &nPayload );
+    if ( DOT11F_FAILED( nStatus ) )
+    {
+        limLog( pMac, LOGE, FL("Failed to calculate the packed size for "
+                               "an RMC (0x%08x)."),
+                nStatus );
+        // We'll fall back on the worst case scenario:
+        nPayload = sizeof( tDot11fRMC );
+    }
+    else if ( DOT11F_WARNED( nStatus ) )
+    {
+        limLog( pMac, LOGW, FL("There were warnings while calculating "
+                               "the packed size for an RMC Action Frame"
+                               " (0x%08x)."), nStatus );
+    }
+
+    nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+                             ( tANI_U16 )nBytes, ( void** ) &pFrame,
+                             ( void** ) &pPacket );
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an RMC "
+                               "Action Frame."), nBytes );
+        return eSIR_FAILURE;
+    }
+
+    // Paranoia:
+    vos_mem_set( pFrame, nBytes, 0 );
+
+    // Next, we fill out the buffer descriptor:
+    nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+                    SIR_MAC_MGMT_ACTION, peerMacAddr,
+                    psessionEntry->selfMacAddr);
+    if ( eSIR_SUCCESS != nSirStatus )
+    {
+        limLog( pMac, LOGE, FL("Failed to populate the buffer descriptor "
+                               "for an RMC Action Frame (%d)."),
+                nSirStatus );
+        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+                    ( void* ) pFrame, ( void* ) pPacket );
+        return nSirStatus;
+    }
+
+    // Update A3 with the BSSID
+    pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+    sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+    // That done, pack the struct:
+    nStatus = dot11fPackRMC( pMac, &RMC,
+                                      pFrame + sizeof(tSirMacMgmtHdr),
+                                      nPayload, &nPayload );
+    if ( DOT11F_FAILED( nStatus ) )
+    {
+        limLog( pMac, LOGE, FL("Failed to pack an RMC "
+                               "(0x%08x)."),
+                nStatus );
+        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame,
+                     ( void* ) pPacket );
+        return eSIR_FAILURE;
+    }
+    else if ( DOT11F_WARNED( nStatus ) )
+    {
+        limLog( pMac, LOGW, FL("There were warnings while packing "
+                               "an RMC (0x%08x)."), nStatus );
+    }
+
+    limLog( pMac, LOG1, FL("Sending an RMC Action frame to "
+             MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peerMacAddr));
+
+    /*
+     * With this masking, RMC action frames will be sent
+     * at self-sta rates for both 2G and 5G bands.
+     */
+    txFlag |= HAL_USE_SELF_STA_REQUESTED_MASK;
+
+    MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT,
+           psessionEntry->peSessionId,
+           pMacHdr->fc.subType));
+    // Queue RMC Action frame in high priority WQ
+    halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+                            HAL_TXRX_FRM_802_11_MGMT,
+                            ANI_TXDIR_TODS,
+                            7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+                            limTxComplete, pFrame, txFlag );
+    MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE,
+           psessionEntry->peSessionId,
+           halstatus));
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGE, FL( "*** Could not send an RMC Action frame"
+                                " (%X) ***" ), halstatus );
+        //Pkt will be freed up by the callback
+        return eSIR_FAILURE;
+    }
+
+    return eSIR_SUCCESS;
+
+} // End limSendRMCActionFrame.
+
+#endif /* WLAN_FEATURE_RMC */
diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
index 04bbcc2..8747a4d 100644
--- a/CORE/MAC/src/pe/lim/limTypes.h
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -872,6 +872,15 @@
 tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, 
                    tANI_U8 *transId, tSirMacAddr peer,tpPESession psessionEntry);
 #endif
+
+#ifdef WLAN_FEATURE_RMC
+void limProcessRMCMessages(tpAniSirGlobal pMac, eRmcMessageType msgType,
+                             tANI_U32 *pMsgBuf);
+tSirRetStatus limSendRMCActionFrame(tpAniSirGlobal  pMac,
+                 tSirMacAddr peerMacAddr, tSirRMCInfo  *pRMC,
+                 tpPESession psessionEntry);
+#endif /* WLAN_FEATURE_RMC */
+
 // Inline functions
 
 /**
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 0d2d51b..56fde57 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -499,6 +499,10 @@
     eCSR_ROAM_UNPROT_MGMT_FRAME_IND,
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+    eCSR_ROAM_IBSS_PEER_INFO_COMPLETE,
+#endif
+
 #ifdef WLAN_FEATURE_AP_HT40_24G
     eCSR_ROAM_2040_COEX_INFO_IND,
 #endif
@@ -601,6 +605,10 @@
     eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP,
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+    eCSR_ROAM_RESULT_IBSS_PEER_INFO_SUCCESS,
+    eCSR_ROAM_RESULT_IBSS_PEER_INFO_FAILED,
+#endif
 }eCsrRoamResult;
 
 
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 358d442..4735ba2 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1452,3 +1452,8 @@
 #endif
 
 void csrDisableDfsChannel(tpAniSirGlobal pMac);
+
+#ifdef WLAN_FEATURE_RMC
+eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
+eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
+#endif /* WLAN_FEATURE_RMC */
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index 5faef48..3280a92 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -119,6 +119,19 @@
 #define SME_IS_START(pMac)  (SME_STATE_STOP != (pMac)->sme.state)
 #define SME_IS_READY(pMac)  (SME_STATE_READY == (pMac)->sme.state)
 
+#ifdef WLAN_FEATURE_RMC
+
+/* HDD Callback function */
+typedef void(*pIbssPeerInfoCb)(void *pUserData, void *infoParam);
+
+/* Peer info */
+typedef struct tagSmePeerInfoHddCbkInfo
+{
+   void *pUserData;
+   pIbssPeerInfoCb peerInfoCbk;
+}tSmePeerInfoHddCbkInfo;
+#endif /* WLAN_FEATURE_RMC */
+
 /* HDD Callback function */
 typedef void(*pEncryptMsgRSPCb)(void *pUserData, void *infoParam);
 
@@ -147,6 +160,9 @@
     tDblLinkList smeScanCmdPendingList;
     //active scan command list
     tDblLinkList smeScanCmdActiveList;
+#ifdef WLAN_FEATURE_RMC
+    tSmePeerInfoHddCbkInfo peerInfoParams;
+#endif /* WLAN_FEATURE_RMC */
 #ifdef FEATURE_WLAN_CH_AVOID
     void (*pChAvoidNotificationCb) (void *pAdapter, void *indParam);
 #endif /* FEATURE_WLAN_CH_AVOID */
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 6ec5636..bf1476a 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -57,7 +57,9 @@
 #include "btcApi.h"
 #include "vos_nvitem.h"
 #include "p2p_Api.h"
+#ifdef WLAN_FEATURE_RMC
 #include "smeInternal.h"
+#endif
 
 #ifdef FEATURE_OEM_DATA_SUPPORT
 #include "oemDataApi.h"
@@ -1847,6 +1849,30 @@
                                          tANI_U8 *pCountry,
                                          v_REGDOMAIN_t reg_domain);
 
+#ifdef WLAN_FEATURE_RMC
+/* ---------------------------------------------------------------------------
+
+    \fn sme_TXFailMonitorStartStopInd
+
+    \brief Indicate FW about TX Fail Monitor Indication`
+
+    \param hHal - The handle returned by macOpen.
+
+    \param tx_fail_count number of failures after which the firmware sends
+                         an indication to host
+
+    \param txFailIndCallback function to be called after receiving TX Fail
+                             indication
+    \return eHalStatus  SUCCESS.
+
+                         FAILURE or RESOURCES  The API finished and failed.
+
+  -------------------------------------------------------------------------------*/
+eHalStatus sme_TXFailMonitorStartStopInd(tHalHandle hHal,
+                                         tANI_U8 tx_fail_count,
+                                         void * txFailIndCallback);
+#endif /* WLAN_FEATURE_RMC */
+
 /* ---------------------------------------------------------------------------
 
     \fn sme_DHCPStartInd
@@ -3589,6 +3615,28 @@
 void sme_enable_disable_split_scan (tHalHandle hHal, tANI_U8 nNumStaChan,
                                     tANI_U8 nNumP2PChan);
 
+#ifdef WLAN_FEATURE_RMC
+/* ---------------------------------------------------------------------------
+    \fn sme_EnableRMC
+    \brief  Used to enable RMC
+    setting will not persist over reboots
+    \param  hHal
+    \param  sessionId
+    \- return eHalStatus
+    -------------------------------------------------------------------------*/
+eHalStatus sme_EnableRMC(tHalHandle hHal, tANI_U32 sessionId);
+
+/* ---------------------------------------------------------------------------
+    \fn sme_DisableRMC
+    \brief  Used to disable RMC
+    setting will not persist over reboots
+    \param  hHal
+    \param  sessionId
+    \- return eHalStatus
+    -------------------------------------------------------------------------*/
+eHalStatus sme_DisableRMC(tHalHandle hHal, tANI_U32 sessionId);
+#endif /* WLAN_FEATURE_RMC */
+
 /* ---------------------------------------------------------------------------
     \fn sme_SendRateUpdateInd
     \brief  API to Update rate
@@ -3598,6 +3646,21 @@
   ---------------------------------------------------------------------------*/
 eHalStatus sme_SendRateUpdateInd(tHalHandle hHal, tSirRateUpdateInd *rateUpdateParams);
 
+#ifdef WLAN_FEATURE_RMC
+/* ---------------------------------------------------------------------------
+    \fn sme_GetIBSSPeerInfo
+    \brief  Used to disable RMC
+    setting will not persist over reboots
+    \param  hHal
+    \param  ibssPeerInfoReq  multicast Group IP address
+    \- return eHalStatus
+    -------------------------------------------------------------------------*/
+eHalStatus sme_RequestIBSSPeerInfo(tHalHandle hHal, void *pUserData,
+                                            pIbssPeerInfoCb peerInfoCbk,
+                                            tANI_BOOLEAN allPeerInfoReqd,
+                                            tANI_U8 staIdx);
+#endif /* WLAN_FEATURE_RMC */
+
 /*
  * sme API to trigger fast BSS roam to a given BSSID independent of RSSI
  * triggers
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 9f3659c..349dfe0 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -18221,6 +18221,79 @@
 }
 #endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */
 
+#ifdef WLAN_FEATURE_RMC
+eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId)
+{
+   tSirSetRMCReq *pMsg = NULL;
+   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;
+   }
+
+   pMsg = vos_mem_malloc(sizeof(tSirSetRMCReq));
+   if (NULL != pMsg)
+   {
+       vos_mem_set((void *)pMsg, sizeof(tSirSetRMCReq), 0);
+       pMsg->msgType = eWNI_SME_ENABLE_RMC_REQ;
+       pMsg->msgLen  = sizeof(tSirSetRMCReq);
+       vos_mem_copy((v_U8_t *)pMsg->mcastTransmitter,
+             &pSession->selfMacAddr, sizeof(tSirMacAddr));
+
+       status = palSendMBMessage(pMac->hHdd, pMsg);
+       if (!HAL_STATUS_SUCCESS(status))
+       {
+           smsLog(pMac, LOGE, FL(" csr enable RMC Post MSG Fail %d "), status);
+           //pMsg is freed by palSendMBMessage
+       }
+   }
+   else
+   {
+       return eHAL_STATUS_FAILURE;
+   }
+   return status;
+}
+
+eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId)
+{
+   tSirSetRMCReq *pMsg = NULL;
+   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;
+   }
+
+   pMsg = vos_mem_malloc(sizeof(tSirSetRMCReq));
+   if (NULL != pMsg)
+   {
+       vos_mem_set((void *)pMsg, sizeof(tSirSetRMCReq), 0);
+       pMsg->msgType = eWNI_SME_DISABLE_RMC_REQ;
+       pMsg->msgLen  = sizeof(tSirSetRMCReq);
+       vos_mem_copy((v_U8_t *)pMsg->mcastTransmitter,
+             &pSession->selfMacAddr, sizeof(tSirMacAddr));
+
+       status = palSendMBMessage(pMac->hHdd, pMsg);
+       if (!HAL_STATUS_SUCCESS(status))
+       {
+           smsLog(pMac, LOGE, FL(" csr disable RMC Post MSG Fail %d "), status);
+           //pMsg is freed by palSendMBMessage
+       }
+   }
+   else
+   {
+       return eHAL_STATUS_FAILURE;
+   }
+   return status;
+}
+
+#endif /* WLAN_FEATURE_RMC */
+
 
 #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
 /* ---------------------------------------------------------------------------
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index c01d6fd..fa773cc 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -2094,6 +2094,31 @@
 #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
 
 
+#ifdef WLAN_FEATURE_RMC
+eHalStatus sme_IbssPeerInfoResponseHandleer( tHalHandle hHal,
+                                      tpSirIbssGetPeerInfoRspParams pIbssPeerInfoParams)
+{
+   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+
+   if (NULL == pMac)
+   {
+       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
+           "%s: pMac is null", __func__);
+       return eHAL_STATUS_FAILURE;
+   }
+   if (pMac->sme.peerInfoParams.peerInfoCbk == NULL)
+   {
+       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+           "%s: HDD callback is null", __func__);
+       return eHAL_STATUS_FAILURE;
+   }
+   pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData,
+                                        &pIbssPeerInfoParams->ibssPeerInfoRspParams);
+   return eHAL_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_RMC */
+
+
 /* ---------------------------------------------------------------------------
     \fn sme_getBcnMissRate
     \brief function sends 'WDA_GET_BCN_MISS_RATE_REQ' to WDA layer,
@@ -2597,6 +2622,25 @@
                 break;
 #endif /* FEATURE_WLAN_LPHB */
 
+#ifdef WLAN_FEATURE_RMC
+          case eWNI_SME_IBSS_PEER_INFO_RSP:
+              MTRACE(vos_trace(VOS_MODULE_ID_SME,
+                       TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type));
+              if (pMsg->bodyptr)
+              {
+                  sme_IbssPeerInfoResponseHandleer(pMac, pMsg->bodyptr);
+                  vos_mem_free(pMsg->bodyptr);
+              }
+              else
+              {
+                  smsLog(pMac, LOGE,
+                         "Empty rsp message for (eWNI_SME_IBSS_PEER_INFO_RSP),"
+                         " nothing to process");
+              }
+              break ;
+
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_CH_AVOID
           /* LPHB timeout indication arrived, send IND to client */
           case eWNI_SME_CH_AVOID_IND:
@@ -5990,7 +6034,6 @@
 
        MTRACE(vos_trace(VOS_MODULE_ID_SME,
                  TRACE_CODE_SME_TX_WDA_MSG, sessionId, vosMessage.type));
-
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
        {
@@ -6005,6 +6048,65 @@
     return (status);
 }
 
+#ifdef WLAN_FEATURE_RMC
+/*---------------------------------------------------------------------------
+
+    \fn sme_TXFailMonitorStopInd
+
+    \brief API to signal the FW to start monitoring TX failures
+
+    \return eHalStatus  SUCCESS.
+
+                         FAILURE or RESOURCES  The API finished and failed.
+ --------------------------------------------------------------------------*/
+eHalStatus sme_TXFailMonitorStartStopInd(tHalHandle hHal, tANI_U8 tx_fail_count,
+                                         void * txFailIndCallback)
+{
+    eHalStatus            status;
+    VOS_STATUS            vosStatus;
+    tpAniSirGlobal        pMac = PMAC_STRUCT(hHal);
+    vos_msg_t             vosMessage;
+    tAniTXFailMonitorInd  *pMsg;
+
+    status = sme_AcquireGlobalLock(&pMac->sme);
+    if ( eHAL_STATUS_SUCCESS == status)
+    {
+        pMsg = (tAniTXFailMonitorInd*)
+                   vos_mem_malloc(sizeof(tAniTXFailMonitorInd));
+        if (NULL == pMsg)
+        {
+            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                   "%s: Failed to allocate memory", __func__);
+            sme_ReleaseGlobalLock( &pMac->sme );
+            return eHAL_STATUS_FAILURE;
+        }
+
+        pMsg->msgType = WDA_TX_FAIL_MONITOR_IND;
+        pMsg->msgLen = (tANI_U16)sizeof(tAniTXFailMonitorInd);
+
+        //tx_fail_count = 0 should disable the Monitoring in FW
+        pMsg->tx_fail_count = tx_fail_count;
+        pMsg->txFailIndCallback = txFailIndCallback;
+
+        vosMessage.type = WDA_TX_FAIL_MONITOR_IND;
+        vosMessage.bodyptr = pMsg;
+        vosMessage.reserved = 0;
+
+        MTRACE(vos_trace(VOS_MODULE_ID_SME,
+                 TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type));
+        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage );
+        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
+        {
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                         "%s: Post TX Fail monitor Start MSG fail", __func__);
+           vos_mem_free(pMsg);
+           status = eHAL_STATUS_FAILURE;
+        }
+        sme_ReleaseGlobalLock( &pMac->sme );
+    }
+    return (status);
+}
+#endif /* WLAN_FEATURE_RMC */
 
 /* ---------------------------------------------------------------------------
     \fn sme_BtcSignalBtEvent
@@ -10767,13 +10869,12 @@
 #endif
 }
 
+
 /* ---------------------------------------------------------------------------
     \fn sme_IsFeatureSupportedByFW
-
     \brief  Check if a feature is enabled by FW
 
     \param  featEnumValue - Enumeration value from placeHolderInCapBitmap
-
     \- return 1/0 (TRUE/FALSE)
     -------------------------------------------------------------------------*/
 tANI_U8 sme_IsFeatureSupportedByFW(tANI_U8 featEnumValue)
@@ -11874,6 +11975,150 @@
     return status;
 }
 
+#ifdef WLAN_FEATURE_RMC
+/* ---------------------------------------------------------------------------
+    \fn sme_EnableRMC
+    \brief  Used to enable RMC
+    setting will not persist over reboots
+    \param  hHal
+    \param  sessionId
+    \- return eHalStatus
+    -------------------------------------------------------------------------*/
+eHalStatus sme_EnableRMC(tHalHandle hHal, tANI_U32 sessionId)
+{
+    eHalStatus status = eHAL_STATUS_FAILURE;
+    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+
+    smsLog(pMac, LOG1, FL("enable RMC"));
+    status = sme_AcquireGlobalLock(&pMac->sme);
+    if (HAL_STATUS_SUCCESS(status))
+    {
+        status = csrEnableRMC(pMac, sessionId);
+        sme_ReleaseGlobalLock(&pMac->sme);
+    }
+    return status;
+}
+
+/* ---------------------------------------------------------------------------
+    \fn sme_DisableRMC
+    \brief  Used to disable RMC
+    setting will not persist over reboots
+    \param  hHal
+    \param  sessionId
+    \- return eHalStatus
+    -------------------------------------------------------------------------*/
+eHalStatus sme_DisableRMC(tHalHandle hHal, tANI_U32 sessionId)
+{
+   eHalStatus status = eHAL_STATUS_FAILURE;
+   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+
+   smsLog(pMac, LOG1, FL("disable RMC"));
+   status = sme_AcquireGlobalLock(&pMac->sme);
+   if (HAL_STATUS_SUCCESS(status))
+   {
+      status = csrDisableRMC(pMac, sessionId);
+      sme_ReleaseGlobalLock(&pMac->sme);
+   }
+   return status;
+}
+#endif /* WLAN_FEATURE_RMC */
+
+/* ---------------------------------------------------------------------------
+    \fn sme_SendRateUpdateInd
+    \brief  API to Update rate
+    \param  hHal - The handle returned by macOpen
+    \param  rateUpdateParams - Pointer to rate update params
+    \return eHalStatus
+  ---------------------------------------------------------------------------*/
+eHalStatus sme_SendRateUpdateInd(tHalHandle hHal, tSirRateUpdateInd *rateUpdateParams)
+{
+    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+    eHalStatus status;
+    vos_msg_t msg;
+
+    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
+    {
+        msg.type     = WDA_RATE_UPDATE_IND;
+        msg.bodyptr  = rateUpdateParams;
+
+        MTRACE(vos_trace(VOS_MODULE_ID_SME,
+                 TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type));
+        if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
+        {
+            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,"%s: Not able "
+                       "to post WDA_SET_RMC_RATE_IND to WDA!",
+                       __func__);
+
+            sme_ReleaseGlobalLock(&pMac->sme);
+            return eHAL_STATUS_FAILURE;
+        }
+
+        sme_ReleaseGlobalLock(&pMac->sme);
+        return eHAL_STATUS_SUCCESS;
+    }
+
+    return status;
+}
+
+#ifdef WLAN_FEATURE_RMC
+/* ---------------------------------------------------------------------------
+    \fn sme_GetIBSSPeerInfo
+    \brief  Used to disable RMC
+    setting will not persist over reboots
+    \param  hHal
+    \param  ibssPeerInfoReq  multicast Group IP address
+    \- return eHalStatus
+    -------------------------------------------------------------------------*/
+eHalStatus sme_RequestIBSSPeerInfo(tHalHandle hHal, void *pUserData,
+                                            pIbssPeerInfoCb peerInfoCbk,
+                                            tANI_BOOLEAN allPeerInfoReqd,
+                                            tANI_U8 staIdx)
+{
+   eHalStatus status = eHAL_STATUS_FAILURE;
+   VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
+   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+   vos_msg_t vosMessage;
+   tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams;
+
+   status = sme_AcquireGlobalLock(&pMac->sme);
+   if ( eHAL_STATUS_SUCCESS == status)
+   {
+       pMac->sme.peerInfoParams.peerInfoCbk = peerInfoCbk;
+       pMac->sme.peerInfoParams.pUserData = pUserData;
+
+       pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *)
+                        vos_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams));
+       if (NULL == pIbssInfoReqParams)
+       {
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                  "%s: Not able to allocate memory for dhcp start", __func__);
+           sme_ReleaseGlobalLock( &pMac->sme );
+           return eHAL_STATUS_FAILURE;
+       }
+       pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd;
+       pIbssInfoReqParams->staIdx = staIdx;
+
+       vosMessage.type = WDA_GET_IBSS_PEER_INFO_REQ;
+       vosMessage.bodyptr = pIbssInfoReqParams;
+       vosMessage.reserved = 0;
+
+       MTRACE(vos_trace(VOS_MODULE_ID_SME,
+                 TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type));
+       vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
+       if ( VOS_STATUS_SUCCESS != vosStatus )
+       {
+          VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                        "%s: Post WDA_GET_IBSS_PEER_INFO_REQ MSG failed", __func__);
+          vos_mem_free(pIbssInfoReqParams);
+          vosStatus = eHAL_STATUS_FAILURE;
+       }
+       sme_ReleaseGlobalLock( &pMac->sme );
+   }
+
+   return (vosStatus);
+}
+#endif
+
 void smeGetCommandQStatus( tHalHandle hHal )
 {
     tSmeCmd *pTempCmd = NULL;
@@ -11950,43 +12195,6 @@
 }
 
 /* ---------------------------------------------------------------------------
-    \fn sme_SendRateUpdateInd
-    \brief  API to Update rate
-    \param  hHal - The handle returned by macOpen
-    \param  rateUpdateParams - Pointer to rate update params
-    \return eHalStatus
-  ---------------------------------------------------------------------------*/
-eHalStatus sme_SendRateUpdateInd(tHalHandle hHal, tSirRateUpdateInd *rateUpdateParams)
-{
-    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
-    eHalStatus status;
-    vos_msg_t msg;
-
-    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
-    {
-        msg.type     = WDA_RATE_UPDATE_IND;
-        msg.bodyptr  = rateUpdateParams;
-
-        MTRACE(vos_trace(VOS_MODULE_ID_SME,
-                 TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type));
-        if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
-        {
-            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,"%s: Not able "
-                       "to post WDA_SET_RMC_RATE_IND to WDA!",
-                       __func__);
-
-            sme_ReleaseGlobalLock(&pMac->sme);
-            return eHAL_STATUS_FAILURE;
-        }
-
-        sme_ReleaseGlobalLock(&pMac->sme);
-        return eHAL_STATUS_SUCCESS;
-    }
-
-    return status;
-}
-
-/* ---------------------------------------------------------------------------
     \fn sme_TriggerBatchScanResultInd
     \brief  API to trigger batch scan result indications from FW
     \param  hHal - The handle returned by macOpen.
diff --git a/CORE/SYS/legacy/src/utils/src/dot11f.c b/CORE/SYS/legacy/src/utils/src/dot11f.c
index a4fbb05..8f5be20 100644
--- a/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -28,7 +28,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Mon Nov 10 19:49:53 2014 from the following file(s):
+  * Wed Sep  9 10:17:04 2015 from the following file(s):
   *
   * dot11f.frms
   *
@@ -763,6 +763,16 @@
 
 #define SigFfListenInterval ( 0x000f )
 
+void dot11fUnpackFfMagicCode(tpAniSirGlobal pCtx,
+                             tANI_U8 *pBuf,
+                             tDot11fFfMagicCode *pDst)
+{
+    DOT11F_MEMCPY(pCtx, pDst->magic, pBuf, 6);
+    (void)pCtx;
+} /* End dot11fUnpackFfMagicCode. */
+
+#define SigFfMagicCode ( 0x0010 )
+
 void dot11fUnpackFfMaxTxPower(tpAniSirGlobal pCtx,
                               tANI_U8 *pBuf,
                               tDot11fFfMaxTxPower *pDst)
@@ -771,7 +781,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfMaxTxPower. */
 
-#define SigFfMaxTxPower ( 0x0010 )
+#define SigFfMaxTxPower ( 0x0011 )
 
 void dot11fUnpackFfNumOfRepetitions(tpAniSirGlobal pCtx,
                                     tANI_U8 *pBuf,
@@ -781,7 +791,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfNumOfRepetitions. */
 
-#define SigFfNumOfRepetitions ( 0x0011 )
+#define SigFfNumOfRepetitions ( 0x0012 )
 
 void dot11fUnpackFfOperatingMode(tpAniSirGlobal pCtx,
                                  tANI_U8 *pBuf,
@@ -796,7 +806,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfOperatingMode. */
 
-#define SigFfOperatingMode ( 0x0012 )
+#define SigFfOperatingMode ( 0x0013 )
 
 void dot11fUnpackFfP2POUI(tpAniSirGlobal pCtx,
                           tANI_U8 *pBuf,
@@ -806,7 +816,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfP2POUI. */
 
-#define SigFfP2POUI ( 0x0013 )
+#define SigFfP2POUI ( 0x0014 )
 
 void dot11fUnpackFfP2POUISubType(tpAniSirGlobal pCtx,
                                  tANI_U8 *pBuf,
@@ -816,7 +826,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfP2POUISubType. */
 
-#define SigFfP2POUISubType ( 0x0014 )
+#define SigFfP2POUISubType ( 0x0015 )
 
 void dot11fUnpackFfRCPI(tpAniSirGlobal pCtx,
                         tANI_U8 *pBuf,
@@ -826,7 +836,37 @@
     (void)pCtx;
 } /* End dot11fUnpackFfRCPI. */
 
-#define SigFfRCPI ( 0x0015 )
+#define SigFfRCPI ( 0x0016 )
+
+void dot11fUnpackFfRMCDialogToken(tpAniSirGlobal pCtx,
+                                  tANI_U8 *pBuf,
+                                  tDot11fFfRMCDialogToken *pDst)
+{
+    framesntohl(pCtx, &pDst->token, pBuf, 0);
+    (void)pCtx;
+} /* End dot11fUnpackFfRMCDialogToken. */
+
+#define SigFfRMCDialogToken ( 0x0017 )
+
+void dot11fUnpackFfRMCOUI(tpAniSirGlobal pCtx,
+                          tANI_U8 *pBuf,
+                          tDot11fFfRMCOUI *pDst)
+{
+    DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 3);
+    (void)pCtx;
+} /* End dot11fUnpackFfRMCOUI. */
+
+#define SigFfRMCOUI ( 0x0018 )
+
+void dot11fUnpackFfRMCVersion(tpAniSirGlobal pCtx,
+                              tANI_U8 *pBuf,
+                              tDot11fFfRMCVersion *pDst)
+{
+    pDst->version = *pBuf;
+    (void)pCtx;
+} /* End dot11fUnpackFfRMCVersion. */
+
+#define SigFfRMCVersion ( 0x0019 )
 
 void dot11fUnpackFfRSNI(tpAniSirGlobal pCtx,
                         tANI_U8 *pBuf,
@@ -836,9 +876,19 @@
     (void)pCtx;
 } /* End dot11fUnpackFfRSNI. */
 
-#define SigFfRSNI ( 0x0016 )
+#define SigFfRSNI ( 0x001a )
 
-#define SigFfReason ( 0x0017 )
+#define SigFfReason ( 0x001b )
+
+void dot11fUnpackFfRuler(tpAniSirGlobal pCtx,
+                         tANI_U8 *pBuf,
+                         tDot11fFfRuler *pDst)
+{
+    DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6);
+    (void)pCtx;
+} /* End dot11fUnpackFfRuler. */
+
+#define SigFfRuler ( 0x001c )
 
 void dot11fUnpackFfRxAntennaId(tpAniSirGlobal pCtx,
                                tANI_U8 *pBuf,
@@ -848,7 +898,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfRxAntennaId. */
 
-#define SigFfRxAntennaId ( 0x0018 )
+#define SigFfRxAntennaId ( 0x001d )
 
 void dot11fUnpackFfSMPowerModeSet(tpAniSirGlobal pCtx,
                                   tANI_U8 *pBuf,
@@ -862,9 +912,9 @@
     (void)pCtx;
 } /* End dot11fUnpackFfSMPowerModeSet. */
 
-#define SigFfSMPowerModeSet ( 0x0019 )
+#define SigFfSMPowerModeSet ( 0x001e )
 
-#define SigFfStatus ( 0x001a )
+#define SigFfStatus ( 0x001f )
 
 void dot11fUnpackFfStatusCode(tpAniSirGlobal pCtx,
                               tANI_U8 *pBuf,
@@ -874,7 +924,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfStatusCode. */
 
-#define SigFfStatusCode ( 0x001b )
+#define SigFfStatusCode ( 0x0020 )
 
 void dot11fUnpackFfTPCEleID(tpAniSirGlobal pCtx,
                             tANI_U8 *pBuf,
@@ -884,7 +934,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfTPCEleID. */
 
-#define SigFfTPCEleID ( 0x001c )
+#define SigFfTPCEleID ( 0x0021 )
 
 void dot11fUnpackFfTPCEleLen(tpAniSirGlobal pCtx,
                              tANI_U8 *pBuf,
@@ -894,7 +944,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfTPCEleLen. */
 
-#define SigFfTPCEleLen ( 0x001d )
+#define SigFfTPCEleLen ( 0x0022 )
 
 void dot11fUnpackFfTSInfo(tpAniSirGlobal pCtx,
                           tANI_U8 *pBuf,
@@ -915,7 +965,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfTSInfo. */
 
-#define SigFfTSInfo ( 0x001e )
+#define SigFfTSInfo ( 0x0023 )
 
 void dot11fUnpackFfTimeStamp(tpAniSirGlobal pCtx,
                              tANI_U8 *pBuf,
@@ -925,7 +975,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfTimeStamp. */
 
-#define SigFfTimeStamp ( 0x001f )
+#define SigFfTimeStamp ( 0x0024 )
 
 void dot11fUnpackFfTransactionId(tpAniSirGlobal pCtx,
                                  tANI_U8 *pBuf,
@@ -935,7 +985,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfTransactionId. */
 
-#define SigFfTransactionId ( 0x0020 )
+#define SigFfTransactionId ( 0x0025 )
 
 void dot11fUnpackFfTxAntennaId(tpAniSirGlobal pCtx,
                                tANI_U8 *pBuf,
@@ -945,7 +995,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfTxAntennaId. */
 
-#define SigFfTxAntennaId ( 0x0021 )
+#define SigFfTxAntennaId ( 0x0026 )
 
 void dot11fUnpackFfTxPower(tpAniSirGlobal pCtx,
                            tANI_U8 *pBuf,
@@ -955,7 +1005,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfTxPower. */
 
-#define SigFfTxPower ( 0x0022 )
+#define SigFfTxPower ( 0x0027 )
 
 void dot11fUnpackFfVhtMembershipStatusArray(tpAniSirGlobal pCtx,
                                             tANI_U8 *pBuf,
@@ -965,7 +1015,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfVhtMembershipStatusArray. */
 
-#define SigFfVhtMembershipStatusArray ( 0x0023 )
+#define SigFfVhtMembershipStatusArray ( 0x0028 )
 
 void dot11fUnpackFfVhtUserPositionArray(tpAniSirGlobal pCtx,
                                         tANI_U8 *pBuf,
@@ -975,7 +1025,7 @@
     (void)pCtx;
 } /* End dot11fUnpackFfVhtUserPositionArray. */
 
-#define SigFfVhtUserPositionArray ( 0x0024 )
+#define SigFfVhtUserPositionArray ( 0x0029 )
 
 tANI_U32 dot11fUnpackTlvAuthorizedMACs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVAuthorizedMACs *pDst)
 {
@@ -15729,6 +15779,53 @@
 
 } /* End dot11fUnpackQosMapConfigure. */
 
+    static const tFFDefn FFS_RMC[] = {
+        { "Category", offsetof(tDot11fRMC, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, },
+        { "RMCOUI", offsetof(tDot11fRMC, RMCOUI), SigFfRMCOUI , DOT11F_FF_RMCOUI_LEN, },
+        { "MagicCode", offsetof(tDot11fRMC, MagicCode), SigFfMagicCode , DOT11F_FF_MAGICCODE_LEN, },
+        { "RMCVersion", offsetof(tDot11fRMC, RMCVersion), SigFfRMCVersion , DOT11F_FF_RMCVERSION_LEN, },
+        { "Action", offsetof(tDot11fRMC, Action), SigFfAction , DOT11F_FF_ACTION_LEN, },
+        { "RMCDialogToken", offsetof(tDot11fRMC, RMCDialogToken), SigFfRMCDialogToken , DOT11F_FF_RMCDIALOGTOKEN_LEN, },
+        { "Ruler", offsetof(tDot11fRMC, Ruler), SigFfRuler , DOT11F_FF_RULER_LEN, },
+    { NULL, 0, 0, 0,},
+    };
+
+    static const tIEDefn IES_RMC[] = {
+    {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },    };
+
+tANI_U32 dot11fUnpackRMC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRMC *pFrm)
+{
+    tANI_U32 i = 0;
+    tANI_U32 status = 0;
+    status = UnpackCore(pCtx, pBuf, nBuf, FFS_RMC, IES_RMC, ( tANI_U8* )pFrm, sizeof(*pFrm));
+
+    (void)i;
+#   ifdef DOT11F_DUMP_FRAMES
+    if (!DOT11F_FAILED(status))
+    {
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Unpacked the RMC:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), pBuf, nBuf);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("to:\n"));
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Category:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Category.category, 1);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCOUI:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCOUI.oui, 3);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("MagicCode:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->MagicCode.magic, 6);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCVersion:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCVersion.version, 1);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Action:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Action.action, 1);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCDialogToken:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCDialogToken.token, 4);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Ruler:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Ruler.mac, 6);
+    }
+#   endif // DOT11F_DUMP_FRAMES
+    return status;
+
+} /* End dot11fUnpackRMC. */
+
     static const tFFDefn FFS_RadioMeasurementReport[] = {
         { "Category", offsetof(tDot11fRadioMeasurementReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, },
         { "Action", offsetof(tDot11fRadioMeasurementReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, },
@@ -20585,6 +20682,9 @@
         case SigFfListenInterval:
             dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfListenInterval* )(pFrm + pFf->offset ))->interval));
             break;
+        case SigFfMagicCode:
+            dot11fUnpackFfMagicCode(pCtx, pBufRemaining, ( tDot11fFfMagicCode* )(pFrm + pFf->offset ));
+            break;
         case SigFfMaxTxPower:
             dot11fUnpackFfMaxTxPower(pCtx, pBufRemaining, ( tDot11fFfMaxTxPower* )(pFrm + pFf->offset ));
             break;
@@ -20603,12 +20703,24 @@
         case SigFfRCPI:
             dot11fUnpackFfRCPI(pCtx, pBufRemaining, ( tDot11fFfRCPI* )(pFrm + pFf->offset ));
             break;
+        case SigFfRMCDialogToken:
+            dot11fUnpackFfRMCDialogToken(pCtx, pBufRemaining, ( tDot11fFfRMCDialogToken* )(pFrm + pFf->offset ));
+            break;
+        case SigFfRMCOUI:
+            dot11fUnpackFfRMCOUI(pCtx, pBufRemaining, ( tDot11fFfRMCOUI* )(pFrm + pFf->offset ));
+            break;
+        case SigFfRMCVersion:
+            dot11fUnpackFfRMCVersion(pCtx, pBufRemaining, ( tDot11fFfRMCVersion* )(pFrm + pFf->offset ));
+            break;
         case SigFfRSNI:
             dot11fUnpackFfRSNI(pCtx, pBufRemaining, ( tDot11fFfRSNI* )(pFrm + pFf->offset ));
             break;
         case SigFfReason:
             dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfReason* )(pFrm + pFf->offset ))->code));
             break;
+        case SigFfRuler:
+            dot11fUnpackFfRuler(pCtx, pBufRemaining, ( tDot11fFfRuler* )(pFrm + pFf->offset ));
+            break;
         case SigFfRxAntennaId:
             dot11fUnpackFfRxAntennaId(pCtx, pBufRemaining, ( tDot11fFfRxAntennaId* )(pFrm + pFf->offset ));
             break;
@@ -22631,6 +22743,14 @@
     return status;
 } /* End dot11fGetPackedQosMapConfigureSize. */
 
+tANI_U32 dot11fGetPackedRMCSize(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U32 *pnNeeded)
+{
+    tANI_U32 status = 0;
+    *pnNeeded = 22;
+    status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_RMC);
+    return status;
+} /* End dot11fGetPackedRMCSize. */
+
 tANI_U32 dot11fGetPackedRadioMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U32 *pnNeeded)
 {
     tANI_U32 status = 0;
@@ -23892,6 +24012,14 @@
     (void)pCtx;
 } /* End dot11fPackFfListenInterval. */
 
+void dot11fPackFfMagicCode(tpAniSirGlobal pCtx,
+                           tDot11fFfMagicCode *pSrc,
+                           tANI_U8 *pBuf)
+{
+    DOT11F_MEMCPY(pCtx, pBuf, pSrc->magic, 6);
+    (void)pCtx;
+} /* End dot11fPackFfMagicCode. */
+
 void dot11fPackFfMaxTxPower(tpAniSirGlobal pCtx,
                             tDot11fFfMaxTxPower *pSrc,
                             tANI_U8 *pBuf)
@@ -23946,6 +24074,30 @@
     (void)pCtx;
 } /* End dot11fPackFfRCPI. */
 
+void dot11fPackFfRMCDialogToken(tpAniSirGlobal pCtx,
+                                tDot11fFfRMCDialogToken *pSrc,
+                                tANI_U8 *pBuf)
+{
+    frameshtonl(pCtx, pBuf, pSrc->token, 0);
+    (void)pCtx;
+} /* End dot11fPackFfRMCDialogToken. */
+
+void dot11fPackFfRMCOUI(tpAniSirGlobal pCtx,
+                        tDot11fFfRMCOUI *pSrc,
+                        tANI_U8 *pBuf)
+{
+    DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 3);
+    (void)pCtx;
+} /* End dot11fPackFfRMCOUI. */
+
+void dot11fPackFfRMCVersion(tpAniSirGlobal pCtx,
+                            tDot11fFfRMCVersion *pSrc,
+                            tANI_U8 *pBuf)
+{
+    *pBuf = pSrc->version;
+    (void)pCtx;
+} /* End dot11fPackFfRMCVersion. */
+
 void dot11fPackFfRSNI(tpAniSirGlobal pCtx,
                       tDot11fFfRSNI *pSrc,
                       tANI_U8 *pBuf)
@@ -23962,6 +24114,14 @@
     (void)pCtx;
 } /* End dot11fPackFfReason. */
 
+void dot11fPackFfRuler(tpAniSirGlobal pCtx,
+                       tDot11fFfRuler *pSrc,
+                       tANI_U8 *pBuf)
+{
+    DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6);
+    (void)pCtx;
+} /* End dot11fPackFfRuler. */
+
 void dot11fPackFfRxAntennaId(tpAniSirGlobal pCtx,
                              tDot11fFfRxAntennaId *pSrc,
                              tANI_U8 *pBuf)
@@ -41402,6 +41562,40 @@
 
 } /* End dot11fUnpackQosMapConfigure. */
 
+tANI_U32 dot11fPackRMC(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed)
+{
+    tANI_U32 i = 0;
+    tANI_U32 status = 0;
+    (void)i;
+    *pnConsumed = 0U;
+    status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_RMC, IES_RMC);
+
+#   ifdef DOT11F_DUMP_FRAMES
+    if (!DOT11F_FAILED(status))
+    {
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Packed the RMC:\n"));
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Category:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Category.category, 1);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCOUI:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCOUI.oui, 3);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("MagicCode:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->MagicCode.magic, 6);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCVersion:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCVersion.version, 1);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Action:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Action.action, 1);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCDialogToken:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCDialogToken.token, 4);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Ruler:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Ruler.mac, 6);
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("to:\n"));
+        FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), pBuf, nBuf);
+    }
+#   endif // DOT11F_DUMP_FRAMES
+    return status;
+
+} /* End dot11fUnpackRMC. */
+
 tANI_U32 dot11fPackRadioMeasurementReport(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed)
 {
     tANI_U32 i = 0;
@@ -45913,6 +46107,9 @@
             case SigFfListenInterval:
                 dot11fPackFfListenInterval(pCtx, (tDot11fFfListenInterval* )(pSrc + pFf->offset), pBufRemaining);
                 break;
+            case SigFfMagicCode:
+                dot11fPackFfMagicCode(pCtx, (tDot11fFfMagicCode* )(pSrc + pFf->offset), pBufRemaining);
+                break;
             case SigFfMaxTxPower:
                 dot11fPackFfMaxTxPower(pCtx, (tDot11fFfMaxTxPower* )(pSrc + pFf->offset), pBufRemaining);
                 break;
@@ -45931,12 +46128,24 @@
             case SigFfRCPI:
                 dot11fPackFfRCPI(pCtx, (tDot11fFfRCPI* )(pSrc + pFf->offset), pBufRemaining);
                 break;
+            case SigFfRMCDialogToken:
+                dot11fPackFfRMCDialogToken(pCtx, (tDot11fFfRMCDialogToken* )(pSrc + pFf->offset), pBufRemaining);
+                break;
+            case SigFfRMCOUI:
+                dot11fPackFfRMCOUI(pCtx, (tDot11fFfRMCOUI* )(pSrc + pFf->offset), pBufRemaining);
+                break;
+            case SigFfRMCVersion:
+                dot11fPackFfRMCVersion(pCtx, (tDot11fFfRMCVersion* )(pSrc + pFf->offset), pBufRemaining);
+                break;
             case SigFfRSNI:
                 dot11fPackFfRSNI(pCtx, (tDot11fFfRSNI* )(pSrc + pFf->offset), pBufRemaining);
                 break;
             case SigFfReason:
                 dot11fPackFfReason(pCtx, (tDot11fFfReason* )(pSrc + pFf->offset), pBufRemaining);
                 break;
+            case SigFfRuler:
+                dot11fPackFfRuler(pCtx, (tDot11fFfRuler* )(pSrc + pFf->offset), pBufRemaining);
+                break;
             case SigFfRxAntennaId:
                 dot11fPackFfRxAntennaId(pCtx, (tDot11fFfRxAntennaId* )(pSrc + pFf->offset), pBufRemaining);
                 break;
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index 3780fa7..8c38da2 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -550,6 +550,11 @@
 #endif
         CASE_RETURN_STRING(eWNI_SME_CANDIDATE_FOUND_IND);
         CASE_RETURN_STRING(eWNI_SME_HANDOFF_REQ);
+#ifdef WLAN_FEATURE_RMC
+        CASE_RETURN_STRING(eWNI_SME_ENABLE_RMC_REQ);
+        CASE_RETURN_STRING(eWNI_SME_DISABLE_RMC_REQ);
+        CASE_RETURN_STRING(eWNI_SME_IBSS_PEER_INFO_RSP);
+#endif
         CASE_RETURN_STRING(eWNI_SME_GET_ROAM_RSSI_REQ);
         CASE_RETURN_STRING(eWNI_SME_GET_ROAM_RSSI_RSP);
         CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_REQ);
@@ -838,6 +843,13 @@
 #ifdef FEATURE_WLAN_LPHB
         CASE_RETURN_STRING(WDA_LPHB_WAIT_EXPIRE_IND);
 #endif
+#ifdef WLAN_FEATURE_RMC
+        CASE_RETURN_STRING(WDA_RMC_BECOME_RULER);
+        CASE_RETURN_STRING(WDA_RMC_RULER_SELECT_RESP);
+        CASE_RETURN_STRING(WDA_RMC_RULER_REQ);
+        CASE_RETURN_STRING(WDA_RMC_UPDATE_IND);
+        CASE_RETURN_STRING(WDA_GET_IBSS_PEER_INFO_RSP);
+#endif
 #ifdef FEATURE_WLAN_BATCH_SCAN
         CASE_RETURN_STRING(WDA_SET_BATCH_SCAN_REQ);
         CASE_RETURN_STRING(WDA_SET_BATCH_SCAN_RSP);
@@ -855,6 +867,10 @@
         CASE_RETURN_STRING(WDA_ADD_PERIODIC_TX_PTRN_IND);
         CASE_RETURN_STRING(WDA_DEL_PERIODIC_TX_PTRN_IND);
         CASE_RETURN_STRING(WDA_RATE_UPDATE_IND);
+#ifdef WLAN_FEATURE_RMC
+        CASE_RETURN_STRING(WDA_GET_IBSS_PEER_INFO_REQ);
+        CASE_RETURN_STRING(WDA_TX_FAIL_MONITOR_IND);
+#endif /* WLAN_FEATURE_RMC */
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
         CASE_RETURN_STRING(WDA_LINK_LAYER_STATS_SET_REQ);
         CASE_RETURN_STRING(WDA_LINK_LAYER_STATS_GET_REQ);
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index 80975c7..bd396dc 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -3288,5 +3288,57 @@
 (
  v_VOID_t
 );
+#ifdef WLAN_FEATURE_RMC
+VOS_STATUS
+WLANTL_EnableRMC
+(
+    v_PVOID_t     pvosGCtx,
+    v_MACADDR_t   *pMcastAddr
+);
+
+
+VOS_STATUS
+WLANTL_DisableRMC
+(
+    v_PVOID_t     pvosGCtx,
+    v_MACADDR_t   *pMcastAddr
+);
+
+/*=============================================================================
+  FUNCTION    WLANTL_SetMcastDuplicateDetection
+
+  DESCRIPTION
+    This function sets multicate duplicate detection operation.
+    If enable is 1, the detection is enabled, else it is disabled.
+
+  DEPENDENCIES
+
+  PARAMETERS
+
+   IN
+
+   pvosGCtx   : Pointer to VOS global context
+   enable : Boolean to enable or disable
+
+  RETURN VALUE
+    The result code associated with performing the operation
+
+    VOS_STATUS_E_FAULT:   Sanity check on input failed
+
+    VOS_STATUS_SUCCESS:   Everything is good :)
+
+   Other return values are possible coming from the called functions.
+   Please check API for additional info.
+
+  SIDE EFFECTS
+
+==============================================================================*/
+VOS_STATUS
+WLANTL_SetMcastDuplicateDetection
+(
+    v_PVOID_t     pvosGCtx,
+    v_U8_t        enable
+);
+#endif /* WLAN_FEATURE_RMC */
 
 #endif /* #ifndef WLAN_QCT_WLANTL_H */
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index 10459f2..9b56815 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -61,6 +61,7 @@
 
   when        who     what, where, why
 ----------    ---    --------------------------------------------------------
+2013-08-19    rajekuma Added RMC support
 2010-07-13    c_shinde Fixed an issue where WAPI rekeying was failing because 
                       WAI frame sent out during rekeying had the protected bit
                       set to 1.
@@ -563,6 +564,16 @@
   }
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+   status = WLANTL_RmcInit(pvosGCtx);
+   if (!VOS_IS_STATUS_SUCCESS(status))
+   {
+    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+              "RMC module init fail"));
+    return status;
+  }
+#endif
+
   pTLCb->isBMPS = VOS_FALSE;
   pmcRegisterDeviceStateUpdateInd( smeContext,
                                    WLANTL_PowerStateChangedCB, pvosGCtx );
@@ -820,6 +831,14 @@
   }
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+  if(VOS_STATUS_SUCCESS != WLANTL_RmcDeInit(pvosGCtx))
+  {
+    TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
+               "RMC module DeInit fail"));
+  }
+#endif
+
   /*------------------------------------------------------------------------
     Cleanup TL control block.
    ------------------------------------------------------------------------*/
@@ -1451,6 +1470,10 @@
         pTLCb->ucTdlsPeerCount++;
 #endif
   }
+#ifdef WLAN_FEATURE_RMC
+  vos_lock_init(&pClientSTA->mcLock);
+#endif /* WLAN_FEATURE_RMC */
+
   return VOS_STATUS_SUCCESS;
 }/* WLANTL_RegisterSTAClient */
 
@@ -1555,6 +1578,15 @@
              "WLAN TL:Clearing STA Client ID: %d", ucSTAId ));
   WLANTL_CleanSTA(pTLCb->atlSTAClients[ucSTAId], 1 /*empty packets*/);
 
+#ifdef WLAN_FEATURE_RMC
+  /*--------------------------------------------------------------------
+    Delete multicast entries for duplicate detection
+    --------------------------------------------------------------------*/
+  WLANTL_McastDeleteAllEntries(pTLCb->atlSTAClients[ucSTAId]);
+
+  vos_lock_destroy(&pTLCb->atlSTAClients[ucSTAId]->mcLock);
+#endif /* WLAN_FEATURE_RMC */
+
   TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
              "WLAN TL:Clearing STA Reset History RSSI and Region number"));
   pTLCb->hoSupport.currentHOState.historyRSSI = 0;
@@ -8796,6 +8828,25 @@
   }
   }
 
+#ifdef WLAN_FEATURE_RMC
+  if (pTLCb->multicastDuplicateDetectionEnabled &&
+      (WLAN_STA_IBSS == pClientSTA->wSTADesc.wSTAType) &&
+       WLANTL_IS_DATA_FRAME(WDA_GET_RX_TYPE_SUBTYPE(aucBDHeader)))
+  {
+    /*
+     * Multicast duplicate detection is only for frames received in
+     * IBSS mode.
+     */
+    if (VOS_TRUE == WLANTL_IsDuplicateMcastFrm(pClientSTA, vosDataBuff))
+    {
+         pTLCb->mcastDupCnt++;
+         /* Duplicate multicast data packet, drop the packet */
+         vos_pkt_return_packet(vosDataBuff);
+         return VOS_STATUS_SUCCESS;
+    }
+  }
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_WAPI
   if ( pClientSTA->wSTADesc.ucIsWapiSta )
   {
@@ -13294,3 +13345,618 @@
 
     return VOS_STATUS_SUCCESS;
 }/* WLANTL_GetSTALinkCapacity */
+
+
+#ifdef WLAN_FEATURE_RMC
+VOS_STATUS WLANTL_RmcInit
+(
+    v_PVOID_t   pAdapter
+)
+{
+    WLANTL_CbType   *pTLCb = VOS_GET_TL_CB(pAdapter);
+    VOS_STATUS       status = VOS_STATUS_SUCCESS;
+    tANI_U8          count;
+
+    /*sanity check*/
+    if (NULL == pTLCb)
+    {
+        TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "Invalid TL handle"));
+        return VOS_STATUS_E_INVAL;
+    }
+
+    for ( count = 0; count < WLANTL_RMC_HASH_TABLE_SIZE; count++ )
+    {
+        pTLCb->rmcSession[count] = NULL;
+    }
+
+    vos_lock_init(&pTLCb->rmcLock);
+
+    pTLCb->multicastDuplicateDetectionEnabled = 1;
+    pTLCb->rmcDataPathEnabled = 0;
+
+    return status;
+}
+
+
+VOS_STATUS WLANTL_RmcDeInit
+(
+    v_PVOID_t   pAdapter
+)
+{
+    WLANTL_CbType   *pTLCb = VOS_GET_TL_CB(pAdapter);
+    VOS_STATUS       status = VOS_STATUS_SUCCESS;
+    tANI_U8          count;
+    WLANTL_RMC_SESSION *pNode;
+    WLANTL_RMC_SESSION *pPrev;
+
+    /*sanity check*/
+    if (NULL == pTLCb)
+    {
+        TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "Invalid TL handle"));
+        return VOS_STATUS_E_INVAL;
+    }
+
+    for ( count = 0; count < WLANTL_RMC_HASH_TABLE_SIZE; count++ )
+    {
+        pNode = pTLCb->rmcSession[count];
+        while (pNode)
+        {
+            pPrev = pNode;
+            pNode = pNode->next;
+            vos_mem_free((v_VOID_t * )pPrev);
+        }
+    }
+
+    vos_lock_destroy(&pTLCb->rmcLock);
+
+    return status;
+}
+
+
+tANI_U8 WLANTL_RmcHashRmcSession ( v_MACADDR_t   *pMcastAddr )
+{
+    tANI_U32 sum;
+    tANI_U8  hash;
+
+    sum = (pMcastAddr->bytes[0] + pMcastAddr->bytes[1] + pMcastAddr->bytes[2] +
+           pMcastAddr->bytes[3] + pMcastAddr->bytes[4] + pMcastAddr->bytes[5]);
+
+    hash = (tANI_U8)(sum & ((WLANTL_RMC_HASH_TABLE_SIZE - 1)));
+
+    return hash;
+}
+
+
+WLANTL_RMC_SESSION* WLANTL_RmcLookUpRmcSession
+(
+    WLANTL_RMC_SESSION *rmcSession[],
+    v_MACADDR_t     *pMcastAddr
+)
+{
+    WLANTL_RMC_SESSION *pNode;
+    tANI_U8               index;
+
+    /*sanity check*/
+    if (NULL == pMcastAddr)
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "Sanity check failed pMcastAddr %p", pMcastAddr));
+        return NULL;
+    }
+
+    index = WLANTL_RmcHashRmcSession(pMcastAddr);
+    pNode = rmcSession[index];
+    while ( pNode )
+    {
+        if (vos_is_macaddr_equal( &(pNode->rmcAddr), pMcastAddr))
+        {
+            return pNode;
+        }
+        pNode = pNode->next;
+    }
+
+    return NULL;
+}
+
+WLANTL_RMC_SESSION *WLANTL_RmcAddRmcSession
+(
+  WLANTL_RMC_SESSION *rmcSession[],
+  v_MACADDR_t   *pMcastAddr
+)
+{
+    WLANTL_RMC_SESSION *pNode;
+    tANI_U8               index;
+
+    index = WLANTL_RmcHashRmcSession(pMcastAddr);
+    pNode = WLANTL_RmcLookUpRmcSession(rmcSession, pMcastAddr);
+    if ( NULL != pNode )
+    {
+        /*already exists*/
+        return NULL;
+    }
+    else
+    {
+        pNode = (WLANTL_RMC_SESSION *)vos_mem_malloc(sizeof(*pNode));
+        if (pNode)
+        {
+            vos_mem_copy( &(pNode->rmcAddr), pMcastAddr,
+                sizeof(pNode->rmcAddr) );
+            pNode->next = rmcSession[index];
+            rmcSession[index] = pNode;
+            return pNode;
+        }
+        else
+        {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "%s: vos_mem_malloc failed can't enable RMC session",
+                __func__);
+            return NULL;
+        }
+    }
+}
+
+tANI_U8
+WLANTL_RmcDeleteRmcSession
+(
+  WLANTL_RMC_SESSION *rmcSession[],
+  v_MACADDR_t   *pMcastAddr
+)
+{
+    WLANTL_RMC_SESSION *pHead;
+    WLANTL_RMC_SESSION *pNode;
+    WLANTL_RMC_SESSION *pPrev;
+    tANI_U8               index;
+
+    index = WLANTL_RmcHashRmcSession(pMcastAddr);
+    pHead = pNode = rmcSession[index];
+    while (pNode)
+    {
+        if (vos_is_macaddr_equal( &(pNode->rmcAddr), pMcastAddr))
+        {
+            if (pHead == pNode)
+            {
+                rmcSession[index] = pNode->next;
+            }
+            else
+            {
+                pPrev->next = pNode->next;
+            }
+            vos_mem_free((v_VOID_t * )pNode);
+            return 1;
+        }
+        pPrev = pNode;
+        pNode = pNode->next;
+    }
+
+    return 0;
+}
+
+VOS_STATUS
+WLANTL_ProcessRmcCommand
+(
+    WLANTL_CbType*  pTLCb,
+    v_MACADDR_t    *pMcastAddr,
+    tANI_U32        command
+)
+{
+    VOS_STATUS status;
+    tANI_U32 count;
+    tANI_U32 rmcActive;
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire( &(pTLCb->rmcLock))))
+    {
+        TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "%s Get Lock Fail", __func__));
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    /*add or delete node from active rmc hash table*/
+    if (command)
+    {
+        /*add requested rmc session in active rmc session list*/
+        if (WLANTL_RmcAddRmcSession(pTLCb->rmcSession, pMcastAddr))
+        {
+            TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                "RMC session " MAC_ADDRESS_STR " added in TL hash table",
+                MAC_ADDR_ARRAY(pMcastAddr->bytes) ) );
+            pTLCb->rmcDataPathEnabled = TRUE;
+            status = VOS_STATUS_SUCCESS;
+        }
+        else
+        {
+            TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                "RMC session " MAC_ADDRESS_STR " already exists in TL hash"
+                " table", MAC_ADDR_ARRAY(pMcastAddr->bytes) ) );
+            status = VOS_STATUS_E_FAILURE;
+        }
+    }
+    else
+    {
+        /*delete requested rmc session from active rmc session list*/
+        if (WLANTL_RmcDeleteRmcSession(pTLCb->rmcSession, pMcastAddr))
+        {
+            TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+                "RMC session " MAC_ADDRESS_STR " deleted from TL hash table",
+                MAC_ADDR_ARRAY(pMcastAddr->bytes)) );
+            status = VOS_STATUS_SUCCESS;
+            rmcActive = FALSE;
+            for ( count = 0; count < WLANTL_RMC_HASH_TABLE_SIZE; count++ )
+            {
+                if (pTLCb->rmcSession[count])
+                {
+                    rmcActive = TRUE;
+                    break;
+                }
+            }
+            if (TRUE == rmcActive)
+            {
+                pTLCb->rmcDataPathEnabled = TRUE;
+            }
+            else
+            {
+                pTLCb->rmcDataPathEnabled = FALSE;
+            }
+        }
+        else
+        {
+            TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                "RMC session " MAC_ADDRESS_STR " doesn't exist in TL hash"
+                " table", MAC_ADDR_ARRAY(pMcastAddr->bytes) ) );
+            status = VOS_STATUS_E_FAILURE;
+        }
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&(pTLCb->rmcLock))))
+    {
+         TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+             "%s Release Lock Fail", __func__));
+         return VOS_STATUS_E_FAILURE;
+    }
+
+    return status;
+}/* End of WLANTL_ProcessRmcCommand */
+
+VOS_STATUS
+WLANTL_EnableRMC
+(
+    v_PVOID_t     pvosGCtx,
+    v_MACADDR_t   *pMcastTransmitterAddr
+)
+{
+    WLANTL_CbType*  pTLCb;
+    VOS_STATUS status;
+
+    /*sanity check*/
+    if ( (NULL == pvosGCtx) || (NULL == pMcastTransmitterAddr) )
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL %s: Sanity check failed pvosGCtx %p aMcastAddr %p",
+            __func__, pvosGCtx, pMcastTransmitterAddr));
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    /*sanity check*/
+    pTLCb = VOS_GET_TL_CB(pvosGCtx);
+    if ( NULL == pTLCb )
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL %s: pTLCb is NULL", __func__));
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    status = WLANTL_ProcessRmcCommand(pTLCb, pMcastTransmitterAddr , 1);
+
+    return status;
+} /* End of WLANTL_EnableRMC */
+
+
+VOS_STATUS
+WLANTL_DisableRMC
+(
+    v_PVOID_t     pvosGCtx,
+    v_MACADDR_t   *pMcastTransmitterAddr
+)
+{
+    WLANTL_CbType* pTLCb;
+    VOS_STATUS status;
+
+    /*Sanity check*/
+    if ((NULL == pvosGCtx) || (NULL == pMcastTransmitterAddr))
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL %s: Sanity check failed pvosGCtx %p aMcastAddr %p",
+             __func__, pvosGCtx, pMcastTransmitterAddr));
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    /*Sanity check*/
+    pTLCb = VOS_GET_TL_CB(pvosGCtx);
+    if (NULL == pTLCb)
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL %s: pTLCb is NULL", __func__));
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    status = WLANTL_ProcessRmcCommand(pTLCb, pMcastTransmitterAddr, 0);
+
+    return status;
+} /* End of WLANTL_DisableRMC */
+
+
+/*=============================================================================
+        Duplicate Multicast Detection Functions
+==============================================================================*/
+
+/*=============================================================================
+  FUNCTION    WLANTL_IsDuplicateMcastFrm
+
+  DESCRIPTION
+    This function checks for duplicast multicast frames and drops them.
+
+  DEPENDENCIES
+
+  PARAMETERS
+
+   IN
+
+   pClientSTA  : Pointer to WLANTL_STAClientType
+   aucBDHeader : Pointer to BD header
+
+  RETURN VALUE
+
+    VOS_FALSE:  This frame is not a duplicate
+
+    VOS_TRUE:   This frame is a duplicate
+
+==============================================================================*/
+v_U8_t
+WLANTL_IsDuplicateMcastFrm
+(
+    WLANTL_STAClientType *pClientSTA,
+    vos_pkt_t *vosDataBuff
+)
+{
+    v_U8_t duplicate = VOS_FALSE;
+    WLANTL_RMC_SESSION *pNode;
+    v_U16_t     usSeqCtrl;
+    v_MACADDR_t mcastAddr;
+    VOS_STATUS  vosStatus;
+    v_PVOID_t   pvPeekData;
+
+    /* Get address 1 of Data Frame */
+    vosStatus = vos_pkt_peek_data(vosDataBuff, WLANTL_MAC_ADDR_ALIGN(1),
+                                  (v_PVOID_t)&pvPeekData, VOS_MAC_ADDR_SIZE);
+
+    if ( VOS_STATUS_SUCCESS != vosStatus )
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                "WLAN TL: Failed to get Addr 1 of 80211 header from packet %d",
+                vosStatus));
+        return VOS_FALSE;
+    }
+
+    /* Copy address 1 of Data Frame */
+    vos_mem_copy(&mcastAddr.bytes, pvPeekData, VOS_MAC_ADDR_SIZE);
+
+    /*
+     * We perform duplicate detection for only multicast data frames
+     */
+    if (vos_is_macaddr_group(&mcastAddr) &&
+         !vos_is_macaddr_broadcast(&mcastAddr))
+    {
+        /* Get sequence control of Data Frame */
+        vosStatus = vos_pkt_peek_data(vosDataBuff,
+                    (WLANTL_MAC_ADDR_ALIGN(1) + (3 * VOS_MAC_ADDR_SIZE)),
+                      (v_PVOID_t)&pvPeekData, sizeof(v_U16_t));
+
+        if ( VOS_STATUS_SUCCESS != vosStatus )
+        {
+            TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                    "WLAN TL: Failed to get Sequence Control from packet %d",
+                    vosStatus));
+            return VOS_FALSE;
+        }
+
+        /* Copy sequence control from the Data Frame */
+        usSeqCtrl = *(v_U16_t *)pvPeekData;
+
+        if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&(pClientSTA->mcLock))))
+        {
+            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                    "%s Get Lock Fail", __func__));
+            return VOS_FALSE;
+        }
+
+        pNode = WLANTL_RmcLookUpRmcSession(pClientSTA->mcastSession,
+                                                      &mcastAddr);
+        if (NULL == pNode)
+        {
+            /* If the session does not exist, add it. */
+            pNode = WLANTL_RmcAddRmcSession(pClientSTA->mcastSession,
+                                              &mcastAddr);
+            /* If we could not add a entry, skip duplicate detection */
+            if (NULL == pNode)
+            {
+                TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                    "%s Failed to add multicast session", __func__));
+                if (!VOS_IS_STATUS_SUCCESS
+                     (vos_lock_release(&(pClientSTA->mcLock))))
+                {
+                    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                        "%s Release Lock Fail", __func__));
+                }
+                return VOS_FALSE;
+            }
+            /* Initialize the sequence control value. */
+            pNode->mcSeqCtl = usSeqCtrl;
+        }
+        else
+        {
+            /*
+             * Check if the sequence number of this frame matches the last
+             * we have seen.
+             */
+            if (pNode->mcSeqCtl == usSeqCtrl)
+            {
+                pNode->rxMCDupcnt++;
+                TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+                     "%s Rx Multicast Duplicate %d " MAC_ADDRESS_STR
+                     " (Seq %x)", __func__,
+                     pNode->rxMCDupcnt, MAC_ADDR_ARRAY(mcastAddr.bytes),
+                     usSeqCtrl));
+                duplicate = VOS_TRUE;
+            }
+            else
+            {
+                /* Update the last seen sequence number */
+                pNode->mcSeqCtl = usSeqCtrl;
+            }
+        }
+
+        if (!VOS_IS_STATUS_SUCCESS (vos_lock_release(&(pClientSTA->mcLock))))
+        {
+            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                    "%s Release Lock Fail", __func__));
+        }
+    }
+
+    return duplicate;
+}
+
+/*=============================================================================
+  FUNCTION    WLANTL_McastDeleteAllEntries
+
+  DESCRIPTION
+    This function removes all multicast entries used for duplicate detection
+
+  DEPENDENCIES
+
+  PARAMETERS
+
+   IN
+
+   pClientSTA  : Pointer to WLANTL_STAClientType
+
+  RETURN VALUE
+
+    None
+
+==============================================================================*/
+void
+WLANTL_McastDeleteAllEntries(WLANTL_STAClientType * pClientSTA)
+{
+    WLANTL_RMC_SESSION *pNode, **head;
+    int index;
+
+    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+                        "%s Deleting all multicast entries", __func__));
+
+    if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&(pClientSTA->mcLock))))
+    {
+        TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                "%s Get Lock Fail", __func__));
+        return;
+    }
+
+    for (index = 0; index < WLANTL_RMC_HASH_TABLE_SIZE; index++)
+    {
+        head = &pClientSTA->mcastSession[index];
+
+        pNode = *head;
+
+        while (pNode)
+        {
+            *head = pNode->next;
+            /* free the group entry */
+            vos_mem_free(pNode);
+            pNode = *head;
+        }
+    }
+
+    if (!VOS_IS_STATUS_SUCCESS (vos_lock_release(&(pClientSTA->mcLock))))
+    {
+        TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                "%s Release Lock Fail", __func__));
+    }
+}
+
+/*=============================================================================
+  FUNCTION    WLANTL_SetMcastDuplicateDetection
+
+  DESCRIPTION
+    This function sets multicate duplicate detection operation.
+    If enable is 1, the detection is enabled, else it is disabled.
+
+  DEPENDENCIES
+
+  PARAMETERS
+
+   IN
+
+   pvosGCtx   : Pointer to VOS global context
+   enable : Boolean to enable or disable
+
+  RETURN VALUE
+    The result code associated with performing the operation
+
+    VOS_STATUS_E_FAULT:   Sanity check on input failed
+
+    VOS_STATUS_SUCCESS:   Everything is good :)
+
+   Other return values are possible coming from the called functions.
+   Please check API for additional info.
+
+  SIDE EFFECTS
+
+==============================================================================*/
+VOS_STATUS
+WLANTL_SetMcastDuplicateDetection
+(
+    v_PVOID_t     pvosGCtx,
+    v_U8_t        enable
+)
+{
+    WLANTL_CbType* pTLCb;
+
+    /*Sanity check*/
+    if (NULL == pvosGCtx)
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL %s: Sanity check failed pvosGCtx %p",
+             __func__, pvosGCtx));
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    /*Sanity check*/
+    pTLCb = VOS_GET_TL_CB(pvosGCtx);
+    if (NULL == pTLCb)
+    {
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL %s: pTLCb is NULL", __func__));
+        return VOS_STATUS_E_FAILURE;
+    }
+
+    switch (enable)
+    {
+    default:
+        /*
+         * Any value other than 0 or 1 is used to dump the
+         * duplicate count.
+         */
+        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL %s: Multicast Duplicate Count %d",
+             __func__, pTLCb->mcastDupCnt));
+        break;
+    case 0:
+    case 1:
+        pTLCb->multicastDuplicateDetectionEnabled = enable;
+        break;
+    }
+
+    return VOS_STATUS_SUCCESS;
+}
+
+#endif /* WLAN_FEATURE_RMC */
diff --git a/CORE/TL/src/wlan_qct_tli.h b/CORE/TL/src/wlan_qct_tli.h
index c59067c..32819d2 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -58,6 +58,7 @@
 
 when        who    what, where, why
 --------    ---    ----------------------------------------------------------
+08/19/13    rajekuma Added RMC support in TL
 02/19/10    bad     Fixed 802.11 to 802.3 ft issues with WAPI
 01/14/10    rnair   Fixed the byte order for the WAI packet type.
 01/08/10    lti     Added TL Data Caching
@@ -185,6 +186,10 @@
 
 #define WLANTL_FRAME_TYPESUBTYPE_MASK 0x3F
 
+#ifdef WLAN_FEATURE_RMC
+#define WLANTL_RMC_HASH_TABLE_SIZE (32)
+#endif
+
 /*-------------------------------------------------------------------------
   BT-AMP related definition - !!! should probably be moved to BT-AMP header
 ---------------------------------------------------------------------------*/
@@ -491,6 +496,18 @@
   v_U8_t              ucSet;
 }WLANTL_UAPSDInfoType;
 
+#ifdef WLAN_FEATURE_RMC
+struct tTL_RMCList
+{
+  struct tTL_RMCList    *next;
+  v_MACADDR_t           rmcAddr;
+  v_U16_t               mcSeqCtl;
+  v_U32_t               rxMCDupcnt;
+};
+
+typedef struct tTL_RMCList WLANTL_RMC_SESSION;
+#endif
+
 /*---------------------------------------------------------------------------
   per-STA cache info
 ---------------------------------------------------------------------------*/
@@ -685,6 +702,11 @@
 
   v_U32_t       linkCapacity;
 
+#ifdef WLAN_FEATURE_RMC
+  WLANTL_RMC_SESSION *mcastSession[WLANTL_RMC_HASH_TABLE_SIZE];
+  vos_lock_t mcLock;
+#endif
+
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
 
   /* Value of the averaged Data RSSI for this station */
@@ -896,6 +918,14 @@
   v_BOOL_t                  isBMPS;
   /* Whether WDA_DS_TX_START_XMIT msg is pending or not */
   v_BOOL_t   isTxTranmitMsgPending;
+
+#ifdef WLAN_FEATURE_RMC
+  WLANTL_RMC_SESSION *rmcSession[WLANTL_RMC_HASH_TABLE_SIZE];
+  vos_lock_t rmcLock;
+  v_U8_t multicastDuplicateDetectionEnabled;
+  v_U8_t rmcDataPathEnabled;
+  v_U32_t mcastDupCnt;
+#endif
   WLANTL_MonRxCBType           pfnMonRx;
   v_BOOL_t              isConversionReq;
 
@@ -1754,4 +1784,99 @@
   v_U8_t          ucSTAId
 );
 
+#ifdef WLAN_FEATURE_RMC
+VOS_STATUS WLANTL_RmcInit
+(
+     v_PVOID_t   pAdapter
+);
+
+VOS_STATUS WLANTL_RmcDeInit
+(
+    v_PVOID_t   pAdapter
+);
+
+
+tANI_U8 WLANTL_RmcHashRmcSession ( v_MACADDR_t   *pMcastAddr );
+
+
+WLANTL_RMC_SESSION *WLANTL_RmcLookUpRmcSession
+(
+    WLANTL_RMC_SESSION *rmcSession[],
+    v_MACADDR_t     *pMcastAddr
+);
+
+WLANTL_RMC_SESSION *WLANTL_RmcAddRmcSession
+(
+    WLANTL_RMC_SESSION *rmcSession[],
+    v_MACADDR_t   *pMcastAddr
+);
+
+tANI_U8
+WLANTL_RmcDeleteRmcSession
+(
+    WLANTL_RMC_SESSION *rmcSession[],
+    v_MACADDR_t   *pMcastAddr
+);
+
+VOS_STATUS
+WLANTL_ProcessRmcCommand
+(
+    WLANTL_CbType*  pTLCb,
+    v_MACADDR_t    *pMcastAddr,
+    tANI_U32        command
+);
+
+/*=============================================================================
+  FUNCTION    WLANTL_IsDuplicateMcastFrm
+
+  DESCRIPTION
+    This function checks for duplicast multicast frames and drops them.
+
+  DEPENDENCIES
+
+  PARAMETERS
+
+   IN
+
+   pClientSTA  : Pointer to WLANTL_STAClientType
+   aucBDHeader : Pointer to BD header
+
+  RETURN VALUE
+
+    VOS_FALSE:  This frame is not a duplicate
+
+    VOS_TRUE:   This frame is a duplicate
+
+==============================================================================*/
+v_U8_t
+WLANTL_IsDuplicateMcastFrm
+(
+    WLANTL_STAClientType *pClientSTA,
+    vos_pkt_t* vosDataBuff
+);
+
+/*=============================================================================
+  FUNCTION    WLANTL_McastDeleteAllEntries
+
+  DESCRIPTION
+    This function removes all multicast entries used for duplicate detection
+
+  DEPENDENCIES
+
+  PARAMETERS
+
+   IN
+
+   pClientSTA  : Pointer to WLANTL_STAClientType
+
+  RETURN VALUE
+
+    None
+
+==============================================================================*/
+void
+WLANTL_McastDeleteAllEntries(WLANTL_STAClientType * pClientSTA);
+
+#endif /*WLAN_FEATURE_RMC*/
+
 #endif /* #ifndef WLAN_QCT_TLI_H */
diff --git a/CORE/WDA/inc/legacy/wlan_qct_hal.h b/CORE/WDA/inc/legacy/wlan_qct_hal.h
index 5e9595f..3d1909c 100644
--- a/CORE/WDA/inc/legacy/wlan_qct_hal.h
+++ b/CORE/WDA/inc/legacy/wlan_qct_hal.h
@@ -339,7 +339,9 @@
 #define HAL_TDLS_PEER_STA_MASK              0x80 //bit 7 set for TDLS peer station 
 #endif
 
-#define HAL_RELIABLE_MCAST_REQUESTED_MASK   0x100
+#ifdef WLAN_FEATURE_RMC
+#define HAL_RMC_REQUESTED_MASK   0x100
+#endif
 
 #define HAL_USE_BD_RATE_1_MASK              0x1000 // bit 12 for BD RATE 1
 #define HAL_USE_BD_RATE_2_MASK              0x2000 // bit 13 for BD RATE 1
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 025e8567..ff4ed62 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -381,6 +381,10 @@
 //parameter 2 - txComplete status : 1- success, 0 - failure.
 typedef eHalStatus (*pWDAAckFnTxComp)(tpAniSirGlobal, void *pData);
 
+#ifdef WLAN_FEATURE_RMC
+typedef void (*WDA_txFailIndCallback)(tANI_U8 *, tANI_U8);
+#endif /* WLAN_FEATURE_RMC */
+
 typedef struct
 {
    tANI_U16 ucValidStaIndex ;
@@ -511,6 +515,10 @@
    vos_event_t          ftmStopDoneEvent;
 
    tWDA_AddSelfStaDebugParams wdaAddSelfStaParams;
+
+#ifdef WLAN_FEATURE_RMC
+   WDA_txFailIndCallback txFailIndCallback;
+#endif /* WLAN_FEATURE_RMC */
    tWDA_RespFailureCounts  failureCounts;
    wpt_uint8  mgmtTxfailureCnt;
 
@@ -1189,6 +1197,10 @@
 #define WDA_DHCP_START_IND              SIR_HAL_DHCP_START_IND
 #define WDA_DHCP_STOP_IND               SIR_HAL_DHCP_STOP_IND
 
+#ifdef WLAN_FEATURE_RMC
+#define WDA_TX_FAIL_MONITOR_IND         SIR_HAL_TX_FAIL_MONITOR_IND
+#endif /* WLAN_FEATURE_RMC */
+
 
 #ifdef WLAN_FEATURE_GTK_OFFLOAD
 #define WDA_GTK_OFFLOAD_REQ             SIR_HAL_GTK_OFFLOAD_REQ
@@ -1224,14 +1236,24 @@
 #define WDA_ADD_PERIODIC_TX_PTRN_IND    SIR_HAL_ADD_PERIODIC_TX_PTRN_IND
 #define WDA_DEL_PERIODIC_TX_PTRN_IND    SIR_HAL_DEL_PERIODIC_TX_PTRN_IND
 
+#define WDA_RATE_UPDATE_IND         SIR_HAL_RATE_UPDATE_IND
+
+#ifdef WLAN_FEATURE_RMC
+#define WDA_RMC_BECOME_RULER       SIR_HAL_RMC_BECOME_RULER
+#define WDA_RMC_RULER_SELECT_RESP  SIR_HAL_RMC_RULER_SELECT_RESP
+#define WDA_RMC_RULER_REQ          SIR_HAL_RMC_RULER_REQ
+#define WDA_RMC_UPDATE_IND          SIR_HAL_RMC_UPDATE_IND
+/* IBSS peer info related message */
+#define WDA_GET_IBSS_PEER_INFO_REQ  SIR_HAL_IBSS_PEER_INFO_REQ
+#define WDA_GET_IBSS_PEER_INFO_RSP  SIR_HAL_IBSS_PEER_INFO_RSP
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
 #define WDA_SET_BATCH_SCAN_REQ            SIR_HAL_SET_BATCH_SCAN_REQ
 #define WDA_SET_BATCH_SCAN_RSP            SIR_HAL_SET_BATCH_SCAN_RSP
 #define WDA_STOP_BATCH_SCAN_IND           SIR_HAL_STOP_BATCH_SCAN_IND
 #define WDA_TRIGGER_BATCH_SCAN_RESULT_IND SIR_HAL_TRIGGER_BATCH_SCAN_RESULT_IND
 #endif
-#define WDA_RATE_UPDATE_IND         SIR_HAL_RATE_UPDATE_IND
-
 
 #define WDA_HT40_OBSS_SCAN_IND   SIR_HAL_HT40_OBSS_SCAN_IND
 #define WDA_HT40_OBSS_STOP_SCAN_IND SIR_HAL_HT40_OBSS_STOP_SCAN_IND
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index a21df76..8af71d4 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -227,6 +227,11 @@
                                   tSirLPHBReq *pData);
 #endif /* FEATURE_WLAN_LPHB */
 
+#ifdef WLAN_FEATURE_RMC
+void WDA_IBSSPeerInfoRequestHandler(v_PVOID_t pVosContext,
+                                                v_PVOID_t pData);
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef WLAN_FEATURE_EXTSCAN
 VOS_STATUS WDA_ProcessEXTScanStartReq(tWDA_CbContext *pWDA,
                                       tSirEXTScanStartReqParams *wdaRequest);
@@ -13493,6 +13498,56 @@
    return CONVERT_WDI2VOS_STATUS(wdiStatus);
 }
 
+/*
+ * FUNCTION: WDA_ProcessRateUpdateInd
+ *
+ */
+VOS_STATUS WDA_ProcessRateUpdateInd(tWDA_CbContext *pWDA,
+                               tSirRateUpdateInd *pRateUpdateParams)
+{
+   WDI_Status wdiStatus;
+   WDI_RateUpdateIndParams rateUpdateParams;
+
+   vos_mem_copy(rateUpdateParams.bssid,
+            pRateUpdateParams->bssid, sizeof(tSirMacAddr));
+
+   rateUpdateParams.ucastDataRateTxFlag =
+                     pRateUpdateParams->ucastDataRateTxFlag;
+   rateUpdateParams.rmcDataRateTxFlag =
+                     pRateUpdateParams->rmcDataRateTxFlag;
+   rateUpdateParams.mcastDataRate24GHzTxFlag =
+                     pRateUpdateParams->mcastDataRate24GHzTxFlag;
+   rateUpdateParams.mcastDataRate5GHzTxFlag =
+                     pRateUpdateParams->mcastDataRate5GHzTxFlag;
+
+   rateUpdateParams.ucastDataRate = pRateUpdateParams->ucastDataRate;
+   rateUpdateParams.rmcDataRate =
+                                 pRateUpdateParams->rmcDataRate;
+   rateUpdateParams.mcastDataRate24GHz = pRateUpdateParams->mcastDataRate24GHz;
+   rateUpdateParams.mcastDataRate5GHz = pRateUpdateParams->mcastDataRate5GHz;
+
+   rateUpdateParams.wdiReqStatusCB = WDA_WdiIndicationCallback;
+   rateUpdateParams.pUserData = pWDA;
+
+   wdiStatus = WDI_RateUpdateInd(&rateUpdateParams);
+
+   if (WDI_STATUS_PENDING == wdiStatus)
+   {
+      VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                "Pending received for %s:%d", __func__, __LINE__ );
+   }
+   else if (WDI_STATUS_SUCCESS_SYNC != wdiStatus)
+   {
+      VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "Failure in %s:%d", __func__, __LINE__ );
+   }
+
+   vos_mem_free(pRateUpdateParams);
+
+   return CONVERT_WDI2VOS_STATUS(wdiStatus);
+}
+
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
 /*
  * FUNCTION: WDA_ProcessStopBatchScanInd
@@ -13823,55 +13878,6 @@
    return CONVERT_WDI2VOS_STATUS(status) ;
 }
 /*
- * FUNCTION: WDA_ProcessRateUpdateInd
- *
- */
-VOS_STATUS WDA_ProcessRateUpdateInd(tWDA_CbContext *pWDA,
-                               tSirRateUpdateInd *pRateUpdateParams)
-{
-   WDI_Status wdiStatus;
-   WDI_RateUpdateIndParams rateUpdateParams;
-
-   vos_mem_copy(rateUpdateParams.bssid,
-            pRateUpdateParams->bssid, sizeof(tSirMacAddr));
-
-   rateUpdateParams.ucastDataRateTxFlag =
-                     pRateUpdateParams->ucastDataRateTxFlag;
-   rateUpdateParams.reliableMcastDataRateTxFlag =
-                     pRateUpdateParams->reliableMcastDataRateTxFlag;
-   rateUpdateParams.mcastDataRate24GHzTxFlag =
-                     pRateUpdateParams->mcastDataRate24GHzTxFlag;
-   rateUpdateParams.mcastDataRate5GHzTxFlag =
-                     pRateUpdateParams->mcastDataRate5GHzTxFlag;
-
-   rateUpdateParams.ucastDataRate = pRateUpdateParams->ucastDataRate;
-   rateUpdateParams.reliableMcastDataRate =
-                                 pRateUpdateParams->reliableMcastDataRate;
-   rateUpdateParams.mcastDataRate24GHz = pRateUpdateParams->mcastDataRate24GHz;
-   rateUpdateParams.mcastDataRate5GHz = pRateUpdateParams->mcastDataRate5GHz;
-
-   rateUpdateParams.wdiReqStatusCB = WDA_WdiIndicationCallback;
-   rateUpdateParams.pUserData = pWDA;
-
-   wdiStatus = WDI_RateUpdateInd(&rateUpdateParams);
-
-   if (WDI_STATUS_PENDING == wdiStatus)
-   {
-      VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
-                "Pending received for %s:%d", __func__, __LINE__ );
-   }
-   else if (WDI_STATUS_SUCCESS_SYNC != wdiStatus)
-   {
-      VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
-                "Failure in %s:%d", __func__, __LINE__ );
-   }
-
-   vos_mem_free(pRateUpdateParams);
-
-   return CONVERT_WDI2VOS_STATUS(wdiStatus);
-}
-
-/*
  * -------------------------------------------------------------------------
  * DATA interface with WDI for Mgmt Frames
  * ------------------------------------------------------------------------- 
@@ -14290,6 +14296,448 @@
    return CONVERT_WDI2VOS_STATUS(status) ;
  }
 
+#ifdef WLAN_FEATURE_RMC
+
+void
+WDA_RMCRulerRspCallback(WDI_RmcRspParamsType *wdiRmcResponse, void *pUserData)
+{
+    tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+    tWDA_CbContext *pWDA = pWdaParams->pWdaContext;
+
+    switch (wdiRmcResponse->cmd)
+    {
+        case eWDI_BECOME_RULER_CMD :
+        {
+            tSirRmcBecomeRulerInd *pRmcBecomeRulerInd;
+
+            pRmcBecomeRulerInd = (tSirRmcBecomeRulerInd *)
+                                   vos_mem_malloc(sizeof(*pRmcBecomeRulerInd));
+
+            if (NULL == pRmcBecomeRulerInd)
+            {
+               VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: unable to allocate pRmcBecomeRulerInd", __func__);
+               break;
+            }
+
+            VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                        "Received eWDI_BECOME_RULER_CMD from WDI");
+
+            pRmcBecomeRulerInd->status = wdiRmcResponse->status;
+
+            vos_mem_copy(pRmcBecomeRulerInd->mcastTransmitter,
+                          wdiRmcResponse->mcastTransmitter,
+                          sizeof(tSirMacAddr));
+            vos_mem_copy(pRmcBecomeRulerInd->mcastGroup,
+                          wdiRmcResponse->mcastGroup,
+                          sizeof(tSirMacAddr));
+
+            WDA_SendMsg(pWDA, WDA_RMC_BECOME_RULER,
+                               (void *)pRmcBecomeRulerInd, 0) ;
+            break;
+        }
+        case eWDI_SUGGEST_RULER_CMD :
+        {
+            tSirRmcRulerSelectInd *pRmcRulerSelectInd;
+
+            pRmcRulerSelectInd = (tSirRmcRulerSelectInd *)
+                                   vos_mem_malloc(sizeof(tSirRmcRulerSelectInd));
+
+            if (NULL == pRmcRulerSelectInd)
+            {
+               VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: unable to allocate pRmcRulerSelectInd", __func__);
+               break;
+            }
+
+            VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                              "Received eWDI_SUGGEST_RULER_CMD from WDI");
+
+            pRmcRulerSelectInd->status = wdiRmcResponse->status;
+
+            vos_mem_copy(pRmcRulerSelectInd->mcastTransmitter,
+                        wdiRmcResponse->mcastTransmitter,
+                        sizeof(tSirMacAddr));
+            vos_mem_copy(pRmcRulerSelectInd->mcastGroup,
+                        wdiRmcResponse->mcastGroup,
+                        sizeof(tSirMacAddr));
+            vos_mem_copy(pRmcRulerSelectInd->ruler,
+                        wdiRmcResponse->ruler,
+                        sizeof(pRmcRulerSelectInd->ruler));
+
+            WDA_SendMsg(pWDA, WDA_RMC_RULER_SELECT_RESP,
+                                       (void *)pRmcRulerSelectInd, 0) ;
+            break;
+        }
+    }
+
+    /* free the config structure */
+    if (pWdaParams->wdaWdiApiMsgParam != NULL)
+    {
+        vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+    }
+    vos_mem_free(pWdaParams->wdaMsgParam);
+    vos_mem_free(pWdaParams);
+
+}
+
+void WDA_RMCRulerReqCallback(WDI_Status wdiStatus, void* pUserData)
+{
+    tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+
+    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+              "<------ %s, wdiStatus: %d", __func__, wdiStatus);
+
+    if (NULL == pWdaParams)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: pWdaParams received NULL", __func__);
+        VOS_ASSERT(0);
+        return;
+    }
+
+    if (IS_WDI_STATUS_FAILURE(wdiStatus))
+    {
+        vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+        vos_mem_free(pWdaParams->wdaMsgParam);
+        vos_mem_free(pWdaParams);
+    }
+
+   return;
+}
+
+static VOS_STATUS
+WDA_ProcessRMCRulerReq(tWDA_CbContext *pWDA,
+                        tSirRmcRulerReq *rmcRulerReq)
+{
+    WDI_Status status;
+    WDI_RmcRulerReqParams *wdiRulerReq;
+    tWDA_ReqParams *pWdaParams;
+
+    wdiRulerReq = (WDI_RmcRulerReqParams *)
+                        vos_mem_malloc(sizeof(*wdiRulerReq));
+
+    if (NULL == wdiRulerReq)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: VOS MEM Alloc Failure", __func__);
+        VOS_ASSERT(0);
+        vos_mem_free(rmcRulerReq);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams));
+    if (NULL == pWdaParams)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                           "%s: VOS MEM Alloc Failure", __func__);
+        VOS_ASSERT(0);
+        vos_mem_free(rmcRulerReq);
+        vos_mem_free(wdiRulerReq);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    pWdaParams->wdaWdiApiMsgParam = (v_PVOID_t *)wdiRulerReq;
+    /* Store param pointer as passed in by caller */
+    pWdaParams->wdaMsgParam = rmcRulerReq;
+    pWdaParams->pWdaContext = pWDA;
+
+    wdiRulerReq->cmd = rmcRulerReq->cmd;
+
+    vos_mem_copy(wdiRulerReq->mcastTransmitter,
+            rmcRulerReq->mcastTransmitter, sizeof(tSirMacAddr));
+    vos_mem_copy(wdiRulerReq->mcastGroup,
+            rmcRulerReq->mcastGroup, sizeof(tSirMacAddr));
+    vos_mem_copy(wdiRulerReq->blacklist,
+            rmcRulerReq->blacklist, sizeof(wdiRulerReq->blacklist));
+
+    wdiRulerReq->wdiReqStatusCB = WDA_RMCRulerReqCallback;
+
+    status = WDI_RmcRulerReq(wdiRulerReq,
+                 (WDI_RmcRulerRspCb)WDA_RMCRulerRspCallback,
+                 (void *)pWdaParams);
+    if (IS_WDI_STATUS_FAILURE(status))
+    {
+        vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+        vos_mem_free(pWdaParams->wdaMsgParam);
+        vos_mem_free(pWdaParams) ;
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                   "Ruler Request failed");
+    }
+    return CONVERT_WDI2VOS_STATUS(status) ;
+}
+
+/*
+ * FUNCTION: WDA_ProcessRMCUpdateInd
+ * Forward Update Indication to WDI
+*/
+static VOS_STATUS
+WDA_ProcessRMCUpdateInd(tWDA_CbContext *pWDA,
+                         tSirRmcUpdateInd *rmcUpdateInd)
+{
+    WDI_Status status;
+    WDI_RmcUpdateIndParams wdiUpdateInd;
+
+    /* Copy the paramters for Update_Ind */
+
+    wdiUpdateInd.indication = rmcUpdateInd->indication;
+    wdiUpdateInd.role = rmcUpdateInd->role;
+
+    vos_mem_copy(wdiUpdateInd.mcastTransmitter,
+            rmcUpdateInd->mcastTransmitter, sizeof(tSirMacAddr));
+
+    vos_mem_copy(wdiUpdateInd.mcastGroup,
+            rmcUpdateInd->mcastGroup, sizeof(tSirMacAddr));
+
+    vos_mem_copy(wdiUpdateInd.mcastRuler,
+            rmcUpdateInd->mcastRuler, sizeof(tSirMacAddr));
+
+    wdiUpdateInd.wdiReqStatusCB = WDA_WdiIndicationCallback;
+    wdiUpdateInd.pUserData = pWDA;
+    status = WDI_RmcUpdateInd(&wdiUpdateInd);
+
+    if (WDI_STATUS_PENDING == status)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                 "Pending received for %s:%d ",__func__,__LINE__ );
+    }
+    else if (WDI_STATUS_SUCCESS_SYNC != status)
+    {
+       VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "Failure in %s:%d ",__func__,__LINE__ );
+    }
+
+    vos_mem_free(rmcUpdateInd);
+
+    return CONVERT_WDI2VOS_STATUS(status) ;
+}
+
+void WDA_GetIbssPeerInfoRspCallback(WDI_IbssPeerInfoRspParams *peerInfoRspParams
+                                    ,void* pUserData)
+{
+
+   tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+   WDI_IbssPeerInfoParams *pIbssPeerInfoParams;
+   tWDA_CbContext *pWDA;
+   tpSirIbssGetPeerInfoRspParams pIbssGetPeerInfoRsp;
+   vos_msg_t vosMsg;
+   v_U32_t wdaCnt = 0;
+
+   VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                                          "<------ %s " ,__func__);
+   if (NULL == pWdaParams)
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: pWdaParams received NULL", __func__);
+      VOS_ASSERT(0);
+      return;
+   }
+
+   if (NULL == peerInfoRspParams)
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: peerInfoRspParams received NULL", __func__);
+      if(pWdaParams->wdaMsgParam)
+         vos_mem_free(pWdaParams->wdaMsgParam);
+      if(pWdaParams->wdaWdiApiMsgParam)
+         vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+      vos_mem_free(pWdaParams);
+
+      VOS_ASSERT(0);
+      return;
+   }
+
+   pIbssPeerInfoParams =
+       (WDI_IbssPeerInfoParams *)peerInfoRspParams->wdiPeerInfoParams;
+
+   pIbssGetPeerInfoRsp =
+                  vos_mem_malloc(sizeof(tSirIbssGetPeerInfoRspParams));
+
+   if(NULL == pIbssGetPeerInfoRsp)
+   {
+      if(pWdaParams->wdaMsgParam)
+         vos_mem_free(pWdaParams->wdaMsgParam);
+      if(pWdaParams->wdaWdiApiMsgParam)
+         vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+      vos_mem_free(pWdaParams);
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: Memory allocation failed for pIbssGetPeerInfoRsp",
+                 __func__);
+      VOS_ASSERT(0);
+      return;
+
+   }
+
+   pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext ;
+
+
+   if (peerInfoRspParams->wdiNumPeers > 32)
+   {
+      pr_info("%s] Number of peers is more than 32, returning\n", __func__);
+      /* free the mem and return */
+      vos_mem_free((v_VOID_t *) pIbssGetPeerInfoRsp);
+         if(pWdaParams->wdaMsgParam)
+            vos_mem_free(pWdaParams->wdaMsgParam);
+         if(pWdaParams->wdaWdiApiMsgParam)
+            vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+         vos_mem_free(pWdaParams);
+
+      return;
+   }
+
+   /* Message Header */
+   pIbssGetPeerInfoRsp->mesgType = eWNI_SME_IBSS_PEER_INFO_RSP;
+   pIbssGetPeerInfoRsp->mesgLen = sizeof(tSirIbssGetPeerInfoRspParams);
+   pIbssGetPeerInfoRsp->ibssPeerInfoRspParams.status = peerInfoRspParams->wdiStatus;
+   pIbssGetPeerInfoRsp->ibssPeerInfoRspParams.numPeers = peerInfoRspParams->wdiNumPeers;
+
+   for (wdaCnt = 0; wdaCnt < peerInfoRspParams->wdiNumPeers; wdaCnt++)
+   {
+      WDI_IbssPeerInfoParams *pWdiTmp = &pIbssPeerInfoParams[wdaCnt];
+      tSirIbssPeerInfoParams *pSmeTmp =
+          &pIbssGetPeerInfoRsp->ibssPeerInfoRspParams.peerInfoParams[wdaCnt];
+
+      pSmeTmp->staIdx = pWdiTmp->wdiStaIdx;
+      pSmeTmp->mcsIndex = pWdiTmp->wdiMcsIndex;
+      pSmeTmp->rssi = pWdiTmp->wdiRssi;
+      pSmeTmp->txRate = pWdiTmp->wdiTxRate;
+      pSmeTmp->txRateFlags = pWdiTmp->wdiTxRateFlags;
+   }
+
+   /* VOS message wrapper */
+   vosMsg.type = eWNI_SME_IBSS_PEER_INFO_RSP;
+   vosMsg.bodyptr = (void *)pIbssGetPeerInfoRsp;
+   vosMsg.bodyval = 0;
+
+   if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg))
+   {
+      /* free the mem and return */
+      vos_mem_free((v_VOID_t *) pIbssGetPeerInfoRsp);
+   }
+
+   if(NULL != pWdaParams)
+   {
+      if(pWdaParams->wdaMsgParam)
+         vos_mem_free(pWdaParams->wdaMsgParam);
+      if(pWdaParams->wdaWdiApiMsgParam)
+         vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+      vos_mem_free(pWdaParams);
+   }
+
+   return;
+}
+
+static VOS_STATUS
+WDA_ProcessIbssPeerInfoReq(tWDA_CbContext *pWDA,
+                      tSirIbssGetPeerInfoReqParams *ibssPeerInfoReqParams)
+{
+   WDI_Status status;
+   WDI_IbssPeerInfoReqType *wdiPeerInfoReq;
+   tWDA_ReqParams *pWdaParams;
+
+   wdiPeerInfoReq = (WDI_IbssPeerInfoReqType *)
+                    vos_mem_malloc(sizeof(WDI_IbssPeerInfoReqType));
+   if (NULL == wdiPeerInfoReq)
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "%s: VOS MEM Alloc Failure", __func__);
+      VOS_ASSERT(0);
+      vos_mem_free(ibssPeerInfoReqParams);
+      return VOS_STATUS_E_NOMEM;
+   }
+
+   pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams));
+   if (NULL == pWdaParams)
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                         "%s: VOS MEM Alloc Failure", __func__);
+      VOS_ASSERT(0);
+      vos_mem_free(wdiPeerInfoReq);
+      vos_mem_free(ibssPeerInfoReqParams);
+      return VOS_STATUS_E_NOMEM;
+   }
+
+   pWdaParams->wdaWdiApiMsgParam = (v_PVOID_t *)wdiPeerInfoReq;
+   /* Store param pointer as passed in by caller */
+   pWdaParams->wdaMsgParam = ibssPeerInfoReqParams;
+   pWdaParams->pWdaContext = pWDA;
+
+   wdiPeerInfoReq->wdiAllPeerInfoReqd =
+                 ibssPeerInfoReqParams->allPeerInfoReqd;
+   wdiPeerInfoReq->wdiStaIdx =
+                 ibssPeerInfoReqParams->staIdx;
+
+   status = WDI_IbssPeerInfoReq(wdiPeerInfoReq,
+               (WDI_IbssPeerInfoReqCb)WDA_GetIbssPeerInfoRspCallback,
+               (void *)pWdaParams);
+   if (IS_WDI_STATUS_FAILURE(status))
+   {
+      vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+      vos_mem_free(pWdaParams->wdaMsgParam);
+      vos_mem_free(pWdaParams) ;
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "IBSS Peer Info Request failed");
+   }
+   return CONVERT_WDI2VOS_STATUS(status) ;
+
+}
+
+/*
+ * FUNCTION: WDA_ProcessTXFailMonitorInd
+ * Forward TX Fail Monitor to WDI
+ */
+static VOS_STATUS WDA_ProcessTXFailMonitorInd(
+                                        tWDA_CbContext *pWDA,
+                                        tAniTXFailMonitorInd *txFailMonitorInd)
+{
+   WDI_Status status;
+   WDI_TXFailMonitorInd *wdiTXFailMonitorInd =
+         (WDI_TXFailMonitorInd *)vos_mem_malloc(sizeof(WDI_TXFailMonitorInd));
+
+   VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+             "<------ %s " ,__func__);
+
+   if (NULL == wdiTXFailMonitorInd)
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "%s: VOS MEM Alloc Failure", __func__);
+      VOS_ASSERT(0);
+      vos_mem_free(txFailMonitorInd);
+      return VOS_STATUS_E_NOMEM;
+   }
+
+   wdiTXFailMonitorInd->tx_fail_count = txFailMonitorInd->tx_fail_count;
+
+   wdiTXFailMonitorInd->wdiReqStatusCB = WDA_WdiIndicationCallback;
+   wdiTXFailMonitorInd->pUserData = pWDA;
+
+   status = WDI_TXFailMonitorStartStopInd(wdiTXFailMonitorInd);
+
+   if (WDI_STATUS_PENDING == status)
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "TX Fail Monitor Indication Pending");
+   }
+   else if (WDI_STATUS_SUCCESS_SYNC == status)
+   {
+     if (0 == txFailMonitorInd->tx_fail_count)
+       pWDA->txFailIndCallback = NULL;
+     else
+       pWDA->txFailIndCallback = txFailMonitorInd->txFailIndCallback;
+   }
+   else
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                 "TX Fail Monitor Indication Failed");
+   }
+
+   vos_mem_free(wdiTXFailMonitorInd);
+   vos_mem_free(txFailMonitorInd);
+
+   return CONVERT_WDI2VOS_STATUS(status) ;
+}
+#endif /* WLAN_FEATURE_RMC */
+
 /*
  * FUNCTION: WDA_ProcessSetSpoofMacAddrReq
  *
@@ -15292,6 +15740,34 @@
             (tSirDelPeriodicTxPtrn *)pMsg->bodyptr);
          break;
       }
+      case WDA_RATE_UPDATE_IND:
+      {
+          WDA_ProcessRateUpdateInd(pWDA, (tSirRateUpdateInd *)pMsg->bodyptr);
+          break;
+      }
+#ifdef WLAN_FEATURE_RMC
+      case WDA_RMC_RULER_REQ:
+      {
+          WDA_ProcessRMCRulerReq(pWDA, (tSirRmcRulerReq *)pMsg->bodyptr);
+          break;
+      }
+      case WDA_RMC_UPDATE_IND:
+      {
+          WDA_ProcessRMCUpdateInd(pWDA, (tSirRmcUpdateInd *)pMsg->bodyptr);
+          break;
+      }
+      case WDA_GET_IBSS_PEER_INFO_REQ:
+      {
+          WDA_ProcessIbssPeerInfoReq(pWDA,
+                            (tSirIbssGetPeerInfoReqParams *)pMsg->bodyptr);
+          break;
+      }
+      case WDA_TX_FAIL_MONITOR_IND:
+      {
+         WDA_ProcessTXFailMonitorInd(pWDA, (tAniTXFailMonitorInd *)pMsg->bodyptr);
+         break;
+      }
+#endif /* WLAN_FEATURE_RMC */
 
 #ifdef FEATURE_WLAN_BATCH_SCAN
       case WDA_SET_BATCH_SCAN_REQ:
@@ -15300,11 +15776,6 @@
             (tSirSetBatchScanReq *)pMsg->bodyptr);
           break;
       }
-      case WDA_RATE_UPDATE_IND:
-      {
-          WDA_ProcessRateUpdateInd(pWDA, (tSirRateUpdateInd *)pMsg->bodyptr);
-          break;
-      }
       case WDA_TRIGGER_BATCH_SCAN_RESULT_IND:
       {
           WDA_ProcessTriggerBatchScanResultInd(pWDA,
@@ -15894,6 +16365,18 @@
          }
          break;
       }
+#ifdef WLAN_FEATURE_RMC
+      case WDI_TX_FAIL_IND:
+      {
+         if (pWDA->txFailIndCallback)
+         {
+            pWDA->txFailIndCallback(
+                     wdiLowLevelInd->wdiIndicationData.wdiTXFailInd.macAddr,
+                     wdiLowLevelInd->wdiIndicationData.wdiTXFailInd.seqNo);
+         }
+	 break;
+      }
+#endif /* WLAN_FEATURE_RMC */
   
 #ifdef FEATURE_WLAN_LPHB
       case WDI_LPHB_IND:
@@ -15973,6 +16456,48 @@
          break;
       }
 
+#ifdef WLAN_FEATURE_RMC
+      case WDI_RMC_RULER_PICK_NEW :
+      {
+         tSirRmcUpdateInd   *pRmcUpdateInd =
+            (tSirRmcUpdateInd *)vos_mem_malloc(sizeof(tSirRmcUpdateInd));
+
+         VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                              "Received WDI_RMC_UPDATE_IND from WDI");
+         if (NULL == pRmcUpdateInd)
+         {
+            VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                  "Memory allocation failure, "
+                  "WDI_RMC_UPDATE_IND not forwarded");
+            break;
+         }
+
+         pRmcUpdateInd->indication =
+           wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.indication;
+         pRmcUpdateInd->role =
+           wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.role;
+
+         /* Copy the mcast transmitter which should be us */
+         vos_mem_copy(pRmcUpdateInd->mcastTransmitter,
+              wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd. \
+              mcastTransmitter,
+              sizeof(tSirMacAddr));
+         /* Copy the mcast group address */
+         vos_mem_copy(pRmcUpdateInd->mcastGroup,
+              wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.mcastGroup,
+              sizeof(tSirMacAddr));
+         vos_mem_copy(pRmcUpdateInd->mcastRuler,
+              wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.mcastRuler,
+              sizeof(tSirMacAddr));
+         vos_mem_copy(pRmcUpdateInd->ruler,
+              wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.ruler,
+              sizeof(pRmcUpdateInd->ruler));
+
+         WDA_SendMsg(pWDA, WDA_RMC_UPDATE_IND, (void *)pRmcUpdateInd, 0) ;
+         break;
+      }
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
      case  WDI_BATCH_SCAN_RESULT_IND:
      {
diff --git a/CORE/WDA/src/wlan_qct_wda_ds.c b/CORE/WDA/src/wlan_qct_wda_ds.c
index 6a7a71c..2e303fb 100644
--- a/CORE/WDA/src/wlan_qct_wda_ds.c
+++ b/CORE/WDA/src/wlan_qct_wda_ds.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -444,6 +444,10 @@
   WDI_DS_TxMetaInfoType* pTxMetaInfo = NULL;
   v_SIZE_t               usMacAddrSize;
   wpt_FrameCtrl          *pFrameControl;
+#ifdef WLAN_FEATURE_RMC
+  WLANTL_CbType*         pTLCb;
+  WLANTL_RMC_SESSION*    pRMCSession;
+#endif
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
 
   /*------------------------------------------------------------------------
@@ -457,6 +461,20 @@
     return VOS_STATUS_E_FAULT;
   }
 
+#ifdef WLAN_FEATURE_RMC
+/*----------------------------------------------------------------
+    Extract TL control block
+   --------------------------------------------------------------*/
+  pTLCb = VOS_GET_TL_CB(pvosGCtx);
+  if ( NULL == pTLCb )
+  {
+    TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+      "WLAN TL %s: pTLCb is NULL", __func__));
+
+    return VOS_STATUS_E_FAILURE;
+  }
+#endif
+
   /*------------------------------------------------------------------------
     Extract TX Meta Info pointer from PAL packet
    ------------------------------------------------------------------------*/
@@ -531,6 +549,42 @@
   // ADDR2
   vos_copy_macaddr( (v_MACADDR_t*)pTxMetaInfo->addr2MACAddress, pAddr2 );
 
+#ifdef WLAN_FEATURE_RMC
+  if (pTLCb->rmcDataPathEnabled)
+  {
+    /*look up for mcast transmitter MAC address in TL's active rmc list*/
+    if (((WDA_TLI_DATA_FRAME_TYPE >> 4) == pTxMetaInfo->frmType) &&
+        (vos_is_macaddr_group(pvDestMacAddr)))
+    {
+        pRMCSession =
+           WLANTL_RmcLookUpRmcSession(pTLCb->rmcSession,
+           (v_MACADDR_t*)pTxMetaInfo->addr2MACAddress);
+
+        if (pRMCSession)
+        {
+            if (0xFF == pvDestMacAddr->bytes[0])
+            {
+               pTxMetaInfo->txFlags |= (HAL_USE_BD_RATE_1_MASK);
+            }
+            else
+            {
+                pTxMetaInfo->txFlags |= (HAL_RMC_REQUESTED_MASK);
+
+                VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+                    "RMC active for " MAC_ADDRESS_STR " RMC session",
+                    MAC_ADDR_ARRAY(pRMCSession->rmcAddr.bytes));
+            }
+        }
+        else
+        {
+            VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+               "RMC disabled for " MAC_ADDRESS_STR " RMC session",
+               MAC_ADDR_ARRAY(pTxMetaInfo->addr2MACAddress));
+        }
+    }
+  }
+#endif /*WLAN_FEATURE_RMC*/
+
   /* Dump TX meta infro for debugging */
   VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,
              "WLAN TL: Dump TX meta info: "
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 3b4797b..bba85c3 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -395,12 +395,20 @@
 
   /* Periodic Tx Pattern FW Indication */
   WDI_PERIODIC_TX_PTRN_FW_IND,
+#ifdef WLAN_FEATURE_RMC
+  /* RMC_Ruler_Pick_New Indication */
+  WDI_RMC_RULER_PICK_NEW,
+#endif
 
 #ifdef FEATURE_WLAN_BATCH_SCAN
   /*Batch scan result indication from FW*/
   WDI_BATCH_SCAN_RESULT_IND,
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+  WDI_TX_FAIL_IND,
+#endif
+
 #ifdef FEATURE_WLAN_CH_AVOID
   WDI_CH_AVOID_IND,
 #endif /* FEATURE_WLAN_CH_AVOID */
@@ -537,6 +545,22 @@
   wpt_uint8       macAddr[WDI_MAC_ADDR_LEN];
 }WDI_DHCPInd;
 
+#ifdef WLAN_FEATURE_RMC
+typedef struct
+{
+   /*Request status callback offered by UMAC - it is called if the current
+    req has returned PENDING as status; it delivers the status of sending
+    the message over the BUS */
+  WDI_ReqStatusCb   wdiReqStatusCB;
+
+  /*The user data passed in by UMAC, it will be sent back when the above
+    function pointer will be called */
+  void*             pUserData;
+
+  wpt_uint8         tx_fail_count;
+}WDI_TXFailMonitorInd;
+#endif /* WLAN_FEATURE_RMC */
+
 /*---------------------------------------------------------------------------
 
   WDI_MacSSid
@@ -739,6 +763,13 @@
 
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+typedef struct
+{
+  wpt_uint8 seqNo;
+  wpt_uint8 macAddr[WDI_MAC_ADDR_LEN];
+} WDI_TXFailIndType;
+#endif /* WLAN_FEATURE_RMC */
 
 typedef struct
 {
@@ -770,6 +801,112 @@
    wpt_macAddr staMacAddr;
 }WDI_IbssPeerInactivityIndType;
 
+#ifdef WLAN_FEATURE_RMC
+/*---------------------------------------------------------------------------
+ WDI_RmcRulerReqParams
+-----------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_uint8       cmd;
+
+    /* MAC address of MCAST Transmitter (source) */
+    wpt_macAddr mcastTransmitter;
+
+    /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */
+    wpt_macAddr mcastGroup;
+
+    /* List of candidates for cmd = WLAN_HAL_SUGGEST_RULER*/
+    wpt_macAddr blacklist[8]; /* HAL_NUM_MAX_RULERS */
+
+    /*
+     * Request status callback offered by UMAC - it is called if the current
+     * req has returned PENDING as status; it delivers the status of sending
+     * the message over the BUS
+     */
+    WDI_ReqStatusCb    wdiReqStatusCB;
+
+} WDI_RmcRulerReqParams;
+
+/*---------------------------------------------------------------------------
+ WDI_RmcUpdateIndParams
+-----------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_uint8       indication;  /* tRmcUpdateIndType */
+
+    wpt_uint8       role;
+
+    /* MAC address of MCAST Transmitter (source) */
+    wpt_macAddr mcastTransmitter;
+
+    /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */
+    wpt_macAddr mcastGroup;
+
+    wpt_macAddr mcastRuler;
+
+    wpt_macAddr ruler[16];
+
+    /*
+     * Request status callback offered by UMAC - it is called if the current
+     * req has returned PENDING as status; it delivers the status of sending
+     * the message over the BUS
+     */
+    WDI_ReqStatusCb   wdiReqStatusCB;
+
+    /*
+     * The user data passed in by UMAC, it will be sent back when the above
+     * function pointer will be called
+     */
+    void   *pUserData;
+
+} WDI_RmcUpdateIndParams;
+
+typedef enum
+{
+  eWDI_SUGGEST_RULER_CMD = 0,
+  eWDI_BECOME_RULER_CMD  = 1,
+} eWDI_RulerRspCmdType;
+
+/*---------------------------------------------------------------------------
+ WDI_RmcRspParamsType
+-----------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_uint8       status;  /* success or failure */
+
+    /*  Command Type */
+    eWDI_RulerRspCmdType cmd;
+
+    /* MAC address of MCAST Transmitter (source) */
+    wpt_macAddr mcastTransmitter;
+
+    /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */
+    wpt_macAddr mcastGroup;
+
+    wpt_macAddr ruler[8];
+} WDI_RmcRspParamsType;
+
+/*---------------------------------------------------------------------------
+ WDI_RmcPickNewRuler
+-----------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_uint8       indication;  /* pick_new */
+
+    wpt_uint8       role;
+
+    /* MAC address of MCAST Transmitter (source) */
+    wpt_macAddr mcastTransmitter;
+
+    /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */
+    wpt_macAddr mcastGroup;
+
+    wpt_macAddr mcastRuler;
+
+    wpt_macAddr ruler[16];
+} WDI_RmcPickNewRuler;
+#endif
+
 /*---------------------------------------------------------------------------
  WDI_TxRateFlags
 -----------------------------------------------------------------------------*/
@@ -806,10 +943,10 @@
      * 0 implies MCAST RA, positive value implies fixed rate,
      * -1 implies ignore this param
      */
-    wpt_int32 reliableMcastDataRate; //unit Mbpsx10
+    wpt_int32 rmcDataRate; //unit Mbpsx10
 
     /* TX flag to differentiate between HT20, HT40 etc */
-    WDI_TxRateFlags reliableMcastDataRateTxFlag;
+    WDI_TxRateFlags rmcDataRateTxFlag;
 
     /*
      * MCAST(or BCAST) fixed data rate in 2.4 GHz, unit Mbpsx10,
@@ -981,11 +1118,19 @@
     /* Periodic TX Pattern FW Indication */
     WDI_PeriodicTxPtrnFwIndType  wdiPeriodicTxPtrnFwInd;
 
+#ifdef WLAN_FEATURE_RMC
+    WDI_RmcPickNewRuler        wdiRmcPickNewRulerInd;
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
     /*batch scan result indication from FW*/
     void *pBatchScanResult;
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+    WDI_TXFailIndType            wdiTXFailInd;
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_CH_AVOID
     WDI_ChAvoidIndType          wdiChAvoidInd;
 #endif /* FEATURE_WLAN_CH_AVOID */
@@ -5907,6 +6052,58 @@
   void*             pUserData;
 } WDI_DelPeriodicTxPtrnParamsType;
 
+#ifdef WLAN_FEATURE_RMC
+/*---------------------------------------------------------------------------
+  WDI_IbssPeerInfoParams
+---------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_uint8  wdiStaIdx;       //StaIdx
+    wpt_uint32 wdiTxRate;       //Tx Rate
+    wpt_uint32 wdiMcsIndex;     //MCS Index
+    wpt_uint32 wdiTxRateFlags;  //TxRate Flags
+    wpt_int8   wdiRssi;         //RSSI
+}WDI_IbssPeerInfoParams;
+
+/*---------------------------------------------------------------------------
+  WDI_IbssPeerInfoRspParams
+---------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_uint32        wdiStatus;                  // Return status
+    wpt_uint8         wdiNumPeers;                // Number of peers
+    WDI_IbssPeerInfoParams *wdiPeerInfoParams; // Peer Info parameters
+}WDI_IbssPeerInfoRspParams;
+
+/*---------------------------------------------------------------------------
+  WDI_GetIbssPeerInfoRspType
+---------------------------------------------------------------------------*/
+typedef struct
+{
+    WDI_IbssPeerInfoRspParams  wdiPeerInfoRspParams;
+
+    /*Request status callback offered by UMAC - it is called if the current
+      req has returned PENDING as status; it delivers the status of sending
+      the message over the BUS */
+    WDI_ReqStatusCb   wdiReqStatusCB;
+
+    /*The user data passed in by UMAC, it will be sent back when the above
+      function pointer will be called */
+    void*             pUserData;
+}WDI_GetIbssPeerInfoRspType;
+
+/*---------------------------------------------------------------------------
+  WDI_IbssPeerInfoReqType
+---------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_boolean wdiAllPeerInfoReqd; // Request info for all peers
+    wpt_uint8   wdiStaIdx;          // STA Index
+    wpt_uint8   wdiBssIdx;          // BSS Index
+}WDI_IbssPeerInfoReqType;
+
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef WLAN_FEATURE_EXTSCAN
 
 #define WDI_WLAN_EXTSCAN_MAX_CHANNELS                 16
@@ -8136,6 +8333,15 @@
                                 void*        pUserData);
 #endif /* FEATURE_WLAN_LPHB */
 
+#ifdef WLAN_FEATURE_RMC
+typedef void  (*WDI_RmcRulerRspCb)(WDI_RmcRspParamsType *wdiRmcResponse,
+                                    void*        pUserData);
+
+typedef void  (*WDI_IbssPeerInfoReqCb)(WDI_IbssPeerInfoRspParams *pInfoRspParams,
+                                            void*        pUserData);
+
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
 /*---------------------------------------------------------------------------
    WDI_SetBatchScanCb
@@ -11209,6 +11415,22 @@
   WDI_DHCPInd *wdiDHCPInd
 );
 
+#ifdef WLAN_FEATURE_RMC
+WDI_Status
+WDI_RmcRulerReq
+(
+  WDI_RmcRulerReqParams  *wdiRmcRulerReqParams,
+  WDI_RmcRulerRspCb rmcRulerRspCb,
+  void *usrData
+);
+
+WDI_Status
+WDI_RmcUpdateInd
+(
+  WDI_RmcUpdateIndParams  *wdiRmcUpdateIndParams
+);
+#endif /* WLAN_FEATURE_RMC */
+
 /**
  @brief WDI_RateUpdateInd will be called when the upper MAC
         requests the device to update rates.
@@ -11229,6 +11451,26 @@
   WDI_RateUpdateIndParams  *wdiRateUpdateIndParams
 );
 
+#ifdef WLAN_FEATURE_RMC
+/**
+ @brief WDI_TXFailMonitorStartStopInd
+       Forward TX monitor start/stop event
+
+ @param
+
+     WDI_TXFailMonitorInd
+
+ @see
+ @return Result of the function call
+*/
+
+WDI_Status
+WDI_TXFailMonitorStartStopInd
+(
+  WDI_TXFailMonitorInd *wdiTXFailMonitorInd
+);
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef WLAN_FEATURE_GTK_OFFLOAD
 /**
  @brief WDI_GTKOffloadReq will be called when the upper MAC 
@@ -11744,6 +11986,26 @@
 
 #endif /*FEATURE_WLAN_BATCH_SCAN*/
 
+#ifdef WLAN_FEATURE_RMC
+/**
+ @brief Process peer info req
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+
+WDI_Status
+WDI_IbssPeerInfoReq
+(
+   WDI_IbssPeerInfoReqType*   wdiPeerInfoReqParams,
+   WDI_IbssPeerInfoReqCb      wdiIbssPeerInfoReqCb,
+  void*                         pUserData
+);
+#endif /* WLAN_FEATURE_RMC */
+
 /**
  @brief wdi_HT40OBSSScanInd
     This API is called to start OBSS scan
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h b/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
index 85fd4c2..77bd475 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -120,9 +120,9 @@
 #define HAL_TDLS_PEER_STA_MASK              0x80 //bit 7 set for TDLS peer station
 #endif
 
-/* Bit 8 is used to route reliable multicast data frames from QID 1.
-   This dynamically changes ACK_POLICY = TRUE for multicast frames */
-#define WDI_RELIABLE_MCAST_REQUESTED_MASK 0x100
+#ifdef WLAN_FEATURE_RMC
+#define WDI_RMC_REQUESTED_MASK 0x100
+#endif
 
 #define WDI_USE_BD_RATE_1_MASK            0x1000
 #define WDI_USE_BD_RATE_2_MASK            0x2000
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index 3bcf995..03e0335 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -96,8 +96,10 @@
  
 #ifdef WLAN_SOFTAP_VSTA_FEATURE
 #define WDI_MAX_SUPPORTED_STAS   41
+#define WDI_MAX_IBSS_PEER_SUPPORED_STAS 32
 #else
 #define WDI_MAX_SUPPORTED_STAS   12
+#define WDI_MAX_IBSS_PEER_SUPPORED_STAS 11
 #endif
 #define WDI_MAX_SUPPORTED_BSS     5 
 
@@ -435,112 +437,121 @@
 
   /* WLAN FW LPHB config request */
   WDI_LPHB_CFG_REQ                              = 85,
+#ifdef WLAN_FEATURE_RMC
+  WDI_RMC_RULER_REQ                            = 86,
+  WDI_HAL_IBSS_PEER_INFO_REQ                    = 87,
+#endif /* WLAN_FEATURE_RMC */
 
   /* WLAN FW set batch scan request */
-  WDI_SET_BATCH_SCAN_REQ                        = 86,
+  WDI_SET_BATCH_SCAN_REQ                        = 88,
 
   /*WLAN DAL Set Max Tx Power Per band Request*/
-  WDI_SET_MAX_TX_POWER_PER_BAND_REQ             = 87,
+  WDI_SET_MAX_TX_POWER_PER_BAND_REQ             = 89,
 
-  WDI_UPDATE_CHAN_REQ                           = 88,
+  WDI_UPDATE_CHAN_REQ                           = 90,
 
-  WDI_GET_BCN_MISS_RATE_REQ                     = 89,
+  WDI_GET_BCN_MISS_RATE_REQ                     = 91,
 
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
-  WDI_LL_STATS_SET_REQ                          = 90,
-  WDI_LL_STATS_GET_REQ                          = 91,
-  WDI_LL_STATS_CLEAR_REQ                        = 92,
+  WDI_LL_STATS_SET_REQ                          = 92,
+  WDI_LL_STATS_GET_REQ                          = 93,
+  WDI_LL_STATS_CLEAR_REQ                        = 94,
 #endif
 
 #ifdef WLAN_FEATURE_EXTSCAN
-  WDI_EXTSCAN_START_REQ                          = 93,
-  WDI_EXTSCAN_STOP_REQ                           = 94,
-  WDI_EXTSCAN_GET_CACHED_RESULTS_REQ             = 95,
-  WDI_EXTSCAN_GET_CAPABILITIES_REQ               = 96,
-  WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ              = 97,
-  WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ            = 98,
-  WDI_EXTSCAN_SET_SSID_HOTLIST_REQ               = 99,
-  WDI_EXTSCAN_RESET_SSID_HOTLIST_REQ             = 100,
+  WDI_EXTSCAN_START_REQ                          = 95,
+  WDI_EXTSCAN_STOP_REQ                           = 96,
+  WDI_EXTSCAN_GET_CACHED_RESULTS_REQ             = 97,
+  WDI_EXTSCAN_GET_CAPABILITIES_REQ               = 98,
+  WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ              = 99,
+  WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ            = 100,
+  WDI_EXTSCAN_SET_SSID_HOTLIST_REQ               = 101,
+  WDI_EXTSCAN_RESET_SSID_HOTLIST_REQ             = 102,
 #endif
 
-  WDI_SPOOF_MAC_ADDR_REQ                         = 101,
+  WDI_SPOOF_MAC_ADDR_REQ                         = 103,
 
-  WDI_GET_FW_STATS_REQ                           = 102,
+  WDI_GET_FW_STATS_REQ                           = 104,
 
   /* Send command to encrypt the given message */
-  WDI_ENCRYPT_MSG_REQ                            = 103,
+  WDI_ENCRYPT_MSG_REQ                            = 105,
 
-  WDI_FW_LOGGING_INIT_REQ                        = 104,
-  WDI_GET_FRAME_LOG_REQ                          = 105,
-
+  WDI_FW_LOGGING_INIT_REQ                        = 106,
+  WDI_GET_FRAME_LOG_REQ                          = 107,
   /* NAN Request */
-  WDI_NAN_REQUEST                                = 106,
+  WDI_NAN_REQUEST                                = 108,
 
-  WDI_MON_START_REQ                              = 107,
-  WDI_MON_STOP_REQ                               = 108,
-  WDI_FATAL_EVENT_LOGGING_REQ                    = 109,
-  WDI_FWR_MEM_DUMP_REQ                           = 110,
-  WDI_START_RSSI_MONITOR_REQ                     = 111,
-  WDI_STOP_RSSI_MONITOR_REQ                      = 112,
-
-  WDI_WIFI_CONFIG_SET_REQ                        = 113,
+  WDI_MON_START_REQ                              = 109,
+  WDI_MON_STOP_REQ                               = 110,
+  WDI_FATAL_EVENT_LOGGING_REQ                    = 111,
+  WDI_FWR_MEM_DUMP_REQ                           = 112,
+  WDI_START_RSSI_MONITOR_REQ                     = 113,
+  WDI_STOP_RSSI_MONITOR_REQ                      = 114,
+  WDI_WIFI_CONFIG_SET_REQ                        = 115,
 
   WDI_MAX_REQ,
 
   /*Send a suspend Indication down to HAL*/
-  WDI_HOST_SUSPEND_IND          = WDI_MAX_REQ ,
+  WDI_HOST_SUSPEND_IND =  WDI_MAX_REQ,
 
   /* Send a traffic stats indication to HAL */
-  WDI_TRAFFIC_STATS_IND,
+  WDI_TRAFFIC_STATS_IND = WDI_MAX_REQ + 1,
 
   /* DHCP Start Indication */
-  WDI_DHCP_START_IND,
+  WDI_DHCP_START_IND = WDI_MAX_REQ + 2,
 
   /* DHCP Stop Indication */
-  WDI_DHCP_STOP_IND,
+  WDI_DHCP_STOP_IND = WDI_MAX_REQ + 3,
 
   /* Drop/Receive unencrypted frames indication to HAL */
-  WDI_EXCLUDE_UNENCRYPTED_IND,
+  WDI_EXCLUDE_UNENCRYPTED_IND = WDI_MAX_REQ + 4,
 
   /* Send an add periodic Tx pattern indication to HAL */
-  WDI_ADD_PERIODIC_TX_PATTERN_IND,
+  WDI_ADD_PERIODIC_TX_PATTERN_IND = WDI_MAX_REQ + 5,
 
   /* Send a delete periodic Tx pattern indicationto HAL */
-  WDI_DEL_PERIODIC_TX_PATTERN_IND,
+  WDI_DEL_PERIODIC_TX_PATTERN_IND = WDI_MAX_REQ + 6,
 
-  /*Send stop batch scan indication to FW*/
-  WDI_STOP_BATCH_SCAN_IND,
-
-  /*Send stop batch scan indication to FW*/
-  WDI_TRIGGER_BATCH_SCAN_RESULT_IND,
-
+#ifdef WLAN_FEATURE_RMC
+  /* Send RMC Update Indication */
+  WDI_RMC_UPDATE_IND = WDI_MAX_REQ + 7,
+#endif
   /* Send Rate Update Indication */
-  WDI_RATE_UPDATE_IND,
+  WDI_RATE_UPDATE_IND = WDI_MAX_REQ + 8,
 
-  WDI_START_HT40_OBSS_SCAN_IND,
-  WDI_STOP_HT40_OBSS_SCAN_IND,
+  /*Send stop batch scan indication to FW*/
+  WDI_STOP_BATCH_SCAN_IND = WDI_MAX_REQ + 9,
+
+  /*Send stop batch scan indication to FW*/
+  WDI_TRIGGER_BATCH_SCAN_RESULT_IND = WDI_MAX_REQ + 10,
+
+#ifdef WLAN_FEATURE_RMC
+  /* TX Monitor start/stop indication */
+  WDI_TX_FAIL_MONITOR_IND = WDI_MAX_REQ + 11,
+#endif
+  WDI_START_HT40_OBSS_SCAN_IND = WDI_MAX_REQ +12,
+  WDI_STOP_HT40_OBSS_SCAN_IND = WDI_MAX_REQ +13,
 
   /* csa channel switch req*/
-  WDI_CH_SWITCH_REQ_V1,
-  WDI_TDLS_CHAN_SWITCH_REQ,
-  WDI_SET_RTS_CTS_HTVHT_IND,
-  WDI_FW_LOGGING_DXE_DONE_IND,
-  WDI_SEND_FREQ_RANGE_CONTROL_IND,
+  WDI_CH_SWITCH_REQ_V1 = WDI_MAX_REQ + 14,
+  WDI_TDLS_CHAN_SWITCH_REQ = WDI_MAX_REQ + 15,
+  WDI_SET_RTS_CTS_HTVHT_IND = WDI_MAX_REQ + 16,
+  WDI_FW_LOGGING_DXE_DONE_IND = WDI_MAX_REQ + 17,
+  WDI_SEND_FREQ_RANGE_CONTROL_IND = WDI_MAX_REQ + 18,
 
 #ifdef WLAN_FEATURE_EXTSCAN
-  WDI_HIGH_PRIORITY_DATA_INFO_IND,
+  WDI_HIGH_PRIORITY_DATA_INFO_IND = WDI_MAX_REQ + 19,
 #endif
 
 #ifdef FEATURE_OEM_DATA_SUPPORT
-  WDI_START_OEM_DATA_REQ_IND_NEW,
+  WDI_START_OEM_DATA_REQ_IND_NEW = WDI_MAX_REQ + 20,
 #endif
 
   /*Keep adding the indications to the max request
     such that we keep them separate */
-  WDI_ANTENNA_DIVERSITY_SELECTION_REQ,
-  WDI_MODIFY_ROAM_PARAMS_IND,
-  WDI_MAX_UMAC_IND
-
+  WDI_ANTENNA_DIVERSITY_SELECTION_REQ = WDI_MAX_REQ + 21,
+  WDI_MODIFY_ROAM_PARAMS_IND = WDI_MAX_REQ + 22,
+  WDI_MAX_UMAC_IND = WDI_MAX_REQ + 23,
 }WDI_RequestEnumType;
 
 /*--------------------------------------------------------------------------- 
@@ -798,50 +809,55 @@
   /* WLAN FW LPHB Config response */
   WDI_LPHB_CFG_RESP                             = 84,
 
-  WDI_SET_BATCH_SCAN_RESP                       = 85,
+#ifdef WLAN_FEATURE_RMC
+  WDI_RMC_RULER_RESP                           = 85,
+  WDI_HAL_IBSS_PEER_INFO_RSP                    = 86,
+#endif /* WLAN_FEATURE_RMC */
 
-  WDI_SET_MAX_TX_POWER_PER_BAND_RSP             = 86,
+  WDI_SET_BATCH_SCAN_RESP                        = 87,
 
-  WDI_UPDATE_CHAN_RESP                          = 87,
+  WDI_SET_MAX_TX_POWER_PER_BAND_RSP             = 88,
+
+  WDI_UPDATE_CHAN_RESP                          = 89,
   /* channel switch resp v1*/
-  WDI_CH_SWITCH_RESP_V1                         = 88,
+  WDI_CH_SWITCH_RESP_V1                         = 90,
 
-  WDI_GET_BCN_MISS_RATE_RSP                     = 89,
+  WDI_GET_BCN_MISS_RATE_RSP                     = 91,
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
-  WDI_LL_STATS_SET_RSP                          = 90,
-  WDI_LL_STATS_GET_RSP                          = 91,
-  WDI_LL_STATS_CLEAR_RSP                        = 92,
+  WDI_LL_STATS_SET_RSP                          = 92,
+  WDI_LL_STATS_GET_RSP                          = 93,
+  WDI_LL_STATS_CLEAR_RSP                        = 94,
 #endif
 
 #ifdef WLAN_FEATURE_EXTSCAN
-  WDI_EXTSCAN_START_RSP                          = 93,
-  WDI_EXTSCAN_STOP_RSP                           = 94,
-  WDI_EXTSCAN_GET_CACHED_RESULTS_RSP             = 95,
-  WDI_EXTSCAN_GET_CAPABILITIES_RSP               = 96,
-  WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP              = 97,
-  WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP            = 98,
-  WDI_EXTSCAN_SET_HOTLIST_SSID_RSP               = 99,
-  WDI_EXTSCAN_RESET_HOTLIST_SSID_RSP             = 100,
+  WDI_EXTSCAN_START_RSP                          = 95,
+  WDI_EXTSCAN_STOP_RSP                           = 96,
+  WDI_EXTSCAN_GET_CACHED_RESULTS_RSP             = 97,
+  WDI_EXTSCAN_GET_CAPABILITIES_RSP               = 98,
+  WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP              = 99,
+  WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP            = 100,
+  WDI_EXTSCAN_SET_HOTLIST_SSID_RSP               = 101,
+  WDI_EXTSCAN_RESET_HOTLIST_SSID_RSP             = 102,
 #endif
-  WDI_SPOOF_MAC_ADDR_RSP                         = 101,
-  WDI_GET_FW_STATS_RSP                           = 102,
+  WDI_SPOOF_MAC_ADDR_RSP                         = 103,
+  WDI_GET_FW_STATS_RSP                           = 104,
 
   /* Send command to encrypt the given message */
-  WDI_ENCRYPT_MSG_RSP                            = 103,
+  WDI_ENCRYPT_MSG_RSP                            = 105,
 
-  WDI_FW_LOGGING_INIT_RSP                        = 104,
-  WDI_GET_FRAME_LOG_RSP                          = 105,
+  WDI_FW_LOGGING_INIT_RSP                        = 106,
+  WDI_GET_FRAME_LOG_RSP                          = 107,
 
-  WDI_NAN_RESPONSE                               = 106,
+  WDI_NAN_RESPONSE                               = 108,
 
-  WDI_MON_START_RSP                              = 107,
-  WDI_MON_STOP_RSP                               = 108,
-  WDI_FATAL_EVENT_LOGGING_RSP                    = 109,
-  WDI_FWR_MEM_DUMP_RSP                           = 110,
-  WDI_START_RSSI_MONITOR_RSP                     = 111,
-  WDI_STOP_RSSI_MONITOR_RSP                      = 112,
+  WDI_MON_START_RSP                              = 109,
+  WDI_MON_STOP_RSP                               = 110,
+  WDI_FATAL_EVENT_LOGGING_RSP                    = 111,
+  WDI_FWR_MEM_DUMP_RSP                           = 112,
+  WDI_START_RSSI_MONITOR_RSP                     = 113,
+  WDI_STOP_RSSI_MONITOR_RSP                      = 114,
 
-  WDI_WIFI_CONFIG_SET_RSP                        = 113,
+  WDI_WIFI_CONFIG_SET_RSP                        = 115,
 
   /*-------------------------------------------------------------------------
     Indications
@@ -902,30 +918,38 @@
   /* Periodic Tx Pattern Indication from FW to Host */
   WDI_HAL_PERIODIC_TX_PTRN_FW_IND     = WDI_HAL_IND_MIN + 16,
 
+#ifdef WLAN_FEATURE_RMC
+  /* Update Indication from FW to Host */
+  WDI_RMC_UPDATE_IND_TO_HOST           = WDI_HAL_IND_MIN + 17,
+#endif
 
-  WDI_BATCHSCAN_RESULT_IND           =  WDI_HAL_IND_MIN + 17,
+  WDI_BATCHSCAN_RESULT_IND           =  WDI_HAL_IND_MIN + 18,
 
-  WDI_HAL_CH_AVOID_IND                 = WDI_HAL_IND_MIN + 18,
+#ifdef WLAN_FEATURE_RMC
+  WDI_HAL_TX_FAIL_IND                  = WDI_HAL_IND_MIN + 19,
+#endif
+
+  WDI_HAL_CH_AVOID_IND                 = WDI_HAL_IND_MIN + 20,
 
   /* print register values indication from FW to Host */
-  WDI_PRINT_REG_INFO_IND               = WDI_HAL_IND_MIN + 19,
+  WDI_PRINT_REG_INFO_IND               = WDI_HAL_IND_MIN + 21,
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
-  WDI_HAL_LL_STATS_RESULTS_IND         = WDI_HAL_IND_MIN + 20,
+  WDI_HAL_LL_STATS_RESULTS_IND         = WDI_HAL_IND_MIN + 22,
 #endif
 #ifdef WLAN_FEATURE_EXTSCAN
-  WDI_HAL_EXTSCAN_PROGRESS_IND       = WDI_HAL_IND_MIN + 21,
-  WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND = WDI_HAL_IND_MIN + 22,
-  WDI_HAL_EXTSCAN_RESULT_IND         = WDI_HAL_IND_MIN + 23,
-  WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND    = WDI_HAL_IND_MIN + 24,
-  WDI_HAL_EXTSCAN_SSID_HOTLIST_RESULT_IND    = WDI_HAL_IND_MIN + 25,
+  WDI_HAL_EXTSCAN_PROGRESS_IND       = WDI_HAL_IND_MIN + 23,
+  WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND = WDI_HAL_IND_MIN + 24,
+  WDI_HAL_EXTSCAN_RESULT_IND         = WDI_HAL_IND_MIN + 25,
+  WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND    = WDI_HAL_IND_MIN + 26,
+  WDI_HAL_EXTSCAN_SSID_HOTLIST_RESULT_IND    = WDI_HAL_IND_MIN + 27,
 #endif
-  WDI_TDLS_CHAN_SWITCH_REQ_RESP      = WDI_HAL_IND_MIN + 26,
-  WDI_HAL_DEL_BA_IND                 = WDI_HAL_IND_MIN + 27,
-  WDI_HAL_NAN_EVENT                  = WDI_HAL_IND_MIN + 28,
-  WDI_HAL_LOST_LINK_PARAMS_IND       = WDI_HAL_IND_MIN + 29,
-  WDI_HAL_RSSI_BREACHED_IND          = WDI_HAL_IND_MIN + 30,
-  WDI_HAL_START_OEM_DATA_RSP_IND_NEW = WDI_HAL_IND_MIN + 31,
-  WDI_ANTENNA_DIVERSITY_SELECTION_RSP = WDI_HAL_IND_MIN + 32,
+  WDI_TDLS_CHAN_SWITCH_REQ_RESP      = WDI_HAL_IND_MIN + 28,
+  WDI_HAL_DEL_BA_IND                 = WDI_HAL_IND_MIN + 29,
+  WDI_HAL_NAN_EVENT                  = WDI_HAL_IND_MIN + 30,
+  WDI_HAL_LOST_LINK_PARAMS_IND       = WDI_HAL_IND_MIN + 31,
+  WDI_HAL_RSSI_BREACHED_IND          = WDI_HAL_IND_MIN + 32,
+  WDI_HAL_START_OEM_DATA_RSP_IND_NEW = WDI_HAL_IND_MIN + 33,
+  WDI_ANTENNA_DIVERSITY_SELECTION_RSP = WDI_HAL_IND_MIN + 34,
   WDI_MAX_RESP
 }WDI_ResponseEnumType; 
 
@@ -3190,6 +3214,23 @@
  );
 
 #endif
+#ifdef WLAN_FEATURE_RMC
+/**
+ @brief Process TX Fail monitor indication
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessTXFailMonitor
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+#endif /* WLAN_FEATURE_RMC */
 /**
  @brief Process start OBSS scan request from Host
 
@@ -4636,6 +4677,24 @@
   WDI_EventInfoType*     pEventData
 );
 
+#ifdef WLAN_FEATURE_RMC
+/**
+*@brief Process Tx Fail Indication
+
+ @param  pWDICtx:         pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessTXFailInd
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+#endif /* WLAN_FEATURE_RMC */
+
 /**
 *@brief Process Noa Start Indication function (called when
         an indication of this kind is being received over the
@@ -5498,7 +5557,6 @@
 );
 #endif // FEATURE_WLAN_SCAN_PNO
 
-
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
 /**
  @brief Process Start Roam Candidate Lookup Request function
@@ -5533,7 +5591,6 @@
 );
 #endif
 
-
 #ifdef WLAN_FEATURE_PACKET_FILTERING
 /**
  @brief Process 8023 Multicast List Request function
@@ -5787,7 +5844,6 @@
   WDI_EventInfoType*     pEventData
 );
 #endif
-
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
 /**
  *  @brief WDI_wdiEdTypeEncToEdTypeEnc -
@@ -5840,6 +5896,82 @@
     WDI_EventInfoType*     pEventData
 );
 
+#ifdef WLAN_FEATURE_RMC
+WDI_Status
+WDI_ProcessRMCRulerReq
+(
+    WDI_ControlBlockType*  pWDICtx,
+    WDI_EventInfoType*     pEventData
+);
+
+WDI_Status
+WDI_ProcessRMCRulerResp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+
+WDI_Status
+WDI_ProcessRMCUpdateInd
+(
+    WDI_ControlBlockType*  pWDICtx,
+    WDI_EventInfoType*     pEventData
+);
+
+WDI_Status
+WDI_RmcUpdateInd
+(
+    WDI_RmcUpdateIndParams  *wdiRmcUpdateIndParams
+);
+
+WDI_Status
+WDI_ProcessRMCRulerResp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+
+WDI_Status
+WDI_ProcessRMCUpdateIndToHost
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+
+/**
+ @brief Process peer info req
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessIbssPeerInfoReq
+(
+    WDI_ControlBlockType*  pWDICtx,
+    WDI_EventInfoType*     pEventData
+);
+
+/**
+ @brief Process peer info resp
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessIbssPeerInfoRsp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
 /**
  @brief WDI_ProcessSetBatchScanRsp -
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 20e8f4d..9d9ebe0 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -440,6 +440,13 @@
 #else
   NULL,
 #endif /* FEATURE_WLAN_LPHB */
+#ifdef WLAN_FEATURE_RMC
+  WDI_ProcessRMCRulerReq,              /* WDI_LBP_RULER_REQ */
+  WDI_ProcessIbssPeerInfoReq,           /* WDI_HAL_IBSS_PEER_INFO_REQ */
+#else
+  NULL,
+  NULL,
+#endif /* WLAN_FEATURE_RMC */
 
 #ifdef FEATURE_WLAN_BATCH_SCAN
   WDI_ProcessSetBatchScanReq,               /* WDI_SET_BATCH_SCAN_REQ */
@@ -515,6 +522,12 @@
 #endif
   WDI_ProcessAddPeriodicTxPtrnInd,      /* WDI_ADD_PERIODIC_TX_PATTERN_IND */
   WDI_ProcessDelPeriodicTxPtrnInd,      /* WDI_DEL_PERIODIC_TX_PATTERN_IND */
+#ifdef WLAN_FEATURE_RMC
+  WDI_ProcessRMCUpdateInd,              /* WDI_RMC_UPDATE_IND */
+#else
+  NULL,
+#endif /* WLAN_FEATURE_RMC */
+  WDI_ProcessRateUpdateInd,              /* WDI_RATE_UPDATE_IND */
 #ifdef FEATURE_WLAN_BATCH_SCAN
   WDI_ProcessStopBatchScanInd,          /* WDI_STOP_BATCH_SCAN_IND */
   WDI_ProcessTriggerBatchScanResultInd, /* WDI_TRIGGER_BATCH_SCAN_RESULT_IND */
@@ -522,7 +535,11 @@
   NULL,
   NULL,
 #endif /* FEATURE_WLAN_BATCH_SCAN */
-  WDI_ProcessRateUpdateInd,              /* WDI_RATE_UPDATE_IND */
+#ifdef WLAN_FEATURE_RMC
+  WDI_ProcessTXFailMonitor,
+#else
+  NULL,
+#endif
 
   WDI_ProcessHT40OBSSScanInd,        /*WDI_START_HT40_OBSS_SCAN_IND */
   WDI_ProcessHT40OBSSStopScanInd,    /*WDI_STOP_HT40_OBSS_SCAN_IND */
@@ -732,6 +749,17 @@
 #else
     NULL,
 #endif /* FEATURE_WLAN_LPHB */
+#ifdef WLAN_FEATURE_RMC
+  WDI_ProcessRMCRulerResp,          /* WDI_RMC_RULER_RESP */
+#else
+    NULL,
+#endif /* WLAN_FEATURE_RMC */
+
+#ifdef WLAN_FEATURE_RMC
+  WDI_ProcessIbssPeerInfoRsp,       /* WDI_HAL_GET_IBSS_PEER_INFO_RSP */
+#else
+  NULL,
+#endif /* WLAN_FEATURE_RMC */
 
 #ifdef FEATURE_WLAN_BATCH_SCAN
     WDI_ProcessSetBatchScanRsp,        /* WDI_SET_BATCH_SCAN_RESP */
@@ -840,14 +868,26 @@
 
   WDI_ProcessPeriodicTxPtrnFwInd,   /* WDI_HAL_PERIODIC_TX_PTRN_FW_IND */
 
+#ifdef WLAN_FEATURE_RMC
+  WDI_ProcessRMCUpdateIndToHost,       /* WDI_RMC_UPDATE_IND_TO_HOST */
+#else
+    NULL,
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
   WDI_ProcessBatchScanResultInd,     /* WDI_BATCHSCAN_RESULT_IND */
 #else
   NULL,
 #endif
 
+#ifdef WLAN_FEATURE_RMC
+  WDI_ProcessTXFailInd,                 /*WDI_HAL_TX_FAIL_IND*/
+#else
+  NULL,
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_CH_AVOID
-    WDI_ProcessChAvoidInd,               /* WDI_LBP_UPDATE_IND_TO_HOST */
+    WDI_ProcessChAvoidInd,               /* WDI_HAL_CH_AVOID_IND */
 #else
    NULL,
 #endif /* FEATURE_WLAN_CH_AVOID */
@@ -1201,6 +1241,9 @@
     CASE_RETURN_STRING( WDI_STOP_BATCH_SCAN_IND );
     CASE_RETURN_STRING( WDI_TRIGGER_BATCH_SCAN_RESULT_IND);
 #endif
+#ifdef WLAN_FEATURE_RMC
+    CASE_RETURN_STRING( WDI_TX_FAIL_MONITOR_IND );
+#endif /* WLAN_FEATURE_RMC */
     CASE_RETURN_STRING(WDI_START_HT40_OBSS_SCAN_IND);
     CASE_RETURN_STRING(WDI_STOP_HT40_OBSS_SCAN_IND);
     CASE_RETURN_STRING(WDI_UPDATE_CHAN_REQ);
@@ -1341,6 +1384,12 @@
     CASE_RETURN_STRING( WDI_SHUTDOWN_RESP );
     CASE_RETURN_STRING( WDI_SET_POWER_PARAMS_RESP );
     CASE_RETURN_STRING( WDI_GET_ROAM_RSSI_RESP );
+#ifdef WLAN_FEATURE_RMC
+    CASE_RETURN_STRING( WDI_RMC_RULER_RESP );
+    CASE_RETURN_STRING( WDI_RMC_UPDATE_IND_TO_HOST );
+
+    CASE_RETURN_STRING( WDI_HAL_IBSS_PEER_INFO_RSP );
+#endif /* WLAN_FEATURE_RMC */
 #ifdef FEATURE_WLAN_BATCH_SCAN
     CASE_RETURN_STRING( WDI_SET_BATCH_SCAN_RESP);
 #endif
@@ -21889,6 +21938,64 @@
   return WDI_STATUS_SUCCESS;
 }/*WDI_ProcessTdlsInd*/
 #endif
+
+#ifdef WLAN_FEATURE_RMC
+/**
+*@brief Process Tx Fail Indication
+
+ @param  pWDICtx:         pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessTXFailInd
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+  WDI_LowLevelIndType  wdiInd;
+  tHalTXFailIndMsg     halTXFailIndMsg;
+  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+  /*-------------------------------------------------------------------------
+  Sanity check
+ -------------------------------------------------------------------------*/
+  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
+      ( NULL == pEventData->pEventData ))
+  {
+     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                 "%s: Invalid parameters", __func__);
+     WDI_ASSERT( 0 );
+     return WDI_STATUS_E_FAILURE;
+  }
+  /*-------------------------------------------------------------------------
+  Extract indication and send it to UMAC
+ -------------------------------------------------------------------------*/
+  wpalMemoryCopy( &halTXFailIndMsg.txFailIndParams,
+                  pEventData->pEventData,
+                  sizeof(halTXFailIndMsg.txFailIndParams) );
+
+  /*Fill in the indication parameters*/
+  wdiInd.wdiIndicationType = WDI_TX_FAIL_IND;
+
+  wdiInd.wdiIndicationData.wdiTXFailInd.seqNo
+                          = halTXFailIndMsg.txFailIndParams.seqNo;
+
+  wpalMemoryCopy(wdiInd.wdiIndicationData.wdiTXFailInd.macAddr,
+                 halTXFailIndMsg.txFailIndParams.macAddr,
+                 sizeof(wdiInd.wdiIndicationData.wdiTXFailInd.macAddr));
+
+  /*Notify UMAC*/
+  if (pWDICtx->wdiLowLevelIndCB)
+     pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
+
+  return WDI_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_RMC */
+
 /**
 *@brief Process Noa Start Indication function (called when
         an indication of this kind is being received over the
@@ -24495,6 +24602,16 @@
     return WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND;
   case WDI_DEL_PERIODIC_TX_PATTERN_IND:
     return WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND;
+#ifdef WLAN_FEATURE_RMC
+  case WDI_RMC_RULER_REQ:
+    return WLAN_HAL_RMC_RULER_REQ;
+  case WDI_RMC_UPDATE_IND:
+    return WLAN_HAL_RMC_UPDATE_IND;
+  case WDI_HAL_IBSS_PEER_INFO_REQ:
+    return WLAN_HAL_GET_IBSS_PEER_INFO_REQ;
+#endif /* WLAN_FEATURE_RMC */
+  case WDI_RATE_UPDATE_IND:
+    return WLAN_HAL_RATE_UPDATE_IND;
 
 #ifdef FEATURE_WLAN_BATCH_SCAN
   case WDI_SET_BATCH_SCAN_REQ:
@@ -24504,8 +24621,12 @@
   case WDI_TRIGGER_BATCH_SCAN_RESULT_IND:
        return WLAN_HAL_BATCHSCAN_TRIGGER_RESULT_IND;
 #endif
-  case WDI_RATE_UPDATE_IND:
-    return WLAN_HAL_RATE_UPDATE_IND;
+
+#ifdef WLAN_FEATURE_RMC
+  case WDI_TX_FAIL_MONITOR_IND:
+    return WLAN_HAL_TX_FAIL_MONITOR_IND;
+#endif
+
   case WDI_START_HT40_OBSS_SCAN_IND:
        return WLAN_HAL_START_HT40_OBSS_SCAN_IND;
   case WDI_STOP_HT40_OBSS_SCAN_IND:
@@ -24837,6 +24958,15 @@
   case WLAN_HAL_PERIODIC_TX_PTRN_FW_IND:
     return WDI_HAL_PERIODIC_TX_PTRN_FW_IND;
 
+#ifdef WLAN_FEATURE_RMC
+  case WLAN_HAL_RMC_RULER_RSP:
+    return WDI_RMC_RULER_RESP;
+  case WLAN_HAL_RMC_UPDATE_IND:
+    return WDI_RMC_UPDATE_IND_TO_HOST;
+  case WLAN_HAL_GET_IBSS_PEER_INFO_RSP:
+    return WDI_HAL_IBSS_PEER_INFO_RSP;
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_BATCH_SCAN
   case WLAN_HAL_BATCHSCAN_SET_RSP:
     return WDI_SET_BATCH_SCAN_RESP;
@@ -24844,6 +24974,11 @@
     return WDI_BATCHSCAN_RESULT_IND;
 #endif // FEATURE_WLAN_BATCH_SCAN
 
+#ifdef WLAN_FEATURE_RMC
+  case WLAN_HAL_TX_FAIL_IND:
+    return WDI_HAL_TX_FAIL_IND;
+#endif /* WLAN_FEATURE_RMC */
+
 #ifdef FEATURE_WLAN_CH_AVOID
   case WLAN_HAL_AVOID_FREQ_RANGE_IND:
     return WDI_HAL_CH_AVOID_IND;
@@ -28818,6 +28953,44 @@
    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
 }
 
+#ifdef WLAN_FEATURE_RMC
+/**
+ @brief WDI_TXFailMonitorInd
+        Host will send an event to the FW to start TX Fail Monitor
+
+ @param
+        WDI_TXFailMonitorInd
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_TXFailMonitorStartStopInd
+(
+  WDI_TXFailMonitorInd *wdiTXFailMonitorInd
+)
+{
+   WDI_EventInfoType   wdiEventData;
+
+   /*------------------------------------------------------------------------
+     Sanity Check
+   ------------------------------------------------------------------------*/
+   if ( eWLAN_PAL_FALSE == gWDIInitialized )
+   {
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+               "WDI API call before module is initialized - Fail request");
+
+      return WDI_STATUS_E_NOT_ALLOWED;
+   }
+
+   wdiEventData.wdiRequest      = WDI_TX_FAIL_MONITOR_IND;
+   wdiEventData.pEventData      = wdiTXFailMonitorInd;
+   wdiEventData.uEventDataSize  = sizeof(wdiTXFailMonitorInd);
+   wdiEventData.pCBfnc          = NULL;
+   wdiEventData.pUserData       = NULL;
+
+   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+#endif /* WLAN_FEATURE_RMC */
 
 /**
  @brief Process DHCP Start Indication message and post it to HAL
@@ -28965,6 +29138,77 @@
 
 }/*WDI_ProcessDHCPStopInd*/
 
+#ifdef WLAN_FEATURE_RMC
+/**
+ @brief Process TX Fail monitor indication
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessTXFailMonitor
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+  wpt_uint8*              pSendBuffer           = NULL;
+  wpt_uint16              usDataOffset          = 0;
+  wpt_uint16              usSendSize            = 0;
+  wpt_uint16              usLen                 = 0;
+  WDI_TXFailMonitorInd*   pwdiTxFailMonitorInd  = NULL;
+  tTXFailMonitorInfo*     pTXFailMonitorInfo;
+  WDI_Status           wdiStatus;
+  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+         "%s", __func__);
+
+  /*-------------------------------------------------------------------------
+    Sanity check
+  -------------------------------------------------------------------------*/
+
+  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+  {
+     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                 "%s: Invalid parameters", __func__);
+     WDI_ASSERT(0);
+     return WDI_STATUS_E_FAILURE;
+  }
+  pwdiTxFailMonitorInd = (WDI_TXFailMonitorInd*)pEventData->pEventData;
+  /*-----------------------------------------------------------------------
+    Get message buffer
+  -----------------------------------------------------------------------*/
+
+  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+                        WDI_TX_FAIL_MONITOR_IND,
+                        sizeof(tDHCPInfo),
+                        &pSendBuffer, &usDataOffset, &usSendSize))||
+      ( usSendSize < (usDataOffset + usLen )))
+  {
+     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+              "Unable to get send buffer in DHCP Start req %p ",
+                pEventData);
+     WDI_ASSERT(0);
+     return WDI_STATUS_E_FAILURE;
+  }
+
+  pTXFailMonitorInfo = (tTXFailMonitorInfo*)pSendBuffer+usDataOffset;
+  pTXFailMonitorInfo->tx_fail_count = pwdiTxFailMonitorInd->tx_fail_count;
+
+  pWDICtx->pReqStatusUserData = pwdiTxFailMonitorInd->pUserData;
+  pWDICtx->wdiReqStatusCB = pwdiTxFailMonitorInd->wdiReqStatusCB;
+ /*-------------------------------------------------------------------------
+    Send TX Fail Monitor start/stop indication to HAL
+  -------------------------------------------------------------------------*/
+  wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
+
+  return  (wdiStatus != WDI_STATUS_SUCCESS)?wdiStatus:WDI_STATUS_SUCCESS_SYNC;
+}/*WDI_ProcessTXFailMonitor*/
+#endif /* WLAN_FEATURE_RMC */
 
 #ifdef WLAN_FEATURE_GTK_OFFLOAD
 /**
@@ -30628,6 +30872,7 @@
 
 } /*WDI_ProcessIbssPeerInactivityInd*/
 
+
 /**
 *@brief WDI_RateUpdateInd will be called when the upper MAC
         requests the device to set rates.
@@ -30738,8 +30983,8 @@
     /* Copy the tx flags */
     pRateUpdateInd->halRateUpdateParams.ucastDataRateTxFlag =
                              pwdiRateUpdateInd->ucastDataRateTxFlag;
-    pRateUpdateInd->halRateUpdateParams.reliableMcastDataRateTxFlag =
-                             pwdiRateUpdateInd->reliableMcastDataRateTxFlag;
+    pRateUpdateInd->halRateUpdateParams.rmcDataRateTxFlag =
+                             pwdiRateUpdateInd->rmcDataRateTxFlag;
     pRateUpdateInd->halRateUpdateParams.mcastDataRate24GHzTxFlag =
                              pwdiRateUpdateInd->mcastDataRate24GHzTxFlag;
     pRateUpdateInd->halRateUpdateParams.mcastDataRate5GHzTxFlag =
@@ -30748,8 +30993,8 @@
     /* Copy the tx rates */
     pRateUpdateInd->halRateUpdateParams.ucastDataRate =
                              pwdiRateUpdateInd->ucastDataRate;
-    pRateUpdateInd->halRateUpdateParams.reliableMcastDataRate =
-                             pwdiRateUpdateInd->reliableMcastDataRate;
+    pRateUpdateInd->halRateUpdateParams.rmcDataRate =
+                             pwdiRateUpdateInd->rmcDataRate;
     pRateUpdateInd->halRateUpdateParams.mcastDataRate24GHz =
                              pwdiRateUpdateInd->mcastDataRate24GHz;
     pRateUpdateInd->halRateUpdateParams.mcastDataRate5GHz =
@@ -30768,7 +31013,604 @@
 
 } /* WDI_ProcessRateUpdateInd */
 
+#ifdef WLAN_FEATURE_RMC
+WDI_Status
+WDI_ProcessRMCRulerResp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+  tHalRmcRulerRspMsg halRmcRulerRspMsg;
+  WDI_RmcRulerRspCb wdiRmcRulerRspCb;
+  WDI_RmcRspParamsType wdiRmcRsp;
+
+  /* Sanity check */
+  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
+      ( NULL == pEventData->pEventData ))
+  {
+     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                 "%s: Invalid parameters", __func__);
+     WDI_ASSERT( 0 );
+     return WDI_STATUS_E_FAILURE;
+  }
+
+  wdiRmcRulerRspCb = (WDI_RmcRulerRspCb)pWDICtx->pfncRspCB;
+
+  /* Extract indication and send it to UMAC */
+  wpalMemoryCopy( &halRmcRulerRspMsg.rulerRspParams,
+                  pEventData->pEventData,
+                  sizeof(halRmcRulerRspMsg.rulerRspParams) );
+
+  wdiRmcRsp.status = halRmcRulerRspMsg.rulerRspParams.status;
+  wpalMemoryCopy(wdiRmcRsp.mcastTransmitter,
+                      &halRmcRulerRspMsg.rulerRspParams.mcastTransmitter,
+                      sizeof(wdiRmcRsp.mcastTransmitter));
+  wpalMemoryCopy(wdiRmcRsp.mcastGroup,
+                      &halRmcRulerRspMsg.rulerRspParams.mcastGroup,
+                      sizeof(wdiRmcRsp.mcastGroup));
+
+  switch (halRmcRulerRspMsg.rulerRspParams.cmd)
+  {
+    default:
+      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                 "%s: Invalid command %d", __func__,
+                  halRmcRulerRspMsg.rulerRspParams.cmd);
+      return WDI_STATUS_E_FAILURE;
+
+    case WLAN_HAL_SUGGEST_RULER:
+    {
+      /* Fill in the indication parameters */
+      wdiRmcRsp.cmd = eWDI_SUGGEST_RULER_CMD;
+      wpalMemoryCopy(wdiRmcRsp.ruler,
+                      &halRmcRulerRspMsg.rulerRspParams.ruler,
+                      sizeof(halRmcRulerRspMsg.rulerRspParams.ruler));
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+               "%s Suggest_Ruler", __func__);
+      break;
+    }
+
+    case WLAN_HAL_BECOME_RULER:
+    {
+      /* Fill in the indication parameters */
+      wdiRmcRsp.cmd = eWDI_BECOME_RULER_CMD;
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+               "%s Become_Ruler", __func__);
+      break;
+    }
+  }
+
+  /* Notify UMAC */
+  wdiRmcRulerRspCb(&wdiRmcRsp, pWDICtx->pRspCBUserData);
+
+  return WDI_STATUS_SUCCESS;
+}
+
+WDI_Status
+WDI_ProcessRMCUpdateIndToHost
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+  WDI_LowLevelIndType wdiInd;
+  tHalRmcUpdateInd halRmcUpdateInd;
+
+  /* Sanity check */
+  if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
+      ( NULL == pEventData->pEventData ))
+  {
+     WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                 "%s: Invalid parameters", __func__);
+     WDI_ASSERT( 0 );
+     return WDI_STATUS_E_FAILURE;
+  }
+
+  /* Extract indication and send it to UMAC */
+  wpalMemoryCopy( &halRmcUpdateInd.rulerIndParams,
+                  pEventData->pEventData,
+                  sizeof(halRmcUpdateInd.rulerIndParams) );
+
+  switch (halRmcUpdateInd.rulerIndParams.indication)
+  {
+    default:
+      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                 "%s: Invalid command %d", __func__,
+                  halRmcUpdateInd.rulerIndParams.indication);
+      return WDI_STATUS_E_FAILURE;
+
+    case WLAN_HAL_RULER_PICK_NEW:
+    {
+      /* Fill in the indication parameters */
+      wdiInd.wdiIndicationType = WDI_RMC_RULER_PICK_NEW;
+      wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.indication
+                        = halRmcUpdateInd.rulerIndParams.indication;
+      wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.role
+                        = halRmcUpdateInd.rulerIndParams.role;
+      wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd. \
+                      mcastTransmitter,
+                      &halRmcUpdateInd.rulerIndParams.mcastTransmitter,
+                      sizeof(tSirMacAddr) );
+      wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.mcastGroup,
+                      &halRmcUpdateInd.rulerIndParams.mcastGroup,
+                      sizeof(tSirMacAddr) );
+      wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.mcastRuler,
+                      &halRmcUpdateInd.rulerIndParams.mcastRuler,
+                      sizeof(tSirMacAddr) );
+      wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.ruler,
+                      &halRmcUpdateInd.rulerIndParams.ruler,
+                      sizeof(tSirMacAddr) * HAL_NUM_MAX_RULERS );
+      break;
+    }
+  }
+
+
+  /* Notify UMAC */
+  pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData );
+
+  return WDI_STATUS_SUCCESS;
+}
+
+WDI_Status
+WDI_RmcRulerReq
+(
+    WDI_RmcRulerReqParams  *wdiRmcRulerReqParams,
+    WDI_RmcRulerRspCb wdiRmcRulerRspCb,
+    void *usrData
+)
+{
+   WDI_EventInfoType      wdiEventData;
+   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+   /*------------------------------------------------------------------------
+     Sanity Check
+   ------------------------------------------------------------------------*/
+    if ( eWLAN_PAL_FALSE == gWDIInitialized )
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "WDI API call before module is initialized - Fail request");
+
+        return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    /*------------------------------------------------------------------------
+      Fill in Event data and post to the Main FSM
+     ------------------------------------------------------------------------*/
+    wdiEventData.wdiRequest      = WDI_RMC_RULER_REQ;
+    wdiEventData.pEventData      = wdiRmcRulerReqParams;
+    wdiEventData.uEventDataSize  = sizeof(WDI_RmcRulerReqParams);
+    wdiEventData.pCBfnc          = wdiRmcRulerRspCb;
+    wdiEventData.pUserData       = usrData;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+
+} /* WDI_RmcRulerReq */
+
+WDI_Status
+WDI_RmcUpdateInd
+(
+    WDI_RmcUpdateIndParams  *wdiRmcUpdateIndParams
+)
+{
+   WDI_EventInfoType      wdiEventData;
+   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+   /*------------------------------------------------------------------------
+    Sanity Check
+   ------------------------------------------------------------------------*/
+   if ( eWLAN_PAL_FALSE == gWDIInitialized )
+   {
+       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+                  "WDI API call before module is initialized - Fail request");
+
+       return WDI_STATUS_E_NOT_ALLOWED;
+   }
+
+   /*------------------------------------------------------------------------
+     Fill in Event data and post to the Main FSM
+   ------------------------------------------------------------------------*/
+    wdiEventData.wdiRequest      = WDI_RMC_UPDATE_IND;
+    wdiEventData.pEventData      = wdiRmcUpdateIndParams;
+    wdiEventData.uEventDataSize  = sizeof(WDI_RmcUpdateIndParams);
+    wdiEventData.pCBfnc          = NULL;
+    wdiEventData.pUserData       = NULL;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+
+}/* WDI_RmcUpdateInd */
+
+WDI_Status
+WDI_ProcessRMCRulerReq
+(
+    WDI_ControlBlockType*  pWDICtx,
+    WDI_EventInfoType*     pEventData
+)
+{
+    WDI_Status              wdiStatus;
+    wpt_uint8*              pSendBuffer        = NULL;
+    wpt_uint16              usDataOffset       = 0;
+    wpt_uint16              usSendSize         = 0;
+    WDI_RmcRulerReqParams *pwdiRulerReq      = NULL;
+    tHalRmcRulerReqMsg    *pRulerReq;
+
+    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+           "%s", __func__);
+
+    /*-------------------------------------------------------------------------
+      Sanity check
+    -------------------------------------------------------------------------*/
+    if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+    {
+       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                   "%s: Invalid parameters", __func__);
+       WDI_ASSERT(0);
+       return WDI_STATUS_E_FAILURE;
+    }
+    pwdiRulerReq = (WDI_RmcRulerReqParams *)pEventData->pEventData;
+    /*-----------------------------------------------------------------------
+      Get message buffer
+    -----------------------------------------------------------------------*/
+
+    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+                          WDI_RMC_RULER_REQ,
+                          sizeof(tHalRmcRulerReqParams),
+                          &pSendBuffer, &usDataOffset, &usSendSize))||
+                          ( usSendSize < (usDataOffset +
+                                 sizeof(tHalRmcRulerReqParams) )))
+    {
+       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+                "Unable to get send buffer in Ruler Req %p ",
+                  pEventData);
+       WDI_ASSERT(0);
+       return WDI_STATUS_E_FAILURE;
+    }
+
+    pRulerReq = (tHalRmcRulerReqMsg *)pSendBuffer;
+    pRulerReq->rulerReqParams.cmd = pwdiRulerReq->cmd;
+    wpalMemoryCopy(pRulerReq->rulerReqParams.mcastTransmitter,
+                     pwdiRulerReq->mcastTransmitter, WDI_MAC_ADDR_LEN);
+    wpalMemoryCopy(pRulerReq->rulerReqParams.mcastGroup,
+                     pwdiRulerReq->mcastGroup, WDI_MAC_ADDR_LEN);
+    wpalMemoryCopy(pRulerReq->rulerReqParams.blacklist,
+                     pwdiRulerReq->blacklist,
+                     WDI_MAC_ADDR_LEN * HAL_NUM_MAX_RULERS);
+
+    pWDICtx->pReqStatusUserData = pEventData->pUserData;
+    pWDICtx->pfncRspCB = pEventData->pCBfnc;
+
+    wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer,
+                            usSendSize, pWDICtx->pfncRspCB,
+                            pWDICtx->pReqStatusUserData,
+                            WDI_RMC_RULER_RESP);
+    return wdiStatus;
+
+} /* WDI_ProcessRMCRulerReq */
+
+/**
+ @brief Process Update Indication and post it to HAL
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessRMCUpdateInd
+(
+    WDI_ControlBlockType*  pWDICtx,
+    WDI_EventInfoType*     pEventData
+)
+{
+    wpt_uint8*              pSendBuffer        = NULL;
+    wpt_uint16              usDataOffset       = 0;
+    wpt_uint16              usSendSize         = 0;
+    WDI_RmcUpdateIndParams *pwdiUpdateInd      = NULL;
+    tHalRmcUpdateInd       *pUpdateInd;
+    WDI_Status              wdiStatus;
+
+    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+           "%s", __func__);
+
+    /*-------------------------------------------------------------------------
+      Sanity check
+    -------------------------------------------------------------------------*/
+    if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+    {
+       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                   "%s: Invalid parameters", __func__);
+       WDI_ASSERT(0);
+       return WDI_STATUS_E_FAILURE;
+    }
+    pwdiUpdateInd = (WDI_RmcUpdateIndParams *)pEventData->pEventData;
+    /*-----------------------------------------------------------------------
+      Get message buffer
+    -----------------------------------------------------------------------*/
+
+    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+                          WDI_RMC_UPDATE_IND,
+                          sizeof(tHalRmcUpdateIndParams),
+                          &pSendBuffer, &usDataOffset, &usSendSize))||
+                          ( usSendSize < (usDataOffset +
+                                 sizeof(tHalRmcUpdateIndParams) )))
+    {
+       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+                "Unable to get send buffer in RMC Update Indication %p ",
+                  pEventData);
+       WDI_ASSERT(0);
+       return WDI_STATUS_E_FAILURE;
+    }
+
+    pUpdateInd = (tHalRmcUpdateInd *)pSendBuffer;
+
+    pUpdateInd->rulerIndParams.indication = pwdiUpdateInd->indication;
+    pUpdateInd->rulerIndParams.role = pwdiUpdateInd->role;
+
+    wpalMemoryCopy(pUpdateInd->rulerIndParams.mcastTransmitter,
+                     pwdiUpdateInd->mcastTransmitter, WDI_MAC_ADDR_LEN);
+    wpalMemoryCopy(pUpdateInd->rulerIndParams.mcastGroup,
+                     pwdiUpdateInd->mcastGroup, WDI_MAC_ADDR_LEN);
+    wpalMemoryCopy(pUpdateInd->rulerIndParams.mcastRuler,
+                     pwdiUpdateInd->mcastRuler, WDI_MAC_ADDR_LEN);
+    /* Zero out parameters not needed for this command */
+    wpalMemoryZero(pUpdateInd->rulerIndParams.ruler,
+                     WDI_MAC_ADDR_LEN * HAL_NUM_MAX_RULERS);
+
+
+    /*-------------------------------------------------------------------------
+     Send Update Indication to HAL
+    -------------------------------------------------------------------------*/
+    pWDICtx->wdiReqStatusCB     = pwdiUpdateInd->wdiReqStatusCB;
+    pWDICtx->pReqStatusUserData = pwdiUpdateInd->pUserData;
+
+    wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize);
+
+    return (wdiStatus != WDI_STATUS_SUCCESS) ?
+                 wdiStatus : WDI_STATUS_SUCCESS_SYNC;
+
+} /* WDI_ProcessRMCUpdateInd */
+
+/**
+ @brief Process peer info req
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_IbssPeerInfoReq
+(
+   WDI_IbssPeerInfoReqType*   wdiPeerInfoReqParams,
+   WDI_IbssPeerInfoReqCb      wdiIbssPeerInfoReqCb,
+   void*                      pUserData
+)
+{
+
+   WDI_EventInfoType  wdiEventData;
+
+   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+   /*------------------------------------------------------------------------
+     Sanity Check
+   ------------------------------------------------------------------------*/
+    if ( eWLAN_PAL_FALSE == gWDIInitialized )
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "WDI API call before module is initialized - Fail request");
+
+        return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    /*------------------------------------------------------------------------
+      Fill in Event data and post to the Main FSM
+     ------------------------------------------------------------------------*/
+    wdiEventData.wdiRequest      = WDI_HAL_IBSS_PEER_INFO_REQ;
+    wdiEventData.pEventData      = wdiPeerInfoReqParams;
+    wdiEventData.uEventDataSize  = sizeof(WDI_IbssPeerInfoReqType);
+    wdiEventData.pCBfnc          = wdiIbssPeerInfoReqCb;
+    wdiEventData.pUserData       = pUserData;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+
+/**
+ @brief Process peer info req
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessIbssPeerInfoReq
+(
+    WDI_ControlBlockType*  pWDICtx,
+    WDI_EventInfoType*     pEventData
+)
+{
+    WDI_Status              wdiStatus;
+    wpt_uint8*              pSendBuffer        = NULL;
+    wpt_uint16              usDataOffset       = 0;
+    wpt_uint16              usSendSize         = 0;
+    WDI_IbssPeerInfoReqType *pwdiInfoReq        = NULL;
+    tHalIbssPeerInfoReq     *pPeerInfoReq;
+    WDI_StaStruct*   pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
+
+    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+           "%s", __func__);
+
+    /*-------------------------------------------------------------------------
+      Sanity check
+    -------------------------------------------------------------------------*/
+    if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+    {
+       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                   "%s: Invalid parameters", __func__);
+       WDI_ASSERT(0);
+       return WDI_STATUS_E_FAILURE;
+    }
+    pwdiInfoReq = (WDI_IbssPeerInfoReqType *)pEventData->pEventData;
+    /*-----------------------------------------------------------------------
+      Get message buffer
+    -----------------------------------------------------------------------*/
+
+    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+                          WDI_HAL_IBSS_PEER_INFO_REQ,
+                          sizeof(tHalIbssPeerInfoReqParams),
+                          &pSendBuffer, &usDataOffset, &usSendSize))||
+                          ( usSendSize < (usDataOffset +
+                                 sizeof(tHalIbssPeerInfoReqParams) )))
+    {
+       WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+                "Unable to get send buffer in IBSS Peer Info Req %p ",
+                  pEventData);
+       WDI_ASSERT(0);
+       return WDI_STATUS_E_FAILURE;
+    }
+
+    pPeerInfoReq = (tHalIbssPeerInfoReq *)pSendBuffer;
+    if (VOS_FALSE == pwdiInfoReq->wdiAllPeerInfoReqd)
+    {
+       if (pSTATable[pwdiInfoReq->wdiStaIdx].valid)
+       {
+          pPeerInfoReq->ibssPeerInfoReqParams.bssIdx =
+                        pSTATable[pwdiInfoReq->wdiStaIdx].bssIdx;
+       }
+       else
+       {
+          WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+                   "Unable to find BSSIDX for STAIDX %d ",
+                    pwdiInfoReq->wdiStaIdx);
+          return WDI_STATUS_E_FAILURE;
+       }
+    }
+    else
+      pPeerInfoReq->ibssPeerInfoReqParams.bssIdx = 0;
+
+    pPeerInfoReq->ibssPeerInfoReqParams.staIdx = pwdiInfoReq->wdiStaIdx;
+    pPeerInfoReq->ibssPeerInfoReqParams.allPeerInfoReqd = pwdiInfoReq->wdiAllPeerInfoReqd;
+
+    pWDICtx->pReqStatusUserData = pEventData->pUserData;
+    pWDICtx->pfncRspCB = pEventData->pCBfnc;
+
+    /*-------------------------------------------------------------------------
+     Send IBSS Peer Info request to HAL
+    -------------------------------------------------------------------------*/
+    wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer,
+                            usSendSize, pWDICtx->pfncRspCB,
+                            pWDICtx->pReqStatusUserData,
+                            WDI_HAL_IBSS_PEER_INFO_RSP);
+    return wdiStatus;
+}
+
+/**
+ @brief Process peer info resp
+
+ @param  pWDICtx:    pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessIbssPeerInfoRsp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+   WDI_IbssPeerInfoReqCb     wdiPeerInfoCb   = NULL;
+   tHalIbssPeerParams        *pHalPeerInfoParams;
+   WDI_IbssPeerInfoRspParams wdiPeerInfoRspParams;
+   wpt_uint32                allocSize=0;
+   WDI_IbssPeerInfoParams   *pPeerInfoParams;
+   wpt_uint8                 wdiCount=0;
+
+   /*-------------------------------------------------------------------------
+     Sanity check
+   -------------------------------------------------------------------------*/
+   if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
+       ( NULL == pEventData->pEventData))
+   {
+      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                  "%s: Invalid parameters", __func__);
+      WDI_ASSERT(0);
+      return WDI_STATUS_E_FAILURE;
+   }
+
+   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+   wdiPeerInfoCb = (WDI_IbssPeerInfoReqCb)pWDICtx->pfncRspCB;
+
+   /*-------------------------------------------------------------------------
+     Extract response and send it to UMAC
+   -------------------------------------------------------------------------*/
+   pHalPeerInfoParams =
+             ((tHalIbssPeerInfoRspParams *)pEventData->pEventData)->ibssPeerParams;
+   wdiPeerInfoRspParams.wdiStatus =
+             WDI_HAL_2_WDI_STATUS(((tHalIbssPeerInfoRspParams *)pEventData->pEventData)->status);
+   wdiPeerInfoRspParams.wdiNumPeers =
+             ((tHalIbssPeerInfoRspParams *)pEventData->pEventData)->numOfPeers;
+
+   /* Size of peer info data received from DAL */
+   allocSize = (sizeof(WDI_IbssPeerInfoParams) * (wdiPeerInfoRspParams.wdiNumPeers));
+
+   pPeerInfoParams = (WDI_IbssPeerInfoParams*)wpalMemoryAllocate(allocSize);
+
+    if (NULL == pPeerInfoParams)
+    {
+        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
+            "Failed to allocate memory in ibss peer info response %p %p %p ",
+            pWDICtx, pEventData, pEventData->pEventData);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+   if (wdiPeerInfoRspParams.wdiNumPeers > WDI_MAX_IBSS_PEER_SUPPORED_STAS)
+   {
+      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                   "Number of stations %d exceed max supported stations %d ",
+                    wdiPeerInfoRspParams.wdiNumPeers,
+                    WDI_MAX_IBSS_PEER_SUPPORED_STAS);
+      vos_mem_free (pPeerInfoParams);
+      return WDI_STATUS_MEM_FAILURE;
+   }
+
+   for (wdiCount = 0; wdiCount < wdiPeerInfoRspParams.wdiNumPeers; wdiCount++)
+   {
+      tHalIbssPeerParams        *pHalTemp = &pHalPeerInfoParams[wdiCount];
+      WDI_IbssPeerInfoParams    *pWdiTemp = &pPeerInfoParams[wdiCount];
+      pWdiTemp->wdiStaIdx = pHalTemp->staIdx;
+      pWdiTemp->wdiRssi = pHalTemp->rssi;
+      pWdiTemp->wdiMcsIndex = pHalTemp->mcsIndex;
+      pWdiTemp->wdiTxRate = pHalTemp->txRate;
+      pWdiTemp->wdiTxRateFlags = pHalTemp->txRateFlags;
+   }
+
+   wdiPeerInfoRspParams.wdiPeerInfoParams = pPeerInfoParams;
+
+   /*Notify UMAC*/
+   if (wdiPeerInfoCb)
+   {
+      wdiPeerInfoCb(&wdiPeerInfoRspParams, pWDICtx->pRspCBUserData);
+   }
+
+   /* Free the allocation */
+   vos_mem_free (pPeerInfoParams);
+
+   return WDI_STATUS_SUCCESS;
+}
+#endif
 #ifdef FEATURE_WLAN_BATCH_SCAN
+
 /**
  @brief Process stop batch indication from WDA
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi_dp.c b/CORE/WDI/CP/src/wlan_qct_wdi_dp.c
index 735e691..48bf139 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi_dp.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi_dp.c
@@ -892,6 +892,13 @@
    
             WDI_STATableGetStaType(pWDICtx, ucStaId, &ucSTAType);
             if(!ucUnicastDst)
+#ifdef WLAN_FEATURE_RMC
+              /*Check for RMC enabled bit if set then
+                queue frames in QID 5 else 0*/
+              if ( ucTxFlag & WDI_RMC_REQUESTED_MASK )
+                pBd->queueId = BTQM_QID5;
+              else
+#endif
                 pBd->queueId = BTQM_QID0;
 #ifndef HAL_SELF_STA_PER_BSS
             else if( ucUnicastDst && (ucStaId == pWDICtx->ucSelfStaId))
diff --git a/Kbuild b/Kbuild
index 148b655..f373faa 100644
--- a/Kbuild
+++ b/Kbuild
@@ -199,6 +199,7 @@
 		$(MAC_SRC_DIR)/pe/lim/limProcessProbeRspFrame.o \
 		$(MAC_SRC_DIR)/pe/lim/limProcessSmeReqMessages.o \
 		$(MAC_SRC_DIR)/pe/lim/limPropExtsUtils.o \
+		$(MAC_SRC_DIR)/pe/lim/limRMC.o \
 		$(MAC_SRC_DIR)/pe/lim/limRoamingAlgo.o \
 		$(MAC_SRC_DIR)/pe/lim/limScanResultUtils.o \
 		$(MAC_SRC_DIR)/pe/lim/limSecurityUtils.o \
@@ -550,6 +551,7 @@
 		-DWLAN_FEATURE_GTK_OFFLOAD \
 		-DWLAN_WAKEUP_EVENTS \
 	        -DWLAN_KD_READY_NOTIFIER \
+		-DWLAN_FEATURE_RMC \
 		-DWLAN_NL80211_TESTMODE \
 		-DFEATURE_WLAN_BATCH_SCAN \
 		-DFEATURE_WLAN_LPHB \
diff --git a/riva/inc/wlan_hal_cfg.h b/riva/inc/wlan_hal_cfg.h
index 8e1349b..fd25f2f 100644
--- a/riva/inc/wlan_hal_cfg.h
+++ b/riva/inc/wlan_hal_cfg.h
@@ -159,7 +159,7 @@
 #define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT          101
 #define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT           102
 #define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER         103
-#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE           104
+#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE                  104
 #define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER      105
 #define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT              106
 #define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT         107
@@ -225,7 +225,7 @@
 #define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN          167
 #define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN    168
 #define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN      169
-#define QWLAN_HAL_CFG_RMCAST_FIXED_RATE                 170
+#define QWLAN_HAL_CFG_RMC_FIXED_RATE                    170
 #define QWLAN_HAL_CFG_ASD_PROBE_INTERVAL                171
 #define QWLAN_HAL_CFG_ASD_TRIGGER_THRESHOLD             172
 #define QWLAN_HAL_CFG_ASD_RTT_RSSI_HYST_THRESHOLD       173
@@ -279,7 +279,6 @@
 
 #define QWLAN_HAL_CFG_MAX_PARAMS                             221
 
-
 /* Total number of Integer CFGs. This is used while allocating the memory for TLV */
 #define QWLAN_HAL_CFG_INTEGER_PARAM                     221
 
@@ -446,6 +445,14 @@
 #define QWLAN_HAL_CFG_FIXED_RATE_STAMAX                        226
 #define QWLAN_HAL_CFG_FIXED_RATE_STADEF                        QWLAN_HAL_CFG_FIXED_RATE_AUTO
 
+/* QWLAN_HAL_CFG_RMC_FIXED_RATE
+ * Follwing rates in user configuration are mapped to TPE rates
+ * Mapping is defined in the gHalUserFixedRateCfgToTpeRateTable
+ */
+#define QWLAN_HAL_CFG_RMC_FIXED_RATE_STAMIN                 0
+#define QWLAN_HAL_CFG_RMC_FIXED_RATE_STAMAX                 226
+#define QWLAN_HAL_CFG_RMC_FIXED_RATE_STADEF                 QWLAN_HAL_CFG_FIXED_RATE_24MBPS
+
 /* QWLAN_HAL_CFG_RETRYRATE_POLICY */
 #define QWLAN_HAL_CFG_RETRYRATE_POLICY_STAMIN         0
 #define QWLAN_HAL_CFG_RETRYRATE_POLICY_STAMAX         255
@@ -882,11 +889,10 @@
 #define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_MAX    300
 #define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_DEF    300
 
-/* QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE */
-#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE_MIN    0
-#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE_MAX    1
-#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE_DEF    0
-
+/* QWLAN_HAL_CFG_ENABLE_TDLS_MODE */
+#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE_MIN    0
+#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE_MAX    1
+#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE_DEF    0
 /* QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER */
 #define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_MIN   0
 #define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_MAX   1
diff --git a/riva/inc/wlan_hal_msg.h b/riva/inc/wlan_hal_msg.h
index 07d95b9..942ffdf 100644
--- a/riva/inc/wlan_hal_msg.h
+++ b/riva/inc/wlan_hal_msg.h
@@ -1,29 +1,30 @@
 
-/* Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
-* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
-
-*
-*
-* Permission to use, copy, modify, and/or distribute this software for
-* any purpose with or without fee is hereby granted, provided that the
-* above copyright notice and this permission notice appear in all
-* copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
-* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
-* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-* PERFORMANCE OF THIS SOFTWARE.
-*/
+/*
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
 
 /*
-* This file was originally distributed by Qualcomm Atheros, Inc.
-* under proprietary terms before Copyright ownership was assigned
-* to the Linux Foundation.
-*/
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
 
 /*==========================================================================
  *
@@ -450,10 +451,9 @@
    WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ   = 217,
    WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_RSP   = 218,
 
-   /* Reliable Multicast using Leader Based Protocol */
-   WLAN_HAL_LBP_LEADER_REQ                  = 219,
-   WLAN_HAL_LBP_LEADER_RSP                  = 220,
-   WLAN_HAL_LBP_UPDATE_IND                  = 221,
+   WLAN_HAL_RMC_RULER_REQ                  = 219,
+   WLAN_HAL_RMC_RULER_RSP                  = 220,
+   WLAN_HAL_RMC_UPDATE_IND                  = 221,
 
    /* Batchscan */
    WLAN_HAL_BATCHSCAN_SET_REQ               = 222,
@@ -7657,61 +7657,152 @@
 
 
 /*---------------------------------------------------------------------------
-* WLAN_HAL_TX_FAIL_IND
-*--------------------------------------------------------------------------*/
-// Northbound indication from FW to host on weak link detection
+ * WLAN_HAL_RMC_RULER_REQ
+ *-------------------------------------------------------------------------*/
+
+#define HAL_MAX_RMC_SESSIONS 2
+
+#define HAL_NUM_MAX_RULERS 8
+
+typedef enum
+{
+   WLAN_HAL_SUGGEST_RULER,
+   WLAN_HAL_BECOME_RULER,
+   WLAN_HAL_RULER_CMD_MAX = WLAN_HAL_MAX_ENUM_SIZE
+}tRulerReqCmdType, tRulerRspCmdType;
+
 typedef PACKED_PRE struct PACKED_POST
 {
-   // Sequence number increases by 1 whenever the device driver
-   // sends a notification event. This is cleared as 0 when the
-   // JOIN IBSS commamd is issued
-    tANI_U16 seqNo;
-    tANI_U16 staId;
-    tANI_U8 macAddr[HAL_MAC_ADDR_LEN];
-} tHalTXFailIndParams, *tpHalTXFailIndParams;
+   tRulerReqCmdType cmd;
+
+   /* MAC address of MCAST Transmitter (source) */
+   tSirMacAddr mcastTransmitter;
+
+   /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */
+   tSirMacAddr mcastGroup;
+
+   /* Optional black list for cmd = WLAN_HAL_SUGGEST_RULER */
+   tSirMacAddr blacklist[HAL_NUM_MAX_RULERS];
+}  tHalRmcRulerReqParams, *tpHalRmcRulerReqParams;
 
 typedef PACKED_PRE struct PACKED_POST
 {
     tHalMsgHeader header;
-    tHalTXFailIndParams txFailIndParams;
-}  tHalTXFailIndMsg, *tpHalTXFailIndMsg;
+   tHalRmcRulerReqParams rulerReqParams;
+}  tHalRmcRulerReqMsg, *tpHalRmcRulerReqMsg;
 
 /*---------------------------------------------------------------------------
-* WLAN_HAL_TX_FAIL_MONITOR_IND
-*--------------------------------------------------------------------------*/
-// Southbound message from Host to monitor the Tx failures
+ * WLAN_HAL_RMC_RULER_RSP
+ *-------------------------------------------------------------------------*/
 typedef PACKED_PRE struct PACKED_POST
 {
-    // tx_fail_count = 0 should disable the TX Fail monitor, non-zero value should enable it.
-    tANI_U8 tx_fail_count;
-} tTXFailMonitorInfo, *tpTXFailMonitorInfo;
+   /* success or failure */
+   tANI_U32 status;
+
+   /*  Command Type */
+   tRulerRspCmdType cmd;
+
+   /* MAC address of MCAST Transmitter (source) */
+   tSirMacAddr mcastTransmitter;
+
+   /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */
+   tSirMacAddr mcastGroup;
+
+   /* List of candidates for cmd = WLAN_HAL_SUGGEST_RULER*/
+   tSirMacAddr ruler[HAL_NUM_MAX_RULERS];
+
+}  tHalRmcRulerRspParams, *tpHalRmcRulerRspParams;
 
 typedef PACKED_PRE struct PACKED_POST
 {
     tHalMsgHeader  header;
-    tTXFailMonitorInfo txFailMonitor;
-} tTXFailMonitorInd, *tpTXFailMonitorInd;
+   tHalRmcRulerRspParams rulerRspParams;
+}  tHalRmcRulerRspMsg, *tpHalRmcRulerRspMsg;
 
 /*---------------------------------------------------------------------------
-* WLAN_HAL_IP_FORWARD_TABLE_UPDATE_IND
-*--------------------------------------------------------------------------*/
-typedef PACKED_PRE struct PACKED_POST
+ * WLAN_HAL_RMC_UPDATE_IND
+ *-------------------------------------------------------------------------*/
+typedef enum
 {
-   tANI_U8 destIpv4Addr[HAL_IPV4_ADDR_LEN];
-   tANI_U8 nextHopMacAddr[HAL_MAC_ADDR_LEN];
-} tDestIpNextHopMacPair;
+   WLAN_HAL_RULER_ACCEPTED,    //Host-->FW
+   WLAN_HAL_RULER_CANCELED,    //Host-->FW
+   WLAN_HAL_RULER_PICK_NEW,    //FW-->Host
+   WLAN_HAL_RULER_IND_MAX = WLAN_HAL_MAX_ENUM_SIZE
+}tRmcUpdateIndType;
+
+typedef enum
+{
+   WLAN_HAL_RMC_RULER_ROLE,
+   WLAN_HAL_RMC_TRANSMITTER_ROLE,
+   WLAN_HAL_RMC_ROLE_MAX = WLAN_HAL_MAX_ENUM_SIZE
+}tRmcRoleType;
 
 typedef PACKED_PRE struct PACKED_POST
 {
-   tANI_U8 numEntries;
-   tDestIpNextHopMacPair destIpMacPair[1];
-} tWlanIpForwardTableUpdateIndParam;
+   tRmcUpdateIndType indication;
+
+   /* Role of the entity generating this indication */
+   tRmcRoleType role;
+
+   /* MAC address of MCAST Transmitter (source) */
+   tSirMacAddr mcastTransmitter;
+
+   /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */
+   tSirMacAddr mcastGroup;
+
+   tSirMacAddr mcastRuler;
+
+   /* Candidate list for indication = WLAN_HAL_RULER_PICK_NEW */
+   tSirMacAddr ruler[HAL_NUM_MAX_RULERS];
+}  tHalRmcUpdateIndParams, *tpHalRmcUpdateIndParams;
 
 typedef PACKED_PRE struct PACKED_POST
 {
    tHalMsgHeader header;
-   tWlanIpForwardTableUpdateIndParam ipForwardTableParams;
-} tWlanIpForwardTableUpdateInd;
+   tHalRmcUpdateIndParams rulerIndParams;
+}  tHalRmcUpdateInd, *tpHalRmcUpdateInd;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+   tANI_U8  staIdx;       // Station Idx;
+   tANI_U32 txRate;       // Legacy transmit rate, in units of 500 kbit/sec,
+                          // for the most recently transmitted frame
+   tANI_U32 mcsIndex;     // mcs index for HT20 and HT40 rates
+   tANI_U32 txRateFlags;  // to differentiate between HT20 and
+                          // HT40 rates; short and long guard interval
+   tANI_S8  rssi;         // RSSI of the last received beacon
+}tHalIbssPeerParams, *tpHalIbssPeerParams;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+   tANI_U32           status;             // success or failure
+   tANI_U8            numOfPeers;         // Number of Peers for
+                                          // which stats are being reported
+   tHalIbssPeerParams ibssPeerParams[1];  // Stats of peer in IBSS
+}tHalIbssPeerInfoRspParams, *tpHalIbssPeerInfoRspParams;
+
+// WLAN_HAL_GET_IBSS_PEER_INFO_RSP
+typedef PACKED_PRE struct PACKED_POST
+{
+   tHalMsgHeader header;
+   tHalIbssPeerInfoRspParams ibssPeerInfoRspParams;
+}tHalIbssPeerInfoRsp, *tpHalIbssPeerInfoRsp;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+   tANI_U8         bssIdx;           // Bss Index
+   tANI_BOOLEAN    allPeerInfoReqd;  // If set, all IBSS peers stats are reported
+   tANI_U8         staIdx;           // If allPeerInfoReqd is not set,
+                                     // only stats of peer with
+                                     // staIdx is reported
+}tHalIbssPeerInfoReqParams, *tpHalIbssPeerInfoReqParams;
+
+// WLAN_HAL_GET_IBSS_PEER_INFO_REQ
+typedef PACKED_PRE struct PACKED_POST
+{
+   tHalMsgHeader header;
+   tHalIbssPeerInfoReqParams ibssPeerInfoReqParams;
+}tHalIbssPeerInfoReq, *tpHalIbssPeerInfoReq;
 
 /*---------------------------------------------------------------------------
  * WLAN_HAL_ROAM_OFFLOAD_SYNCH_IND
@@ -7839,8 +7930,7 @@
 /*---------------------------------------------------------------------------
  WLAN_HAL_RATE_UPDATE_IND
  *-------------------------------------------------------------------------*/
-
-typedef PACKED_PRE struct PACKED_POST
+ typedef PACKED_PRE struct PACKED_POST
 {
     /* 0 implies UCAST RA, positive value implies fixed rate, -1 implies ignore this param */
     tANI_S32 ucastDataRate; //unit Mbpsx10
@@ -7852,18 +7942,18 @@
     tSirMacAddr bssid;
 
     /* 0 implies MCAST RA, positive value implies fixed rate, -1 implies ignore */
-    tANI_S32 reliableMcastDataRate; //unit Mbpsx10
+    tANI_S32 rmcDataRate; //unit Mbpsx10
 
     /* TX flag to differentiate between HT20, HT40 etc */
-    tTxRateInfoFlags reliableMcastDataRateTxFlag;
+    tTxRateInfoFlags rmcDataRateTxFlag;
 
-    /* Default (non-reliable) MCAST(or BCAST)  fixed rate in 2.4 GHz, 0 implies ignore */
+    /* Default (non-RMC) MCAST(or BCAST)  fixed rate in 2.4 GHz, 0 implies ignore */
     tANI_U32 mcastDataRate24GHz; //unit Mbpsx10
 
     /* TX flag to differentiate between HT20, HT40 etc */
     tTxRateInfoFlags mcastDataRate24GHzTxFlag;
 
-    /*  Default (non-reliable) MCAST(or BCAST) fixed rate in 5 GHz, 0 implies ignore */
+    /*  Default (non-RMC) MCAST(or BCAST) fixed rate in 5 GHz, 0 implies ignore */
     tANI_U32 mcastDataRate5GHz; //unit Mbpsx10
 
     /* TX flag to differentiate between HT20, HT40 etc */
@@ -7878,6 +7968,42 @@
 }  tHalRateUpdateInd, * tpHalRateUpdateInd;
 
 /*---------------------------------------------------------------------------
+* WLAN_HAL_TX_FAIL_IND
+*--------------------------------------------------------------------------*/
+// Northbound indication from FW to host on weak link detection
+typedef PACKED_PRE struct PACKED_POST
+{
+   // Sequence number increases by 1 whenever the device driver
+   // sends a notification event. This is cleared as 0 when the
+   // JOIN IBSS commamd is issued
+    tANI_U16 seqNo;
+    tANI_U16 staId;
+    tANI_U8 macAddr[HAL_MAC_ADDR_LEN];
+} tHalTXFailIndParams, *tpHalTXFailIndParams;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    tHalMsgHeader header;
+    tHalTXFailIndParams txFailIndParams;
+}  tHalTXFailIndMsg, *tpHalTXFailIndMsg;
+
+/*---------------------------------------------------------------------------
+* WLAN_HAL_TX_FAIL_MONITOR_IND
+*--------------------------------------------------------------------------*/
+// Southbound message from Host to monitor the Tx failures
+typedef PACKED_PRE struct PACKED_POST
+{
+    // tx_fail_count = 0 should disable the TX Fail monitor, non-zero value should enable it.
+    tANI_U8 tx_fail_count;
+} tTXFailMonitorInfo, *tpTXFailMonitorInfo;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    tHalMsgHeader  header;
+    tTXFailMonitorInfo txFailMonitor;
+} tTXFailMonitorInd, *tpTXFailMonitorInd;
+
+/*---------------------------------------------------------------------------
  * WLAN_HAL_AVOID_FREQ_RANGE_IND
  *-------------------------------------------------------------------------*/