| /******************************************************************************* |
| * |
| * This file is provided under a dual license. When you use or |
| * distribute this software, you may choose to be licensed under |
| * version 2 of the GNU General Public License ("GPLv2 License") |
| * or BSD License. |
| * |
| * GPLv2 License |
| * |
| * Copyright(C) 2016 MediaTek Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of version 2 of the GNU General Public License as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| * See http://www.gnu.org/licenses/gpl-2.0.html for more details. |
| * |
| * BSD LICENSE |
| * |
| * Copyright(C) 2016 MediaTek Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of the copyright holder nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| ******************************************************************************/ |
| /* |
| ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common |
| * /wlan_oid.c#11 |
| */ |
| |
| /*! \file wlanoid.c |
| * \brief This file contains the WLAN OID processing routines of Windows |
| * driver for MediaTek Inc. 802.11 Wireless LAN Adapters. |
| */ |
| |
| |
| /****************************************************************************** |
| * C O M P I L E R F L A G S |
| ****************************************************************************** |
| */ |
| |
| /****************************************************************************** |
| * E X T E R N A L R E F E R E N C E S |
| ****************************************************************************** |
| */ |
| #include "precomp.h" |
| #include "mgmt/rsn.h" |
| #include "gl_wext.h" |
| #include "debug.h" |
| #include <stddef.h> |
| |
| /****************************************************************************** |
| * C O N S T A N T S |
| ****************************************************************************** |
| */ |
| |
| /****************************************************************************** |
| * D A T A T Y P E S |
| ****************************************************************************** |
| */ |
| |
| /****************************************************************************** |
| * P U B L I C D A T A |
| ****************************************************************************** |
| */ |
| struct PARAM_CUSTOM_KEY_CFG_STRUCT g_rDefaulteSetting[] = { |
| /*format : |
| *: {"firmware config parameter", "firmware config value"} |
| */ |
| {"AdapScan", "0x0"} |
| }; |
| |
| |
| /****************************************************************************** |
| * P R I V A T E D A T A |
| ****************************************************************************** |
| */ |
| |
| /****************************************************************************** |
| * M A C R O S |
| ****************************************************************************** |
| */ |
| |
| /****************************************************************************** |
| * F U N C T I O N D E C L A R A T I O N S |
| ****************************************************************************** |
| */ |
| #if DBG && 0 |
| static void SetRCID(u_int8_t fgOneTb3, u_int8_t *fgRCID); |
| #endif |
| |
| #if CFG_SLT_SUPPORT |
| static void SetTestChannel(uint8_t *pucPrimaryChannel); |
| #endif |
| |
| /****************************************************************************** |
| * F U N C T I O N S |
| ****************************************************************************** |
| */ |
| static void setApUapsdEnable(struct ADAPTER *prAdapter, |
| u_int8_t enable) |
| { |
| struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT rUapsdParams; |
| uint32_t u4SetInfoLen = 0; |
| uint8_t ucBssIdx; |
| |
| /* FIX ME: Add p2p role index selection */ |
| if (p2pFuncRoleToBssIdx( |
| prAdapter, 0, &ucBssIdx) != WLAN_STATUS_SUCCESS) |
| return; |
| |
| DBGLOG(OID, INFO, "setApUapsdEnable: %d, ucBssIdx: %d\n", |
| enable, ucBssIdx); |
| |
| rUapsdParams.ucBssIdx = ucBssIdx; |
| |
| if (enable) { |
| prAdapter->rWifiVar.ucApUapsd = TRUE; |
| rUapsdParams.fgEnAPSD = 1; |
| rUapsdParams.fgEnAPSD_AcBe = 1; |
| rUapsdParams.fgEnAPSD_AcBk = 1; |
| rUapsdParams.fgEnAPSD_AcVi = 1; |
| rUapsdParams.fgEnAPSD_AcVo = 1; |
| /* default: 0, do not limit delivery pkt number */ |
| rUapsdParams.ucMaxSpLen = 0; |
| } else { |
| prAdapter->rWifiVar.ucApUapsd = FALSE; |
| rUapsdParams.fgEnAPSD = 0; |
| rUapsdParams.fgEnAPSD_AcBe = 0; |
| rUapsdParams.fgEnAPSD_AcBk = 0; |
| rUapsdParams.fgEnAPSD_AcVi = 0; |
| rUapsdParams.fgEnAPSD_AcVo = 0; |
| /* default: 0, do not limit delivery pkt number */ |
| rUapsdParams.ucMaxSpLen = 0; |
| } |
| wlanoidSetUApsdParam(prAdapter, |
| &rUapsdParams, |
| sizeof(struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT), |
| &u4SetInfoLen); |
| } |
| |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| static u_int8_t IsBufferedStatisticsUsable( |
| struct ADAPTER *prAdapter) |
| { |
| ASSERT(prAdapter); |
| |
| if (prAdapter->fgIsStatValid == TRUE && |
| (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= |
| CFG_STATISTICS_VALID_CYCLE) |
| return TRUE; |
| else |
| return FALSE; |
| } |
| #endif |
| |
| #if DBG && 0 |
| static void SetRCID(u_int8_t fgOneTb3, u_int8_t *fgRCID) |
| { |
| if (fgOneTb3) |
| *fgRCID = 0; |
| else |
| *fgRCID = 1; |
| } |
| #endif |
| |
| #if CFG_SLT_SUPPORT |
| static void SetTestChannel(uint8_t *pucPrimaryChannel) |
| { |
| if (*pucPrimaryChannel < 5) |
| *pucPrimaryChannel = 8; |
| else if (*pucPrimaryChannel > 10) |
| *pucPrimaryChannel = 3; |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the supported physical layer network |
| * type that can be used by the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryNetworkTypesSupported(IN struct ADAPTER |
| *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| uint32_t u4NumItem = 0; |
| enum ENUM_PARAM_NETWORK_TYPE |
| eSupportedNetworks[PARAM_NETWORK_TYPE_NUM]; |
| struct PARAM_NETWORK_TYPE_LIST *prSupported; |
| |
| /* The array of all physical layer network subtypes that the driver |
| * supports. |
| */ |
| |
| DEBUGFUNC("wlanoidQueryNetworkTypesSupported"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| /* Init. */ |
| for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; |
| u4NumItem++) |
| eSupportedNetworks[u4NumItem] = 0; |
| |
| u4NumItem = 0; |
| |
| eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS; |
| u4NumItem++; |
| |
| eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24; |
| u4NumItem++; |
| |
| *pu4QueryInfoLen = |
| (uint32_t) OFFSET_OF(struct PARAM_NETWORK_TYPE_LIST, |
| eNetworkType) + |
| (u4NumItem * sizeof(enum ENUM_PARAM_NETWORK_TYPE)); |
| |
| if (u4QueryBufferLen < *pu4QueryInfoLen) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prSupported = (struct PARAM_NETWORK_TYPE_LIST *) |
| pvQueryBuffer; |
| prSupported->NumberOfItems = u4NumItem; |
| kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, |
| u4NumItem * sizeof(enum ENUM_PARAM_NETWORK_TYPE)); |
| |
| DBGLOG(REQ, TRACE, "NDIS supported network type list: %u\n", |
| prSupported->NumberOfItems); |
| DBGLOG_MEM8(REQ, INFO, prSupported, *pu4QueryInfoLen); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryNetworkTypesSupported */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current physical layer network |
| * type used by the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryNetworkTypeInUse(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| /* TODO: need to check the OID handler content again!! */ |
| |
| enum ENUM_PARAM_NETWORK_TYPE rCurrentNetworkTypeInUse = |
| PARAM_NETWORK_TYPE_OFDM24; |
| |
| DEBUGFUNC("wlanoidQueryNetworkTypeInUse"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(enum |
| ENUM_PARAM_NETWORK_TYPE)) { |
| *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) |
| rCurrentNetworkTypeInUse = (enum ENUM_PARAM_NETWORK_TYPE) ( |
| prAdapter->rWlanInfo.ucNetworkType); |
| else |
| rCurrentNetworkTypeInUse = (enum ENUM_PARAM_NETWORK_TYPE) ( |
| prAdapter->rWlanInfo.ucNetworkTypeInUse); |
| |
| *(enum ENUM_PARAM_NETWORK_TYPE *) pvQueryBuffer = |
| rCurrentNetworkTypeInUse; |
| *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); |
| |
| DBGLOG(REQ, TRACE, "Network type in use: %d\n", |
| rCurrentNetworkTypeInUse); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryNetworkTypeInUse */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the physical layer network type used |
| * by the driver. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns the |
| * amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted. |
| * \retval WLAN_STATUS_INVALID_DATA The given network type is not in the |
| * supported list. |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetNetworkTypeInUse(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| /* TODO: need to check the OID handler content again!! */ |
| |
| enum ENUM_PARAM_NETWORK_TYPE eNewNetworkType; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidSetNetworkTypeInUse"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (u4SetBufferLen < sizeof(enum ENUM_PARAM_NETWORK_TYPE)) { |
| *pu4SetInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| eNewNetworkType = *(enum ENUM_PARAM_NETWORK_TYPE *) |
| pvSetBuffer; |
| *pu4SetInfoLen = sizeof(enum ENUM_PARAM_NETWORK_TYPE); |
| |
| DBGLOG(REQ, INFO, "New network type: %d mode\n", |
| eNewNetworkType); |
| |
| switch (eNewNetworkType) { |
| |
| case PARAM_NETWORK_TYPE_DS: |
| prAdapter->rWlanInfo.ucNetworkTypeInUse = |
| (uint8_t) PARAM_NETWORK_TYPE_DS; |
| break; |
| |
| case PARAM_NETWORK_TYPE_OFDM5: |
| prAdapter->rWlanInfo.ucNetworkTypeInUse = |
| (uint8_t) PARAM_NETWORK_TYPE_OFDM5; |
| break; |
| |
| case PARAM_NETWORK_TYPE_OFDM24: |
| prAdapter->rWlanInfo.ucNetworkTypeInUse = |
| (uint8_t) PARAM_NETWORK_TYPE_OFDM24; |
| break; |
| |
| case PARAM_NETWORK_TYPE_AUTOMODE: |
| prAdapter->rWlanInfo.ucNetworkTypeInUse = |
| (uint8_t) PARAM_NETWORK_TYPE_AUTOMODE; |
| break; |
| |
| case PARAM_NETWORK_TYPE_FH: |
| DBGLOG(REQ, INFO, "Not support network type: %d\n", |
| eNewNetworkType); |
| rStatus = WLAN_STATUS_NOT_SUPPORTED; |
| break; |
| |
| default: |
| DBGLOG(REQ, INFO, "Unknown network type: %d\n", |
| eNewNetworkType); |
| rStatus = WLAN_STATUS_INVALID_DATA; |
| break; |
| } |
| |
| /* Verify if we support the new network type. */ |
| if (rStatus != WLAN_STATUS_SUCCESS) |
| DBGLOG(REQ, WARN, "Unknown network type: %d\n", |
| eNewNetworkType); |
| |
| return rStatus; |
| } /* wlanoidSetNetworkTypeInUse */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current BSSID. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryBssid(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQueryBssid"); |
| |
| ASSERT(prAdapter); |
| |
| if (u4QueryBufferLen < MAC_ADDR_LEN) { |
| ASSERT(pu4QueryInfoLen); |
| *pu4QueryInfoLen = MAC_ADDR_LEN; |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) |
| kalMemCopy(pvQueryBuffer, |
| prAdapter->rWlanInfo.rCurrBssId.arMacAddress, |
| MAC_ADDR_LEN); |
| else if (prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_IBSS) { |
| uint8_t aucTemp[PARAM_MAC_ADDR_LEN]; /*!< BSSID */ |
| |
| COPY_MAC_ADDR(aucTemp, |
| prAdapter->rWlanInfo.rCurrBssId.arMacAddress); |
| aucTemp[0] &= ~BIT(0); |
| aucTemp[1] |= BIT(1); |
| COPY_MAC_ADDR(pvQueryBuffer, aucTemp); |
| } else |
| rStatus = WLAN_STATUS_ADAPTER_NOT_READY; |
| |
| *pu4QueryInfoLen = MAC_ADDR_LEN; |
| return rStatus; |
| } /* wlanoidQueryBssid */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the list of all BSSIDs detected by |
| * the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryBssidList(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| uint32_t i, u4BssidListExLen; |
| struct PARAM_BSSID_LIST_EX *prList; |
| struct PARAM_BSSID_EX *prBssidEx; |
| uint8_t *cp; |
| |
| DEBUGFUNC("wlanoidQueryBssidList"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (u4QueryBufferLen) { |
| ASSERT(pvQueryBuffer); |
| |
| if (!pvQueryBuffer) |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| u4BssidListExLen = 0; |
| |
| if (prAdapter->fgIsRadioOff == FALSE) { |
| for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) |
| u4BssidListExLen += ALIGN_4( |
| prAdapter->rWlanInfo.arScanResult[i].u4Length); |
| } |
| |
| if (u4BssidListExLen) |
| u4BssidListExLen += 4; /* u4NumberOfItems. */ |
| else |
| u4BssidListExLen = sizeof(struct PARAM_BSSID_LIST_EX); |
| |
| *pu4QueryInfoLen = u4BssidListExLen; |
| |
| if (u4QueryBufferLen < *pu4QueryInfoLen) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| /* Clear the buffer */ |
| kalMemZero(pvQueryBuffer, u4BssidListExLen); |
| |
| prList = (struct PARAM_BSSID_LIST_EX *) pvQueryBuffer; |
| cp = (uint8_t *) &prList->arBssid[0]; |
| |
| if (prAdapter->fgIsRadioOff == FALSE |
| && prAdapter->rWlanInfo.u4ScanResultNum > 0) { |
| /* fill up for each entry */ |
| for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { |
| prBssidEx = (struct PARAM_BSSID_EX *) cp; |
| |
| /* copy structure */ |
| kalMemCopy(prBssidEx, |
| &(prAdapter->rWlanInfo.arScanResult[i]), |
| OFFSET_OF(struct PARAM_BSSID_EX, aucIEs)); |
| |
| /* For WHQL test, Rssi should be |
| * in range -10 ~ -200 dBm |
| */ |
| if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM) |
| prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM; |
| |
| if (prAdapter->rWlanInfo.arScanResult[i].u4IELength |
| > 0) { |
| /* copy IEs */ |
| kalMemCopy(prBssidEx->aucIEs, |
| prAdapter->rWlanInfo.apucScanResultIEs[i], |
| prAdapter->rWlanInfo.arScanResult[i] |
| .u4IELength); |
| } |
| /* 4-bytes alignement */ |
| prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length); |
| |
| cp += prBssidEx->u4Length; |
| prList->u4NumberOfItems++; |
| } |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryBssidList */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to request the driver to perform |
| * scanning. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetBssidListScan(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct PARAM_SSID *prSsid; |
| struct PARAM_SSID rSsid; |
| |
| DEBUGFUNC("wlanoidSetBssidListScan()"); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(OID, WARN, |
| "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (prAdapter->fgTestMode) { |
| DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| ASSERT(pu4SetInfoLen); |
| *pu4SetInfoLen = 0; |
| |
| if (prAdapter->fgIsRadioOff) { |
| DBGLOG(OID, WARN, |
| "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| if (pvSetBuffer != NULL && u4SetBufferLen != 0) { |
| COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, |
| u4SetBufferLen); |
| prSsid = &rSsid; |
| } else { |
| prSsid = NULL; |
| } |
| |
| #if CFG_SUPPORT_RDD_TEST_MODE |
| if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { |
| if ((prAdapter->fgEnOnlineScan == TRUE) |
| && (prAdapter->ucRddStatus)) { |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != |
| PARAM_MEDIA_STATE_CONNECTED) |
| aisFsmScanRequest(prAdapter, prSsid, NULL, 0); |
| else |
| return WLAN_STATUS_FAILURE; |
| } else |
| return WLAN_STATUS_FAILURE; |
| } else |
| #endif |
| { |
| if (prAdapter->fgEnOnlineScan == TRUE) |
| aisFsmScanRequest(prAdapter, prSsid, NULL, 0); |
| else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != |
| PARAM_MEDIA_STATE_CONNECTED) |
| aisFsmScanRequest(prAdapter, prSsid, NULL, 0); |
| else |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetBssidListScan */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to request the driver to perform |
| * scanning with attaching information elements(IEs) specified from user |
| * space |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetBssidListScanExt(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct PARAM_SCAN_REQUEST_EXT *prScanRequest; |
| struct PARAM_SSID *prSsid; |
| uint8_t *pucIe; |
| uint32_t u4IeLength; |
| |
| DEBUGFUNC("wlanoidSetBssidListScanExt()"); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(OID, WARN, |
| "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (prAdapter->fgTestMode) { |
| DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| ASSERT(pu4SetInfoLen); |
| *pu4SetInfoLen = 0; |
| |
| if (u4SetBufferLen != sizeof(struct PARAM_SCAN_REQUEST_EXT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (prAdapter->fgIsRadioOff) { |
| DBGLOG(OID, WARN, |
| "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_SUCCESS; |
| } |
| DBGLOG(OID, TRACE, "ScanEX\n"); |
| if (pvSetBuffer != NULL && u4SetBufferLen != 0) { |
| prScanRequest = (struct PARAM_SCAN_REQUEST_EXT *) |
| pvSetBuffer; |
| prSsid = &(prScanRequest->rSsid); |
| pucIe = prScanRequest->pucIE; |
| u4IeLength = prScanRequest->u4IELength; |
| } else { |
| prScanRequest = NULL; |
| prSsid = NULL; |
| pucIe = NULL; |
| u4IeLength = 0; |
| } |
| |
| #if CFG_SUPPORT_RDD_TEST_MODE |
| if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { |
| if ((prAdapter->fgEnOnlineScan == TRUE) |
| && (prAdapter->ucRddStatus)) { |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != |
| PARAM_MEDIA_STATE_CONNECTED) |
| aisFsmScanRequest(prAdapter, prSsid, pucIe, |
| u4IeLength); |
| else |
| return WLAN_STATUS_FAILURE; |
| } else |
| return WLAN_STATUS_FAILURE; |
| } else |
| #endif |
| { |
| if (prAdapter->fgEnOnlineScan == TRUE) |
| aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); |
| else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != |
| PARAM_MEDIA_STATE_CONNECTED) |
| aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); |
| else |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetBssidListScanWithIE */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to request the driver to perform |
| * scanning with attaching information elements(IEs) specified from user |
| * space and multiple SSID |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetBssidListScanAdv(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct PARAM_SCAN_REQUEST_ADV *prScanRequest; |
| |
| DEBUGFUNC("wlanoidSetBssidListScanAdv()"); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(OID, WARN, |
| "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (prAdapter->fgTestMode) { |
| DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| ASSERT(pu4SetInfoLen); |
| *pu4SetInfoLen = 0; |
| |
| if (u4SetBufferLen != sizeof(struct PARAM_SCAN_REQUEST_ADV)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| else if (pvSetBuffer == NULL) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| if (prAdapter->fgIsRadioOff) { |
| DBGLOG(OID, WARN, |
| "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| prScanRequest = (struct PARAM_SCAN_REQUEST_ADV *) |
| pvSetBuffer; |
| |
| #if CFG_SUPPORT_RDD_TEST_MODE |
| if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { |
| if ((prAdapter->fgEnOnlineScan == TRUE) |
| && (prAdapter->ucRddStatus)) { |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) |
| != PARAM_MEDIA_STATE_CONNECTED) { |
| aisFsmScanRequestAdv(prAdapter, prScanRequest); |
| } else |
| return WLAN_STATUS_FAILURE; |
| } else |
| return WLAN_STATUS_FAILURE; |
| } else |
| #endif |
| { |
| if (prAdapter->fgEnOnlineScan == TRUE) { |
| aisFsmScanRequestAdv(prAdapter, prScanRequest); |
| } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) |
| != PARAM_MEDIA_STATE_CONNECTED) { |
| aisFsmScanRequestAdv(prAdapter, prScanRequest); |
| } else |
| return WLAN_STATUS_FAILURE; |
| } |
| cnmTimerStartTimer(prAdapter, |
| &prAdapter->rWifiVar.rAisFsmInfo.rScanDoneTimer, |
| SEC_TO_MSEC(AIS_SCN_DONE_TIMEOUT_SEC)); |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetBssidListScanAdv */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine will initiate the join procedure to attempt to associate |
| * with the specified BSSID. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetBssid(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| uint8_t *pAddr; |
| uint32_t i; |
| int32_t i4Idx = -1; |
| struct MSG_AIS_ABORT *prAisAbortMsg; |
| uint8_t ucReasonOfDisconnect; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = MAC_ADDR_LEN; |
| if (u4SetBufferLen != MAC_ADDR_LEN) { |
| *pu4SetInfoLen = MAC_ADDR_LEN; |
| return WLAN_STATUS_INVALID_LENGTH; |
| } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| pAddr = (uint8_t *) pvSetBuffer; |
| |
| /* re-association check */ |
| if (kalGetMediaStateIndicated(prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) { |
| if (EQUAL_MAC_ADDR( |
| prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) { |
| kalSetMediaStateIndicated(prGlueInfo, |
| PARAM_MEDIA_STATE_TO_BE_INDICATED); |
| ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_REASSOCIATION; |
| } else { |
| kalIndicateStatusAndComplete(prGlueInfo, |
| WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); |
| ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_NEW_CONNECTION; |
| } |
| } else { |
| ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_NEW_CONNECTION; |
| } |
| |
| /* check if any scanned result matchs with the BSSID */ |
| for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { |
| if (EQUAL_MAC_ADDR( |
| prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { |
| i4Idx = (int32_t) i; |
| break; |
| } |
| } |
| |
| /* prepare message to AIS */ |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_IBSS |
| || prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_DEDICATED_IBSS) { |
| /* IBSS *//* beacon period */ |
| prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = |
| prAdapter->rWlanInfo.u2BeaconPeriod; |
| prAdapter->rWifiVar.rConnSettings.u2AtimWindow = |
| prAdapter->rWlanInfo.u2AtimWindow; |
| } |
| |
| /* Set Connection Request Issued Flag */ |
| prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; |
| prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = |
| CONNECT_BY_BSSID; |
| |
| /* Send AIS Abort Message */ |
| prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( |
| prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_AIS_ABORT)); |
| if (!prAisAbortMsg) { |
| DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; |
| prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect; |
| |
| /* Update the information to CONNECTION_SETTINGS_T */ |
| prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0; |
| prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0'; |
| COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, |
| pAddr); |
| |
| if (EQUAL_MAC_ADDR( |
| prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) |
| prAisAbortMsg->fgDelayIndication = TRUE; |
| else |
| prAisAbortMsg->fgDelayIndication = FALSE; |
| |
| #if CFG_DISCONN_DEBUG_FEATURE |
| /* used to disconnect debug capability */ |
| g_rDisconnInfoTemp.ucTrigger = DISCONNECT_TRIGGER_ACTIVE; |
| #endif |
| |
| mboxSendMsg(prAdapter, MBOX_ID_0, |
| (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidSetBssid() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine will initiate the join procedure to attempt |
| * to associate with the new SSID. If the previous scanning |
| * result is aged, we will scan the channels at first. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetSsid(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| struct PARAM_SSID *pParamSsid; |
| uint32_t i; |
| int32_t i4Idx = -1, i4MaxRSSI = INT_MIN; |
| struct MSG_AIS_ABORT *prAisAbortMsg; |
| u_int8_t fgIsValidSsid = TRUE; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| /* MSDN: |
| * Powering on the radio if the radio is powered off through a setting |
| * of OID_802_11_DISASSOCIATE |
| */ |
| if (prAdapter->fgIsRadioOff == TRUE) |
| prAdapter->fgIsRadioOff = FALSE; |
| |
| if (u4SetBufferLen < sizeof(struct PARAM_SSID) |
| || u4SetBufferLen > sizeof(struct PARAM_SSID)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| else if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| pParamSsid = (struct PARAM_SSID *) pvSetBuffer; |
| |
| if (pParamSsid->u4SsidLen > 32) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ |
| /* re-association check */ |
| if (kalGetMediaStateIndicated(prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) { |
| if (EQUAL_SSID( |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, |
| pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { |
| kalSetMediaStateIndicated(prGlueInfo, |
| PARAM_MEDIA_STATE_TO_BE_INDICATED); |
| } else |
| kalIndicateStatusAndComplete(prGlueInfo, |
| WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); |
| } |
| /* check if any scanned result matchs with the SSID */ |
| for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { |
| uint8_t *aucSsid = |
| prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; |
| uint8_t ucSsidLength = (uint8_t) |
| prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; |
| int32_t i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; |
| |
| if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, |
| pParamSsid->u4SsidLen) && |
| i4RSSI >= i4MaxRSSI) { |
| i4Idx = (int32_t) i; |
| i4MaxRSSI = i4RSSI; |
| } |
| } |
| |
| /* prepare message to AIS */ |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_IBSS |
| || prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_DEDICATED_IBSS) { |
| /* IBSS *//* beacon period */ |
| prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = |
| prAdapter->rWlanInfo.u2BeaconPeriod; |
| prAdapter->rWifiVar.rConnSettings.u2AtimWindow = |
| prAdapter->rWlanInfo.u2AtimWindow; |
| } |
| |
| if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { |
| if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) { |
| fgIsValidSsid = FALSE; |
| |
| for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { |
| if (!((pParamSsid->aucSsid[i] > 0) |
| && (pParamSsid->aucSsid[i] <= 0x1F))) { |
| fgIsValidSsid = TRUE; |
| break; |
| } |
| } |
| } |
| } |
| |
| /* Set Connection Request Issued Flag */ |
| if (fgIsValidSsid) { |
| prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; |
| |
| if (pParamSsid->u4SsidLen) |
| prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = |
| CONNECT_BY_SSID_BEST_RSSI; |
| else |
| /* wildcard SSID */ |
| prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = |
| CONNECT_BY_SSID_ANY; |
| } else |
| prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; |
| |
| /* Send AIS Abort Message */ |
| prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( |
| prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_AIS_ABORT)); |
| if (!prAisAbortMsg) { |
| DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; |
| prAisAbortMsg->ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_NEW_CONNECTION; |
| COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, |
| prAdapter->rWifiVar.rConnSettings.ucSSIDLen, |
| pParamSsid->aucSsid, (uint8_t) pParamSsid->u4SsidLen); |
| |
| if (EQUAL_SSID( |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, |
| pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { |
| prAisAbortMsg->fgDelayIndication = TRUE; |
| } else { |
| /* Update the information to CONNECTION_SETTINGS_T */ |
| prAisAbortMsg->fgDelayIndication = FALSE; |
| } |
| DBGLOG(SCN, INFO, "SSID %s\n", |
| prAdapter->rWifiVar.rConnSettings.aucSSID); |
| |
| #if CFG_DISCONN_DEBUG_FEATURE |
| /* used to disconnect debug capability */ |
| g_rDisconnInfoTemp.ucTrigger = DISCONNECT_TRIGGER_ACTIVE; |
| #endif |
| |
| mboxSendMsg(prAdapter, MBOX_ID_0, |
| (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* end of wlanoidSetSsid() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine will initiate the join procedure to attempt |
| * to associate with the new BSS, base on given SSID, BSSID, and |
| * freqency. |
| * If the target connecting BSS is in the same ESS as current connected |
| * BSS, roaming will be performed. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetConnect(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| struct PARAM_CONNECT *pParamConn; |
| struct CONNECTION_SETTINGS *prConnSettings; |
| uint32_t i; |
| struct MSG_AIS_ABORT *prAisAbortMsg; |
| u_int8_t fgIsValidSsid = TRUE; |
| u_int8_t fgEqualSsid = FALSE; |
| u_int8_t fgEqualBssid = FALSE; |
| const uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| /* MSDN: |
| * Powering on the radio if the radio is powered off through a setting |
| * of OID_802_11_DISASSOCIATE |
| */ |
| if (prAdapter->fgIsRadioOff == TRUE) |
| prAdapter->fgIsRadioOff = FALSE; |
| |
| if (u4SetBufferLen != sizeof(struct PARAM_CONNECT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| else if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( |
| prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_AIS_ABORT)); |
| if (!prAisAbortMsg) { |
| DBGLOG(REQ, ERROR, "Fail in allocating AisAbortMsg.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; |
| |
| pParamConn = (struct PARAM_CONNECT *) pvSetBuffer; |
| prConnSettings = &prAdapter->rWifiVar.rConnSettings; |
| |
| if (pParamConn->u4SsidLen > 32) { |
| cnmMemFree(prAdapter, prAisAbortMsg); |
| DBGLOG(OID, WARN, "SsidLen [%d] is invalid!\n", |
| pParamConn->u4SsidLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } else if (!pParamConn->pucBssid && !pParamConn->pucSsid) { |
| cnmMemFree(prAdapter, prAisAbortMsg); |
| DBGLOG(OID, WARN, "Bssid or ssid is invalid!\n"); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| kalMemZero(prConnSettings->aucSSID, |
| sizeof(prConnSettings->aucSSID)); |
| prConnSettings->ucSSIDLen = 0; |
| kalMemZero(prConnSettings->aucBSSID, |
| sizeof(prConnSettings->aucBSSID)); |
| kalMemZero(prConnSettings->aucBSSIDHint, |
| sizeof(prConnSettings->aucBSSIDHint)); |
| prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; |
| prConnSettings->fgIsConnByBssidIssued = FALSE; |
| |
| if (pParamConn->pucSsid) { |
| prConnSettings->eConnectionPolicy = |
| CONNECT_BY_SSID_BEST_RSSI; |
| prConnSettings->ucSSIDLen = pParamConn->u4SsidLen; |
| COPY_SSID(prConnSettings->aucSSID, |
| prConnSettings->ucSSIDLen, pParamConn->pucSsid, |
| (uint8_t) pParamConn->u4SsidLen); |
| if (EQUAL_SSID( |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, |
| pParamConn->pucSsid, pParamConn->u4SsidLen)) |
| fgEqualSsid = TRUE; |
| } |
| if (pParamConn->pucBssid) { |
| if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) |
| && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) { |
| prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID; |
| prConnSettings->fgIsConnByBssidIssued = TRUE; |
| COPY_MAC_ADDR(prConnSettings->aucBSSID, |
| pParamConn->pucBssid); |
| if (EQUAL_MAC_ADDR( |
| prAdapter->rWlanInfo.rCurrBssId.arMacAddress, |
| pParamConn->pucBssid)) |
| fgEqualBssid = TRUE; |
| } else |
| DBGLOG(INIT, INFO, "wrong bssid " MACSTR "to connect\n", |
| MAC2STR(pParamConn->pucBssid)); |
| } else if (pParamConn->pucBssidHint) { |
| if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssidHint) |
| && IS_UCAST_MAC_ADDR(pParamConn->pucBssidHint)) { |
| prConnSettings->eConnectionPolicy = |
| CONNECT_BY_BSSID_HINT; |
| COPY_MAC_ADDR(prConnSettings->aucBSSIDHint, |
| pParamConn->pucBssidHint); |
| if (EQUAL_MAC_ADDR( |
| prAdapter->rWlanInfo.rCurrBssId.arMacAddress, |
| pParamConn->pucBssidHint)) |
| fgEqualBssid = TRUE; |
| } |
| } else |
| DBGLOG(INIT, INFO, "No Bssid set\n"); |
| prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq; |
| |
| /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ |
| /* re-association check */ |
| if (kalGetMediaStateIndicated(prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) { |
| if (fgEqualSsid) { |
| prAisAbortMsg->ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_ROAMING; |
| if (fgEqualBssid) { |
| kalSetMediaStateIndicated(prGlueInfo, |
| PARAM_MEDIA_STATE_TO_BE_INDICATED); |
| prAisAbortMsg->ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_REASSOCIATION; |
| } |
| } else { |
| DBGLOG(INIT, INFO, "DisBySsid\n"); |
| kalIndicateStatusAndComplete(prGlueInfo, |
| WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); |
| prAisAbortMsg->ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_NEW_CONNECTION; |
| } |
| } else |
| prAisAbortMsg->ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_NEW_CONNECTION; |
| #if 0 |
| /* check if any scanned result matchs with the SSID */ |
| for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { |
| uint8_t *aucSsid = |
| prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; |
| uint8_t ucSsidLength = (uint8_t) |
| prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; |
| int32_t i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; |
| |
| if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, |
| pParamConn->u4SsidLen) && |
| i4RSSI >= i4MaxRSSI) { |
| i4Idx = (int32_t) i; |
| i4MaxRSSI = i4RSSI; |
| } |
| if (EQUAL_MAC_ADDR( |
| prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { |
| i4Idx = (int32_t) i; |
| break; |
| } |
| } |
| #endif |
| /* prepare message to AIS */ |
| if (prConnSettings->eOPMode == NET_TYPE_IBSS |
| || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { |
| /* IBSS *//* beacon period */ |
| prConnSettings->u2BeaconPeriod = |
| prAdapter->rWlanInfo.u2BeaconPeriod; |
| prConnSettings->u2AtimWindow = |
| prAdapter->rWlanInfo.u2AtimWindow; |
| } |
| |
| if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { |
| if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) { |
| fgIsValidSsid = FALSE; |
| |
| if (pParamConn->pucSsid) { |
| for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { |
| if (!((pParamConn->pucSsid[i] > 0) && |
| (pParamConn->pucSsid[i] <= 0x1F))) { |
| fgIsValidSsid = TRUE; |
| break; |
| } |
| } |
| } else { |
| DBGLOG(INIT, ERROR, |
| "pParamConn->pucSsid is NULL\n"); |
| } |
| } |
| } |
| |
| /* Set Connection Request Issued Flag */ |
| if (fgIsValidSsid) |
| prConnSettings->fgIsConnReqIssued = TRUE; |
| else { |
| prConnSettings->eReConnectLevel = RECONNECT_LEVEL_USER_SET; |
| prConnSettings->fgIsConnReqIssued = FALSE; |
| } |
| |
| if (fgEqualSsid || fgEqualBssid) |
| prAisAbortMsg->fgDelayIndication = TRUE; |
| else |
| /* Update the information to CONNECTION_SETTINGS_T */ |
| prAisAbortMsg->fgDelayIndication = FALSE; |
| |
| #if CFG_DISCONN_DEBUG_FEATURE |
| /* used to disconnect debug capability */ |
| g_rDisconnInfoTemp.ucTrigger = DISCONNECT_TRIGGER_ACTIVE; |
| #endif |
| |
| mboxSendMsg(prAdapter, MBOX_ID_0, |
| (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); |
| |
| DBGLOG(INIT, INFO, "ssid %s, bssid " MACSTR |
| ", bssid_hint " MACSTR ", conn policy %d, disc reason %d\n", |
| prConnSettings->aucSSID, MAC2STR(prConnSettings->aucBSSID), |
| MAC2STR(prConnSettings->aucBSSIDHint), |
| prConnSettings->eConnectionPolicy, |
| prAisAbortMsg->ucReasonOfDisconnect); |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidSetConnect */ |
| |
| #if CFG_SUPPORT_CFG80211_AUTH |
| uint32_t |
| wlanoidSendAuthAssoc(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct STA_RECORD *prStaRec = NULL; |
| uint8_t *pAddr; |
| |
| if (!prAdapter || !pu4SetInfoLen) { |
| DBGLOG(REQ, WARN, "prAdapter or SetInfoLen is NULL!\n"); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| *pu4SetInfoLen = MAC_ADDR_LEN; |
| if (u4SetBufferLen != MAC_ADDR_LEN) { |
| *pu4SetInfoLen = MAC_ADDR_LEN; |
| return WLAN_STATUS_INVALID_LENGTH; |
| } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, "Failed because adapter not ready!\n"); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| pAddr = (uint8_t *)pvSetBuffer; |
| |
| DBGLOG(REQ, INFO, "try to find sta ["MACSTR"]\n", MAC2STR(pAddr)); |
| /* skip join initial flow |
| * when it has been completed with the same auth parameters |
| */ |
| prStaRec = cnmGetStaRecByAddress(prAdapter, |
| prAdapter->prAisBssInfo->ucBssIndex, |
| pAddr); |
| |
| if (prStaRec) |
| saaSendAuthAssoc(prAdapter, prStaRec); |
| else |
| DBGLOG(REQ, WARN, |
| "can't send auth since can't find StaRec\n"); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the currently associated SSID. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQuerySsid(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| struct PARAM_SSID *prAssociatedSsid; |
| |
| DEBUGFUNC("wlanoidQuerySsid"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_SSID); |
| |
| /* Check for query buffer length */ |
| if (u4QueryBufferLen < *pu4QueryInfoLen) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prAssociatedSsid = (struct PARAM_SSID *) pvQueryBuffer; |
| |
| kalMemZero(prAssociatedSsid->aucSsid, |
| sizeof(prAssociatedSsid->aucSsid)); |
| |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) { |
| prAssociatedSsid->u4SsidLen = |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen; |
| |
| if (prAssociatedSsid->u4SsidLen) { |
| kalMemCopy(prAssociatedSsid->aucSsid, |
| prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, |
| prAssociatedSsid->u4SsidLen); |
| } |
| } else { |
| prAssociatedSsid->u4SsidLen = 0; |
| |
| DBGLOG(REQ, TRACE, "Null SSID\n"); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQuerySsid */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current 802.11 network type. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryInfrastructureMode(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| DEBUGFUNC("wlanoidQueryInfrastructureMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_OP_MODE); |
| |
| if (u4QueryBufferLen < sizeof(enum ENUM_PARAM_OP_MODE)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *(enum ENUM_PARAM_OP_MODE *) pvQueryBuffer = |
| prAdapter->rWifiVar.rConnSettings.eOPMode; |
| |
| /* |
| ** According to OID_802_11_INFRASTRUCTURE_MODE |
| ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE, |
| ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned. |
| */ |
| #if DBG |
| switch (*(enum ENUM_PARAM_OP_MODE *) pvQueryBuffer) { |
| case NET_TYPE_IBSS: |
| DBGLOG(REQ, INFO, "IBSS mode\n"); |
| break; |
| case NET_TYPE_INFRA: |
| DBGLOG(REQ, INFO, "Infrastructure mode\n"); |
| break; |
| default: |
| DBGLOG(REQ, INFO, "Automatic mode\n"); |
| } |
| #endif |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryInfrastructureMode */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set mode to infrastructure or |
| * IBSS, or automatic switch between the two. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid |
| * length of the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetInfrastructureMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| enum ENUM_PARAM_OP_MODE eOpMode; |
| /* P_WLAN_TABLE_T prWlanTable; */ |
| #if CFG_SUPPORT_802_11W |
| /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */ |
| #endif |
| /* P_BSS_INFO_T prBssInfo; */ |
| /* UINT_8 i; */ |
| |
| DEBUGFUNC("wlanoidSetInfrastructureMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| if (u4SetBufferLen < sizeof(enum ENUM_PARAM_OP_MODE)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| *pu4SetInfoLen = sizeof(enum ENUM_PARAM_OP_MODE); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| eOpMode = *(enum ENUM_PARAM_OP_MODE *) pvSetBuffer; |
| /* Verify the new infrastructure mode. */ |
| if (eOpMode >= NET_TYPE_NUM) { |
| DBGLOG(REQ, TRACE, "Invalid mode value %d\n", eOpMode); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| /* check if possible to switch to AdHoc mode */ |
| if (eOpMode == NET_TYPE_IBSS |
| || eOpMode == NET_TYPE_DEDICATED_IBSS) { |
| if (cnmAisIbssIsPermitted(prAdapter) == FALSE) { |
| DBGLOG(REQ, TRACE, "Mode value %d unallowed\n", |
| eOpMode); |
| return WLAN_STATUS_FAILURE; |
| } |
| } |
| |
| /* Save the new infrastructure mode setting. */ |
| prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode; |
| |
| prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; |
| #if CFG_SUPPORT_WAPI |
| prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; |
| kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42); |
| #endif |
| |
| #if CFG_SUPPORT_802_11W |
| prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = |
| FALSE; |
| prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = |
| FALSE; |
| #endif |
| |
| #if CFG_SUPPORT_WPS2 |
| kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200); |
| prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; |
| #endif |
| |
| #if 0 /* STA record remove at AIS_ABORT nicUpdateBss and DISCONNECT */ |
| for (i = 0; i < prAdapter->ucHwBssIdNum; i++) { |
| prBssInfo = prAdapter->aprBssInfo[i]; |
| if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) |
| cnmStaFreeAllStaByNetwork(prAdapter, |
| prBssInfo->ucBssIndex, 0); |
| } |
| #endif |
| |
| /* Clean up the Tx key flag */ |
| if (prAdapter->prAisBssInfo != NULL) { |
| prAdapter->prAisBssInfo->fgBcDefaultKeyExist = FALSE; |
| prAdapter->prAisBssInfo->ucBcDefaultKeyIdx = 0xFF; |
| } |
| |
| /* prWlanTable = prAdapter->rWifiVar.arWtbl; */ |
| /* prWlanTable[prAdapter->prAisBssInfo->ucBMCWlanIndex].ucKeyId = 0; */ |
| |
| #if DBG |
| DBGLOG(RSN, TRACE, "wlanoidSetInfrastructureMode\n"); |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_INFRASTRUCTURE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, nicOidCmdTimeoutCommon, |
| 0, NULL, pvSetBuffer, u4SetBufferLen); |
| } /* wlanoidSetInfrastructureMode */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current 802.11 authentication |
| * mode. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryAuthMode(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| DEBUGFUNC("wlanoidQueryAuthMode"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_AUTH_MODE); |
| |
| if (u4QueryBufferLen < sizeof(enum ENUM_PARAM_AUTH_MODE)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| *(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer = |
| prAdapter->rWifiVar.rConnSettings.eAuthMode; |
| |
| #if DBG |
| switch (*(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer) { |
| case AUTH_MODE_OPEN: |
| DBGLOG(REQ, INFO, "Current auth mode: Open\n"); |
| break; |
| |
| case AUTH_MODE_SHARED: |
| DBGLOG(REQ, INFO, "Current auth mode: Shared\n"); |
| break; |
| |
| case AUTH_MODE_AUTO_SWITCH: |
| DBGLOG(REQ, INFO, "Current auth mode: Auto-switch\n"); |
| break; |
| |
| case AUTH_MODE_WPA: |
| DBGLOG(REQ, INFO, "Current auth mode: WPA\n"); |
| break; |
| |
| case AUTH_MODE_WPA_PSK: |
| DBGLOG(REQ, INFO, "Current auth mode: WPA PSK\n"); |
| break; |
| |
| case AUTH_MODE_WPA_NONE: |
| DBGLOG(REQ, INFO, "Current auth mode: WPA None\n"); |
| break; |
| |
| case AUTH_MODE_WPA2: |
| DBGLOG(REQ, INFO, "Current auth mode: WPA2\n"); |
| break; |
| |
| case AUTH_MODE_WPA2_PSK: |
| DBGLOG(REQ, INFO, "Current auth mode: WPA2 PSK\n"); |
| break; |
| |
| #if CFG_SUPPORT_CFG80211_AUTH |
| case AUTH_MODE_WPA2_SAE: |
| DBGLOG(REQ, INFO, "Current auth mode: SAE\n"); |
| break; |
| #endif |
| |
| default: |
| DBGLOG(REQ, INFO, "Current auth mode: %d\n", |
| *(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer); |
| break; |
| } |
| #endif |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryAuthMode */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the IEEE 802.11 authentication mode |
| * to the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_NOT_ACCEPTED |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetAuthMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| /* UINT_32 i, u4AkmSuite; */ |
| /* P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; */ |
| |
| DEBUGFUNC("wlanoidSetAuthMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| *pu4SetInfoLen = sizeof(enum ENUM_PARAM_AUTH_MODE); |
| |
| if (u4SetBufferLen < sizeof(enum ENUM_PARAM_AUTH_MODE)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| /* RF Test */ |
| /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ |
| /* return WLAN_STATUS_SUCCESS; */ |
| /* } */ |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| /* Check if the new authentication mode is valid. */ |
| if (*(enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer >= |
| AUTH_MODE_NUM) { |
| DBGLOG(REQ, TRACE, "Invalid auth mode %d\n", |
| *(enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| switch (*(enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer) { |
| case AUTH_MODE_WPA: |
| case AUTH_MODE_WPA_PSK: |
| case AUTH_MODE_WPA2: |
| case AUTH_MODE_WPA2_PSK: |
| case AUTH_MODE_WPA2_FT: |
| case AUTH_MODE_WPA2_FT_PSK: |
| /* infrastructure mode only */ |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode != |
| NET_TYPE_INFRA) |
| return WLAN_STATUS_NOT_ACCEPTED; |
| break; |
| |
| case AUTH_MODE_WPA_NONE: |
| /* ad hoc mode only */ |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode != |
| NET_TYPE_IBSS) |
| return WLAN_STATUS_NOT_ACCEPTED; |
| break; |
| |
| default: |
| break; |
| } |
| |
| /* Save the new authentication mode. */ |
| prAdapter->rWifiVar.rConnSettings.eAuthMode = * |
| (enum ENUM_PARAM_AUTH_MODE *) pvSetBuffer; |
| |
| #if 1 /* DBG */ |
| switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { |
| case AUTH_MODE_OPEN: |
| DBGLOG(RSN, TRACE, "New auth mode: open\n"); |
| break; |
| |
| case AUTH_MODE_SHARED: |
| DBGLOG(RSN, TRACE, "New auth mode: shared\n"); |
| break; |
| |
| case AUTH_MODE_AUTO_SWITCH: |
| DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n"); |
| break; |
| |
| case AUTH_MODE_WPA: |
| DBGLOG(RSN, TRACE, "New auth mode: WPA\n"); |
| break; |
| |
| case AUTH_MODE_WPA_PSK: |
| DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n"); |
| break; |
| |
| case AUTH_MODE_WPA_NONE: |
| DBGLOG(RSN, TRACE, "New auth mode: WPA None\n"); |
| break; |
| |
| case AUTH_MODE_WPA2: |
| DBGLOG(RSN, TRACE, "New auth mode: WPA2\n"); |
| break; |
| |
| case AUTH_MODE_WPA2_PSK: |
| DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n"); |
| break; |
| |
| #if CFG_SUPPORT_SAE |
| case AUTH_MODE_WPA2_SAE: |
| DBGLOG(RSN, INFO, "New auth mode: SAE\n"); |
| break; |
| #endif |
| |
| default: |
| DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", |
| prAdapter->rWifiVar.rConnSettings.eAuthMode); |
| } |
| #endif |
| |
| #if 0 |
| if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= |
| AUTH_MODE_WPA) { |
| switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { |
| case AUTH_MODE_WPA: |
| u4AkmSuite = WPA_AKM_SUITE_802_1X; |
| break; |
| |
| case AUTH_MODE_WPA_PSK: |
| u4AkmSuite = WPA_AKM_SUITE_PSK; |
| break; |
| |
| case AUTH_MODE_WPA_NONE: |
| u4AkmSuite = WPA_AKM_SUITE_NONE; |
| break; |
| |
| case AUTH_MODE_WPA2: |
| u4AkmSuite = RSN_AKM_SUITE_802_1X; |
| break; |
| |
| case AUTH_MODE_WPA2_PSK: |
| u4AkmSuite = RSN_AKM_SUITE_PSK; |
| break; |
| |
| default: |
| u4AkmSuite = 0; |
| } |
| } else { |
| u4AkmSuite = 0; |
| } |
| |
| /* Enable the specific AKM suite only. */ |
| for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { |
| prEntry = &prAdapter->rMib |
| .dot11RSNAConfigAuthenticationSuitesTable[i]; |
| |
| if (prEntry->dot11RSNAConfigAuthenticationSuite == |
| u4AkmSuite) |
| prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = |
| TRUE; |
| else |
| prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = |
| FALSE; |
| #if CFG_SUPPORT_802_11W |
| if (kalGetMfpSetting(prAdapter->prGlueInfo) != |
| RSN_AUTH_MFP_DISABLED) { |
| if ((u4AkmSuite == RSN_AKM_SUITE_PSK) && |
| prEntry->dot11RSNAConfigAuthenticationSuite == |
| RSN_AKM_SUITE_PSK_SHA256) { |
| DBGLOG(RSN, TRACE, |
| "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n"); |
| prEntry-> |
| dot11RSNAConfigAuthenticationSuiteEnabled = |
| TRUE; |
| |
| } |
| if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) && |
| prEntry->dot11RSNAConfigAuthenticationSuite == |
| RSN_AKM_SUITE_802_1X_SHA256) { |
| DBGLOG(RSN, TRACE, |
| "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n"); |
| prEntry-> |
| dot11RSNAConfigAuthenticationSuiteEnabled = |
| TRUE; |
| } |
| } |
| #endif |
| } |
| #endif |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidSetAuthMode */ |
| |
| #if 0 |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current 802.11 privacy filter |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryPrivacyFilter(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| DEBUGFUNC("wlanoidQueryPrivacyFilter"); |
| |
| ASSERT(prAdapter); |
| |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(enum ENUM_PARAM_PRIVACY_FILTER); |
| |
| if (u4QueryBufferLen < sizeof(enum |
| ENUM_PARAM_PRIVACY_FILTER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| *(enum ENUM_PARAM_PRIVACY_FILTER *) pvQueryBuffer = |
| prAdapter->rWlanInfo.ePrivacyFilter; |
| |
| #if DBG |
| switch (*(enum ENUM_PARAM_PRIVACY_FILTER *) pvQueryBuffer) { |
| case PRIVACY_FILTER_ACCEPT_ALL: |
| DBGLOG(REQ, INFO, "Current privacy mode: open mode\n"); |
| break; |
| |
| case PRIVACY_FILTER_8021xWEP: |
| DBGLOG(REQ, INFO, "Current privacy mode: filtering mode\n"); |
| break; |
| |
| default: |
| DBGLOG(REQ, INFO, "Current auth mode: %d\n", |
| *(enum ENUM_PARAM_AUTH_MODE *) pvQueryBuffer); |
| } |
| #endif |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryPrivacyFilter */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the IEEE 802.11 privacy filter |
| * to the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_NOT_ACCEPTED |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetPrivacyFilter(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| |
| DEBUGFUNC("wlanoidSetPrivacyFilter"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| *pu4SetInfoLen = sizeof(enum ENUM_PARAM_PRIVACY_FILTER); |
| |
| if (u4SetBufferLen < sizeof(enum ENUM_PARAM_PRIVACY_FILTER)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| /* Check if the new authentication mode is valid. */ |
| if (*(enum ENUM_PARAM_PRIVACY_FILTER *) pvSetBuffer >= |
| PRIVACY_FILTER_NUM) { |
| DBGLOG(REQ, TRACE, "Invalid privacy filter %d\n", |
| *(enum ENUM_PARAM_PRIVACY_FILTER *) pvSetBuffer); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| switch (*(enum ENUM_PARAM_PRIVACY_FILTER *) pvSetBuffer) { |
| default: |
| break; |
| } |
| |
| /* Save the new authentication mode. */ |
| prAdapter->rWlanInfo.ePrivacyFilter = |
| *(enum ENUM_PARAM_PRIVACY_FILTER) pvSetBuffer; |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidSetPrivacyFilter */ |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to reload the available default settings for |
| * the specified type field. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetReloadDefaults(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| enum ENUM_PARAM_NETWORK_TYPE eNetworkType; |
| uint32_t u4Len; |
| uint8_t ucCmdSeqNum; |
| |
| DEBUGFUNC("wlanoidSetReloadDefaults"); |
| |
| ASSERT(prAdapter); |
| |
| ASSERT(pu4SetInfoLen); |
| *pu4SetInfoLen = sizeof(enum ENUM_RELOAD_DEFAULTS); |
| |
| /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ |
| /* return WLAN_STATUS_SUCCESS; */ |
| /* } */ |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| ASSERT(pvSetBuffer); |
| /* Verify the available reload options and reload the settings. */ |
| switch (*(enum ENUM_RELOAD_DEFAULTS *) pvSetBuffer) { |
| case ENUM_RELOAD_WEP_KEYS: |
| /* Reload available default WEP keys from the permanent |
| * storage. |
| */ |
| prAdapter->rWifiVar.rConnSettings.eAuthMode = |
| AUTH_MODE_OPEN; |
| /* ENUM_ENCRYPTION_DISABLED; */ |
| prAdapter->rWifiVar.rConnSettings.eEncStatus = |
| ENUM_ENCRYPTION1_KEY_ABSENT; |
| { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| struct CMD_802_11_KEY *prCmdKey; |
| uint8_t aucBCAddr[] = BC_MAC_ADDR; |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + sizeof(struct CMD_802_11_KEY))); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, |
| "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| |
| /* compose CMD_802_11_KEY cmd pkt */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + |
| sizeof(struct CMD_802_11_KEY); |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| prCmdInfo->fgIsOid = g_fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = |
| sizeof(struct PARAM_REMOVE_KEY); |
| prCmdInfo->pvInformationBuffer = pvSetBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetBufferLen; |
| |
| /* Setup WIFI_CMD_T */ |
| prWifiCmd = |
| (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| prCmdKey = |
| (struct CMD_802_11_KEY *)(prWifiCmd->aucBuffer); |
| |
| kalMemZero((uint8_t *) prCmdKey, |
| sizeof(struct CMD_802_11_KEY)); |
| |
| prCmdKey->ucAddRemove = 0; /* Remove */ |
| prCmdKey->ucKeyId = |
| 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & |
| * 0x000000ff); |
| */ |
| kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, |
| MAC_ADDR_LEN); |
| |
| ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); |
| |
| prCmdKey->ucKeyType = 0; |
| |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| } |
| |
| break; |
| |
| default: |
| DBGLOG(REQ, TRACE, "Invalid reload option %d\n", |
| *(enum ENUM_RELOAD_DEFAULTS *) pvSetBuffer); |
| rStatus = WLAN_STATUS_INVALID_DATA; |
| } |
| |
| /* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */ |
| eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE; |
| wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, |
| sizeof(eNetworkType), &u4Len); |
| |
| return rStatus; |
| } /* wlanoidSetReloadDefaults */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set a WEP key to the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| #ifdef LINUX |
| uint8_t keyBuffer[sizeof(struct PARAM_KEY) + |
| 16 /* LEGACY_KEY_MAX_LEN */]; |
| uint8_t aucBCAddr[] = BC_MAC_ADDR; |
| #endif |
| uint32_t |
| wlanoidSetAddWep(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| #ifndef LINUX |
| uint8_t keyBuffer[sizeof(struct PARAM_KEY) + |
| 16 /* LEGACY_KEY_MAX_LEN */]; |
| uint8_t aucBCAddr[] = BC_MAC_ADDR; |
| #endif |
| struct PARAM_WEP *prNewWepKey; |
| struct PARAM_KEY *prParamKey = (struct PARAM_KEY *) |
| keyBuffer; |
| uint32_t u4KeyId, u4SetLen; |
| |
| DEBUGFUNC("wlanoidSetAddWep"); |
| |
| ASSERT(prAdapter); |
| |
| *pu4SetInfoLen = OFFSET_OF(struct PARAM_WEP, |
| aucKeyMaterial); |
| |
| if (u4SetBufferLen < OFFSET_OF(struct PARAM_WEP, |
| aucKeyMaterial)) { |
| ASSERT(pu4SetInfoLen); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| prNewWepKey = (struct PARAM_WEP *) pvSetBuffer; |
| |
| /* Verify the total buffer for minimum length. */ |
| if (u4SetBufferLen < OFFSET_OF(struct PARAM_WEP, |
| aucKeyMaterial) + prNewWepKey->u4KeyLength) { |
| DBGLOG(REQ, WARN, |
| "Invalid total buffer length (%d) than minimum length (%d)\n", |
| (uint8_t) u4SetBufferLen, |
| (uint8_t) OFFSET_OF(struct PARAM_WEP, aucKeyMaterial)); |
| |
| *pu4SetInfoLen = OFFSET_OF(struct PARAM_WEP, |
| aucKeyMaterial); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| /* Verify the key structure length. */ |
| if (prNewWepKey->u4Length > u4SetBufferLen) { |
| DBGLOG(REQ, WARN, |
| "Invalid key structure length (%d) greater than total buffer length (%d)\n", |
| (uint8_t) prNewWepKey->u4Length, |
| (uint8_t) u4SetBufferLen); |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| /* Verify the key material length for maximum key material length:16 */ |
| if (prNewWepKey->u4KeyLength > |
| 16 /* LEGACY_KEY_MAX_LEN */) { |
| DBGLOG(REQ, WARN, |
| "Invalid key material length (%d) greater than maximum key material length (16)\n", |
| (uint8_t) prNewWepKey->u4KeyLength); |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, |
| 29) /* WEP_KEY_ID_FIELD */; |
| |
| /* Verify whether key index is valid or not, current version |
| * driver support only 4 global WEP keys setting by this OID |
| */ |
| if (u4KeyId > MAX_KEY_NUM - 1) { |
| DBGLOG(REQ, ERROR, "Error, invalid WEP key ID: %d\n", |
| (uint8_t) u4KeyId); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| prParamKey->u4KeyIndex = u4KeyId; |
| |
| /* Transmit key */ |
| if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY) |
| prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY; |
| |
| /* Per client key */ |
| if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY) |
| prParamKey->u4KeyIndex |= IS_UNICAST_KEY; |
| |
| prParamKey->u4KeyLength = prNewWepKey->u4KeyLength; |
| |
| kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN); |
| |
| kalMemCopy(prParamKey->aucKeyMaterial, |
| prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength); |
| |
| prParamKey->ucBssIdx = prAdapter->prAisBssInfo->ucBssIndex; |
| |
| if (prParamKey->u4KeyLength == WEP_40_LEN) |
| prParamKey->ucCipher = CIPHER_SUITE_WEP40; |
| else if (prParamKey->u4KeyLength == WEP_104_LEN) |
| prParamKey->ucCipher = CIPHER_SUITE_WEP104; |
| else if (prParamKey->u4KeyLength == WEP_128_LEN) |
| prParamKey->ucCipher = CIPHER_SUITE_WEP128; |
| |
| prParamKey->u4Length = OFFSET_OF( |
| struct PARAM_KEY, aucKeyMaterial) + prNewWepKey->u4KeyLength; |
| |
| wlanoidSetAddKey(prAdapter, (void *) prParamKey, |
| prParamKey->u4Length, &u4SetLen); |
| |
| return WLAN_STATUS_PENDING; |
| } /* wlanoidSetAddWep */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to request the driver to remove the WEP key |
| * at the specified key index. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetRemoveWep(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| uint32_t u4KeyId, u4SetLen; |
| struct PARAM_REMOVE_KEY rRemoveKey; |
| uint8_t aucBCAddr[] = BC_MAC_ADDR; |
| |
| DEBUGFUNC("wlanoidSetRemoveWep"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| u4KeyId = *(uint32_t *) pvSetBuffer; |
| |
| /* Dump PARAM_WEP content. */ |
| DBGLOG(REQ, INFO, "Set: Dump PARAM_KEY_INDEX content\n"); |
| DBGLOG(REQ, INFO, "Index : %u\n", u4KeyId); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| if (u4KeyId & IS_TRANSMIT_KEY) { |
| /* Bit 31 should not be set */ |
| DBGLOG(REQ, ERROR, "Invalid WEP key index: %u\n", u4KeyId); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| u4KeyId &= BITS(0, 7); |
| |
| /* Verify whether key index is valid or not. Current version |
| * driver support only 4 global WEP keys. |
| */ |
| if (u4KeyId > MAX_KEY_NUM - 1) { |
| DBGLOG(REQ, ERROR, "invalid WEP key ID %u\n", u4KeyId); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| kalMemZero(&rRemoveKey, sizeof(struct PARAM_REMOVE_KEY)); |
| rRemoveKey.u4Length = sizeof(struct PARAM_REMOVE_KEY); |
| rRemoveKey.u4KeyIndex = *(uint32_t *) pvSetBuffer; |
| |
| kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN); |
| |
| wlanoidSetRemoveKey(prAdapter, (void *)&rRemoveKey, |
| sizeof(struct PARAM_REMOVE_KEY), &u4SetLen); |
| |
| return WLAN_STATUS_PENDING; |
| } /* wlanoidSetRemoveWep */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set a key to the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * |
| * \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetAddKey(IN struct ADAPTER *prAdapter, IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, OUT uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| struct PARAM_KEY *prNewKey; |
| struct CMD_802_11_KEY *prCmdKey; |
| uint8_t ucCmdSeqNum; |
| struct BSS_INFO *prBssInfo; |
| struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; |
| struct STA_RECORD *prStaRec = NULL; |
| u_int8_t fgNoHandshakeSec = FALSE; |
| #if CFG_SUPPORT_TDLS |
| struct STA_RECORD *prTmpStaRec; |
| #endif |
| DEBUGFUNC("wlanoidSetAddKey"); |
| DBGLOG(REQ, LOUD, "\n"); |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| DBGLOG(RSN, TRACE, "wlanoidSetAddKey\n"); |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(RSN, WARN, |
| "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| prNewKey = (struct PARAM_KEY *) pvSetBuffer; |
| /* Verify the key structure length. */ |
| if (prNewKey->u4Length > u4SetBufferLen) { |
| DBGLOG(RSN, WARN, |
| "Invalid key structure length (%d) greater than total buffer length (%d)\n", |
| (uint8_t) prNewKey->u4Length, (uint8_t) u4SetBufferLen); |
| *pu4SetInfoLen = u4SetBufferLen; |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| /* Verify the key material length for key material buffer */ |
| if (prNewKey->u4KeyLength > prNewKey->u4Length - |
| OFFSET_OF(struct PARAM_KEY, aucKeyMaterial)) { |
| DBGLOG(RSN, WARN, "Invalid key material length (%d)\n", |
| (uint8_t) prNewKey->u4KeyLength); |
| *pu4SetInfoLen = u4SetBufferLen; |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| /* Exception check */ |
| if (prNewKey->u4KeyIndex & 0x0fffff00) |
| return WLAN_STATUS_INVALID_DATA; |
| /* Exception check, pairwise key must with transmit bit enabled */ |
| if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) |
| return WLAN_STATUS_INVALID_DATA; |
| if (!(prNewKey->u4KeyLength == WEP_40_LEN || |
| prNewKey->u4KeyLength == WEP_104_LEN || |
| prNewKey->u4KeyLength == CCMP_KEY_LEN || |
| prNewKey->u4KeyLength == TKIP_KEY_LEN)) { |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| /* Exception check, pairwise key must with transmit bit enabled */ |
| if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { |
| if (/* ((prNewKey->u4KeyIndex & 0xff) != 0) || */ |
| ((prNewKey->arBSSID[0] == 0xff) && |
| (prNewKey->arBSSID[1] == 0xff) && |
| (prNewKey->arBSSID[2] == 0xff) && |
| (prNewKey->arBSSID[3] == 0xff) && |
| (prNewKey->arBSSID[4] == 0xff) && |
| (prNewKey->arBSSID[5] == 0xff))) { |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| } |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| /* Dump PARAM_KEY content. */ |
| DBGLOG(RSN, TRACE, "Set: Dump PARAM_KEY content, Len: 0x%08x, BSSID: " |
| MACSTR |
| ", KeyIdx: 0x%08x, KeyLen: 0x%08x, Cipher: %d, Material:\n", |
| prNewKey->u4Length, MAC2STR(prNewKey->arBSSID), |
| prNewKey->u4KeyIndex, prNewKey->u4KeyLength, |
| prNewKey->ucCipher); |
| DBGLOG_MEM8(RSN, TRACE, prNewKey->aucKeyMaterial, |
| prNewKey->u4KeyLength); |
| DBGLOG(RSN, TRACE, "Key RSC:\n"); |
| DBGLOG_MEM8(RSN, TRACE, &prNewKey->rKeyRSC, sizeof(uint64_t)); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prNewKey->ucBssIdx); |
| if (!prBssInfo) { |
| DBGLOG(REQ, INFO, "BSS Info not exist !!\n"); |
| return WLAN_STATUS_SUCCESS; |
| } |
| /* Tx Rx KeyType addr |
| * STA, GC: |
| * case1: 1 1 0 BC addr (no sta record of AP at this moment) WEP, |
| * notice: tx at default key setting WEP key now save to BSS_INFO |
| * case2: 0 1 0 BSSID (sta record of AP) RSN BC key |
| * case3: 1 1 1 AP addr (sta record of AP) RSN STA key |
| * |
| * GO: |
| * case1: 1 1 0 BSSID (no sta record) WEP -- Not support |
| * case2: 1 0 0 BSSID (no sta record) RSN BC key |
| * case3: 1 1 1 STA addr STA key |
| */ |
| if (prNewKey->ucCipher == CIPHER_SUITE_WEP40 || |
| prNewKey->ucCipher == CIPHER_SUITE_WEP104 || |
| prNewKey->ucCipher == CIPHER_SUITE_WEP128) { |
| /* check if the key no need handshake, then save to bss wep key |
| * for global usage |
| */ |
| fgNoHandshakeSec = TRUE; |
| } |
| if (fgNoHandshakeSec) { |
| #if DBG |
| if (IS_BSS_AIS(prBssInfo)) { |
| if (prAdapter->rWifiVar.rConnSettings.eAuthMode |
| >= AUTH_MODE_WPA && |
| prAdapter->rWifiVar.rConnSettings.eAuthMode != |
| AUTH_MODE_WPA_NONE) { |
| DBGLOG(RSN, WARN, |
| "Set wep at not open/shared setting\n"); |
| return WLAN_STATUS_SUCCESS; |
| } |
| } |
| #endif |
| } |
| if ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) { |
| prStaRec = cnmGetStaRecByAddress(prAdapter, |
| prBssInfo->ucBssIndex, prNewKey->arBSSID); |
| if (!prStaRec) { /* Already disconnected ? */ |
| DBGLOG(REQ, INFO, |
| "[wlan] Not set the peer key while disconnect\n"); |
| return WLAN_STATUS_SUCCESS; |
| } |
| #if CFG_SUPPORT_FRAG_ATTACK_DETECTION |
| /* clear fragment cache when rekey */ |
| nicRxClearFrag(prAdapter, prStaRec); |
| #endif |
| } |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + sizeof(struct CMD_802_11_KEY))); |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| DBGLOG(RSN, TRACE, "ucCmdSeqNum = %d\n", ucCmdSeqNum); |
| /* compose CMD_802_11_KEY cmd pkt */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(struct CMD_802_11_KEY); |
| #if CFG_SUPPORT_REPLAY_DETECTION |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetAddKey; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutSetAddKey; |
| #else |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| #endif |
| prCmdInfo->fgIsOid = g_fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = u4SetBufferLen; |
| prCmdInfo->pvInformationBuffer = pvSetBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetBufferLen; |
| /* Setup WIFI_CMD_T */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| prCmdKey = (struct CMD_802_11_KEY *) (prWifiCmd->aucBuffer); |
| kalMemZero(prCmdKey, sizeof(struct CMD_802_11_KEY)); |
| prCmdKey->ucAddRemove = 1; /* Add */ |
| prCmdKey->ucTxKey = |
| ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) |
| ? 1 : 0; |
| prCmdKey->ucKeyType = |
| ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) |
| ? 1 : 0; |
| prCmdKey->ucIsAuthenticator = |
| ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) |
| ? 1 : 0; |
| /* Copy the addr of the key */ |
| if ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) { |
| if (prStaRec) { |
| /* Overwrite the fgNoHandshakeSec in case */ |
| fgNoHandshakeSec = FALSE; /* Legacy 802.1x wep case ? */ |
| /* ASSERT(FALSE); */ |
| } |
| } else { |
| if (!IS_BSS_ACTIVE(prBssInfo)) |
| DBGLOG(REQ, INFO, |
| "[wlan] BSS info (%d) not active yet!", |
| prNewKey->ucBssIdx); |
| } |
| prCmdKey->ucBssIdx = prBssInfo->ucBssIndex; |
| prCmdKey->ucKeyId = (uint8_t) (prNewKey->u4KeyIndex & 0xff); |
| /* Note: the key length may not correct for WPA-None */ |
| prCmdKey->ucKeyLen = (uint8_t) prNewKey->u4KeyLength; |
| kalMemCopy(prCmdKey->aucKeyMaterial, |
| (uint8_t *)prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen); |
| if (prNewKey->ucCipher) { |
| prCmdKey->ucAlgorithmId = prNewKey->ucCipher; |
| if (IS_BSS_AIS(prBssInfo)) { |
| #if CFG_SUPPORT_802_11W |
| if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP) { |
| if (prCmdKey->ucKeyId >= 4) { |
| struct AIS_SPECIFIC_BSS_INFO |
| *prAisSpecBssInfo; |
| |
| prAisSpecBssInfo = |
| &prAdapter->rWifiVar |
| .rAisSpecificBssInfo; |
| prAisSpecBssInfo->fgBipKeyInstalled = |
| TRUE; |
| |
| DBGLOG(RSN, INFO, |
| "Change BIP BC keyId from %d to 3\n", |
| prCmdKey->ucKeyId); |
| /* Set IGTK WTBL keyid 3 for WTBL to correcly search GTK */ |
| prCmdKey->ucKeyId = 3; |
| } |
| } |
| #endif |
| if ((prCmdKey->ucAlgorithmId == CIPHER_SUITE_CCMP) && |
| rsnCheckPmkidCandicate(prAdapter)) { |
| DBGLOG(RSN, TRACE, |
| "Add key: Prepare a timer to indicate candidate PMKID Candidate\n"); |
| cnmTimerStopTimer(prAdapter, |
| &prAisSpecBssInfo->rPreauthenticationTimer); |
| cnmTimerStartTimer(prAdapter, |
| &prAisSpecBssInfo->rPreauthenticationTimer, |
| SEC_TO_MSEC( |
| WAIT_TIME_IND_PMKID_CANDICATE_SEC)); |
| } |
| |
| if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_TKIP) { |
| /* Todo:: Support AP mode defragment */ |
| /* for pairwise key only */ |
| if ((prNewKey->u4KeyIndex & BITS(30, 31)) == |
| ((IS_UNICAST_KEY) | (IS_TRANSMIT_KEY))) { |
| kalMemCopy( |
| prAdapter->rWifiVar |
| .rAisSpecificBssInfo.aucRxMicKey, |
| &prCmdKey->aucKeyMaterial[16], |
| MIC_KEY_LEN); |
| kalMemCopy( |
| prAdapter->rWifiVar |
| .rAisSpecificBssInfo.aucTxMicKey, |
| &prCmdKey->aucKeyMaterial[24], |
| MIC_KEY_LEN); |
| } |
| } |
| } else { |
| #if CFG_SUPPORT_802_11W |
| /* AP PMF */ |
| if ((prCmdKey->ucKeyId >= 4 && prCmdKey->ucKeyId <= 5) |
| && (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP)) { |
| DBGLOG(RSN, INFO, "AP mode set BIP\n"); |
| prBssInfo->rApPmfCfg.fgBipKeyInstalled = TRUE; |
| } |
| #endif |
| } |
| } else { /* Legacy windows NDIS no cipher info */ |
| #if 0 |
| if (prNewKey->u4KeyLength == 5) { |
| prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40; |
| } else if (prNewKey->u4KeyLength == 13) { |
| prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104; |
| } else if (prNewKey->u4KeyLength == 16) { |
| if (prAdapter->rWifiVar.rConnSettings.eAuthMode < |
| AUTH_MODE_WPA) |
| prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128; |
| else { |
| if (IS_BSS_AIS(prBssInfo)) { |
| #if CFG_SUPPORT_802_11W |
| if (prCmdKey->ucKeyId >= 4) { |
| struct AIS_SPECIFIC_BSS_INFO |
| *prAisSpecBssInfo; |
| |
| prCmdKey->ucAlgorithmId = |
| CIPHER_SUITE_BIP; |
| prAisSpecBssInfo = |
| &prAdapter->rWifiVar |
| .rAisSpecificBssInfo; |
| prAisSpecBssInfo |
| ->fgBipKeyInstalled = |
| TRUE; |
| } else |
| #endif |
| { |
| prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; |
| if (rsnCheckPmkidCandicate(prAdapter)) { |
| DBGLOG(RSN, TRACE, |
| "Add key: Prepare a timer to indicate candidate PMKID\n"); |
| cnmTimerStopTimer(prAdapter, |
| &prAisSpecBssInfo |
| ->rPreauthenticationTimer); |
| cnmTimerStartTimer(prAdapter, |
| &prAisSpecBssInfo |
| ->rPreauthenticationTimer, |
| SEC_TO_MSEC( |
| WAIT_TIME_IND_PMKID_CANDICATE_SEC)); |
| } |
| } |
| } |
| } |
| } else if (prNewKey->u4KeyLength == 32) { |
| if (IS_BSS_AIS(prBssInfo)) { |
| if (prAdapter->rWifiVar.rConnSettings.eAuthMode |
| == AUTH_MODE_WPA_NONE) { |
| if (prAdapter->rWifiVar.rConnSettings |
| .eEncStatus == |
| ENUM_ENCRYPTION2_ENABLED) { |
| prCmdKey->ucAlgorithmId = |
| CIPHER_SUITE_TKIP; |
| } else if (prAdapter->rWifiVar |
| .rConnSettings.eEncStatus == |
| ENUM_ENCRYPTION3_ENABLED) { |
| prCmdKey->ucAlgorithmId = |
| CIPHER_SUITE_CCMP; |
| prCmdKey->ucKeyLen = |
| CCMP_KEY_LEN; |
| } |
| } else { |
| prCmdKey->ucAlgorithmId = |
| CIPHER_SUITE_TKIP; |
| kalMemCopy( |
| prAdapter->rWifiVar |
| .rAisSpecificBssInfo |
| .aucRxMicKey, |
| &prCmdKey->aucKeyMaterial[16], |
| MIC_KEY_LEN); |
| kalMemCopy( |
| prAdapter->rWifiVar |
| .rAisSpecificBssInfo |
| .aucTxMicKey, |
| &prCmdKey->aucKeyMaterial[24], |
| MIC_KEY_LEN); |
| if (0 /* Todo::GCMP & GCMP-BIP ? */) { |
| if (rsnCheckPmkidCandicate(prAdapter)) { |
| DBGLOG(RSN, TRACE, |
| "Add key: Prepare a timer to indicate candidate PMKID\n"); |
| cnmTimerStopTimer(prAdapter, |
| &prAisSpecBssInfo-> |
| rPreauthenticationTimer); |
| cnmTimerStartTimer(prAdapter, |
| &prAisSpecBssInfo-> |
| rPreauthenticationTimer, |
| SEC_TO_MSEC( |
| WAIT_TIME_IND_PMKID_CANDICATE_SEC)); |
| } |
| } else { |
| prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; |
| } |
| } |
| } |
| #endif |
| } |
| { |
| #if CFG_SUPPORT_TDLS |
| prTmpStaRec = cnmGetStaRecByAddress(prAdapter, |
| prBssInfo->ucBssIndex, prNewKey->arBSSID); |
| if (prTmpStaRec) { |
| if (IS_DLS_STA(prTmpStaRec)) { |
| prStaRec = prTmpStaRec; |
| |
| /*128 ,TODO GCMP 256 */ |
| prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; |
| |
| kalMemCopy(prCmdKey->aucPeerAddr, |
| prStaRec->aucMacAddr, MAC_ADDR_LEN); |
| } |
| } |
| #endif |
| |
| #if CFG_SUPPORT_802_11W |
| /* AP PMF */ |
| if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP) { |
| if (prCmdKey->ucIsAuthenticator) { |
| DBGLOG(RSN, INFO, |
| "Authenticator BIP bssid:%d\n", |
| prBssInfo->ucBssIndex); |
| |
| prCmdKey->ucWlanIndex = |
| secPrivacySeekForBcEntry(prAdapter, |
| prBssInfo->ucBssIndex, |
| prBssInfo->aucOwnMacAddr, |
| STA_REC_INDEX_NOT_FOUND, |
| prCmdKey->ucAlgorithmId, |
| prCmdKey->ucKeyId); |
| } else { |
| prCmdKey->ucWlanIndex = |
| secPrivacySeekForBcEntry(prAdapter, |
| prBssInfo->ucBssIndex, |
| prBssInfo->prStaRecOfAP->aucMacAddr, |
| prBssInfo->prStaRecOfAP->ucIndex, |
| prCmdKey->ucAlgorithmId, |
| prCmdKey->ucKeyId); |
| kalMemCopy(prCmdKey->aucPeerAddr, |
| prBssInfo->prStaRecOfAP->aucMacAddr, MAC_ADDR_LEN); |
| } |
| |
| DBGLOG(RSN, INFO, "BIP BC wtbl index:%d\n", |
| prCmdKey->ucWlanIndex); |
| } else |
| #endif |
| if (1) { |
| if (prStaRec) { |
| if (prCmdKey->ucKeyType) { /* RSN STA */ |
| struct WLAN_TABLE *prWtbl; |
| |
| prWtbl = prAdapter->rWifiVar.arWtbl; |
| prWtbl[prStaRec->ucWlanIndex].ucKeyId = |
| prCmdKey->ucKeyId; |
| prCmdKey->ucWlanIndex = |
| prStaRec->ucWlanIndex; |
| |
| /* wait for CMD Done ? */ |
| prStaRec->fgTransmitKeyExist = TRUE; |
| |
| kalMemCopy(prCmdKey->aucPeerAddr, |
| prNewKey->arBSSID, |
| MAC_ADDR_LEN); |
| #if CFG_SUPPORT_802_11W |
| /* AP PMF */ |
| DBGLOG(RSN, INFO, |
| "Assign client PMF flag = %d\n", |
| prStaRec->rPmfCfg.fgApplyPmf); |
| prCmdKey->ucMgmtProtection = |
| prStaRec->rPmfCfg.fgApplyPmf; |
| #endif |
| } else { |
| ASSERT(FALSE); |
| } |
| } else { /* Overwrite the old one for AP and STA WEP */ |
| if (prBssInfo->prStaRecOfAP) { |
| DBGLOG(RSN, INFO, "AP REC\n"); |
| prCmdKey->ucWlanIndex = |
| secPrivacySeekForBcEntry( |
| prAdapter, |
| prBssInfo->ucBssIndex, |
| prBssInfo->prStaRecOfAP |
| ->aucMacAddr, |
| prBssInfo->prStaRecOfAP |
| ->ucIndex, |
| prCmdKey->ucAlgorithmId, |
| prCmdKey->ucKeyId); |
| kalMemCopy(prCmdKey->aucPeerAddr, |
| prBssInfo->prStaRecOfAP |
| ->aucMacAddr, |
| MAC_ADDR_LEN); |
| } else { |
| DBGLOG(RSN, INFO, "!AP && !STA REC\n"); |
| prCmdKey->ucWlanIndex = |
| secPrivacySeekForBcEntry( |
| prAdapter, |
| prBssInfo->ucBssIndex, |
| prBssInfo->aucOwnMacAddr, |
| STA_REC_INDEX_NOT_FOUND, |
| prCmdKey->ucAlgorithmId, |
| prCmdKey->ucKeyId); |
| kalMemCopy(prCmdKey->aucPeerAddr, |
| prBssInfo->aucOwnMacAddr, |
| MAC_ADDR_LEN); |
| } |
| if (prCmdKey->ucKeyId >= MAX_KEY_NUM) { |
| DBGLOG(RSN, ERROR, |
| "prCmdKey->ucKeyId [%u] overrun\n", |
| prCmdKey->ucKeyId); |
| return WLAN_STATUS_FAILURE; |
| } |
| if (fgNoHandshakeSec) { |
| /* WEP: STA and AP */ |
| prBssInfo->wepkeyWlanIdx = |
| prCmdKey->ucWlanIndex; |
| prBssInfo->wepkeyUsed[ |
| prCmdKey->ucKeyId] = TRUE; |
| } else if (!prBssInfo->prStaRecOfAP) { |
| /* AP WPA/RSN */ |
| prBssInfo->ucBMCWlanIndexS[ |
| prCmdKey->ucKeyId] = |
| prCmdKey->ucWlanIndex; |
| prBssInfo->ucBMCWlanIndexSUsed[ |
| prCmdKey->ucKeyId] = TRUE; |
| } else { |
| /* STA WPA/RSN, should not have tx but |
| * no sta record |
| */ |
| prBssInfo->ucBMCWlanIndexS[ |
| prCmdKey->ucKeyId] = |
| prCmdKey->ucWlanIndex; |
| prBssInfo->ucBMCWlanIndexSUsed[ |
| prCmdKey->ucKeyId] = TRUE; |
| DBGLOG(RSN, INFO, |
| "BMCWlanIndex kid = %d, index = %d\n", |
| prCmdKey->ucKeyId, |
| prCmdKey->ucWlanIndex); |
| } |
| if (prCmdKey->ucTxKey) { /* */ |
| prBssInfo->fgBcDefaultKeyExist = TRUE; |
| prBssInfo->ucBcDefaultKeyIdx = |
| prCmdKey->ucKeyId; |
| } |
| } |
| } |
| } |
| #if 1 |
| DBGLOG(RSN, INFO, "Add key cmd to wlan index %d:", |
| prCmdKey->ucWlanIndex); |
| DBGLOG(RSN, INFO, "(BSS = %d) " MACSTR "\n", prCmdKey->ucBssIdx, |
| MAC2STR(prCmdKey->aucPeerAddr)); |
| DBGLOG(RSN, INFO, "Tx = %d type = %d Auth = %d\n", prCmdKey->ucTxKey, |
| prCmdKey->ucKeyType, |
| prCmdKey->ucIsAuthenticator); |
| DBGLOG(RSN, INFO, "cipher = %d keyid = %d keylen = %d\n", |
| prCmdKey->ucAlgorithmId, prCmdKey->ucKeyId, |
| prCmdKey->ucKeyLen); |
| DBGLOG_MEM8(RSN, INFO, prCmdKey->aucKeyMaterial, prCmdKey->ucKeyLen); |
| if (prCmdKey->ucKeyId < MAX_KEY_NUM) { |
| DBGLOG(RSN, INFO, "wepkeyUsed = %d\n", |
| prBssInfo->wepkeyUsed[prCmdKey->ucKeyId]); |
| DBGLOG(RSN, INFO, "wepkeyWlanIdx = %d:", |
| prBssInfo->wepkeyWlanIdx); |
| DBGLOG(RSN, INFO, "ucBMCWlanIndexSUsed = %d\n", |
| prBssInfo->ucBMCWlanIndexSUsed[prCmdKey->ucKeyId]); |
| DBGLOG(RSN, INFO, "ucBMCWlanIndexS = %d:", |
| prBssInfo->ucBMCWlanIndexS[prCmdKey->ucKeyId]); |
| } else |
| DBGLOG(RSN, WARN, "invalid prCmdKey->ucKeyId(%d)\n", |
| prCmdKey->ucKeyId); |
| #endif |
| prAdapter->rWifiVar.rAisSpecificBssInfo.ucKeyAlgorithmId = |
| prCmdKey->ucAlgorithmId; |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, (struct QUE_ENTRY *) prCmdInfo); |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| return WLAN_STATUS_PENDING; |
| } /* wlanoidSetAddKey */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to request the driver to remove the key at |
| * the specified key index. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetRemoveKey(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| struct PARAM_REMOVE_KEY *prRemovedKey; |
| struct CMD_802_11_KEY *prCmdKey; |
| uint8_t ucCmdSeqNum; |
| struct WLAN_TABLE *prWlanTable; |
| struct STA_RECORD *prStaRec = NULL; |
| struct BSS_INFO *prBssInfo; |
| /* UINT_8 i = 0; */ |
| u_int8_t fgRemoveWepKey = FALSE; |
| u_int8_t fgRemoveBCKey = FALSE; |
| uint32_t ucRemoveBCKeyAtIdx = WTBL_RESERVED_ENTRY; |
| uint32_t u4KeyIndex; |
| u_int8_t fgIsOid = g_fgIsOid; |
| |
| DEBUGFUNC("wlanoidSetRemoveKey"); |
| |
| if (prAdapter == NULL) { |
| DBGLOG(REQ, WARN, "prAdapter is NULL"); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| if (pu4SetInfoLen == NULL) { |
| DBGLOG(REQ, WARN, "The pu4SetInfoLen is NULL"); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| DBGLOG(RSN, INFO, "wlanoidSetRemoveKey\n"); |
| |
| prWlanTable = prAdapter->rWifiVar.arWtbl; |
| *pu4SetInfoLen = sizeof(struct PARAM_REMOVE_KEY); |
| |
| if (u4SetBufferLen < sizeof(struct PARAM_REMOVE_KEY)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| if (pvSetBuffer == NULL) { |
| DBGLOG(REQ, WARN, "pvSetBuffer is NULL"); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| prRemovedKey = (struct PARAM_REMOVE_KEY *) pvSetBuffer; |
| |
| /* Dump PARAM_REMOVE_KEY content. */ |
| DBGLOG(RSN, INFO, "Set: Dump PARAM_REMOVE_KEY content (%p)\n", |
| prRemovedKey); |
| DBGLOG(RSN, INFO, "Length : 0x%08x\n", |
| prRemovedKey->u4Length); |
| DBGLOG(RSN, INFO, "Key Index : 0x%08x\n", |
| prRemovedKey->u4KeyIndex); |
| DBGLOG(RSN, INFO, "BSS_INDEX : %d\n", |
| prRemovedKey->ucBssIdx); |
| DBGLOG(RSN, INFO, "BSSID:\n"); |
| DBGLOG_MEM8(RSN, INFO, prRemovedKey->arBSSID, MAC_ADDR_LEN); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, |
| prRemovedKey->ucBssIdx); |
| |
| if (prBssInfo == NULL) { |
| DBGLOG(REQ, WARN, "prBssInfo is NULL"); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| u4KeyIndex = prRemovedKey->u4KeyIndex & 0x000000FF; |
| #if CFG_SUPPORT_802_11W |
| if (u4KeyIndex >= MAX_KEY_NUM + 2) { |
| DBGLOG(RSN, WARN, "key id %d over the max val\n", u4KeyIndex); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| #else |
| /* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */ |
| #endif |
| |
| if (u4KeyIndex >= 4) { |
| DBGLOG(RSN, INFO, "Remove bip key Index : 0x%08x\n", |
| u4KeyIndex); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /* Clean up the Tx key flag */ |
| if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) { |
| prStaRec = cnmGetStaRecByAddress(prAdapter, |
| prRemovedKey->ucBssIdx, prRemovedKey->arBSSID); |
| if (!prStaRec) { |
| DBGLOG(RSN, INFO, "unicast key w/o starec\n"); |
| return WLAN_STATUS_SUCCESS; |
| } |
| } else { |
| if (u4KeyIndex == prBssInfo->ucBcDefaultKeyIdx) |
| prBssInfo->fgBcDefaultKeyExist = FALSE; |
| } |
| |
| if (!prStaRec) { |
| if (prBssInfo->wepkeyUsed[u4KeyIndex] == TRUE) |
| fgRemoveWepKey = TRUE; |
| |
| if (fgRemoveWepKey) { |
| DBGLOG(RSN, INFO, "Remove wep key id = %d", u4KeyIndex); |
| prBssInfo->wepkeyUsed[u4KeyIndex] = FALSE; |
| if (prBssInfo->fgBcDefaultKeyExist && |
| prBssInfo->ucBcDefaultKeyIdx == u4KeyIndex) { |
| prBssInfo->fgBcDefaultKeyExist = FALSE; |
| prBssInfo->ucBcDefaultKeyIdx = 0xff; |
| } |
| |
| if (prBssInfo->wepkeyWlanIdx >= WTBL_SIZE) { |
| DBGLOG(REQ, WARN, "wepkeyWlanIdx err : %d\n", |
| prBssInfo->wepkeyWlanIdx); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| ucRemoveBCKeyAtIdx = prBssInfo->wepkeyWlanIdx; |
| fgRemoveBCKey = TRUE; |
| } else { |
| DBGLOG(RSN, INFO, "Remove group key id = %d", |
| u4KeyIndex); |
| |
| if (prBssInfo->ucBMCWlanIndexSUsed[u4KeyIndex]) { |
| if (prBssInfo->fgBcDefaultKeyExist && |
| prBssInfo->ucBcDefaultKeyIdx == |
| u4KeyIndex) { |
| prBssInfo->fgBcDefaultKeyExist = FALSE; |
| prBssInfo->ucBcDefaultKeyIdx = 0xff; |
| } |
| |
| if ((u4KeyIndex != 0) && |
| (prBssInfo->ucBMCWlanIndexS[u4KeyIndex] |
| >= WTBL_SIZE)) { |
| DBGLOG(REQ, WARN, "u4KeyIndex err\n"); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| ucRemoveBCKeyAtIdx = |
| prBssInfo->ucBMCWlanIndexS[u4KeyIndex]; |
| prBssInfo->ucBMCWlanIndexSUsed[u4KeyIndex] = |
| FALSE; |
| prBssInfo->ucBMCWlanIndexS[u4KeyIndex] = |
| WTBL_RESERVED_ENTRY; |
| fgRemoveBCKey = TRUE; |
| } |
| } |
| |
| /* Change the wtbl to not used state */ |
| if (fgRemoveBCKey) |
| prWlanTable[ucRemoveBCKeyAtIdx].ucUsed = FALSE; |
| |
| DBGLOG(RSN, INFO, "ucRemoveBCKeyAtIdx = %d", |
| ucRemoveBCKeyAtIdx); |
| |
| if (ucRemoveBCKeyAtIdx >= WTBL_SIZE) |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + sizeof(struct CMD_802_11_KEY))); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, |
| prRemovedKey->ucBssIdx); |
| |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| |
| if (prRemovedKey->ucCtrlFlag & FLAG_RM_KEY_CTRL_WO_OID) |
| fgIsOid = FALSE; |
| |
| /* compose CMD_802_11_KEY cmd pkt */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| /* prCmdInfo->ucBssIndex = prRemovedKey->ucBssIdx; */ |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof( |
| struct CMD_802_11_KEY); |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| prCmdInfo->fgIsOid = fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| /* prCmdInfo->fgDriverDomainMCR = FALSE; */ |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = sizeof(struct PARAM_REMOVE_KEY); |
| prCmdInfo->pvInformationBuffer = pvSetBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetBufferLen; |
| |
| /* Setup WIFI_CMD_T */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| prCmdKey = (struct CMD_802_11_KEY *) (prWifiCmd->aucBuffer); |
| |
| kalMemZero((uint8_t *) prCmdKey, |
| sizeof(struct CMD_802_11_KEY)); |
| |
| prCmdKey->ucAddRemove = 0; /* Remove */ |
| prCmdKey->ucKeyId = (uint8_t) u4KeyIndex; |
| kalMemCopy(prCmdKey->aucPeerAddr, |
| (uint8_t *) prRemovedKey->arBSSID, MAC_ADDR_LEN); |
| prCmdKey->ucBssIdx = prRemovedKey->ucBssIdx; |
| |
| if (prStaRec) { |
| prCmdKey->ucKeyType = 1; |
| prCmdKey->ucWlanIndex = prStaRec->ucWlanIndex; |
| prStaRec->fgTransmitKeyExist = FALSE; |
| } else if (ucRemoveBCKeyAtIdx < WTBL_SIZE) { |
| prCmdKey->ucWlanIndex = ucRemoveBCKeyAtIdx; |
| } else { |
| ASSERT(FALSE); |
| } |
| |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| } /* wlanoidSetRemoveKey */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the default key |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * |
| * \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetDefaultKey(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| struct PARAM_DEFAULT_KEY *prDefaultKey; |
| struct CMD_DEFAULT_KEY *prCmdDefaultKey; |
| uint8_t ucCmdSeqNum; |
| struct BSS_INFO *prBssInfo; |
| u_int8_t fgSetWepKey = FALSE; |
| uint8_t ucWlanIndex = WTBL_RESERVED_ENTRY; |
| |
| DEBUGFUNC("wlanoidSetDefaultKey"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| prDefaultKey = (struct PARAM_DEFAULT_KEY *) pvSetBuffer; |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| /* Dump PARAM_DEFAULT_KEY_T content. */ |
| DBGLOG(RSN, INFO, |
| "Key Index : %d, Unicast Key : %d, Multicast Key : %d\n", |
| prDefaultKey->ucKeyID, prDefaultKey->ucUnicast, |
| prDefaultKey->ucMulticast); |
| |
| /* prWlanTable = prAdapter->rWifiVar.arWtbl; */ |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| if (prDefaultKey->ucBssIdx > HW_BSSID_NUM) |
| return WLAN_STATUS_FAILURE; |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, |
| prDefaultKey->ucBssIdx); |
| |
| DBGLOG(RSN, INFO, "WlanIdx = %d\n", |
| prBssInfo->wepkeyWlanIdx); |
| |
| if (prDefaultKey->ucMulticast) { |
| if (prBssInfo->prStaRecOfAP) { /* Actually GC not have wep */ |
| if (prBssInfo->wepkeyUsed[prDefaultKey->ucKeyID]) { |
| prBssInfo->ucBcDefaultKeyIdx = |
| prDefaultKey->ucKeyID; |
| prBssInfo->fgBcDefaultKeyExist = TRUE; |
| ucWlanIndex = prBssInfo->wepkeyWlanIdx; |
| } else { |
| if (prDefaultKey->ucUnicast) { |
| DBGLOG(RSN, ERROR, |
| "Set STA Unicast default key"); |
| return WLAN_STATUS_SUCCESS; |
| } |
| ASSERT(FALSE); |
| } |
| } else { /* For AP mode only */ |
| |
| if (prBssInfo->wepkeyUsed[prDefaultKey->ucKeyID] |
| == TRUE) |
| fgSetWepKey = TRUE; |
| |
| if (fgSetWepKey) { |
| ucWlanIndex = prBssInfo->wepkeyWlanIdx; |
| } else { |
| if (!prBssInfo->ucBMCWlanIndexSUsed[ |
| prDefaultKey->ucKeyID]) { |
| DBGLOG(RSN, ERROR, |
| "Set AP wep default but key not exist!"); |
| return WLAN_STATUS_SUCCESS; |
| } |
| ucWlanIndex = prBssInfo->ucBMCWlanIndexS[ |
| prDefaultKey->ucKeyID]; |
| } |
| prBssInfo->ucBcDefaultKeyIdx = prDefaultKey->ucKeyID; |
| prBssInfo->fgBcDefaultKeyExist = TRUE; |
| } |
| if (ucWlanIndex > WTBL_SIZE) |
| ASSERT(FALSE); |
| |
| } else { |
| DBGLOG(RSN, ERROR, |
| "Check the case set unicast default key!"); |
| ASSERT(FALSE); |
| } |
| |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + sizeof(struct CMD_DEFAULT_KEY))); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| DBGLOG(RSN, TRACE, |
| "ucCmdSeqNum = %d, CMD_ID_DEFAULT_KEY_ID (%d) with wlan idx = %d\n", |
| ucCmdSeqNum, prDefaultKey->ucKeyID, ucWlanIndex); |
| |
| /* compose CMD_802_11_KEY cmd pkt */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof( |
| struct CMD_DEFAULT_KEY); |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| prCmdInfo->fgIsOid = g_fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_DEFAULT_KEY_ID; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = u4SetBufferLen; |
| prCmdInfo->pvInformationBuffer = pvSetBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetBufferLen; |
| |
| /* Setup WIFI_CMD_T */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| prCmdDefaultKey = (struct CMD_DEFAULT_KEY *) ( |
| prWifiCmd->aucBuffer); |
| |
| kalMemZero(prCmdDefaultKey, sizeof(struct CMD_DEFAULT_KEY)); |
| |
| prCmdDefaultKey->ucBssIdx = prDefaultKey->ucBssIdx; |
| prCmdDefaultKey->ucKeyId = prDefaultKey->ucKeyID; |
| prCmdDefaultKey->ucWlanIndex = ucWlanIndex; |
| prCmdDefaultKey->ucMulticast = prDefaultKey->ucMulticast; |
| |
| DBGLOG(RSN, INFO, |
| "CMD_ID_DEFAULT_KEY_ID (%d) with wlan idx = %d\n", |
| prDefaultKey->ucKeyID, ucWlanIndex); |
| |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| } /* wlanoidSetDefaultKey */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current encryption status. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryEncryptionStatus(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| u_int8_t fgTransmitKeyAvailable = TRUE; |
| enum ENUM_WEP_STATUS eEncStatus = 0; |
| |
| DEBUGFUNC("wlanoidQueryEncryptionStatus"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(enum ENUM_WEP_STATUS); |
| |
| fgTransmitKeyAvailable = |
| prAdapter->prAisBssInfo->fgBcDefaultKeyExist; |
| |
| switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { |
| case ENUM_ENCRYPTION3_ENABLED: |
| if (fgTransmitKeyAvailable) |
| eEncStatus = ENUM_ENCRYPTION3_ENABLED; |
| else |
| eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT; |
| break; |
| |
| case ENUM_ENCRYPTION2_ENABLED: |
| if (fgTransmitKeyAvailable) { |
| eEncStatus = ENUM_ENCRYPTION2_ENABLED; |
| break; |
| } |
| eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT; |
| break; |
| |
| case ENUM_ENCRYPTION1_ENABLED: |
| if (fgTransmitKeyAvailable) |
| eEncStatus = ENUM_ENCRYPTION1_ENABLED; |
| else |
| eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; |
| break; |
| |
| case ENUM_ENCRYPTION_DISABLED: |
| eEncStatus = ENUM_ENCRYPTION_DISABLED; |
| break; |
| |
| default: |
| DBGLOG(REQ, ERROR, "Unknown Encryption Status Setting:%d\n", |
| prAdapter->rWifiVar.rConnSettings.eEncStatus); |
| } |
| |
| #if DBG |
| DBGLOG(REQ, INFO, |
| "Encryption status: %d Return:%d\n", |
| prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus); |
| #endif |
| |
| *(enum ENUM_WEP_STATUS *) pvQueryBuffer = eEncStatus; |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryEncryptionStatus */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the encryption status to the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_NOT_SUPPORTED |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetEncryptionStatus(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct GLUE_INFO *prGlueInfo; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| enum ENUM_WEP_STATUS eEewEncrypt; |
| |
| DEBUGFUNC("wlanoidSetEncryptionStatus"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| *pu4SetInfoLen = sizeof(enum ENUM_WEP_STATUS); |
| |
| /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ |
| /* return WLAN_STATUS_SUCCESS; */ |
| /* } */ |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| eEewEncrypt = *(enum ENUM_WEP_STATUS *) pvSetBuffer; |
| DBGLOG(REQ, INFO, "ENCRYPTION_STATUS %d\n", eEewEncrypt); |
| |
| switch (eEewEncrypt) { |
| case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */ |
| DBGLOG(RSN, INFO, "Disable Encryption\n"); |
| secSetCipherSuite(prAdapter, |
| CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | |
| CIPHER_FLAG_WEP128); |
| break; |
| |
| case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */ |
| DBGLOG(RSN, INFO, "Enable Encryption1\n"); |
| secSetCipherSuite(prAdapter, |
| CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | |
| CIPHER_FLAG_WEP128); |
| break; |
| |
| case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */ |
| secSetCipherSuite(prAdapter, |
| CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | |
| CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP); |
| DBGLOG(RSN, INFO, "Enable Encryption2\n"); |
| break; |
| |
| case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */ |
| secSetCipherSuite(prAdapter, |
| CIPHER_FLAG_WEP40 | |
| CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | |
| CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP); |
| DBGLOG(RSN, INFO, "Enable Encryption3\n"); |
| break; |
| |
| #if CFG_SUPPORT_SUITB |
| case ENUM_ENCRYPTION4_ENABLED: /* Eanble GCMP256 */ |
| secSetCipherSuite(prAdapter, CIPHER_FLAG_GCMP256); |
| DBGLOG(RSN, INFO, "Enable Encryption4\n"); |
| break; |
| #endif |
| |
| default: |
| DBGLOG(RSN, INFO, "Unacceptible encryption status: %d\n", |
| *(enum ENUM_WEP_STATUS *) pvSetBuffer); |
| |
| rStatus = WLAN_STATUS_NOT_SUPPORTED; |
| } |
| |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| /* Save the new encryption status. */ |
| prAdapter->rWifiVar.rConnSettings.eEncStatus = * |
| (enum ENUM_WEP_STATUS *) pvSetBuffer; |
| } |
| |
| return rStatus; |
| } /* wlanoidSetEncryptionStatus */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to test the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetTest(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_802_11_TEST *prTest; |
| void *pvTestData; |
| void *pvStatusBuffer; |
| uint32_t u4StatusBufferSize; |
| |
| DEBUGFUNC("wlanoidSetTest"); |
| |
| ASSERT(prAdapter); |
| |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| prTest = (struct PARAM_802_11_TEST *) pvSetBuffer; |
| |
| DBGLOG(REQ, TRACE, "Test - Type %u\n", prTest->u4Type); |
| |
| switch (prTest->u4Type) { |
| case 1: /* Type 1: generate an authentication event */ |
| pvTestData = (void *) &prTest->u.AuthenticationEvent; |
| pvStatusBuffer = (void *) |
| prAdapter->aucIndicationEventBuffer; |
| u4StatusBufferSize = prTest->u4Length - 8; |
| if (u4StatusBufferSize > sizeof( |
| prTest->u.AuthenticationEvent)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| break; |
| |
| case 2: /* Type 2: generate an RSSI status indication */ |
| pvTestData = (void *) &prTest->u.RssiTrigger; |
| pvStatusBuffer = (void *) |
| &prAdapter->rWlanInfo.rCurrBssId.rRssi; |
| u4StatusBufferSize = sizeof(int32_t); |
| break; |
| |
| default: |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| /* Get the contents of the StatusBuffer from the test structure. */ |
| kalMemCopy(pvStatusBuffer, pvTestData, u4StatusBufferSize); |
| |
| kalIndicateStatusAndComplete(prAdapter->prGlueInfo, |
| WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, |
| pvStatusBuffer, u4StatusBufferSize); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetTest */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the driver's WPA2 status. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryCapability(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CAPABILITY *prCap; |
| struct PARAM_AUTH_ENCRYPTION |
| *prAuthenticationEncryptionSupported; |
| |
| DEBUGFUNC("wlanoidQueryCapability"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = 4 * sizeof(uint32_t) + 14 * sizeof( |
| struct PARAM_AUTH_ENCRYPTION); |
| |
| if (u4QueryBufferLen < *pu4QueryInfoLen) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prCap = (struct PARAM_CAPABILITY *) pvQueryBuffer; |
| |
| prCap->u4Length = *pu4QueryInfoLen; |
| prCap->u4Version = 2; /* WPA2 */ |
| prCap->u4NoOfPMKIDs = CFG_MAX_PMKID_CACHE; |
| prCap->u4NoOfAuthEncryptPairsSupported = 14; |
| |
| prAuthenticationEncryptionSupported = |
| &prCap->arAuthenticationEncryptionSupported[0]; |
| |
| /* fill 14 entries of supported settings */ |
| prAuthenticationEncryptionSupported[0].eAuthModeSupported = |
| AUTH_MODE_OPEN; |
| |
| prAuthenticationEncryptionSupported[0].eEncryptStatusSupported |
| = ENUM_ENCRYPTION_DISABLED; |
| |
| prAuthenticationEncryptionSupported[1].eAuthModeSupported = |
| AUTH_MODE_OPEN; |
| prAuthenticationEncryptionSupported[1].eEncryptStatusSupported |
| = ENUM_ENCRYPTION1_ENABLED; |
| |
| prAuthenticationEncryptionSupported[2].eAuthModeSupported = |
| AUTH_MODE_SHARED; |
| prAuthenticationEncryptionSupported[2].eEncryptStatusSupported |
| = ENUM_ENCRYPTION_DISABLED; |
| |
| prAuthenticationEncryptionSupported[3].eAuthModeSupported = |
| AUTH_MODE_SHARED; |
| prAuthenticationEncryptionSupported[3].eEncryptStatusSupported |
| = ENUM_ENCRYPTION1_ENABLED; |
| |
| prAuthenticationEncryptionSupported[4].eAuthModeSupported = |
| AUTH_MODE_WPA; |
| prAuthenticationEncryptionSupported[4].eEncryptStatusSupported |
| = ENUM_ENCRYPTION2_ENABLED; |
| |
| prAuthenticationEncryptionSupported[5].eAuthModeSupported = |
| AUTH_MODE_WPA; |
| prAuthenticationEncryptionSupported[5].eEncryptStatusSupported |
| = ENUM_ENCRYPTION3_ENABLED; |
| |
| prAuthenticationEncryptionSupported[6].eAuthModeSupported = |
| AUTH_MODE_WPA_PSK; |
| prAuthenticationEncryptionSupported[6].eEncryptStatusSupported |
| = ENUM_ENCRYPTION2_ENABLED; |
| |
| prAuthenticationEncryptionSupported[7].eAuthModeSupported = |
| AUTH_MODE_WPA_PSK; |
| prAuthenticationEncryptionSupported[7].eEncryptStatusSupported |
| = ENUM_ENCRYPTION3_ENABLED; |
| |
| prAuthenticationEncryptionSupported[8].eAuthModeSupported = |
| AUTH_MODE_WPA_NONE; |
| prAuthenticationEncryptionSupported[8].eEncryptStatusSupported |
| = ENUM_ENCRYPTION2_ENABLED; |
| |
| prAuthenticationEncryptionSupported[9].eAuthModeSupported = |
| AUTH_MODE_WPA_NONE; |
| prAuthenticationEncryptionSupported[9].eEncryptStatusSupported |
| = ENUM_ENCRYPTION3_ENABLED; |
| |
| prAuthenticationEncryptionSupported[10].eAuthModeSupported = |
| AUTH_MODE_WPA2; |
| prAuthenticationEncryptionSupported[10].eEncryptStatusSupported |
| = ENUM_ENCRYPTION2_ENABLED; |
| |
| prAuthenticationEncryptionSupported[11].eAuthModeSupported = |
| AUTH_MODE_WPA2; |
| prAuthenticationEncryptionSupported[11].eEncryptStatusSupported |
| = ENUM_ENCRYPTION3_ENABLED; |
| |
| prAuthenticationEncryptionSupported[12].eAuthModeSupported = |
| AUTH_MODE_WPA2_PSK; |
| prAuthenticationEncryptionSupported[12].eEncryptStatusSupported |
| = ENUM_ENCRYPTION2_ENABLED; |
| |
| prAuthenticationEncryptionSupported[13].eAuthModeSupported = |
| AUTH_MODE_WPA2_PSK; |
| prAuthenticationEncryptionSupported[13].eEncryptStatusSupported |
| = ENUM_ENCRYPTION3_ENABLED; |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidQueryCapability */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the PMKID in the PMK cache. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryPmkid(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t i; |
| struct PARAM_PMKID *prPmkid; |
| struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; |
| |
| DEBUGFUNC("wlanoidQueryPmkid"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; |
| |
| *pu4QueryInfoLen = OFFSET_OF(struct PARAM_PMKID, |
| arBSSIDInfo) + |
| prAisSpecBssInfo->u4PmkidCacheCount * sizeof( |
| struct PARAM_BSSID_INFO); |
| |
| if (u4QueryBufferLen < *pu4QueryInfoLen) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prPmkid = (struct PARAM_PMKID *) pvQueryBuffer; |
| |
| prPmkid->u4Length = *pu4QueryInfoLen; |
| prPmkid->u4BSSIDInfoCount = |
| prAisSpecBssInfo->u4PmkidCacheCount; |
| |
| for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { |
| kalMemCopy(prPmkid->arBSSIDInfo[i].arBSSID, |
| prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, |
| (sizeof(uint8_t) * PARAM_MAC_ADDR_LEN)); |
| kalMemCopy(prPmkid->arBSSIDInfo[i].arPMKID, |
| prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arPMKID, |
| (sizeof(uint8_t) * 16)); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidQueryPmkid */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the PMKID to the PMK cache in the |
| * driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetPmkid(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t i, j; |
| struct PARAM_PMKID *prPmkid; |
| struct AIS_SPECIFIC_BSS_INFO *prAisSpecBssInfo; |
| |
| DEBUGFUNC("wlanoidSetPmkid"); |
| |
| DBGLOG(REQ, INFO, "wlanoidSetPmkid\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| /* It's possibble BSSIDInfoCount is zero, because OS wishes to clean |
| * PMKID |
| */ |
| if (u4SetBufferLen < OFFSET_OF(struct PARAM_PMKID, |
| arBSSIDInfo)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| ASSERT(pvSetBuffer); |
| prPmkid = (struct PARAM_PMKID *) pvSetBuffer; |
| |
| if (u4SetBufferLen < |
| ((prPmkid->u4BSSIDInfoCount * sizeof(struct |
| PARAM_BSSID_INFO)) + OFFSET_OF(struct PARAM_PMKID, |
| arBSSIDInfo))) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| if (prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| DBGLOG(REQ, INFO, "Count %u\n", prPmkid->u4BSSIDInfoCount); |
| |
| prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; |
| |
| /* This OID replace everything in the PMKID cache. */ |
| if (prPmkid->u4BSSIDInfoCount == 0) { |
| prAisSpecBssInfo->u4PmkidCacheCount = 0; |
| kalMemZero(prAisSpecBssInfo->arPmkidCache, |
| sizeof(struct PMKID_ENTRY) * CFG_MAX_PMKID_CACHE); |
| } |
| if ((prAisSpecBssInfo->u4PmkidCacheCount + |
| prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)) { |
| prAisSpecBssInfo->u4PmkidCacheCount = 0; |
| kalMemZero(prAisSpecBssInfo->arPmkidCache, |
| sizeof(struct PMKID_ENTRY) * CFG_MAX_PMKID_CACHE); |
| } |
| |
| /* |
| * The driver can only clear its PMKID cache whenever it make a media |
| * disconnect indication. Otherwise, it must change the PMKID cache |
| * only when set through this OID. |
| */ |
| for (i = 0; i < prPmkid->u4BSSIDInfoCount; i++) { |
| /* Search for desired BSSID. If desired BSSID is found, |
| * then set the PMKID |
| */ |
| if (!rsnSearchPmkidEntry(prAdapter, |
| (uint8_t *) prPmkid->arBSSIDInfo[i].arBSSID, &j)) { |
| /* No entry found for the specified BSSID, so add one |
| * entry |
| */ |
| if (prAisSpecBssInfo->u4PmkidCacheCount < |
| CFG_MAX_PMKID_CACHE - 1) { |
| j = prAisSpecBssInfo->u4PmkidCacheCount; |
| kalMemCopy( |
| prAisSpecBssInfo->arPmkidCache[j] |
| .rBssidInfo.arBSSID, |
| prPmkid->arBSSIDInfo[i].arBSSID, |
| (sizeof(uint8_t) * PARAM_MAC_ADDR_LEN)); |
| prAisSpecBssInfo->u4PmkidCacheCount++; |
| } else { |
| j = CFG_MAX_PMKID_CACHE; |
| } |
| } |
| |
| if (j < CFG_MAX_PMKID_CACHE) { |
| kalMemCopy( |
| prAisSpecBssInfo->arPmkidCache[j].rBssidInfo |
| .arPMKID, |
| prPmkid->arBSSIDInfo[i].arPMKID, |
| (sizeof(uint8_t) * 16)); |
| DBGLOG(RSN, TRACE, |
| "Add BSSID " MACSTR " idx=%u PMKID value " MACSTR |
| "\n", |
| MAC2STR(prAisSpecBssInfo->arPmkidCache[j] |
| .rBssidInfo.arBSSID), |
| j, |
| MAC2STR(prAisSpecBssInfo->arPmkidCache[j] |
| .rBssidInfo.arPMKID)); |
| prAisSpecBssInfo->arPmkidCache[j].fgPmkidExist = TRUE; |
| } |
| } |
| |
| if (prAdapter->rWifiVar.rConnSettings.fgOkcEnabled) { |
| struct BSS_DESC *prBssDesc = |
| prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; |
| uint8_t *pucPmkID = NULL; |
| |
| if ((prPmkid->u4Length & BIT(31)) || |
| (prBssDesc && EQUAL_MAC_ADDR( |
| prPmkid->arBSSIDInfo[0].arBSSID, prBssDesc->aucBSSID))) { |
| if (j == CFG_MAX_PMKID_CACHE) { |
| j = 0; |
| kalMemCopy( |
| prAisSpecBssInfo->arPmkidCache[0] |
| .rBssidInfo.arBSSID, |
| prPmkid->arBSSIDInfo[0].arBSSID, |
| (sizeof(uint8_t) * PARAM_MAC_ADDR_LEN)); |
| kalMemCopy( |
| prAisSpecBssInfo->arPmkidCache[0] |
| .rBssidInfo.arPMKID, |
| prPmkid->arBSSIDInfo[0].arPMKID, |
| (sizeof(uint8_t) * 16)); |
| prAisSpecBssInfo->arPmkidCache[0].fgPmkidExist |
| = TRUE; |
| } |
| pucPmkID = prAisSpecBssInfo->arPmkidCache[j].rBssidInfo |
| .arPMKID; |
| log_dbg(RSN, INFO, MACSTR " OKC PMKID %02x%02x%02x%02x%02x%02x%02x%02x...\n", |
| MAC2STR(prAisSpecBssInfo-> |
| arPmkidCache[j].rBssidInfo.arBSSID), |
| pucPmkID[0], pucPmkID[1], |
| pucPmkID[2], pucPmkID[3], |
| pucPmkID[4], pucPmkID[5], |
| pucPmkID[6], pucPmkID[7]); |
| } |
| aisFsmRunEventSetOkcPmk(prAdapter); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidSetPmkid */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the set of supported data rates that |
| * the radio is capable of running |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query |
| * \param[in] u4QueryBufferLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQuerySupportedRates(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint8_t eRate[PARAM_MAX_LEN_RATES] = { |
| /* BSSBasicRateSet for 802.11n Non-HT rates */ |
| 0x8C, /* 6M */ |
| 0x92, /* 9M */ |
| 0x98, /* 12M */ |
| 0xA4, /* 18M */ |
| 0xB0, /* 24M */ |
| 0xC8, /* 36M */ |
| 0xE0, /* 48M */ |
| 0xEC /* 54M */ |
| }; |
| |
| DEBUGFUNC("wlanoidQuerySupportedRates"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = (sizeof(uint8_t) * |
| PARAM_MAX_LEN_RATES_EX); |
| |
| if (u4QueryBufferLen < *pu4QueryInfoLen) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| kalMemCopy(pvQueryBuffer, (void *) &eRate, |
| (sizeof(uint8_t) * PARAM_MAX_LEN_RATES)); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidQuerySupportedRates() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query current desired rates. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryDesiredRates(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryDesiredRates"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = (sizeof(uint8_t) * |
| PARAM_MAX_LEN_RATES_EX); |
| |
| if (u4QueryBufferLen < *pu4QueryInfoLen) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| kalMemCopy(pvQueryBuffer, |
| (void *) &(prAdapter->rWlanInfo.eDesiredRates), |
| (sizeof(uint8_t) * PARAM_MAX_LEN_RATES)); |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* end of wlanoidQueryDesiredRates() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to Set the desired rates. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetDesiredRates(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t i; |
| |
| DEBUGFUNC("wlanoidSetDesiredRates"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (u4SetBufferLen < (sizeof(uint8_t) * |
| PARAM_MAX_LEN_RATES)) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *pu4SetInfoLen = (sizeof(uint8_t) * PARAM_MAX_LEN_RATES); |
| |
| if (u4SetBufferLen < (sizeof(uint8_t) * |
| PARAM_MAX_LEN_RATES)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| kalMemCopy((void *) &(prAdapter->rWlanInfo.eDesiredRates), |
| pvSetBuffer, (sizeof(uint8_t) * PARAM_MAX_LEN_RATES)); |
| |
| prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = |
| PARAM_MAX_LEN_RATES; |
| for (i = 0; i < PARAM_MAX_LEN_RATES; i++) |
| prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = |
| (uint16_t) (prAdapter->rWlanInfo.eDesiredRates[i]); |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_LINK_ATTRIB, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_LINK_ATTRIB), |
| (uint8_t *) &(prAdapter->rWlanInfo.eLinkAttr), |
| pvSetBuffer, |
| u4SetBufferLen); |
| |
| } /* end of wlanoidSetDesiredRates() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the maximum frame size in bytes, |
| * not including the header. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryMaxFrameSize(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryMaxFrameSize"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *(uint32_t *) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - |
| ETHERNET_HEADER_SZ; |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryMaxFrameSize */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the maximum total packet length |
| * in bytes. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryMaxTotalSize(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryMaxTotalSize"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *(uint32_t *) pvQueryBuffer = ETHERNET_MAX_PKT_SZ; |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryMaxTotalSize */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the vendor ID of the NIC. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryVendorId(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| #if DBG |
| uint8_t *cp; |
| #endif |
| DEBUGFUNC("wlanoidQueryVendorId"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3); |
| *((uint8_t *) pvQueryBuffer + 3) = 1; |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| #if DBG |
| cp = (uint8_t *) pvQueryBuffer; |
| DBGLOG(REQ, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], |
| cp[1], cp[2], cp[3]); |
| #endif |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryVendorId */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current RSSI value. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the |
| * query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call failed due to invalid |
| * length of the query buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRssi(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| |
| return wlanQueryRssi(prAdapter, |
| pvQueryBuffer, |
| u4QueryBufferLen, |
| pu4QueryInfoLen, |
| g_fgIsOid); |
| } |
| |
| uint32_t |
| wlanQueryRssi(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen, |
| IN uint8_t fgIsOid) { |
| |
| DEBUGFUNC("wlanoidQueryRssi"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (prAdapter->fgIsEnableLpdvt) |
| return WLAN_STATUS_NOT_SUPPORTED; |
| |
| *pu4QueryInfoLen = sizeof(int32_t); |
| |
| /* Check for query buffer length */ |
| if (u4QueryBufferLen < *pu4QueryInfoLen) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_DISCONNECTED) { |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (prAdapter->fgIsLinkQualityValid == TRUE && |
| (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) <= |
| CFG_LINK_QUALITY_VALID_PERIOD) { |
| int32_t rRssi; |
| |
| /* ranged from (-128 ~ 30) in unit of dBm */ |
| rRssi = (int32_t) prAdapter->rLinkQuality.cRssi; |
| |
| if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) |
| rRssi = PARAM_WHQL_RSSI_MAX_DBM; |
| else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) |
| rRssi = PARAM_WHQL_RSSI_MIN_DBM; |
| |
| kalMemCopy(pvQueryBuffer, &rRssi, sizeof(int32_t)); |
| return WLAN_STATUS_SUCCESS; |
| } |
| #ifdef LINUX |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_LINK_QUALITY, |
| FALSE, |
| TRUE, |
| fgIsOid, |
| nicCmdEventQueryLinkQuality, |
| nicOidCmdTimeoutCommon, |
| *pu4QueryInfoLen, pvQueryBuffer, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| #else |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_LINK_QUALITY, |
| FALSE, |
| TRUE, |
| fgIsOid, |
| nicCmdEventQueryLinkQuality, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| #endif |
| } /* end of wlanoidQueryRssi() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current RSSI trigger value. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the |
| * query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call failed due to invalid |
| * length of the query buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRssiTrigger(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryRssiTrigger"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (prAdapter->rWlanInfo.eRssiTriggerType == |
| ENUM_RSSI_TRIGGER_NONE) |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| |
| *pu4QueryInfoLen = sizeof(int32_t); |
| |
| /* Check for query buffer length */ |
| if (u4QueryBufferLen < *pu4QueryInfoLen) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| *(int32_t *) pvQueryBuffer = |
| prAdapter->rWlanInfo.rRssiTriggerValue; |
| DBGLOG(REQ, INFO, "RSSI trigger: %d dBm\n", |
| *(int32_t *) pvQueryBuffer); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryRssiTrigger */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set a trigger value of the RSSI event. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns the |
| * amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetRssiTrigger(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| int32_t rRssiTriggerValue; |
| |
| DEBUGFUNC("wlanoidSetRssiTrigger"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(int32_t); |
| rRssiTriggerValue = *(int32_t *) pvSetBuffer; |
| |
| if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM |
| || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM) |
| return |
| /* Save the RSSI trigger value to the Adapter structure |
| */ |
| prAdapter->rWlanInfo.rRssiTriggerValue = |
| rRssiTriggerValue; |
| |
| /* If the RSSI trigger value is equal to the current RSSI value, the |
| * indication triggers immediately. We need to indicate the protocol |
| * that an RSSI status indication event triggers. |
| */ |
| if (rRssiTriggerValue == (int32_t) ( |
| prAdapter->rLinkQuality.cRssi)) { |
| prAdapter->rWlanInfo.eRssiTriggerType = |
| ENUM_RSSI_TRIGGER_TRIGGERED; |
| |
| kalIndicateStatusAndComplete(prAdapter->prGlueInfo, |
| WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, |
| (void *) &prAdapter->rWlanInfo.rRssiTriggerValue, |
| sizeof(int32_t)); |
| } else if (rRssiTriggerValue < (int32_t) ( |
| prAdapter->rLinkQuality.cRssi)) |
| prAdapter->rWlanInfo.eRssiTriggerType = |
| ENUM_RSSI_TRIGGER_GREATER; |
| else if (rRssiTriggerValue > (int32_t) ( |
| prAdapter->rLinkQuality.cRssi)) |
| prAdapter->rWlanInfo.eRssiTriggerType = |
| ENUM_RSSI_TRIGGER_LESS; |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetRssiTrigger */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set a suggested value for the number of |
| * bytes of received packet data that will be indicated to the protocol |
| * driver. We just accept the set and ignore this value. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetCurrentLookahead(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| DEBUGFUNC("wlanoidSetCurrentLookahead"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) { |
| *pu4SetInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetCurrentLookahead */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the number of frames that the driver |
| * receives but does not indicate to the protocols due to errors. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRcvError(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryRcvError"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not |
| * calculated |
| */ |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| prAdapter->rStatStruct.rFCSErrorCount.QuadPart; |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) |
| prAdapter->rStatStruct.rFCSErrorCount.QuadPart; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryRecvError, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryRcvError */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to query the number of frames that the NIC |
| * cannot receive due to lack of NIC receive buffer space. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS If success; |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRcvNoBuffer(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryRcvNoBuffer"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) 0; /* @FIXME */ |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) 0; /* @FIXME */ |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryRecvNoBuffer, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryRcvNoBuffer */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to query the number of frames that the NIC |
| * received and it is CRC error. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS If success; |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRcvCrcError(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryRcvCrcError"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| prAdapter->rStatStruct.rFCSErrorCount.QuadPart; |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) |
| prAdapter->rStatStruct.rFCSErrorCount.QuadPart; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryRecvCrcError, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryRcvCrcError */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to query the current 802.11 statistics. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryStatistics(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_802_11_STATISTICS_STRUCT rStatistics; |
| |
| DEBUGFUNC("wlanoidQueryStatistics"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_802_11_STATISTICS_STRUCT); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(struct |
| PARAM_802_11_STATISTICS_STRUCT)) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| struct PARAM_802_11_STATISTICS_STRUCT *prStatistics; |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_802_11_STATISTICS_STRUCT); |
| prStatistics = (struct PARAM_802_11_STATISTICS_STRUCT *) |
| pvQueryBuffer; |
| |
| prStatistics->u4Length = sizeof(struct |
| PARAM_802_11_STATISTICS_STRUCT); |
| prStatistics->rTransmittedFragmentCount = |
| prAdapter->rStatStruct.rTransmittedFragmentCount; |
| prStatistics->rMulticastTransmittedFrameCount = |
| prAdapter->rStatStruct.rMulticastTransmittedFrameCount; |
| prStatistics->rFailedCount = |
| prAdapter->rStatStruct.rFailedCount; |
| prStatistics->rRetryCount = |
| prAdapter->rStatStruct.rRetryCount; |
| prStatistics->rMultipleRetryCount = |
| prAdapter->rStatStruct.rMultipleRetryCount; |
| prStatistics->rRTSSuccessCount = |
| prAdapter->rStatStruct.rRTSSuccessCount; |
| prStatistics->rRTSFailureCount = |
| prAdapter->rStatStruct.rRTSFailureCount; |
| prStatistics->rACKFailureCount = |
| prAdapter->rStatStruct.rACKFailureCount; |
| prStatistics->rFrameDuplicateCount = |
| prAdapter->rStatStruct.rFrameDuplicateCount; |
| prStatistics->rReceivedFragmentCount = |
| prAdapter->rStatStruct.rReceivedFragmentCount; |
| prStatistics->rMulticastReceivedFrameCount = |
| prAdapter->rStatStruct.rMulticastReceivedFrameCount; |
| prStatistics->rFCSErrorCount = |
| prAdapter->rStatStruct.rFCSErrorCount; |
| prStatistics->rTKIPLocalMICFailures.QuadPart = 0; |
| prStatistics->rTKIPICVErrors.QuadPart = 0; |
| prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; |
| prStatistics->rTKIPReplays.QuadPart = 0; |
| prStatistics->rCCMPFormatErrors.QuadPart = 0; |
| prStatistics->rCCMPReplays.QuadPart = 0; |
| prStatistics->rCCMPDecryptErrors.QuadPart = 0; |
| prStatistics->rFourWayHandshakeFailures.QuadPart = 0; |
| prStatistics->rWEPUndecryptableCount.QuadPart = 0; |
| prStatistics->rWEPICVErrorCount.QuadPart = 0; |
| prStatistics->rDecryptSuccessCount.QuadPart = 0; |
| prStatistics->rDecryptFailureCount.QuadPart = 0; |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryStatistics, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_802_11_STATISTICS_STRUCT), |
| (uint8_t *)&rStatistics, |
| pvQueryBuffer, u4QueryBufferLen); |
| |
| } /* wlanoidQueryStatistics */ |
| |
| uint32_t |
| wlanoidQueryBugReport(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryBugReport"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(struct _EVENT_BUG_REPORT_T); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(OID, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(struct |
| _EVENT_BUG_REPORT_T)) { |
| DBGLOG(OID, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_BUG_REPORT, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryBugReport, |
| nicOidCmdTimeoutCommon, |
| 0, NULL, pvQueryBuffer, u4QueryBufferLen); |
| } /* wlanoidQueryBugReport */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to query current media streaming status. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryMediaStreamMode(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryMediaStreamMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(enum ENUM_MEDIA_STREAM_MODE); |
| |
| if (u4QueryBufferLen < *pu4QueryInfoLen) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *(enum ENUM_MEDIA_STREAM_MODE *) pvQueryBuffer = |
| prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? |
| ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidQueryMediaStreamMode */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to enter media streaming mode or exit media |
| * streaming mode |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetMediaStreamMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| enum ENUM_MEDIA_STREAM_MODE eStreamMode; |
| |
| DEBUGFUNC("wlanoidSetMediaStreamMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (u4SetBufferLen < sizeof(enum ENUM_MEDIA_STREAM_MODE)) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *pu4SetInfoLen = sizeof(enum ENUM_MEDIA_STREAM_MODE); |
| |
| eStreamMode = *(enum ENUM_MEDIA_STREAM_MODE *) pvSetBuffer; |
| |
| if (eStreamMode == ENUM_MEDIA_STREAM_OFF) |
| prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; |
| else |
| prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_LINK_ATTRIB, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetMediaStreamMode, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_LINK_ATTRIB), |
| (uint8_t *) &(prAdapter->rWlanInfo.eLinkAttr), |
| pvSetBuffer, u4SetBufferLen); |
| } /* wlanoidSetMediaStreamMode */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to query the permanent MAC address of the |
| * NIC. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryPermanentAddr(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryPermanentAddr"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < MAC_ADDR_LEN) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| COPY_MAC_ADDR(pvQueryBuffer, |
| prAdapter->rWifiVar.aucPermanentAddress); |
| *pu4QueryInfoLen = MAC_ADDR_LEN; |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryPermanentAddr */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to query the MAC address the NIC is |
| * currently using. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryCurrentAddr(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryCurrentAddr"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < MAC_ADDR_LEN) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| COPY_MAC_ADDR(pvQueryBuffer, |
| prAdapter->rWifiVar.aucMacAddress); |
| *pu4QueryInfoLen = MAC_ADDR_LEN; |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryCurrentAddr */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! \brief This routine is called to query NIC link speed. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure |
| * \param[in] pvQueryBuf A pointer to the buffer that holds the result of the |
| * query buffer |
| * \param[in] u4QueryBufLen The length of the query buffer |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryLinkSpeed(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryLinkSpeed"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (prAdapter->fgIsEnableLpdvt) |
| return WLAN_STATUS_NOT_SUPPORTED; |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != |
| PARAM_MEDIA_STATE_CONNECTED) { |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (prAdapter->fgIsLinkRateValid == TRUE && |
| (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) <= |
| CFG_LINK_QUALITY_VALID_PERIOD) { |
| *(uint32_t *) pvQueryBuffer = |
| prAdapter->rLinkQuality.u2LinkSpeed * |
| 5000; /* change to unit of 100bps */ |
| return WLAN_STATUS_SUCCESS; |
| } else { |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_LINK_QUALITY, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryLinkSpeed, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, u4QueryBufferLen); |
| } |
| } /* end of wlanoidQueryLinkSpeed() */ |
| |
| #if CFG_SUPPORT_QA_TOOL |
| #if CFG_SUPPORT_BUFFER_MODE |
| uint32_t |
| wlanoidSetEfusBufferMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_EFUSE_BUFFER_MODE |
| *prSetEfuseBufModeInfo; |
| struct CMD_EFUSE_BUFFER_MODE *prCmdSetEfuseBufModeInfo = |
| NULL; |
| PFN_CMD_DONE_HANDLER pfCmdDoneHandler; |
| uint32_t u4EfuseContentSize, u4QueryInfoLen; |
| u_int8_t fgSetQuery, fgNeedResp; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidSetEfusBufferMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| /* get the buffer mode info */ |
| prSetEfuseBufModeInfo = |
| (struct PARAM_CUSTOM_EFUSE_BUFFER_MODE *) pvSetBuffer; |
| |
| /* copy command header */ |
| prCmdSetEfuseBufModeInfo = (struct CMD_EFUSE_BUFFER_MODE *) |
| kalMemAlloc(sizeof(struct CMD_EFUSE_BUFFER_MODE), |
| VIR_MEM_TYPE); |
| if (prCmdSetEfuseBufModeInfo == NULL) |
| return WLAN_STATUS_FAILURE; |
| kalMemZero(prCmdSetEfuseBufModeInfo, |
| sizeof(struct CMD_EFUSE_BUFFER_MODE)); |
| prCmdSetEfuseBufModeInfo->ucSourceMode = |
| prSetEfuseBufModeInfo->ucSourceMode; |
| prCmdSetEfuseBufModeInfo->ucCount = |
| prSetEfuseBufModeInfo->ucCount; |
| prCmdSetEfuseBufModeInfo->ucCmdType = |
| prSetEfuseBufModeInfo->ucCmdType; |
| prCmdSetEfuseBufModeInfo->ucReserved = |
| prSetEfuseBufModeInfo->ucReserved; |
| |
| /* decide content size and SetQuery / NeedResp flag */ |
| if (prAdapter->fgIsSupportBufferBinSize16Byte == TRUE) { |
| u4EfuseContentSize = sizeof(struct BIN_CONTENT) * |
| EFUSE_CONTENT_SIZE; |
| pfCmdDoneHandler = nicCmdEventSetCommon; |
| fgSetQuery = TRUE; |
| fgNeedResp = FALSE; |
| } else { |
| #if (CFG_FW_Report_Efuse_Address == 1) |
| u4EfuseContentSize = (prAdapter->u4EfuseEndAddress) - |
| (prAdapter->u4EfuseStartAddress) + 1; |
| #else |
| u4EfuseContentSize = EFUSE_CONTENT_BUFFER_SIZE; |
| #endif |
| pfCmdDoneHandler = NULL; |
| fgSetQuery = FALSE; |
| fgNeedResp = TRUE; |
| } |
| |
| u4QueryInfoLen = OFFSET_OF(struct CMD_EFUSE_BUFFER_MODE, |
| aBinContent) + u4EfuseContentSize; |
| |
| if (u4SetBufferLen < u4QueryInfoLen) { |
| kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, |
| sizeof(struct CMD_EFUSE_BUFFER_MODE)); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *pu4SetInfoLen = u4QueryInfoLen; |
| kalMemCopy(prCmdSetEfuseBufModeInfo->aBinContent, |
| prSetEfuseBufModeInfo->aBinContent, |
| u4EfuseContentSize); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_EFUSE_BUFFER_MODE, |
| fgSetQuery, |
| fgNeedResp, |
| g_fgIsOid, |
| pfCmdDoneHandler, |
| nicOidCmdTimeoutCommon, |
| u4QueryInfoLen, |
| (uint8_t *) (prCmdSetEfuseBufModeInfo), |
| pvSetBuffer, u4SetBufferLen); |
| |
| kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, |
| sizeof(struct CMD_EFUSE_BUFFER_MODE)); |
| |
| return rWlanStatus; |
| } |
| |
| uint32_t |
| wlanoidConnacSetEfusBufferMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T |
| *prSetEfuseBufModeInfo; |
| struct CMD_EFUSE_BUFFER_MODE_CONNAC_T |
| *prCmdSetEfuseBufModeInfo = NULL; |
| uint32_t u4EfuseContentSize, u4QueryInfoLen; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidSetEfusBufferMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| DBGLOG(OID, INFO, "u4SetBufferLen = %d\n", u4SetBufferLen); |
| /* get the buffer mode info */ |
| prSetEfuseBufModeInfo = |
| (struct PARAM_CUSTOM_EFUSE_BUFFER_MODE_CONNAC_T *) pvSetBuffer; |
| |
| /* copy command header */ |
| prCmdSetEfuseBufModeInfo = (struct CMD_EFUSE_BUFFER_MODE_CONNAC_T *) |
| kalMemAlloc(sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T), |
| VIR_MEM_TYPE); |
| if (prCmdSetEfuseBufModeInfo == NULL) |
| return WLAN_STATUS_FAILURE; |
| kalMemZero(prCmdSetEfuseBufModeInfo, |
| sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T)); |
| prCmdSetEfuseBufModeInfo->ucSourceMode = |
| prSetEfuseBufModeInfo->ucSourceMode; |
| prCmdSetEfuseBufModeInfo->ucContentFormat = |
| prSetEfuseBufModeInfo->ucContentFormat; |
| prCmdSetEfuseBufModeInfo->u2Count = |
| prSetEfuseBufModeInfo->u2Count; |
| |
| u4EfuseContentSize = prCmdSetEfuseBufModeInfo->u2Count; |
| |
| u4QueryInfoLen = OFFSET_OF(struct |
| CMD_EFUSE_BUFFER_MODE_CONNAC_T, |
| aBinContent) + u4EfuseContentSize; |
| |
| if (u4SetBufferLen < u4QueryInfoLen) { |
| kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, |
| sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T)); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *pu4SetInfoLen = u4QueryInfoLen; |
| kalMemCopy(prCmdSetEfuseBufModeInfo->aBinContent, |
| prSetEfuseBufModeInfo->aBinContent, |
| u4EfuseContentSize); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_EFUSE_BUFFER_MODE, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| NULL, |
| nicOidCmdTimeoutCommon, |
| u4QueryInfoLen, |
| (uint8_t *) (prCmdSetEfuseBufModeInfo), |
| pvSetBuffer, u4SetBufferLen); |
| |
| kalMemFree(prCmdSetEfuseBufModeInfo, VIR_MEM_TYPE, |
| sizeof(struct CMD_EFUSE_BUFFER_MODE_CONNAC_T)); |
| |
| return rWlanStatus; |
| } |
| |
| /*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/ |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to read efuse content. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryProcessAccessEfuseRead(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_ACCESS_EFUSE *prSetAccessEfuseInfo; |
| struct CMD_ACCESS_EFUSE rCmdSetAccessEfuse; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQueryProcessAccessEfuseRead"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_ACCESS_EFUSE)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prSetAccessEfuseInfo = (struct PARAM_CUSTOM_ACCESS_EFUSE *) |
| pvSetBuffer; |
| |
| kalMemSet(&rCmdSetAccessEfuse, 0, |
| sizeof(struct CMD_ACCESS_EFUSE)); |
| |
| rCmdSetAccessEfuse.u4Address = |
| prSetAccessEfuseInfo->u4Address; |
| rCmdSetAccessEfuse.u4Valid = prSetAccessEfuseInfo->u4Valid; |
| |
| |
| DBGLOG(INIT, INFO, |
| "MT6632 : wlanoidQueryProcessAccessEfuseRead, address=%d\n", |
| rCmdSetAccessEfuse.u4Address); |
| |
| kalMemCopy(rCmdSetAccessEfuse.aucData, |
| prSetAccessEfuseInfo->aucData, |
| sizeof(uint8_t) * 16); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_EFUSE_ACCESS, |
| FALSE, /* Query Bit: True->write False->read */ |
| TRUE, |
| g_fgIsOid, |
| NULL, /* No Tx done function wait until fw ack */ |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_EFUSE), |
| (uint8_t *) (&rCmdSetAccessEfuse), pvSetBuffer, |
| u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to write efuse content. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryProcessAccessEfuseWrite(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_ACCESS_EFUSE *prSetAccessEfuseInfo; |
| struct CMD_ACCESS_EFUSE rCmdSetAccessEfuse; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQueryProcessAccessEfuseWrite"); |
| DBGLOG(INIT, INFO, |
| "MT6632 : wlanoidQueryProcessAccessEfuseWrite\n"); |
| |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_ACCESS_EFUSE); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_ACCESS_EFUSE)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prSetAccessEfuseInfo = (struct PARAM_CUSTOM_ACCESS_EFUSE *) |
| pvSetBuffer; |
| |
| kalMemSet(&rCmdSetAccessEfuse, 0, |
| sizeof(struct CMD_ACCESS_EFUSE)); |
| |
| rCmdSetAccessEfuse.u4Address = |
| prSetAccessEfuseInfo->u4Address; |
| rCmdSetAccessEfuse.u4Valid = prSetAccessEfuseInfo->u4Valid; |
| |
| DBGLOG(INIT, INFO, |
| "MT6632 : wlanoidQueryProcessAccessEfuseWrite, address=%d\n", |
| rCmdSetAccessEfuse.u4Address); |
| |
| |
| kalMemCopy(rCmdSetAccessEfuse.aucData, |
| prSetAccessEfuseInfo->aucData, |
| sizeof(uint8_t) * 16); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_EFUSE_ACCESS, |
| TRUE, /* Query Bit: True->write False->read*/ |
| TRUE, |
| g_fgIsOid, |
| NULL, /* No Tx done function wait until fw ack */ |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_EFUSE), |
| (uint8_t *) (&rCmdSetAccessEfuse), pvSetBuffer, |
| u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| |
| |
| |
| |
| uint32_t |
| wlanoidQueryEfuseFreeBlock(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_EFUSE_FREE_BLOCK |
| *prGetEfuseFreeBlockInfo; |
| struct CMD_EFUSE_FREE_BLOCK rCmdGetEfuseFreeBlock; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQueryEfuseFreeBlock"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_EFUSE_FREE_BLOCK); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_EFUSE_FREE_BLOCK)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prGetEfuseFreeBlockInfo = (struct |
| PARAM_CUSTOM_EFUSE_FREE_BLOCK *) pvSetBuffer; |
| |
| kalMemSet(&rCmdGetEfuseFreeBlock, 0, |
| sizeof(struct CMD_EFUSE_FREE_BLOCK)); |
| |
| rCmdGetEfuseFreeBlock.ucVersion = 1;/*1:new version, 0:old version*/ |
| rCmdGetEfuseFreeBlock.ucDieIndex = 0;/*0:D Die, 1: A die */ |
| |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_EFUSE_FREE_BLOCK, |
| FALSE, /* Query Bit: True->write False->read */ |
| TRUE, |
| g_fgIsOid, |
| NULL, /* No Tx done function wait until fw ack */ |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_EFUSE_FREE_BLOCK), |
| (uint8_t *) (&rCmdGetEfuseFreeBlock), pvSetBuffer, |
| u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryGetTxPower(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_GET_TX_POWER *prGetTxPowerInfo; |
| struct CMD_GET_TX_POWER rCmdGetTxPower; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQueryGetTxPower"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_GET_TX_POWER *); |
| |
| if (u4SetBufferLen < sizeof(struct PARAM_CUSTOM_GET_TX_POWER |
| *)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prGetTxPowerInfo = (struct PARAM_CUSTOM_GET_TX_POWER *) |
| pvSetBuffer; |
| |
| kalMemSet(&rCmdGetTxPower, 0, |
| sizeof(struct CMD_GET_TX_POWER)); |
| |
| rCmdGetTxPower.ucTxPwrType = EXT_EVENT_TARGET_TX_POWER; |
| rCmdGetTxPower.ucCenterChannel = |
| prGetTxPowerInfo->ucCenterChannel; |
| rCmdGetTxPower.ucDbdcIdx = prGetTxPowerInfo->ucDbdcIdx; |
| rCmdGetTxPower.ucBand = prGetTxPowerInfo->ucBand; |
| |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_GET_TX_POWER, |
| FALSE, /* Query Bit: True->write False->read*/ |
| TRUE, |
| g_fgIsOid, |
| NULL, /* No Tx done function wait until fw ack */ |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_GET_TX_POWER), |
| (uint8_t *) (&rCmdGetTxPower), |
| pvSetBuffer, u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| |
| |
| /*#endif*/ |
| |
| #endif /* CFG_SUPPORT_BUFFER_MODE */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query RX statistics. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRxStatistics(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_ACCESS_RX_STAT *prRxStatistics; |
| struct CMD_ACCESS_RX_STAT *prCmdAccessRxStat; |
| struct CMD_ACCESS_RX_STAT rCmdAccessRxStat; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| /* UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; */ |
| uint32_t u4SeqNum = 0; |
| uint32_t u4TotalNum = 0; |
| |
| prCmdAccessRxStat = &rCmdAccessRxStat; |
| |
| DEBUGFUNC("wlanoidQueryRxStatistics"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| DBGLOG(INIT, ERROR, "MT6632 : wlanoidQueryRxStatistics\n"); |
| |
| prRxStatistics = (struct PARAM_CUSTOM_ACCESS_RX_STAT *) |
| pvQueryBuffer; |
| |
| *pu4QueryInfoLen = 8 + prRxStatistics->u4TotalNum; |
| |
| u4SeqNum = prRxStatistics->u4SeqNum; |
| u4TotalNum = prRxStatistics->u4TotalNum; |
| |
| do { |
| prCmdAccessRxStat->u4SeqNum = u4SeqNum; |
| prCmdAccessRxStat->u4TotalNum = u4TotalNum; |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ACCESS_RX_STAT, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryRxStatistics, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_RX_STAT), |
| (uint8_t *) prCmdAccessRxStat, pvQueryBuffer, |
| u4QueryBufferLen); |
| } while (FALSE); |
| |
| return rStatus; |
| } |
| |
| #if CFG_SUPPORT_TX_BF |
| |
| uint32_t |
| wlanoidStaRecUpdate(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_STAREC_UPDATE *prStaRecUpdateInfo; |
| struct STAREC_COMMON *prStaRecCmm; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidStaRecUpdate"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct STAREC_COMMON); |
| if (u4SetBufferLen < sizeof(struct STAREC_COMMON)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prStaRecUpdateInfo = |
| (struct CMD_STAREC_UPDATE *) cnmMemAlloc(prAdapter, |
| RAM_TYPE_MSG, (CMD_STAREC_UPDATE_HDR_SIZE + |
| u4SetBufferLen)); |
| if (!prStaRecUpdateInfo) { |
| DBGLOG(INIT, ERROR, |
| "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| /* fix me: configurable ucBssIndex */ |
| prStaRecCmm = (struct STAREC_COMMON *) pvSetBuffer; |
| prStaRecUpdateInfo->ucBssIndex = 0; |
| prStaRecUpdateInfo->ucWlanIdx = prStaRecCmm->u2Reserve1; |
| prStaRecUpdateInfo->u2TotalElementNum = 1; |
| kalMemCopy(prStaRecUpdateInfo->aucBuffer, pvSetBuffer, |
| u4SetBufferLen); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_STAREC_UPDATE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen), |
| (uint8_t *) prStaRecUpdateInfo, NULL, 0); |
| |
| cnmMemFree(prAdapter, prStaRecUpdateInfo); |
| |
| return rWlanStatus; |
| } |
| |
| uint32_t |
| wlanoidStaRecBFUpdate(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_STAREC_UPDATE *prStaRecUpdateInfo; |
| struct CMD_STAREC_BF *prStaRecBF; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidStaRecBFUpdate"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct CMD_STAREC_BF); |
| if (u4SetBufferLen < sizeof(struct CMD_STAREC_BF)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prStaRecUpdateInfo = |
| (struct CMD_STAREC_UPDATE *) cnmMemAlloc(prAdapter, |
| RAM_TYPE_MSG, (CMD_STAREC_UPDATE_HDR_SIZE + |
| u4SetBufferLen)); |
| if (!prStaRecUpdateInfo) { |
| DBGLOG(INIT, ERROR, |
| "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| /* fix me: configurable ucBssIndex */ |
| prStaRecBF = (struct CMD_STAREC_BF *) pvSetBuffer; |
| prStaRecUpdateInfo->ucBssIndex = prStaRecBF->ucReserved[0]; |
| prStaRecUpdateInfo->ucWlanIdx = prStaRecBF->ucReserved[1]; |
| prStaRecUpdateInfo->u2TotalElementNum = 1; |
| kalMemCopy(prStaRecUpdateInfo->aucBuffer, pvSetBuffer, |
| u4SetBufferLen); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_STAREC_UPDATE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen), |
| (uint8_t *) prStaRecUpdateInfo, NULL, 0); |
| |
| cnmMemFree(prAdapter, prStaRecUpdateInfo); |
| |
| return rWlanStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief extend command packet generation utility |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] ucCID Command ID |
| * \param[in] ucExtCID Extend command ID |
| * \param[in] fgSetQuery Set or Query |
| * \param[in] fgNeedResp Need for response |
| * \param[in] pfCmdDoneHandler Function pointer when command is done |
| * \param[in] u4SetQueryInfoLen The length of the set/query buffer |
| * \param[in] pucInfoBuffer Pointer to set/query buffer |
| * |
| * |
| * \retval WLAN_STATUS_PENDING |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanSendSetQueryExtCmd(IN struct ADAPTER *prAdapter, |
| uint8_t ucCID, |
| uint8_t ucExtCID, |
| u_int8_t fgSetQuery, |
| u_int8_t fgNeedResp, |
| u_int8_t fgIsOid, |
| PFN_CMD_DONE_HANDLER pfCmdDoneHandler, |
| PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, |
| uint32_t u4SetQueryInfoLen, |
| uint8_t *pucInfoBuffer, OUT void *pvSetQueryBuffer, |
| IN uint32_t u4SetQueryBufferLen) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| uint8_t ucCmdSeqNum; |
| |
| if (kalIsResetting()) { |
| DBGLOG(INIT, WARN, "Chip resetting, skip\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + u4SetQueryInfoLen)); |
| |
| DEBUGFUNC("wlanSendSetQueryCmd"); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); |
| |
| /* Setup common CMD Info Packet */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->u2InfoBufLen = (uint16_t) (CMD_HDR_SIZE + |
| u4SetQueryInfoLen); |
| prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; |
| prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; |
| prCmdInfo->fgIsOid = fgIsOid; |
| prCmdInfo->ucCID = ucCID; |
| prCmdInfo->fgSetQuery = fgSetQuery; |
| prCmdInfo->fgNeedResp = fgNeedResp; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; |
| prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; |
| |
| /* Setup WIFI_CMD_T (no payload) */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->u2Length = prCmdInfo->u2InfoBufLen - |
| (uint16_t) OFFSET_OF(struct WIFI_CMD, u2Length); |
| prWifiCmd->u2PqId = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucExtenCID = ucExtCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) |
| kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, |
| u4SetQueryInfoLen); |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| return WLAN_STATUS_PENDING; |
| } |
| |
| uint32_t |
| wlanoidBssInfoBasic(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_BSS_INFO_UPDATE *prBssInfoUpdateBasic; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidManualAssoc"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct BSSINFO_BASIC); |
| if (u4SetBufferLen < sizeof(struct BSSINFO_BASIC)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prBssInfoUpdateBasic = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, |
| (CMD_BSSINFO_UPDATE_HDR_SIZE + u4SetBufferLen)); |
| if (!prBssInfoUpdateBasic) { |
| DBGLOG(INIT, ERROR, |
| "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| /* fix me: configurable ucBssIndex */ |
| prBssInfoUpdateBasic->ucBssIndex = 0; |
| prBssInfoUpdateBasic->u2TotalElementNum = 1; |
| kalMemCopy(prBssInfoUpdateBasic->aucBuffer, pvSetBuffer, |
| u4SetBufferLen); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_BSSINFO_UPDATE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| (CMD_BSSINFO_UPDATE_HDR_SIZE + u4SetBufferLen), |
| (uint8_t *) prBssInfoUpdateBasic, NULL, 0); |
| |
| cnmMemFree(prAdapter, prBssInfoUpdateBasic); |
| |
| return rWlanStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to do Coex Isolation Detection. |
| |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * eturns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS* \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryCoexIso(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| struct PARAM_COEX_HANDLER *prParaCoexHandler; |
| struct PARAM_COEX_ISO_DETECT *prParaCoexIsoDetect; |
| struct CMD_COEX_HANDLER rCmdCoexHandler; |
| struct CMD_COEX_ISO_DETECT rCmdCoexIsoDetect; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_COEX_HANDLER); |
| |
| if (u4QueryBufferLen < sizeof(struct PARAM_COEX_HANDLER)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prParaCoexHandler = |
| (struct PARAM_COEX_HANDLER *) pvQueryBuffer; |
| prParaCoexIsoDetect = |
| (struct PARAM_COEX_ISO_DETECT *) &prParaCoexHandler->aucBuffer[0]; |
| |
| rCmdCoexIsoDetect.u4Channel = prParaCoexIsoDetect->u4Channel; |
| rCmdCoexIsoDetect.u4IsoPath = prParaCoexIsoDetect->u4IsoPath; |
| rCmdCoexIsoDetect.u4Isolation = prParaCoexIsoDetect->u4Isolation; |
| |
| rCmdCoexHandler.u4SubCmd = prParaCoexHandler->u4SubCmd; |
| |
| /* Copy Memory */ |
| kalMemCopy(rCmdCoexHandler.aucBuffer, |
| &rCmdCoexIsoDetect, |
| sizeof(rCmdCoexIsoDetect)); |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_COEX_CTRL, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryCoexIso, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_COEX_HANDLER), |
| (unsigned char *) &rCmdCoexHandler, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } |
| |
| uint32_t |
| wlanoidQueryCoexGetInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| struct PARAM_COEX_HANDLER *prParaCoexHandler; |
| struct PARAM_COEX_GET_INFO *prParaCoexGetInfo; |
| struct CMD_COEX_HANDLER rCmdCoexHandler; |
| struct CMD_COEX_GET_INFO rCmdCoexGetInfo; |
| |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_COEX_HANDLER); |
| |
| if (u4QueryBufferLen < sizeof(struct PARAM_COEX_HANDLER)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prParaCoexHandler = |
| (struct PARAM_COEX_HANDLER *)pvQueryBuffer; |
| prParaCoexGetInfo = |
| (struct PARAM_COEX_GET_INFO *)&prParaCoexHandler->aucBuffer[0]; |
| |
| kalMemZero(rCmdCoexGetInfo.ucCoexInfo, |
| sizeof(rCmdCoexGetInfo.ucCoexInfo)); |
| |
| rCmdCoexHandler.u4SubCmd = prParaCoexHandler->u4SubCmd; |
| |
| /* Copy Memory */ |
| kalMemCopy(rCmdCoexHandler.aucBuffer, |
| &rCmdCoexGetInfo, |
| sizeof(struct CMD_COEX_GET_INFO)); |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_COEX_CTRL, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCoexGetInfo, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_COEX_HANDLER), |
| (unsigned char *) &rCmdCoexHandler, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| } |
| |
| uint32_t |
| wlanoidDevInfoActive(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_DEV_INFO_UPDATE *prDevInfoUpdateActive; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidManualAssoc"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct CMD_DEVINFO_ACTIVE); |
| if (u4SetBufferLen < sizeof(struct CMD_DEVINFO_ACTIVE)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prDevInfoUpdateActive = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, |
| (CMD_DEVINFO_UPDATE_HDR_SIZE + u4SetBufferLen)); |
| if (!prDevInfoUpdateActive) { |
| DBGLOG(INIT, ERROR, |
| "Allocate P_CMD_DEV_INFO_UPDATE_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| /* fix me: configurable ucOwnMacIdx */ |
| prDevInfoUpdateActive->ucOwnMacIdx = 0; |
| prDevInfoUpdateActive->ucAppendCmdTLV = 0; |
| prDevInfoUpdateActive->u2TotalElementNum = 1; |
| kalMemCopy(prDevInfoUpdateActive->aucBuffer, pvSetBuffer, |
| u4SetBufferLen); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_DEVINFO_UPDATE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| (CMD_DEVINFO_UPDATE_HDR_SIZE + u4SetBufferLen), |
| (uint8_t *) prDevInfoUpdateActive, NULL, 0); |
| |
| cnmMemFree(prAdapter, prDevInfoUpdateActive); |
| |
| return rWlanStatus; |
| } |
| |
| uint32_t |
| wlanoidManualAssoc(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_STAREC_UPDATE *prStaRecManualAssoc; |
| struct CMD_MANUAL_ASSOC_STRUCT *prManualAssoc; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidManualAssoc"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct CMD_STAREC_UPDATE); |
| if (u4SetBufferLen < sizeof(struct CMD_STAREC_UPDATE)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prStaRecManualAssoc = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, |
| (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen)); |
| if (!prStaRecManualAssoc) { |
| DBGLOG(INIT, ERROR, |
| "Allocate P_CMD_STAREC_UPDATE_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prManualAssoc = (struct CMD_MANUAL_ASSOC_STRUCT *) |
| pvSetBuffer; |
| prStaRecManualAssoc->ucWlanIdx = prManualAssoc->ucWtbl; |
| prStaRecManualAssoc->ucBssIndex = prManualAssoc->ucOwnmac; |
| prStaRecManualAssoc->u2TotalElementNum = 1; |
| kalMemCopy(prStaRecManualAssoc->aucBuffer, pvSetBuffer, |
| u4SetBufferLen); |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_STAREC_UPDATE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| (CMD_STAREC_UPDATE_HDR_SIZE + u4SetBufferLen), |
| (uint8_t *) prStaRecManualAssoc, NULL, 0); |
| |
| cnmMemFree(prAdapter, prStaRecManualAssoc); |
| |
| return rWlanStatus; |
| } |
| |
| struct TXBF_CMD_DONE_HANDLER { |
| uint32_t u4TxBfCmdId; |
| void (*pFunc)(struct ADAPTER *, struct CMD_INFO *, |
| uint8_t *); |
| }; |
| |
| struct TXBF_CMD_DONE_HANDLER rTxBfCmdDoneHandler[] = { |
| {BF_SOUNDING_OFF, nicCmdEventSetCommon}, |
| {BF_SOUNDING_ON, nicCmdEventSetCommon}, |
| {BF_DATA_PACKET_APPLY, nicCmdEventSetCommon}, |
| {BF_PFMU_MEM_ALLOCATE, nicCmdEventSetCommon}, |
| {BF_PFMU_MEM_RELEASE, nicCmdEventSetCommon}, |
| {BF_PFMU_TAG_READ, nicCmdEventPfmuTagRead}, |
| {BF_PFMU_TAG_WRITE, nicCmdEventSetCommon}, |
| {BF_PROFILE_READ, nicCmdEventPfmuDataRead}, |
| {BF_PROFILE_WRITE, nicCmdEventSetCommon}, |
| {BF_PN_READ, nicCmdEventSetCommon}, |
| {BF_PN_WRITE, nicCmdEventSetCommon}, |
| {BF_PFMU_MEM_ALLOC_MAP_READ, nicCmdEventSetCommon}, |
| #if CFG_SUPPORT_TX_BF_FPGA |
| {BF_PFMU_SW_TAG_WRITE, nicCmdEventSetCommon} |
| #endif |
| }; |
| |
| uint32_t |
| wlanoidTxBfAction(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| union PARAM_CUSTOM_TXBF_ACTION_STRUCT *prTxBfActionInfo; |
| union CMD_TXBF_ACTION rCmdTxBfActionInfo; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| u_int8_t fgSetQuery, fgNeedResp; |
| uint32_t u4TxBfCmdId; |
| uint8_t ucIdx; |
| |
| DEBUGFUNC("wlanoidTxBfAction"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(union |
| PARAM_CUSTOM_TXBF_ACTION_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(union |
| PARAM_CUSTOM_TXBF_ACTION_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prTxBfActionInfo = (union PARAM_CUSTOM_TXBF_ACTION_STRUCT *) |
| pvSetBuffer; |
| |
| memcpy(&rCmdTxBfActionInfo, prTxBfActionInfo, |
| sizeof(union CMD_TXBF_ACTION)); |
| |
| u4TxBfCmdId = |
| rCmdTxBfActionInfo.rProfileTagRead.ucTxBfCategory; |
| if (TXBF_CMD_NEED_TO_RESPONSE(u4TxBfCmdId) == |
| 0) { /* don't need response */ |
| fgSetQuery = TRUE; |
| fgNeedResp = FALSE; |
| } else { |
| fgSetQuery = FALSE; |
| fgNeedResp = TRUE; |
| } |
| |
| for (ucIdx = 0; ucIdx < ARRAY_SIZE(rTxBfCmdDoneHandler); |
| ucIdx++) { |
| if (u4TxBfCmdId == rTxBfCmdDoneHandler[ucIdx].u4TxBfCmdId) |
| break; |
| } |
| |
| if (ucIdx == ARRAY_SIZE(rTxBfCmdDoneHandler)) { |
| DBGLOG(RFTEST, ERROR, |
| "ucIdx [%d] overrun of rTxBfCmdDoneHandler\n", ucIdx); |
| return WLAN_STATUS_NOT_SUPPORTED; |
| } |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_BF_ACTION, |
| fgSetQuery, |
| fgNeedResp, |
| g_fgIsOid, |
| rTxBfCmdDoneHandler[ucIdx].pFunc, |
| nicOidCmdTimeoutCommon, |
| sizeof(union CMD_TXBF_ACTION), |
| (uint8_t *) &rCmdTxBfActionInfo, |
| pvSetBuffer, |
| u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| |
| #if CFG_SUPPORT_MU_MIMO |
| uint32_t |
| wlanoidMuMimoAction(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_MUMIMO_ACTION_STRUCT |
| *prMuMimoActionInfo; |
| union CMD_MUMIMO_ACTION rCmdMuMimoActionInfo; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| u_int8_t fgSetQuery, fgNeedResp; |
| uint32_t u4MuMimoCmdId; |
| void (*pFunc)(struct ADAPTER *, struct CMD_INFO *, |
| uint8_t *); |
| |
| DEBUGFUNC("wlanoidMuMimoAction"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_MUMIMO_ACTION_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_MUMIMO_ACTION_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prMuMimoActionInfo = (struct |
| PARAM_CUSTOM_MUMIMO_ACTION_STRUCT *) pvSetBuffer; |
| |
| memcpy(&rCmdMuMimoActionInfo, prMuMimoActionInfo, |
| sizeof(union CMD_MUMIMO_ACTION)); |
| |
| u4MuMimoCmdId = rCmdMuMimoActionInfo.ucMuMimoCategory; |
| if (MU_CMD_NEED_TO_RESPONSE(u4MuMimoCmdId) == 0) { |
| fgSetQuery = TRUE; |
| fgNeedResp = FALSE; |
| } else { |
| fgSetQuery = FALSE; |
| fgNeedResp = TRUE; |
| } |
| |
| pFunc = nicCmdEventSetCommon; |
| if (u4MuMimoCmdId == MU_HQA_GET_QD) |
| pFunc = nicCmdEventGetQd; |
| else if (u4MuMimoCmdId == MU_HQA_GET_CALC_LQ) |
| pFunc = nicCmdEventGetCalcLq; |
| else if (u4MuMimoCmdId == MU_GET_CALC_INIT_MCS) |
| pFunc = nicCmdEventGetCalcInitMcs; |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_MU_CTRL, |
| fgSetQuery, |
| fgNeedResp, |
| g_fgIsOid, |
| pFunc, |
| nicOidCmdTimeoutCommon, |
| sizeof(union CMD_MUMIMO_ACTION), |
| (uint8_t *) &rCmdMuMimoActionInfo, |
| pvSetBuffer, |
| u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| #endif /* CFG_SUPPORT_MU_MIMO */ |
| #endif /* CFG_SUPPORT_TX_BF */ |
| #endif /* CFG_SUPPORT_QA_TOOL */ |
| |
| #if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to Trigger FW Cal for Backup Cal Data to Host |
| * Side. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetCalBackup(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| struct PARAM_CAL_BACKUP_STRUCT_V2 *prCalBackupDataV2Info; |
| |
| DBGLOG(RFTEST, INFO, "%s\n", __func__); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CAL_BACKUP_STRUCT_V2); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CAL_BACKUP_STRUCT_V2)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prCalBackupDataV2Info = (struct PARAM_CAL_BACKUP_STRUCT_V2 |
| *) pvSetBuffer; |
| |
| if (prCalBackupDataV2Info->ucReason == 1 |
| && prCalBackupDataV2Info->ucAction == 2) { |
| /* Trigger All Cal Function */ |
| return wlanoidSendCalBackupV2Cmd(prAdapter, pvSetBuffer, |
| u4SetBufferLen); |
| } else if (prCalBackupDataV2Info->ucReason == 4 |
| && prCalBackupDataV2Info->ucAction == 6) { |
| /* For Debug Use, Tell FW Print Cal Data (Rom or Ram) */ |
| return wlanoidSendCalBackupV2Cmd(prAdapter, pvSetBuffer, |
| u4SetBufferLen); |
| } else if (prCalBackupDataV2Info->ucReason == 3 |
| && prCalBackupDataV2Info->ucAction == 5) { |
| /* Send Cal Data to FW */ |
| if (prCalBackupDataV2Info->ucRomRam == 0) |
| prCalBackupDataV2Info->u4RemainLength = |
| g_rBackupCalDataAllV2.u4ValidRomCalDataLength; |
| else if (prCalBackupDataV2Info->ucRomRam == 1) |
| prCalBackupDataV2Info->u4RemainLength = |
| g_rBackupCalDataAllV2.u4ValidRamCalDataLength; |
| |
| return wlanoidSendCalBackupV2Cmd(prAdapter, pvSetBuffer, |
| u4SetBufferLen); |
| } |
| |
| return rWlanStatus; |
| } |
| |
| uint32_t wlanoidSendCalBackupV2Cmd(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen) { |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| struct PARAM_CAL_BACKUP_STRUCT_V2 *prCalBackupDataV2Info; |
| struct CMD_CAL_BACKUP_STRUCT_V2 *prCmdCalBackupDataV2; |
| uint8_t ucReason, ucAction, ucNeedResp, ucFragNum, ucRomRam; |
| uint32_t u4DumpMaxSize = PARAM_CAL_DATA_DUMP_MAX_SIZE; |
| uint32_t u4RemainLength, u4CurrAddr, u4CurrLen; |
| |
| DBGLOG(RFTEST, INFO, "%s\n", __func__); |
| |
| prCmdCalBackupDataV2 = (struct CMD_CAL_BACKUP_STRUCT_V2 *) |
| kalMemAlloc(sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), |
| VIR_MEM_TYPE); |
| |
| prCalBackupDataV2Info = (struct PARAM_CAL_BACKUP_STRUCT_V2 *) |
| pvQueryBuffer; |
| |
| ucReason = prCalBackupDataV2Info->ucReason; |
| ucAction = prCalBackupDataV2Info->ucAction; |
| ucNeedResp = prCalBackupDataV2Info->ucNeedResp; |
| ucRomRam = prCalBackupDataV2Info->ucRomRam; |
| |
| if (ucAction == 2) { |
| /* Trigger All Cal Function */ |
| prCmdCalBackupDataV2->ucReason = ucReason; |
| prCmdCalBackupDataV2->ucAction = ucAction; |
| prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; |
| prCmdCalBackupDataV2->ucFragNum = |
| prCalBackupDataV2Info->ucFragNum; |
| prCmdCalBackupDataV2->ucRomRam = ucRomRam; |
| prCmdCalBackupDataV2->u4ThermalValue = |
| prCalBackupDataV2Info->u4ThermalValue; |
| prCmdCalBackupDataV2->u4Address = |
| prCalBackupDataV2Info->u4Address; |
| prCmdCalBackupDataV2->u4Length = |
| prCalBackupDataV2Info->u4Length; |
| prCmdCalBackupDataV2->u4RemainLength = |
| prCalBackupDataV2Info->u4RemainLength; |
| #if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG |
| DBGLOG(RFTEST, INFO, |
| "=========== Driver Send Query CMD#0 or CMD#1 (Info) ===========\n"); |
| DBGLOG(RFTEST, INFO, "Reason = %d\n", |
| prCmdCalBackupDataV2->ucReason); |
| DBGLOG(RFTEST, INFO, "Action = %d\n", |
| prCmdCalBackupDataV2->ucAction); |
| DBGLOG(RFTEST, INFO, "NeedResp = %d\n", |
| prCmdCalBackupDataV2->ucNeedResp); |
| DBGLOG(RFTEST, INFO, "FragNum = %d\n", |
| prCmdCalBackupDataV2->ucFragNum); |
| DBGLOG(RFTEST, INFO, "RomRam = %d\n", |
| prCmdCalBackupDataV2->ucRomRam); |
| DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", |
| prCmdCalBackupDataV2->u4ThermalValue); |
| DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", |
| prCmdCalBackupDataV2->u4Address); |
| DBGLOG(RFTEST, INFO, "Length = %d\n", |
| prCmdCalBackupDataV2->u4Length); |
| DBGLOG(RFTEST, INFO, "RemainLength = %d\n", |
| prCmdCalBackupDataV2->u4RemainLength); |
| DBGLOG(RFTEST, INFO, |
| "================================================================\n"); |
| #endif |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_CAL_BACKUP_IN_HOST_V2, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| NULL, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), |
| (uint8_t *) prCmdCalBackupDataV2, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); |
| } else if (ucAction == 0 || ucAction == 1 |
| || ucAction == 6) { |
| /* Query CMD#0 and CMD#1. */ |
| /* For Thermal Value and Total Cal Data Length. */ |
| prCmdCalBackupDataV2->ucReason = ucReason; |
| prCmdCalBackupDataV2->ucAction = ucAction; |
| prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; |
| prCmdCalBackupDataV2->ucFragNum = |
| prCalBackupDataV2Info->ucFragNum; |
| prCmdCalBackupDataV2->ucRomRam = ucRomRam; |
| prCmdCalBackupDataV2->u4ThermalValue = |
| prCalBackupDataV2Info->u4ThermalValue; |
| prCmdCalBackupDataV2->u4Address = |
| prCalBackupDataV2Info->u4Address; |
| prCmdCalBackupDataV2->u4Length = |
| prCalBackupDataV2Info->u4Length; |
| prCmdCalBackupDataV2->u4RemainLength = |
| prCalBackupDataV2Info->u4RemainLength; |
| #if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG |
| DBGLOG(RFTEST, INFO, |
| "=========== Driver Send Query CMD#0 or CMD#1 (Info) ===========\n"); |
| DBGLOG(RFTEST, INFO, "Reason = %d\n", |
| prCmdCalBackupDataV2->ucReason); |
| DBGLOG(RFTEST, INFO, "Action = %d\n", |
| prCmdCalBackupDataV2->ucAction); |
| DBGLOG(RFTEST, INFO, "NeedResp = %d\n", |
| prCmdCalBackupDataV2->ucNeedResp); |
| DBGLOG(RFTEST, INFO, "FragNum = %d\n", |
| prCmdCalBackupDataV2->ucFragNum); |
| DBGLOG(RFTEST, INFO, "RomRam = %d\n", |
| prCmdCalBackupDataV2->ucRomRam); |
| DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", |
| prCmdCalBackupDataV2->u4ThermalValue); |
| DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", |
| prCmdCalBackupDataV2->u4Address); |
| DBGLOG(RFTEST, INFO, "Length = %d\n", |
| prCmdCalBackupDataV2->u4Length); |
| DBGLOG(RFTEST, INFO, "RemainLength = %d\n", |
| prCmdCalBackupDataV2->u4RemainLength); |
| DBGLOG(RFTEST, INFO, |
| "================================================================\n"); |
| #endif |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_CAL_BACKUP_IN_HOST_V2, |
| FALSE, |
| TRUE, |
| FALSE, |
| nicCmdEventQueryCalBackupV2, |
| NULL, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), |
| (uint8_t *) prCmdCalBackupDataV2, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); |
| } else if (ucAction == 4) { |
| /* Query All Cal Data from FW (Rom or Ram). */ |
| u4RemainLength = prCalBackupDataV2Info->u4RemainLength; |
| u4CurrAddr = prCalBackupDataV2Info->u4Address + |
| prCalBackupDataV2Info->u4Length; |
| ucFragNum = prCalBackupDataV2Info->ucFragNum + 1; |
| |
| if (u4RemainLength > u4DumpMaxSize) { |
| u4CurrLen = u4DumpMaxSize; |
| u4RemainLength -= u4DumpMaxSize; |
| } else { |
| u4CurrLen = u4RemainLength; |
| u4RemainLength = 0; |
| } |
| |
| prCmdCalBackupDataV2->ucReason = ucReason; |
| prCmdCalBackupDataV2->ucAction = ucAction; |
| prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; |
| prCmdCalBackupDataV2->ucFragNum = ucFragNum; |
| prCmdCalBackupDataV2->ucRomRam = ucRomRam; |
| prCmdCalBackupDataV2->u4ThermalValue = |
| prCalBackupDataV2Info->u4ThermalValue; |
| prCmdCalBackupDataV2->u4Address = u4CurrAddr; |
| prCmdCalBackupDataV2->u4Length = u4CurrLen; |
| prCmdCalBackupDataV2->u4RemainLength = u4RemainLength; |
| #if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG |
| DBGLOG(RFTEST, INFO, |
| "========= Driver Send Query All Cal Data from FW (Info) =========\n"); |
| DBGLOG(RFTEST, INFO, "Reason = %d\n", |
| prCmdCalBackupDataV2->ucReason); |
| DBGLOG(RFTEST, INFO, "Action = %d\n", |
| prCmdCalBackupDataV2->ucAction); |
| DBGLOG(RFTEST, INFO, "NeedResp = %d\n", |
| prCmdCalBackupDataV2->ucNeedResp); |
| DBGLOG(RFTEST, INFO, "FragNum = %d\n", |
| prCmdCalBackupDataV2->ucFragNum); |
| DBGLOG(RFTEST, INFO, "RomRam = %d\n", |
| prCmdCalBackupDataV2->ucRomRam); |
| DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", |
| prCmdCalBackupDataV2->u4ThermalValue); |
| DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", |
| prCmdCalBackupDataV2->u4Address); |
| DBGLOG(RFTEST, INFO, "Length = %d\n", |
| prCmdCalBackupDataV2->u4Length); |
| DBGLOG(RFTEST, INFO, "RemainLength = %d\n", |
| prCmdCalBackupDataV2->u4RemainLength); |
| DBGLOG(RFTEST, INFO, |
| "=================================================================\n"); |
| #endif |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_CAL_BACKUP_IN_HOST_V2, |
| FALSE, |
| TRUE, |
| FALSE, |
| nicCmdEventQueryCalBackupV2, |
| NULL, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), |
| (uint8_t *) prCmdCalBackupDataV2, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); |
| } else if (ucAction == 5) { |
| /* Send All Cal Data to FW (Rom or Ram). */ |
| u4RemainLength = prCalBackupDataV2Info->u4RemainLength; |
| u4CurrAddr = prCalBackupDataV2Info->u4Address + |
| prCalBackupDataV2Info->u4Length; |
| ucFragNum = prCalBackupDataV2Info->ucFragNum + 1; |
| |
| if (u4RemainLength > u4DumpMaxSize) { |
| u4CurrLen = u4DumpMaxSize; |
| u4RemainLength -= u4DumpMaxSize; |
| } else { |
| u4CurrLen = u4RemainLength; |
| u4RemainLength = 0; |
| } |
| |
| prCmdCalBackupDataV2->ucReason = ucReason; |
| prCmdCalBackupDataV2->ucAction = ucAction; |
| prCmdCalBackupDataV2->ucNeedResp = ucNeedResp; |
| prCmdCalBackupDataV2->ucFragNum = ucFragNum; |
| prCmdCalBackupDataV2->ucRomRam = ucRomRam; |
| prCmdCalBackupDataV2->u4ThermalValue = |
| prCalBackupDataV2Info->u4ThermalValue; |
| prCmdCalBackupDataV2->u4Address = u4CurrAddr; |
| prCmdCalBackupDataV2->u4Length = u4CurrLen; |
| prCmdCalBackupDataV2->u4RemainLength = u4RemainLength; |
| #if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG |
| DBGLOG(RFTEST, INFO, |
| "========= Driver Send All Cal Data to FW (Info) =========\n"); |
| DBGLOG(RFTEST, INFO, "Reason = %d\n", |
| prCmdCalBackupDataV2->ucReason); |
| DBGLOG(RFTEST, INFO, "Action = %d\n", |
| prCmdCalBackupDataV2->ucAction); |
| DBGLOG(RFTEST, INFO, "NeedResp = %d\n", |
| prCmdCalBackupDataV2->ucNeedResp); |
| DBGLOG(RFTEST, INFO, "FragNum = %d\n", |
| prCmdCalBackupDataV2->ucFragNum); |
| DBGLOG(RFTEST, INFO, "RomRam = %d\n", |
| prCmdCalBackupDataV2->ucRomRam); |
| DBGLOG(RFTEST, INFO, "ThermalValue = %d\n", |
| prCmdCalBackupDataV2->u4ThermalValue); |
| DBGLOG(RFTEST, INFO, "Address = 0x%08x\n", |
| prCmdCalBackupDataV2->u4Address); |
| DBGLOG(RFTEST, INFO, "Length = %d\n", |
| prCmdCalBackupDataV2->u4Length); |
| DBGLOG(RFTEST, INFO, "RemainLength = %d\n", |
| prCmdCalBackupDataV2->u4RemainLength); |
| #endif |
| /* Copy Cal Data From Driver to FW */ |
| if (prCmdCalBackupDataV2->ucRomRam == 0) |
| kalMemCopy( |
| (uint8_t *)(prCmdCalBackupDataV2->au4Buffer), |
| (uint8_t *)(g_rBackupCalDataAllV2.au4RomCalData) + |
| prCmdCalBackupDataV2->u4Address, |
| prCmdCalBackupDataV2->u4Length); |
| else if (prCmdCalBackupDataV2->ucRomRam == 1) |
| kalMemCopy( |
| (uint8_t *)(prCmdCalBackupDataV2->au4Buffer), |
| (uint8_t *)(g_rBackupCalDataAllV2.au4RamCalData) + |
| prCmdCalBackupDataV2->u4Address, |
| prCmdCalBackupDataV2->u4Length); |
| #if CFG_SUPPORT_CAL_RESULT_BACKUP_TO_HOST_DBGLOG |
| DBGLOG(RFTEST, INFO, |
| "Check some of elements (0x%08x), (0x%08x), (0x%08x), (0x%08x), (0x%08x)\n", |
| prCmdCalBackupDataV2->au4Buffer[0], |
| prCmdCalBackupDataV2->au4Buffer[1], |
| prCmdCalBackupDataV2->au4Buffer[2], |
| prCmdCalBackupDataV2->au4Buffer[3], |
| prCmdCalBackupDataV2->au4Buffer[4]); |
| DBGLOG(RFTEST, INFO, |
| "Check some of elements (0x%08x), (0x%08x), (0x%08x), (0x%08x), (0x%08x)\n", |
| prCmdCalBackupDataV2->au4Buffer[( |
| prCmdCalBackupDataV2->u4Length |
| / sizeof(uint32_t)) - 5], |
| prCmdCalBackupDataV2->au4Buffer[( |
| prCmdCalBackupDataV2->u4Length |
| / sizeof(uint32_t)) - 4], |
| prCmdCalBackupDataV2->au4Buffer[( |
| prCmdCalBackupDataV2->u4Length |
| / sizeof(uint32_t)) - 3], |
| prCmdCalBackupDataV2->au4Buffer[( |
| prCmdCalBackupDataV2->u4Length |
| / sizeof(uint32_t)) - 2], |
| prCmdCalBackupDataV2->au4Buffer[( |
| prCmdCalBackupDataV2->u4Length |
| / sizeof(uint32_t)) - 1]); |
| |
| DBGLOG(RFTEST, INFO, |
| "=================================================================\n"); |
| #endif |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_CAL_BACKUP_IN_HOST_V2, |
| FALSE, |
| TRUE, |
| FALSE, |
| nicCmdEventQueryCalBackupV2, |
| NULL, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2), |
| (uint8_t *) prCmdCalBackupDataV2, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| kalMemFree(prCmdCalBackupDataV2, VIR_MEM_TYPE, |
| sizeof(struct CMD_CAL_BACKUP_STRUCT_V2)); |
| } |
| |
| return rWlanStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryCalBackupV2(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| struct PARAM_CAL_BACKUP_STRUCT_V2 *prCalBackupDataV2Info; |
| |
| DBGLOG(RFTEST, INFO, "%s\n", __func__); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_CAL_BACKUP_STRUCT_V2); |
| |
| prCalBackupDataV2Info = (struct PARAM_CAL_BACKUP_STRUCT_V2 |
| *) pvQueryBuffer; |
| |
| if (prCalBackupDataV2Info->ucReason == 0 |
| && prCalBackupDataV2Info->ucAction == 0) { |
| /* Get Thermal Temp from FW */ |
| return wlanoidSendCalBackupV2Cmd(prAdapter, pvQueryBuffer, |
| u4QueryBufferLen); |
| } else if (prCalBackupDataV2Info->ucReason == 0 |
| && prCalBackupDataV2Info->ucAction == 1) { |
| /* Get Cal Data Size from FW */ |
| return wlanoidSendCalBackupV2Cmd(prAdapter, pvQueryBuffer, |
| u4QueryBufferLen); |
| } else if (prCalBackupDataV2Info->ucReason == 2 |
| && prCalBackupDataV2Info->ucAction == 4) { |
| /* Get Cal Data from FW */ |
| if (prCalBackupDataV2Info->ucRomRam == 0) |
| prCalBackupDataV2Info->u4RemainLength = |
| g_rBackupCalDataAllV2.u4ValidRomCalDataLength; |
| else if (prCalBackupDataV2Info->ucRomRam == 1) |
| prCalBackupDataV2Info->u4RemainLength = |
| g_rBackupCalDataAllV2.u4ValidRamCalDataLength; |
| |
| return wlanoidSendCalBackupV2Cmd(prAdapter, pvQueryBuffer, |
| u4QueryBufferLen); |
| } else { |
| return rWlanStatus; |
| } |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query MCR value. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryMcrRead(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrRdInfo; |
| struct CMD_ACCESS_REG rCmdAccessReg; |
| |
| DEBUGFUNC("wlanoidQueryMcrRead"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_CUSTOM_MCR_RW_STRUCT); |
| |
| if (u4QueryBufferLen < sizeof(struct |
| PARAM_CUSTOM_MCR_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prMcrRdInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) |
| pvQueryBuffer; |
| |
| /* 0x9000 - 0x9EFF reserved for FW */ |
| #if CFG_SUPPORT_SWCR |
| if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) { |
| swCrReadWriteCmd(prAdapter, SWCR_READ, |
| (uint16_t) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), |
| &prMcrRdInfo->u4McrData); |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif /* CFG_SUPPORT_SWCR */ |
| |
| /* Check if access F/W Domain MCR (due to WiFiSYS is placed from |
| * 0x6000-0000 |
| */ |
| if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) { |
| /* fill command */ |
| rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = 0; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ACCESS_REG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryMcrRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| } else { |
| HAL_MCR_RD(prAdapter, (prMcrRdInfo->u4McrOffset & BITS(2, |
| 31)), /* address is in DWORD unit */ |
| &prMcrRdInfo->u4McrData); |
| |
| DBGLOG(INIT, TRACE, |
| "MCR Read: Offset = %#08x, Data = %#08x\n", |
| prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); |
| return WLAN_STATUS_SUCCESS; |
| } |
| } /* end of wlanoidQueryMcrRead() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to write MCR and enable specific function. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetMcrWrite(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrWrInfo; |
| struct CMD_ACCESS_REG rCmdAccessReg; |
| |
| #if CFG_STRESS_TEST_SUPPORT |
| struct AIS_FSM_INFO *prAisFsmInfo; |
| struct BSS_INFO *prBssInfo = prAdapter->prAisBssInfo; |
| struct STA_RECORD *prStaRec = prBssInfo->prStaRecOfAP; |
| uint32_t u4McrOffset, u4McrData; |
| #endif |
| |
| DEBUGFUNC("wlanoidSetMcrWrite"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_MCR_RW_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_MCR_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prMcrWrInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) |
| pvSetBuffer; |
| |
| /* 0x9000 - 0x9EFF reserved for FW */ |
| /* 0xFFFE reserved for FW */ |
| |
| /* -- Puff Stress Test Begin */ |
| #if CFG_STRESS_TEST_SUPPORT |
| |
| /* 0xFFFFFFFE for Control Rate */ |
| if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) { |
| if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM |
| && prMcrWrInfo->u4McrData > 0) |
| prAdapter->rWifiVar.eRateSetting = |
| (enum ENUM_REGISTRY_FIXED_RATE) |
| (prMcrWrInfo->u4McrData); |
| cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); |
| cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); |
| DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n"); |
| DBGLOG(INIT, TRACE, |
| "[Stress Test] Rate is Changed to index %d...\n", |
| prAdapter->rWifiVar.eRateSetting); |
| } |
| /* 0xFFFFFFFD for Switch Channel */ |
| else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) { |
| if (prMcrWrInfo->u4McrData <= 11 |
| && prMcrWrInfo->u4McrData >= 1) |
| prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData; |
| nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); |
| DBGLOG(INIT, TRACE, |
| "[Stress Test] Channel is switched to %d ...\n", |
| prBssInfo->ucPrimaryChannel); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| /* 0xFFFFFFFFC for Control RF Band and SCO */ |
| else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) { |
| /* Band */ |
| if (prMcrWrInfo->u4McrData & 0x80000000) { |
| /* prBssInfo->eBand = BAND_5G; |
| * prBssInfo->ucPrimaryChannel = 52; // Bond to Channel 52 |
| */ |
| } else { |
| prBssInfo->eBand = BAND_2G4; |
| prBssInfo->ucPrimaryChannel = 8; /* Bond to Channel 6 */ |
| } |
| |
| /* Bandwidth */ |
| if (prMcrWrInfo->u4McrData & 0x00010000) { |
| prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; |
| prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; |
| |
| if (prMcrWrInfo->u4McrData == 0x00010002) { |
| prBssInfo->eBssSCO = CHNL_EXT_SCB; /* U20 */ |
| prBssInfo->ucPrimaryChannel += 2; |
| } else if (prMcrWrInfo->u4McrData == 0x00010001) { |
| prBssInfo->eBssSCO = CHNL_EXT_SCA; /* L20 */ |
| prBssInfo->ucPrimaryChannel -= 2; |
| } else { |
| prBssInfo->eBssSCO = CHNL_EXT_SCA; /* 40 */ |
| } |
| } |
| |
| rlmBssInitForAPandIbss(prAdapter, prBssInfo); |
| } |
| /* 0xFFFFFFFB for HT Capability */ |
| else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) { |
| /* Enable HT Capability */ |
| if (prMcrWrInfo->u4McrData & 0x00000001) { |
| prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; |
| DEBUGFUNC("[Stress Test]Enable HT capability...\n"); |
| } else { |
| prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF); |
| DEBUGFUNC("[Stress Test]Disable HT capability...\n"); |
| } |
| cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); |
| cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); |
| } |
| /* 0xFFFFFFFA for Enable Random Rx Reset */ |
| else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) { |
| rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_RANDOM_RX_RESET_EN, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| /* 0xFFFFFFF9 for Disable Random Rx Reset */ |
| else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) { |
| rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_RANDOM_RX_RESET_DE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| /* 0xFFFFFFF8 for Enable SAPP */ |
| else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) { |
| rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SAPP_EN, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| /* 0xFFFFFFF7 for Disable SAPP */ |
| else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) { |
| rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SAPP_DE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| |
| else |
| #endif |
| /* -- Puff Stress Test End */ |
| |
| /* Check if access F/W Domain MCR */ |
| if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) { |
| |
| /* 0x9000 - 0x9EFF reserved for FW */ |
| #if CFG_SUPPORT_SWCR |
| if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) { |
| swCrReadWriteCmd(prAdapter, SWCR_WRITE, |
| (uint16_t)(prMcrWrInfo->u4McrOffset & |
| BITS(0, 15)), |
| &prMcrWrInfo->u4McrData); |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif /* CFG_SUPPORT_SWCR */ |
| |
| #if 1 |
| /* low power test special command */ |
| if (prMcrWrInfo->u4McrOffset == 0x11111110) { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| /* DbgPrint("Enter test mode\n"); */ |
| prAdapter->fgTestMode = TRUE; |
| return rStatus; |
| } |
| if (prMcrWrInfo->u4McrOffset == 0x11111111) { |
| /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ |
| |
| nicpmSetAcpiPowerD3(prAdapter); |
| kalDevSetPowerState(prAdapter->prGlueInfo, |
| (uint32_t) ParamDeviceStateD3); |
| return WLAN_STATUS_SUCCESS; |
| } |
| if (prMcrWrInfo->u4McrOffset == 0x11111112) { |
| |
| /* DbgPrint("LP enter sleep\n"); */ |
| |
| /* fill command */ |
| rCmdAccessReg.u4Address = |
| prMcrWrInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = |
| prMcrWrInfo->u4McrData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ACCESS_REG, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| #endif |
| |
| #if 1 |
| /* low power test special command */ |
| if (prMcrWrInfo->u4McrOffset == 0x11111110) { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| /* DbgPrint("Enter test mode\n"); */ |
| prAdapter->fgTestMode = TRUE; |
| return rStatus; |
| } |
| if (prMcrWrInfo->u4McrOffset == 0x11111111) { |
| /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ |
| |
| nicpmSetAcpiPowerD3(prAdapter); |
| kalDevSetPowerState(prAdapter->prGlueInfo, |
| (uint32_t) ParamDeviceStateD3); |
| return WLAN_STATUS_SUCCESS; |
| } |
| if (prMcrWrInfo->u4McrOffset == 0x11111112) { |
| |
| /* DbgPrint("LP enter sleep\n"); */ |
| |
| /* fill command */ |
| rCmdAccessReg.u4Address = |
| prMcrWrInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = |
| prMcrWrInfo->u4McrData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ACCESS_REG, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| #endif |
| |
| #if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN |
| if (prMcrWrInfo->u4McrOffset == 0x22220000) { |
| /* read test mode */ |
| kalSetSdioTestPattern(prAdapter->prGlueInfo, |
| TRUE, TRUE); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| if (prMcrWrInfo->u4McrOffset == 0x22220001) { |
| /* write test mode */ |
| kalSetSdioTestPattern(prAdapter->prGlueInfo, |
| TRUE, FALSE); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| if (prMcrWrInfo->u4McrOffset == 0x22220002) { |
| /* leave from test mode */ |
| kalSetSdioTestPattern(prAdapter->prGlueInfo, |
| FALSE, FALSE); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| /* fill command */ |
| rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; |
| rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ACCESS_REG, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_REG), |
| (uint8_t *) &rCmdAccessReg, |
| pvSetBuffer, u4SetBufferLen); |
| } else { |
| HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & |
| BITS(2, 31)), /* address is in DWORD unit */ |
| prMcrWrInfo->u4McrData); |
| |
| DBGLOG(INIT, TRACE, |
| "MCR Write: Offset = %#08x, Data = %#08x\n", |
| prMcrWrInfo->u4McrOffset, |
| prMcrWrInfo->u4McrData); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| } /* wlanoidSetMcrWrite */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query driver MCR value. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryDrvMcrRead(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrRdInfo; |
| /* CMD_ACCESS_REG rCmdAccessReg; */ |
| |
| DEBUGFUNC("wlanoidQueryMcrRead"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_CUSTOM_MCR_RW_STRUCT); |
| |
| if (u4QueryBufferLen < sizeof(struct |
| PARAM_CUSTOM_MCR_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prMcrRdInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) |
| pvQueryBuffer; |
| |
| ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); |
| HAL_MCR_RD(prAdapter, (prMcrRdInfo->u4McrOffset & BITS(2, |
| 31)), &prMcrRdInfo->u4McrData); |
| RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); |
| |
| DBGLOG(INIT, TRACE, |
| "DRV MCR Read: Offset = %#08x, Data = %#08x\n", |
| prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* end of wlanoidQueryMcrRead() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to write MCR and enable specific function. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetDrvMcrWrite(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_MCR_RW_STRUCT *prMcrWrInfo; |
| /* CMD_ACCESS_REG rCmdAccessReg; */ |
| |
| DEBUGFUNC("wlanoidSetMcrWrite"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_MCR_RW_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_MCR_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prMcrWrInfo = (struct PARAM_CUSTOM_MCR_RW_STRUCT *) |
| pvSetBuffer; |
| |
| ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); |
| HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, |
| 31)), prMcrWrInfo->u4McrData); |
| |
| DBGLOG(INIT, TRACE, |
| "DRV MCR Write: Offset = %#08x, Data = %#08x\n", |
| prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetMcrWrite */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query SW CTRL |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQuerySwCtrlRead(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_SW_CTRL_STRUCT *prSwCtrlInfo; |
| uint32_t rWlanStatus; |
| uint16_t u2Id, u2SubId; |
| uint32_t u4Data; |
| |
| struct CMD_SW_DBG_CTRL rCmdSwCtrl; |
| |
| DEBUGFUNC("wlanoidQuerySwCtrlRead"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_CUSTOM_SW_CTRL_STRUCT); |
| |
| if (u4QueryBufferLen < sizeof(struct |
| PARAM_CUSTOM_SW_CTRL_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prSwCtrlInfo = (struct PARAM_CUSTOM_SW_CTRL_STRUCT *) |
| pvQueryBuffer; |
| |
| u2Id = (uint16_t) (prSwCtrlInfo->u4Id >> 16); |
| u2SubId = (uint16_t) (prSwCtrlInfo->u4Id & BITS(0, 15)); |
| u4Data = 0; |
| rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| switch (u2Id) { |
| /* 0x9000 - 0x9EFF reserved for FW */ |
| /* 0xFFFE reserved for FW */ |
| |
| #if CFG_SUPPORT_SWCR |
| case 0x9F00: |
| swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */, |
| (uint16_t) u2SubId, &u4Data); |
| break; |
| #endif /* CFG_SUPPORT_SWCR */ |
| |
| case 0xFFFF: { |
| u4Data = 0x5AA56620; |
| } |
| break; |
| |
| case 0xBABA: |
| switch ((u2SubId >> 8) & BITS(0, 7)) { |
| case 0x00: |
| /* Dump Tx resource and queue status */ |
| qmDumpQueueStatus(prAdapter, NULL, 0); |
| cnmDumpMemoryStatus(prAdapter, NULL, 0); |
| break; |
| |
| case 0x01: |
| /* Dump StaRec info by index */ |
| cnmDumpStaRec(prAdapter, |
| (uint8_t) (u2SubId & BITS(0, 7))); |
| break; |
| |
| case 0x02: |
| /* Dump BSS info by index */ |
| bssDumpBssInfo(prAdapter, |
| (uint8_t) (u2SubId & BITS(0, 7))); |
| break; |
| |
| case 0x03: |
| /*Dump BSS statistics by index */ |
| wlanDumpBssStatistics(prAdapter, |
| (uint8_t) (u2SubId & BITS(0, 7))); |
| break; |
| |
| case 0x04: |
| halDumpHifStatus(prAdapter, NULL, 0); |
| break; |
| |
| default: |
| break; |
| } |
| |
| u4Data = 0xBABABABA; |
| break; |
| |
| case 0x9000: |
| default: { |
| rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; |
| rCmdSwCtrl.u4Data = 0; |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SW_DBG_CTRL, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQuerySwCtrlRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_SW_DBG_CTRL), |
| (uint8_t *) &rCmdSwCtrl, |
| pvQueryBuffer, u4QueryBufferLen); |
| return rWlanStatus; |
| } |
| } /* switch(u2Id) */ |
| |
| prSwCtrlInfo->u4Data = u4Data; |
| |
| return rWlanStatus; |
| |
| } |
| |
| /* end of wlanoidQuerySwCtrlRead() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to write SW CTRL |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetSwCtrlWrite(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_SW_CTRL_STRUCT *prSwCtrlInfo; |
| struct CMD_SW_DBG_CTRL rCmdSwCtrl; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| uint16_t u2Id, u2SubId; |
| uint32_t u4Data; |
| uint8_t ucNss; |
| uint8_t ucChannelWidth; |
| uint8_t ucBssIndex; |
| |
| DEBUGFUNC("wlanoidSetSwCtrlWrite"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| if (!prAdapter) { |
| DBGLOG(INIT, ERROR, "prAdapter is NULL error\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| if (!pu4SetInfoLen) { |
| DBGLOG(INIT, ERROR, "pu4SetInfoLen is NULL error\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_SW_CTRL_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_SW_CTRL_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (!pvSetBuffer) { |
| DBGLOG(INIT, ERROR, "pvSetBuffer is NULL error\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prSwCtrlInfo = (struct PARAM_CUSTOM_SW_CTRL_STRUCT *) |
| pvSetBuffer; |
| |
| u2Id = (uint16_t) (prSwCtrlInfo->u4Id >> 16); |
| u2SubId = (uint16_t) (prSwCtrlInfo->u4Id & BITS(0, 15)); |
| u4Data = prSwCtrlInfo->u4Data; |
| |
| switch (u2Id) { |
| |
| /* 0x9000 - 0x9EFF reserved for FW */ |
| /* 0xFFFE reserved for FW */ |
| |
| #if CFG_SUPPORT_SWCR |
| case 0x9F00: |
| swCrReadWriteCmd(prAdapter, SWCR_WRITE, (uint16_t) u2SubId, |
| &u4Data); |
| break; |
| #endif /* CFG_SUPPORT_SWCR */ |
| |
| case 0x2222: |
| ucNss = (uint8_t)(u4Data & BITS(0, 3)); |
| ucChannelWidth = (uint8_t)((u4Data & BITS(4, 7)) >> 4); |
| ucBssIndex = (uint8_t) u2SubId; |
| |
| if (!IS_BSS_INDEX_VALID(ucBssIndex)) { |
| DBGLOG(RLM, ERROR, |
| "Invalid bssidx:%d\n", ucBssIndex); |
| break; |
| } |
| |
| if ((u2SubId & BITS(8, 15)) != 0) { /* Debug OP change |
| * parameters |
| */ |
| DBGLOG(RLM, INFO, |
| "[UT_OP] BSS[%d] IsBwChange[%d] BW[%d] IsNssChange[%d] Nss[%d]\n", |
| ucBssIndex, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| fgIsOpChangeChannelWidth, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| ucOpChangeChannelWidth, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| fgIsOpChangeNss, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| ucOpChangeNss); |
| |
| DBGLOG(RLM, INFO, |
| "[UT_OP] current OP mode: w[%d] s1[%d] s2[%d] sco[%d] Nss[%d]\n", |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| ucVhtChannelWidth, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| ucVhtChannelFrequencyS1, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| ucVhtChannelFrequencyS2, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| eBssSCO, |
| prAdapter->aprBssInfo[ucBssIndex]-> |
| ucNss); |
| } else { |
| /* ucChannelWidth 0:20MHz, 1:40MHz, 2:80MHz, 3:160MHz |
| * 4:80+80MHz |
| */ |
| DBGLOG(RLM, INFO, |
| "[UT_OP] Change BSS[%d] OpMode to BW[%d] Nss[%d]\n", |
| ucBssIndex, ucChannelWidth, ucNss); |
| rlmChangeOperationMode(prAdapter, ucBssIndex, |
| ucChannelWidth, ucNss, rlmDummyChangeOpHandler); |
| } |
| break; |
| |
| case 0x1000: |
| if (u2SubId == 0x8000) { |
| /* CTIA power save mode setting (code: 0x10008000) */ |
| prAdapter->u4CtiaPowerMode = u4Data; |
| prAdapter->fgEnCtiaPowerMode = TRUE; |
| |
| /* */ |
| { |
| enum PARAM_POWER_MODE ePowerMode; |
| |
| if (prAdapter->u4CtiaPowerMode == 0) |
| /* force to keep in CAM mode */ |
| ePowerMode = Param_PowerModeCAM; |
| else if (prAdapter->u4CtiaPowerMode == 1) |
| ePowerMode = Param_PowerModeMAX_PSP; |
| else |
| ePowerMode = Param_PowerModeFast_PSP; |
| |
| rWlanStatus = nicConfigPowerSaveProfile( |
| prAdapter, |
| prAdapter->prAisBssInfo->ucBssIndex, |
| ePowerMode, g_fgIsOid, |
| PS_CALLER_SW_WRITE); |
| } |
| } |
| break; |
| case 0x1001: |
| if (u2SubId == 0x0) |
| prAdapter->fgEnOnlineScan = (u_int8_t) u4Data; |
| else if (u2SubId == 0x1) |
| prAdapter->fgDisBcnLostDetection = (u_int8_t) u4Data; |
| else if (u2SubId == 0x2) |
| prAdapter->rWifiVar.ucUapsd = (u_int8_t) u4Data; |
| else if (u2SubId == 0x3) { |
| prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15); |
| GET_BSS_INFO_BY_INDEX(prAdapter, |
| u4Data >> 16)->rPmProfSetupInfo.ucBmpDeliveryAC = |
| (uint8_t) prAdapter->u4UapsdAcBmp; |
| GET_BSS_INFO_BY_INDEX(prAdapter, |
| u4Data >> 16)->rPmProfSetupInfo.ucBmpTriggerAC = |
| (uint8_t) prAdapter->u4UapsdAcBmp; |
| } else if (u2SubId == 0x4) |
| prAdapter->fgDisStaAgingTimeoutDetection = |
| (u_int8_t) u4Data; |
| else if (u2SubId == 0x5) |
| prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = |
| (uint8_t) u4Data; |
| else if (u2SubId == 0x0100) { |
| if (u4Data == 2) |
| prAdapter->rWifiVar.ucRxGf = FEATURE_DISABLED; |
| else |
| prAdapter->rWifiVar.ucRxGf = FEATURE_ENABLED; |
| } else if (u2SubId == 0x0101) |
| prAdapter->rWifiVar.ucRxShortGI = (uint8_t) u4Data; |
| else if (u2SubId == 0x0103) { /* AP Mode WMMPS */ |
| DBGLOG(OID, INFO, |
| "ApUapsd 0x10010103 cmd received: %d\n", |
| u4Data); |
| setApUapsdEnable(prAdapter, (u_int8_t) u4Data); |
| } else if (u2SubId == 0x0110) { |
| prAdapter->fgIsEnableLpdvt = (u_int8_t) u4Data; |
| prAdapter->fgEnOnlineScan = (u_int8_t) u4Data; |
| DBGLOG(INIT, INFO, "--- Enable LPDVT [%d] ---\n", |
| prAdapter->fgIsEnableLpdvt); |
| } |
| |
| break; |
| |
| #if CFG_SUPPORT_SWCR |
| case 0x1002: |
| #if CFG_RX_PKTS_DUMP |
| if (u2SubId == 0x0) { |
| if (u4Data) |
| u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT); |
| swCrFrameCheckEnable(prAdapter, u4Data); |
| } |
| #endif |
| if (u2SubId == 0x1) { |
| u_int8_t fgIsEnable; |
| uint8_t ucType; |
| uint32_t u4Timeout; |
| |
| fgIsEnable = (u_int8_t) (u4Data & 0xff); |
| ucType = 0; /* ((u4Data>>4) & 0xf); */ |
| u4Timeout = ((u4Data >> 8) & 0xff); |
| swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, |
| u4Timeout); |
| } |
| break; |
| #endif |
| case 0x1003: /* for debug switches */ |
| switch (u2SubId) { |
| case 1: |
| DBGLOG(OID, INFO, |
| "Enable VoE 5.7 Packet Jitter test\n"); |
| prAdapter->rDebugInfo.fgVoE5_7Test = !!u4Data; |
| break; |
| case 0x0002: |
| { |
| struct CMD_TX_AMPDU rTxAmpdu; |
| uint32_t rStatus; |
| |
| rTxAmpdu.fgEnable = !!u4Data; |
| |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, CMD_ID_TX_AMPDU, TRUE, FALSE, FALSE, |
| NULL, NULL, sizeof(struct CMD_TX_AMPDU), |
| (uint8_t *)&rTxAmpdu, NULL, 0); |
| DBGLOG(OID, INFO, "disable tx ampdu status %u\n", |
| rStatus); |
| break; |
| } |
| default: |
| break; |
| } |
| break; |
| |
| #if CFG_SUPPORT_802_11W |
| case 0x2000: |
| DBGLOG(RSN, INFO, "802.11w test 0x%x\n", u2SubId); |
| if (u2SubId == 0x0) |
| rsnStartSaQuery(prAdapter); |
| if (u2SubId == 0x1) |
| rsnStopSaQuery(prAdapter); |
| if (u2SubId == 0x2) |
| rsnSaQueryRequest(prAdapter, NULL); |
| if (u2SubId == 0x3) { |
| struct BSS_INFO *prBssInfo = prAdapter->prAisBssInfo; |
| |
| authSendDeauthFrame(prAdapter, prBssInfo, |
| prBssInfo->prStaRecOfAP, NULL, 7, NULL); |
| } |
| /* wext_set_mode */ |
| /* |
| * if (u2SubId == 0x3) { |
| * prAdapter->prGlueInfo->rWpaInfo.u4Mfp = |
| * RSN_AUTH_MFP_DISABLED; |
| * } |
| * if (u2SubId == 0x4) { |
| * //prAdapter->rWifiVar.rAisSpecificBssInfo |
| * // .fgMgmtProtection = TRUE; |
| * prAdapter->prGlueInfo->rWpaInfo.u4Mfp = |
| * RSN_AUTH_MFP_OPTIONAL; |
| * } |
| * if (u2SubId == 0x5) { |
| * //prAdapter->rWifiVar.rAisSpecificBssInfo |
| * // .fgMgmtProtection = TRUE; |
| * prAdapter->prGlueInfo->rWpaInfo.u4Mfp = |
| * RSN_AUTH_MFP_REQUIRED; |
| * } |
| */ |
| break; |
| #endif |
| case 0xFFFF: { |
| /* CMD_ACCESS_REG rCmdAccessReg; */ |
| #if 1 /* CFG_MT6573_SMT_TEST */ |
| if (u2SubId == 0x0123) { |
| |
| DBGLOG(HAL, INFO, "set smt fixed rate: %u\n", u4Data); |
| |
| if ((enum ENUM_REGISTRY_FIXED_RATE) (u4Data) < |
| FIXED_RATE_NUM) |
| prAdapter->rWifiVar.eRateSetting = |
| (enum ENUM_REGISTRY_FIXED_RATE)(u4Data); |
| else |
| prAdapter->rWifiVar.eRateSetting = |
| FIXED_RATE_NONE; |
| |
| if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) |
| /* Enable Auto (Long/Short) Preamble */ |
| prAdapter->rWifiVar.ePreambleType = |
| PREAMBLE_TYPE_AUTO; |
| else if ((prAdapter->rWifiVar.eRateSetting >= |
| FIXED_RATE_MCS0_20M_400NS && |
| prAdapter->rWifiVar.eRateSetting <= |
| FIXED_RATE_MCS7_20M_400NS) |
| || (prAdapter->rWifiVar.eRateSetting >= |
| FIXED_RATE_MCS0_40M_400NS && |
| prAdapter->rWifiVar.eRateSetting <= |
| FIXED_RATE_MCS32_400NS)) |
| /* Force Short Preamble */ |
| prAdapter->rWifiVar.ePreambleType = |
| PREAMBLE_TYPE_SHORT; |
| else |
| /* Force Long Preamble */ |
| prAdapter->rWifiVar.ePreambleType = |
| PREAMBLE_TYPE_LONG; |
| |
| /* abort to re-connect */ |
| #if 1 |
| kalIndicateStatusAndComplete(prAdapter->prGlueInfo, |
| WLAN_STATUS_MEDIA_DISCONNECT, |
| NULL, 0); |
| #else |
| aisBssBeaconTimeout(prAdapter); |
| #endif |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } else if (u2SubId == 0x1234) { |
| /* 1. Disable On-Lin Scan */ |
| /* 3. Disable FIFO FULL no ack */ |
| /* 4. Disable Roaming */ |
| /* Disalbe auto tx power */ |
| /* 2. Keep at CAM mode */ |
| /* 5. Disable Beacon Timeout Detection */ |
| rWlanStatus = nicEnterCtiaMode(prAdapter, |
| TRUE, g_fgIsOid); |
| } else if (u2SubId == 0x1235) { |
| /* 1. Enaable On-Lin Scan */ |
| /* 3. Enable FIFO FULL no ack */ |
| /* 4. Enable Roaming */ |
| /* Enable auto tx power */ |
| /* 2. Keep at Fast PS */ |
| /* 5. Enable Beacon Timeout Detection */ |
| rWlanStatus = nicEnterCtiaMode(prAdapter, |
| FALSE, g_fgIsOid); |
| } else if (u2SubId == 0x1260) { |
| /* Disable On-Line Scan */ |
| rWlanStatus = nicEnterCtiaModeOfScan(prAdapter, |
| TRUE, TRUE); |
| } else if (u2SubId == 0x1261) { |
| /* Enable On-Line Scan */ |
| rWlanStatus = nicEnterCtiaModeOfScan(prAdapter, |
| FALSE, TRUE); |
| } else if (u2SubId == 0x1262) { |
| /* Disable Roaming */ |
| rWlanStatus = nicEnterCtiaModeOfRoaming(prAdapter, |
| TRUE, TRUE); |
| } else if (u2SubId == 0x1263) { |
| /* Enable Roaming */ |
| rWlanStatus = nicEnterCtiaModeOfRoaming(prAdapter, |
| FALSE, TRUE); |
| } else if (u2SubId == 0x1264) { |
| /* Keep at CAM mode */ |
| rWlanStatus = nicEnterCtiaModeOfCAM(prAdapter, |
| TRUE, g_fgIsOid); |
| } else if (u2SubId == 0x1265) { |
| /* Keep at Fast PS */ |
| rWlanStatus = nicEnterCtiaModeOfCAM(prAdapter, |
| FALSE, g_fgIsOid); |
| } else if (u2SubId == 0x1266) { |
| /* Disable Beacon Timeout Detection */ |
| rWlanStatus = nicEnterCtiaModeOfBCNTimeout(prAdapter, |
| TRUE, TRUE); |
| } else if (u2SubId == 0x1267) { |
| /* Enable Beacon Timeout Detection */ |
| rWlanStatus = nicEnterCtiaModeOfBCNTimeout(prAdapter, |
| FALSE, TRUE); |
| } else if (u2SubId == 0x1268) { |
| /* Disalbe auto tx power */ |
| rWlanStatus = nicEnterCtiaModeOfAutoTxPower(prAdapter, |
| TRUE, TRUE); |
| } else if (u2SubId == 0x1269) { |
| /* Enable auto tx power */ |
| rWlanStatus = nicEnterCtiaModeOfAutoTxPower(prAdapter, |
| FALSE, TRUE); |
| } else if (u2SubId == 0x1270) { |
| /* Disalbe FIFO FULL no ack */ |
| rWlanStatus = nicEnterCtiaModeOfFIFOFullNoAck(prAdapter, |
| TRUE, TRUE); |
| } else if (u2SubId == 0x1271) { |
| /* Enable FIFO FULL no ack */ |
| rWlanStatus = nicEnterCtiaModeOfFIFOFullNoAck(prAdapter, |
| FALSE, TRUE); |
| } |
| #endif |
| #if CFG_MTK_STAGE_SCAN |
| else if (u2SubId == 0x1250) |
| prAdapter->aePreferBand[KAL_NETWORK_TYPE_AIS_INDEX] = |
| BAND_NULL; |
| else if (u2SubId == 0x1251) |
| prAdapter->aePreferBand[KAL_NETWORK_TYPE_AIS_INDEX] = |
| BAND_2G4; |
| else if (u2SubId == 0x1252) { |
| if (prAdapter->fgEnable5GBand) |
| prAdapter->aePreferBand |
| [KAL_NETWORK_TYPE_AIS_INDEX] = BAND_5G; |
| else |
| /* Skip this setting if 5G band is disabled */ |
| DBGLOG(SCN, INFO, |
| "Skip 5G stage scan request due to 5G is disabled\n"); |
| } |
| #endif |
| } |
| break; |
| |
| case 0x9000: |
| default: { |
| rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; |
| rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data; |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SW_DBG_CTRL, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_SW_DBG_CTRL), |
| (uint8_t *) &rCmdSwCtrl, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| } /* switch(u2Id) */ |
| |
| return rWlanStatus; |
| } /* wlanoidSetSwCtrlWrite */ |
| |
| uint32_t |
| wlanoidQueryChipConfig(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT *prChipConfigInfo; |
| struct CMD_CHIP_CONFIG rCmdChipConfig; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQuerySwCtrlRead"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_CUSTOM_CHIP_CONFIG_STRUCT); |
| |
| if (u4QueryBufferLen < sizeof(struct |
| PARAM_CUSTOM_CHIP_CONFIG_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prChipConfigInfo = (struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT |
| *) pvQueryBuffer; |
| kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); |
| |
| rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; |
| rCmdChipConfig.ucType = prChipConfigInfo->ucType; |
| rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; |
| rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; |
| if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { |
| DBGLOG(REQ, INFO, |
| "Chip config Msg Size %u is not valid (query)\n", |
| rCmdChipConfig.u2MsgSize); |
| rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; |
| } |
| kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, |
| rCmdChipConfig.u2MsgSize); |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_CHIP_CONFIG, FALSE, |
| TRUE, g_fgIsOid, |
| /*nicCmdEventQuerySwCtrlRead, */ |
| nicCmdEventQueryChipConfig, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_CHIP_CONFIG), |
| (uint8_t *) &rCmdChipConfig, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| return rWlanStatus; |
| |
| } |
| |
| /* end of wlanoidQueryChipConfig() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set chip |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetChipConfig(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT *prChipConfigInfo; |
| struct CMD_CHIP_CONFIG rCmdChipConfig; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DATA_STRUCT_INSPECTING_ASSERT( |
| sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE); |
| DEBUGFUNC("wlanoidSetChipConfig"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_CHIP_CONFIG_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_CHIP_CONFIG_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prChipConfigInfo = (struct PARAM_CUSTOM_CHIP_CONFIG_STRUCT |
| *) pvSetBuffer; |
| kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); |
| |
| rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; |
| rCmdChipConfig.ucType = prChipConfigInfo->ucType; |
| rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; |
| rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; |
| if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { |
| DBGLOG(REQ, INFO, |
| "Chip config Msg Size %u is not valid (set)\n", |
| rCmdChipConfig.u2MsgSize); |
| rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; |
| } |
| kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, |
| rCmdChipConfig.u2MsgSize); |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_CHIP_CONFIG, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_CHIP_CONFIG), |
| (uint8_t *) &rCmdChipConfig, |
| pvSetBuffer, u4SetBufferLen); |
| |
| return rWlanStatus; |
| } /* wlanoidSetChipConfig */ |
| |
| void |
| wlanLoadDefaultCustomerSetting(IN struct ADAPTER * |
| prAdapter) { |
| |
| uint8_t ucItemNum, i; |
| |
| |
| ucItemNum = (sizeof(g_rDefaulteSetting) / sizeof( |
| struct PARAM_CUSTOM_KEY_CFG_STRUCT)); |
| DBGLOG(INIT, TRACE, "Default firmware setting %d item\n", |
| ucItemNum); |
| |
| |
| for (i = 0; i < ucItemNum; i++) { |
| wlanCfgSet(prAdapter, g_rDefaulteSetting[i].aucKey, |
| g_rDefaulteSetting[i].aucValue, 0); |
| DBGLOG(INIT, TRACE, "%s with %s\n", |
| g_rDefaulteSetting[i].aucKey, |
| g_rDefaulteSetting[i].aucValue); |
| } |
| |
| #if 1 |
| /*If need to re-parsing , included wlanInitFeatureOption*/ |
| wlanInitFeatureOption(prAdapter); |
| #endif |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set cfg and callback |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetKeyCfg(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| struct PARAM_CUSTOM_KEY_CFG_STRUCT *prKeyCfgInfo; |
| |
| DEBUGFUNC("wlanoidSetKeyCfg"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_KEY_CFG_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_KEY_CFG_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| prKeyCfgInfo = (struct PARAM_CUSTOM_KEY_CFG_STRUCT *) |
| pvSetBuffer; |
| |
| if (kalMemCmp(prKeyCfgInfo->aucKey, "reload", 6) == 0) |
| wlanGetConfig(prAdapter); /* Reload config file */ |
| else |
| wlanCfgSet(prAdapter, prKeyCfgInfo->aucKey, |
| prKeyCfgInfo->aucValue, 0); |
| |
| wlanInitFeatureOption(prAdapter); |
| #if CFG_SUPPORT_EASY_DEBUG |
| wlanFeatureToFw(prAdapter); |
| #endif |
| |
| return rWlanStatus; |
| } |
| |
| /* wlanoidSetSwCtrlWrite */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query EEPROM value. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryEepromRead(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_EEPROM_RW_STRUCT *prEepromRwInfo; |
| struct CMD_ACCESS_EEPROM rCmdAccessEeprom; |
| |
| DEBUGFUNC("wlanoidQueryEepromRead"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT); |
| |
| if (u4QueryBufferLen < sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prEepromRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) |
| pvQueryBuffer; |
| |
| kalMemZero(&rCmdAccessEeprom, |
| sizeof(struct CMD_ACCESS_EEPROM)); |
| rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ACCESS_EEPROM, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryEepromRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_EEPROM), |
| (uint8_t *) &rCmdAccessEeprom, pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryEepromRead */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to write EEPROM value. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetEepromWrite(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_EEPROM_RW_STRUCT *prEepromRwInfo; |
| struct CMD_ACCESS_EEPROM rCmdAccessEeprom; |
| |
| DEBUGFUNC("wlanoidSetEepromWrite"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prEepromRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) |
| pvSetBuffer; |
| |
| kalMemZero(&rCmdAccessEeprom, |
| sizeof(struct CMD_ACCESS_EEPROM)); |
| rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; |
| rCmdAccessEeprom.u2Data = prEepromRwInfo->u2EepromData; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ACCESS_EEPROM, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_EEPROM), |
| (uint8_t *) &rCmdAccessEeprom, pvSetBuffer, |
| u4SetBufferLen); |
| |
| } /* wlanoidSetEepromWrite */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the number of the successfully |
| * transmitted packets. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryXmitOk(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryXmitOk"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| prAdapter->rStatStruct |
| .rTransmittedFragmentCount.QuadPart; |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) |
| prAdapter->rStatStruct |
| .rTransmittedFragmentCount.QuadPart; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryXmitOk, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryXmitOk */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the number of the successfully |
| * received packets. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRcvOk(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryRcvOk"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| prAdapter->rStatStruct.rReceivedFragmentCount |
| .QuadPart; |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) |
| prAdapter->rStatStruct.rReceivedFragmentCount |
| .QuadPart; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryRecvOk, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryRcvOk */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the number of frames that the driver |
| * fails to transmit. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryXmitError(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryXmitError"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| prAdapter->rStatStruct.rFailedCount.QuadPart; |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) |
| prAdapter->rStatStruct.rFailedCount.QuadPart; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryXmitError, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryXmitError */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the number of frames successfully |
| * transmitted after exactly one collision. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryXmitOneCollision(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryXmitOneCollision"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| (prAdapter->rStatStruct.rMultipleRetryCount |
| .QuadPart - |
| prAdapter->rStatStruct.rRetryCount.QuadPart); |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) |
| (prAdapter->rStatStruct.rMultipleRetryCount |
| .QuadPart - |
| prAdapter->rStatStruct.rRetryCount.QuadPart); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryXmitOneCollision, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryXmitOneCollision */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the number of frames successfully |
| * transmitted after more than one collision. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryXmitMoreCollisions(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryXmitMoreCollisions"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) ( |
| prAdapter->rStatStruct.rMultipleRetryCount |
| .QuadPart); |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) ( |
| prAdapter->rStatStruct.rMultipleRetryCount |
| .QuadPart); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryXmitMoreCollisions, |
| nicOidCmdTimeoutCommon, 0, NULL, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryXmitMoreCollisions */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the number of frames |
| * not transmitted due to excessive collisions. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryXmitMaxCollisions(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryXmitMaxCollisions"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(uint32_t) |
| || (u4QueryBufferLen > sizeof(uint32_t) |
| && u4QueryBufferLen < sizeof(uint64_t))) { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #if CFG_ENABLE_STATISTICS_BUFFERING |
| if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { |
| if (u4QueryBufferLen == sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| prAdapter->rStatStruct.rFailedCount.QuadPart; |
| } else { |
| *pu4QueryInfoLen = sizeof(uint64_t); |
| *(uint64_t *) pvQueryBuffer = (uint64_t) |
| prAdapter->rStatStruct.rFailedCount.QuadPart; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_STATISTICS, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryXmitMaxCollisions, |
| nicOidCmdTimeoutCommon, 0, |
| NULL, pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* wlanoidQueryXmitMaxCollisions */ |
| |
| #define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00006620 /* for WPDWifi DLL */ |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query current the OID interface version, |
| * which is the interface between the application and driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryOidInterfaceVersion(IN struct ADAPTER * |
| prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryOidInterfaceVersion"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *(uint32_t *) pvQueryBuffer = |
| MTK_CUSTOM_OID_INTERFACE_VERSION; |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| DBGLOG(REQ, WARN, "Custom OID interface version: %#08X\n", |
| *(uint32_t *) pvQueryBuffer); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryOidInterfaceVersion */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query current Multicast Address List. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryMulticastList(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| #ifndef LINUX |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_MAC_MCAST_ADDR, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryMcastAddr, |
| nicOidCmdTimeoutCommon, 0, |
| NULL, pvQueryBuffer, |
| u4QueryBufferLen); |
| #else |
| return WLAN_STATUS_SUCCESS; |
| #endif |
| } /* end of wlanoidQueryMulticastList() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set Multicast Address List. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_MULTICAST_FULL |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetMulticastList(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| /* The data must be a multiple of the Ethernet address size. */ |
| if ((u4SetBufferLen % MAC_ADDR_LEN)) { |
| DBGLOG(REQ, WARN, "Invalid MC list length %u\n", |
| u4SetBufferLen); |
| |
| *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / |
| MAC_ADDR_LEN) * MAC_ADDR_LEN; |
| |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| /* Verify if we can support so many multicast addresses. */ |
| if (u4SetBufferLen > MAX_NUM_GROUP_ADDR * MAC_ADDR_LEN) { |
| DBGLOG(REQ, WARN, "Too many MC addresses\n"); |
| |
| return WLAN_STATUS_MULTICAST_FULL; |
| } |
| |
| /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && |
| * pvSetBuffer == NULL to clear exist Multicast List. |
| */ |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / |
| MAC_ADDR_LEN; |
| rCmdMacMcastAddr.ucBssIndex = |
| prAdapter->prAisBssInfo->ucBssIndex; |
| kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, |
| u4SetBufferLen); |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_MAC_MCAST_ADDR, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_MAC_MCAST_ADDR), |
| (uint8_t *) &rCmdMacMcastAddr, |
| pvSetBuffer, u4SetBufferLen); |
| } /* end of wlanoidSetMulticastList() */ |
| |
| uint32_t |
| wlanoidRssiMonitor(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_RSSI_MONITOR_T rRssi; |
| int8_t orig_max_rssi_value; |
| int8_t orig_min_rssi_value; |
| uint32_t rStatus1 = WLAN_STATUS_SUCCESS; |
| uint32_t rStatus2; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_RSSI_MONITOR_T); |
| |
| /* Check for query buffer length */ |
| if (u4QueryBufferLen < *pu4QueryInfoLen) { |
| DBGLOG(OID, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_DISCONNECTED) |
| rStatus1 = WLAN_STATUS_ADAPTER_NOT_READY; |
| |
| kalMemZero(&rRssi, sizeof(struct PARAM_RSSI_MONITOR_T)); |
| |
| orig_max_rssi_value = rRssi.max_rssi_value; |
| orig_min_rssi_value = rRssi.min_rssi_value; |
| |
| kalMemCopy(&rRssi, pvQueryBuffer, |
| sizeof(struct PARAM_RSSI_MONITOR_T)); |
| if (rRssi.enable) { |
| if (rRssi.max_rssi_value > PARAM_WHQL_RSSI_MAX_DBM) |
| rRssi.max_rssi_value = PARAM_WHQL_RSSI_MAX_DBM; |
| if (rRssi.min_rssi_value < -120) |
| rRssi.min_rssi_value = -120; |
| } else { |
| rRssi.max_rssi_value = 0; |
| rRssi.min_rssi_value = 0; |
| } |
| |
| DBGLOG(OID, INFO, |
| "enable=%d, max_rssi_value=%d, min_rssi_value=%d, orig_max_rssi_value=%d, orig_min_rssi_value=%d\n", |
| rRssi.enable, rRssi.max_rssi_value, rRssi.min_rssi_value, |
| orig_max_rssi_value, orig_min_rssi_value); |
| |
| rStatus2 = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_RSSI_MONITOR, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_RSSI_MONITOR_T), |
| (uint8_t *)&rRssi, NULL, 0); |
| |
| return (rStatus1 == WLAN_STATUS_ADAPTER_NOT_READY) ? |
| rStatus1 : rStatus2; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set Packet Filter. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_NOT_SUPPORTED |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetCurrentPacketFilter(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t u4NewPacketFilter; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| uint32_t rResult = WLAN_STATUS_FAILURE; |
| struct CMD_RX_PACKET_FILTER rSetRxPacketFilter; |
| |
| DBGLOG(REQ, TRACE, "wlanoidSetCurrentPacketFilter"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) { |
| *pu4SetInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| ASSERT(pvSetBuffer); |
| |
| /* Set the new packet filter. */ |
| u4NewPacketFilter = *(uint32_t *) pvSetBuffer; |
| |
| DBGLOG(REQ, TRACE, "New packet filter: %#08x\n", |
| u4NewPacketFilter); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| do { |
| /* Verify the bits of the new packet filter. If any bits are |
| * set that we don't support, leave. |
| */ |
| if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) { |
| rStatus = WLAN_STATUS_NOT_SUPPORTED; |
| DBGLOG(REQ, WARN, "some flags we don't support\n"); |
| break; |
| } |
| #if DBG |
| /* Need to enable or disable promiscuous support depending on |
| * the new filter. |
| */ |
| if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS) |
| DBGLOG(REQ, INFO, "Enable promiscuous mode\n"); |
| else |
| DBGLOG(REQ, INFO, "Disable promiscuous mode\n"); |
| |
| if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) |
| DBGLOG(REQ, INFO, "Enable all-multicast mode\n"); |
| else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) |
| DBGLOG(REQ, INFO, "Enable multicast\n"); |
| else |
| DBGLOG(REQ, INFO, "Disable multicast\n"); |
| |
| if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) |
| DBGLOG(REQ, INFO, "Enable Broadcast\n"); |
| else |
| DBGLOG(REQ, INFO, "Disable Broadcast\n"); |
| #endif |
| |
| prAdapter->fgAllMulicastFilter = FALSE; |
| if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) |
| prAdapter->fgAllMulicastFilter = TRUE; |
| } while (FALSE); |
| |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| /* Store the packet filter */ |
| |
| prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK; |
| prAdapter->u4OsPacketFilter |= u4NewPacketFilter; |
| |
| kalMemZero(&rSetRxPacketFilter, sizeof(rSetRxPacketFilter)); |
| rSetRxPacketFilter.u4RxPacketFilter = |
| prAdapter->u4OsPacketFilter; |
| rResult = wlanoidSetPacketFilter(prAdapter, |
| &rSetRxPacketFilter, |
| g_fgIsOid, pvSetBuffer, |
| u4SetBufferLen); |
| DBGLOG(OID, TRACE, "[MC debug] u4OsPacketFilter=%x\n", |
| prAdapter->u4OsPacketFilter); |
| return rResult; |
| } else { |
| return rStatus; |
| } |
| } /* wlanoidSetCurrentPacketFilter */ |
| |
| uint32_t wlanoidSetPacketFilter(struct ADAPTER *prAdapter, |
| void *pvPacketFiltr, |
| u_int8_t fgIsOid, void *pvSetBuffer, |
| uint32_t u4SetBufferLen) { |
| struct CMD_RX_PACKET_FILTER *prSetRxPacketFilter = NULL; |
| |
| prSetRxPacketFilter = (struct CMD_RX_PACKET_FILTER *) |
| pvPacketFiltr; |
| #if CFG_SUPPORT_DROP_MC_PACKET |
| if (prAdapter->prGlueInfo->fgIsInSuspendMode) |
| prSetRxPacketFilter->u4RxPacketFilter &= |
| ~(PARAM_PACKET_FILTER_MULTICAST | |
| PARAM_PACKET_FILTER_ALL_MULTICAST); |
| #endif |
| DBGLOG(OID, TRACE, |
| "[MC debug] u4PacketFilter=%x, IsSuspend=%d\n", |
| prSetRxPacketFilter->u4RxPacketFilter, |
| prAdapter->prGlueInfo->fgIsInSuspendMode); |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_RX_FILTER, |
| TRUE, |
| FALSE, |
| fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_RX_PACKET_FILTER), |
| (uint8_t *)prSetRxPacketFilter, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query current packet filter. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryCurrentPacketFilter(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryCurrentPacketFilter"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| if (u4QueryBufferLen >= sizeof(uint32_t)) { |
| ASSERT(pvQueryBuffer); |
| *(uint32_t *) pvQueryBuffer = prAdapter->u4OsPacketFilter; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidQueryCurrentPacketFilter */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query ACPI device power state. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryAcpiDevicePowerState(IN struct ADAPTER * |
| prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| #if DBG |
| enum PARAM_DEVICE_POWER_STATE *prPowerState; |
| #endif |
| |
| DEBUGFUNC("wlanoidQueryAcpiDevicePowerState"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(enum PARAM_DEVICE_POWER_STATE); |
| |
| #if DBG |
| prPowerState = (enum PARAM_DEVICE_POWER_STATE *) |
| pvQueryBuffer; |
| switch (*prPowerState) { |
| case ParamDeviceStateD0: |
| DBGLOG(REQ, INFO, "Query Power State: D0\n"); |
| break; |
| case ParamDeviceStateD1: |
| DBGLOG(REQ, INFO, "Query Power State: D1\n"); |
| break; |
| case ParamDeviceStateD2: |
| DBGLOG(REQ, INFO, "Query Power State: D2\n"); |
| break; |
| case ParamDeviceStateD3: |
| DBGLOG(REQ, INFO, "Query Power State: D3\n"); |
| break; |
| default: |
| break; |
| } |
| #endif |
| |
| /* Since we will disconnect the newwork, therefore we do not |
| * need to check queue empty |
| */ |
| *(enum PARAM_DEVICE_POWER_STATE *) pvQueryBuffer = |
| ParamDeviceStateD3; |
| /* WARNLOG(("Ready to transition to D3\n")); */ |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* pwrmgtQueryPower */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set ACPI device power state. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetAcpiDevicePowerState(IN struct ADAPTER * |
| prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| enum PARAM_DEVICE_POWER_STATE *prPowerState; |
| u_int8_t fgRetValue = TRUE; |
| |
| DEBUGFUNC("wlanoidSetAcpiDevicePowerState"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(enum PARAM_DEVICE_POWER_STATE); |
| |
| ASSERT(pvSetBuffer); |
| prPowerState = (enum PARAM_DEVICE_POWER_STATE *) |
| pvSetBuffer; |
| switch (*prPowerState) { |
| case ParamDeviceStateD0: |
| DBGLOG(REQ, INFO, "Set Power State: D0\n"); |
| kalDevSetPowerState(prAdapter->prGlueInfo, |
| (uint32_t) ParamDeviceStateD0); |
| fgRetValue = nicpmSetAcpiPowerD0(prAdapter); |
| break; |
| case ParamDeviceStateD1: |
| DBGLOG(REQ, INFO, "Set Power State: D1\n"); |
| kal_fallthrough; |
| /* no break here */ |
| case ParamDeviceStateD2: |
| DBGLOG(REQ, INFO, "Set Power State: D2\n"); |
| kal_fallthrough; |
| /* no break here */ |
| case ParamDeviceStateD3: |
| DBGLOG(REQ, INFO, "Set Power State: D3\n"); |
| fgRetValue = nicpmSetAcpiPowerD3(prAdapter); |
| kalDevSetPowerState(prAdapter->prGlueInfo, |
| (uint32_t) ParamDeviceStateD3); |
| break; |
| default: |
| break; |
| } |
| |
| if (fgRetValue == TRUE) |
| return WLAN_STATUS_SUCCESS; |
| else |
| return WLAN_STATUS_FAILURE; |
| } /* end of wlanoidSetAcpiDevicePowerState() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current fragmentation threshold. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryFragThreshold(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryFragThreshold"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| #if CFG_TX_FRAGMENT |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| #else |
| |
| return WLAN_STATUS_NOT_SUPPORTED; |
| #endif /* CFG_TX_FRAGMENT */ |
| |
| } /* end of wlanoidQueryFragThreshold() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set a new fragmentation threshold to the |
| * driver. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetFragThreshold(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| #if CFG_TX_FRAGMENT |
| return WLAN_STATUS_SUCCESS; |
| #else |
| return WLAN_STATUS_NOT_SUPPORTED; |
| #endif /* CFG_TX_FRAGMENT */ |
| |
| } /* end of wlanoidSetFragThreshold() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the current RTS threshold. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryRtsThreshold(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryRtsThreshold"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) { |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| *((uint32_t *) pvQueryBuffer) = |
| prAdapter->rWlanInfo.eRtsThreshold; |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidQueryRtsThreshold */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set a new RTS threshold to the driver. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetRtsThreshold(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *prRtsThreshold; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| if (u4SetBufferLen < sizeof(uint32_t)) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prRtsThreshold = (uint32_t *) pvSetBuffer; |
| *prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold; |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* wlanoidSetRtsThreshold */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is used to turn radio off. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetDisassociate(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct MSG_AIS_ABORT *prAisAbortMsg; |
| #if CFG_SUPPORT_CFG80211_AUTH |
| struct net_device *ndev = NULL; |
| #endif |
| |
| DEBUGFUNC("wlanoidSetDisassociate"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = 0; |
| |
| #if CFG_SUPPORT_CFG80211_AUTH |
| if (prAdapter->prGlueInfo->prDevHandler) |
| ndev = prAdapter->prGlueInfo->prDevHandler; |
| |
| if (prAdapter->rWifiVar.rConnSettings.bss && ndev) { |
| struct cfg80211_assoc_failure data; |
| |
| data.bss[0] = prAdapter->rWifiVar.rConnSettings.bss; |
| data.timeout = 1; |
| DBGLOG(REQ, INFO, "assoc timeout notify\n"); |
| /* ops caller have already hold the mutex. */ |
| cfg80211_assoc_failure(ndev, &data); |
| DBGLOG(REQ, INFO, "assoc timeout notify, Done\n"); |
| prAdapter->rWifiVar.rConnSettings.bss = NULL; |
| } |
| #endif |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| /* prepare message to AIS */ |
| prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; |
| prAdapter->rWifiVar.rConnSettings.eReConnectLevel = |
| RECONNECT_LEVEL_USER_SET; |
| |
| /* Send AIS Abort Message */ |
| prAisAbortMsg = (struct MSG_AIS_ABORT *) cnmMemAlloc( |
| prAdapter, RAM_TYPE_MSG, |
| sizeof(struct MSG_AIS_ABORT)); |
| if (!prAisAbortMsg) { |
| DBGLOG(REQ, ERROR, "Fail in creating AisAbortMsg.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; |
| prAisAbortMsg->ucReasonOfDisconnect = |
| DISCONNECT_REASON_CODE_NEW_CONNECTION; |
| prAisAbortMsg->fgDelayIndication = FALSE; |
| |
| #if CFG_DISCONN_DEBUG_FEATURE |
| /* used to disconnect debug capability */ |
| g_rDisconnInfoTemp.ucTrigger = DISCONNECT_TRIGGER_ACTIVE; |
| #endif |
| |
| mboxSendMsg(prAdapter, MBOX_ID_0, |
| (struct MSG_HDR *) prAisAbortMsg, MSG_SEND_METHOD_BUF); |
| |
| /* indicate for disconnection */ |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) |
| kalIndicateStatusAndComplete(prAdapter->prGlueInfo, |
| WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, 0); |
| #if !defined(LINUX) |
| prAdapter->fgIsRadioOff = TRUE; |
| #endif |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* wlanoidSetDisassociate */ |
| |
| #if CFG_SUPPORT_CSI |
| uint32_t |
| wlanoidSetCSIControl( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct CMD_CSI_CONTROL_T *pCSICtrl; |
| |
| DEBUGFUNC("wlanoidSetCSIControl"); |
| |
| *pu4SetInfoLen = sizeof(struct CMD_CSI_CONTROL_T); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "[CSI] (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4SetBufferLen < sizeof(struct CMD_CSI_CONTROL_T)) { |
| DBGLOG(REQ, WARN, |
| "[CSI] Too short length %lu\n", u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| pCSICtrl = (struct CMD_CSI_CONTROL_T *)pvSetBuffer; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_CSI_CONTROL, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_CSI_CONTROL_T), |
| (uint8_t *)pCSICtrl, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is used to query the power save profile. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \return WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQuery802dot11PowerSaveProfile(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (u4QueryBufferLen != 0) { |
| ASSERT(pvQueryBuffer); |
| |
| /* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) |
| * (prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); |
| */ |
| *(enum PARAM_POWER_MODE *) pvQueryBuffer = |
| (enum PARAM_POWER_MODE) ( |
| prAdapter->rWlanInfo.arPowerSaveMode[ |
| prAdapter->prAisBssInfo->ucBssIndex].ucPsProfile); |
| *pu4QueryInfoLen = sizeof(enum PARAM_POWER_MODE); |
| |
| /* hack for CTIA power mode setting function */ |
| if (prAdapter->fgEnCtiaPowerMode) { |
| /* set to non-zero value (to prevent MMI query 0, */ |
| /* before it intends to set 0, which will skip its |
| * following state machine) |
| */ |
| *(enum PARAM_POWER_MODE *) pvQueryBuffer = |
| (enum PARAM_POWER_MODE) 2; |
| } |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is used to set the power save profile. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSet802dot11PowerSaveProfile(IN struct ADAPTER * |
| prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t status; |
| struct PARAM_POWER_MODE_ *prPowerMode; |
| struct BSS_INFO *prBssInfo; |
| |
| const uint8_t *apucPsMode[Param_PowerModeMax] = { |
| (uint8_t *) "CAM", |
| (uint8_t *) "MAX PS", |
| (uint8_t *) "FAST PS" |
| }; |
| |
| DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_POWER_MODE_); |
| prPowerMode = (struct PARAM_POWER_MODE_ *) pvSetBuffer; |
| |
| if (u4SetBufferLen < sizeof(struct PARAM_POWER_MODE_)) { |
| DBGLOG(REQ, WARN, |
| "Set power mode error: Invalid length %u\n", |
| u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } else if (prPowerMode->ePowerMode >= Param_PowerModeMax) { |
| DBGLOG(REQ, WARN, |
| "Set power mode error: Invalid power mode(%u)\n", |
| prPowerMode->ePowerMode); |
| return WLAN_STATUS_INVALID_DATA; |
| } else if (prPowerMode->ucBssIdx >= |
| prAdapter->ucHwBssIdNum) { |
| DBGLOG(REQ, WARN, |
| "Set power mode error: Invalid BSS index(%u)\n", |
| prPowerMode->ucBssIdx); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, |
| prPowerMode->ucBssIdx); |
| |
| if (prAdapter->fgEnCtiaPowerMode) { |
| if (prPowerMode->ePowerMode != Param_PowerModeCAM) { |
| /* User setting to PS mode (Param_PowerModeMAX_PSP or |
| * Param_PowerModeFast_PSP) |
| */ |
| |
| if (prAdapter->u4CtiaPowerMode == 0) |
| /* force to keep in CAM mode */ |
| prPowerMode->ePowerMode = Param_PowerModeCAM; |
| else if (prAdapter->u4CtiaPowerMode == 1) |
| prPowerMode->ePowerMode = |
| Param_PowerModeMAX_PSP; |
| else if (prAdapter->u4CtiaPowerMode == 2) |
| prPowerMode->ePowerMode = |
| Param_PowerModeFast_PSP; |
| } |
| } |
| |
| /* only CAM mode allowed when TP/Sigma on */ |
| if ((prAdapter->rWifiVar.ucTpTestMode == |
| ENUM_TP_TEST_MODE_THROUGHPUT) || |
| (prAdapter->rWifiVar.ucTpTestMode == |
| ENUM_TP_TEST_MODE_SIGMA_AC_N_PMF)) |
| prPowerMode->ePowerMode = Param_PowerModeCAM; |
| else if (prAdapter->rWifiVar.ePowerMode != |
| Param_PowerModeMax) |
| prPowerMode->ePowerMode = prAdapter->rWifiVar.ePowerMode; |
| |
| /* for WMM PS Sigma certification, keep WiFi in ps mode continuously */ |
| /* force PS == Param_PowerModeMAX_PSP */ |
| if ((prAdapter->rWifiVar.ucTpTestMode == |
| ENUM_TP_TEST_MODE_SIGMA_WMM_PS) && |
| (prPowerMode->ePowerMode >= Param_PowerModeMAX_PSP)) |
| prPowerMode->ePowerMode = Param_PowerModeMAX_PSP; |
| |
| status = nicConfigPowerSaveProfile(prAdapter, prPowerMode->ucBssIdx, |
| prPowerMode->ePowerMode, |
| g_fgIsOid, PS_CALLER_COMMON); |
| |
| if (prPowerMode->ePowerMode < Param_PowerModeMax) { |
| DBGLOG(INIT, TRACE, |
| "Set %s Network BSS(%u) PS mode to %s (%d)\n", |
| apucNetworkType[prBssInfo->eNetworkType], |
| prPowerMode->ucBssIdx, |
| apucPsMode[prPowerMode->ePowerMode], |
| prPowerMode->ePowerMode); |
| } else { |
| DBGLOG(INIT, TRACE, |
| "Invalid PS mode setting (%d) for %s Network BSS(%u)\n", |
| prPowerMode->ePowerMode, |
| apucNetworkType[prBssInfo->eNetworkType], |
| prPowerMode->ucBssIdx); |
| } |
| |
| return status; |
| |
| } /* end of wlanoidSetAcpiDevicePowerStateMode() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query current status of AdHoc Mode. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryAdHocMode(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidQueryAdHocMode() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set AdHoc Mode. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetAdHocMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidSetAdHocMode() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query RF frequency. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryFrequency(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryFrequency"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_INFRA) { |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) |
| *(uint32_t *) pvQueryBuffer = nicChannelNum2Freq( |
| prAdapter->prAisBssInfo->ucPrimaryChannel); |
| else |
| *(uint32_t *) pvQueryBuffer = 0; |
| } else |
| *(uint32_t *) pvQueryBuffer = nicChannelNum2Freq( |
| prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidQueryFrequency() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set RF frequency by User Settings. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetFrequency(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pu4FreqInKHz; |
| |
| DEBUGFUNC("wlanoidSetFrequency"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| pu4FreqInKHz = (uint32_t *) pvSetBuffer; |
| |
| prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum = |
| (uint8_t) nicFreq2ChannelNum(*pu4FreqInKHz); |
| prAdapter->rWifiVar.rConnSettings.eAdHocBand = *pu4FreqInKHz |
| < 5000000 ? BAND_2G4 : BAND_5G; |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidSetFrequency() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set 802.11 channel of the radio frequency. |
| * This is a proprietary function call to Lunux currently. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetChannel(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| ASSERT(0); /* // */ |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the Beacon Interval from User |
| * Settings. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryBeaconInterval(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryBeaconInterval"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED) { |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_INFRA) |
| *(uint32_t *) pvQueryBuffer = |
| prAdapter->rWlanInfo.rCurrBssId.rConfiguration |
| .u4BeaconPeriod; |
| else |
| *(uint32_t *) pvQueryBuffer = |
| (uint32_t)prAdapter->rWlanInfo.u2BeaconPeriod; |
| } else { |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_INFRA) |
| *(uint32_t *) pvQueryBuffer = 0; |
| else |
| *(uint32_t *) pvQueryBuffer = |
| (uint32_t)prAdapter->rWlanInfo.u2BeaconPeriod; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidQueryBeaconInterval() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the Beacon Interval to User Settings. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetBeaconInterval(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pu4BeaconInterval; |
| |
| DEBUGFUNC("wlanoidSetBeaconInterval"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| pu4BeaconInterval = (uint32_t *) pvSetBuffer; |
| |
| if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) |
| || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) { |
| DBGLOG(REQ, TRACE, "Invalid Beacon Interval = %u\n", |
| *pu4BeaconInterval); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| prAdapter->rWlanInfo.u2BeaconPeriod = (uint16_t) * |
| pu4BeaconInterval; |
| |
| DBGLOG(REQ, INFO, "Set beacon interval: %d\n", |
| prAdapter->rWlanInfo.u2BeaconPeriod); |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidSetBeaconInterval() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query the ATIM window from User Settings. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryAtimWindow(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| DEBUGFUNC("wlanoidQueryAtimWindow"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rWifiVar.rConnSettings.eOPMode == |
| NET_TYPE_INFRA) |
| *(uint32_t *) pvQueryBuffer = 0; |
| else |
| *(uint32_t *) pvQueryBuffer = (uint32_t) |
| prAdapter->rWlanInfo.u2AtimWindow; |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } /* end of wlanoidQueryAtimWindow() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the ATIM window to User Settings. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetAtimWindow(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pu4AtimWindow; |
| |
| DEBUGFUNC("wlanoidSetAtimWindow"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| pu4AtimWindow = (uint32_t *) pvSetBuffer; |
| |
| prAdapter->rWlanInfo.u2AtimWindow = (uint16_t) * |
| pu4AtimWindow; |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidSetAtimWindow() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to Set the MAC address which is currently used |
| * by the NIC. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetCurrentAddr(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| ASSERT(0); /* // */ |
| |
| return WLAN_STATUS_SUCCESS; |
| } /* end of wlanoidSetCurrentAddr() */ |
| |
| #if CFG_TCP_IP_CHKSUM_OFFLOAD |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Setting the checksum offload function. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetCSUMOffload(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t u4CSUMFlags; |
| struct CMD_BASIC_CONFIG rCmdBasicConfig; |
| struct WIFI_VAR *prWifiVar = &prAdapter->rWifiVar; |
| |
| DEBUGFUNC("wlanoidSetCSUMOffload"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| u4CSUMFlags = *(uint32_t *) pvSetBuffer; |
| |
| kalMemZero(&rCmdBasicConfig, |
| sizeof(struct CMD_BASIC_CONFIG)); |
| |
| rCmdBasicConfig.ucNative80211 = 0; /* @FIXME: for Vista */ |
| |
| if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) |
| rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2); |
| |
| if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) |
| rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1); |
| |
| if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) |
| rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0); |
| |
| if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) |
| rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2); |
| |
| if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) |
| rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1); |
| |
| if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | |
| CSUM_OFFLOAD_EN_RX_IPv6)) |
| rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0); |
| |
| prAdapter->u4CSUMFlags = u4CSUMFlags; |
| rCmdBasicConfig.ucCtrlFlagAssertPath = |
| prWifiVar->ucCtrlFlagAssertPath; |
| rCmdBasicConfig.ucCtrlFlagDebugLevel = |
| prWifiVar->ucCtrlFlagDebugLevel; |
| |
| wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_BASIC_CONFIG, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| NULL, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_BASIC_CONFIG), |
| (uint8_t *) &rCmdBasicConfig, |
| pvSetBuffer, u4SetBufferLen); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Setting the IP address for pattern search function. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \return WLAN_STATUS_SUCCESS |
| * \return WLAN_STATUS_ADAPTER_NOT_READY |
| * \return WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetNetworkAddress(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| uint32_t i, u4IPv4AddrIdx; |
| struct CMD_SET_NETWORK_ADDRESS_LIST |
| *prCmdNetworkAddressList; |
| struct PARAM_NETWORK_ADDRESS_LIST *prNetworkAddressList = |
| (struct PARAM_NETWORK_ADDRESS_LIST *) pvSetBuffer; |
| struct PARAM_NETWORK_ADDRESS *prNetworkAddress; |
| uint32_t u4IPv4AddrCount, u4CmdSize; |
| #if CFG_ENABLE_GTK_FRAME_FILTER |
| uint32_t u4IpV4AddrListSize; |
| struct BSS_INFO *prBssInfo = |
| &prAdapter->rWifiVar.arBssInfoPool[KAL_NETWORK_TYPE_AIS_INDEX]; |
| #endif |
| |
| DEBUGFUNC("wlanoidSetNetworkAddress"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = 4; |
| |
| if (u4SetBufferLen < OFFSET_OF(struct |
| PARAM_NETWORK_ADDRESS_LIST, arAddress)) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| *pu4SetInfoLen = 0; |
| u4IPv4AddrCount = 0; |
| |
| /* 4 <1.1> Get IPv4 address count */ |
| /* We only suppot IPv4 address setting */ |
| prNetworkAddress = prNetworkAddressList->arAddress; |
| for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { |
| if ((prNetworkAddress->u2AddressType == |
| PARAM_PROTOCOL_ID_TCP_IP) && |
| (prNetworkAddress->u2AddressLength == IPV4_ADDR_LEN)) { |
| u4IPv4AddrCount++; |
| } |
| |
| prNetworkAddress = (struct PARAM_NETWORK_ADDRESS *) |
| ((unsigned long) prNetworkAddress + |
| (unsigned long) (prNetworkAddress->u2AddressLength + |
| OFFSET_OF(struct PARAM_NETWORK_ADDRESS, aucAddress))); |
| } |
| |
| /* 4 <2> Calculate command buffer size */ |
| /* construct payload of command packet */ |
| if (u4IPv4AddrCount == 0) |
| u4CmdSize = sizeof(struct CMD_SET_NETWORK_ADDRESS_LIST); |
| else |
| u4CmdSize = |
| OFFSET_OF(struct CMD_SET_NETWORK_ADDRESS_LIST, |
| arNetAddress) + |
| (sizeof(struct IPV4_NETWORK_ADDRESS) * |
| u4IPv4AddrCount); |
| |
| /* 4 <3> Allocate command buffer */ |
| prCmdNetworkAddressList = (struct CMD_SET_NETWORK_ADDRESS_LIST *) |
| kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); |
| |
| if (prCmdNetworkAddressList == NULL) |
| return WLAN_STATUS_FAILURE; |
| |
| #if CFG_ENABLE_GTK_FRAME_FILTER |
| u4IpV4AddrListSize = |
| OFFSET_OF(struct IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + |
| (u4IPv4AddrCount * sizeof(struct IPV4_NETWORK_ADDRESS)); |
| if (prBssInfo->prIpV4NetAddrList) |
| FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); |
| prBssInfo->prIpV4NetAddrList = |
| (struct IPV4_NETWORK_ADDRESS_LIST *) |
| kalMemAlloc(u4IpV4AddrListSize, |
| VIR_MEM_TYPE); |
| prBssInfo->prIpV4NetAddrList->ucAddrCount = |
| (uint8_t) u4IPv4AddrCount; |
| #endif |
| |
| /* 4 <4> Fill P_CMD_SET_NETWORK_ADDRESS_LIST */ |
| prCmdNetworkAddressList->ucBssIndex = |
| prNetworkAddressList->ucBssIdx; |
| |
| /* only to set IP address to FW once ARP filter is enabled */ |
| if (prAdapter->fgEnArpFilter) { |
| prCmdNetworkAddressList->ucAddressCount = |
| (uint8_t) u4IPv4AddrCount; |
| prNetworkAddress = prNetworkAddressList->arAddress; |
| |
| /* DBGLOG(INIT, INFO, ("%s: u4IPv4AddrCount (%lu)\n", |
| * __FUNCTION__, u4IPv4AddrCount)); |
| */ |
| |
| for (i = 0, u4IPv4AddrIdx = 0; |
| i < prNetworkAddressList->u4AddressCount; i++) { |
| if (prNetworkAddress->u2AddressType == |
| PARAM_PROTOCOL_ID_TCP_IP && |
| prNetworkAddress->u2AddressLength == |
| IPV4_ADDR_LEN) { |
| |
| kalMemCopy(prCmdNetworkAddressList-> |
| arNetAddress[u4IPv4AddrIdx].aucIpAddr, |
| prNetworkAddress->aucAddress, |
| sizeof(uint32_t)); |
| |
| #if CFG_ENABLE_GTK_FRAME_FILTER |
| kalMemCopy(prBssInfo->prIpV4NetAddrList-> |
| arNetAddr[u4IPv4AddrIdx].aucIpAddr, |
| prNetworkAddress->aucAddress, |
| sizeof(uint32_t)); |
| #endif |
| |
| DBGLOG(INIT, INFO, |
| "%s: IPv4 Addr [%u][" IPV4STR "]\n", |
| __func__, u4IPv4AddrIdx, |
| IPV4TOSTR(prNetworkAddress->aucAddress)); |
| |
| u4IPv4AddrIdx++; |
| } |
| |
| prNetworkAddress = (struct PARAM_NETWORK_ADDRESS *) |
| ((unsigned long)prNetworkAddress + |
| (unsigned long)(prNetworkAddress->u2AddressLength + |
| OFFSET_OF(struct PARAM_NETWORK_ADDRESS, |
| aucAddress))); |
| } |
| |
| } else { |
| prCmdNetworkAddressList->ucAddressCount = 0; |
| } |
| |
| DBGLOG(INIT, INFO, |
| "%s: Set %u IPv4 address for BSS[%u]\n", __func__, |
| u4IPv4AddrCount, |
| prCmdNetworkAddressList->ucBssIndex); |
| |
| /* 4 <5> Send command */ |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_IP_ADDRESS, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetIpAddress, |
| nicOidCmdTimeoutCommon, |
| u4CmdSize, |
| (uint8_t *) prCmdNetworkAddressList, |
| pvSetBuffer, |
| u4SetBufferLen); |
| |
| kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, |
| u4CmdSize); |
| return rStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Set driver to switch into RF test mode |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, |
| * should be NULL |
| * \param[in] u4SetBufferLen The length of the set buffer, should be 0 |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \return WLAN_STATUS_SUCCESS |
| * \return WLAN_STATUS_ADAPTER_NOT_READY |
| * \return WLAN_STATUS_INVALID_DATA |
| * \return WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidRftestSetTestMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus; |
| struct CMD_TEST_CTRL rCmdTestCtrl; |
| |
| DEBUGFUNC("wlanoidRftestSetTestMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = 0; |
| |
| if (u4SetBufferLen == 0) { |
| if ((prAdapter->fgTestMode == FALSE) |
| || (prAdapter->fgIcapMode == TRUE)) { |
| /* switch to RF Test mode */ |
| rCmdTestCtrl.ucAction = 0; /* Switch mode */ |
| rCmdTestCtrl.u.u4OpMode = 1; /* RF test mode */ |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TEST_CTRL, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventEnterRfTest, |
| nicOidCmdEnterRFTestTimeout, |
| sizeof(struct CMD_TEST_CTRL), |
| (uint8_t *) &rCmdTestCtrl, |
| pvSetBuffer, u4SetBufferLen); |
| } else { |
| /* already in test mode .. */ |
| rStatus = WLAN_STATUS_SUCCESS; |
| } |
| } else { |
| rStatus = WLAN_STATUS_INVALID_DATA; |
| } |
| |
| return rStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Set driver to switch into RF test ICAP mode |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, |
| * should be NULL |
| * \param[in] u4SetBufferLen The length of the set buffer, should be 0 |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \return WLAN_STATUS_SUCCESS |
| * \return WLAN_STATUS_ADAPTER_NOT_READY |
| * \return WLAN_STATUS_INVALID_DATA |
| * \return WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidRftestSetTestIcapMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus; |
| struct CMD_TEST_CTRL rCmdTestCtrl; |
| |
| DEBUGFUNC("wlanoidRftestSetTestIcapMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = 0; |
| |
| if (u4SetBufferLen == 0) { |
| if (prAdapter->fgIcapMode == FALSE) { |
| /* switch to RF Test mode */ |
| rCmdTestCtrl.ucAction = 0; /* Switch mode */ |
| rCmdTestCtrl.u.u4OpMode = 2; /* RF test mode */ |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TEST_CTRL, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventEnterRfTest, |
| nicOidCmdEnterRFTestTimeout, |
| sizeof(struct CMD_TEST_CTRL), |
| (uint8_t *) &rCmdTestCtrl, |
| pvSetBuffer, u4SetBufferLen); |
| } else { |
| /* already in ICAP mode .. */ |
| rStatus = WLAN_STATUS_SUCCESS; |
| } |
| } else { |
| rStatus = WLAN_STATUS_INVALID_DATA; |
| } |
| |
| return rStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Set driver to switch into normal operation mode from RF test mode |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * should be NULL |
| * \param[in] u4SetBufferLen The length of the set buffer, should be 0 |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \return WLAN_STATUS_SUCCESS |
| * \return WLAN_STATUS_ADAPTER_NOT_READY |
| * \return WLAN_STATUS_INVALID_DATA |
| * \return WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidRftestSetAbortTestMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus; |
| struct CMD_TEST_CTRL rCmdTestCtrl; |
| |
| DEBUGFUNC("wlanoidRftestSetAbortTestMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = 0; |
| |
| if (u4SetBufferLen == 0) { |
| if (prAdapter->fgTestMode == TRUE) { |
| /* switch to normal mode */ |
| rCmdTestCtrl.ucAction = 0; /* Switch mode */ |
| rCmdTestCtrl.u.u4OpMode = 0; /* normal mode */ |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TEST_CTRL, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventLeaveRfTest, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TEST_CTRL), |
| (uint8_t *) &rCmdTestCtrl, |
| pvSetBuffer, u4SetBufferLen); |
| } else { |
| /* already in normal mode .. */ |
| rStatus = WLAN_STATUS_SUCCESS; |
| } |
| } else { |
| rStatus = WLAN_STATUS_INVALID_DATA; |
| } |
| |
| return rStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief query for RF test parameter |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| * \retval WLAN_STATUS_NOT_SUPPORTED |
| * \retval WLAN_STATUS_NOT_ACCEPTED |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidRftestQueryAutoTest(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_MTK_WIFI_TEST_STRUCT *prRfATInfo; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidRftestQueryAutoTest"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_MTK_WIFI_TEST_STRUCT); |
| |
| #if 0 /* PeiHsuan Temp Remove this check for workaround Gen2/Gen3 EM Mode |
| * Modification |
| */ |
| if (u4QueryBufferLen != sizeof(struct PARAM_MTK_WIFI_TEST_STRUCT)) { |
| DBGLOG(REQ, ERROR, "Invalid data. QueryBufferLen: %ld.\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #endif |
| |
| prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT *) |
| pvQueryBuffer; |
| |
| DBGLOG(RFTEST, INFO, |
| "Get AT_CMD BufferLen = %d, AT Index = %d, Data = %d\n", |
| u4QueryBufferLen, |
| prRfATInfo->u4FuncIndex, |
| prRfATInfo->u4FuncData); |
| |
| rStatus = rftestQueryATInfo(prAdapter, |
| prRfATInfo->u4FuncIndex, |
| prRfATInfo->u4FuncData, |
| pvQueryBuffer, u4QueryBufferLen); |
| |
| return rStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Set RF test parameter |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \return WLAN_STATUS_SUCCESS |
| * \return WLAN_STATUS_ADAPTER_NOT_READY |
| * \return WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidRftestSetAutoTest(IN struct ADAPTER *prAdapter, |
| OUT void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_MTK_WIFI_TEST_STRUCT *prRfATInfo; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidRftestSetAutoTest"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_MTK_WIFI_TEST_STRUCT); |
| |
| #if 0 /* PeiHsuan Temp Remove this check for workaround Gen2/Gen3 EM Mode |
| * Modification |
| */ |
| if (u4SetBufferLen != sizeof(struct |
| PARAM_MTK_WIFI_TEST_STRUCT)) { |
| DBGLOG(REQ, ERROR, "Invalid data. SetBufferLen: %ld.\n", |
| u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| #endif |
| |
| prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT *) |
| pvSetBuffer; |
| |
| DBGLOG(RFTEST, INFO, |
| "Set AT_CMD BufferLen = %d, AT Index = %d, Data = %d\n", |
| u4SetBufferLen, |
| prRfATInfo->u4FuncIndex, |
| prRfATInfo->u4FuncData); |
| |
| rStatus = rftestSetATInfo(prAdapter, |
| prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData); |
| |
| return rStatus; |
| } |
| |
| /* RF test OID set handler */ |
| uint32_t rftestSetATInfo(IN struct ADAPTER *prAdapter, |
| uint32_t u4FuncIndex, uint32_t u4FuncData) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| struct CMD_TEST_CTRL *pCmdTestCtrl; |
| uint8_t ucCmdSeqNum; |
| |
| ASSERT(prAdapter); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + sizeof(struct CMD_TEST_CTRL))); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| |
| /* Setup common CMD Info Packet */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof( |
| struct CMD_TEST_CTRL); |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| prCmdInfo->fgIsOid = g_fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_TEST_CTRL; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = sizeof(struct CMD_TEST_CTRL); |
| prCmdInfo->pvInformationBuffer = NULL; |
| prCmdInfo->u4InformationBufferLength = 0; |
| |
| /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| pCmdTestCtrl = (struct CMD_TEST_CTRL *) ( |
| prWifiCmd->aucBuffer); |
| pCmdTestCtrl->ucAction = 1; /* Set ATInfo */ |
| pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; |
| pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; |
| |
| if ((u4FuncIndex == RF_AT_FUNCID_COMMAND) |
| && (u4FuncData == RF_AT_COMMAND_ICAP)) { |
| prAdapter->rIcapInfo.fgIcapEnable = TRUE; |
| prAdapter->rIcapInfo.fgCaptureDone = FALSE; |
| } |
| /* ICAP dump name Reset */ |
| if ((u4FuncIndex == RF_AT_FUNCID_COMMAND) |
| && (u4FuncData == RF_AT_COMMAND_RESET_DUMP_NAME)) |
| prAdapter->rIcapInfo.u2DumpIndex = 0; |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prAdapter->prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| } |
| |
| uint32_t wlanoidExtRfTestICapStart(IN struct ADAPTER *prAdapter, |
| OUT void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_TEST_CTRL_EXT_T rCmdTestCtrl; |
| struct RBIST_CAP_START_T *prCmdICapInfo; |
| struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *prRfATInfo; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidExtRfTestICapStart"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_MTK_WIFI_TEST_STRUCT_EXT_T); |
| |
| prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *) |
| pvSetBuffer; |
| |
| DBGLOG(RFTEST, INFO, |
| "Set AT_CMD BufferLen = %d, AT Index = %d\n", |
| u4SetBufferLen, |
| prRfATInfo->u4FuncIndex); |
| |
| rCmdTestCtrl.ucAction = ACTION_IN_RFTEST; |
| rCmdTestCtrl.u.rRfATInfo.u4FuncIndex = |
| SET_ICAP_CAPTURE_START; |
| |
| prCmdICapInfo = &(rCmdTestCtrl.u.rRfATInfo.Data.rICapInfo); |
| kalMemCopy(prCmdICapInfo, &(prRfATInfo->Data.rICapInfo), |
| sizeof(struct RBIST_CAP_START_T)); |
| |
| prAdapter->rIcapInfo.fgIcapEnable = TRUE; |
| prAdapter->rIcapInfo.fgCaptureDone = FALSE; |
| |
| rStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_RF_TEST, |
| TRUE, /* Query Bit: True->write False->read */ |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TEST_CTRL_EXT_T), |
| (uint8_t *)&rCmdTestCtrl, pvSetBuffer, |
| u4SetBufferLen); |
| return rStatus; |
| } |
| |
| uint32_t wlanoidExtRfTestICapStatus(IN struct ADAPTER *prAdapter, |
| OUT void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_TEST_CTRL_EXT_T rCmdTestCtrl; |
| struct RBIST_CAP_START_T *prCmdICapInfo; |
| struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *prRfATInfo; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidExtRfTestICapStatus"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_MTK_WIFI_TEST_STRUCT_EXT_T); |
| |
| prRfATInfo = (struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *) |
| pvSetBuffer; |
| |
| DBGLOG(RFTEST, INFO, |
| "Set AT_CMD BufferLen = %d, AT Index = %d\n", |
| u4SetBufferLen, |
| prRfATInfo->u4FuncIndex); |
| |
| rCmdTestCtrl.ucAction = ACTION_IN_RFTEST; |
| rCmdTestCtrl.u.rRfATInfo.u4FuncIndex = |
| GET_ICAP_CAPTURE_STATUS; |
| |
| prCmdICapInfo = &(rCmdTestCtrl.u.rRfATInfo.Data.rICapInfo); |
| kalMemCopy(prCmdICapInfo, &(prRfATInfo->Data.rICapInfo), |
| sizeof(struct RBIST_CAP_START_T)); |
| |
| rStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_RF_TEST, |
| FALSE, /* Query Bit: True->write False->read */ |
| TRUE, |
| g_fgIsOid, |
| NULL, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TEST_CTRL_EXT_T), |
| (uint8_t *)(&rCmdTestCtrl), pvSetBuffer, |
| u4SetBufferLen); |
| return rStatus; |
| } |
| |
| void wlanoidRfTestICapRawDataProc(IN struct ADAPTER * |
| prAdapter, uint32_t u4CapStartAddr, |
| uint32_t u4TotalBufferSize) { |
| struct CMD_TEST_CTRL_EXT_T rCmdTestCtrl; |
| struct PARAM_MTK_WIFI_TEST_STRUCT_EXT_T *prRfATInfo; |
| uint32_t u4SetBufferLen = 0; |
| void *pvSetBuffer = NULL; |
| int32_t rStatus; |
| |
| ASSERT(prAdapter); |
| |
| prRfATInfo = &(rCmdTestCtrl.u.rRfATInfo); |
| |
| rCmdTestCtrl.ucAction = ACTION_IN_RFTEST; |
| prRfATInfo->u4FuncIndex = GET_ICAP_RAW_DATA; |
| prRfATInfo->Data.rICapDump.u4Address = u4CapStartAddr; |
| prRfATInfo->Data.rICapDump.u4AddrOffset = 0x04; |
| prRfATInfo->Data.rICapDump.u4Bank = 1; |
| prRfATInfo->Data.rICapDump.u4BankSize = u4TotalBufferSize; |
| |
| rStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_RF_TEST, |
| TRUE, /* Query Bit: True->write False->read */ |
| FALSE, |
| FALSE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TEST_CTRL_EXT_T), |
| (uint8_t *)(&rCmdTestCtrl), |
| pvSetBuffer, u4SetBufferLen); |
| } |
| |
| uint32_t |
| rftestQueryATInfo(IN struct ADAPTER *prAdapter, |
| uint32_t u4FuncIndex, uint32_t u4FuncData, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| struct CMD_TEST_CTRL *pCmdTestCtrl; |
| uint8_t ucCmdSeqNum; |
| union EVENT_TEST_STATUS *prTestStatus; |
| |
| ASSERT(prAdapter); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) { |
| /* driver implementation */ |
| prTestStatus = (union EVENT_TEST_STATUS *) pvQueryBuffer; |
| |
| prTestStatus->rATInfo.u4FuncData = |
| (prAdapter->rVerInfo.u2FwProductID << 16) | |
| (prAdapter->rVerInfo.u2FwOwnVersion); |
| u4QueryBufferLen = sizeof(union EVENT_TEST_STATUS); |
| |
| return WLAN_STATUS_SUCCESS; |
| } else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) { |
| /* driver implementation */ |
| prTestStatus = (union EVENT_TEST_STATUS *) pvQueryBuffer; |
| |
| prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION; |
| u4QueryBufferLen = sizeof(union EVENT_TEST_STATUS); |
| |
| return WLAN_STATUS_SUCCESS; |
| } else if (u4FuncIndex == |
| RF_AT_FUNCID_QUERY_ICAP_DUMP_FILE) { |
| /* driver implementation */ |
| prTestStatus = (union EVENT_TEST_STATUS *) pvQueryBuffer; |
| |
| prTestStatus->rATInfo.u4FuncData = |
| prAdapter->rIcapInfo.u2DumpIndex; |
| u4QueryBufferLen = sizeof(union EVENT_TEST_STATUS); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + sizeof(struct CMD_TEST_CTRL))); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| |
| /* Setup common CMD Info Packet */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof( |
| struct CMD_TEST_CTRL); |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| prCmdInfo->fgIsOid = g_fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_TEST_CTRL; |
| prCmdInfo->fgSetQuery = FALSE; |
| prCmdInfo->fgNeedResp = TRUE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = sizeof(struct CMD_TEST_CTRL); |
| prCmdInfo->pvInformationBuffer = pvQueryBuffer; |
| prCmdInfo->u4InformationBufferLength = u4QueryBufferLen; |
| |
| /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| pCmdTestCtrl = (struct CMD_TEST_CTRL *) ( |
| prWifiCmd->aucBuffer); |
| pCmdTestCtrl->ucAction = 2; /* Get ATInfo */ |
| pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; |
| pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; |
| |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prAdapter->prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| |
| } |
| |
| uint32_t rftestSetFrequency(IN struct ADAPTER *prAdapter, |
| IN uint32_t u4FreqInKHz, |
| IN uint32_t *pu4SetInfoLen) { |
| struct CMD_TEST_CTRL rCmdTestCtrl; |
| |
| ASSERT(prAdapter); |
| |
| rCmdTestCtrl.ucAction = 5; /* Set Channel Frequency */ |
| rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TEST_CTRL, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TEST_CTRL), |
| (uint8_t *) &rCmdTestCtrl, NULL, 0); |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief command packet generation utility |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] ucCID Command ID |
| * \param[in] fgSetQuery Set or Query |
| * \param[in] fgNeedResp Need for response |
| * \param[in] pfCmdDoneHandler Function pointer when command is done |
| * \param[in] u4SetQueryInfoLen The length of the set/query buffer |
| * \param[in] pucInfoBuffer Pointer to set/query buffer |
| * |
| * |
| * \retval WLAN_STATUS_PENDING |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanSendSetQueryCmd(IN struct ADAPTER *prAdapter, |
| uint8_t ucCID, |
| u_int8_t fgSetQuery, |
| u_int8_t fgNeedResp, |
| u_int8_t fgIsOid, |
| PFN_CMD_DONE_HANDLER pfCmdDoneHandler, |
| PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, |
| uint32_t u4SetQueryInfoLen, |
| uint8_t *pucInfoBuffer, OUT void *pvSetQueryBuffer, |
| IN uint32_t u4SetQueryBufferLen) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| uint8_t ucCmdSeqNum; |
| |
| if (kalIsResetting()) { |
| DBGLOG(INIT, WARN, "Chip resetting, skip\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + u4SetQueryInfoLen)); |
| |
| DEBUGFUNC("wlanSendSetQueryCmd"); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); |
| |
| /* Setup common CMD Info Packet */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->u2InfoBufLen = (uint16_t) (CMD_HDR_SIZE + |
| u4SetQueryInfoLen); |
| prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; |
| prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; |
| prCmdInfo->fgIsOid = fgIsOid; |
| prCmdInfo->ucCID = ucCID; |
| prCmdInfo->fgSetQuery = fgSetQuery; |
| prCmdInfo->fgNeedResp = fgNeedResp; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; |
| prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; |
| |
| /* Setup WIFI_CMD_T (no payload) */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->u2Length = prCmdInfo->u2InfoBufLen - |
| (uint16_t) OFFSET_OF(struct WIFI_CMD, u2Length); |
| prWifiCmd->u2PqId = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) |
| kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, |
| u4SetQueryInfoLen); |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| return WLAN_STATUS_PENDING; |
| } |
| |
| #if CFG_SUPPORT_WAPI |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called by WAPI ui to set wapi mode, which is needed to |
| * info the the driver to operation at WAPI mode while driver initialize. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * \param[in] u4SetBufferLen The length of the set buffer |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid length of |
| * the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetWapiMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| DEBUGFUNC("wlanoidSetWapiMode"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| /* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi |
| * assoc ie at the check point |
| * The Adapter Connection setting fgUseWapi will cleat whil oid |
| * set mode (infra), |
| * And set fgUseWapi True while set wapi assoc ie |
| * policay selection, add key all depend on this flag, |
| * The fgUseWapi may remove later |
| */ |
| if (*(uint32_t *) pvSetBuffer) |
| prAdapter->fgUseWapi = TRUE; |
| else |
| prAdapter->fgUseWapi = FALSE; |
| |
| #if 0 |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + 4)); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| |
| /* compose CMD_BUILD_CONNECTION cmd pkt */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4; |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = NULL; |
| prCmdInfo->fgIsOid = TRUE; |
| prCmdInfo->ucCID = CMD_ID_WAPI_MODE; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| prCmdInfo->fgDriverDomainMCR = FALSE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = u4SetBufferLen; |
| prCmdInfo->pvInformationBuffer = pvSetBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetBufferLen; |
| |
| /* Setup WIFI_CMD_T */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| cp = (uint8_t *) (prWifiCmd->aucBuffer); |
| |
| kalMemCopy(cp, (uint8_t *) pvSetBuffer, 4); |
| |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| #else |
| return WLAN_STATUS_SUCCESS; |
| #endif |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called by WAPI to set the assoc info, which is needed |
| * to add to Association request frame while join WAPI AP. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * \param[in] u4SetBufferLen The length of the set buffer |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid length of |
| * the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetWapiAssocInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct WAPI_INFO_ELEM *prWapiInfo; |
| uint8_t *cp; |
| uint16_t u2AuthSuiteCount = 0; |
| uint16_t u2PairSuiteCount = 0; |
| uint32_t u4AuthKeyMgtSuite = 0; |
| uint32_t u4PairSuite = 0; |
| uint32_t u4GroupSuite = 0; |
| uint16_t u2IeLength = 0; |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| DEBUGFUNC("wlanoidSetWapiAssocInfo"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; |
| |
| if (u4SetBufferLen < 20 /* From EID to Group cipher */) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (!wextSrchDesiredWAPIIE((uint8_t *) pvSetBuffer, |
| u4SetBufferLen, (uint8_t **) &prWapiInfo)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (!prWapiInfo || prWapiInfo->ucLength < 18 |
| || prWapiInfo->ucLength > 40) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| u2IeLength = prWapiInfo->ucLength + 2; |
| |
| /* Skip Version check */ |
| cp = (uint8_t *) &prWapiInfo->u2AuthKeyMgtSuiteCount; |
| |
| WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); |
| |
| if (u2AuthSuiteCount > 1) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| cp += 2; |
| WLAN_GET_FIELD_32(cp, &u4AuthKeyMgtSuite); |
| |
| DBGLOG(SEC, TRACE, |
| "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n", |
| u2AuthSuiteCount, |
| (uint8_t) (u4AuthKeyMgtSuite & 0x000000FF), |
| (uint8_t) ((u4AuthKeyMgtSuite >> 8) & 0x000000FF), |
| (uint8_t) ((u4AuthKeyMgtSuite >> 16) & 0x000000FF), |
| (uint8_t) ((u4AuthKeyMgtSuite >> 24) & 0x000000FF)); |
| |
| if (u4AuthKeyMgtSuite != WAPI_AKM_SUITE_802_1X |
| && u4AuthKeyMgtSuite != WAPI_AKM_SUITE_PSK) |
| ASSERT(FALSE); |
| |
| cp += 4; |
| WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); |
| if (u2PairSuiteCount > 1) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| cp += 2; |
| WLAN_GET_FIELD_32(cp, &u4PairSuite); |
| DBGLOG(SEC, TRACE, |
| "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n", |
| u2PairSuiteCount, |
| (uint8_t) (u4PairSuite & 0x000000FF), |
| (uint8_t) ((u4PairSuite >> 8) & 0x000000FF), |
| (uint8_t) ((u4PairSuite >> 16) & 0x000000FF), |
| (uint8_t) ((u4PairSuite >> 24) & 0x000000FF)); |
| |
| if (u4PairSuite != WAPI_CIPHER_SUITE_WPI) |
| ASSERT(FALSE); |
| |
| cp += 4; |
| WLAN_GET_FIELD_32(cp, &u4GroupSuite); |
| DBGLOG(SEC, TRACE, |
| "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n", |
| (uint8_t) (u4GroupSuite & 0x000000FF), |
| (uint8_t) ((u4GroupSuite >> 8) & 0x000000FF), |
| (uint8_t) ((u4GroupSuite >> 16) & 0x000000FF), |
| (uint8_t) ((u4GroupSuite >> 24) & 0x000000FF)); |
| |
| if (u4GroupSuite != WAPI_CIPHER_SUITE_WPI) |
| ASSERT(FALSE); |
| |
| prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite = |
| u4AuthKeyMgtSuite; |
| prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher |
| = u4PairSuite; |
| prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher |
| = u4GroupSuite; |
| |
| kalMemCopy(prAdapter->prGlueInfo->aucWapiAssocInfoIEs, |
| prWapiInfo, u2IeLength); |
| prAdapter->prGlueInfo->u2WapiAssocInfoIESz = u2IeLength; |
| DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u2IeLength); |
| |
| prAdapter->rWifiVar.rConnSettings.fgWapiMode = TRUE; |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the wpi key to the driver. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * |
| * \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked. |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetWapiKey(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| struct PARAM_WPI_KEY *prNewKey; |
| struct CMD_802_11_KEY *prCmdKey; |
| uint8_t *pc; |
| uint8_t ucCmdSeqNum; |
| struct STA_RECORD *prStaRec; |
| struct BSS_INFO *prBssInfo; |
| uint32_t u4Ret = 0; |
| |
| DEBUGFUNC("wlanoidSetWapiKey"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| prNewKey = (struct PARAM_WPI_KEY *) pvSetBuffer; |
| |
| DBGLOG_MEM8(REQ, TRACE, (uint8_t *) pvSetBuffer, 560); |
| pc = (uint8_t *) pvSetBuffer; |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| /* Todo:: WAPI AP mode !!!!! */ |
| prBssInfo = prAdapter->prAisBssInfo; |
| |
| prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0); |
| |
| /* Dump P_PARAM_WPI_KEY_T content. */ |
| DBGLOG(REQ, TRACE, |
| "Set: Dump P_PARAM_WPI_KEY_T content\r\n"); |
| DBGLOG(REQ, TRACE, "TYPE : %d\r\n", |
| prNewKey->eKeyType); |
| DBGLOG(REQ, TRACE, "Direction : %d\r\n", |
| prNewKey->eDirection); |
| DBGLOG(REQ, TRACE, "KeyID : %d\r\n", prNewKey->ucKeyID); |
| DBGLOG(REQ, TRACE, "AddressIndex:\r\n"); |
| DBGLOG_MEM8(REQ, TRACE, prNewKey->aucAddrIndex, 12); |
| prNewKey->u4LenWPIEK = 16; |
| |
| DBGLOG_MEM8(REQ, TRACE, (uint8_t *) prNewKey->aucWPIEK, |
| (uint8_t) prNewKey->u4LenWPIEK); |
| prNewKey->u4LenWPICK = 16; |
| |
| DBGLOG(REQ, TRACE, "CK Key(%d):\r\n", |
| (uint8_t) prNewKey->u4LenWPICK); |
| DBGLOG_MEM8(REQ, TRACE, (uint8_t *) prNewKey->aucWPICK, |
| (uint8_t) prNewKey->u4LenWPICK); |
| DBGLOG(REQ, TRACE, "PN:\r\n"); |
| if (prNewKey->eKeyType == 0) { |
| prNewKey->aucPN[0] = 0x5c; |
| prNewKey->aucPN[1] = 0x36; |
| prNewKey->aucPN[2] = 0x5c; |
| prNewKey->aucPN[3] = 0x36; |
| prNewKey->aucPN[4] = 0x5c; |
| prNewKey->aucPN[5] = 0x36; |
| prNewKey->aucPN[6] = 0x5c; |
| prNewKey->aucPN[7] = 0x36; |
| prNewKey->aucPN[8] = 0x5c; |
| prNewKey->aucPN[9] = 0x36; |
| prNewKey->aucPN[10] = 0x5c; |
| prNewKey->aucPN[11] = 0x36; |
| prNewKey->aucPN[12] = 0x5c; |
| prNewKey->aucPN[13] = 0x36; |
| prNewKey->aucPN[14] = 0x5c; |
| prNewKey->aucPN[15] = 0x36; |
| } |
| |
| DBGLOG_MEM8(REQ, TRACE, (uint8_t *) prNewKey->aucPN, 16); |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + u4SetBufferLen)); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| |
| /* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof( |
| struct CMD_802_11_KEY); |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| prCmdInfo->fgIsOid = g_fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = u4SetBufferLen; |
| prCmdInfo->pvInformationBuffer = pvSetBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetBufferLen; |
| |
| /* Setup WIFI_CMD_T */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| prCmdKey = (struct CMD_802_11_KEY *) (prWifiCmd->aucBuffer); |
| |
| kalMemZero(prCmdKey, sizeof(struct CMD_802_11_KEY)); |
| |
| prCmdKey->ucAddRemove = 1; /* Add */ |
| |
| if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) { |
| prCmdKey->ucTxKey = 1; |
| prCmdKey->ucKeyType = 1; |
| } |
| kalMemCopy(prCmdKey->aucPeerAddr, |
| (uint8_t *) prNewKey->aucAddrIndex, MAC_ADDR_LEN); |
| if ((prCmdKey->aucPeerAddr[0] & prCmdKey->aucPeerAddr[1] & |
| prCmdKey->aucPeerAddr[2] & |
| prCmdKey->aucPeerAddr[3] & prCmdKey->aucPeerAddr[4] & |
| prCmdKey->aucPeerAddr[5]) == 0xFF) { |
| prStaRec = cnmGetStaRecByAddress(prAdapter, |
| prBssInfo->ucBssIndex, prBssInfo->aucBSSID); |
| if (prStaRec == NULL) { |
| u4Ret = WLAN_STATUS_FAILURE; |
| goto Error; |
| } |
| /* AIS RSN Group key, addr is BC addr */ |
| kalMemCopy(prCmdKey->aucPeerAddr, prStaRec->aucMacAddr, |
| MAC_ADDR_LEN); |
| } else { |
| prStaRec = cnmGetStaRecByAddress(prAdapter, |
| prBssInfo->ucBssIndex, prCmdKey->aucPeerAddr); |
| } |
| |
| prCmdKey->ucBssIdx = |
| prAdapter->prAisBssInfo->ucBssIndex; /* AIS */ |
| |
| prCmdKey->ucKeyId = prNewKey->ucKeyID; |
| |
| prCmdKey->ucKeyLen = 32; |
| |
| prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI; |
| |
| kalMemCopy(prCmdKey->aucKeyMaterial, |
| (uint8_t *) prNewKey->aucWPIEK, 16); |
| |
| kalMemCopy(prCmdKey->aucKeyMaterial + 16, |
| (uint8_t *) prNewKey->aucWPICK, 16); |
| |
| kalMemCopy(prCmdKey->aucKeyRsc, (uint8_t *) prNewKey->aucPN, |
| 16); |
| |
| if (prCmdKey->ucTxKey) { |
| if (prStaRec) { |
| if (prCmdKey->ucKeyType) { /* AIS RSN STA */ |
| prCmdKey->ucWlanIndex = prStaRec->ucWlanIndex; |
| prStaRec->fgTransmitKeyExist = |
| TRUE; /* wait for CMD Done ? */ |
| } else { |
| u4Ret = WLAN_STATUS_INVALID_DATA; |
| goto Error; |
| } |
| } |
| #if 0 |
| if (fgAddTxBcKey || !prStaRec) { |
| |
| if ((prCmdKey->aucPeerAddr[0] |
| & prCmdKey->aucPeerAddr[1] |
| & prCmdKey->aucPeerAddr[2] |
| & prCmdKey->aucPeerAddr[3] |
| & prCmdKey->aucPeerAddr[4] |
| & prCmdKey->aucPeerAddr[5]) == 0xFF) { |
| prCmdKey->ucWlanIndex = |
| 255; /* AIS WEP Tx key */ |
| } else { /* Exist this case ? */ |
| ASSERT(FALSE); |
| /* prCmdKey->ucWlanIndex = */ |
| /* secPrivacySeekForBcEntry(prAdapter, */ |
| /* prBssInfo->ucBssIndex, */ |
| /* NETWORK_TYPE_AIS, */ |
| /* prCmdKey->aucPeerAddr, */ |
| /* prCmdKey->ucAlgorithmId, */ |
| /* prCmdKey->ucKeyId, */ |
| } |
| |
| prBssInfo->fgBcDefaultKeyExist = TRUE; |
| prBssInfo->ucBMCWlanIndex = |
| prCmdKey->ucWlanIndex; /* Saved for AIS WEP */ |
| prBssInfo->ucTxBcDefaultIdx = prCmdKey->ucKeyId; |
| } |
| #endif |
| } else { |
| /* Including IBSS RSN Rx BC key ? */ |
| if ((prCmdKey->aucPeerAddr[0] & prCmdKey->aucPeerAddr[1] & |
| prCmdKey->aucPeerAddr[2] & prCmdKey->aucPeerAddr[3] & |
| prCmdKey->aucPeerAddr[4] & prCmdKey->aucPeerAddr[5]) == |
| 0xFF) { |
| prCmdKey->ucWlanIndex = |
| WTBL_RESERVED_ENTRY; /* AIS WEP, should not have |
| * this case!! |
| */ |
| } else { |
| if (prStaRec) { /* AIS RSN Group key but addr is BSSID |
| */ |
| /* ASSERT(prStaRec->ucBMCWlanIndex < WTBL_SIZE) |
| */ |
| prCmdKey->ucWlanIndex = |
| secPrivacySeekForBcEntry(prAdapter, |
| prStaRec->ucBssIndex, |
| prStaRec->aucMacAddr, |
| prStaRec->ucIndex, |
| prCmdKey->ucAlgorithmId, |
| prCmdKey->ucKeyId); |
| prStaRec->ucWlanIndex = prCmdKey->ucWlanIndex; |
| } else { /* Exist this case ? */ |
| u4Ret = WLAN_STATUS_FAILURE; |
| goto Error; |
| /* prCmdKey->ucWlanIndex = */ |
| /* secPrivacySeekForBcEntry(prAdapter, */ |
| /* prBssInfo->ucBssIndex, */ |
| /* NETWORK_TYPE_AIS, */ |
| /* prCmdKey->aucPeerAddr, */ |
| /* prCmdKey->ucAlgorithmId, */ |
| /* prCmdKey->ucKeyId, */ |
| } |
| } |
| } |
| |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| |
| Error: |
| if (prCmdInfo) |
| cmdBufFreeCmdInfo(prAdapter, prCmdInfo); |
| return u4Ret; |
| } /* wlanoidSetAddKey */ |
| #endif |
| |
| #if CFG_SUPPORT_WPS2 |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called by WSC to set the assoc info, which is needed |
| * to add to Association request frame while join WPS AP. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * \param[in] u4SetBufferLen The length of the set buffer |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid length of |
| * the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetWSCAssocInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| DEBUGFUNC("wlanoidSetWSCAssocInfo"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| if (u4SetBufferLen == 0) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| kalMemCopy(prAdapter->prGlueInfo->aucWSCAssocInfoIE, |
| pvSetBuffer, u4SetBufferLen); |
| prAdapter->prGlueInfo->u2WSCAssocInfoIELen = |
| (uint16_t) u4SetBufferLen; |
| DBGLOG(SEC, TRACE, "Assoc Info IE sz %d\n", u4SetBufferLen); |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } |
| #endif |
| |
| #if CFG_ENABLE_WAKEUP_ON_LAN |
| uint32_t |
| wlanoidSetAddWakeupPattern(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_PM_PACKET_PATTERN *prPacketPattern; |
| |
| DEBUGFUNC("wlanoidSetAddWakeupPattern"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_PM_PACKET_PATTERN); |
| |
| if (u4SetBufferLen < sizeof(struct PARAM_PM_PACKET_PATTERN)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prPacketPattern = (struct PARAM_PM_PACKET_PATTERN *) |
| pvSetBuffer; |
| |
| /* FIXME: Send the struct to firmware */ |
| |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| uint32_t |
| wlanoidSetRemoveWakeupPattern(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_PM_PACKET_PATTERN *prPacketPattern; |
| |
| DEBUGFUNC("wlanoidSetAddWakeupPattern"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_PM_PACKET_PATTERN); |
| |
| if (u4SetBufferLen < sizeof(struct PARAM_PM_PACKET_PATTERN)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prPacketPattern = (struct PARAM_PM_PACKET_PATTERN *) |
| pvSetBuffer; |
| |
| /* FIXME: Send the struct to firmware */ |
| |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| uint32_t |
| wlanoidQueryEnableWakeup(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t *pu4WakeupEventEnable; |
| |
| DEBUGFUNC("wlanoidQueryEnableWakeup"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| pu4WakeupEventEnable = (uint32_t *) pvQueryBuffer; |
| |
| *pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable; |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetEnableWakeup(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pu4WakeupEventEnable; |
| |
| DEBUGFUNC("wlanoidSetEnableWakup"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| pu4WakeupEventEnable = (uint32_t *) pvSetBuffer; |
| prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable; |
| |
| /* FIXME: Send Command Event for setting |
| * wakeup-pattern / Magic Packet to firmware |
| */ |
| |
| return WLAN_STATUS_FAILURE; |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to configure PS related settings for WMM-PS |
| * test. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetWiFiWmmPsTest(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_WMM_PS_TEST_STRUCT *prWmmPsTestInfo; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| struct CMD_SET_WMM_PS_TEST_STRUCT rSetWmmPsTestParam; |
| uint16_t u2CmdBufLen; |
| struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; |
| struct BSS_INFO *prBssInfo; |
| |
| DEBUGFUNC("wlanoidSetWiFiWmmPsTest"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_WMM_PS_TEST_STRUCT); |
| |
| prWmmPsTestInfo = (struct PARAM_CUSTOM_WMM_PS_TEST_STRUCT *) |
| pvSetBuffer; |
| |
| rSetWmmPsTestParam.ucBssIndex = |
| prAdapter->prAisBssInfo->ucBssIndex; |
| rSetWmmPsTestParam.bmfgApsdEnAc = |
| prWmmPsTestInfo->bmfgApsdEnAc; |
| rSetWmmPsTestParam.ucIsEnterPsAtOnce = |
| prWmmPsTestInfo->ucIsEnterPsAtOnce; |
| rSetWmmPsTestParam.ucIsDisableUcTrigger = |
| prWmmPsTestInfo->ucIsDisableUcTrigger; |
| |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, |
| rSetWmmPsTestParam.ucBssIndex); |
| prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; |
| prPmProfSetupInfo->ucBmpDeliveryAC = |
| (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3); |
| prPmProfSetupInfo->ucBmpTriggerAC = |
| rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3); |
| |
| u2CmdBufLen = sizeof(struct CMD_SET_WMM_PS_TEST_STRUCT); |
| |
| #if 0 |
| /* it will apply the disable trig or not immediately */ |
| if (prPmInfo->ucWmmPsDisableUcPoll |
| && prPmInfo->ucWmmPsConnWithTrig) |
| NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); |
| else |
| NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); |
| #endif |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_WMM_PS_TEST_PARMS, |
| TRUE, FALSE, g_fgIsOid, |
| nicCmdEventSetCommon,/* TODO? */ |
| nicCmdTimeoutCommon, u2CmdBufLen, |
| (uint8_t *) &rSetWmmPsTestParam, NULL, 0); |
| |
| return rStatus; |
| } /* wlanoidSetWiFiWmmPsTest */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to configure enable/disable TX A-MPDU feature. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetTxAmpdu(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| struct CMD_TX_AMPDU rTxAmpdu; |
| uint16_t u2CmdBufLen; |
| u_int8_t *pfgEnable; |
| |
| DEBUGFUNC("wlanoidSetTxAmpdu"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(u_int8_t); |
| |
| pfgEnable = (u_int8_t *) pvSetBuffer; |
| |
| rTxAmpdu.fgEnable = *pfgEnable; |
| |
| u2CmdBufLen = sizeof(struct CMD_TX_AMPDU); |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_TX_AMPDU, |
| TRUE, FALSE, TRUE, NULL, NULL, |
| u2CmdBufLen, |
| (uint8_t *) &rTxAmpdu, NULL, 0); |
| |
| return rStatus; |
| } /* wlanoidSetTxAmpdu */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to configure reject/accept ADDBA Request. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetAddbaReject(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| struct CMD_ADDBA_REJECT rAddbaReject; |
| uint16_t u2CmdBufLen; |
| u_int8_t *pfgEnable; |
| |
| DEBUGFUNC("wlanoidSetAddbaReject"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(u_int8_t); |
| |
| pfgEnable = (u_int8_t *) pvSetBuffer; |
| |
| rAddbaReject.fgEnable = *pfgEnable; |
| |
| u2CmdBufLen = sizeof(struct CMD_ADDBA_REJECT); |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_ADDBA_REJECT, |
| TRUE, FALSE, TRUE, NULL, NULL, |
| u2CmdBufLen, |
| (uint8_t *) &rAddbaReject, NULL, 0); |
| |
| return rStatus; |
| } /* wlanoidSetAddbaReject */ |
| |
| #if CFG_SLT_SUPPORT |
| |
| uint32_t |
| wlanoidQuerySLTStatus(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| struct PARAM_MTK_SLT_TEST_STRUCT *prMtkSltInfo = |
| (struct PARAM_MTK_SLT_TEST_STRUCT *) NULL; |
| struct SLT_INFO *prSltInfo = (struct SLT_INFO *) NULL; |
| |
| DEBUGFUNC("wlanoidQuerySLTStatus"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_MTK_SLT_TEST_STRUCT); |
| |
| if (u4QueryBufferLen < sizeof(struct |
| PARAM_MTK_SLT_TEST_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvQueryBuffer); |
| |
| prMtkSltInfo = (struct PARAM_MTK_SLT_TEST_STRUCT *) |
| pvQueryBuffer; |
| |
| prSltInfo = &(prAdapter->rWifiVar.rSltInfo); |
| |
| switch (prMtkSltInfo->rSltFuncIdx) { |
| case ENUM_MTK_SLT_FUNC_LP_SET: { |
| struct PARAM_MTK_SLT_LP_TEST_STRUCT *prLpSetting = |
| (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) NULL; |
| |
| ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( |
| struct PARAM_MTK_SLT_LP_TEST_STRUCT)); |
| |
| prLpSetting = (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) |
| &prMtkSltInfo->unFuncInfoContent; |
| |
| prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt; |
| } |
| break; |
| default: |
| /* TBD... */ |
| break; |
| } |
| |
| return rWlanStatus; |
| } /* wlanoidQuerySLTStatus */ |
| |
| uint32_t |
| wlanoidUpdateSLTMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| struct PARAM_MTK_SLT_TEST_STRUCT *prMtkSltInfo = |
| (struct PARAM_MTK_SLT_TEST_STRUCT *) NULL; |
| struct SLT_INFO *prSltInfo = (struct SLT_INFO *) NULL; |
| struct BSS_DESC *prBssDesc = (struct BSS_DESC *) NULL; |
| struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL; |
| struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL; |
| |
| /* 1. Action: Update or Initial Set |
| * 2. Role. |
| * 3. Target MAC address. |
| * 4. RF BW & Rate Settings |
| */ |
| |
| DEBUGFUNC("wlanoidUpdateSLTMode"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_MTK_SLT_TEST_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_MTK_SLT_TEST_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prMtkSltInfo = (struct PARAM_MTK_SLT_TEST_STRUCT *) |
| pvSetBuffer; |
| |
| prSltInfo = &(prAdapter->rWifiVar.rSltInfo); |
| prBssInfo = prAdapter->prAisBssInfo; |
| |
| switch (prMtkSltInfo->rSltFuncIdx) { |
| case ENUM_MTK_SLT_FUNC_INITIAL: { /* Initialize */ |
| struct PARAM_MTK_SLT_INITIAL_STRUCT *prMtkSltInit = |
| (struct PARAM_MTK_SLT_INITIAL_STRUCT *) NULL; |
| |
| ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( |
| struct PARAM_MTK_SLT_INITIAL_STRUCT)); |
| |
| prMtkSltInit = (struct PARAM_MTK_SLT_INITIAL_STRUCT *) |
| &prMtkSltInfo->unFuncInfoContent; |
| |
| if (prSltInfo->prPseudoStaRec != NULL) { |
| /* The driver has been initialized. */ |
| prSltInfo->prPseudoStaRec = NULL; |
| } |
| |
| prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc( |
| prAdapter, BSS_TYPE_IBSS, |
| prMtkSltInit->aucTargetMacAddr, |
| prMtkSltInit->aucTargetMacAddr); |
| |
| prSltInfo->u2SiteID = prMtkSltInit->u2SiteID; |
| |
| /* Bandwidth 2.4G: Channel 1~14 |
| * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64, |
| * *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, |
| * 149, 153, *157, 161, |
| * 184, 188, 192, 196, 200, 204, 208, 212, *216 |
| */ |
| prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5; |
| |
| switch (prSltInfo->ucChannel2G4) { |
| case 1: |
| prSltInfo->ucChannel5G = 36; |
| break; |
| case 6: |
| prSltInfo->ucChannel5G = 52; |
| break; |
| case 11: |
| prSltInfo->ucChannel5G = 104; |
| break; |
| case 16: |
| prSltInfo->ucChannel2G4 = 14; |
| prSltInfo->ucChannel5G = 161; |
| break; |
| default: |
| ASSERT(FALSE); |
| } |
| |
| if (prSltInfo->prPseudoBssDesc == NULL) { |
| do { |
| prSltInfo->prPseudoBssDesc = |
| scanAllocateBssDesc(prAdapter); |
| |
| if (prSltInfo->prPseudoBssDesc == NULL) { |
| rWlanStatus = WLAN_STATUS_FAILURE; |
| break; |
| } |
| prBssDesc = prSltInfo->prPseudoBssDesc; |
| |
| } while (FALSE); |
| } else { |
| prBssDesc = prSltInfo->prPseudoBssDesc; |
| } |
| |
| if (prBssDesc) { |
| prBssDesc->eBSSType = BSS_TYPE_IBSS; |
| |
| COPY_MAC_ADDR(prBssDesc->aucSrcAddr, |
| prMtkSltInit->aucTargetMacAddr); |
| COPY_MAC_ADDR(prBssDesc->aucBSSID, |
| prBssInfo->aucOwnMacAddr); |
| |
| prBssDesc->u2BeaconInterval = 100; |
| prBssDesc->u2ATIMWindow = 0; |
| prBssDesc->ucDTIMPeriod = 1; |
| |
| prBssDesc->u2IELength = 0; |
| |
| prBssDesc->fgIsERPPresent = TRUE; |
| prBssDesc->fgIsHTPresent = TRUE; |
| |
| prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX); |
| prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX); |
| prBssDesc->fgIsUnknownBssBasicRate = FALSE; |
| |
| prBssDesc->fgIsLargerTSF = TRUE; |
| |
| prBssDesc->eBand = BAND_2G4; |
| |
| prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4; |
| |
| prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN; |
| |
| GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); |
| } |
| } |
| break; |
| case ENUM_MTK_SLT_FUNC_RATE_SET: /* Update RF Settings. */ |
| if (prSltInfo->prPseudoStaRec == NULL) { |
| rWlanStatus = WLAN_STATUS_FAILURE; |
| } else { |
| struct PARAM_MTK_SLT_TR_TEST_STRUCT *prTRSetting = |
| (struct PARAM_MTK_SLT_TR_TEST_STRUCT *) NULL; |
| |
| ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( |
| struct PARAM_MTK_SLT_TR_TEST_STRUCT)); |
| |
| prStaRec = prSltInfo->prPseudoStaRec; |
| prTRSetting = (struct PARAM_MTK_SLT_TR_TEST_STRUCT *) |
| &prMtkSltInfo->unFuncInfoContent; |
| |
| if (prTRSetting->rNetworkType == |
| PARAM_NETWORK_TYPE_OFDM5) { |
| prBssInfo->eBand = BAND_5G; |
| prBssInfo->ucPrimaryChannel = |
| prSltInfo->ucChannel5G; |
| } |
| if (prTRSetting->rNetworkType == |
| PARAM_NETWORK_TYPE_OFDM24) { |
| prBssInfo->eBand = BAND_2G4; |
| prBssInfo->ucPrimaryChannel = |
| prSltInfo->ucChannel2G4; |
| } |
| |
| if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) { |
| /* RF 40 */ |
| /* It would controls RFBW capability in WTBL. */ |
| prStaRec->u2HtCapInfo |= |
| HT_CAP_INFO_SUP_CHNL_WIDTH; |
| /* This controls RF BW, RF BW would be 40 |
| * only if |
| * 1. PHY_TYPE_BIT_HT is TRUE. |
| * 2. SCO is SCA/SCB. |
| */ |
| prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; |
| |
| /* U20/L20 Control. */ |
| switch (prTRSetting->u4FixedRate & 0xC000) { |
| case FIXED_EXT_CHNL_U20: |
| prBssInfo->eBssSCO = |
| CHNL_EXT_SCB; /* +2 */ |
| if (prTRSetting->rNetworkType == |
| PARAM_NETWORK_TYPE_OFDM5) { |
| prBssInfo->ucPrimaryChannel |
| += 2; |
| } else { |
| /* For channel 1, testing L20 at |
| * channel 8. AOSP |
| */ |
| SetTestChannel( |
| &prBssInfo->ucPrimaryChannel); |
| } |
| break; |
| case FIXED_EXT_CHNL_L20: |
| default: /* 40M */ |
| prBssInfo->eBssSCO = |
| CHNL_EXT_SCA; /* -2 */ |
| if (prTRSetting->rNetworkType == |
| PARAM_NETWORK_TYPE_OFDM5) { |
| prBssInfo->ucPrimaryChannel |
| -= 2; |
| } else { |
| /* For channel 11 / 14. testing |
| * U20 at channel 3. AOSP |
| */ |
| SetTestChannel( |
| &prBssInfo->ucPrimaryChannel); |
| } |
| break; |
| } |
| } else { |
| /* RF 20 */ |
| prStaRec->u2HtCapInfo &= |
| ~HT_CAP_INFO_SUP_CHNL_WIDTH; |
| prBssInfo->eBssSCO = CHNL_EXT_SCN; |
| } |
| |
| prBssInfo->fgErpProtectMode = FALSE; |
| prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; |
| prBssInfo->eGfOperationMode = GF_MODE_NORMAL; |
| |
| nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); |
| |
| prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | |
| HT_CAP_INFO_SHORT_GI_40M); |
| |
| switch (prTRSetting->u4FixedRate & 0xFF) { |
| case RATE_OFDM_54M: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_54M_SW_INDEX); |
| break; |
| case RATE_OFDM_48M: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_48M_SW_INDEX); |
| break; |
| case RATE_OFDM_36M: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_36M_SW_INDEX); |
| break; |
| case RATE_OFDM_24M: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_24M_SW_INDEX); |
| break; |
| case RATE_OFDM_6M: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_6M_SW_INDEX); |
| break; |
| case RATE_CCK_11M_LONG: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_11M_SW_INDEX); |
| break; |
| case RATE_CCK_1M_LONG: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_1M_SW_INDEX); |
| break; |
| case RATE_GF_MCS_0: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_HT_PHY_SW_INDEX); |
| prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; |
| break; |
| case RATE_MM_MCS_7: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_HT_PHY_SW_INDEX); |
| prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; |
| #if 0 /* Only for Current Measurement Mode. */ |
| prStaRec->u2HtCapInfo |= |
| (HT_CAP_INFO_SHORT_GI_20M | |
| HT_CAP_INFO_SHORT_GI_40M); |
| #endif |
| break; |
| case RATE_GF_MCS_7: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_HT_PHY_SW_INDEX); |
| prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; |
| break; |
| default: |
| prStaRec->u2DesiredNonHTRateSet = |
| BIT(RATE_36M_SW_INDEX); |
| break; |
| } |
| |
| cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); |
| |
| cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); |
| |
| } |
| break; |
| case ENUM_MTK_SLT_FUNC_LP_SET: { /* Reset LP Test Result. */ |
| struct PARAM_MTK_SLT_LP_TEST_STRUCT *prLpSetting = |
| (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) NULL; |
| |
| ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof( |
| struct PARAM_MTK_SLT_LP_TEST_STRUCT)); |
| |
| prLpSetting = (struct PARAM_MTK_SLT_LP_TEST_STRUCT *) |
| &prMtkSltInfo->unFuncInfoContent; |
| |
| if (prSltInfo->prPseudoBssDesc == NULL) { |
| /* Please initial SLT Mode first. */ |
| break; |
| } |
| prBssDesc = prSltInfo->prPseudoBssDesc; |
| |
| switch (prLpSetting->rLpTestMode) { |
| case ENUM_MTK_LP_TEST_NORMAL: |
| /* In normal mode, we would use target MAC address to be |
| * the BSSID. |
| */ |
| COPY_MAC_ADDR(prBssDesc->aucBSSID, |
| prBssInfo->aucOwnMacAddr); |
| prSltInfo->fgIsDUT = FALSE; |
| break; |
| case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE: |
| /* 1. Lower AIFS of BCN queue. |
| * 2. Fixed Random Number tobe 0. |
| */ |
| prSltInfo->fgIsDUT = FALSE; |
| /* In LP test mode, we would use MAC address of Golden |
| * Sample to be the BSSID. |
| */ |
| COPY_MAC_ADDR(prBssDesc->aucBSSID, |
| prBssInfo->aucOwnMacAddr); |
| break; |
| case ENUM_MTK_LP_TEST_DUT: |
| /* 1. Enter Sleep Mode. |
| * 2. Fix random number a large value & enlarge AIFN of |
| * BCN queue. |
| */ |
| COPY_MAC_ADDR(prBssDesc->aucBSSID, |
| prBssDesc->aucSrcAddr); |
| prSltInfo->u4BeaconReceiveCnt = 0; |
| prSltInfo->fgIsDUT = TRUE; |
| break; |
| } |
| |
| } |
| |
| break; |
| default: |
| break; |
| } |
| |
| return WLAN_STATUS_FAILURE; |
| |
| return rWlanStatus; |
| } /* wlanoidUpdateSLTMode */ |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query NVRAM value. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryNvramRead(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_EEPROM_RW_STRUCT *prNvramRwInfo; |
| uint16_t u2Data; |
| u_int8_t fgStatus; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQueryNvramRead"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT); |
| |
| if (u4QueryBufferLen < sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prNvramRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) |
| pvQueryBuffer; |
| |
| if (prNvramRwInfo->ucEepromMethod == |
| PARAM_EEPROM_READ_METHOD_READ) { |
| fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, |
| prNvramRwInfo->ucEepromIndex << |
| 1, /* change to byte offset */ |
| &u2Data); |
| |
| if (fgStatus) { |
| prNvramRwInfo->u2EepromData = u2Data; |
| DBGLOG(REQ, INFO, |
| "NVRAM Read: index=%#X, data=%#02X\r\n", |
| prNvramRwInfo->ucEepromIndex, u2Data); |
| } else { |
| DBGLOG(REQ, ERROR, "NVRAM Read Failed: index=%#x.\r\n", |
| prNvramRwInfo->ucEepromIndex); |
| rStatus = WLAN_STATUS_FAILURE; |
| } |
| } else if (prNvramRwInfo->ucEepromMethod == |
| PARAM_EEPROM_READ_METHOD_GETSIZE) { |
| prNvramRwInfo->u2EepromData = CFG_FILE_WIFI_REC_SIZE; |
| DBGLOG(REQ, INFO, "EEPROM size =%d\r\n", |
| prNvramRwInfo->u2EepromData); |
| } |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT); |
| |
| return rStatus; |
| } /* wlanoidQueryNvramRead */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to write NVRAM value. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetNvramWrite(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_EEPROM_RW_STRUCT *prNvramRwInfo; |
| u_int8_t fgStatus; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidSetNvramWrite"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_EEPROM_RW_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prNvramRwInfo = (struct PARAM_CUSTOM_EEPROM_RW_STRUCT *) |
| pvSetBuffer; |
| |
| fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, |
| prNvramRwInfo->ucEepromIndex << |
| 1, /* change to byte offset */ |
| prNvramRwInfo->u2EepromData); |
| |
| if (fgStatus == FALSE) { |
| DBGLOG(REQ, ERROR, "NVRAM Write Failed.\r\n"); |
| rStatus = WLAN_STATUS_FAILURE; |
| } |
| |
| return rStatus; |
| } /* wlanoidSetNvramWrite */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to get the config data source type. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryCfgSrcType(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| ASSERT(prAdapter); |
| |
| *pu4QueryInfoLen = sizeof(enum ENUM_CFG_SRC_TYPE); |
| |
| if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) |
| *(enum ENUM_CFG_SRC_TYPE *) pvQueryBuffer = |
| CFG_SRC_TYPE_NVRAM; |
| else |
| *(enum ENUM_CFG_SRC_TYPE *) pvQueryBuffer = |
| CFG_SRC_TYPE_EEPROM; |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to get the config data source type. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryEepromType(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| ASSERT(prAdapter); |
| |
| *pu4QueryInfoLen = sizeof(enum ENUM_EEPROM_TYPE *); |
| |
| #if CFG_SUPPORT_NIC_CAPABILITY |
| if (prAdapter->fgIsEepromUsed == TRUE) |
| *(enum ENUM_EEPROM_TYPE *) pvQueryBuffer = |
| EEPROM_TYPE_PRESENT; |
| else |
| *(enum ENUM_EEPROM_TYPE *) pvQueryBuffer = EEPROM_TYPE_NO; |
| #else |
| *(enum ENUM_EEPROM_TYPE *) pvQueryBuffer = EEPROM_TYPE_NO; |
| #endif |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to get the config data source type. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_FAILURE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetCountryCode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint8_t *pucCountry; |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| |
| if (regd_is_single_sku_en()) { |
| rlmDomainOidSetCountry(prAdapter, pvSetBuffer, |
| u4SetBufferLen); |
| *pu4SetInfoLen = u4SetBufferLen; |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| ASSERT(u4SetBufferLen == 2); |
| |
| *pu4SetInfoLen = 2; |
| |
| pucCountry = pvSetBuffer; |
| |
| prAdapter->rWifiVar.rConnSettings.u2CountryCode = |
| (((uint16_t) pucCountry[0]) << 8) | ((uint16_t) pucCountry[1]); |
| |
| /* Force to re-search country code in regulatory domains */ |
| prAdapter->prDomainInfo = NULL; |
| rlmDomainSendCmd(prAdapter); |
| |
| /* Update supported channel list in channel table based on current |
| * country domain |
| */ |
| wlanUpdateChannelTable(prAdapter->prGlueInfo); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetScanMacOui(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct PARAM_BSS_MAC_OUI *prParamMacOui; |
| struct BSS_INFO *prBssInfo; |
| |
| ASSERT(prAdapter); |
| ASSERT(prAdapter->prGlueInfo); |
| ASSERT(pvSetBuffer); |
| ASSERT(u4SetBufferLen == sizeof(struct PARAM_BSS_MAC_OUI)); |
| |
| prParamMacOui = (struct PARAM_BSS_MAC_OUI *)pvSetBuffer; |
| |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prParamMacOui->ucBssIndex); |
| if (!prBssInfo) { |
| log_dbg(REQ, ERROR, "Invalid bss info (ind=%u)\n", |
| prParamMacOui->ucBssIndex); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| kalMemCopy(prBssInfo->ucScanOui, prParamMacOui->ucMacOui, MAC_OUI_LEN); |
| prBssInfo->fgIsScanOuiSet = TRUE; |
| *pu4SetInfoLen = MAC_OUI_LEN; |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| #if 0 |
| uint32_t |
| wlanoidSetNoaParam(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_NOA_PARAM_STRUCT *prNoaParam; |
| struct CMD_CUSTOM_NOA_PARAM_STRUCT rCmdNoaParam; |
| |
| DEBUGFUNC("wlanoidSetNoaParam"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_NOA_PARAM_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_NOA_PARAM_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prNoaParam = (struct PARAM_CUSTOM_NOA_PARAM_STRUCT *) |
| pvSetBuffer; |
| |
| kalMemZero(&rCmdNoaParam, |
| sizeof(struct CMD_CUSTOM_NOA_PARAM_STRUCT)); |
| rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; |
| rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; |
| rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_NOA_PARAM, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_CUSTOM_NOA_PARAM_STRUCT), |
| (uint8_t *) &rCmdNoaParam, pvSetBuffer, |
| u4SetBufferLen); |
| } |
| |
| uint32_t |
| wlanoidSetOppPsParam(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT *prOppPsParam; |
| struct CMD_CUSTOM_OPPPS_PARAM_STRUCT rCmdOppPsParam; |
| |
| DEBUGFUNC("wlanoidSetOppPsParam"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_OPPPS_PARAM_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_OPPPS_PARAM_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prOppPsParam = (struct PARAM_CUSTOM_OPPPS_PARAM_STRUCT *) |
| pvSetBuffer; |
| |
| kalMemZero(&rCmdOppPsParam, |
| sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT)); |
| rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_OPPPS_PARAM, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT), |
| (uint8_t *) &rCmdOppPsParam, pvSetBuffer, |
| u4SetBufferLen); |
| } |
| |
| uint32_t |
| wlanoidSetUApsdParam(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT *prUapsdParam; |
| struct CMD_CUSTOM_UAPSD_PARAM_STRUCT rCmdUapsdParam; |
| struct PM_PROFILE_SETUP_INFO *prPmProfSetupInfo; |
| struct BSS_INFO *prBssInfo; |
| |
| DEBUGFUNC("wlanoidSetUApsdParam"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_UAPSD_PARAM_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_UAPSD_PARAM_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prBssInfo = & |
| (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); |
| prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; |
| |
| prUapsdParam = (struct PARAM_CUSTOM_UAPSD_PARAM_STRUCT *) |
| pvSetBuffer; |
| |
| kalMemZero(&rCmdUapsdParam, |
| sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT)); |
| rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; |
| prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; |
| |
| rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; |
| rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; |
| rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; |
| rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; |
| prPmProfSetupInfo->ucBmpDeliveryAC = |
| ((prUapsdParam->fgEnAPSD_AcBe << 0) | |
| (prUapsdParam->fgEnAPSD_AcBk << 1) | |
| (prUapsdParam->fgEnAPSD_AcVi << 2) | |
| (prUapsdParam->fgEnAPSD_AcVo << 3)); |
| prPmProfSetupInfo->ucBmpTriggerAC = |
| ((prUapsdParam->fgEnAPSD_AcBe << 0) | |
| (prUapsdParam->fgEnAPSD_AcBk << 1) | |
| (prUapsdParam->fgEnAPSD_AcVi << 2) | |
| (prUapsdParam->fgEnAPSD_AcVo << 3)); |
| |
| rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; |
| prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_UAPSD_PARAM, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_CUSTOM_OPPPS_PARAM_STRUCT), |
| (uint8_t *)&rCmdUapsdParam, pvSetBuffer, |
| u4SetBufferLen); |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set BT profile or BT information and the |
| * driver will set the built-in PTA configuration into chip. |
| * |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetBT(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| |
| struct PTA_IPC *prPtaIpc; |
| |
| DEBUGFUNC("wlanoidSetBT.\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PTA_IPC); |
| if (u4SetBufferLen != sizeof(struct PTA_IPC)) { |
| /* WARNLOG(("Invalid length %ld\n", u4SetBufferLen)); */ |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail to set BT profile because of ACPI_D3\n"); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| ASSERT(pvSetBuffer); |
| prPtaIpc = (struct PTA_IPC *) pvSetBuffer; |
| |
| #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG |
| DBGLOG(INIT, INFO, |
| "BCM BWCS CMD: BWCS CMD = %02x%02x%02x%02x\n", |
| prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], |
| prPtaIpc->u.aucBTPParams[2], prPtaIpc->u.aucBTPParams[3]); |
| |
| DBGLOG(INIT, INFO, |
| "BCM BWCS CMD: aucBTPParams[0]=%02x, aucBTPParams[1]=%02x, aucBTPParams[2]=%02x, aucBTPParams[3]=%02x.\n", |
| prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], |
| prPtaIpc->u.aucBTPParams[2], prPtaIpc->u.aucBTPParams[3]); |
| |
| #endif |
| |
| wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_BWCS, TRUE, FALSE, FALSE, |
| NULL, NULL, sizeof(struct PTA_IPC), |
| (uint8_t *) prPtaIpc, NULL, 0); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to query current BT profile and BTCR values |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number |
| * of bytes written into the query buffer. If the |
| * call failed due to invalid length of the query |
| * buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryBT(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| /* P_PARAM_PTA_IPC_T prPtaIpc; */ |
| /* UINT_32 u4QueryBuffLen; */ |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct PTA_IPC); |
| |
| /* Check for query buffer length */ |
| if (u4QueryBufferLen != sizeof(struct PTA_IPC)) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| ASSERT(pvQueryBuffer); |
| /* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */ |
| /* prPtaIpc->ucCmd = BT_CMD_PROFILE; */ |
| /* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */ |
| /* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); |
| */ |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| #if 0 |
| uint32_t |
| wlanoidQueryBtSingleAntenna(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| P_PTA_INFO_T prPtaInfo; |
| uint32_t *pu4SingleAntenna; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| /* Check for query buffer length */ |
| if (u4QueryBufferLen != sizeof(uint32_t)) { |
| DBGLOG(REQ, WARN, "Invalid length %lu\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| ASSERT(pvQueryBuffer); |
| |
| prPtaInfo = &prAdapter->rPtaInfo; |
| pu4SingleAntenna = (uint32_t *) pvQueryBuffer; |
| |
| if (prPtaInfo->fgSingleAntenna) { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME |
| * "Q Single Ant = 1\r\n")); |
| */ |
| *pu4SingleAntenna = 1; |
| } else { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME |
| * "Q Single Ant = 0\r\n")); |
| */ |
| *pu4SingleAntenna = 0; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetBtSingleAntenna(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| |
| uint32_t *pu4SingleAntenna; |
| uint32_t u4SingleAntenna; |
| P_PTA_INFO_T prPtaInfo; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| prPtaInfo = &prAdapter->rPtaInfo; |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| if (u4SetBufferLen != sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (IS_ARB_IN_RFTEST_STATE(prAdapter)) |
| return WLAN_STATUS_SUCCESS; |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail to set antenna because of ACPI_D3\n"); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| ASSERT(pvSetBuffer); |
| pu4SingleAntenna = (uint32_t *) pvSetBuffer; |
| u4SingleAntenna = *pu4SingleAntenna; |
| |
| if (u4SingleAntenna == 0) { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME |
| * "Set Single Ant = 0\r\n")); |
| */ |
| prPtaInfo->fgSingleAntenna = FALSE; |
| } else { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME |
| * "Set Single Ant = 1\r\n")); |
| */ |
| prPtaInfo->fgSingleAntenna = TRUE; |
| } |
| ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS |
| uint32_t |
| wlanoidQueryPta(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| P_PTA_INFO_T prPtaInfo; |
| uint32_t *pu4Pta; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| /* Check for query buffer length */ |
| if (u4QueryBufferLen != sizeof(uint32_t)) { |
| DBGLOG(REQ, WARN, "Invalid length %lu\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| ASSERT(pvQueryBuffer); |
| |
| prPtaInfo = &prAdapter->rPtaInfo; |
| pu4Pta = (uint32_t *) pvQueryBuffer; |
| |
| if (prPtaInfo->fgEnabled) { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */ |
| *pu4Pta = 1; |
| } else { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */ |
| *pu4Pta = 0; |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetPta(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pu4PtaCtrl; |
| uint32_t u4PtaCtrl; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| if (u4SetBufferLen != sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| if (IS_ARB_IN_RFTEST_STATE(prAdapter)) |
| return WLAN_STATUS_SUCCESS; |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail to set BT setting because of ACPI_D3\n"); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| ASSERT(pvSetBuffer); |
| pu4PtaCtrl = (uint32_t *) pvSetBuffer; |
| u4PtaCtrl = *pu4PtaCtrl; |
| |
| if (u4PtaCtrl == 0) { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); |
| */ |
| nicPtaSetFunc(prAdapter, FALSE); |
| } else { |
| /* DBGLOG(INIT, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); |
| */ |
| nicPtaSetFunc(prAdapter, TRUE); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif |
| |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set Tx power profile. |
| * |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetTxPower(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct SET_TXPWR_CTRL *pTxPwr = (struct SET_TXPWR_CTRL *) |
| pvSetBuffer; |
| struct SET_TXPWR_CTRL *prCmd; |
| uint32_t i; |
| uint32_t rStatus; |
| |
| DEBUGFUNC("wlanoidSetTxPower"); |
| DBGLOG(REQ, LOUD, "\r\n"); |
| |
| prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, |
| sizeof(struct SET_TXPWR_CTRL)); |
| kalMemZero(prCmd, sizeof(struct SET_TXPWR_CTRL)); |
| prCmd->c2GLegacyStaPwrOffset = |
| pTxPwr->c2GLegacyStaPwrOffset; |
| prCmd->c2GHotspotPwrOffset = pTxPwr->c2GHotspotPwrOffset; |
| prCmd->c2GP2pPwrOffset = pTxPwr->c2GP2pPwrOffset; |
| prCmd->c2GBowPwrOffset = pTxPwr->c2GBowPwrOffset; |
| prCmd->c5GLegacyStaPwrOffset = |
| pTxPwr->c5GLegacyStaPwrOffset; |
| prCmd->c5GHotspotPwrOffset = pTxPwr->c5GHotspotPwrOffset; |
| prCmd->c5GP2pPwrOffset = pTxPwr->c5GP2pPwrOffset; |
| prCmd->c5GBowPwrOffset = pTxPwr->c5GBowPwrOffset; |
| prCmd->ucConcurrencePolicy = pTxPwr->ucConcurrencePolicy; |
| for (i = 0; i < 14; i++) |
| prCmd->acTxPwrLimit2G[i] = pTxPwr->acTxPwrLimit2G[i]; |
| |
| for (i = 0; i < 4; i++) |
| prCmd->acTxPwrLimit5G[i] = pTxPwr->acTxPwrLimit5G[i]; |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| |
| #if 0 |
| DBGLOG(INIT, INFO, "c2GLegacyStaPwrOffset=%d\n", |
| pTxPwr->c2GLegacyStaPwrOffset); |
| DBGLOG(INIT, INFO, "c2GHotspotPwrOffset=%d\n", |
| pTxPwr->c2GHotspotPwrOffset); |
| DBGLOG(INIT, INFO, "c2GP2pPwrOffset=%d\n", |
| pTxPwr->c2GP2pPwrOffset); |
| DBGLOG(INIT, INFO, "c2GBowPwrOffset=%d\n", |
| pTxPwr->c2GBowPwrOffset); |
| DBGLOG(INIT, INFO, "c5GLegacyStaPwrOffset=%d\n", |
| pTxPwr->c5GLegacyStaPwrOffset); |
| DBGLOG(INIT, INFO, "c5GHotspotPwrOffset=%d\n", |
| pTxPwr->c5GHotspotPwrOffset); |
| DBGLOG(INIT, INFO, "c5GP2pPwrOffset=%d\n", |
| pTxPwr->c5GP2pPwrOffset); |
| DBGLOG(INIT, INFO, "c5GBowPwrOffset=%d\n", |
| pTxPwr->c5GBowPwrOffset); |
| DBGLOG(INIT, INFO, "ucConcurrencePolicy=%d\n", |
| pTxPwr->ucConcurrencePolicy); |
| |
| for (i = 0; i < 14; i++) |
| DBGLOG(INIT, INFO, "acTxPwrLimit2G[%d]=%d\n", i, |
| pTxPwr->acTxPwrLimit2G[i]); |
| |
| for (i = 0; i < 4; i++) |
| DBGLOG(INIT, INFO, "acTxPwrLimit5G[%d]=%d\n", i, |
| pTxPwr->acTxPwrLimit5G[i]); |
| #endif |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ |
| CMD_ID_SET_TXPWR_CTRL, /* ucCID */ |
| TRUE, /* fgSetQuery */ |
| FALSE, /* fgNeedResp */ |
| g_fgIsOid, /* fgIsOid */ |
| nicCmdEventSetCommon, nicOidCmdTimeoutCommon, |
| sizeof(struct SET_TXPWR_CTRL), /* u4SetQueryInfoLen */ |
| (uint8_t *) prCmd, /* pucInfoBuffer */ |
| NULL, /* pvSetQueryBuffer */ |
| 0 /* u4SetQueryBufferLen */ |
| ); |
| |
| /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ |
| cnmMemFree(prAdapter, prCmd); |
| |
| return rStatus; |
| |
| } |
| |
| uint32_t wlanSendMemDumpCmd(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen) { |
| struct PARAM_CUSTOM_MEM_DUMP_STRUCT *prMemDumpInfo; |
| struct CMD_DUMP_MEM *prCmdDumpMem; |
| struct CMD_DUMP_MEM rCmdDumpMem; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| uint32_t u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; |
| |
| uint32_t u4RemainLeng = 0; |
| uint32_t u4CurAddr = 0; |
| uint8_t ucFragNum = 0; |
| |
| prCmdDumpMem = &rCmdDumpMem; |
| prMemDumpInfo = (struct PARAM_CUSTOM_MEM_DUMP_STRUCT *) |
| pvQueryBuffer; |
| |
| u4RemainLeng = prMemDumpInfo->u4RemainLength; |
| u4CurAddr = prMemDumpInfo->u4Address + |
| prMemDumpInfo->u4Length; |
| ucFragNum = prMemDumpInfo->ucFragNum + 1; |
| |
| /* Query. If request length is larger than max length, do it as ping |
| * pong. Send a command and wait for a event. Send next command while |
| * the event is received. |
| */ |
| do { |
| uint32_t u4CurLeng = 0; |
| |
| if (u4RemainLeng > u4MemSize) { |
| u4CurLeng = u4MemSize; |
| u4RemainLeng -= u4MemSize; |
| } else { |
| u4CurLeng = u4RemainLeng; |
| u4RemainLeng = 0; |
| } |
| |
| prCmdDumpMem->u4Address = u4CurAddr; |
| prCmdDumpMem->u4Length = u4CurLeng; |
| prCmdDumpMem->u4RemainLength = u4RemainLeng; |
| prCmdDumpMem->ucFragNum = ucFragNum; |
| #if CFG_SUPPORT_QA_TOOL |
| prCmdDumpMem->u4IcapContent = prMemDumpInfo->u4IcapContent; |
| #endif /* CFG_SUPPORT_QA_TOOL */ |
| |
| DBGLOG(REQ, TRACE, "[%d] 0x%X, len %u, remain len %u\n", |
| ucFragNum, prCmdDumpMem->u4Address, |
| prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength); |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_DUMP_MEM, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventQueryMemDump, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_DUMP_MEM), |
| (uint8_t *) prCmdDumpMem, |
| pvQueryBuffer, u4QueryBufferLen); |
| |
| } while (FALSE); |
| |
| return rStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to dump memory. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryMemDump(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_CUSTOM_MEM_DUMP_STRUCT *prMemDumpInfo; |
| |
| DEBUGFUNC("wlanoidQueryMemDump"); |
| DBGLOG(INIT, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| |
| prMemDumpInfo = (struct PARAM_CUSTOM_MEM_DUMP_STRUCT *) |
| pvQueryBuffer; |
| DBGLOG(REQ, TRACE, "Dump 0x%X, len %u\n", |
| prMemDumpInfo->u4Address, prMemDumpInfo->u4Length); |
| |
| prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length; |
| prMemDumpInfo->u4Length = 0; |
| prMemDumpInfo->ucFragNum = 0; |
| |
| return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* end of wlanoidQueryMcrRead() */ |
| |
| #if CFG_ENABLE_WIFI_DIRECT |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is used to set the p2p mode. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetP2pMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t status = WLAN_STATUS_SUCCESS; |
| struct PARAM_CUSTOM_P2P_SET_STRUCT *prSetP2P = |
| (struct PARAM_CUSTOM_P2P_SET_STRUCT *) NULL; |
| /* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = |
| * P_MSG_P2P_NETDEV_REGISTER_T)NULL; |
| */ |
| DEBUGFUNC("wlanoidSetP2pMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_P2P_SET_STRUCT); |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_P2P_SET_STRUCT)) { |
| DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prSetP2P = (struct PARAM_CUSTOM_P2P_SET_STRUCT *) |
| pvSetBuffer; |
| |
| DBGLOG(P2P, TRACE, "Set P2P enable[%d] mode[%d]\n", |
| prSetP2P->u4Enable, prSetP2P->u4Mode); |
| |
| /* |
| * enable = 1, mode = 0 => init P2P network |
| * enable = 1, mode = 1 => init Soft AP network |
| * enable = 0 => uninit P2P/AP network |
| * enable = 1, mode = 2 => init dual Soft AP network |
| * enable = 1, mode = 3 => init AP+P2P network |
| */ |
| |
| |
| DBGLOG(P2P, INFO, "P2P Compile as (%d)p2p-like interface\n", |
| KAL_P2P_NUM); |
| |
| if (prSetP2P->u4Mode >= RUNNING_P2P_MODE_NUM) { |
| DBGLOG(P2P, ERROR, "P2P interface mode(%d) is wrong\n", |
| prSetP2P->u4Mode); |
| ASSERT(0); |
| } |
| |
| if (prSetP2P->u4Enable) { |
| p2pSetMode(prSetP2P->u4Mode); |
| |
| if (p2pLaunch(prAdapter->prGlueInfo)) { |
| /* ToDo:: ASSERT */ |
| ASSERT(prAdapter->fgIsP2PRegistered); |
| if (prAdapter->rWifiVar.ucApUapsd |
| && (prSetP2P->u4Mode != RUNNING_P2P_MODE)) { |
| DBGLOG(OID, INFO, |
| "wlanoidSetP2pMode Default enable ApUapsd\n"); |
| setApUapsdEnable(prAdapter, TRUE); |
| } |
| } else { |
| DBGLOG(P2P, ERROR, "P2P Launch Failed\n"); |
| status = WLAN_STATUS_FAILURE; |
| } |
| |
| } else { |
| if (prAdapter->fgIsP2PRegistered) |
| p2pRemove(prAdapter->prGlueInfo); |
| |
| } |
| |
| #if 0 |
| prP2pNetdevRegMsg = (struct MSG_P2P_NETDEV_REGISTER *) |
| cnmMemAlloc(prAdapter, RAM_TYPE_MSG, |
| (sizeof(struct MSG_P2P_NETDEV_REGISTER))); |
| |
| if (prP2pNetdevRegMsg == NULL) { |
| ASSERT(FALSE); |
| status = WLAN_STATUS_RESOURCES; |
| return status; |
| } |
| |
| prP2pNetdevRegMsg->rMsgHdr.eMsgId = |
| MID_MNY_P2P_NET_DEV_REGISTER; |
| prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? |
| TRUE : FALSE; |
| prP2pNetdevRegMsg->ucMode = (uint8_t) prSetP2P->u4Mode; |
| |
| mboxSendMsg(prAdapter, MBOX_ID_0, |
| (struct MSG_HDR *) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF); |
| #endif |
| |
| return status; |
| |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set the GTK rekey data |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| * \retval WLAN_STATUS_INVALID_DATA |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetGtkRekeyData(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct GLUE_INFO *prGlueInfo; |
| struct CMD_INFO *prCmdInfo; |
| struct WIFI_CMD *prWifiCmd; |
| uint8_t ucCmdSeqNum; |
| struct BSS_INFO *prBssInfo; |
| |
| DBGLOG(REQ, INFO, "wlanoidSetGtkRekeyData\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(RSN, WARN, |
| "Fail in set rekey! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| prBssInfo = prAdapter->prAisBssInfo; |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| prGlueInfo = prAdapter->prGlueInfo; |
| prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, |
| (CMD_HDR_SIZE + sizeof(struct PARAM_GTK_REKEY_DATA))); |
| |
| if (!prCmdInfo) { |
| DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* increase command sequence number */ |
| ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); |
| DBGLOG(REQ, INFO, "ucCmdSeqNum = %d\n", ucCmdSeqNum); |
| |
| /* compose PARAM_GTK_REKEY_DATA cmd pkt */ |
| prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; |
| prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof( |
| struct PARAM_GTK_REKEY_DATA); |
| prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; |
| prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; |
| prCmdInfo->fgIsOid = g_fgIsOid; |
| prCmdInfo->ucCID = CMD_ID_SET_GTK_REKEY_DATA; |
| prCmdInfo->fgSetQuery = TRUE; |
| prCmdInfo->fgNeedResp = FALSE; |
| prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; |
| prCmdInfo->u4SetInfoLen = u4SetBufferLen; |
| prCmdInfo->pvInformationBuffer = pvSetBuffer; |
| prCmdInfo->u4InformationBufferLength = u4SetBufferLen; |
| |
| /* Setup WIFI_CMD_T */ |
| prWifiCmd = (struct WIFI_CMD *) (prCmdInfo->pucInfoBuffer); |
| prWifiCmd->u2TxByteCount = prCmdInfo->u2InfoBufLen; |
| prWifiCmd->u2PQ_ID = CMD_PQ_ID; |
| prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID; |
| prWifiCmd->ucCID = prCmdInfo->ucCID; |
| prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; |
| prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; |
| |
| if (u4SetBufferLen > 0 && pvSetBuffer != NULL) |
| kalMemCopy(prWifiCmd->aucBuffer, (uint8_t *) pvSetBuffer, |
| u4SetBufferLen); |
| |
| /* insert into prCmdQueue */ |
| kalEnqueueCommand(prGlueInfo, |
| (struct QUE_ENTRY *) prCmdInfo); |
| |
| /* wakeup txServiceThread later */ |
| GLUE_SET_EVENT(prGlueInfo); |
| |
| return WLAN_STATUS_PENDING; |
| |
| } /* wlanoidSetGtkRekeyData */ |
| |
| #if CFG_SUPPORT_SCHED_SCAN |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to request starting of schedule scan |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * |
| * \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetStartSchedScan(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_SCHED_SCAN_REQUEST *prSchedScanRequest; |
| |
| DEBUGFUNC("wlanoidSetStartSchedScan()"); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| ASSERT(pu4SetInfoLen); |
| *pu4SetInfoLen = 0; |
| |
| if (u4SetBufferLen != sizeof(struct |
| PARAM_SCHED_SCAN_REQUEST)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| else if (pvSetBuffer == NULL) |
| return WLAN_STATUS_INVALID_DATA; |
| else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == |
| PARAM_MEDIA_STATE_CONNECTED |
| && prAdapter->fgEnOnlineScan == FALSE) |
| return WLAN_STATUS_FAILURE; |
| |
| if (prAdapter->fgIsRadioOff) { |
| DBGLOG(REQ, WARN, |
| "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| prSchedScanRequest = (struct PARAM_SCHED_SCAN_REQUEST *) |
| pvSetBuffer; |
| |
| if (scnFsmSchedScanRequest(prAdapter, |
| prSchedScanRequest) == TRUE) |
| return WLAN_STATUS_SUCCESS; |
| else |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to request termination of schedule scan |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_INVALID_DATA |
| * |
| * \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetStopSchedScan(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t ret; |
| |
| ASSERT(prAdapter); |
| |
| /* ask SCN module to stop scan request */ |
| if (scnFsmSchedScanStopRequest(prAdapter) == TRUE) |
| ret = WLAN_STATUS_SUCCESS; |
| else { |
| DBGLOG(REQ, WARN, "scnFsmSchedScanStopRequest failed.\n"); |
| ret = WLAN_STATUS_FAILURE; |
| } |
| return ret; |
| } |
| #endif /* CFG_SUPPORT_SCHED_SCAN */ |
| |
| #if CFG_M0VE_BA_TO_DRIVER |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to reset BA scoreboard. |
| * |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t wlanoidResetBAScoreboard(IN struct ADAPTER * |
| prAdapter, IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen) { |
| uint32_t rStatus; |
| |
| DEBUGFUNC("wlanoidResetBAScoreboard"); |
| DBGLOG(REQ, WARN, "[Puff]wlanoidResetBAScoreboard\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ |
| CMD_ID_RESET_BA_SCOREBOARD, /* ucCID */ |
| TRUE, /* fgSetQuery */ |
| FALSE, /* fgNeedResp */ |
| TRUE, /* fgIsOid */ |
| NULL, /* pfCmdDoneHandler */ |
| NULL, /* pfCmdTimeoutHandler */ |
| u4SetBufferLen, /* u4SetQueryInfoLen */ |
| (uint8_t *) pvSetBuffer, /* pucInfoBuffer */ |
| NULL, /* pvSetQueryBuffer */ |
| 0 /* u4SetQueryBufferLen */ |
| ); |
| |
| /* ASSERT(rStatus == WLAN_STATUS_PENDING); */ |
| |
| return rStatus; |
| |
| } |
| |
| #endif |
| |
| #if CFG_SUPPORT_BATCH_SCAN |
| |
| #define CMD_WLS_BATCHING "WLS_BATCHING" |
| |
| #define BATCHING_SET "SET" |
| #define BATCHING_GET "GET" |
| #define BATCHING_STOP "STOP" |
| |
| #define PARAM_SCANFREQ "SCANFREQ" |
| #define PARAM_MSCAN "MSCAN" |
| #define PARAM_BESTN "BESTN" |
| #define PARAM_CHANNEL "CHANNEL" |
| #define PARAM_RTT "RTT" |
| |
| uint32_t |
| batchSetCmd(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4WritenLen) { |
| struct CHANNEL_INFO *prRfChannelInfo; |
| struct CMD_BATCH_REQ rCmdBatchReq; |
| |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| int8_t *head, *p, *p2; |
| uint32_t tokens; |
| int32_t scanfreq, mscan, bestn, rtt; |
| char *pcTemp; |
| /* CHAR c_scanfreq[4], c_mscan[4], c_bestn[4], c_rtt[4], c_channel[100]; |
| */ |
| /* INT_32 ch_type; */ |
| uint32_t u4Value = 0; |
| int32_t i4Ret = 0; |
| |
| DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", |
| (char *)pvSetBuffer, u4SetBufferLen); |
| |
| if (!pu4WritenLen) |
| return -EINVAL; |
| *pu4WritenLen = 0; |
| |
| if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) { |
| DBGLOG(SCN, TRACE, "[BATCH] invalid len %d\n", |
| u4SetBufferLen); |
| return -EINVAL; |
| } |
| |
| head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1; |
| kalMemSet(&rCmdBatchReq, 0, sizeof(struct CMD_BATCH_REQ)); |
| |
| if (!kalStrnCmp(head, BATCHING_SET, |
| kalStrLen(BATCHING_SET))) { |
| |
| DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n"); |
| |
| head += kalStrLen(BATCHING_SET) + 1; |
| |
| /* SCANFREQ, MSCAN, BESTN */ |
| tokens = sscanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", |
| &scanfreq, &mscan, &bestn); |
| if (tokens != 3) { |
| DBGLOG(SCN, TRACE, |
| "[BATCH] Parse fail: tokens=%d, SCANFREQ=%d MSCAN=%d BESTN=%d\n", |
| tokens, scanfreq, mscan, bestn); |
| return -EINVAL; |
| } |
| /* RTT */ |
| p = kalStrStr(head, PARAM_RTT); |
| if (!p) { |
| DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", |
| head); |
| return -EINVAL; |
| } |
| tokens = sscanf(p, "RTT=%d", &rtt); |
| if (tokens != 1) { |
| DBGLOG(SCN, TRACE, |
| "[BATCH] Parse fail: tokens=%d, rtt=%d\n", |
| tokens, rtt); |
| return -EINVAL; |
| } |
| /* CHANNEL */ |
| p = kalStrStr(head, PARAM_CHANNEL); |
| if (!p) { |
| DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n"); |
| return -EINVAL; |
| } |
| head = p; |
| p = kalStrChr(head, '>'); |
| if (!p) { |
| DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n"); |
| return -EINVAL; |
| } |
| /* else { |
| * p = '.'; // remove '>' because sscanf can not parse <%s> |
| * } |
| */ |
| /* tokens = sscanf(head, "CHANNEL=<%s", c_channel); |
| * if (tokens != 1) { |
| * DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%d, |
| * CHANNEL=<%s>\n", tokens, c_channel); |
| * return -EINVAL; |
| * } |
| */ |
| rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED; |
| rCmdBatchReq.ucChannelListNum = 0; |
| prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; |
| p = head + kalStrLen(PARAM_CHANNEL) + 2; /* c_channel; */ |
| pcTemp = (char *)p; |
| while ((p2 = kalStrSep(&pcTemp, ",")) != NULL) { |
| if (p2 == NULL || *p2 == 0) |
| break; |
| if (*p2 == '\0') |
| continue; |
| if (*p2 == 'A') { |
| rCmdBatchReq.ucChannelType = |
| rCmdBatchReq.ucChannelType == |
| SCAN_CHANNEL_2G4 ? |
| SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G; |
| } else if (*p2 == 'B') { |
| rCmdBatchReq.ucChannelType = |
| rCmdBatchReq.ucChannelType == |
| SCAN_CHANNEL_5G ? |
| SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4; |
| } else { |
| |
| /* Translate Freq from MHz to channel number. */ |
| /* prRfChannelInfo->ucChannelNum = |
| * kalStrtol(p2, NULL, 0); |
| */ |
| i4Ret = kalkStrtou32(p2, 0, &u4Value); |
| if (i4Ret) |
| DBGLOG(SCN, TRACE, |
| "parse ucChannelNum error i4Ret=%d\n", |
| i4Ret); |
| prRfChannelInfo->ucChannelNum = |
| (uint8_t) u4Value; |
| DBGLOG(SCN, TRACE, |
| "Scanning Channel:%d, freq: %d\n", |
| prRfChannelInfo->ucChannelNum, |
| nicChannelNum2Freq( |
| prRfChannelInfo->ucChannelNum)); |
| prRfChannelInfo->ucBand = |
| prRfChannelInfo->ucChannelNum < 15 |
| ? BAND_2G4 : BAND_5G; |
| |
| rCmdBatchReq.ucChannelListNum++; |
| if (rCmdBatchReq.ucChannelListNum >= 32) |
| break; |
| prRfChannelInfo++; |
| } |
| } |
| |
| /* set channel for test */ |
| #if 0 |
| rCmdBatchReq.ucChannelType = |
| 4; /* SCAN_CHANNEL_SPECIFIED; */ |
| rCmdBatchReq.ucChannelListNum = 0; |
| prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; |
| for (i = 1; i <= 14; i++) { |
| |
| /* filter out some */ |
| if (i == 1 || i == 5 || i == 11) |
| continue; |
| |
| /* Translate Freq from MHz to channel number. */ |
| prRfChannelInfo->ucChannelNum = i; |
| DBGLOG(SCN, TRACE, "Scanning Channel:%d, freq: %d\n", |
| prRfChannelInfo->ucChannelNum, |
| nicChannelNum2Freq( |
| prRfChannelInfo->ucChannelNum)); |
| prRfChannelInfo->ucBand = BAND_2G4; |
| |
| rCmdBatchReq.ucChannelListNum++; |
| prRfChannelInfo++; |
| } |
| #endif |
| #if 0 |
| rCmdBatchReq.ucChannelType = 0; /* SCAN_CHANNEL_FULL; */ |
| #endif |
| |
| rCmdBatchReq.u4Scanfreq = scanfreq; |
| rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? |
| CFG_BATCH_MAX_MSCAN : mscan; |
| rCmdBatchReq.ucBestn = bestn; |
| rCmdBatchReq.ucRtt = rtt; |
| DBGLOG(SCN, TRACE, |
| "[BATCH] SCANFREQ=%d MSCAN=%d BESTN=%d RTT=%d\n", |
| rCmdBatchReq.u4Scanfreq, rCmdBatchReq.ucMScan, |
| rCmdBatchReq.ucBestn, rCmdBatchReq.ucRtt); |
| |
| if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) { |
| DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n", |
| rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? |
| "FULL" : rCmdBatchReq.ucChannelType == |
| SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all"); |
| } else { |
| DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n"); |
| prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; |
| for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; |
| tokens++) { |
| DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n", |
| prRfChannelInfo->ucBand |
| == BAND_2G4 ? "2.4G" : "5G", |
| prRfChannelInfo->ucChannelNum); |
| prRfChannelInfo++; |
| } |
| } |
| |
| rCmdBatchReq.ucSeqNum = 1; |
| rCmdBatchReq.ucNetTypeIndex = KAL_NETWORK_TYPE_AIS_INDEX; |
| rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START; |
| |
| *pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", |
| rCmdBatchReq.ucMScan); |
| |
| } else if (!kalStrnCmp(head, BATCHING_STOP, |
| kalStrLen(BATCHING_STOP))) { |
| |
| DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n"); |
| |
| rCmdBatchReq.ucSeqNum = 1; |
| rCmdBatchReq.ucNetTypeIndex = KAL_NETWORK_TYPE_AIS_INDEX; |
| rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP; |
| } else { |
| return -EINVAL; |
| } |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_BATCH_REQ, |
| TRUE, FALSE, g_fgIsOid, NULL, NULL, |
| sizeof(struct CMD_BATCH_REQ), |
| (uint8_t *) &rCmdBatchReq, NULL, 0); |
| |
| /* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */ |
| /* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */ |
| |
| /* exit: */ |
| return rStatus; |
| } |
| |
| uint32_t |
| batchGetCmd(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct CMD_BATCH_REQ rCmdBatchReq; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| struct EVENT_BATCH_RESULT *prEventBatchResult; |
| /* UINT_32 i; */ |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| prEventBatchResult = (struct EVENT_BATCH_RESULT *) |
| pvQueryBuffer; |
| |
| DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%d) XXX\n", |
| prEventBatchResult->ucScanCount); |
| |
| *pu4QueryInfoLen = sizeof(struct EVENT_BATCH_RESULT); |
| |
| rCmdBatchReq.ucSeqNum = 2; |
| rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT; |
| rCmdBatchReq.ucMScan = |
| prEventBatchResult->ucScanCount; /* Get which round result */ |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_BATCH_REQ, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventBatchScanResult, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_BATCH_REQ), |
| (uint8_t *) &rCmdBatchReq, |
| (void *) pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| return rStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * \param[in] u4SetBufferLen The length of the set buffer |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid length of |
| * the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetBatchScanReq(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, |
| pu4SetInfoLen); |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuffer A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryBatchScanResult(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| return batchGetCmd(prAdapter, pvQueryBuffer, |
| u4QueryBufferLen, pu4QueryInfoLen); |
| |
| } /* end of wlanoidQueryBatchScanResult() */ |
| |
| #endif /* CFG_SUPPORT_BATCH_SCAN */ |
| |
| #if CFG_SUPPORT_PASSPOINT |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called by HS2.0 to set the assoc info, which is needed |
| * to add to Association request frame while join HS2.0 AP. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * \param[in] u4SetBufferLen The length of the set buffer |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid length of |
| * the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetHS20Info(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct IE_HS20_INDICATION *prHS20IndicationIe; |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| DEBUGFUNC("wlanoidSetHS20AssocInfo"); |
| DBGLOG(OID, LOUD, "\r\n"); |
| |
| if (u4SetBufferLen == 0) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| *pu4SetInfoLen = u4SetBufferLen; |
| |
| prHS20IndicationIe = (struct IE_HS20_INDICATION *) |
| pvSetBuffer; |
| |
| prAdapter->prGlueInfo->ucHotspotConfig = |
| prHS20IndicationIe->ucHotspotConfig; |
| prAdapter->prGlueInfo->fgConnectHS20AP = TRUE; |
| |
| DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen); |
| |
| kalMemCopy(prAdapter->prGlueInfo->aucHS20AssocInfoIE, |
| pvSetBuffer, u4SetBufferLen); |
| prAdapter->prGlueInfo->u2HS20AssocInfoIELen = |
| (uint16_t) u4SetBufferLen; |
| DBGLOG(SEC, TRACE, "HS20 Assoc Info IE sz %u\n", |
| u4SetBufferLen); |
| |
| return WLAN_STATUS_SUCCESS; |
| |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called by WSC to set the assoc info, which is needed |
| * to add to Association request frame while join WPS AP. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * \param[in] u4SetBufferLen The length of the set buffer |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid length of |
| * the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetInterworkingInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called by WSC to set the Roaming Consortium IE info, |
| * which is needed to add to Association request frame while join WPS AP. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set |
| * \param[in] u4SetBufferLen The length of the set buffer |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed due to invalid length of |
| * the set buffer, returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetRoamingConsortiumIEInfo(IN struct ADAPTER * |
| prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set_bssid_pool |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| * \retval WLAN_STATUS_MULTICAST_FULL |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetHS20BssidPool(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_HS20_SET_BSSID_POOL)) { |
| *pu4SetInfoLen = sizeof(struct PARAM_HS20_SET_BSSID_POOL); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, |
| KAL_NETWORK_TYPE_AIS_INDEX); |
| |
| return rWlanStatus; |
| } /* end of wlanoidSendHS20GASRequest() */ |
| |
| #endif /* CFG_SUPPORT_PASSPOINT */ |
| |
| #if CFG_SUPPORT_SNIFFER |
| uint32_t |
| wlanoidSetMonitor(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_MONITOR_SET_STRUCT *prMonitorSetInfo; |
| struct CMD_MONITOR_SET_INFO rCmdMonitorSetInfo; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidSetMonitor"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_MONITOR_SET_STRUCT); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_MONITOR_SET_STRUCT)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prMonitorSetInfo = (struct PARAM_CUSTOM_MONITOR_SET_STRUCT |
| *) pvSetBuffer; |
| |
| rCmdMonitorSetInfo.ucEnable = prMonitorSetInfo->ucEnable; |
| rCmdMonitorSetInfo.ucBand = prMonitorSetInfo->ucBand; |
| rCmdMonitorSetInfo.ucPriChannel = |
| prMonitorSetInfo->ucPriChannel; |
| rCmdMonitorSetInfo.ucSco = prMonitorSetInfo->ucSco; |
| rCmdMonitorSetInfo.ucChannelWidth = |
| prMonitorSetInfo->ucChannelWidth; |
| rCmdMonitorSetInfo.ucChannelS1 = |
| prMonitorSetInfo->ucChannelS1; |
| rCmdMonitorSetInfo.ucChannelS2 = |
| prMonitorSetInfo->ucChannelS2; |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_MONITOR, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_MONITOR_SET_INFO), |
| (uint8_t *) &rCmdMonitorSetInfo, |
| pvSetBuffer, |
| u4SetBufferLen); |
| #if CFG_SUPPORT_TX_BEACON_STA_MODE |
| if (rCmdMonitorSetInfo.ucEnable != 0) |
| nicActivateNetwork(prAdapter, 0); |
| else |
| nicDeactivateNetwork(prAdapter, 0); |
| #endif |
| return rWlanStatus; |
| } |
| #endif |
| |
| |
| #if CFG_SUPPORT_ADVANCE_CONTROL |
| uint32_t |
| wlanoidAdvCtrl(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| return wlanAdvCtrl(prAdapter, |
| pvQueryBuffer, |
| u4QueryBufferLen, |
| pu4QueryInfoLen, |
| g_fgIsOid); |
| } |
| |
| uint32_t |
| wlanAdvCtrl(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen, |
| IN uint8_t fgIsOid) |
| { |
| struct CMD_ADV_CONFIG_HEADER *cmd; |
| uint16_t type = 0; |
| uint32_t len; |
| u_int8_t fgSetQuery = FALSE; |
| u_int8_t fgNeedResp = TRUE; |
| |
| DEBUGFUNC("wlanoidAdvCtrl"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(*cmd)) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| cmd = (struct CMD_ADV_CONFIG_HEADER *)pvQueryBuffer; |
| |
| if (cmd->u2Type & CMD_ADV_CONTROL_SET) { |
| fgSetQuery = TRUE; |
| fgNeedResp = FALSE; |
| } |
| |
| type = cmd->u2Type; |
| type &= ~CMD_ADV_CONTROL_SET; |
| DBGLOG(RSN, INFO, "%s cmd type %d\n", __func__, cmd->u2Type); |
| switch (type) { |
| case CMD_PTA_CONFIG_TYPE: |
| *pu4QueryInfoLen = sizeof(struct CMD_PTA_CONFIG); |
| len = sizeof(struct CMD_PTA_CONFIG); |
| break; |
| #if CFG_SUPPORT_EXT_PTA_DEBUG_COMMAND |
| case CMD_EXT_PTA_CONFIG_TYPE: |
| *pu4QueryInfoLen = sizeof(struct CMD_EXT_PTA_CONFIG); |
| len = sizeof(struct CMD_EXT_PTA_CONFIG); |
| break; |
| #endif |
| case CMD_GET_REPORT_TYPE: |
| *pu4QueryInfoLen = sizeof(struct CMD_GET_TRAFFIC_REPORT); |
| len = sizeof(struct CMD_GET_TRAFFIC_REPORT); |
| break; |
| case CMD_NOISE_HISTOGRAM_TYPE: |
| #if CFG_IPI_2CHAIN_SUPPORT |
| case CMD_NOISE_HISTOGRAM_TYPE2: |
| #endif |
| *pu4QueryInfoLen = sizeof(struct CMD_NOISE_HISTOGRAM_REPORT); |
| len = sizeof(struct CMD_NOISE_HISTOGRAM_REPORT); |
| break; |
| #ifdef CFG_SUPPORT_ADMINCTRL |
| case CMD_ADMINCTRL_CONFIG_TYPE: |
| *pu4QueryInfoLen = sizeof(struct CMD_ADMIN_CTRL_CONFIG); |
| len = sizeof(struct CMD_ADMIN_CTRL_CONFIG); |
| break; |
| #endif |
| default: |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ADV_CONTROL, |
| fgSetQuery, |
| fgNeedResp, |
| fgIsOid, |
| nicCmdEventQueryAdvCtrl, |
| nicOidCmdTimeoutCommon, |
| len, (uint8_t *)cmd, |
| pvQueryBuffer, u4QueryBufferLen); |
| } |
| #endif |
| |
| |
| #if CFG_SUPPORT_MSP |
| uint32_t |
| wlanoidQueryWlanInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| |
| return wlanQueryWlanInfo(prAdapter, |
| pvQueryBuffer, |
| u4QueryBufferLen, |
| pu4QueryInfoLen, |
| g_fgIsOid); |
| } |
| |
| uint32_t |
| wlanQueryWlanInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen, |
| IN uint8_t fgIsOid) { |
| struct PARAM_HW_WLAN_INFO *prHwWlanInfo; |
| |
| DEBUGFUNC("wlanoidQueryWlanInfo"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_HW_WLAN_INFO); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(struct PARAM_HW_WLAN_INFO)) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prHwWlanInfo = (struct PARAM_HW_WLAN_INFO *)pvQueryBuffer; |
| DBGLOG(RSN, INFO, |
| "MT6632 : wlanoidQueryWlanInfo index = %d\n", |
| prHwWlanInfo->u4Index); |
| |
| /* *pu4QueryInfoLen = 8 + prRxStatistics->u4TotalNum; */ |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_WLAN_INFO, |
| FALSE, |
| TRUE, |
| fgIsOid, |
| nicCmdEventQueryWlanInfo, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_HW_WLAN_INFO), |
| (uint8_t *)prHwWlanInfo, |
| pvQueryBuffer, u4QueryBufferLen); |
| |
| } /* wlanoidQueryWlanInfo */ |
| |
| |
| uint32_t |
| wlanoidQueryMibInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_HW_MIB_INFO *prHwMibInfo; |
| |
| DEBUGFUNC("wlanoidQueryMibInfo"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_HW_MIB_INFO); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(struct |
| PARAM_HW_MIB_INFO)) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prHwMibInfo = (struct PARAM_HW_MIB_INFO *)pvQueryBuffer; |
| DBGLOG(RSN, INFO, |
| "MT6632 : wlanoidQueryMibInfo index = %d\n", |
| prHwMibInfo->u4Index); |
| |
| /* *pu4QueryInfoLen = 8 + prRxStatistics->u4TotalNum; */ |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_MIB_INFO, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryMibInfo, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_HW_MIB_INFO), |
| (uint8_t *)prHwMibInfo, |
| pvQueryBuffer, u4QueryBufferLen); |
| |
| } /* wlanoidQueryMibInfo */ |
| #endif |
| |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set FW log to Host. |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer Pointer to the buffer that holds the data to be |
| * set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| * \retval WLAN_STATUS_NOT_SUPPORTED |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidSetFwLog2Host( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_FW_LOG_2_HOST_CTRL *prFwLog2HostCtrl; |
| |
| DEBUGFUNC("wlanoidSetFwLog2Host"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct CMD_FW_LOG_2_HOST_CTRL); |
| |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set FW log to Host! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4SetBufferLen < sizeof(struct |
| CMD_FW_LOG_2_HOST_CTRL)) { |
| DBGLOG(REQ, WARN, "Too short length %d\n", u4SetBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prFwLog2HostCtrl = (struct CMD_FW_LOG_2_HOST_CTRL *) |
| pvSetBuffer; |
| #if CFG_SUPPORT_FW_DBG_LEVEL_CTRL |
| DBGLOG(REQ, INFO, "McuDest %d, LogType %d, (FwLogLevel %d)\n", |
| prFwLog2HostCtrl->ucMcuDest, |
| prFwLog2HostCtrl->ucFwLog2HostCtrl, |
| prFwLog2HostCtrl->ucFwLogLevel); |
| #else |
| DBGLOG(REQ, INFO, "McuDest %d, LogType %d\n", |
| prFwLog2HostCtrl->ucMcuDest, |
| prFwLog2HostCtrl->ucFwLog2HostCtrl); |
| #endif |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_FW_LOG_2_HOST, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_FW_LOG_2_HOST_CTRL), |
| (uint8_t *)prFwLog2HostCtrl, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| |
| uint32_t |
| wlanoidNotifyFwSuspend( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_SUSPEND_MODE_SETTING *prSuspendCmd; |
| |
| if (!prAdapter || !pvSetBuffer) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prSuspendCmd = (struct CMD_SUSPEND_MODE_SETTING *) |
| pvSetBuffer; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_SUSPEND_MODE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_SUSPEND_MODE_SETTING), |
| (uint8_t *)prSuspendCmd, |
| NULL, |
| 0); |
| } |
| |
| uint32_t |
| wlanoidQueryCnm( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_GET_CNM_T *prCnmInfo = NULL; |
| |
| DEBUGFUNC("wlanoidQueryLinkSpeed"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (prAdapter->fgIsEnableLpdvt) |
| return WLAN_STATUS_NOT_SUPPORTED; |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_GET_CNM_T); |
| |
| if (u4QueryBufferLen < sizeof(struct PARAM_GET_CNM_T)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| prCnmInfo = (struct PARAM_GET_CNM_T *)pvQueryBuffer; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_CNM, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCnmInfo, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_GET_CNM_T), |
| (uint8_t *)prCnmInfo, |
| pvQueryBuffer, u4QueryBufferLen); |
| } |
| |
| uint32_t |
| wlanoidPacketKeepAlive(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| struct PARAM_PACKET_KEEPALIVE_T *prPacket; |
| |
| DEBUGFUNC("wlanoidPacketKeepAlive"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_PACKET_KEEPALIVE_T); |
| |
| /* Check for query buffer length */ |
| if (u4SetBufferLen < *pu4SetInfoLen) { |
| DBGLOG(OID, WARN, "Too short length %u\n", u4SetBufferLen); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| prPacket = (struct PARAM_PACKET_KEEPALIVE_T *) |
| kalMemAlloc(sizeof(struct PARAM_PACKET_KEEPALIVE_T), |
| VIR_MEM_TYPE); |
| if (!prPacket) { |
| DBGLOG(OID, ERROR, |
| "Can not alloc memory for struct PARAM_PACKET_KEEPALIVE_T\n"); |
| return -ENOMEM; |
| } |
| kalMemCopy(prPacket, pvSetBuffer, |
| sizeof(struct PARAM_PACKET_KEEPALIVE_T)); |
| |
| DBGLOG(OID, INFO, "fgEnable=%d, index=%d\r\n", |
| prPacket->fgEnable, prPacket->index); |
| |
| rStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_WFC_KEEP_ALIVE, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_PACKET_KEEPALIVE_T), |
| (uint8_t *)prPacket, NULL, 0); |
| kalMemFree(prPacket, VIR_MEM_TYPE, |
| sizeof(struct PARAM_PACKET_KEEPALIVE_T)); |
| return rStatus; |
| } |
| |
| #if CFG_SUPPORT_DBDC |
| uint32_t |
| wlanoidSetDbdcEnable( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint8_t ucDBDCEnable; |
| |
| if (!prAdapter || !pvSetBuffer) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| kalMemCopy(&ucDBDCEnable, pvSetBuffer, 1); |
| cnmUpdateDbdcSetting(prAdapter, ucDBDCEnable); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif /*#if CFG_SUPPORT_DBDC*/ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set tx target power base. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQuerySetTxTargetPower(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_SET_TX_TARGET_POWER |
| *prSetTxTargetPowerInfo; |
| struct CMD_SET_TX_TARGET_POWER rCmdSetTxTargetPower; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQuerySetTxTargetPower"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct |
| PARAM_CUSTOM_SET_TX_TARGET_POWER *); |
| |
| if (u4SetBufferLen < sizeof(struct |
| PARAM_CUSTOM_SET_TX_TARGET_POWER *)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| ASSERT(pvSetBuffer); |
| |
| prSetTxTargetPowerInfo = |
| (struct PARAM_CUSTOM_SET_TX_TARGET_POWER *) pvSetBuffer; |
| |
| kalMemSet(&rCmdSetTxTargetPower, 0, |
| sizeof(struct CMD_SET_TX_TARGET_POWER)); |
| |
| rCmdSetTxTargetPower.ucTxTargetPwr = |
| prSetTxTargetPowerInfo->ucTxTargetPwr; |
| |
| DBGLOG(INIT, INFO, |
| "MT6632 : wlanoidQuerySetTxTargetPower =%x dbm\n", |
| rCmdSetTxTargetPower.ucTxTargetPwr); |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_TX_PWR, |
| TRUE, /* fgSetQuery Bit: True->write False->read */ |
| FALSE, /* fgNeedResp */ |
| g_fgIsOid, /* fgIsOid*/ |
| nicCmdEventSetCommon, /* REF: wlanoidSetDbdcEnable */ |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ACCESS_EFUSE), |
| (uint8_t *) (&rCmdSetTxTargetPower), pvSetBuffer, |
| u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| |
| #if (CFG_SUPPORT_DFS_MASTER == 1) |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set rdd report. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQuerySetRddReport(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_SET_RDD_REPORT *prSetRddReport; |
| struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQuerySetRddReport"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct PARAM_CUSTOM_SET_RDD_REPORT |
| *); |
| |
| ASSERT(pvSetBuffer); |
| |
| prSetRddReport = (struct PARAM_CUSTOM_SET_RDD_REPORT *) |
| pvSetBuffer; |
| |
| prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *) |
| cnmMemAlloc(prAdapter, RAM_TYPE_MSG, |
| sizeof(*prCmdRddOnOffCtrl)); |
| |
| ASSERT(prCmdRddOnOffCtrl); |
| if (prCmdRddOnOffCtrl == NULL) { |
| DBGLOG(INIT, ERROR, "prCmdRddOnOffCtrl is NULL"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prCmdRddOnOffCtrl->ucDfsCtrl = RDD_RADAR_EMULATE; |
| |
| prCmdRddOnOffCtrl->ucRddIdx = prSetRddReport->ucDbdcIdx; |
| |
| if (prCmdRddOnOffCtrl->ucRddIdx) |
| prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_1; |
| else |
| prCmdRddOnOffCtrl->ucRddRxSel = RDD_IN_SEL_0; |
| |
| DBGLOG(INIT, INFO, |
| "MT6632 : wlanoidQuerySetRddReport - DFS ctrl: %.d, RDD index: %d\n", |
| prCmdRddOnOffCtrl->ucDfsCtrl, prCmdRddOnOffCtrl->ucRddIdx); |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_RDD_ON_OFF_CTRL, |
| TRUE, /* fgSetQuery Bit: True->write False->read */ |
| FALSE, /* fgNeedResp */ |
| g_fgIsOid, /* fgIsOid*/ |
| nicCmdEventSetCommon, /* REF: wlanoidSetDbdcEnable */ |
| nicOidCmdTimeoutCommon, |
| sizeof(*prCmdRddOnOffCtrl), |
| (uint8_t *) (prCmdRddOnOffCtrl), pvSetBuffer, |
| u4SetBufferLen); |
| |
| cnmMemFree(prAdapter, prCmdRddOnOffCtrl); |
| |
| return rWlanStatus; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set rdd report. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQuerySetRadarDetectMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE |
| *prSetRadarDetectMode; |
| struct CMD_RDD_ON_OFF_CTRL *prCmdRddOnOffCtrl; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| DEBUGFUNC("wlanoidQuerySetRadarDetectMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = |
| sizeof(struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE *); |
| |
| ASSERT(pvSetBuffer); |
| |
| prSetRadarDetectMode = |
| (struct PARAM_CUSTOM_SET_RADAR_DETECT_MODE *) pvSetBuffer; |
| |
| prCmdRddOnOffCtrl = (struct CMD_RDD_ON_OFF_CTRL *)cnmMemAlloc( |
| prAdapter, RAM_TYPE_MSG, |
| sizeof(*prCmdRddOnOffCtrl)); |
| |
| ASSERT(prCmdRddOnOffCtrl); |
| if (prCmdRddOnOffCtrl == NULL) { |
| DBGLOG(INIT, ERROR, "prCmdRddOnOffCtrl is NULL"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prCmdRddOnOffCtrl->ucDfsCtrl = RDD_DET_MODE; |
| |
| prCmdRddOnOffCtrl->ucSetVal = |
| prSetRadarDetectMode->ucRadarDetectMode; |
| |
| DBGLOG(INIT, INFO, |
| "MT6632 : wlanoidQuerySetRadarDetectMode - DFS ctrl: %.d, Radar Detect Mode: %d\n", |
| prCmdRddOnOffCtrl->ucDfsCtrl, prCmdRddOnOffCtrl->ucSetVal); |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_RDD_ON_OFF_CTRL, |
| TRUE, /* fgSetQuery Bit: True->write False->read */ |
| FALSE, /* fgNeedResp */ |
| g_fgIsOid, /* fgIsOid*/ |
| nicCmdEventSetCommon, /* REF: wlanoidSetDbdcEnable */ |
| nicOidCmdTimeoutCommon, |
| sizeof(*prCmdRddOnOffCtrl), |
| (uint8_t *) (prCmdRddOnOffCtrl), |
| pvSetBuffer, |
| u4SetBufferLen); |
| |
| cnmMemFree(prAdapter, prCmdRddOnOffCtrl); |
| |
| return rWlanStatus; |
| } |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is used to turn radio off. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. |
| * \param[in] u4SetBufferLen The length of the set buffer. |
| * \param[out] pu4SetInfoLen If the call is successful, returns the number of |
| * bytes read from the set buffer. If the call failed |
| * due to invalid length of the set buffer, returns |
| * the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_ADAPTER_NOT_READY |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidLinkDown(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| DEBUGFUNC("wlanoidSetDisassociate"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = 0; |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in set link down! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } |
| |
| aisBssLinkDown(prAdapter); |
| |
| prAdapter->prGlueInfo->u4LinkDownPendFlag = TRUE; |
| |
| return WLAN_STATUS_PENDING; |
| } /* wlanoidSetDisassociate */ |
| |
| uint32_t |
| wlanoidGetTxPwrTbl(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| struct CMD_GET_TXPWR_TBL CmdPwrTbl; |
| struct PARAM_CMD_GET_TXPWR_TBL *prPwrTbl = NULL; |
| |
| DEBUGFUNC("wlanoidGetTxPwrTbl"); |
| DBGLOG(REQ, LOUD, "\n"); |
| |
| if (!prAdapter || (!pvQueryBuffer && u4QueryBufferLen) || |
| !pu4QueryInfoLen) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_CMD_GET_TXPWR_TBL); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(struct PARAM_CMD_GET_TXPWR_TBL)) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prPwrTbl = (struct PARAM_CMD_GET_TXPWR_TBL *)pvQueryBuffer; |
| |
| CmdPwrTbl.ucCmdVer = 0x01; |
| CmdPwrTbl.u2CmdLen = sizeof(struct CMD_GET_TXPWR_TBL); |
| CmdPwrTbl.ucDbdcIdx = prPwrTbl->ucDbdcIdx; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_GET_TXPWR_TBL, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventGetTxPwrTbl, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_GET_TXPWR_TBL), |
| (uint8_t *)&CmdPwrTbl, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } |
| |
| #if CFG_SUPPORT_NCHO |
| #define FW_CFG_KEY_NCHO_ENABLE "NCHOEnable" |
| #define FW_CFG_KEY_NCHO_ROAM_RCPI "RoamingRCPIValue" |
| #define FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME "NCHOScnChannelTime" |
| #define FW_CFG_KEY_NCHO_SCN_HOME_TIME "NCHOScnHomeTime" |
| #define FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME "NCHOScnHomeAwayTime" |
| #define FW_CFG_KEY_NCHO_SCN_NPROBES "NCHOScnNumProbs" |
| #define FW_CFG_KEY_NCHO_WES_MODE "NCHOWesMode" |
| #define FW_CFG_KEY_NCHO_SCAN_DFS_MODE "NCHOScnDfsMode" |
| |
| uint32_t |
| wlanoidSetNchoHeader(struct CMD_HEADER *prCmdHeader, |
| struct CMD_FORMAT_V1 *pr_cmd_v1, |
| char *pStr, uint32_t u4Len) { |
| prCmdHeader->cmdVersion = CMD_VER_1_EXT; |
| prCmdHeader->cmdType = CMD_TYPE_QUERY; |
| prCmdHeader->itemNum = 1; |
| prCmdHeader->cmdBufferLen = sizeof(struct CMD_FORMAT_V1); |
| kalMemSet(prCmdHeader->buffer, 0, MAX_CMD_BUFFER_LENGTH); |
| |
| if (!prCmdHeader || !pStr || u4Len == 0) |
| return WLAN_STATUS_FAILURE; |
| |
| pr_cmd_v1->itemStringLength = u4Len; |
| kalMemCopy(pr_cmd_v1->itemString, pStr, u4Len); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetNchoRoamTrigger(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| int32_t *pi4Param = NULL; |
| char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoRoamTrigger"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(int32_t); |
| |
| if (u4SetBufferLen < sizeof(int32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pi4Param = (int32_t *) pvSetBuffer; |
| *pi4Param = dBm_TO_RCPI(*pi4Param); /* DB to RCPI */ |
| if (*pi4Param < RCPI_LOW_BOUND |
| || *pi4Param > RCPI_HIGH_BOUND) { |
| DBGLOG(INIT, ERROR, "NCHO roam trigger invalid %d\n", |
| *pi4Param); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_ROAM_RCPI, |
| *pi4Param); |
| rStatus = wlanFwCfgParse(prAdapter, acCmd); |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| prAdapter->rNchoInfo.i4RoamTrigger = RCPI_TO_dBm(*pi4Param); |
| DBGLOG(INIT, TRACE, "NCHO roam trigger is %d\n", |
| prAdapter->rNchoInfo.i4RoamTrigger); |
| } |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoRoamTrigger(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct CMD_HEADER cmdV1Header; |
| struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) |
| pvQueryBuffer; |
| struct CMD_FORMAT_V1 *prCmdV1 = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoRoamTrigger"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_HEADER); |
| |
| if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; |
| rStatus = wlanoidSetNchoHeader(prCmdV1Header, |
| prCmdV1, |
| FW_CFG_KEY_NCHO_ROAM_RCPI, |
| kalStrLen(FW_CFG_KEY_NCHO_ROAM_RCPI)); |
| if (rStatus != WLAN_STATUS_SUCCESS) { |
| DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); |
| return rStatus; |
| } |
| kalMemCopy(&cmdV1Header, prCmdV1Header, |
| sizeof(struct CMD_HEADER)); |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, |
| CMD_ID_GET_SET_CUSTOMER_CFG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCfgRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_HEADER), |
| (uint8_t *)&cmdV1Header, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSetNchoRoamDelta(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| int32_t *pi4Param = NULL; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoRoamDelta"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(int32_t); |
| |
| if (u4SetBufferLen < sizeof(int32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pi4Param = (int32_t *) pvSetBuffer; |
| if (*pi4Param > 100) { |
| DBGLOG(INIT, ERROR, "NCHO roam delta invalid %d\n", |
| *pi4Param); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| prAdapter->rNchoInfo.i4RoamDelta = *pi4Param; |
| DBGLOG(INIT, TRACE, "NCHO roam delta is %d\n", *pi4Param); |
| rStatus = WLAN_STATUS_SUCCESS; |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoRoamDelta(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| int32_t *pParam = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoRoamDelta"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(int32_t *)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| pParam = (int32_t *) pvQueryBuffer; |
| *pParam = prAdapter->rNchoInfo.i4RoamDelta; |
| DBGLOG(INIT, TRACE, "NCHO roam delta is %d\n", *pParam); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetNchoRoamScnPeriod(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoRoamScnPeriod"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| |
| prAdapter->rNchoInfo.u4RoamScanPeriod = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO roam scan period is %d\n", |
| *pParam); |
| rStatus = WLAN_STATUS_SUCCESS; |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoRoamScnPeriod(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t *pParam = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoRoamScnPeriod"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| pParam = (uint32_t *) pvQueryBuffer; |
| *pParam = prAdapter->rNchoInfo.u4RoamScanPeriod; |
| DBGLOG(INIT, TRACE, "NCHO roam scan period is %d\n", |
| *pParam); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetNchoRoamScnChnl(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct _CFG_NCHO_SCAN_CHNL_T *prRoamScnChnl = NULL; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoRoamScnChnl"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(struct _CFG_NCHO_SCAN_CHNL_T); |
| |
| if (u4SetBufferLen < sizeof(struct _CFG_NCHO_SCAN_CHNL_T)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prRoamScnChnl = (struct _CFG_NCHO_SCAN_CHNL_T *) |
| pvSetBuffer; |
| |
| kalMemCopy(&prAdapter->rNchoInfo.rRoamScnChnl, |
| prRoamScnChnl, *pu4SetInfoLen); |
| prAdapter->rNchoInfo.u4RoamScanControl = TRUE; |
| DBGLOG(INIT, TRACE, |
| "NCHO set roam scan channel num is %d\n", |
| prRoamScnChnl->ucChannelListNum); |
| rStatus = WLAN_STATUS_SUCCESS; |
| |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoRoamScnChnl(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct _CFG_NCHO_SCAN_CHNL_T *prRoamScnChnl = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoRoamScnChnl"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(struct _CFG_NCHO_SCAN_CHNL_T)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prRoamScnChnl = (struct _CFG_NCHO_SCAN_CHNL_T *) |
| pvQueryBuffer; |
| kalMemCopy(prRoamScnChnl, |
| &prAdapter->rNchoInfo.rRoamScnChnl, u4QueryBufferLen); |
| DBGLOG(INIT, TRACE, "NCHO roam scan channel num is %d\n", |
| prRoamScnChnl->ucChannelListNum); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetNchoRoamScnCtrl(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoRoamScnChnl"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam != TRUE && *pParam != FALSE) { |
| DBGLOG(INIT, ERROR, "NCHO roam scan control invalid %d\n", |
| *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| prAdapter->rNchoInfo.u4RoamScanControl = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO roam scan control is %d\n", |
| *pParam); |
| rStatus = WLAN_STATUS_SUCCESS; |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoRoamScnCtrl(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t *pParam = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoRoamScnCtrl"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| pParam = (uint32_t *) pvQueryBuffer; |
| *pParam = prAdapter->rNchoInfo.u4RoamScanControl; |
| DBGLOG(INIT, TRACE, "NCHO roam scan control is %d\n", |
| *pParam); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetNchoScnChnlTime(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoScnChnlTime"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam < 10 && *pParam > 1000) { |
| DBGLOG(INIT, ERROR, "NCHO scan channel time invalid %d\n", |
| *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME, |
| *pParam); |
| rStatus = wlanFwCfgParse(prAdapter, acCmd); |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| prAdapter->rNchoInfo.u4ScanChannelTime = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO scan channel time is %d\n", |
| *pParam); |
| } |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoScnChnlTime(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct CMD_HEADER cmdV1Header; |
| struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) |
| pvQueryBuffer; |
| struct CMD_FORMAT_V1 *prCmdV1 = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoScnChnlTime"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_HEADER); |
| |
| if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; |
| rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, |
| FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME, |
| kalStrLen(FW_CFG_KEY_NCHO_SCN_CHANNEL_TIME)); |
| if (rStatus != WLAN_STATUS_SUCCESS) { |
| DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); |
| return rStatus; |
| } |
| kalMemCopy(&cmdV1Header, prCmdV1Header, |
| sizeof(struct CMD_HEADER)); |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, |
| CMD_ID_GET_SET_CUSTOMER_CFG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCfgRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_HEADER), |
| (uint8_t *)&cmdV1Header, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSetNchoScnHomeTime(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoScnHomeTime"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam < 10 && *pParam > 1000) { |
| DBGLOG(INIT, ERROR, "NCHO scan home time invalid %d\n", |
| *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCN_HOME_TIME, |
| *pParam); |
| DBGLOG(REQ, TRACE, "NCHO cmd is %s\n", acCmd); |
| rStatus = wlanFwCfgParse(prAdapter, acCmd); |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| prAdapter->rNchoInfo.u4ScanHomeTime = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO scan home time is %d\n", *pParam); |
| } |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoScnHomeTime(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct CMD_HEADER cmdV1Header; |
| struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) |
| pvQueryBuffer; |
| struct CMD_FORMAT_V1 *prCmdV1 = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoScnHomeTime"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_HEADER); |
| |
| if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; |
| rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, |
| FW_CFG_KEY_NCHO_SCN_HOME_TIME, |
| kalStrLen(FW_CFG_KEY_NCHO_SCN_HOME_TIME)); |
| if (rStatus != WLAN_STATUS_SUCCESS) { |
| DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); |
| return rStatus; |
| } |
| kalMemCopy(&cmdV1Header, prCmdV1Header, |
| sizeof(struct CMD_HEADER)); |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, |
| CMD_ID_GET_SET_CUSTOMER_CFG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCfgRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_HEADER), |
| (uint8_t *)&cmdV1Header, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSetNchoScnHomeAwayTime(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoScnHomeAwayTime"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam < 10 && *pParam > 1000) { |
| DBGLOG(INIT, ERROR, "NCHO scan home away time invalid %d\n", |
| *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| |
| kalSprintf(acCmd, "%s %d", |
| FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME, *pParam); |
| DBGLOG(REQ, TRACE, "NCHO cmd is %s\n", acCmd); |
| rStatus = wlanFwCfgParse(prAdapter, acCmd); |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| prAdapter->rNchoInfo.u4ScanHomeawayTime = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO scan home away is %d\n", *pParam); |
| } |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoScnHomeAwayTime(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct CMD_HEADER cmdV1Header; |
| struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) |
| pvQueryBuffer; |
| struct CMD_FORMAT_V1 *prCmdV1 = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoScnHomeTime"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_HEADER); |
| |
| if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; |
| rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, |
| FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME, |
| kalStrLen(FW_CFG_KEY_NCHO_SCN_HOME_AWAY_TIME)); |
| if (rStatus != WLAN_STATUS_SUCCESS) { |
| DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); |
| return rStatus; |
| } |
| kalMemCopy(&cmdV1Header, prCmdV1Header, |
| sizeof(struct CMD_HEADER)); |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, |
| CMD_ID_GET_SET_CUSTOMER_CFG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCfgRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_HEADER), |
| (uint8_t *)&cmdV1Header, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSetNchoScnNprobes(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoScnNprobes"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam > 16) { |
| DBGLOG(INIT, ERROR, "NCHO scan Nprobes invalid %d\n", |
| *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| |
| kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCN_NPROBES, |
| *pParam); |
| rStatus = wlanFwCfgParse(prAdapter, acCmd); |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| prAdapter->rNchoInfo.u4ScanNProbes = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO Nprobes is %d\n", *pParam); |
| } |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoScnNprobes(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct CMD_HEADER cmdV1Header; |
| struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) |
| pvQueryBuffer; |
| struct CMD_FORMAT_V1 *prCmdV1 = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoScnNprobes"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_HEADER); |
| |
| if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; |
| rStatus = wlanoidSetNchoHeader(prCmdV1Header, |
| prCmdV1, |
| FW_CFG_KEY_NCHO_SCN_NPROBES, |
| kalStrLen(FW_CFG_KEY_NCHO_SCN_NPROBES)); |
| if (rStatus != WLAN_STATUS_SUCCESS) { |
| DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); |
| return rStatus; |
| } |
| kalMemCopy(&cmdV1Header, prCmdV1Header, |
| sizeof(struct CMD_HEADER)); |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, |
| CMD_ID_GET_SET_CUSTOMER_CFG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCfgRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_HEADER), |
| (uint8_t *)&cmdV1Header, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidGetNchoReassocInfo(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct BSS_DESC *prBssDesc = NULL; |
| struct PARAM_CONNECT *prParamConn; |
| |
| DEBUGFUNC("wlanoidGetNchoReassocInfo"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| ASSERT(pvQueryBuffer); |
| |
| prParamConn = (struct PARAM_CONNECT *)pvQueryBuffer; |
| if (prAdapter->rNchoInfo.fgECHOEnabled == TRUE) { |
| prBssDesc = scanSearchBssDescByBssid(prAdapter, |
| prParamConn->pucBssid); |
| if (prBssDesc != NULL) { |
| prParamConn->u4SsidLen = prBssDesc->ucSSIDLen; |
| COPY_SSID(prParamConn->pucSsid, |
| prParamConn->u4SsidLen, |
| prBssDesc->aucSSID, |
| prBssDesc->ucSSIDLen); |
| rStatus = WLAN_STATUS_SUCCESS; |
| } |
| } |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSendNchoActionFrameStart(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct _NCHO_INFO_T *prNchoInfo = NULL; |
| struct _NCHO_ACTION_FRAME_PARAMS_T *prParamActionFrame = |
| NULL; |
| |
| DEBUGFUNC("wlanoidSendNchoActionFrameStart"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| |
| prNchoInfo = &prAdapter->rNchoInfo; |
| prParamActionFrame = (struct _NCHO_ACTION_FRAME_PARAMS_T *) |
| pvSetBuffer; |
| prNchoInfo->fgIsSendingAF = TRUE; |
| prNchoInfo->fgChGranted = FALSE; |
| COPY_MAC_ADDR(prNchoInfo->rParamActionFrame.aucBssid, |
| prParamActionFrame->aucBssid); |
| prNchoInfo->rParamActionFrame.i4channel = |
| prParamActionFrame->i4channel; |
| prNchoInfo->rParamActionFrame.i4DwellTime = |
| prParamActionFrame->i4DwellTime; |
| prNchoInfo->rParamActionFrame.i4len = |
| prParamActionFrame->i4len; |
| kalMemCopy(prNchoInfo->rParamActionFrame.aucData, |
| prParamActionFrame->aucData, |
| prParamActionFrame->i4len); |
| DBGLOG(INIT, TRACE, "NCHO send ncho action frame start\n"); |
| rStatus = WLAN_STATUS_SUCCESS; |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSendNchoActionFrameEnd(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSendNchoActionFrameEnd"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| prAdapter->rNchoInfo.fgIsSendingAF = FALSE; |
| prAdapter->rNchoInfo.fgChGranted = TRUE; |
| DBGLOG(INIT, TRACE, "NCHO send action frame end\n"); |
| rStatus = WLAN_STATUS_SUCCESS; |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSetNchoWesMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoWesMode"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam != TRUE && *pParam != FALSE) { |
| DBGLOG(INIT, ERROR, "NCHO wes mode invalid %d\n", *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| |
| prAdapter->rNchoInfo.u4WesMode = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO WES mode is %d\n", *pParam); |
| rStatus = WLAN_STATUS_SUCCESS; |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoWesMode(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t *pParam = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoWesMode"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| pParam = (uint32_t *) pvQueryBuffer; |
| *pParam = prAdapter->rNchoInfo.u4WesMode; |
| DBGLOG(INIT, TRACE, "NCHO Wes mode is %d\n", *pParam); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetNchoBand(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoBand"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| |
| switch (*pParam) { |
| case NCHO_BAND_AUTO: |
| prAdapter->aePreferBand[NETWORK_TYPE_AIS] = BAND_NULL; |
| prAdapter->rNchoInfo.eBand = NCHO_BAND_AUTO; |
| rStatus = WLAN_STATUS_SUCCESS; |
| break; |
| case NCHO_BAND_2G4: |
| prAdapter->aePreferBand[NETWORK_TYPE_AIS] = BAND_2G4; |
| prAdapter->rNchoInfo.eBand = NCHO_BAND_2G4; |
| rStatus = WLAN_STATUS_SUCCESS; |
| break; |
| case NCHO_BAND_5G: |
| prAdapter->aePreferBand[NETWORK_TYPE_AIS] = BAND_5G; |
| prAdapter->rNchoInfo.eBand = NCHO_BAND_5G; |
| rStatus = WLAN_STATUS_SUCCESS; |
| break; |
| default: |
| DBGLOG(INIT, ERROR, "NCHO wes mode invalid %d\n", *pParam); |
| rStatus = WLAN_STATUS_INVALID_DATA; |
| break; |
| } |
| |
| DBGLOG(INIT, INFO, "NCHO enabled:%d ,band:%d,status:%d\n" |
| , prAdapter->rNchoInfo.fgECHOEnabled, *pParam, rStatus); |
| |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoBand(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t *pParam = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoBand"); |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| if (u4QueryBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| pParam = (uint32_t *) pvQueryBuffer; |
| *pParam = prAdapter->rNchoInfo.eBand; |
| DBGLOG(INIT, TRACE, "NCHO band is %d\n", *pParam); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetNchoDfsScnMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| char acCmd[NCHO_CMD_MAX_LENGTH] = {0}; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoDfsScnMode"); |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam >= NCHO_DFS_SCN_NUM) { |
| DBGLOG(INIT, ERROR, "NCHO DFS scan mode invalid %d\n", |
| *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| |
| kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_SCAN_DFS_MODE, |
| *pParam); |
| rStatus = wlanFwCfgParse(prAdapter, acCmd); |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| prAdapter->rNchoInfo.eDFSScnMode = *pParam; |
| DBGLOG(INIT, TRACE, "NCHO DFS scan mode is %d\n", *pParam); |
| } |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoDfsScnMode(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct CMD_HEADER cmdV1Header; |
| struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) |
| pvQueryBuffer; |
| struct CMD_FORMAT_V1 *prCmdV1 = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoDfsScnMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_HEADER); |
| |
| if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| if (prAdapter->rNchoInfo.fgECHOEnabled == FALSE) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; |
| rStatus = wlanoidSetNchoHeader(prCmdV1Header, prCmdV1, |
| FW_CFG_KEY_NCHO_SCAN_DFS_MODE, |
| kalStrLen(FW_CFG_KEY_NCHO_SCAN_DFS_MODE)); |
| if (rStatus != WLAN_STATUS_SUCCESS) { |
| DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); |
| return rStatus; |
| } |
| kalMemCopy(&cmdV1Header, prCmdV1Header, |
| sizeof(struct CMD_HEADER)); |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, |
| CMD_ID_GET_SET_CUSTOMER_CFG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCfgRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_HEADER), |
| (uint8_t *)&cmdV1Header, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidSetNchoEnable(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t *pParam = NULL; |
| char acCmd[NCHO_CMD_MAX_LENGTH] = { 0 }; |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| |
| DEBUGFUNC("wlanoidSetNchoEnable"); |
| DBGLOG(OID, LOUD, "\n"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| ASSERT(pvSetBuffer); |
| |
| *pu4SetInfoLen = sizeof(uint32_t); |
| |
| if (u4SetBufferLen < sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| pParam = (uint32_t *) pvSetBuffer; |
| if (*pParam != 0 && *pParam != 1) { |
| DBGLOG(INIT, ERROR, "NCHO DFS scan mode invalid %d\n", |
| *pParam); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| |
| kalSprintf(acCmd, "%s %d", FW_CFG_KEY_NCHO_ENABLE, *pParam); |
| rStatus = wlanFwCfgParse(prAdapter, acCmd); |
| if (rStatus == WLAN_STATUS_SUCCESS) { |
| prAdapter->rNchoInfo.fgECHOEnabled = *pParam; |
| DBGLOG(INIT, INFO, "NCHO enable is %d\n", *pParam); |
| } |
| |
| return rStatus; |
| } |
| |
| uint32_t |
| wlanoidQueryNchoEnable(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| uint32_t rStatus = WLAN_STATUS_FAILURE; |
| struct CMD_HEADER cmdV1Header; |
| struct CMD_HEADER *prCmdV1Header = (struct CMD_HEADER *) |
| pvQueryBuffer; |
| struct CMD_FORMAT_V1 *prCmdV1 = NULL; |
| |
| DEBUGFUNC("wlanoidQueryNchoRoamTrigger"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4QueryInfoLen); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_HEADER); |
| |
| if (u4QueryBufferLen < sizeof(struct CMD_HEADER)) |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| |
| prCmdV1 = (struct CMD_FORMAT_V1 *) prCmdV1Header->buffer; |
| rStatus = wlanoidSetNchoHeader(prCmdV1Header, |
| prCmdV1, |
| FW_CFG_KEY_NCHO_ENABLE, |
| kalStrLen(FW_CFG_KEY_NCHO_ENABLE)); |
| if (rStatus != WLAN_STATUS_SUCCESS) { |
| DBGLOG(REQ, ERROR, "NCHO no enough memory\n"); |
| return rStatus; |
| } |
| kalMemCopy(&cmdV1Header, prCmdV1Header, |
| sizeof(struct CMD_HEADER)); |
| rStatus = wlanSendSetQueryCmd( |
| prAdapter, |
| CMD_ID_GET_SET_CUSTOMER_CFG, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryCfgRead, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_HEADER), |
| (uint8_t *)&cmdV1Header, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| return rStatus; |
| } |
| #endif /* CFG_SUPPORT_NCHO */ |
| |
| uint32_t |
| wlanoidAbortScan(IN struct ADAPTER *prAdapter, |
| OUT void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| |
| struct AIS_FSM_INFO *prAisFsmInfo = NULL; |
| |
| prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); |
| if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN || |
| prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { |
| DBGLOG(OID, INFO, "wlanoidAbortScan\n"); |
| prAisFsmInfo->fgIsScanOidAborted = TRUE; |
| aisFsmStateAbort_SCAN(prAdapter); |
| } |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidDisableTdlsPs(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_TDLS_PS_T rTdlsPs; |
| |
| if (!prAdapter || !pvSetBuffer) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| rTdlsPs.ucIsEnablePs = *(uint8_t *)pvSetBuffer - '0'; |
| DBGLOG(OID, INFO, "enable tdls ps %d\n", |
| rTdlsPs.ucIsEnablePs); |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TDLS_PS, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(rTdlsPs), |
| (uint8_t *)&rTdlsPs, |
| NULL, |
| 0); |
| } |
| |
| uint32_t wlanoidSetSer(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| uint32_t u4CmdId; |
| |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| |
| if (u4SetBufferLen != sizeof(uint32_t)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| u4CmdId = *((uint32_t *)pvSetBuffer); |
| |
| DBGLOG(OID, INFO, "Set SER CMD[%d]\n", u4CmdId); |
| |
| switch (u4CmdId) { |
| case SER_USER_CMD_DISABLE: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET, |
| SER_SET_DISABLE, 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET, SER_SET_ENABLE, 0); |
| break; |
| |
| case SER_USER_CMD_QUERY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_QUERY, 0, 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_TRACKING_ONLY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| SER_ENABLE_TRACKING, 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_L1_RECOVER_ONLY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| SER_ENABLE_TRACKING | SER_ENABLE_L1_RECOVER, |
| 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_L2_RECOVER_ONLY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| SER_ENABLE_TRACKING | SER_ENABLE_L2_RECOVER, |
| 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_L3_RX_ABORT_ONLY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| SER_ENABLE_TRACKING | SER_ENABLE_L3_RX_ABORT, |
| 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_L3_TX_ABORT_ONLY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| SER_ENABLE_TRACKING | SER_ENABLE_L3_TX_ABORT, |
| 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_L3_TX_DISABLE_ONLY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| SER_ENABLE_TRACKING | |
| SER_ENABLE_L3_TX_DISABLE, 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_L3_BFRECOVER_ONLY: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| SER_ENABLE_TRACKING | |
| SER_ENABLE_L3_BF_RECOVER, 0); |
| break; |
| |
| case SER_USER_CMD_ENABLE_MASK_RECOVER_ALL: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_SET_ENABLE_MASK, |
| (SER_ENABLE_TRACKING | |
| SER_ENABLE_L1_RECOVER | |
| SER_ENABLE_L2_RECOVER | |
| SER_ENABLE_L3_RX_ABORT | |
| SER_ENABLE_L3_TX_ABORT | |
| SER_ENABLE_L3_TX_DISABLE | |
| SER_ENABLE_L3_BF_RECOVER), 0); |
| break; |
| |
| case SER_USER_CMD_L0_RECOVER: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L0_RECOVER, 0); |
| break; |
| |
| case SER_USER_CMD_L1_RECOVER: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L1_RECOVER, 0); |
| break; |
| |
| case SER_USER_CMD_L2_BN0_RECOVER: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L2_RECOVER, ENUM_BAND_0); |
| break; |
| |
| case SER_USER_CMD_L2_BN1_RECOVER: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L2_RECOVER, ENUM_BAND_1); |
| break; |
| |
| case SER_USER_CMD_L3_RX0_ABORT: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L3_RX_ABORT, ENUM_BAND_0); |
| break; |
| |
| case SER_USER_CMD_L3_RX1_ABORT: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L3_RX_ABORT, ENUM_BAND_1); |
| break; |
| |
| case SER_USER_CMD_L3_TX0_ABORT: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L3_TX_ABORT, ENUM_BAND_0); |
| break; |
| |
| case SER_USER_CMD_L3_TX1_ABORT: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L3_TX_ABORT, ENUM_BAND_1); |
| break; |
| |
| case SER_USER_CMD_L3_TX0_DISABLE: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L3_TX_DISABLE, ENUM_BAND_0); |
| break; |
| |
| case SER_USER_CMD_L3_TX1_DISABLE: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L3_TX_DISABLE, ENUM_BAND_1); |
| break; |
| |
| case SER_USER_CMD_L3_BF_RECOVER: |
| wlanoidSerExtCmd(prAdapter, SER_ACTION_RECOVER, |
| SER_SET_L3_BF_RECOVER, 0); |
| break; |
| |
| default: |
| DBGLOG(OID, ERROR, "Error SER CMD\n"); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t wlanoidSerExtCmd(IN struct ADAPTER *prAdapter, uint8_t ucAction, |
| uint8_t ucSerSet, uint8_t ucDbdcIdx) { |
| struct EXT_CMD_SER_T rCmdSer = {0}; |
| uint32_t rStatus = WLAN_STATUS_SUCCESS; |
| |
| rCmdSer.ucAction = ucAction; |
| rCmdSer.ucSerSet = ucSerSet; |
| rCmdSer.ucDbdcIdx = ucDbdcIdx; |
| |
| rStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_SER, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| NULL, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct EXT_CMD_SER_T), |
| (uint8_t *)&rCmdSer, NULL, 0); |
| return rStatus; |
| } |
| |
| #if (CFG_SUPPORT_TXPOWER_INFO == 1) |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to set rdd report. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidQueryTxPowerInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T *prTxPowerInfo = |
| NULL; |
| struct CMD_TX_POWER_SHOW_INFO_T rCmdTxPowerShowInfo; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| if (!prAdapter) |
| return WLAN_STATUS_FAILURE; |
| if (!pvQueryBuffer) |
| return WLAN_STATUS_FAILURE; |
| if (!pu4QueryInfoLen) |
| return WLAN_STATUS_FAILURE; |
| |
| if (u4QueryBufferLen < |
| sizeof(struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T)) { |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_TXPOWER_ALL_RATE_POWER_INFO_T); |
| return WLAN_STATUS_BUFFER_TOO_SHORT; |
| } |
| |
| *pu4QueryInfoLen = sizeof(struct |
| PARAM_TXPOWER_ALL_RATE_POWER_INFO_T); |
| |
| prTxPowerInfo = (struct PARAM_TXPOWER_ALL_RATE_POWER_INFO_T |
| *) pvQueryBuffer; |
| |
| kalMemSet(&rCmdTxPowerShowInfo, 0, |
| sizeof(struct CMD_TX_POWER_SHOW_INFO_T)); |
| |
| rCmdTxPowerShowInfo.ucPowerCtrlFormatId = |
| TX_POWER_SHOW_INFO; |
| rCmdTxPowerShowInfo.ucTxPowerInfoCatg = |
| prTxPowerInfo->ucTxPowerCategory; |
| rCmdTxPowerShowInfo.ucBandIdx = prTxPowerInfo->ucBandIdx; |
| |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_TX_POWER_FEATURE_CTRL, |
| FALSE, /* Query Bit: True->write False->read */ |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryTxPowerInfo, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TX_POWER_SHOW_INFO_T), |
| (uint8_t *) (&rCmdTxPowerShowInfo), |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| return rWlanStatus; |
| } |
| #endif |
| |
| uint32_t |
| wlanoidSetDrvRoamingPolicy(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| #if CFG_SUPPORT_ROAMING |
| uint32_t u4RoamingPoily = 0; |
| struct ROAMING_INFO *prRoamingFsmInfo; |
| struct CONNECTION_SETTINGS *prConnSettings; |
| uint32_t u4CurConPolicy; |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| |
| u4RoamingPoily = *(uint32_t *)pvSetBuffer; |
| |
| prRoamingFsmInfo = (struct ROAMING_INFO *) & |
| (prAdapter->rWifiVar.rRoamingInfo); |
| |
| prConnSettings = (struct CONNECTION_SETTINGS *) |
| &prAdapter->rWifiVar.rConnSettings; |
| u4CurConPolicy = prConnSettings->eConnectionPolicy; |
| |
| if (u4RoamingPoily == 1) { |
| if (((prAdapter->rWifiVar.rAisFsmInfo.eCurrentState == |
| AIS_STATE_NORMAL_TR) |
| || (prAdapter->rWifiVar.rAisFsmInfo.eCurrentState == |
| AIS_STATE_ONLINE_SCAN)) |
| && (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE)) |
| roamingFsmRunEventStart(prAdapter); |
| |
| /* Change Connect by any , avoid to connect by BSSID on roaming |
| * or beacon timeout! |
| */ |
| prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; |
| |
| } else { |
| if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_IDLE) |
| roamingFsmRunEventAbort(prAdapter); |
| } |
| prRoamingFsmInfo->fgDrvRoamingAllow = (u_int8_t) |
| u4RoamingPoily; |
| |
| DBGLOG(REQ, INFO, |
| "wlanoidSetDrvRoamingPolicy, RoamingPoily= %d, conn policy= [%d] -> [%d]\n", |
| u4RoamingPoily, u4CurConPolicy, |
| prRoamingFsmInfo->fgDrvRoamingAllow); |
| #endif |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t wlanoidUpdateFtIes(struct ADAPTER *prAdapter, void *pvSetBuffer, |
| uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) |
| { |
| struct FT_IES *prFtIes = NULL; |
| uint32_t u4IeLen = 0; |
| uint8_t *pucIEStart = NULL; |
| struct STA_RECORD *prStaRec = NULL; |
| #if CFG_SUPPORT_CFG80211_AUTH |
| uint16_t u2Offset = 0; |
| #else |
| struct MSG_SAA_FT_CONTINUE *prFtContinueMsg = NULL; |
| struct cfg80211_update_ft_ies_params *ftie = NULL; |
| #endif |
| |
| if (!pvSetBuffer || u4SetBufferLen == 0) { |
| DBGLOG(OID, ERROR, |
| "FT: pvSetBuffer is Null %d, Buffer Len %u\n", |
| !pvSetBuffer, u4SetBufferLen); |
| return WLAN_STATUS_INVALID_DATA; |
| } |
| prStaRec = prAdapter->rWifiVar.rAisFsmInfo.prTargetStaRec; |
| prFtIes = &prAdapter->prGlueInfo->rFtIeForTx; |
| #if CFG_SUPPORT_CFG80211_AUTH |
| pucIEStart = (uint8_t *)pvSetBuffer; |
| u4IeLen = u4SetBufferLen; |
| DBGLOG(OID, INFO, "u4IeLen %d\n", u4IeLen); |
| #else |
| ftie = (struct cfg80211_update_ft_ies_params *)pvSetBuffer; |
| |
| if (ftie->ie_len == 0) { |
| DBGLOG(OID, WARN, "FT: FT Ies length is 0\n"); |
| return WLAN_STATUS_SUCCESS; |
| } |
| if (prFtIes->u4IeLength != ftie->ie_len) { |
| kalMemFree(prFtIes->pucIEBuf, VIR_MEM_TYPE, |
| prFtIes->u4IeLength); |
| prFtIes->pucIEBuf = kalMemAlloc(ftie->ie_len, VIR_MEM_TYPE); |
| prFtIes->u4IeLength = ftie->ie_len; |
| } |
| pucIEStart = prFtIes->pucIEBuf; |
| u4IeLen = prFtIes->u4IeLength; |
| prFtIes->u2MDID = ftie->md; |
| #endif |
| prFtIes->prFTIE = NULL; |
| prFtIes->prMDIE = NULL; |
| prFtIes->prRsnIE = NULL; |
| prFtIes->prTIE = NULL; |
| #if CFG_SUPPORT_CFG80211_AUTH |
| IE_FOR_EACH(pucIEStart, u4IeLen, u2Offset) { |
| switch (IE_ID(pucIEStart)) { |
| case ELEM_ID_MOBILITY_DOMAIN: |
| if (prFtIes->prMDIE == NULL) |
| prFtIes->prMDIE = kalMemAlloc( |
| IE_SIZE(pucIEStart), VIR_MEM_TYPE); |
| COPY_IE((unsigned long)(prFtIes->prMDIE), pucIEStart); |
| prFtIes->u4IeLength += IE_SIZE(pucIEStart); |
| break; |
| case ELEM_ID_FAST_TRANSITION: |
| if (prFtIes->prFTIE == NULL) |
| prFtIes->prFTIE = kalMemAlloc(IE_SIZE( |
| pucIEStart), VIR_MEM_TYPE); |
| COPY_IE((unsigned long)(prFtIes->prFTIE), pucIEStart); |
| prFtIes->u4IeLength += IE_SIZE(pucIEStart); |
| break; |
| case ELEM_ID_RESOURCE_INFO_CONTAINER: |
| break; |
| case ELEM_ID_TIMEOUT_INTERVAL: |
| if (prFtIes->prTIE == NULL) |
| prFtIes->prTIE = kalMemAlloc( |
| IE_SIZE(pucIEStart), VIR_MEM_TYPE); |
| COPY_IE((unsigned long)(prFtIes->prTIE), pucIEStart); |
| prFtIes->u4IeLength += IE_SIZE(pucIEStart); |
| break; |
| case ELEM_ID_RSN: |
| if (prFtIes->prRsnIE == NULL) |
| prFtIes->prRsnIE = kalMemAlloc( |
| IE_SIZE(pucIEStart), VIR_MEM_TYPE); |
| COPY_IE((unsigned long)(prFtIes->prRsnIE), pucIEStart); |
| prFtIes->u4IeLength += IE_SIZE(pucIEStart); |
| break; |
| } |
| } |
| DBGLOG(OID, INFO, |
| "FT: IesLen %u, MDIE %d FTIE %d RSN %d TIE %d\n", |
| prFtIes->u4IeLength, !!prFtIes->prMDIE, |
| !!prFtIes->prFTIE, !!prFtIes->prRsnIE, |
| !!prFtIes->prTIE); |
| |
| #else |
| if (u4IeLen) |
| kalMemCopy(pucIEStart, ftie->ie, u4IeLen); |
| while (u4IeLen >= 2) { |
| uint32_t u4InfoElemLen = IE_SIZE(pucIEStart); |
| |
| if (u4InfoElemLen > u4IeLen) |
| break; |
| switch (pucIEStart[0]) { |
| case ELEM_ID_MOBILITY_DOMAIN: |
| prFtIes->prMDIE = |
| (struct IE_MOBILITY_DOMAIN *)pucIEStart; |
| break; |
| case ELEM_ID_FAST_TRANSITION: |
| prFtIes->prFTIE = |
| (struct IE_FAST_TRANSITION *)pucIEStart; |
| break; |
| case ELEM_ID_RESOURCE_INFO_CONTAINER: |
| break; |
| case ELEM_ID_TIMEOUT_INTERVAL: |
| prFtIes->prTIE = |
| (struct IE_TIMEOUT_INTERVAL *)pucIEStart; |
| break; |
| case ELEM_ID_RSN: |
| prFtIes->prRsnIE = (struct RSN_INFO_ELEM *)pucIEStart; |
| break; |
| } |
| u4IeLen -= u4InfoElemLen; |
| pucIEStart += u4InfoElemLen; |
| } |
| DBGLOG(OID, INFO, |
| "FT: MdId %d IesLen %u, MDIE %d FTIE %d RSN %d TIE %d\n", |
| ftie->md, prFtIes->u4IeLength, !!prFtIes->prMDIE, |
| !!prFtIes->prFTIE, !!prFtIes->prRsnIE, !!prFtIes->prTIE); |
| #endif |
| |
| #if !CFG_SUPPORT_CFG80211_AUTH |
| /* check if SAA is waiting to send Reassoc req */ |
| if (!prStaRec || prStaRec->ucAuthTranNum != AUTH_TRANSACTION_SEQ_2 || |
| !prStaRec->fgIsReAssoc || prStaRec->ucStaState != STA_STATE_1) |
| return WLAN_STATUS_SUCCESS; |
| |
| prFtContinueMsg = (struct MSG_SAA_FT_CONTINUE *)cnmMemAlloc( |
| prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_SAA_FT_CONTINUE)); |
| if (!prFtContinueMsg) { |
| DBGLOG(OID, WARN, "FT: failed to allocate Join Req Msg\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| prFtContinueMsg->rMsgHdr.eMsgId = MID_OID_SAA_FSM_CONTINUE; |
| prFtContinueMsg->prStaRec = prStaRec; |
| /* ToDo: for Resource Request Protocol, we need to check if RIC request |
| ** is included. |
| */ |
| if (prFtIes->prMDIE && (prFtIes->prMDIE->ucBitMap & BIT(1))) |
| prFtContinueMsg->fgFTRicRequest = TRUE; |
| else |
| prFtContinueMsg->fgFTRicRequest = FALSE; |
| DBGLOG(OID, INFO, "FT: continue to do auth/assoc, Ft Request %d\n", |
| prFtContinueMsg->fgFTRicRequest); |
| mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prFtContinueMsg, |
| MSG_SEND_METHOD_BUF); |
| #endif |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t wlanoidSendNeighborRequest(struct ADAPTER *prAdapter, |
| void *pvSetBuffer, uint32_t u4SetBufferLen, |
| uint32_t *pu4SetInfoLen) |
| { |
| struct SUB_ELEMENT_LIST *prSSIDIE = NULL; |
| struct BSS_INFO *prAisBssInfo = NULL; |
| uint8_t ucSSIDIELen = 0; |
| uint8_t *pucSSID = (uint8_t *)pvSetBuffer; |
| |
| if (!prAdapter || !prAdapter->prAisBssInfo) |
| return WLAN_STATUS_INVALID_DATA; |
| prAisBssInfo = prAdapter->prAisBssInfo; |
| if (prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED) { |
| DBGLOG(OID, ERROR, "didn't connected any Access Point\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| if (u4SetBufferLen == 0 || !pucSSID) { |
| rlmTxNeighborReportRequest(prAdapter, |
| prAisBssInfo->prStaRecOfAP, NULL); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| ucSSIDIELen = (uint8_t)(u4SetBufferLen + sizeof(*prSSIDIE)); |
| prSSIDIE = kalMemAlloc(ucSSIDIELen, PHY_MEM_TYPE); |
| if (!prSSIDIE) { |
| DBGLOG(OID, ERROR, "No Memory\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| prSSIDIE->prNext = NULL; |
| prSSIDIE->rSubIE.ucSubID = ELEM_ID_SSID; |
| prSSIDIE->rSubIE.ucLength = (uint8_t)u4SetBufferLen; |
| kalMemCopy(&prSSIDIE->rSubIE.aucOptInfo[0], pucSSID, |
| (uint8_t)u4SetBufferLen); |
| DBGLOG(OID, INFO, "Send Neighbor Request, SSID=%s\n", pucSSID); |
| rlmTxNeighborReportRequest(prAdapter, prAisBssInfo->prStaRecOfAP, |
| prSSIDIE); |
| kalMemFree(prSSIDIE, PHY_MEM_TYPE, ucSSIDIELen); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t wlanoidSync11kCapabilities(struct ADAPTER *prAdapter, |
| void *pvSetBuffer, uint32_t u4SetBufferLen, |
| uint32_t *pu4SetInfoLen) |
| { |
| struct CMD_SET_RRM_CAPABILITY rCmdRrmCapa; |
| |
| kalMemZero(&rCmdRrmCapa, sizeof(rCmdRrmCapa)); |
| rCmdRrmCapa.ucCmdVer = 0x1; |
| rCmdRrmCapa.ucRrmEnable = 1; |
| rlmFillRrmCapa(&rCmdRrmCapa.ucCapabilities[0]); |
| return wlanSendSetQueryCmd( |
| prAdapter, CMD_ID_SET_RRM_CAPABILITY, TRUE, FALSE, g_fgIsOid, |
| nicCmdEventSetCommon, nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_SET_RRM_CAPABILITY), (uint8_t *)&rCmdRrmCapa, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| |
| static uint8_t pow_r(uint8_t x, uint8_t y) |
| { |
| uint8_t result = 0; |
| uint8_t tmp = 0; |
| |
| if (y == 0) |
| return 1; |
| if (y == 1) |
| return x; |
| tmp = pow_r(x, y/2); |
| if ((y & 1) != 0) |
| result = x * tmp * tmp; |
| else |
| result = tmp * tmp; |
| return result; |
| |
| } |
| |
| uint32_t wlanoidSendBTMQuery(struct ADAPTER *prAdapter, void *pvSetBuffer, |
| uint32_t u4SetBufferLen, uint32_t *pu4SetInfoLen) |
| { |
| struct STA_RECORD *prStaRec = NULL; |
| struct BSS_TRANSITION_MGT_PARAM_T *prBtmMgt = NULL; |
| uint8_t i = 0; |
| uint8_t uReason = 0; |
| |
| if (!prAdapter->prAisBssInfo || |
| prAdapter->prAisBssInfo->eConnectionState != |
| PARAM_MEDIA_STATE_CONNECTED) { |
| DBGLOG(OID, INFO, "Not connected yet\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| prStaRec = prAdapter->prAisBssInfo->prStaRecOfAP; |
| if (!prStaRec || !prStaRec->fgSupportBTM) { |
| DBGLOG(OID, INFO, |
| "Target BSS(%p) didn't support Bss Transition Management\n", |
| prStaRec); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| if (pvSetBuffer != NULL) { |
| for (i = 0; i < strlen(pvSetBuffer); i++) { |
| uReason += ((*(uint8_t *)(pvSetBuffer + i) - '0') |
| * pow_r(10, (strlen(pvSetBuffer) - i - 1))); |
| } |
| } |
| prBtmMgt = &prAdapter->rWifiVar.rAisSpecificBssInfo.rBTMParam; |
| prBtmMgt->ucDialogToken = wnmGetBtmToken(); |
| prBtmMgt->ucQueryReason = pvSetBuffer ? uReason |
| : BSS_TRANSITION_LOW_RSSI; |
| DBGLOG(OID, INFO, "Send BssTransitionManagementQuery, Reason %d\n", |
| prBtmMgt->ucQueryReason); |
| wnmSendBTMQueryFrame(prAdapter, prStaRec); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /* |
| * This func is mainly from bionic's strtok.c |
| */ |
| static int8_t *strtok_r(int8_t *s, const int8_t *delim, int8_t **last) |
| { |
| char *spanp; |
| int c, sc; |
| char *tok; |
| |
| |
| if (s == NULL) { |
| s = *last; |
| if (s == 0) |
| return NULL; |
| } |
| cont: |
| c = *s++; |
| for (spanp = (char *)delim; (sc = *spanp++) != 0;) { |
| if (c == sc) |
| goto cont; |
| } |
| |
| if (c == 0) { /* no non-delimiter characters */ |
| *last = NULL; |
| return NULL; |
| } |
| tok = s - 1; |
| |
| for (;;) { |
| c = *s++; |
| spanp = (char *)delim; |
| do { |
| sc = *spanp++; |
| if (sc == c) { |
| if (c == 0) |
| s = NULL; |
| else |
| s[-1] = 0; |
| *last = s; |
| return tok; |
| } |
| } while (sc != 0); |
| } |
| } |
| |
| uint32_t wlanoidTspecOperation(struct ADAPTER *prAdapter, void *pvBuffer, |
| uint32_t u4BufferLen, uint32_t *pu4InfoLen) |
| { |
| struct PARAM_QOS_TSPEC *prTspecParam = NULL; |
| struct MSG_TS_OPERATE *prMsgTsOperate = NULL; |
| uint8_t *pucCmd = (uint8_t *)pvBuffer; |
| uint8_t *pucSavedPtr = NULL; |
| uint8_t *pucItem = NULL; |
| uint32_t u4Ret = 1; |
| uint8_t ucApsdSetting = 2; /* 0: legacy; 1: u-apsd; 2: not set yet */ |
| enum TSPEC_OP_CODE eTsOp; |
| |
| #if !CFG_SUPPORT_WMM_AC |
| DBGLOG(OID, INFO, "WMM AC is not supported\n"); |
| return WLAN_STATUS_FAILURE; |
| #endif |
| if (kalStrniCmp(pucCmd, "dumpts", 6) == 0) { |
| *pu4InfoLen = kalSnprintf(pucCmd, u4BufferLen, "%s", |
| "\nAll Active Tspecs:\n"); |
| u4BufferLen -= *pu4InfoLen; |
| pucCmd += *pu4InfoLen; |
| *pu4InfoLen += |
| wmmDumpActiveTspecs(prAdapter, pucCmd, u4BufferLen); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| if (kalStrniCmp(pucCmd, "addts", 5) == 0) |
| eTsOp = TX_ADDTS_REQ; |
| else if (kalStrniCmp(pucCmd, "delts", 5) == 0) |
| eTsOp = TX_DELTS_REQ; |
| else { |
| DBGLOG(OID, INFO, "wrong operation %s\n", pucCmd); |
| return WLAN_STATUS_FAILURE; |
| } |
| /* addts token n,tid n,dir n,psb n,up n,fixed n,size n,maxsize |
| ** n,maxsrvint n, minsrvint n, |
| ** inact n, suspension n, srvstarttime n, minrate n,meanrate n,peakrate |
| ** n,burst n,delaybound n, |
| ** phyrate n,SBA n,mediumtime n |
| */ |
| prMsgTsOperate = (struct MSG_TS_OPERATE *)cnmMemAlloc( |
| prAdapter, RAM_TYPE_MSG, sizeof(struct MSG_TS_OPERATE)); |
| if (!prMsgTsOperate) |
| return WLAN_STATUS_FAILURE; |
| |
| kalMemZero(prMsgTsOperate, sizeof(struct MSG_TS_OPERATE)); |
| prMsgTsOperate->rMsgHdr.eMsgId = MID_OID_WMM_TSPEC_OPERATE; |
| prMsgTsOperate->eOpCode = eTsOp; |
| prTspecParam = &prMsgTsOperate->rTspecParam; |
| pucCmd += 6; |
| pucItem = (uint8_t *)strtok_r((int8_t *)pucCmd, ",", |
| (int8_t **)&pucSavedPtr); |
| while (pucItem) { |
| if (kalStrniCmp(pucItem, "token ", 6) == 0) |
| u4Ret = kstrtou8(pucItem + 6, 0, |
| &prTspecParam->ucDialogToken); |
| else if (kalStrniCmp(pucItem, "tid ", 4) == 0) { |
| u4Ret = kstrtou8(pucItem + 4, 0, |
| &prMsgTsOperate->ucTid); |
| prTspecParam->rTsInfo.ucTid = prMsgTsOperate->ucTid; |
| } else if (kalStrniCmp(pucItem, "dir ", 4) == 0) |
| u4Ret = kstrtou8(pucItem + 4, 0, |
| &prTspecParam->rTsInfo.ucDirection); |
| else if (kalStrniCmp(pucItem, "psb ", 4) == 0) |
| u4Ret = kstrtou8(pucItem+4, 0, &ucApsdSetting); |
| else if (kalStrniCmp(pucItem, "up ", 3) == 0) |
| u4Ret = kstrtou8(pucItem + 3, 0, |
| &prTspecParam->rTsInfo.ucuserPriority); |
| else if (kalStrniCmp(pucItem, "size ", 5) == 0) { |
| uint16_t u2Size = 0; |
| |
| u4Ret = kstrtou16(pucItem+5, 0, &u2Size); |
| prTspecParam->u2NominalMSDUSize |= u2Size; |
| } else if (kalStrniCmp(pucItem, "fixed ", 6) == 0) { |
| uint8_t ucFixed = 0; |
| |
| u4Ret = kstrtou8(pucItem+6, 0, &ucFixed); |
| if (ucFixed) |
| prTspecParam->u2NominalMSDUSize |= BIT(15); |
| } else if (kalStrniCmp(pucItem, "maxsize ", 8) == 0) |
| u4Ret = kstrtou16(pucItem + 8, 0, |
| &prTspecParam->u2MaxMSDUsize); |
| else if (kalStrniCmp(pucItem, "maxsrvint ", 10) == 0) |
| u4Ret = kalkStrtou32(pucItem + 10, 0, |
| &prTspecParam->u4MaxSvcIntv); |
| else if (kalStrniCmp(pucItem, "minsrvint ", 10) == 0) |
| u4Ret = kalkStrtou32(pucItem + 10, 0, |
| &prTspecParam->u4MinSvcIntv); |
| else if (kalStrniCmp(pucItem, "inact ", 6) == 0) |
| u4Ret = kalkStrtou32(pucItem + 6, 0, |
| &prTspecParam->u4InactIntv); |
| else if (kalStrniCmp(pucItem, "suspension ", 11) == 0) |
| u4Ret = kalkStrtou32(pucItem + 11, 0, |
| &prTspecParam->u4SpsIntv); |
| else if (kalStrniCmp(pucItem, "srvstarttime ", 13) == 0) |
| u4Ret = kalkStrtou32(pucItem + 13, 0, |
| &prTspecParam->u4SvcStartTime); |
| else if (kalStrniCmp(pucItem, "minrate ", 8) == 0) |
| u4Ret = kalkStrtou32(pucItem + 8, 0, |
| &prTspecParam->u4MinDataRate); |
| else if (kalStrniCmp(pucItem, "meanrate ", 9) == 0) |
| u4Ret = kalkStrtou32(pucItem + 9, 0, |
| &prTspecParam->u4MeanDataRate); |
| else if (kalStrniCmp(pucItem, "peakrate ", 9) == 0) |
| u4Ret = kalkStrtou32(pucItem + 9, 0, |
| &prTspecParam->u4PeakDataRate); |
| else if (kalStrniCmp(pucItem, "burst ", 6) == 0) |
| u4Ret = kalkStrtou32(pucItem + 6, 0, |
| &prTspecParam->u4MaxBurstSize); |
| else if (kalStrniCmp(pucItem, "delaybound ", 11) == 0) |
| u4Ret = kalkStrtou32(pucItem + 11, 0, |
| &prTspecParam->u4DelayBound); |
| else if (kalStrniCmp(pucItem, "phyrate ", 8) == 0) |
| u4Ret = kalkStrtou32(pucItem + 8, 0, |
| &prTspecParam->u4MinPHYRate); |
| else if (kalStrniCmp(pucItem, "sba ", 4) == 0) |
| u4Ret = wlanDecimalStr2Hexadecimals( |
| pucItem + 4, &prTspecParam->u2Sba); |
| else if (kalStrniCmp(pucItem, "mediumtime ", 11) == 0) |
| u4Ret = kstrtou16(pucItem + 11, 0, |
| &prTspecParam->u2MediumTime); |
| |
| if (u4Ret) { |
| DBGLOG(OID, ERROR, "Parse %s error\n", pucItem); |
| cnmMemFree(prAdapter, prMsgTsOperate); |
| return WLAN_STATUS_FAILURE; |
| } |
| pucItem = |
| (uint8_t *)strtok_r(NULL, ",", (int8_t **)&pucSavedPtr); |
| } |
| /* if APSD is not set in addts request, use global wmmps settings */ |
| if (!prAdapter->prAisBssInfo) |
| DBGLOG(OID, ERROR, "AisBssInfo is NULL!\n"); |
| else if (ucApsdSetting == 2) { |
| struct PM_PROFILE_SETUP_INFO *prPmProf = NULL; |
| enum ENUM_ACI eAc = |
| aucUp2ACIMap[prTspecParam->rTsInfo.ucuserPriority]; |
| |
| prPmProf = &prAdapter->prAisBssInfo->rPmProfSetupInfo; |
| switch (prTspecParam->rTsInfo.ucDirection) { |
| case UPLINK_TS: /* UpLink*/ |
| if (prPmProf->ucBmpTriggerAC & BIT(eAc)) |
| prTspecParam->rTsInfo.ucApsd = 1; |
| break; |
| case DOWNLINK_TS:/* DownLink */ |
| if (prPmProf->ucBmpDeliveryAC & BIT(eAc)) |
| prTspecParam->rTsInfo.ucApsd = 1; |
| break; |
| case BI_DIR_TS: /* Bi-directional */ |
| if ((prPmProf->ucBmpTriggerAC & BIT(eAc)) && |
| (prPmProf->ucBmpDeliveryAC & BIT(eAc))) |
| prTspecParam->rTsInfo.ucApsd = 1; |
| break; |
| } |
| } else |
| prTspecParam->rTsInfo.ucApsd = ucApsdSetting; |
| *(--pucCmd) = 0; |
| pucCmd -= 5; |
| DBGLOG(OID, INFO, |
| "%s %d %d %d %d %d %d %d %u %u %u %u %u %u %u %u %u %u %u 0x%04x %d\n", |
| pucCmd, prTspecParam->ucDialogToken, prTspecParam->rTsInfo.ucTid, |
| prTspecParam->rTsInfo.ucDirection, prTspecParam->rTsInfo.ucApsd, |
| prTspecParam->rTsInfo.ucuserPriority, |
| prTspecParam->u2NominalMSDUSize, prTspecParam->u2MaxMSDUsize, |
| prTspecParam->u4MaxSvcIntv, prTspecParam->u4MinSvcIntv, |
| prTspecParam->u4InactIntv, prTspecParam->u4SpsIntv, |
| prTspecParam->u4SvcStartTime, prTspecParam->u4MinDataRate, |
| prTspecParam->u4MeanDataRate, prTspecParam->u4PeakDataRate, |
| prTspecParam->u4MaxBurstSize, prTspecParam->u4DelayBound, |
| prTspecParam->u4MinPHYRate, prTspecParam->u2Sba, |
| prTspecParam->u2MediumTime); |
| mboxSendMsg(prAdapter, MBOX_ID_0, (struct MSG_HDR *)prMsgTsOperate, |
| MSG_SEND_METHOD_BUF); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /* It's a Integretion Test function for RadioMeasurement. If you found errors |
| ** during doing Radio Measurement, |
| ** you can run this IT function with iwpriv wlan0 driver \"RM-IT |
| ** xx,xx,xx, xx\" |
| ** xx,xx,xx,xx is the RM request frame data |
| */ |
| uint32_t wlanoidPktProcessIT(struct ADAPTER *prAdapter, void *pvBuffer, |
| uint32_t u4BufferLen, uint32_t *pu4InfoLen) |
| { |
| struct SW_RFB rSwRfb; |
| static uint8_t aucPacket[200] = {0,}; |
| uint8_t *pucSavedPtr = (int8_t *)pvBuffer; |
| uint8_t *pucItem = NULL; |
| uint8_t j = 0; |
| int8_t i = 0; |
| uint8_t ucByte; |
| u_int8_t fgBTMReq = FALSE; |
| void (*process_func)(struct ADAPTER *prAdapter, |
| struct SW_RFB *prSwRfb); |
| |
| if (!pvBuffer) { |
| DBGLOG(OID, ERROR, "pvBuffer is NULL\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| if (!kalStrniCmp(pucSavedPtr, "RM-IT ", 6)) { |
| process_func = rlmProcessRadioMeasurementRequest; |
| pucSavedPtr += 6; |
| } else if (!kalStrniCmp(pucSavedPtr, "BTM-IT ", 7)) { |
| process_func = wnmRecvBTMRequest; |
| pucSavedPtr += 7; |
| fgBTMReq = TRUE; |
| } else { |
| pucSavedPtr[10] = 0; |
| DBGLOG(OID, ERROR, "IT type %s is not supported\n", |
| pucSavedPtr); |
| return WLAN_STATUS_NOT_SUPPORTED; |
| } |
| kalMemZero(aucPacket, sizeof(aucPacket)); |
| pucItem = strtok_r(pucSavedPtr, ",", (int8_t **)&pucSavedPtr); |
| while (pucItem) { |
| ucByte = *pucItem; |
| i = 0; |
| while (ucByte) { |
| if (i > 1) { |
| DBGLOG(OID, ERROR, |
| "more than 2 char for one byte\n"); |
| return WLAN_STATUS_FAILURE; |
| } else if (i == 1) |
| aucPacket[j] <<= 4; |
| if (ucByte >= '0' && ucByte <= '9') |
| aucPacket[j] |= ucByte - '0'; |
| else if (ucByte >= 'a' && ucByte <= 'f') |
| aucPacket[j] |= ucByte - 'a' + 10; |
| else if (ucByte >= 'A' && ucByte <= 'F') |
| aucPacket[j] |= ucByte - 'A' + 10; |
| else { |
| DBGLOG(OID, ERROR, "not a hex char %c\n", |
| ucByte); |
| return WLAN_STATUS_FAILURE; |
| } |
| ucByte = *(++pucItem); |
| i++; |
| } |
| j++; |
| pucItem = strtok_r(NULL, ",", (int8_t **)&pucSavedPtr); |
| } |
| DBGLOG(OID, INFO, "Dump IT packet, len %d\n", j); |
| dumpMemory8(aucPacket, j); |
| if (j < WLAN_MAC_MGMT_HEADER_LEN) { |
| DBGLOG(OID, ERROR, "packet length %d less than mac header 24\n", |
| j); |
| return WLAN_STATUS_FAILURE; |
| } |
| rSwRfb.pvHeader = (void *)&aucPacket[0]; |
| rSwRfb.u2PacketLen = j; |
| rSwRfb.u2HeaderLen = WLAN_MAC_MGMT_HEADER_LEN; |
| rSwRfb.ucStaRecIdx = KAL_NETWORK_TYPE_AIS_INDEX; |
| if (fgBTMReq) { |
| struct HW_MAC_RX_DESC rRxStatus; |
| |
| rSwRfb.prRxStatus = (struct HW_MAC_RX_DESC *)&rRxStatus; |
| rSwRfb.prRxStatus->ucChanFreq = 6; |
| wnmWNMAction(prAdapter, &rSwRfb); |
| } else { |
| process_func(prAdapter, &rSwRfb); |
| } |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| /* Firmware Integration Test functions |
| ** This function receives commands that are input by a firmware IT test script |
| ** By using IT test script, RD no need to run IT with a real Access Point |
| ** For example: iwpriv wlan0 driver \"Fw-Event Roaming ....\" |
| */ |
| uint32_t wlanoidFwEventIT(struct ADAPTER *prAdapter, void *pvBuffer, |
| uint32_t u4BufferLen, uint32_t *pu4InfoLen) |
| { |
| uint8_t *pucCmd = (int8_t *)pvBuffer; |
| |
| /* Firmware roaming Integration Test case */ |
| if (!kalStrniCmp(pucCmd, "Roaming", 7)) { |
| uint8_t ucRCPI = 0; |
| uint8_t ucFrameType = 0; |
| uint32_t i = 0; |
| struct CMD_INFO *prCmdInfo; |
| struct GLUE_INFO *prGlueInfo = prAdapter->prGlueInfo; |
| struct WLAN_ACTION_FRAME *prAction = NULL; |
| struct QUE_ENTRY *prEntry = NULL; |
| struct QUE_ENTRY *prPreEntry = NULL; |
| #if CFG_SUPPORT_ROAMING |
| struct CMD_ROAMING_TRANSIT rTransit = {0}; |
| #endif |
| GLUE_SPIN_LOCK_DECLARATION(); |
| #if CFG_SUPPORT_ROAMING |
| if (prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc) |
| rTransit.u2Data = prAdapter->rWifiVar.rAisFsmInfo |
| .prTargetBssDesc->ucRCPI; |
| rTransit.u2Event = ROAMING_EVENT_DISCOVERY; |
| rTransit.eReason = ROAMING_REASON_POOR_RCPI; |
| roamingFsmRunEventDiscovery(prAdapter, &rTransit); |
| #endif |
| /* Try to find the BTM query frame which is sent by |
| ** roamingFsmRunEventDiscovery |
| */ |
| GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); |
| for (prEntry = QUEUE_GET_HEAD(&prGlueInfo->rCmdQueue); |
| prEntry != NULL; prPreEntry = prEntry, |
| prEntry = QUEUE_GET_NEXT_ENTRY(&prCmdInfo->rQueEntry)) { |
| prCmdInfo = (struct CMD_INFO *)prEntry; |
| if (!prCmdInfo->prMsduInfo || |
| prCmdInfo->prMsduInfo->eSrc != TX_PACKET_MGMT || |
| !prCmdInfo->prMsduInfo->prPacket) |
| continue; |
| prAction = (struct WLAN_ACTION_FRAME *) |
| prCmdInfo->prMsduInfo->prPacket; |
| if (prAction->u2FrameCtrl != MAC_FRAME_ACTION) |
| continue; |
| if (prAction->ucCategory == CATEGORY_RM_ACTION && |
| prAction->ucAction == |
| ACTION_NEIGHBOR_REPORT_REQ) { |
| ucFrameType = 1; |
| break; |
| } |
| if (prAction->ucCategory == CATEGORY_WNM_ACTION && |
| prAction->ucAction == |
| ACTION_WNM_BSS_TRANSITION_MANAGEMENT_QUERY) { |
| ucFrameType = 2; |
| break; |
| } |
| } |
| if (prEntry) { |
| if (prPreEntry) { |
| prPreEntry->prNext = prEntry->prNext; |
| prGlueInfo->rCmdQueue.u4NumElem--; |
| } else |
| QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); |
| } |
| GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); |
| /* roamingFsmRunEventDiscovery has sent a btm query frame */ |
| if (ucFrameType == 2) { |
| struct ACTION_BTM_QUERY_FRAME *prBtmQuery = |
| (struct ACTION_BTM_QUERY_FRAME *)prAction; |
| |
| /* IT string may be "Roaming <btm request packet |
| ** string>", to reuse btm it function, |
| ** we need to replace Roaming with BTM-IT. Length of |
| ** Roaming is 7 bytes, so pucCmd |
| ** need to self add 1, and buffer length need to self |
| ** minus 1, and copy BTM-IT to pucCmd. |
| */ |
| pucCmd++; |
| u4BufferLen--; |
| kalMemCopy(pucCmd, "BTM-IT", 6); |
| |
| /* Find the diaglogToken string in <btm request packet |
| ** string>, it follows "BTM-IT ", whose length is 7 |
| */ |
| for (ucRCPI = 0, i = 7; i < u4BufferLen; i++) { |
| if (pucCmd[i] == ',') |
| ucRCPI++; |
| if (ucRCPI == |
| OFFSET_OF(struct ACTION_BTM_QUERY_FRAME, |
| ucDialogToken)) |
| break; |
| } |
| /* Replace diaglog token string with the token that is |
| ** in query frame |
| */ |
| ucRCPI = prBtmQuery->ucDialogToken; |
| ucFrameType = (ucRCPI >> 4) & 0xf; |
| if (ucFrameType > 9) |
| pucCmd[++i] = ucFrameType + 'a' - 10; |
| else |
| pucCmd[++i] = ucFrameType + '0'; |
| ucFrameType = ucRCPI & 0xf; |
| if (ucFrameType > 9) |
| pucCmd[++i] = ucFrameType + 'a' - 10; |
| else |
| pucCmd[++i] = ucFrameType + '0'; |
| wlanoidPktProcessIT(prAdapter, (void *)pucCmd, |
| u4BufferLen, pu4InfoLen); |
| } else if (ucFrameType == 1) { |
| /* Not support neighbor ap report request IT now */ |
| } |
| } else { |
| DBGLOG(OID, ERROR, "Not supported Fw Event IT type %s\n", |
| pucCmd); |
| return WLAN_STATUS_FAILURE; |
| } |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t wlanoidDumpUapsdSetting(struct ADAPTER *prAdapter, void *pvBuffer, |
| uint32_t u4BufferLen, uint32_t *pu4InfoLen) |
| { |
| uint8_t *pucCmd = (uint8_t *)pvBuffer; |
| uint8_t ucFinalSetting = 0; |
| uint8_t ucStaticSetting = 0; |
| struct PM_PROFILE_SETUP_INFO *prPmProf = NULL; |
| |
| if (!pvBuffer) { |
| DBGLOG(OID, ERROR, "pvBuffer is NULL\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| if (!prAdapter->prAisBssInfo) |
| return WLAN_STATUS_FAILURE; |
| prPmProf = &prAdapter->prAisBssInfo->rPmProfSetupInfo; |
| ucStaticSetting = |
| (prPmProf->ucBmpDeliveryAC << 4) | prPmProf->ucBmpTriggerAC; |
| ucFinalSetting = wmmCalculateUapsdSetting(prAdapter); |
| *pu4InfoLen = kalSnprintf( |
| pucCmd, u4BufferLen, |
| "\nStatic Uapsd Setting:0x%02x\nFinal Uapsd Setting:0x%02x", |
| ucStaticSetting, ucFinalSetting); |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| #if CFG_SUPPORT_OSHARE |
| uint32_t |
| wlanoidSetOshareMode(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| if (!prAdapter || !pvSetBuffer) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| DBGLOG(OID, TRACE, "wlanoidSetOshareMode\n"); |
| |
| return wlanSendSetQueryCmd(prAdapter, /* prAdapter */ |
| CMD_ID_SET_OSHARE_MODE, /* ucCID */ |
| TRUE, /* fgSetQuery */ |
| FALSE, /* fgNeedResp */ |
| g_fgIsOid, /* fgIsOid */ |
| nicCmdEventSetCommon, /* pfCmdDoneHandler*/ |
| nicOidCmdTimeoutCommon, /* pfCmdTimeoutHandler */ |
| u4SetBufferLen, /* u4SetQueryInfoLen */ |
| (uint8_t *) pvSetBuffer,/* pucInfoBuffer */ |
| NULL, /* pvSetQueryBuffer */ |
| 0); /* u4SetQueryBufferLen */ |
| } |
| #endif |
| |
| uint32_t |
| wlanoidQueryWifiLogLevelSupport(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_WIFI_LOG_LEVEL_UI *pparam; |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| pparam = (struct PARAM_WIFI_LOG_LEVEL_UI *) pvQueryBuffer; |
| pparam->u4Enable = wlanDbgLevelUiSupport(prAdapter, |
| pparam->u4Version, pparam->u4Module); |
| |
| DBGLOG(OID, INFO, "version: %d, module: %d, enable: %d\n", |
| pparam->u4Version, |
| pparam->u4Module, |
| pparam->u4Enable); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_WIFI_LOG_LEVEL_UI); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidQueryWifiLogLevel(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct PARAM_WIFI_LOG_LEVEL *pparam; |
| |
| ASSERT(prAdapter); |
| if (u4QueryBufferLen) |
| ASSERT(pvQueryBuffer); |
| ASSERT(pu4QueryInfoLen); |
| |
| pparam = (struct PARAM_WIFI_LOG_LEVEL *) pvQueryBuffer; |
| pparam->u4Level = wlanDbgGetLogLevelImpl(prAdapter, |
| pparam->u4Version, |
| pparam->u4Module); |
| |
| DBGLOG(OID, INFO, "version: %d, module: %d, level: %d\n", |
| pparam->u4Version, |
| pparam->u4Module, |
| pparam->u4Level); |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_WIFI_LOG_LEVEL_UI); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t |
| wlanoidSetWifiLogLevel(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct PARAM_WIFI_LOG_LEVEL *pparam; |
| |
| ASSERT(prAdapter); |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| pparam = (struct PARAM_WIFI_LOG_LEVEL *) pvSetBuffer; |
| |
| DBGLOG(OID, INFO, "version: %d, module: %d, level: %d\n", |
| pparam->u4Version, |
| pparam->u4Module, |
| pparam->u4Level); |
| |
| wlanDbgSetLogLevelImpl(prAdapter, |
| pparam->u4Version, |
| pparam->u4Module, |
| pparam->u4Level); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| |
| uint32_t wlanoidSetDrvSer(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| ASSERT(prAdapter); |
| |
| prAdapter->u4HifChkFlag |= HIF_DRV_SER; |
| kalSetHifDbgEvent(prAdapter->prGlueInfo); |
| |
| return 0; |
| } |
| |
| uint32_t wlanoidSetAmsduNum(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct mt66xx_chip_info *prChipInfo = NULL; |
| |
| ASSERT(prAdapter); |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| prChipInfo = prAdapter->chip_info; |
| prChipInfo->ucMaxSwAmsduNum = (uint8_t)*((uint32_t *)pvSetBuffer); |
| DBGLOG(OID, INFO, "Set SW AMSDU Num: %d\n", |
| prChipInfo->ucMaxSwAmsduNum); |
| return 0; |
| } |
| |
| uint32_t wlanoidSetAmsduSize(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct mt66xx_chip_info *prChipInfo = NULL; |
| struct WIFI_VAR *prWifiVar = NULL; |
| |
| ASSERT(prAdapter); |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| ASSERT(pu4SetInfoLen); |
| |
| prChipInfo = prAdapter->chip_info; |
| prWifiVar = &prAdapter->rWifiVar; |
| prWifiVar->u4TxMaxAmsduInAmpduLen = *((uint32_t *)pvSetBuffer); |
| DBGLOG(OID, INFO, "Set SW AMSDU max Size: %d\n", |
| prWifiVar->u4TxMaxAmsduInAmpduLen); |
| return 0; |
| } |
| |
| uint32_t |
| wlanoidShowPdmaInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| prAdapter->u4HifDbgFlag |= DEG_HIF_PDMA; |
| kalSetHifDbgEvent(prAdapter->prGlueInfo); |
| |
| return 0; |
| } |
| |
| uint32_t |
| wlanoidShowPseInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| prAdapter->u4HifDbgFlag |= DEG_HIF_PSE; |
| kalSetHifDbgEvent(prAdapter->prGlueInfo); |
| |
| return 0; |
| } |
| |
| uint32_t |
| wlanoidShowPleInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| prAdapter->u4HifDbgFlag |= DEG_HIF_PLE; |
| kalSetHifDbgEvent(prAdapter->prGlueInfo); |
| |
| return 0; |
| } |
| |
| uint32_t |
| wlanoidShowCsrInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| prAdapter->u4HifDbgFlag |= DEG_HIF_HOST_CSR; |
| kalSetHifDbgEvent(prAdapter->prGlueInfo); |
| |
| return 0; |
| } |
| |
| uint32_t |
| wlanoidShowDmaschInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| prAdapter->u4HifDbgFlag |= DEG_HIF_DMASCH; |
| kalSetHifDbgEvent(prAdapter->prGlueInfo); |
| |
| return 0; |
| } |
| |
| #if CFG_SUPPORT_LOWLATENCY_MODE |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to enable/disable low latency mode |
| * |
| * \param[in] prAdapter A pointer to the Adapter structure. |
| * \param[in] pvSetBuffer A pointer to the buffer that holds the |
| * OID-specific data to be set. |
| * \param[in] u4SetBufferLen The number of bytes the set buffer. |
| * \param[out] pu4SetInfoLen Points to the number of bytes it read or is |
| * needed |
| * \retval WLAN_STATUS_SUCCESS |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t wlanoidSetLowLatencyMode( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| u_int8_t fgEnMode = FALSE; /* Low Latency Mode */ |
| u_int8_t fgEnScan = FALSE; /* Scan management */ |
| u_int8_t fgEnPM = FALSE; /* Power management */ |
| uint32_t u4Events; |
| uint32_t u4PowerFlag; |
| struct PARAM_POWER_MODE_ rPowerMode; |
| struct WIFI_VAR *prWifiVar = NULL; |
| |
| DEBUGFUNC("wlanoidSetLowLatencyMode"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pvSetBuffer); |
| if (u4SetBufferLen != sizeof(uint32_t)) { |
| *pu4SetInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| ASSERT(pu4SetInfoLen); |
| |
| /* Initialize */ |
| prWifiVar = &prAdapter->rWifiVar; |
| kalMemCopy(&u4Events, pvSetBuffer, u4SetBufferLen); |
| DBGLOG(OID, INFO, |
| "LowLatency(gaming) event - gas:0x%x, net:0x%x, whitelist:0x%x, scan=%u, reorder=%u, power=%u\n", |
| (u4Events & GED_EVENT_GAS), |
| (u4Events & GED_EVENT_NETWORK), |
| (u4Events & GED_EVENT_DOPT_WIFI_SCAN), |
| (uint32_t)prWifiVar->ucLowLatencyModeScan, |
| (uint32_t)prWifiVar->ucLowLatencyModeReOrder, |
| (uint32_t)prWifiVar->ucLowLatencyModePower); |
| rPowerMode.ucBssIdx = prAdapter->prAisBssInfo->ucBssIndex; |
| u4PowerFlag = |
| prAdapter->rWlanInfo.u4PowerSaveFlag[rPowerMode.ucBssIdx]; |
| |
| /* Enable/disable low latency mode decision: |
| * |
| * Enable if it's GAS and network event |
| * and the Glue media state is connected. |
| */ |
| if ((u4Events & GED_EVENT_GAS) != 0 |
| && (u4Events & GED_EVENT_NETWORK) != 0 |
| && PARAM_MEDIA_STATE_CONNECTED |
| == kalGetMediaStateIndicated(prAdapter->prGlueInfo)) |
| fgEnMode = TRUE; /* It will enable low latency mode */ |
| |
| /* Enable/disable scan management decision: |
| * |
| * Enable if it will enable low latency mode. |
| * Or, enable if it is a white list event. |
| */ |
| if (fgEnMode != TRUE |
| || (u4Events & GED_EVENT_DOPT_WIFI_SCAN) != 0) |
| fgEnScan = TRUE; /* It will enable scan management */ |
| |
| /* Enable/disable power management decision: |
| */ |
| if (BIT(PS_CALLER_GPU) & u4PowerFlag) |
| fgEnPM = TRUE; |
| else |
| fgEnPM = FALSE; |
| |
| /* Debug log for the actions */ |
| if (fgEnMode != prAdapter->fgEnLowLatencyMode |
| || fgEnScan != prAdapter->fgEnCfg80211Scan |
| || fgEnPM != fgEnMode) { |
| DBGLOG(OID, INFO, |
| "LowLatency(gaming) change (m:%d,s:%d,PM:%d,F:0x%x)\n", |
| fgEnMode, fgEnScan, fgEnPM, u4PowerFlag); |
| } |
| |
| /* Scan management: |
| * |
| * Disable/enable scan |
| */ |
| if ((prWifiVar->ucLowLatencyModeScan == FEATURE_ENABLED) && |
| (fgEnScan != prAdapter->fgEnCfg80211Scan)) |
| prAdapter->fgEnCfg80211Scan = fgEnScan; |
| |
| if ((prWifiVar->ucLowLatencyModeReOrder == FEATURE_ENABLED) && |
| (fgEnMode != prAdapter->fgEnLowLatencyMode)) { |
| prAdapter->fgEnLowLatencyMode = fgEnMode; |
| |
| /* Queue management: |
| * |
| * Change QM RX BA timeout if the gaming mode state changed |
| */ |
| if (fgEnMode) { |
| prAdapter->u4QmRxBaMissTimeout |
| = QM_RX_BA_ENTRY_MISS_TIMEOUT_MS_SHORT; |
| } else { |
| prAdapter->u4QmRxBaMissTimeout |
| = QM_RX_BA_ENTRY_MISS_TIMEOUT_MS; |
| } |
| } |
| |
| /* Power management: |
| * |
| * Set power saving mode profile to FW |
| * |
| * Do if 1. the power saving caller including GPU |
| * and 2. it will disable low latency mode. |
| * Or, do if 1. the power saving caller is not including GPU |
| * and 2. it will enable low latency mode. |
| */ |
| if ((prWifiVar->ucLowLatencyModePower == FEATURE_ENABLED) && |
| (fgEnPM != fgEnMode)) { |
| if (fgEnMode == TRUE) |
| rPowerMode.ePowerMode = Param_PowerModeCAM; |
| else |
| rPowerMode.ePowerMode = Param_PowerModeFast_PSP; |
| |
| nicConfigPowerSaveProfile(prAdapter, rPowerMode.ucBssIdx, |
| rPowerMode.ePowerMode, FALSE, PS_CALLER_GPU); |
| } |
| |
| *pu4SetInfoLen = 0; /* We do not need to read */ |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif /* CFG_SUPPORT_LOWLATENCY_MODE */ |
| |
| uint32_t |
| wlanoidGetIpiInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| |
| struct PARAM_GET_IPI_INFO_T *prCmdGetIpiInfo; |
| |
| *pu4QueryInfoLen = sizeof(struct PARAM_GET_IPI_INFO_T); |
| |
| if (u4QueryBufferLen < sizeof(struct PARAM_GET_IPI_INFO_T)) { |
| DBGLOG(REQ, WARN, "Too short length %u\n", |
| u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } |
| |
| prCmdGetIpiInfo = (struct PARAM_GET_IPI_INFO_T *)pvQueryBuffer; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_IPI_INFO, |
| TRUE, |
| FALSE, |
| g_fgIsOid, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_GET_IPI_INFO_T), |
| (uint8_t *) prCmdGetIpiInfo, |
| pvQueryBuffer, u4QueryBufferLen); |
| } |
| |
| #ifdef CFG_GET_TEMPURATURE |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief This routine is called to get die temperature. |
| * |
| * \param[in] pvAdapter Pointer to the Adapter structure. |
| * \param[out] pvQueryBuf A pointer to the buffer that holds the result of |
| * the query (temperature) |
| * \param[in] u4QueryBufLen The length of the query buffer (integer: 4 bytes) |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer, |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| |
| uint32_t |
| wlanoidGetTemperature(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| struct CMD_THERMAL_SENSOR_INFO rThermalInfo; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| |
| if (!prAdapter || !pvQueryBuffer || !pu4QueryInfoLen) |
| return WLAN_STATUS_INVALID_DATA; |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(int)) { |
| DBGLOG(REQ, WARN, "Too short length %ld\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } else if (prAdapter->fgTestMode == TRUE) { |
| /*DBGLOG(REQ, WARN, "Not supported in Test Mode\n");*/ |
| return WLAN_STATUS_NOT_SUPPORTED; |
| } |
| kalMemSet(&rThermalInfo, 0, |
| sizeof(struct CMD_THERMAL_SENSOR_INFO)); |
| |
| rThermalInfo.u1ThermalCtrlFormatId = THERMAL_SENSOR_INFO_GET; |
| rThermalInfo.u1ActionIdx = THERMAL_SENSOR_INFO_TEMPERATURE; |
| |
| |
| /* Not necessary to use : CMD_ID_GET_TEMPERATURE * |
| * Use new THERMAL SENSOR service instead * |
| */ |
| rWlanStatus = wlanSendSetQueryExtCmd(prAdapter, |
| CMD_ID_LAYER_0_EXT_MAGIC_NUM, |
| EXT_CMD_ID_GET_SENSOR_RESULT, |
| FALSE, /* Query Bit: True->write False->read */ |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventGetTemperature, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_THERMAL_SENSOR_INFO), |
| (uint8_t *) (&rThermalInfo), |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| return rWlanStatus; |
| } |
| #endif |
| |
| |
| #if CFG_SUPPORT_ANT_DIV |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief antenna diversity config |
| * |
| * \param[in] prAdapter Pointer to the Adapter structure. |
| * \param[in] pvQueryBuffer Pointer to the buffer that holds the result of |
| * the query. |
| * \param[in] u4QueryBufferLen The length of the query buffer. |
| * \param[out] pu4QueryInfoLen If the call is successful, returns the number of |
| * bytes written into the query buffer. If the call |
| * failed due to invalid length of the query buffer |
| * returns the amount of storage needed. |
| * |
| * \retval WLAN_STATUS_SUCCESS |
| * \retval WLAN_STATUS_BUFFER_TOO_SHORT |
| * \retval WLAN_STATUS_NOT_SUPPORTED |
| * \retval WLAN_STATUS_NOT_ACCEPTED |
| * \retval WLAN_STATUS_INVALID_LENGTH |
| */ |
| /*----------------------------------------------------------------------------*/ |
| uint32_t |
| wlanoidAntDivCfg(IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) |
| { |
| struct CMD_ANT_DIV_CTRL *prAntDivInfo; |
| uint32_t rWlanStatus = WLAN_STATUS_SUCCESS; |
| u_int8_t fgSetQuery = TRUE; |
| u_int8_t fgNeedResp = FALSE; |
| |
| DEBUGFUNC("wlanoidSetAntDiv"); |
| if (prAdapter == NULL) |
| return -EFAULT; |
| if (pu4SetInfoLen == NULL) |
| return -EFAULT; |
| if (pvSetBuffer == NULL) |
| return -EFAULT; |
| |
| *pu4SetInfoLen = sizeof(struct CMD_ANT_DIV_CTRL); |
| if (u4SetBufferLen < sizeof(struct CMD_ANT_DIV_CTRL)) |
| return WLAN_STATUS_INVALID_LENGTH; |
| |
| prAntDivInfo = (struct CMD_ANT_DIV_CTRL *) pvSetBuffer; |
| |
| /* GET need to wait for response from FW module */ |
| switch (prAntDivInfo->ucAction) { |
| case ANT_DIV_CMD_GET_ANT: |
| case ANT_DIV_CMD_DETC: |
| fgSetQuery = FALSE; |
| fgNeedResp = TRUE; |
| break; |
| case ANT_DIV_CMD_SWH: |
| fgSetQuery = TRUE; |
| fgNeedResp = TRUE; |
| break; |
| case ANT_DIV_CMD_SET_ANT: |
| fgSetQuery = TRUE; |
| fgNeedResp = FALSE; |
| break; |
| default: |
| DBGLOG(REQ, WARN, "don't support action = %d\n", |
| prAntDivInfo->ucAction); |
| return WLAN_STATUS_INVALID_DATA; |
| break; |
| } |
| |
| rWlanStatus = wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_ANT_DIV_CTRL, |
| fgSetQuery, |
| fgNeedResp, |
| g_fgIsOid, |
| nicCmdEventAntDiv, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_ANT_DIV_CTRL), |
| (uint8_t *) prAntDivInfo, |
| pvSetBuffer, u4SetBufferLen); |
| |
| return rWlanStatus; |
| } |
| #endif |
| #if (CFG_SUPPORT_GET_MCS_INFO == 1) |
| uint32_t |
| wlanoidTxQueryMcsInfo(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) |
| { |
| struct PARAM_TX_MCS_INFO *prMcsInfo; |
| |
| DEBUGFUNC("wlanoidQueryWlanInfo"); |
| |
| if (prAdapter->rAcpiState == ACPI_STATE_D3) { |
| DBGLOG(REQ, WARN, |
| "Adapter not ready. ACPI=D%d, Radio=%d\n", |
| prAdapter->rAcpiState, prAdapter->fgIsRadioOff); |
| *pu4QueryInfoLen = sizeof(uint32_t); |
| return WLAN_STATUS_ADAPTER_NOT_READY; |
| } else if (u4QueryBufferLen < sizeof(int)) { |
| DBGLOG(REQ, WARN, "Too short length %ld\n", u4QueryBufferLen); |
| return WLAN_STATUS_INVALID_LENGTH; |
| } else if (prAdapter->fgTestMode == TRUE) { |
| /*DBGLOG(REQ, WARN, "Not supported in Test Mode\n");*/ |
| return WLAN_STATUS_NOT_SUPPORTED; |
| } |
| |
| if (prAdapter->prAisBssInfo->prStaRecOfAP == NULL) |
| return WLAN_STATUS_FAILURE; |
| |
| prMcsInfo = (struct PARAM_TX_MCS_INFO *)pvQueryBuffer; |
| prMcsInfo->ucStaIndex = prAdapter->prAisBssInfo->prStaRecOfAP->ucIndex; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TX_MCS_INFO, |
| FALSE, |
| TRUE, |
| g_fgIsOid, |
| nicCmdEventQueryTxMcsInfo, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct PARAM_TX_MCS_INFO), |
| (uint8_t *) prMcsInfo, |
| pvQueryBuffer, u4QueryBufferLen); |
| } |
| #endif |
| |
| #ifdef CFG_SUPPORT_TIME_MEASURE |
| uint32_t wlanoidQueryStartFtm( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen |
| ) |
| { |
| struct CMD_TM_ACTION_T rCmdTmAction; |
| struct PARAM_TM_T *prTmrParam; |
| uint8_t fgNeedResp = FALSE; |
| |
| DEBUGFUNC("wlanoidQueryStartFtm"); |
| |
| if (prAdapter == NULL) |
| return -EFAULT; |
| if (pu4QueryInfoLen == NULL) |
| return -EFAULT; |
| if ((u4QueryBufferLen > 0) && (pvQueryBuffer == NULL)) |
| return -EFAULT; |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_TM_ACTION_T); |
| prTmrParam = (struct PARAM_TM_T *)pvQueryBuffer; |
| |
| rCmdTmAction.ucTmCategory = TM_ACTION_START_FTM; |
| rCmdTmAction.ucCmdVer = TM_CMD_EVENT_VER; |
| rCmdTmAction.u2CmdLen = CMD_TM_ACTION_START_FTM_LEN; |
| if (prTmrParam->ucFTMNum != 0 && prTmrParam->ucMinDeltaIn100US != 0 && |
| prTmrParam->ucFTMBandwidth != 0) { |
| COPY_MAC_ADDR(rCmdTmAction.aucRttPeerAddr, |
| prTmrParam->aucRttPeerAddr); |
| rCmdTmAction.ucFTMNum = prTmrParam->ucFTMNum; |
| rCmdTmAction.ucMinDeltaIn100US = prTmrParam->ucMinDeltaIn100US; |
| rCmdTmAction.ucFTMBandwidth = prTmrParam->ucFTMBandwidth; |
| fgNeedResp = (prTmrParam->u4DistanceCm == 0); |
| } |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TMR_ACTION, |
| TRUE, |
| fgNeedResp, |
| TRUE, |
| nicCmdEventGetTmReport, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TM_ACTION_T), |
| (uint8_t *)&rCmdTmAction, |
| pvQueryBuffer, u4QueryBufferLen); |
| } |
| |
| uint32_t wlanoidQueryFtm( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, |
| IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen |
| ) |
| { |
| struct CMD_TM_ACTION_T rCmdTmAction; |
| struct PARAM_TM_T *prTmrParam; |
| #if KERNEL_VERSION(4, 20, 0) <= LINUX_VERSION_CODE |
| struct timespec64 Ftmtv_raw; |
| #else |
| struct timespec Ftmtv_raw; |
| #endif |
| |
| DEBUGFUNC("wlanoidQueryStartFtm"); |
| |
| if (prAdapter == NULL) |
| return -EFAULT; |
| if (pu4QueryInfoLen == NULL) |
| return -EFAULT; |
| if ((u4QueryBufferLen > 0) && (pvQueryBuffer == NULL)) |
| return -EFAULT; |
| |
| *pu4QueryInfoLen = sizeof(struct CMD_TM_ACTION_T); |
| prTmrParam = (struct PARAM_TM_T *)pvQueryBuffer; |
| |
| rCmdTmAction.ucTmCategory = prTmrParam->ucTmCategory; |
| rCmdTmAction.ucCmdVer = TM_CMD_EVENT_VER; |
| rCmdTmAction.u2CmdLen = CMD_TM_ACTION_QUERY_LEN; |
| |
| #if KERNEL_VERSION(4, 20, 0) <= LINUX_VERSION_CODE |
| ktime_get_raw_ts64(&Ftmtv_raw); |
| #else |
| getrawmonotonic(&Ftmtv_raw); |
| #endif |
| |
| /* gpio_set_value(A1, 1); */ |
| /* gpio_set_value(A1, 0); */ |
| g_u8LastSysClkps = g_u8SysClkps; |
| g_u8SysClkps = (uint64_t)(Ftmtv_raw.tv_sec * 1000000000LL |
| + Ftmtv_raw.tv_nsec) * 1000; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TMR_ACTION, |
| TRUE, |
| TRUE, |
| TRUE, |
| nicCmdEventGetTmReport, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TM_ACTION_T), |
| (uint8_t *)&rCmdTmAction, |
| pvQueryBuffer, u4QueryBufferLen); |
| } |
| |
| uint32_t wlanoidSetEnableTmr( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen |
| ) |
| { |
| struct CMD_TM_ACTION_T rCmdTmAction; |
| struct PARAM_TM_T *prTmrParam; |
| |
| DEBUGFUNC("wlanoidSetEnableTmr"); |
| |
| if (prAdapter == NULL) |
| return -EFAULT; |
| if (pu4SetInfoLen == NULL) |
| return -EFAULT; |
| if ((u4SetBufferLen > 0) && (pvSetBuffer == NULL)) |
| return -EFAULT; |
| |
| *pu4SetInfoLen = sizeof(struct CMD_TM_ACTION_T); |
| prTmrParam = (struct PARAM_TM_T *)pvSetBuffer; |
| |
| rCmdTmAction.ucTmCategory = TM_ACTION_TMR_ENABLE; |
| rCmdTmAction.ucCmdVer = TM_CMD_EVENT_VER; |
| rCmdTmAction.u2CmdLen = CMD_TM_ACTION_START_FTM_LEN; |
| rCmdTmAction.fgFtmEnable = prTmrParam->fgFtmEnable; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_TMR_ACTION, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventGetTmReport, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TM_ACTION_T), |
| (uint8_t *)&rCmdTmAction, |
| pvSetBuffer, u4SetBufferLen); |
| } |
| #endif |
| |
| #if CFG_SUPPORT_MDNS_OFFLOAD |
| uint32_t |
| wlanoidSetMdnsCmdToFw( |
| IN struct ADAPTER *prAdapter, |
| IN void *pvSetBuffer, |
| IN uint32_t u4SetBufferLen, |
| OUT uint32_t *pu4SetInfoLen) { |
| struct CMD_MDNS_PARAM_T *cmdMdnsParam; |
| |
| DEBUGFUNC("wlanoidSetMdnsCmdToFw"); |
| |
| ASSERT(prAdapter); |
| ASSERT(pu4SetInfoLen); |
| |
| *pu4SetInfoLen = sizeof(struct CMD_MDNS_PARAM_T); |
| |
| if (u4SetBufferLen) |
| ASSERT(pvSetBuffer); |
| |
| cmdMdnsParam = (struct CMD_MDNS_PARAM_T *) |
| pvSetBuffer; |
| |
| DBGLOG(SW4, STATE, "set cmd %u.\n", cmdMdnsParam->ucCmd); |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_SET_MDNS_RECORD, |
| TRUE, |
| FALSE, |
| TRUE, |
| nicCmdEventSetCommon, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_MDNS_PARAM_T), |
| (uint8_t *)cmdMdnsParam, |
| NULL, |
| 0); |
| } |
| #endif |
| |
| #if IS_ENABLED(CFG_AP_80211K_SUPPORT) |
| uint32_t wlanoidSendBeaconReportRequest(struct ADAPTER *prAdapter, |
| void *pvSetBuffer, |
| uint32_t u4SetBufferLen, |
| uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo = NULL; |
| uint8_t ucRoleIdx = 0; |
| uint8_t ucBssIdx = 0; |
| struct BSS_INFO *prBssInfo = NULL; |
| struct STA_RECORD *prStaRec = NULL; |
| struct SUB_ELEMENT_LIST *prIE = NULL; |
| struct IE_MEASUREMENT_REQ *prMeasureReqIE = NULL; |
| struct RM_BCN_REQ *prBeaconReqIE = NULL; |
| struct IE_SSID *prSSIDIe = NULL; |
| struct SUB_IE_BEACON_REPORTING *prBcnReport = NULL; |
| struct SUB_IE_REPORTING_DETAIL *prReportDetail = NULL; |
| struct SUB_IE_REQUEST *prRequest = NULL; |
| struct SUB_IE_AP_CHANNEL_REPORT *prAPChanReport = NULL; |
| uint8_t *prTmpElem = NULL; |
| uint8_t ucIELen = 0; |
| uint8_t ucSsidLen = 0; |
| struct PARAM_CUSTOM_BCN_REP_REQ_STRUCT *prSetBcnRepReqInfo = NULL; |
| |
| if (!prAdapter) |
| return WLAN_STATUS_INVALID_DATA; |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| /* check parameter */ |
| if (pvSetBuffer == NULL |
| || u4SetBufferLen != |
| sizeof(struct PARAM_CUSTOM_BCN_REP_REQ_STRUCT)) { |
| DBGLOG(REQ, WARN, "need BCN Rep Req Info\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| prSetBcnRepReqInfo = |
| (struct PARAM_CUSTOM_BCN_REP_REQ_STRUCT *) pvSetBuffer; |
| |
| /* get Bss Index from ndev */ |
| if (mtk_Netdev_To_RoleIdx(prGlueInfo, |
| prGlueInfo->prP2PInfo[1]->prDevHandler, |
| &ucRoleIdx) != 0) |
| return WLAN_STATUS_FAILURE; |
| if (p2pFuncRoleToBssIdx(prAdapter, ucRoleIdx, &ucBssIdx) |
| != WLAN_STATUS_SUCCESS) |
| return WLAN_STATUS_FAILURE; |
| DBGLOG(REQ, INFO, "ucRoleIdx = %d\n", ucRoleIdx); |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); |
| if (!prBssInfo) { |
| DBGLOG(REQ, WARN, "bss is not active\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| /* get Station Record */ |
| prStaRec = bssGetClientByMac(prAdapter, |
| prBssInfo, |
| prSetBcnRepReqInfo->aucPeerMac); |
| if (prStaRec == NULL) { |
| DBGLOG(REQ, WARN, "can't find station\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prStaRec->u2BcnReqRepetition = prSetBcnRepReqInfo->u2Repetition; |
| |
| /* allocate IE memory */ |
| ucIELen = sizeof(*prIE) + 3 |
| + sizeof(*prBeaconReqIE) |
| + sizeof(*prBcnReport) |
| + sizeof(*prReportDetail); |
| if (kalStrLen(prSetBcnRepReqInfo->aucSsid)) |
| ucIELen += sizeof(*prSSIDIe); |
| |
| if (prSetBcnRepReqInfo->ucReportingDetail == 1) |
| ucIELen += sizeof(*prRequest); |
| |
| if (prSetBcnRepReqInfo->ucChannel == 255) |
| ucIELen += sizeof(*prAPChanReport); |
| |
| prIE = kalMemAlloc(ucIELen, PHY_MEM_TYPE); |
| if (!prIE) { |
| DBGLOG(OID, ERROR, "No Memory\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| prIE->prNext = NULL; |
| prMeasureReqIE = (struct IE_MEASUREMENT_REQ *) &prIE->rSubIE; |
| prBeaconReqIE = |
| (struct RM_BCN_REQ *) &prMeasureReqIE->aucRequestFields[0]; |
| |
| /* beacon request ie */ |
| prBeaconReqIE->ucRegulatoryClass = prSetBcnRepReqInfo->ucOperClass; |
| prBeaconReqIE->ucChannel = prSetBcnRepReqInfo->ucChannel; |
| prBeaconReqIE->u2RandomInterval = prSetBcnRepReqInfo->u2RandomInterval; |
| prBeaconReqIE->u2Duration = prSetBcnRepReqInfo->u2MeasureDuration; |
| prBeaconReqIE->ucMeasurementMode = |
| prSetBcnRepReqInfo->ucMeasurementMode; |
| COPY_MAC_ADDR(prBeaconReqIE->aucBssid, prSetBcnRepReqInfo->aucBssid); |
| |
| prTmpElem = &prBeaconReqIE->aucSubElements[0]; |
| /* ssid ie */ |
| if (kalStrLen(prSetBcnRepReqInfo->aucSsid)) { |
| prSSIDIe = (struct IE_SSID *) prTmpElem; |
| prSSIDIe->ucId = BCN_REQ_ELEM_SUBID_SSID; |
| ucSsidLen = kalStrLen(prSetBcnRepReqInfo->aucSsid); |
| prSSIDIe->ucLength = ucSsidLen; |
| if (ucSsidLen > ELEM_MAX_LEN_SSID) { |
| DBGLOG(REQ, WARN, "ssid length %u is too long\n", |
| ucSsidLen); |
| kalMemFree(prIE, PHY_MEM_TYPE, ucIELen); |
| return WLAN_STATUS_FAILURE; |
| } |
| kalMemCopy(&prSSIDIe->aucSSID, |
| &prSetBcnRepReqInfo->aucSsid, |
| ucSsidLen); |
| prTmpElem += (2 + prSSIDIe->ucLength); |
| } |
| |
| /* Beacon Report information */ |
| prBcnReport = (struct SUB_IE_BEACON_REPORTING *) prTmpElem; |
| prBcnReport->ucId = BCN_REQ_ELEM_SUBID_BEACON_REPORTING; |
| prBcnReport->ucLength = 2; |
| prBcnReport->ucReportingCond = prSetBcnRepReqInfo->ucReportCondition; |
| prBcnReport->ucReportingRef = prSetBcnRepReqInfo->ucReportReference; |
| prTmpElem += (2 + prBcnReport->ucLength); |
| |
| /* Reporting detail ie */ |
| prReportDetail = (struct SUB_IE_REPORTING_DETAIL *) prTmpElem; |
| prReportDetail->ucSubID = BCN_REQ_ELEM_SUBID_REPORTING_DETAIL; |
| prReportDetail->ucLength = 1; |
| prReportDetail->ucDetailValue = prSetBcnRepReqInfo->ucReportingDetail; |
| prTmpElem += (2 + prReportDetail->ucLength); |
| |
| /* Request */ |
| if (prSetBcnRepReqInfo->ucReportingDetail == 1) { |
| prRequest = (struct SUB_IE_REQUEST *) prTmpElem; |
| prRequest->ucId = BCN_REQ_ELEM_SUBID_REQUEST; |
| prRequest->ucLength = prSetBcnRepReqInfo->ucNumberOfRequest; |
| kalMemCopy(prRequest->aucElems, |
| prSetBcnRepReqInfo->ucRequestElemList, |
| prSetBcnRepReqInfo->ucNumberOfRequest); |
| prTmpElem += (2 + prRequest->ucLength); |
| } |
| |
| /* AP Channel Report ie */ |
| if (prSetBcnRepReqInfo->ucChannel == 255) { |
| prAPChanReport = (struct SUB_IE_AP_CHANNEL_REPORT *) prTmpElem; |
| prAPChanReport->ucId = BCN_REQ_ELEM_SUBID_AP_CHANNEL_REPORT; |
| prAPChanReport->ucLength = |
| 1 + prSetBcnRepReqInfo->ucNumberOfAPChanReport; |
| prAPChanReport->ucOpClass = prSetBcnRepReqInfo->ucOperClass; |
| kalMemCopy(prAPChanReport->aucElems, |
| prSetBcnRepReqInfo->ucChanList, |
| prSetBcnRepReqInfo->ucNumberOfAPChanReport); |
| } |
| |
| /* measurement ie */ |
| prMeasureReqIE->ucId = ELEM_ID_MEASUREMENT_REQ; |
| prMeasureReqIE->ucLength = |
| 3 + OFFSET_OF(struct RM_BCN_REQ, aucSubElements); |
| |
| if (kalStrLen(prSetBcnRepReqInfo->aucSsid)) |
| prMeasureReqIE->ucLength += (2 + prSSIDIe->ucLength); |
| |
| prMeasureReqIE->ucLength += (2 + prBcnReport->ucLength); |
| prMeasureReqIE->ucLength += (2 + prReportDetail->ucLength); |
| |
| if (prSetBcnRepReqInfo->ucReportingDetail == 1) |
| prMeasureReqIE->ucLength += (2 + prRequest->ucLength); |
| |
| if (prSetBcnRepReqInfo->ucChannel == 255) |
| prMeasureReqIE->ucLength += (2 + prAPChanReport->ucLength); |
| |
| prMeasureReqIE->ucToken = 0; |
| prMeasureReqIE->ucRequestMode = 0; |
| prMeasureReqIE->ucMeasurementType = ELEM_RM_TYPE_BEACON_REQ; |
| |
| DBGLOG(OID, INFO, "Send Beacon Report Request\n"); |
| rlmTxMeasurementRequest(prAdapter, prStaRec, prIE); |
| |
| kalMemFree(prIE, PHY_MEM_TYPE, ucIELen); |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif /* CFG_AP_80211K_SUPPORT */ |
| |
| #if IS_ENABLED(CFG_AP_80211V_SUPPORT) |
| uint32_t wlanoidSendBTMRequest(struct ADAPTER *prAdapter, |
| void *pvSetBuffer, uint32_t u4SetBufferLen, |
| uint32_t *pu4SetInfoLen) |
| { |
| struct GLUE_INFO *prGlueInfo = NULL; |
| uint8_t ucRoleIdx = 0; |
| uint8_t ucBssIdx = 0; |
| struct BSS_INFO *prBssInfo = NULL; |
| struct STA_RECORD *prStaRec = NULL; |
| struct PARAM_CUSTOM_BTM_REQ_STRUCT *prSetBtmReqInfo = NULL; |
| |
| if (!prAdapter) |
| return WLAN_STATUS_INVALID_DATA; |
| prGlueInfo = prAdapter->prGlueInfo; |
| |
| /* check parameter */ |
| if (pvSetBuffer == NULL |
| || u4SetBufferLen |
| != sizeof(struct PARAM_CUSTOM_BTM_REQ_STRUCT)) { |
| DBGLOG(REQ, WARN, "need BTM Req Info\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| prSetBtmReqInfo = (struct PARAM_CUSTOM_BTM_REQ_STRUCT *) pvSetBuffer; |
| |
| /* get Bss Index from ndev */ |
| if (mtk_Netdev_To_RoleIdx(prGlueInfo, |
| prGlueInfo->prP2PInfo[1]->prDevHandler, |
| &ucRoleIdx) != 0) |
| return WLAN_STATUS_FAILURE; |
| if (p2pFuncRoleToBssIdx(prAdapter, ucRoleIdx, &ucBssIdx) |
| != WLAN_STATUS_SUCCESS) |
| return WLAN_STATUS_FAILURE; |
| DBGLOG(REQ, INFO, "ucRoleIdx = %d\n", ucRoleIdx); |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx); |
| if (!prBssInfo) { |
| DBGLOG(REQ, WARN, "bss is not active\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| /* get Station Record */ |
| prStaRec = bssGetClientByMac(prAdapter, |
| prBssInfo, |
| prSetBtmReqInfo->aucPeerMac); |
| if (prStaRec == NULL) { |
| DBGLOG(REQ, WARN, "can't find station\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| DBGLOG(OID, INFO, "Send BTM Request\n"); |
| wnmSendBTMRequestFrame(prGlueInfo->prAdapter, |
| prStaRec, prSetBtmReqInfo); |
| |
| return WLAN_STATUS_SUCCESS; |
| } |
| #endif /* CFG_AP_80211V_SUPPORT */ |
| |
| #if (CFG_SUPPORT_TSF_SYNC == 1) |
| uint32_t |
| wlanoidLatchTSF(IN struct ADAPTER *prAdapter, |
| IN void *pvQueryBuffer, IN uint32_t u4QueryBufferLen, |
| OUT uint32_t *pu4QueryInfoLen) { |
| struct CMD_TSF_SYNC *prCmdTSF; |
| |
| DEBUGFUNC("wlanoidLatchTSF"); |
| |
| if (!prAdapter) { |
| DBGLOG(REQ, WARN, "NULL prAdapter!\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| if (!pvQueryBuffer) { |
| DBGLOG(REQ, WARN, "NULL pvQueryBuffer!\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| if (!pu4QueryInfoLen) { |
| DBGLOG(REQ, WARN, "NULL pu4QueryInfoLen!\n"); |
| return WLAN_STATUS_FAILURE; |
| } |
| |
| prCmdTSF = (struct CMD_TSF_SYNC *)pvQueryBuffer; |
| |
| return wlanSendSetQueryCmd(prAdapter, |
| CMD_ID_BEACON_TSF_SYNC, |
| FALSE, |
| TRUE, |
| TRUE, |
| nicCmdEventLatchTSF, |
| nicOidCmdTimeoutCommon, |
| sizeof(struct CMD_TSF_SYNC), |
| (uint8_t *) pvQueryBuffer, |
| pvQueryBuffer, |
| u4QueryBufferLen); |
| |
| } /* end of wlanoidLatchTSF() */ |
| #endif |
| |