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, ¶m);
+
+ 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, ¶m);
+
+ 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
*-------------------------------------------------------------------------*/