summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajesh Chauhan <rajeshc@qca.qualcomm.com>2013-09-20 17:54:42 -0700
committerMadan Mohan Koyyalamudi <mkoyyala@qca.qualcomm.com>2013-10-23 20:05:15 -0700
commitce8742cd83308803ffa8e2ead3ef576a09dc3c7c (patch)
tree13db9b14bd16429310ba6e2fdc8bbe0898753961
parent0a4b764a824e78bd52ec8be1aacc831ef08fb5ec (diff)
cld: Add support for OEM Data Request and Response
Add support for OEM Data Request and Response Change-Id: I55c995720153a37bbd208f4bd44c725f6d00c353 CRs-Fixed: 547980
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h14
-rw-r--r--CORE/HDD/inc/wlan_hdd_oemdata.h66
-rw-r--r--CORE/HDD/inc/wlan_hdd_tgt_cfg.h1
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c17
-rw-r--r--CORE/HDD/src/wlan_hdd_oemdata.c663
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c16
-rw-r--r--CORE/MAC/inc/sirApi.h8
-rw-r--r--CORE/MAC/src/pe/include/limGlobal.h8
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMessageQueue.c12
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c6
-rw-r--r--CORE/SME/inc/oemDataApi.h18
-rw-r--r--CORE/SME/inc/sme_Api.h51
-rw-r--r--CORE/SME/src/oemData/oemDataApi.c28
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c73
-rw-r--r--CORE/SVC/external/wlan_nlink_common.h3
-rw-r--r--CORE/SVC/inc/wlan_ptt_sock_svc.h6
-rw-r--r--CORE/WDA/inc/legacy/halMsgApi.h8
17 files changed, 993 insertions, 5 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index d9a5295fb945..3883033f987c 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -909,6 +909,16 @@ struct hdd_context_s
/** ptt Process ID*/
v_SINT_t ptt_pid;
+#ifdef FEATURE_OEM_DATA_SUPPORT
+#ifdef QCA_WIFI_2_0
+ /* OEM App registered or not */
+ v_BOOL_t oem_app_registered;
+
+ /* OEM App Process ID */
+ v_SINT_t oem_pid;
+#endif
+#endif
+
v_U8_t change_iface;
/** Concurrency Parameters*/
@@ -970,6 +980,10 @@ struct hdd_context_s
v_U8_t configuredMcastBcastFilter;
v_U8_t sus_res_mcastbcast_filter;
+#ifdef QCA_WIFI_2_0
+ v_U32_t target_type;
+ v_U32_t target_fw_version;
+#endif
};
diff --git a/CORE/HDD/inc/wlan_hdd_oemdata.h b/CORE/HDD/inc/wlan_hdd_oemdata.h
index d493a1ce6b20..b17d40eb59a9 100644
--- a/CORE/HDD/inc/wlan_hdd_oemdata.h
+++ b/CORE/HDD/inc/wlan_hdd_oemdata.h
@@ -44,12 +44,78 @@
#define __WLAN_HDD_OEM_DATA_H__
#ifndef OEM_DATA_REQ_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_REQ_SIZE 276
+#else
#define OEM_DATA_REQ_SIZE 134
#endif
+#endif
#ifndef OEM_DATA_RSP_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_RSP_SIZE 1720
+#else
#define OEM_DATA_RSP_SIZE 1968
#endif
+#endif
+
+#ifdef QCA_WIFI_2_0
+#define OEM_APP_SIGNATURE_LEN 16
+#define OEM_APP_SIGNATURE_STR "QUALCOMM-OEM-APP"
+
+#define OEM_TARGET_SIGNATURE_LEN 8
+#define OEM_TARGET_SIGNATURE "QUALCOMM"
+
+typedef enum
+{
+ /* Error null context */
+ OEM_ERR_NULL_CONTEXT = 1,
+
+ /* OEM App is not registered */
+ OEM_ERR_APP_NOT_REGISTERED,
+
+ /* Inavalid signature */
+ OEM_ERR_INVALID_SIGNATURE,
+
+ /* Invalid message type */
+ OEM_ERR_NULL_MESSAGE_HEADER,
+
+ /* Invalid message type */
+ OEM_ERR_INVALID_MESSAGE_TYPE,
+
+ /* Invalid length in message body */
+ OEM_ERR_INVALID_MESSAGE_LENGTH
+} eOemErrorCode;
+
+int oem_activate_service(void *pAdapter);
+
+int iw_get_oem_data_cap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+typedef struct sDriverVersion
+{
+ tANI_U8 major;
+ tANI_U8 minor;
+ tANI_U8 patch;
+ tANI_U8 build;
+} tDriverVersion;
+
+struct iw_oem_data_cap
+{
+ /* Signature of chipset vendor, e.g. QUALCOMM */
+ tANI_U8 oem_target_signature[OEM_TARGET_SIGNATURE_LEN];
+ tANI_U32 oem_target_type; /* Chip type */
+ tANI_U32 oem_fw_version; /* FW version */
+ tDriverVersion driver_version; /* CLD version */
+ tANI_U16 allowed_dwell_time_min; /* Channel dwell time - allowed min */
+ tANI_U16 allowed_dwell_time_max; /* Channel dwell time - allowed max */
+ tANI_U16 curr_dwell_time_min; /* Channel dwell time - current min */
+ tANI_U16 curr_dwell_time_max; /* Channel dwell time - current max */
+ tANI_U8 supported_bands; /* 2.4G or 5G Hz */
+ tANI_U8 num_channels; /* Num of channels IDs to follow */
+ tANI_U8 *channel_list; /* List of channel IDs */
+};
+#endif /* QCA_WIFI_2_0 */
struct iw_oem_data_req
{
diff --git a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
index da0578cf4652..1d15b2d8b76e 100644
--- a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
@@ -71,6 +71,7 @@ struct hdd_tgt_vht_cap {
#endif
struct hdd_tgt_cfg {
+ u_int32_t target_fw_version;
u_int8_t band_cap;
u_int8_t alpha2[3];
v_MACADDR_t hw_macaddr;
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 07c8c77ca8d7..75198dfa9ee6 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -2206,6 +2206,8 @@ void hdd_update_tgt_cfg(void *context, void *param)
MAC_ADDR_ARRAY(hdd_ctx->cfg_ini->intfMacAddr[0].bytes));
}
+ hdd_ctx->target_fw_version = cfg->target_fw_version;
+
hdd_update_tgt_services(hdd_ctx, &cfg->services);
hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
@@ -5556,6 +5558,9 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
#else
hif_init_adf_ctx(adf_ctx, hif_sc);
((VosContextType*)pVosContext)->pHIFContext = hif_sc;
+
+ /* store target type and target version info in hdd ctx */
+ pHddCtx->target_type = ((struct ol_softc *)hif_sc)->target_type;
#endif
((VosContextType*)(pVosContext))->adf_ctx = adf_ctx;
#endif /* QCA_WIFI_2_0 */
@@ -5987,6 +5992,18 @@ register_wiphy:
goto err_nl_srv;
}
+#ifdef FEATURE_OEM_DATA_SUPPORT
+#ifdef QCA_WIFI_2_0
+ //Initialize the OEM service
+ if (oem_activate_service(pHddCtx) != 0)
+ {
+ hddLog(VOS_TRACE_LEVEL_FATAL,
+ "%s: oem_activate_service failed", __func__);
+ goto err_nl_srv;
+ }
+#endif
+#endif
+
#ifdef PTT_SOCK_SVC_ENABLE
//Initialize the PTT service
if(ptt_sock_activate_svc(pHddCtx) != 0)
diff --git a/CORE/HDD/src/wlan_hdd_oemdata.c b/CORE/HDD/src/wlan_hdd_oemdata.c
index 3eb0e01d5af2..7ab47b9e02e9 100644
--- a/CORE/HDD/src/wlan_hdd_oemdata.c
+++ b/CORE/HDD/src/wlan_hdd_oemdata.c
@@ -45,6 +45,12 @@
#include <linux/wireless.h>
#include <wlan_hdd_includes.h>
#include <net/arp.h>
+#include "qwlan_version.h"
+
+#ifdef QCA_WIFI_2_0
+static struct hdd_context_s *pHddCtx;
+#endif /* QCA_WIFI_2_0 */
+
/*---------------------------------------------------------------------------------------------
@@ -158,9 +164,9 @@ int iw_get_oem_data_rsp(
return eHAL_STATUS_SUCCESS;
}
-/**--------------------------------------------------------------------------------------------
+/**---------------------------------------------------------------------------
- \brief iw_set_oem_data_req() -
+ \brief iw_set_oem_data_req()
This function sets the oem data req configuration. This invokes
the respective sme oem data req functionality. Function for
@@ -229,5 +235,658 @@ int iw_set_oem_data_req(
return status;
}
+#ifdef QCA_WIFI_2_0
+
+/* Forward declaration */
+static int oem_msg_callback(struct sk_buff *skb);
+
+/**---------------------------------------------------------------------------
+
+ \brief iw_get_oem_data_cap()
+
+ This function gets the capability information for OEM Data Request
+ and Response.
+
+ \param - dev - Pointer to the net device
+ - info - Pointer to the iw_oem_data_cap
+ - wrqu - Pointer to the iwreq data
+ - extra - Pointer to the data
+
+ \return - 0 for success, non zero for failure
+
+----------------------------------------------------------------------------*/
+int iw_get_oem_data_cap(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ struct iw_oem_data_cap oemDataCap;
+ struct iw_oem_data_cap *pHddOemDataCap;
+ hdd_adapter_t *pAdapter = (netdev_priv(dev));
+ hdd_context_t *pHddContext;
+ hdd_config_t *pConfig;
+
+ if (!pAdapter)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s:Invalid context, pAdapter is null", __func__);
+ return -EINVAL;
+ }
+
+ pHddContext = WLAN_HDD_GET_CTX(pAdapter);
+ if (!pHddContext)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s:Invalid context, HDD context is null", __func__);
+ return -EINVAL;
+ }
+
+ if (pHddContext->isLogpInProgress)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s:LOGP in Progress. Ignore!!!", __func__);
+ return -EBUSY;
+ }
+
+ pConfig = pHddContext->cfg_ini;
+ if (!pConfig)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s:HDD configuration is null", __func__);
+ return -ENOENT;
+ }
+
+ do
+ {
+ strlcpy(oemDataCap.oem_target_signature, OEM_TARGET_SIGNATURE,
+ OEM_TARGET_SIGNATURE_LEN);
+ oemDataCap.oem_target_type = pHddContext->target_type;
+ oemDataCap.oem_fw_version = pHddContext->target_fw_version;
+ oemDataCap.driver_version.major = QWLAN_VERSION_MAJOR;
+ oemDataCap.driver_version.minor = QWLAN_VERSION_MINOR;
+ oemDataCap.driver_version.patch = QWLAN_VERSION_PATCH;
+ oemDataCap.driver_version.build = QWLAN_VERSION_BUILD;
+ oemDataCap.allowed_dwell_time_min = pConfig->nNeighborScanMinChanTime;
+ oemDataCap.allowed_dwell_time_max = pConfig->nNeighborScanMaxChanTime;
+ oemDataCap.curr_dwell_time_min =
+ sme_getNeighborScanMinChanTime(pHddContext->hHal);
+ oemDataCap.curr_dwell_time_max =
+ sme_getNeighborScanMaxChanTime(pHddContext->hHal);
+ oemDataCap.supported_bands = pConfig->nBandCapability;
+
+ status = sme_getValidChannelList(pHddContext->hHal,
+ &oemDataCap.num_channels,
+ &oemDataCap.channel_list);
+ if (eHAL_STATUS_SUCCESS == status)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s:failed to get valid channel list", __func__);
+ return -ENOENT;
+ }
+
+ pHddOemDataCap = (struct iw_oem_data_cap *)(extra);
+ vos_mem_copy(pHddOemDataCap, &oemDataCap,
+ sizeof(struct iw_oem_data_cap));
+ } while(0);
+
+ return status;
+}
+
+/**---------------------------------------------------------------------------
+
+ \brief send_oem_reg_rsp_nlink_msg() - send oem registration response
+
+ This function sends oem message to registetred application process
+
+ \param -
+ - none
+
+ \return - none
+
+ --------------------------------------------------------------------------*/
+void send_oem_reg_rsp_nlink_msg(void)
+{
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ tAniMsgHdr *aniHdr;
+ tANI_U8 *buf;
+ tANI_U8 *numInterfaces;
+ tANI_U8 *deviceMode;
+ tANI_U8 *vdevId;
+ hdd_adapter_list_node_t *pAdapterNode = NULL;
+ hdd_adapter_list_node_t *pNext = NULL;
+ hdd_adapter_t *pAdapter = NULL;
+ VOS_STATUS status = 0;
+
+ /* OEM message is always to a specific process and cannot be a broadcast */
+ if (pHddCtx->oem_pid == 0)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid dest pid", __func__);
+ return;
+ }
+
+ skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
+ if (skb == NULL)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: alloc_skb failed", __func__);
+ return;
+ }
+
+ nlh = (struct nlmsghdr *)skb->data;
+ nlh->nlmsg_pid = 0; /* from kernel */
+ nlh->nlmsg_flags = 0;
+ nlh->nlmsg_seq = 0;
+ nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+ aniHdr = NLMSG_DATA(nlh);
+ aniHdr->type = ANI_MSG_APP_REG_RSP;
+
+ /* Fill message body:
+ * First byte will be number of interfaces, followed by
+ * two bytes for each interfaces
+ * - one byte for device mode
+ * - one byte for vdev id
+ */
+ buf = (char *) ((char *)aniHdr + sizeof(tAniMsgHdr));
+ numInterfaces = buf++;
+ *numInterfaces = 0;
+
+ /* Iterate through each of the adapters and fill device mode and vdev id */
+ status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
+ while ((VOS_STATUS_SUCCESS == status) && pAdapterNode)
+ {
+ pAdapter = pAdapterNode->pAdapter;
+ if (pAdapter)
+ {
+ deviceMode = buf++;
+ vdevId = buf++;
+ *deviceMode = pAdapter->device_mode;
+ *vdevId = pAdapter->sessionId;
+ (*numInterfaces)++;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: numInterfaces: %d, deviceMode: %d, vdevId: %d",
+ __func__, *numInterfaces, *deviceMode, *vdevId);
+ }
+ status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
+ pAdapterNode = pNext;
+ }
+
+ aniHdr->length = sizeof(tANI_U8) + (*numInterfaces) * 2 * sizeof(tANI_U8);
+ nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));
+
+ skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: sending App Reg Response length (%d) to process pid (%d)",
+ __func__, aniHdr->length, pHddCtx->oem_pid);
+
+ (void)nl_srv_ucast(skb, pHddCtx->oem_pid);
+
+ return;
+}
+
+/**---------------------------------------------------------------------------
+
+ \brief send_oem_err_rsp_nlink_msg() - send oem error response
+
+ This function sends error response to oem app
+
+ \param -
+ - app_pid - PID of oem application process
+
+ \return - none
+
+ --------------------------------------------------------------------------*/
+void send_oem_err_rsp_nlink_msg(v_SINT_t app_pid, tANI_U8 error_code)
+{
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ tAniMsgHdr *aniHdr;
+ tANI_U8 *buf;
+
+ skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
+ if (skb == NULL)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: alloc_skb failed", __func__);
+ return;
+ }
+
+ nlh = (struct nlmsghdr *)skb->data;
+ nlh->nlmsg_pid = 0; /* from kernel */
+ nlh->nlmsg_flags = 0;
+ nlh->nlmsg_seq = 0;
+ nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+ aniHdr = NLMSG_DATA(nlh);
+ aniHdr->type = ANI_MSG_OEM_ERROR;
+ aniHdr->length = sizeof(tANI_U8);
+ nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + aniHdr->length);
+
+ /* message body will contain one byte of error code */
+ buf = (char *) ((char *) aniHdr + sizeof(tAniMsgHdr));
+ *buf = error_code;
+
+ skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: sending oem error response to process pid (%d)",
+ __func__, app_pid);
+
+ (void)nl_srv_ucast(skb, app_pid);
+
+ return;
+}
+
+/**---------------------------------------------------------------------------
+
+ \brief send_oem_data_rsp_msg() - send oem data response
+
+ This function sends oem data rsp message to registetred application process
+ over the netlink socket.
+
+ \param -
+ - oemDataRsp - Pointer to OEM Data Response struct
+
+ \return - 0 for success, non zero for failure
+
+ --------------------------------------------------------------------------*/
+void send_oem_data_rsp_msg(int length, tANI_U8 *oemDataRsp)
+{
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ tAniMsgHdr *aniHdr;
+ tANI_U8 *oemData;
+
+ /* OEM message is always to a specific process and cannot be a broadcast */
+ if (pHddCtx->oem_pid == 0)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid dest pid", __func__);
+ return;
+ }
+
+ if (length > OEM_DATA_RSP_SIZE)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid length of Oem Data response", __func__);
+ return;
+ }
+
+ skb = alloc_skb(NLMSG_SPACE(sizeof(struct nlmsghdr) + OEM_DATA_RSP_SIZE),
+ GFP_KERNEL);
+ if (skb == NULL)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: alloc_skb failed", __func__);
+ return;
+ }
+
+ nlh = (struct nlmsghdr *)skb->data;
+ nlh->nlmsg_pid = 0; /* from kernel */
+ nlh->nlmsg_flags = 0;
+ nlh->nlmsg_seq = 0;
+ nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+ aniHdr = NLMSG_DATA(nlh);
+ aniHdr->type = ANI_MSG_OEM_DATA_RSP;
+
+ aniHdr->length = length;
+ nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));
+ oemData = (tANI_U8 *) ((char *)aniHdr + sizeof(tAniMsgHdr));
+ vos_mem_copy(oemData, oemDataRsp, length);
+
+ skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: sending Oem Data Response of len (%d) to process pid (%d)",
+ __func__, length, pHddCtx->oem_pid);
+
+ (void)nl_srv_ucast(skb, pHddCtx->oem_pid);
+
+ return;
+}
+
+/**---------------------------------------------------------------------------
+
+ \brief oem_process_data_req_msg() - process oem data request
+
+ This function sends oem message to SME
+
+ \param -
+ - oemDataLen - Length to OEM Data buffer
+ - oemData - Pointer to OEM Data buffer
+
+ \return - 0 for success, non zero for failure
+
+ --------------------------------------------------------------------------*/
+int oem_process_data_req_msg(int oemDataLen, char *oemData)
+{
+ hdd_adapter_t *pAdapter = NULL;
+ tOemDataReqConfig oemDataReqConfig;
+ tANI_U32 oemDataReqID = 0;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+
+ /* for now, STA interface only */
+ pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
+ if (!pAdapter)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: No adapter for STA mode", __func__);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ if (!oemData)
+ {
+ hddLog(LOGE, "in %s oemData is NULL\n", __func__);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ vos_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig));
+
+ vos_mem_copy((&oemDataReqConfig)->oemDataReq, oemData, oemDataLen);
+
+ status = sme_OemDataReq(pHddCtx->hHal,
+ pAdapter->sessionId,
+ &oemDataReqConfig,
+ &oemDataReqID,
+ &hdd_OemDataReqCallback,
+ pAdapter->dev);
+ return status;
+}
+
+/**---------------------------------------------------------------------------
+
+ \brief oem_process_channel_info_req_msg() - process oem channel_info request
+
+ This function responds with channel info to oem process
+
+ \param -
+ - numOfChannels - number of channels
+ - chanList - channel list
+
+ \return - 0 for success, non zero for failure
+
+ --------------------------------------------------------------------------*/
+int oem_process_channel_info_req_msg(int numOfChannels, char *chanList)
+{
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ tAniMsgHdr *aniHdr;
+ tSmeChannelInfo *pChanInfo;
+ tSmeChannelInfo chanInfo;
+ tANI_U8 chanId;
+ eHalStatus status = eHAL_STATUS_FAILURE;
+ int i;
+ tANI_U8 *buf;
+
+ /* OEM message is always to a specific process and cannot be a broadcast */
+ if (pHddCtx->oem_pid == 0)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid dest pid", __func__);
+ return -1;
+ }
+
+ skb = alloc_skb(NLMSG_SPACE(sizeof(struct nlmsghdr) + sizeof(tANI_U8) +
+ numOfChannels * sizeof(tSmeChannelInfo)), GFP_KERNEL);
+ if (skb == NULL)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: alloc_skb failed", __func__);
+ return -1;
+ }
+
+ nlh = (struct nlmsghdr *)skb->data;
+ nlh->nlmsg_pid = 0; /* from kernel */
+ nlh->nlmsg_flags = 0;
+ nlh->nlmsg_seq = 0;
+ nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+ aniHdr = NLMSG_DATA(nlh);
+ aniHdr->type = ANI_MSG_CHANNEL_INFO_RSP;
+
+ aniHdr->length = sizeof(tANI_U8) + numOfChannels * sizeof(tSmeChannelInfo);
+ nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));
+
+ /* First byte of message body will have num of channels */
+ buf = (char *) ((char *)aniHdr + sizeof(tAniMsgHdr));
+ *buf++ = numOfChannels;
+
+ /* Next follows channel info struct for each channel id.
+ * If chan id is wrong or SME returns failure for a channel
+ * then fill in 0 in channel info for that particular channel
+ */
+ for (i = 0 ; i < numOfChannels; i++)
+ {
+ pChanInfo = (tSmeChannelInfo *) ((char *) buf +
+ i * sizeof(tSmeChannelInfo));
+
+ chanId = chanList[i];
+ status = sme_getChannelInfo(pHddCtx->hHal, chanId, &chanInfo);
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ /* channel info is not returned, fill in zeros in channel
+ * info struct
+ */
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: sme_getChannelInfo failed for chan (%d), return info 0",
+ __func__, chanId);
+ chanInfo.chan_id = chanId;
+ chanInfo.mhz = 0;
+ chanInfo.band_center_freq1 = 0;
+ chanInfo.band_center_freq2 = 0;
+ chanInfo.info = 0;
+ chanInfo.reg_info_1 = 0;
+ chanInfo.reg_info_2 = 0;
+ }
+ vos_mem_copy(pChanInfo, &chanInfo, sizeof(tSmeChannelInfo));
+ }
+
+ skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: sending channel info resp for num channels (%d) to pid (%d)",
+ __func__, numOfChannels, pHddCtx->oem_pid);
+
+ (void)nl_srv_ucast(skb, pHddCtx->oem_pid);
+
+ return 0;
+}
+
+/**---------------------------------------------------------------------------
+
+ \brief oem_activate_service() - Activate oem message handler
+
+ This function registers a handler to receive netlink message from
+ an OEM application process.
+
+ \param -
+ - pAdapter - ponter to HDD adapter
+
+ \return - 0 for success, non zero for failure
+
+ --------------------------------------------------------------------------*/
+int oem_activate_service(void *pAdapter)
+{
+ pHddCtx = (struct hdd_context_s*) pAdapter;
+
+ /* Register the msg handler for msgs addressed to WLAN_NL_MSG_OEM */
+ nl_srv_register(WLAN_NL_MSG_OEM, oem_msg_callback);
+ return 0;
+}
+
+/*
+ * Callback function invoked by Netlink service for all netlink
+ * messages (from user space) addressed to WLAN_NL_MSG_OEM
+ */
+/**---------------------------------------------------------------------------
+
+ \brief oem_msg_callback() - callback invoked by netlink service
+
+ This function gets invoked by netlink service when a message
+ is received from user space addressed to WLAN_NL_MSG_OEM
+
+ \param -
+ - skb - skb with netlink message
+
+ \return - 0 for success, non zero for failure
+
+ --------------------------------------------------------------------------*/
+int oem_msg_callback(struct sk_buff *skb)
+{
+ struct nlmsghdr *nlh;
+ tAniMsgHdr *msg_hdr;
+ char *sign_str = NULL;
+ nlh = (struct nlmsghdr *)skb->data;
+
+ if (!nlh)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Netlink header null", __func__);
+ return -1;
+ }
+
+ if (!pHddCtx)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context null", __func__);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, OEM_ERR_NULL_CONTEXT);
+ return -1;
+ }
+
+ if (pHddCtx->isLogpInProgress)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s:LOGP in Progress. Ignore!!!", __func__);
+ return -EBUSY;
+ }
+
+ msg_hdr = NLMSG_DATA(nlh);
+
+ if (!msg_hdr)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Message header null", __func__);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, OEM_ERR_NULL_MESSAGE_HEADER);
+ return -1;
+ }
+
+ if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(tAniMsgHdr) + msg_hdr->length))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid nl msg len, nlh->nlmsg_len (%d), msg_hdr->len (%d)",
+ __func__, nlh->nlmsg_len, msg_hdr->length);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+ return -1;
+ }
+
+ switch (msg_hdr->type)
+ {
+ case ANI_MSG_APP_REG_REQ:
+ /* Registration request is only allowed for Qualcomm Application */
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Received App Req Req from App process pid(%d), len(%d)",
+ __func__, nlh->nlmsg_pid, msg_hdr->length);
+
+ sign_str = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr));
+ if ((OEM_APP_SIGNATURE_LEN == msg_hdr->length) &&
+ (0 == strncmp(sign_str, OEM_APP_SIGNATURE_STR,
+ OEM_APP_SIGNATURE_LEN)))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Received App Req Req from App process pid(%d)",
+ __func__, nlh->nlmsg_pid);
+
+ pHddCtx->oem_app_registered = TRUE;
+ pHddCtx->oem_pid = nlh->nlmsg_pid;
+ send_oem_reg_rsp_nlink_msg();
+ }
+ else
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid signature in App Reg Request from pid(%d)",
+ __func__, nlh->nlmsg_pid);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+ OEM_ERR_INVALID_SIGNATURE);
+ return -1;
+ }
+ break;
+
+ case ANI_MSG_OEM_DATA_REQ:
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Received Oem Data Request length(%d) from pid: %d",
+ __func__, msg_hdr->length, nlh->nlmsg_pid);
+
+ if ((!pHddCtx->oem_app_registered) ||
+ (nlh->nlmsg_pid != pHddCtx->oem_pid))
+ {
+ /* either oem app is not registered yet or pid is different */
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: OEM DataReq: app not regsitered(%d) or incorrect pid(%d)",
+ __func__, pHddCtx->oem_app_registered, nlh->nlmsg_pid);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+ OEM_ERR_APP_NOT_REGISTERED);
+ return -1;
+ }
+
+ if ((!msg_hdr->length) ||
+ (OEM_DATA_REQ_SIZE < msg_hdr->length))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid length (%d) in Oem Data Request",
+ __func__, msg_hdr->length);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+ OEM_ERR_INVALID_MESSAGE_LENGTH);
+ return -1;
+ }
+ oem_process_data_req_msg(msg_hdr->length,
+ (char *) ((char *)msg_hdr +
+ sizeof(tAniMsgHdr)));
+ break;
+
+ case ANI_MSG_CHANNEL_INFO_REQ:
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: Received channel info request, num channel(%d) from pid: %d",
+ __func__, msg_hdr->length, nlh->nlmsg_pid);
+
+ if ((!pHddCtx->oem_app_registered) ||
+ (nlh->nlmsg_pid != pHddCtx->oem_pid))
+ {
+ /* either oem app is not registered yet or pid is different */
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Chan InfoReq: app not regsitered(%d) or incorrect pid(%d)",
+ __func__, pHddCtx->oem_app_registered, nlh->nlmsg_pid);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+ OEM_ERR_APP_NOT_REGISTERED);
+ return -1;
+ }
+
+ /* message length contains list of channel ids */
+ if ((!msg_hdr->length) ||
+ (WNI_CFG_VALID_CHANNEL_LIST_LEN < msg_hdr->length))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid length (%d) in channel info request",
+ __func__, msg_hdr->length);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+ OEM_ERR_INVALID_MESSAGE_LENGTH);
+ return -1;
+ }
+ oem_process_channel_info_req_msg(msg_hdr->length,
+ (char *)((char*)msg_hdr + sizeof(tAniMsgHdr)));
+ break;
+
+ default:
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Received Invalid message type (%d), length (%d)",
+ __func__, msg_hdr->type, msg_hdr->length);
+ send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+ OEM_ERR_INVALID_MESSAGE_TYPE);
+ return -1;
+ }
+ return 0;
+}
+#endif /* QCA_WIFI_2_0 */
#endif
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 7116cdf680fa..57079574f6cb 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -366,6 +366,10 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
/* Private ioctl to trigger reassociation */
#define WLAN_SET_POWER_PARAMS (SIOCIWFIRSTPRIV + 29)
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/* Private ioctl to get capability information for OEM Data Request/Response */
+#define WLAN_PRIV_GET_OEM_DATA_CAP (SIOCIWFIRSTPRIV + 30)
+#endif
#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
#define WLAN_STATS_INVALID 0
@@ -2440,7 +2444,6 @@ static int iw_get_linkspeed(struct net_device *dev,
return 0;
}
-
/*
* Support for the RSSI & RSSI-APPROX private commands
* Per the WiFi framework the response must be of the form
@@ -7609,6 +7612,9 @@ static const iw_handler we_private[] = {
[WLAN_PRIV_SET_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_set_dynamic_mcbc_filter,
[WLAN_PRIV_CLEAR_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_clear_dynamic_mcbc_filter,
[WLAN_SET_POWER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_power_params_priv,
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ [WLAN_PRIV_GET_OEM_DATA_CAP - SIOCIWFIRSTPRIV] = iw_get_oem_data_cap,
+#endif
[WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
};
@@ -8322,11 +8328,17 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
0,
"setpowerparams" },
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ {
+ WLAN_PRIV_GET_OEM_DATA_CAP,
+ 0,
+ IW_PRIV_TYPE_BYTE | sizeof(struct iw_oem_data_cap),
+ "getOemDataCap" },
+#endif
{
WLAN_GET_LINK_SPEED,
IW_PRIV_TYPE_CHAR | 18,
IW_PRIV_TYPE_CHAR | 3, "getLinkSpeed" },
-
};
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 62f2635c7e04..4d0dff6abe89 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -889,11 +889,19 @@ typedef struct sSirSmeScanChanReq
#ifdef FEATURE_OEM_DATA_SUPPORT
#ifndef OEM_DATA_REQ_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_REQ_SIZE 276
+#else
#define OEM_DATA_REQ_SIZE 134
#endif
+#endif
#ifndef OEM_DATA_RSP_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_RSP_SIZE 1720
+#else
#define OEM_DATA_RSP_SIZE 1968
#endif
+#endif
typedef struct sSirOemDataReq
{
diff --git a/CORE/MAC/src/pe/include/limGlobal.h b/CORE/MAC/src/pe/include/limGlobal.h
index 33e4cef1a258..28163fa62255 100644
--- a/CORE/MAC/src/pe/include/limGlobal.h
+++ b/CORE/MAC/src/pe/include/limGlobal.h
@@ -328,11 +328,19 @@ struct tLimScanResultNode
#ifdef FEATURE_OEM_DATA_SUPPORT
#ifndef OEM_DATA_REQ_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_REQ_SIZE 276
+#else
#define OEM_DATA_REQ_SIZE 134
#endif
+#endif
#ifndef OEM_DATA_RSP_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_RSP_SIZE 1720
+#else
#define OEM_DATA_RSP_SIZE 1968
#endif
+#endif
// OEM Data related structure definitions
typedef struct sLimMlmOemDataReq
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 8c0374b294d4..0a45557ef58f 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1002,13 +1002,16 @@ void limOemDataRspHandleResumeLinkRsp(tpAniSirGlobal pMac, eHalStatus status, tA
void limProcessOemDataRsp(tpAniSirGlobal pMac, tANI_U32* body)
{
- eHalStatus status = eHAL_STATUS_SUCCESS;
tpLimMlmOemDataRsp mlmOemDataRsp = NULL;
+#ifndef QCA_WIFI_2_0
+ eHalStatus status = eHAL_STATUS_SUCCESS;
tpStartOemDataRsp oemDataRsp = NULL;
+#endif
//Process all the messages for the lim queue
SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+#ifndef QCA_WIFI_2_0
oemDataRsp = (tpStartOemDataRsp)(body);
status = palAllocateMemory(pMac->hHdd, (void**)(&mlmOemDataRsp), sizeof(tLimMlmOemDataRsp));
@@ -1026,6 +1029,13 @@ void limProcessOemDataRsp(tpAniSirGlobal pMac, tANI_U32* body)
palFreeMemory(pMac->hHdd, (void*)(oemDataRsp));
limResumeLink(pMac, limOemDataRspHandleResumeLinkRsp, (tANI_U32*)mlmOemDataRsp);
+#else
+ mlmOemDataRsp = (tpLimMlmOemDataRsp) body;
+
+ PELOG1(limLog(pMac, LOG1, FL("%s: sending oem data response msg to sme"),
+ __func__);)
+ limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)(mlmOemDataRsp));
+#endif
return;
}
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index 2fc252b6a1d9..357a94b17714 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -1931,10 +1931,16 @@ static void limProcessMlmOemDataReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;
+#ifdef QCA_WIFI_2_0
+ PELOG2(limLog(pMac, LOG2,
+ FL("%s: Calling limSendHalOemDataReq"), __func__);)
+ limSendHalOemDataReq(pMac);
+#else
MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState));
//Now request for link suspension
limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN, limSetOemDataReqMode, NULL);
+#endif
}
else
{
diff --git a/CORE/SME/inc/oemDataApi.h b/CORE/SME/inc/oemDataApi.h
index ad1f6421a82d..7da6c9bcc047 100644
--- a/CORE/SME/inc/oemDataApi.h
+++ b/CORE/SME/inc/oemDataApi.h
@@ -47,12 +47,20 @@
#include "csrLinkList.h"
#ifndef OEM_DATA_REQ_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_REQ_SIZE 276
+#else
#define OEM_DATA_REQ_SIZE 134
#endif
+#endif
#ifndef OEM_DATA_RSP_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_RSP_SIZE 1720
+#else
#define OEM_DATA_RSP_SIZE 1968
#endif
+#endif
/*************************************************************************************************************
OEM DATA REQ/RSP - DATA STRUCTURES
@@ -133,6 +141,16 @@ eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8*);
-------------------------------------------------------------------------------*/
eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal);
+#ifdef QCA_WIFI_2_0
+/* ---------------------------------------------------------------------------
+ \fn send_oem_data_rsp_msg
+ \brief This function sends oem data response message to registered
+ application
+ \return None
+ --------------------------------------------------------------------------*/
+void send_oem_data_rsp_msg(int length, tANI_U8 *oemDataRsp);
+#endif /* QCA_WIFI_2_0 */
+
#endif //_OEM_DATA_API_H__
#endif //FEATURE_OEM_DATA_SUPPORT
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 57716048c292..bfc7a63bbeeb 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -78,6 +78,26 @@
#define SME_INVALID_COUNTRY_CODE "XX"
+#define SME_2_4_GHZ_MAX_FREQ 3000
+#define SME_MODE_11A 0 /* 11a mode */
+#define SME_MODE_11G 1 /* 11b/g mode */
+
+/* channel info consists of 6 bits of channel mode */
+#define SME_SET_CHANNEL_MODE(psme_channel, val) do { \
+ (psme_channel)->info &= 0xffffffc0; \
+ (psme_channel)->info |= (val); \
+} while(0)
+
+#define SME_SET_CHANNEL_MAX_POWER(psme_channel, val) do { \
+ (psme_channel)->reg_info_1 &= 0xffff00ff; \
+ (psme_channel)->reg_info_1 |= ((val & 0xff) << 8); \
+} while(0)
+
+#define SME_SET_CHANNEL_REG_POWER(psme_channel, val) do { \
+ (psme_channel)->reg_info_1 &= 0xff00ffff; \
+ (psme_channel)->reg_info_1 |= ((val & 0xff) << 16); \
+} while(0)
+
/*--------------------------------------------------------------------------
Type declarations
------------------------------------------------------------------------*/
@@ -105,6 +125,31 @@ typedef struct _smeConfigParams
tANI_BOOLEAN fP2pListenOffload;
} tSmeConfigParams, *tpSmeConfigParams;
+#ifdef QCA_WIFI_2_0
+typedef struct _smeChannelInfo
+{
+ /* channel id */
+ tANI_U8 chan_id;
+
+ /* primary 20 MHz channel frequency in mhz */
+ tANI_U32 mhz;
+
+ /* Center frequency 1 in MHz */
+ tANI_U32 band_center_freq1;
+
+ /* Center frequency 2 in MHz - valid only for 11acvht 80plus80 mode */
+ tANI_U32 band_center_freq2;
+
+ /* channel info described below */
+ tANI_U32 info;
+
+ /* contains min power, max power, reg power and reg class id */
+ tANI_U32 reg_info_1;
+
+ /* contains antennamax */
+ tANI_U32 reg_info_2;
+} tSmeChannelInfo;
+#endif
/*-------------------------------------------------------------------------
Function declarations and documenation
@@ -2804,7 +2849,13 @@ eHalStatus sme_PsOffloadDisablePowerSave (tHalHandle hHal, tANI_U32 sessionId);
int sme_UpdateHTConfig(tHalHandle hHal, tANI_U8 sessionId, tANI_U16 htCapab,
int value);
tANI_S16 sme_GetHTConfig(tHalHandle hHal, tANI_U8 session_id, tANI_U16 ht_capab);
+eHalStatus sme_getValidChannelList(tHalHandle hHal, tANI_U8 *numChannels,
+ tANI_U8 **chanList);
#ifdef FEATURE_WLAN_PNO_OFFLOAD
eHalStatus sme_MoveCsrToScanStateForPno (tHalHandle hHal, tANI_U8 sessionId);
#endif
+#ifdef QCA_WIFI_2_0
+eHalStatus sme_getChannelInfo(tHalHandle hHal, tANI_U8 chanId,
+ tSmeChannelInfo *chanInfo);
+#endif
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/oemData/oemDataApi.c b/CORE/SME/src/oemData/oemDataApi.c
index 033a366e3e67..79a9892e39d7 100644
--- a/CORE/SME/src/oemData/oemDataApi.c
+++ b/CORE/SME/src/oemData/oemDataApi.c
@@ -308,6 +308,7 @@ eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg)
break;
}
+#ifndef QCA_WIFI_2_0
pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
if(pEntry)
{
@@ -359,7 +360,34 @@ eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg)
oemData_ReleaseOemDataReqCommand(pMac, pCommand, eHAL_STATUS_SUCCESS);
pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE;
+#else /* QCA_WIFI_2_0 */
+ /* In this case, there can be multiple OEM Data Responses for one
+ * OEM Data request, SME does not peek into data response so SME
+ * can not know which response is the last one. So SME clears active
+ * request command on receiving first response and thereafter SME
+ * passes each sunsequent response to upper user layer.
+ */
+ pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+ if (pEntry)
+ {
+ pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+ if (eSmeCommandOemDataReq == pCommand->command)
+ {
+ if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
+ &pCommand->Link, LL_ACCESS_LOCK))
+ {
+ vos_mem_set(&(pCommand->u.oemDataCmd),
+ sizeof(tOemDataCmd), 0);
+ smeReleaseCommand(pMac, pCommand);
+ }
+ }
+ }
+
+ pOemDataRsp = (tSirOemDataRsp *)pMsg;
+ smsLog(pMac, LOG1, "calling send_oem_data_rsp_msg");
+ send_oem_data_rsp_msg(sizeof(tOemDataRsp), &pOemDataRsp->oemDataRsp[0]);
+#endif /* QCA_WIFI_2_0 */
} while(0);
return status;
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 70080337949d..1a2cd283e740 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -66,6 +66,7 @@
#include "csrInternal.h"
#include "wlan_qct_wda.h"
#include "halMsgApi.h"
+#include "vos_utils.h"
#include "sapApi.h"
@@ -8932,3 +8933,75 @@ eHalStatus sme_MoveCsrToScanStateForPno (tHalHandle hHal, tANI_U8 sessionId)
return status;
}
#endif
+
+eHalStatus sme_getValidChannelList(tHalHandle hHal, tANI_U8 *numChannels,
+ tANI_U8 **chanList)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ eHalStatus status;
+
+ status = sme_AcquireGlobalLock(&pMac->sme);
+ if (HAL_STATUS_SUCCESS(status))
+ {
+ *numChannels =
+ pMac->roam.neighborRoamInfo.cfgParams.channelInfo.numOfChannels;
+ vos_mem_copy(*chanList,
+ &pMac->roam.neighborRoamInfo.cfgParams.channelInfo.ChannelList,
+ *numChannels);
+ sme_ReleaseGlobalLock(&pMac->sme);
+ }
+ return status;
+}
+
+#ifdef QCA_WIFI_2_0
+eHalStatus sme_getChannelInfo(tHalHandle hHal, tANI_U8 chanId,
+ tSmeChannelInfo *chanInfo)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ eHalStatus status;
+ tANI_U8 i;
+ eAniBoolean found = false;
+
+ status = sme_AcquireGlobalLock(&pMac->sme);
+ if (HAL_STATUS_SUCCESS(status))
+ {
+ for (i = 0 ; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++)
+ {
+ if (pMac->scan.defaultPowerTable[i].chanId == chanId)
+ {
+ chanInfo->chan_id = chanId;
+ chanInfo->mhz = vos_chan_to_freq(chanId);
+ chanInfo->band_center_freq1 = chanInfo->mhz;
+ chanInfo->band_center_freq2 = 0;
+
+ if (chanInfo->mhz < SME_2_4_GHZ_MAX_FREQ)
+ {
+ SME_SET_CHANNEL_MODE(chanInfo, SME_MODE_11G);
+ }
+ else
+ {
+ SME_SET_CHANNEL_MODE(chanInfo, SME_MODE_11A);
+ }
+
+ SME_SET_CHANNEL_MAX_POWER(chanInfo,
+ pMac->scan.defaultPowerTable[i].pwr);
+
+ SME_SET_CHANNEL_REG_POWER(chanInfo,
+ pMac->scan.defaultPowerTable[i].pwr);
+
+ /* TODO: Set CHANNEL_MIN_POWER */
+ /* TODO: Set CHANNEL_ANTENNA_MAX */
+ /* TODO: Set CHANNEL_REG_CLASSID */
+
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ status = eHAL_STATUS_FAILURE;
+
+ sme_ReleaseGlobalLock(&pMac->sme);
+ }
+ return status;
+}
+#endif /* QCA_WIFI_2_0 */
diff --git a/CORE/SVC/external/wlan_nlink_common.h b/CORE/SVC/external/wlan_nlink_common.h
index 43e30591bd14..0fd897fa1c17 100644
--- a/CORE/SVC/external/wlan_nlink_common.h
+++ b/CORE/SVC/external/wlan_nlink_common.h
@@ -102,6 +102,9 @@ typedef enum eAniNlModuleTypes {
ANI_NL_MSG_PUMAC = ANI_NL_MSG_BASE + 0x01,// PTT Socket App
ANI_NL_MSG_PTT = ANI_NL_MSG_BASE + 0x07,// Quarky GUI
WLAN_NL_MSG_BTC,
+#ifdef QCA_WIFI_2_0
+ WLAN_NL_MSG_OEM,
+#endif
ANI_NL_MSG_MAX
} tAniNlModTypes, tWlanNlModTypes;
diff --git a/CORE/SVC/inc/wlan_ptt_sock_svc.h b/CORE/SVC/inc/wlan_ptt_sock_svc.h
index e6f427d93a6f..2157d4980902 100644
--- a/CORE/SVC/inc/wlan_ptt_sock_svc.h
+++ b/CORE/SVC/inc/wlan_ptt_sock_svc.h
@@ -61,6 +61,12 @@
#define ANI_DRIVER_MSG_START 0x0001
#define ANI_MSG_APP_REG_REQ (ANI_DRIVER_MSG_START + 0)
#define ANI_MSG_APP_REG_RSP (ANI_DRIVER_MSG_START + 1)
+#define ANI_MSG_OEM_DATA_REQ (ANI_DRIVER_MSG_START + 2)
+#define ANI_MSG_OEM_DATA_RSP (ANI_DRIVER_MSG_START + 3)
+#define ANI_MSG_CHANNEL_INFO_REQ (ANI_DRIVER_MSG_START + 4)
+#define ANI_MSG_CHANNEL_INFO_RSP (ANI_DRIVER_MSG_START + 5)
+#define ANI_MSG_OEM_ERROR (ANI_DRIVER_MSG_START + 6)
+
#define ANI_MAX_RADIOS 3
#define ANI_NL_MSG_OK 0
#define ANI_NL_MSG_ERROR -1
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index 762fff53ca34..df4066d4c0fa 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -688,11 +688,19 @@ typedef struct {
#ifdef FEATURE_OEM_DATA_SUPPORT
#ifndef OEM_DATA_REQ_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_REQ_SIZE 276
+#else
#define OEM_DATA_REQ_SIZE 134
#endif
+#endif
#ifndef OEM_DATA_RSP_SIZE
+#ifdef QCA_WIFI_2_0
+#define OEM_DATA_RSP_SIZE 1720
+#else
#define OEM_DATA_RSP_SIZE 1968
#endif
+#endif
typedef struct
{