diff options
| author | Rajesh Chauhan <rajeshc@qca.qualcomm.com> | 2013-09-20 17:54:42 -0700 |
|---|---|---|
| committer | Madan Mohan Koyyalamudi <mkoyyala@qca.qualcomm.com> | 2013-10-23 20:05:15 -0700 |
| commit | ce8742cd83308803ffa8e2ead3ef576a09dc3c7c (patch) | |
| tree | 13db9b14bd16429310ba6e2fdc8bbe0898753961 | |
| parent | 0a4b764a824e78bd52ec8be1aacc831ef08fb5ec (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.h | 14 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_oemdata.h | 66 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_tgt_cfg.h | 1 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 17 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_oemdata.c | 663 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 16 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 8 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/include/limGlobal.h | 8 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMessageQueue.c | 12 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c | 6 | ||||
| -rw-r--r-- | CORE/SME/inc/oemDataApi.h | 18 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 51 | ||||
| -rw-r--r-- | CORE/SME/src/oemData/oemDataApi.c | 28 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 73 | ||||
| -rw-r--r-- | CORE/SVC/external/wlan_nlink_common.h | 3 | ||||
| -rw-r--r-- | CORE/SVC/inc/wlan_ptt_sock_svc.h | 6 | ||||
| -rw-r--r-- | CORE/WDA/inc/legacy/halMsgApi.h | 8 |
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 { |
