| /****************************************************************************** |
| * |
| * 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: @(#) gl_p2p_cfg80211.c@@ |
| */ |
| |
| /*! \file gl_p2p_kal.c |
| * \brief |
| * |
| */ |
| |
| /******************************************************************************* |
| * 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 "net/cfg80211.h" |
| #include "precomp.h" |
| #include "gl_wext.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 |
| ******************************************************************************** |
| */ |
| |
| /******************************************************************************* |
| * 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 |
| ******************************************************************************** |
| */ |
| |
| struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo); |
| |
| /******************************************************************************* |
| * F U N C T I O N S |
| ******************************************************************************** |
| */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to retrieve Wi-Fi Direct state from glue layer |
| * |
| * \param[in] |
| * prGlueInfo |
| * rPeerAddr |
| * \return |
| * ENUM_BOW_DEVICE_STATE |
| */ |
| /*----------------------------------------------------------------------------*/ |
| #if 0 |
| ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo) |
| { |
| ASSERT(prGlueInfo); |
| |
| return prGlueInfo->prP2PInfo[0]->eState; |
| } /* end of kalP2PGetState() */ |
| #endif |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to update the assoc req to p2p |
| * |
| * \param[in] |
| * prGlueInfo |
| * pucFrameBody |
| * u4FrameBodyLen |
| * fgReassocRequest |
| * \return |
| * none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID |
| kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, |
| IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest, IN UINT_8 ucBssIndex) |
| { |
| P_BSS_INFO_T prBssInfo; |
| union iwreq_data wrqu; |
| unsigned char *pucExtraInfo = NULL; |
| unsigned char *pucDesiredIE = NULL; |
| /* unsigned char aucExtraInfoBuf[200]; */ |
| PUINT_8 cp; |
| struct net_device *prNetdevice = (struct net_device *)NULL; |
| |
| memset(&wrqu, 0, sizeof(wrqu)); |
| |
| if (fgReassocRequest) { |
| if (u4FrameBodyLen < 15) { |
| /* |
| * printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); |
| */ |
| return; |
| } |
| } else { |
| if (u4FrameBodyLen < 9) { |
| /* |
| * printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); |
| */ |
| return; |
| } |
| } |
| |
| cp = pucFrameBody; |
| |
| if (fgReassocRequest) { |
| /* Capability information field 2 */ |
| /* Listen interval field 2 */ |
| /* Current AP address 6 */ |
| cp += 10; |
| u4FrameBodyLen -= 10; |
| } else { |
| /* Capability information field 2 */ |
| /* Listen interval field 2 */ |
| cp += 4; |
| u4FrameBodyLen -= 4; |
| } |
| |
| /* do supplicant a favor, parse to the start of WPA/RSN IE */ |
| if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { |
| /* printk("wextSrchDesiredWPSIE!!\n"); */ |
| /* WPS IE found */ |
| } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0x30, &pucDesiredIE)) { |
| /* printk("wextSrchDesiredWPAIE!!\n"); */ |
| /* RSN IE found */ |
| } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { |
| /* printk("wextSrchDesiredWPAIE!!\n"); */ |
| /* WPA IE found */ |
| } else { |
| /* no WPA/RSN IE found, skip this event */ |
| return; |
| } |
| |
| /* IWEVASSOCREQIE, indicate binary string */ |
| pucExtraInfo = pucDesiredIE; |
| wrqu.data.length = pucDesiredIE[1] + 2; |
| |
| prBssInfo = GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, ucBssIndex); |
| |
| if (ucBssIndex == P2P_DEV_BSS_INDEX) |
| prNetdevice = prGlueInfo->prP2PInfo[prBssInfo->u4PrivateData]->prDevHandler; |
| else |
| prNetdevice = prGlueInfo->prP2PInfo[prBssInfo->u4PrivateData]->aprRoleHandler; |
| |
| /* Send event to user space */ |
| wireless_send_event(prNetdevice, IWEVASSOCREQIE, &wrqu, pucExtraInfo); |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to set Wi-Fi Direct state in glue layer |
| * |
| * \param[in] |
| * prGlueInfo |
| * eBowState |
| * rPeerAddr |
| * \return |
| * none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| #if 0 |
| VOID |
| kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, |
| IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| memset(&evt, 0, sizeof(evt)); |
| |
| if (eState == PARAM_MEDIA_STATE_CONNECTED) { |
| prGlueInfo->prP2PInfo[0]->eState = PARAM_MEDIA_STATE_CONNECTED; |
| |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_CONNECT=" MACSTR, MAC2STR(rPeerAddr)); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate in IWECUSTOM event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| } else if (eState == PARAM_MEDIA_STATE_DISCONNECTED) { |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_DISCONNECT=" MACSTR, MAC2STR(rPeerAddr)); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate in IWECUSTOM event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| } else { |
| ASSERT(0); |
| } |
| |
| } /* end of kalP2PSetState() */ |
| #endif |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to retrieve Wi-Fi Direct operating frequency |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| * in unit of KHz |
| */ |
| /*----------------------------------------------------------------------------*/ |
| #if 0 |
| UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) |
| { |
| ASSERT(prGlueInfo); |
| |
| return prGlueInfo->prP2PInfo[0]->u4FreqInKHz; |
| } /* end of kalP2PGetFreqInKHz() */ |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to retrieve Bluetooth-over-Wi-Fi role |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| * 0: P2P Device |
| * 1: Group Client |
| * 2: Group Owner |
| */ |
| /*----------------------------------------------------------------------------*/ |
| UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIdx) |
| { |
| ASSERT(prGlueInfo); |
| |
| return prGlueInfo->prP2PInfo[ucRoleIdx]->ucRole; |
| } /* end of kalP2PGetRole() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to set Wi-Fi Direct role |
| * |
| * \param[in] |
| * prGlueInfo |
| * ucResult |
| * 0: successful |
| * 1: error |
| * ucRole |
| * 0: P2P Device |
| * 1: Group Client |
| * 2: Group Owner |
| * |
| * \return |
| * none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| #if 1 |
| VOID kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN UINT_8 ucRoleIdx) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(ucRole <= 2); |
| |
| prGlueInfo->prP2PInfo[ucRoleIdx]->ucRole = ucRole; |
| /* Remove non-used code */ |
| } /* end of kalP2PSetRole() */ |
| |
| #else |
| VOID |
| kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, |
| IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| ASSERT(ucRole <= 2); |
| |
| memset(&evt, 0, sizeof(evt)); |
| |
| if (ucResult == 0) |
| prGlueInfo->prP2PInfo[0]->ucRole = ucRole; |
| |
| if (pucSSID) |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, |
| ucRole, 1 /* persistence or not */, pucSSID[7], pucSSID[8]); |
| else |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, |
| ucRole, 1 /* persistence or not */, '0', '0'); |
| |
| evt.data.length = strlen(aucBuffer); |
| |
| /* if (pucSSID) */ |
| /* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */ |
| |
| /* indicate in IWECUSTOM event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| } /* end of kalP2PSetRole() */ |
| |
| #endif |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to set the cipher for p2p |
| * |
| * \param[in] |
| * prGlueInfo |
| * u4Cipher |
| * |
| * \return |
| * none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher, IN UINT_8 ucRoleIdx) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); |
| |
| /* It can be WEP40 (used to identify cipher is WEP), TKIP and CCMP */ |
| prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise = u4Cipher; |
| |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to get the cipher, return false for security is none |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| * TRUE: cipher is ccmp |
| * FALSE: cipher is none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIdx) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) |
| return TRUE; |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) |
| return TRUE; |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise == IW_AUTH_CIPHER_WEP40) |
| return TRUE; |
| |
| return FALSE; |
| } |
| |
| BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIdx) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) |
| return TRUE; |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) |
| return FALSE; |
| |
| return FALSE; |
| } |
| |
| BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIdx) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[ucRoleIdx]); |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) |
| return FALSE; |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIdx]->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) |
| return TRUE; |
| |
| return FALSE; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to set the status of WSC |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PDevInfo); |
| |
| prGlueInfo->prP2PDevInfo->ucWSCRunning = ucWscMode; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to get the status of WSC |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| */ |
| /*----------------------------------------------------------------------------*/ |
| UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PDevInfo); |
| |
| return prGlueInfo->prP2PDevInfo->ucWSCRunning; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to get the wsc ie length |
| * |
| * \param[in] |
| * prGlueInfo |
| * ucType : 0 for beacon, 1 for probe req, 2 for probe resp |
| * |
| * \return |
| * The WSC IE length |
| */ |
| /*----------------------------------------------------------------------------*/ |
| UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN UINT_8 ucRoleIdx) |
| { |
| ASSERT(prGlueInfo); |
| |
| ASSERT(ucType < 3); |
| |
| return prGlueInfo->prP2PInfo[ucRoleIdx]->u2WSCIELen[ucType]; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to copy the wsc ie setting from p2p supplicant |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| * The WPS IE length |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_8 ucRoleIdx) |
| { |
| P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| |
| do { |
| if ((prGlueInfo == NULL) || (ucType >= 3) || (pucBuffer == NULL)) |
| break; |
| |
| prGlP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; |
| |
| kalMemCopy(pucBuffer, prGlP2pInfo->aucWSCIE[ucType], prGlP2pInfo->u2WSCIELen[ucType]); |
| |
| } while (FALSE); |
| |
| } |
| |
| VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, |
| IN UINT_16 u2BufferLength, IN UINT_8 ucRoleIdx) |
| { |
| P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| |
| do { |
| if ((prGlueInfo == NULL) || (ucType >= 3) || ((u2BufferLength > 0) && (pucBuffer == NULL))) |
| break; |
| |
| if (u2BufferLength > 400) { |
| DBGLOG(P2P, ERROR, |
| "Buffer length is not enough, GLUE only 400 bytes but %d received\n", u2BufferLength); |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prGlP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; |
| |
| kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], pucBuffer, u2BufferLength); |
| |
| prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength; |
| |
| } while (FALSE); |
| |
| } /* kalP2PUpdateWSC_IE */ |
| |
| #if 0 |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief indicate an event to supplicant for device connection request |
| * |
| * \param[in] prGlueInfo Pointer of GLUE_INFO_T |
| * |
| * \retval none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, |
| IN PARAM_MAC_ADDRESS rPeerAddr, |
| IN UINT_8 ucDevType,/* 0: P2P Device / 1: GC / 2: GO */ |
| IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod |
| ) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| /* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */ |
| prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength; |
| kalMemCopy(prGlueInfo->prP2PInfo[0]->aucConnReqDevName, |
| pucDevName, |
| prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength); |
| COPY_MAC_ADDR(prGlueInfo->prP2PInfo[0]->rConnReqPeerAddr, rPeerAddr); |
| prGlueInfo->prP2PInfo[0]->ucConnReqDevType = ucDevType; |
| prGlueInfo->prP2PInfo[0]->i4ConnReqConfigMethod = i4ConfigMethod; |
| prGlueInfo->prP2PInfo[0]->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod; |
| |
| /* prepare event structure */ |
| memset(&evt, 0, sizeof(evt)); |
| |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ"); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate in IWEVCUSTOM event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| } /* end of kalP2PIndicateConnReq() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Indicate an event to supplicant for device connection request from other device. |
| * |
| * \param[in] prGlueInfo Pointer of GLUE_INFO_T |
| * \param[in] pucGroupBssid Only valid when invitation Type equals to 0. |
| * |
| * \retval none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID |
| kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, |
| IN P_P2P_DEVICE_DESC_T prP2pDevDesc, |
| IN PUINT_8 pucSsid, |
| IN UINT_8 ucSsidLen, |
| IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid) |
| { |
| #if 1 |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| /* buffer peer information for later IOC_P2P_GET_STRUCT access */ |
| prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength = |
| (UINT_32) ((prP2pDevDesc->u2NameLength > 32) ? 32 : prP2pDevDesc->u2NameLength); |
| kalMemCopy(prGlueInfo->prP2PInfo[0]->aucConnReqDevName, prP2pDevDesc->aucName, |
| prGlueInfo->prP2PInfo[0]->u4ConnReqNameLength); |
| COPY_MAC_ADDR(prGlueInfo->prP2PInfo[0]->rConnReqPeerAddr, prP2pDevDesc->aucDeviceAddr); |
| COPY_MAC_ADDR(prGlueInfo->prP2PInfo[0]->rConnReqGroupAddr, pucGroupBssid); |
| prGlueInfo->prP2PInfo[0]->i4ConnReqConfigMethod = (INT_32) (prP2pDevDesc->u2ConfigMethod); |
| prGlueInfo->prP2PInfo[0]->ucOperatingChnl = ucOperatingChnl; |
| prGlueInfo->prP2PInfo[0]->ucInvitationType = ucInvitationType; |
| |
| /* prepare event structure */ |
| memset(&evt, 0, sizeof(evt)); |
| |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE"); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate in IWEVCUSTOM event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| #else |
| P_MSG_P2P_CONNECTION_REQUEST_T prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; |
| P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; |
| P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; |
| |
| do { |
| ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL)); |
| |
| /* Not a real solution */ |
| |
| prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; |
| prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; |
| |
| prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, |
| RAM_TYPE_MSG, |
| sizeof(MSG_P2P_CONNECTION_REQUEST_T)); |
| |
| if (prP2pConnReq == NULL) |
| break; |
| |
| kalMemZero(prP2pConnReq, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); |
| |
| prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; |
| |
| prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; |
| |
| COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, prP2pDevDesc->aucDeviceAddr); |
| |
| prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod; |
| |
| if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) { |
| prP2pConnReq->fgIsPersistentGroup = FALSE; |
| prP2pConnReq->fgIsTobeGO = FALSE; |
| |
| } |
| |
| else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) { |
| DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n"); |
| prP2pConnReq->fgIsPersistentGroup = TRUE; |
| prP2pConnReq->fgIsTobeGO = (prGlueInfo->prP2PInfo[0]->ucRole == 2) ? TRUE : FALSE; |
| |
| } |
| |
| p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL); |
| |
| if (ucOperatingChnl != 0) |
| prP2pSpecificBssInfo->ucPreferredChannel = ucOperatingChnl; |
| |
| if ((ucSsidLen < 32) && (pucSsid != NULL)) |
| COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, pucSsid, ucSsidLen); |
| |
| mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pConnReq, MSG_SEND_METHOD_BUF); |
| |
| } while (FALSE); |
| |
| /* frog add. */ |
| /* TODO: Invitation Indication */ |
| |
| #endif |
| |
| } /* kalP2PInvitationIndication */ |
| #endif |
| |
| #if 0 |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Indicate an status to supplicant for device invitation status. |
| * |
| * \param[in] prGlueInfo Pointer of GLUE_INFO_T |
| * |
| * \retval none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| /* buffer peer information for later IOC_P2P_GET_STRUCT access */ |
| prGlueInfo->prP2PInfo[0]->u4InvStatus = u4InvStatus; |
| |
| /* prepare event structure */ |
| memset(&evt, 0, sizeof(evt)); |
| |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS"); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate in IWEVCUSTOM event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| } /* kalP2PInvitationStatus */ |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Indicate an event to supplicant for Service Discovery request from other device. |
| * |
| * \param[in] prGlueInfo Pointer of GLUE_INFO_T |
| * |
| * \retval none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| memset(&evt, 0, sizeof(evt)); |
| |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_REQ %d", ucSeqNum); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate IWEVP2PSDREQ event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| } /* end of kalP2PIndicateSDRequest() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Indicate an event to supplicant for Service Discovery response |
| * from other device. |
| * |
| * \param[in] prGlueInfo Pointer of GLUE_INFO_T |
| * |
| * \retval none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| memset(&evt, 0, sizeof(evt)); |
| |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_RESP %d", ucSeqNum); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate IWEVP2PSDREQ event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| } /* end of kalP2PIndicateSDResponse() */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief Indicate an event to supplicant for Service Discovery TX Done |
| * from other device. |
| * |
| * \param[in] prGlueInfo Pointer of GLUE_INFO_T |
| * \param[in] ucSeqNum Sequence number of the frame |
| * \param[in] ucStatus Status code for TX |
| * |
| * \retval none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| memset(&evt, 0, sizeof(evt)); |
| |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus); |
| evt.data.length = strlen(aucBuffer); |
| |
| /* indicate IWEVP2PSDREQ event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| |
| } /* end of kalP2PIndicateSDResponse() */ |
| |
| struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[0]); |
| return prGlueInfo->prP2PInfo[0]->prDevHandler; |
| } |
| |
| #if CFG_SUPPORT_ANTI_PIRACY |
| #if 0 |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] prAdapter Pointer of ADAPTER_T |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen) |
| { |
| union iwreq_data evt; |
| UINT_8 aucBuffer[IW_CUSTOM_MAX]; |
| |
| ASSERT(prGlueInfo); |
| |
| memset(&evt, 0, sizeof(evt)); |
| snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP="); |
| |
| kalMemCopy(prGlueInfo->prP2PInfo[0]->aucSecCheckRsp, pucRsp, u2RspLen); |
| evt.data.length = strlen(aucBuffer); |
| |
| #if DBG |
| DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo[0]->aucSecCheckRsp, u2RspLen); |
| #endif |
| /* indicate in IWECUSTOM event */ |
| wireless_send_event(prGlueInfo->prP2PInfo[0]->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); |
| } /* p2pFsmRunEventRxDisassociation */ |
| #endif |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief |
| * |
| * \param[in] prAdapter Pointer of ADAPTER_T |
| * |
| * \return none |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID |
| kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, |
| IN ENUM_BAND_T eSpecificBand, |
| IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) |
| { |
| rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, |
| FALSE, ucMaxChannelNum, pucNumOfChannel, paucChannelList); |
| } /* kalGetChnlList */ |
| |
| /* ////////////////////////////////////ICS SUPPORT////////////////////////////////////// */ |
| |
| VOID |
| kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, |
| IN UINT_64 u8SeqNum, |
| IN UINT_32 u4ChannelNum, |
| IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration) |
| { |
| struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; |
| RF_CHANNEL_INFO_T rChannelInfo; |
| enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; |
| |
| do { |
| if (prGlueInfo == NULL) |
| break; |
| |
| kalMemZero(&rChannelInfo, sizeof(RF_CHANNEL_INFO_T)); |
| |
| rChannelInfo.ucChannelNum = u4ChannelNum; |
| rChannelInfo.eBand = eBand; |
| |
| prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo[0], &rChannelInfo); |
| |
| kalP2pFuncGetChannelType(eSco, &eChnlType); |
| |
| cfg80211_ready_on_channel(prGlueInfo->prP2PInfo[0]->prWdev, /* struct wireless_dev, */ |
| u8SeqNum, /* u64 cookie, */ |
| prIEEE80211ChnlStruct, /* struct ieee80211_channel * chan, */ |
| u4Duration, /* unsigned int duration, */ |
| GFP_KERNEL); /* gfp_t gfp *//* allocation flags */ |
| } while (FALSE); |
| |
| } /* kalP2PIndicateChannelReady */ |
| |
| VOID |
| kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, |
| IN UINT_64 u8SeqNum, |
| IN UINT_32 u4ChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco) |
| { |
| |
| P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; |
| enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; |
| RF_CHANNEL_INFO_T rRfChannelInfo; |
| |
| do { |
| if (prGlueInfo == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; |
| |
| if (prGlueP2pInfo == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n"); |
| |
| rRfChannelInfo.eBand = eBand; |
| rRfChannelInfo.ucChannelNum = u4ChannelNum; |
| |
| prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueP2pInfo, &rRfChannelInfo); |
| |
| kalP2pFuncGetChannelType(eSco, &eChnlType); |
| |
| cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev, /* struct wireless_dev, */ |
| u8SeqNum, prIEEE80211ChnlStruct, GFP_KERNEL); |
| } while (FALSE); |
| |
| } /* kalP2PIndicateChannelExpired */ |
| |
| VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIndex, IN BOOLEAN fgIsAbort) |
| { |
| P_GL_P2P_DEV_INFO_T prP2pGlueDevInfo = (P_GL_P2P_DEV_INFO_T) NULL; |
| P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| struct cfg80211_scan_request *prScanRequest = NULL; |
| |
| GLUE_SPIN_LOCK_DECLARATION(); |
| |
| do { |
| if (prGlueInfo == NULL) { |
| |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; |
| prP2pGlueDevInfo = prGlueInfo->prP2PDevInfo; |
| |
| if ((prGlueP2pInfo == NULL) || (prP2pGlueDevInfo == NULL)) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| DBGLOG(INIT, INFO, "[p2p] scan complete %p\n", prP2pGlueDevInfo->prScanRequest); |
| |
| KAL_ACQUIRE_MUTEX(prGlueInfo->prAdapter, MUTEX_DEL_INF); |
| GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); |
| |
| if (prP2pGlueDevInfo->prScanRequest != NULL) { |
| prScanRequest = prP2pGlueDevInfo->prScanRequest; |
| prP2pGlueDevInfo->prScanRequest = NULL; |
| } |
| GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); |
| |
| if ((prScanRequest != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { |
| |
| /* report all queued beacon/probe response frames to upper layer */ |
| scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL); |
| |
| DBGLOG(INIT, INFO, "DBG:p2p_cfg_scan_done\n"); |
| cfg80211_scan_done(prScanRequest, fgIsAbort); |
| } |
| KAL_RELEASE_MUTEX(prGlueInfo->prAdapter, MUTEX_DEL_INF); |
| |
| } while (FALSE); |
| |
| } /* kalP2PIndicateScanDone */ |
| |
| VOID |
| kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, |
| IN PUINT_8 pucFrameBuf, |
| IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength) |
| { |
| P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| struct ieee80211_channel *prChannelEntry = (struct ieee80211_channel *)NULL; |
| struct ieee80211_mgmt *prBcnProbeRspFrame = (struct ieee80211_mgmt *)pucFrameBuf; |
| struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL; |
| |
| do { |
| if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (prChannelInfo == NULL)) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; |
| |
| if (prGlueP2pInfo == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prChannelEntry = kalP2pFuncGetChannelEntry(prGlueP2pInfo, prChannelInfo); |
| |
| if (prChannelEntry == NULL) { |
| DBGLOG(P2P, TRACE, "Unknown channel info\n"); |
| break; |
| } |
| |
| /* rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; */ |
| |
| prCfg80211Bss = cfg80211_inform_bss_frame(prGlueP2pInfo->prWdev->wiphy, /* struct wiphy * wiphy, */ |
| prChannelEntry, |
| prBcnProbeRspFrame, u4BufLen, i4SignalStrength, GFP_KERNEL); |
| |
| /* Return this structure. */ |
| cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, prCfg80211Bss); |
| |
| } while (FALSE); |
| |
| return; |
| |
| } /* kalP2PIndicateBssInfo */ |
| |
| VOID kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgIsAck) |
| { |
| P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| PUINT_64 pu8GlCookie = (PUINT_64) NULL; |
| struct net_device *prNetdevice = (struct net_device *)NULL; |
| |
| do { |
| if ((prGlueInfo == NULL) || (prMsduInfo == NULL)) { |
| DBGLOG(P2P, WARN, "Unexpected pointer PARAM. 0x%lx, 0x%lx.\n", prGlueInfo, prMsduInfo); |
| ASSERT(FALSE); |
| break; |
| } |
| |
| pu8GlCookie = |
| (PUINT_64) ((ULONG) prMsduInfo->prPacket + |
| (ULONG) prMsduInfo->u2FrameLength + MAC_TX_RESERVED_FIELD); |
| |
| if (prMsduInfo->ucBssIndex == P2P_DEV_BSS_INDEX) { |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[0]; |
| prNetdevice = prGlueP2pInfo->prDevHandler; |
| |
| } else { |
| P_BSS_INFO_T prP2pBssInfo = |
| GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, prMsduInfo->ucBssIndex); |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[prP2pBssInfo->u4PrivateData]; |
| prNetdevice = prGlueP2pInfo->aprRoleHandler; |
| } |
| |
| cfg80211_mgmt_tx_status(prNetdevice->ieee80211_ptr, /* struct net_device * dev, */ |
| *pu8GlCookie, |
| (PUINT_8) ((ULONG) prMsduInfo->prPacket + |
| MAC_TX_RESERVED_FIELD), |
| prMsduInfo->u2FrameLength, fgIsAck, GFP_KERNEL); |
| |
| } while (FALSE); |
| |
| } /* kalP2PIndicateMgmtTxStatus */ |
| |
| VOID |
| kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, |
| IN P_SW_RFB_T prSwRfb, IN BOOLEAN fgIsDevInterface, IN UINT_8 ucRoleIdx) |
| { |
| #define DBG_P2P_MGMT_FRAME_INDICATION 1 |
| P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| INT_32 i4Freq = 0; |
| UINT_8 ucChnlNum = 0; |
| #if DBG_P2P_MGMT_FRAME_INDICATION |
| P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; |
| #endif |
| struct net_device *prNetdevice = (struct net_device *)NULL; |
| |
| do { |
| if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIdx]; |
| |
| /* ToDo[6630]: Get the following by channel freq */ |
| /* HAL_RX_STATUS_GET_CHAN_FREQ( prSwRfb->prRxStatus) */ |
| /* ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; */ |
| |
| ucChnlNum = HAL_RX_STATUS_GET_CHNL_NUM(prSwRfb->prRxStatus); |
| |
| #if DBG_P2P_MGMT_FRAME_INDICATION |
| |
| prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; |
| |
| switch (prWlanHeader->u2FrameCtrl) { |
| case MAC_FRAME_PROBE_REQ: |
| DBGLOG(P2P, TRACE, "RX Probe Req at channel %d ", ucChnlNum); |
| break; |
| case MAC_FRAME_PROBE_RSP: |
| DBGLOG(P2P, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); |
| break; |
| case MAC_FRAME_ACTION: |
| DBGLOG(P2P, TRACE, "RX Action frame at channel %d ", ucChnlNum); |
| break; |
| default: |
| DBGLOG(P2P, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); |
| break; |
| } |
| |
| DBGLOG(P2P, TRACE, "from: " MACSTR "\n", MAC2STR(prWlanHeader->aucAddr2)); |
| #endif |
| i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; |
| |
| if (fgIsDevInterface) |
| prNetdevice = prGlueP2pInfo->prDevHandler; |
| else |
| prNetdevice = prGlueP2pInfo->aprRoleHandler; |
| |
| #if (KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE) |
| cfg80211_rx_mgmt(prNetdevice->ieee80211_ptr, /* struct net_device * dev, */ |
| i4Freq, |
| RCPI_TO_dBm(nicRxGetRcpiValueFromRxv(RCPI_MODE_WF0, prSwRfb)), |
| prSwRfb->pvHeader, |
| prSwRfb->u2PacketLen, |
| NL80211_RXMGMT_FLAG_ANSWERED); |
| #elif (KERNEL_VERSION(3, 12, 0) <= CFG80211_VERSION_CODE) |
| cfg80211_rx_mgmt(prNetdevice->ieee80211_ptr, /* struct net_device * dev, */ |
| i4Freq, |
| RCPI_TO_dBm(nicRxGetRcpiValueFromRxv(RCPI_MODE_WF0, prSwRfb)), |
| prSwRfb->pvHeader, |
| prSwRfb->u2PacketLen, |
| NL80211_RXMGMT_FLAG_ANSWERED, |
| GFP_ATOMIC); |
| #else |
| cfg80211_rx_mgmt(prNetdevice->ieee80211_ptr, /* struct net_device * dev, */ |
| i4Freq, |
| RCPI_TO_dBm(nicRxGetRcpiValueFromRxv(RCPI_MODE_WF0, prSwRfb)), |
| prSwRfb->pvHeader, |
| prSwRfb->u2PacketLen, |
| GFP_ATOMIC); |
| #endif |
| |
| |
| } while (FALSE); |
| |
| } /* kalP2PIndicateRxMgmtFrame */ |
| #if CFG_WPS_DISCONNECT || (KERNEL_VERSION(4, 4, 0) <= CFG80211_VERSION_CODE) |
| VOID |
| kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, |
| IN UINT_8 ucRoleIndex, |
| IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, |
| IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, |
| IN WLAN_STATUS eStatus) |
| { |
| P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| |
| do { |
| if (prGlueInfo == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; |
| |
| if (prP2pConnInfo) { |
| cfg80211_connect_result(prGlueP2pInfo->aprRoleHandler, |
| /* struct net_device * dev, */ |
| prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, |
| prP2pConnInfo->u4BufLength, |
| pucRxIEBuf, u2RxIELen, u2StatusReason, |
| GFP_KERNEL); /* gfp_t gfp *//* allocation flags */ |
| |
| prP2pConnInfo->eConnRequest = P2P_CONNECTION_TYPE_IDLE; |
| } else { |
| /* Disconnect, what if u2StatusReason == 0? */ |
| cfg80211_disconnected(prGlueP2pInfo->aprRoleHandler, |
| /* struct net_device * dev, */ |
| u2StatusReason, pucRxIEBuf, u2RxIELen, |
| eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, GFP_KERNEL); |
| } |
| |
| } while (FALSE); |
| |
| } /* kalP2PGCIndicateConnectionStatus */ |
| |
| #else |
| VOID |
| kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, |
| IN UINT_8 ucRoleIndex, |
| IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, |
| IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason) |
| { |
| P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; |
| |
| do { |
| if (prGlueInfo == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| prGlueP2pInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; |
| |
| if (prP2pConnInfo) { |
| cfg80211_connect_result(prGlueP2pInfo->aprRoleHandler, |
| /* struct net_device * dev, */ |
| prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, |
| prP2pConnInfo->u4BufLength, |
| pucRxIEBuf, u2RxIELen, u2StatusReason, |
| GFP_KERNEL); /* gfp_t gfp *//* allocation flags */ |
| |
| prP2pConnInfo->eConnRequest = P2P_CONNECTION_TYPE_IDLE; |
| } else { |
| /* Disconnect, what if u2StatusReason == 0? */ |
| cfg80211_disconnected(prGlueP2pInfo->aprRoleHandler, |
| /* struct net_device * dev, */ |
| u2StatusReason, pucRxIEBuf, u2RxIELen, GFP_KERNEL); |
| } |
| |
| } while (FALSE); |
| |
| } /* kalP2PGCIndicateConnectionStatus */ |
| |
| #endif |
| |
| VOID |
| kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, |
| IN UINT_8 ucRoleIndex, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew) |
| { |
| P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; |
| |
| do { |
| if ((prGlueInfo == NULL) || (prCliStaRec == NULL) || (ucRoleIndex >= 2)) |
| break; |
| |
| prP2pGlueInfo = prGlueInfo->prP2PInfo[ucRoleIndex]; |
| |
| if (fgIsNew) { |
| struct station_info rStationInfo; |
| |
| kalMemZero(&rStationInfo, sizeof(rStationInfo)); |
| |
| #if KERNEL_VERSION(4, 4, 0) > CFG80211_VERSION_CODE |
| rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES; |
| #endif |
| rStationInfo.generation = ++prP2pGlueInfo->i4Generation; |
| |
| rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe; |
| rStationInfo.assoc_req_ies_len = prCliStaRec->u2AssocReqIeLen; |
| |
| cfg80211_new_sta(prP2pGlueInfo->aprRoleHandler, |
| /* struct net_device * dev, */ |
| prCliStaRec->aucMacAddr, &rStationInfo, GFP_KERNEL); |
| } else { |
| ++prP2pGlueInfo->i4Generation; |
| |
| cfg80211_del_sta(prP2pGlueInfo->aprRoleHandler, |
| /* struct net_device * dev, */ |
| prCliStaRec->aucMacAddr, GFP_KERNEL); |
| } |
| |
| } while (FALSE); |
| |
| return; |
| |
| } /* kalP2PGOStationUpdate */ |
| |
| #if (CFG_SUPPORT_DFS_MASTER == 1) |
| VOID kalP2PRddDetectUpdate(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIndex) |
| { |
| DBGLOG(INIT, INFO, "Radar Detection event\n"); |
| |
| do { |
| if (prGlueInfo == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIndex]->chandef == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| /* cac start disable for next cac slot if enable in dfs channel */ |
| prGlueInfo->prP2PInfo[ucRoleIndex]->prWdev->cac_started = FALSE; |
| DBGLOG(INIT, INFO, "kalP2PRddDetectUpdate: Update to OS\n"); |
| cfg80211_radar_event(prGlueInfo->prP2PInfo[ucRoleIndex]->prWdev->wiphy, |
| prGlueInfo->prP2PInfo[ucRoleIndex]->chandef, GFP_KERNEL); |
| DBGLOG(INIT, INFO, "kalP2PRddDetectUpdate: Update to OS Done\n"); |
| |
| netif_carrier_off(prGlueInfo->prP2PInfo[ucRoleIndex]->prDevHandler); |
| netif_tx_stop_all_queues(prGlueInfo->prP2PInfo[ucRoleIndex]->prDevHandler); |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIndex]->chandef->chan) |
| cnmMemFree(prGlueInfo->prAdapter, prGlueInfo->prP2PInfo[ucRoleIndex]->chandef->chan); |
| |
| prGlueInfo->prP2PInfo[ucRoleIndex]->chandef->chan = NULL; |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIndex]->chandef) |
| cnmMemFree(prGlueInfo->prAdapter, prGlueInfo->prP2PInfo[ucRoleIndex]->chandef); |
| |
| prGlueInfo->prP2PInfo[ucRoleIndex]->chandef = NULL; |
| |
| } while (FALSE); |
| |
| } /* kalP2PRddDetectUpdate */ |
| |
| VOID kalP2PCacFinishedUpdate(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIndex) |
| { |
| DBGLOG(INIT, INFO, "CAC Finished event\n"); |
| |
| do { |
| if (prGlueInfo == NULL) |
| ASSERT(FALSE); |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIndex]->chandef == NULL) { |
| ASSERT(FALSE); |
| break; |
| } |
| |
| DBGLOG(INIT, INFO, "kalP2PCacFinishedUpdate: Update to OS\n"); |
| cfg80211_cac_event(prGlueInfo->prP2PInfo[ucRoleIndex]->prDevHandler, |
| prGlueInfo->prP2PInfo[ucRoleIndex]->chandef, NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); |
| DBGLOG(INIT, INFO, "kalP2PCacFinishedUpdate: Update to OS Done\n"); |
| |
| } while (FALSE); |
| |
| } /* kalP2PRddDetectUpdate */ |
| #endif |
| |
| BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type) |
| { |
| BOOLEAN fgIsValid = FALSE; |
| |
| do { |
| if (channel_type) { |
| |
| switch (rChnlSco) { |
| case CHNL_EXT_SCN: |
| *channel_type = NL80211_CHAN_NO_HT; |
| break; |
| case CHNL_EXT_SCA: |
| *channel_type = NL80211_CHAN_HT40MINUS; |
| break; |
| case CHNL_EXT_SCB: |
| *channel_type = NL80211_CHAN_HT40PLUS; |
| break; |
| default: |
| ASSERT(FALSE); |
| *channel_type = NL80211_CHAN_NO_HT; |
| break; |
| } |
| |
| } |
| |
| fgIsValid = TRUE; |
| } while (FALSE); |
| |
| return fgIsValid; |
| } /* kalP2pFuncGetChannelType */ |
| |
| struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo) |
| { |
| struct ieee80211_channel *prTargetChannelEntry = (struct ieee80211_channel *)NULL; |
| UINT_32 u4TblSize = 0, u4Idx = 0; |
| struct wiphy *wiphy = prP2pInfo->prWdev->wiphy; |
| |
| do { |
| if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) |
| break; |
| |
| switch (prChannelInfo->eBand) { |
| case BAND_2G4: |
| prTargetChannelEntry = wiphy->bands[IEEE80211_BAND_2GHZ]->channels; |
| u4TblSize = wiphy->bands[IEEE80211_BAND_2GHZ]->n_channels; |
| break; |
| case BAND_5G: |
| prTargetChannelEntry = wiphy->bands[IEEE80211_BAND_5GHZ]->channels; |
| u4TblSize = wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; |
| break; |
| default: |
| break; |
| } |
| |
| if (prTargetChannelEntry == NULL) |
| break; |
| |
| for (u4Idx = 0; u4Idx < u4TblSize; u4Idx++, prTargetChannelEntry++) { |
| if (prTargetChannelEntry->hw_value == prChannelInfo->ucChannelNum) |
| break; |
| |
| } |
| |
| if (u4Idx == u4TblSize) { |
| prTargetChannelEntry = NULL; |
| break; |
| } |
| |
| } while (FALSE); |
| |
| return prTargetChannelEntry; |
| } /* kalP2pFuncGetChannelEntry */ |
| |
| #if CFG_SUPPORT_HOTSPOT_WPS_MANAGER |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to set the block list of Hotspot |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| */ |
| /*----------------------------------------------------------------------------*/ |
| BOOLEAN kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock, |
| IN UINT_8 ucRoleIndex) |
| { |
| UINT_8 aucNullAddr[] = NULL_MAC_ADDR; |
| BOOLEAN fgIsValid = FALSE; |
| UINT_32 i; |
| |
| ASSERT(prGlueInfo); |
| /*ASSERT(prGlueInfo->prP2PInfo[ucRoleIndex]);*/ |
| |
| |
| /*if only one ap mode register, prGlueInfo->prP2PInfo[1] would be null*/ |
| if (!prGlueInfo->prP2PInfo[ucRoleIndex]) |
| return fgIsValid; |
| |
| |
| if (fgIsblock) { |
| for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { |
| if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { |
| if (UNEQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo[ucRoleIndex]->aucblackMACList[i]), |
| rbssid)) { |
| if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo[ucRoleIndex]->aucblackMACList[i]), |
| aucNullAddr)) { |
| COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo[ucRoleIndex] |
| ->aucblackMACList[i]), rbssid); |
| fgIsValid = FALSE; |
| return fgIsValid; |
| } |
| } |
| } |
| } |
| } else { |
| for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { |
| if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo[ucRoleIndex]->aucblackMACList[i]), rbssid)) { |
| COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo[ucRoleIndex]->aucblackMACList[i]), aucNullAddr); |
| fgIsValid = FALSE; |
| return fgIsValid; |
| } |
| } |
| } |
| |
| return fgIsValid; |
| |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to compare the black list of Hotspot |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| */ |
| /*----------------------------------------------------------------------------*/ |
| BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN UINT_8 ucRoleIndex) |
| { |
| UINT_8 aucNullAddr[] = NULL_MAC_ADDR; |
| BOOLEAN fgIsExsit = FALSE; |
| UINT_32 i; |
| |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[ucRoleIndex]); |
| |
| for (i = 0; i < P2P_MAXIMUM_CLIENT_COUNT; i++) { |
| if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { |
| if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo[ucRoleIndex]->aucblackMACList[i]), rbssid)) { |
| fgIsExsit = TRUE; |
| return fgIsExsit; |
| } |
| } |
| } |
| |
| return fgIsExsit; |
| |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to return the max clients of Hotspot |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| */ |
| /*----------------------------------------------------------------------------*/ |
| VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient, IN UINT_8 ucRoleIndex) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[ucRoleIndex]); |
| |
| if (u4MaxClient == 0 || prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients >= P2P_MAXIMUM_CLIENT_COUNT) |
| prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients = P2P_MAXIMUM_CLIENT_COUNT; |
| else |
| prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients = u4MaxClient; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /*! |
| * \brief to return the max clients of Hotspot |
| * |
| * \param[in] |
| * prGlueInfo |
| * |
| * \return |
| */ |
| /*----------------------------------------------------------------------------*/ |
| BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient, IN UINT_8 ucRoleIndex) |
| { |
| ASSERT(prGlueInfo); |
| ASSERT(prGlueInfo->prP2PInfo[ucRoleIndex]); |
| |
| if (prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients) { |
| if ((UINT_8) u4NumClient > prGlueInfo->prP2PInfo[ucRoleIndex]->ucMaxClients) |
| return TRUE; |
| else |
| return FALSE; |
| } |
| |
| return FALSE; |
| } |
| |
| #endif |