/*----------------------------------------------------------------------------*/ PUINT_8 p2pBuildReAssocReqFrameCommonIEs( IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer ) { P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL; prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; /* Fill the SSID element. */ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. */ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, SSID_IE(pucBuffer)->ucLength, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); pucBuffer += IE_SIZE(pucBuffer); return pucBuffer; }
/*----------------------------------------------------------------------------*/ WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE) { if (0) /* Todo:: Not HS20 STA */ return 0; #if 0 P_HS20_INFO_T prHS20Info; prHS20Info = &(prAdapter->rWifiVar.rHS20Info); /* * Generate 802.11u Interworking IE (107) */ hs20FillInterworkingIE(prAdapter, prHS20Info->ucAccessNetworkOptions, prHS20Info->ucVenueGroup, prHS20Info->ucVenueType, pucTargetBSSID, prIE); prIE += IE_SIZE(prIE); #endif /* * Generate Ext Cap IE (127) */ hs20FillProreqExtCapIE(prAdapter, prIE); prIE += IE_SIZE(prIE); /* * Generate HS2.0 Indication IE (221) */ hs20FillHS20IE(prAdapter, prIE); prIE += IE_SIZE(prIE); return WLAN_STATUS_SUCCESS; }
/*----------------------------------------------------------------------------*/ VOID rlmRspGenerateObssScanIE ( P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo ) { P_BSS_INFO_T prBssInfo; P_IE_OBSS_SCAN_PARAM_T prObssScanIe; P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL; ASSERT(prAdapter); ASSERT(prMsduInfo); ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ASSERT(prBssInfo); if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) && prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) { prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T) (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); /* Add 20/40 BSS coexistence IE */ prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS; prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN; prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell; prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell; prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval; prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel; prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel; prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor; prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold; ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN+ ELEM_MAX_LEN_OBSS_SCAN)); prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe); } }
/*----------------------------------------------------------------------------*/ VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo) { P_WLAN_AUTH_FRAME_T prAuthFrame; P_STA_RECORD_T prStaRec; UINT_16 u2TransactionSeqNum; ASSERT(prMsduInfo); prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); if (!prStaRec) return; ASSERT(prStaRec); /* For Management, frame header and payload are in a continuous buffer */ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket; WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) /* Only consider SEQ_3 for Challenge Text */ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) && (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) { COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText)); prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText); } return; } /* end of authAddIEChallengeText() */
VOID hs20FillExtCapIE ( P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo ) { P_EXT_CAP_T prExtCap; ASSERT(prAdapter); ASSERT(prMsduInfo); /* Add Extended Capabilities IE */ prExtCap = (P_EXT_CAP_T) (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); prExtCap->ucId = ELEM_ID_EXTENDED_CAP; if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; else prExtCap->ucLength = 3 - ELEM_HDR_LEN; kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) { prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; } if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); /* For R2 WNM-Notification*/ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); } printk("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP); ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); }
/*----------------------------------------------------------------------------*/ VOID authHandleIEChallengeText ( P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr ) { P_WLAN_AUTH_FRAME_T prAuthFrame; P_STA_RECORD_T prStaRec; UINT_16 u2TransactionSeqNum; ASSERT(prSwRfb); ASSERT(prIEHdr); prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ASSERT(prStaRec); if(!prStaRec) { return; } /* For Management, frame header and payload are in a continuous buffer */ prAuthFrame = (P_WLAN_AUTH_FRAME_T)prSwRfb->pvHeader; //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; // NOTE(Kevin): Optimized for ARM /* Only consider SEQ_2 for Challenge Text */ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) && (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) { /* Free previous allocated TCM memory */ if (prStaRec->prChallengeText) { ASSERT(0); cnmMemFree(prAdapter, prStaRec->prChallengeText); prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T)NULL; } if ( ( prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)) ) == NULL) { return; } /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */ COPY_IE(prStaRec->prChallengeText, prIEHdr); } return; } /* end of authAddIEChallengeText() */
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_connect ( struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme ) { P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus; UINT_32 u4BufLen; ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ENUM_PARAM_AUTH_MODE_T eAuthMode; UINT_32 cipher; PARAM_SSID_T rNewSsid; BOOLEAN fgCarryWPSIE = FALSE; ENUM_PARAM_OP_MODE_T eOpMode; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) eOpMode = NET_TYPE_AUTO_SWITCH; else eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode; rStatus = kalIoctl(prGlueInfo, wlanoidSetInfrastructureMode, &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, INFO, ("wlanoidSetInfrastructureMode fail 0x%lx\n", rStatus)); return -EFAULT; } /* after set operation mode, key table are cleared */ /* reset wpa info */ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; prGlueInfo->rWpaInfo.u4KeyMgmt = 0; prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; #if CFG_SUPPORT_802_11W prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; #endif if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2; else prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; switch (sme->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; break; case NL80211_AUTHTYPE_SHARED_KEY: prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; break; default: prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY; break; } if (sme->crypto.n_ciphers_pairwise) { prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = sme->crypto.ciphers_pairwise[0]; switch (sme->crypto.ciphers_pairwise[0]) { case WLAN_CIPHER_SUITE_WEP40: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40; break; case WLAN_CIPHER_SUITE_WEP104: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104; break; case WLAN_CIPHER_SUITE_TKIP: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP; break; case WLAN_CIPHER_SUITE_CCMP: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; break; case WLAN_CIPHER_SUITE_AES_CMAC: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; break; default: DBGLOG(REQ, WARN, ("invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0])); return -EINVAL; } } if (sme->crypto.cipher_group) { prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group; switch (sme->crypto.cipher_group) { case WLAN_CIPHER_SUITE_WEP40: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40; break; case WLAN_CIPHER_SUITE_WEP104: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104; break; case WLAN_CIPHER_SUITE_TKIP: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP; break; case WLAN_CIPHER_SUITE_CCMP: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; break; case WLAN_CIPHER_SUITE_AES_CMAC: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; break; default: DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } if (sme->crypto.n_akm_suites) { prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = sme->crypto.akm_suites[0]; if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: eAuthMode = AUTH_MODE_WPA; break; case WLAN_AKM_SUITE_PSK: eAuthMode = AUTH_MODE_WPA_PSK; break; default: DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: eAuthMode = AUTH_MODE_WPA2; break; case WLAN_AKM_SUITE_PSK: eAuthMode = AUTH_MODE_WPA2_PSK; break; default: DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } } if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; } prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy; //prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; //prGlueInfo->prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; prGlueInfo->fgWpsActive = FALSE; //prGlueInfo->prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; if (sme->ie && sme->ie_len > 0) { WLAN_STATUS rStatus; UINT_32 u4BufLen; PUINT_8 prDesiredIE = NULL; #if CFG_SUPPORT_WAPI rStatus = kalIoctl(prGlueInfo, wlanoidSetWapiAssocInfo, sme->ie, sme->ie_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(SEC, WARN, ("[wapi] set wapi assoc info error:%lx\n", rStatus)); } #endif #if CFG_SUPPORT_WPS2 if (wextSrchDesiredWPSIE(sme->ie, sme->ie_len, 0xDD, (PUINT_8 *)&prDesiredIE)) { prGlueInfo->fgWpsActive = TRUE; fgCarryWPSIE = TRUE; rStatus = kalIoctl(prGlueInfo, wlanoidSetWSCAssocInfo, prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(SEC, WARN, ("WSC] set WSC assoc info error:%lx\n", rStatus)); } } #endif } /* clear WSC Assoc IE buffer in case WPS IE is not detected */ if(fgCarryWPSIE == FALSE) { kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200); prGlueInfo->u2WSCAssocInfoIELen = 0; } rStatus = kalIoctl(prGlueInfo, wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set auth mode error:%lx\n", rStatus)); } cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) { if (cipher & IW_AUTH_CIPHER_CCMP) { eEncStatus = ENUM_ENCRYPTION3_ENABLED; } else if (cipher & IW_AUTH_CIPHER_TKIP) { eEncStatus = ENUM_ENCRYPTION2_ENABLED; } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { eEncStatus = ENUM_ENCRYPTION1_ENABLED; } else if (cipher & IW_AUTH_CIPHER_NONE) { if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) eEncStatus = ENUM_ENCRYPTION1_ENABLED; else eEncStatus = ENUM_ENCRYPTION_DISABLED; } else { eEncStatus = ENUM_ENCRYPTION_DISABLED; } } else { eEncStatus = ENUM_ENCRYPTION_DISABLED; } rStatus = kalIoctl(prGlueInfo, wlanoidSetEncryptionStatus, &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set encryption mode error:%lx\n", rStatus)); } if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; kalMemSet(prWepKey, 0, sizeof(prWepKey)); prWepKey->u4Length = 12 + sme->key_len; prWepKey->u4KeyLength = (UINT_32) sme->key_len; prWepKey->u4KeyIndex = (UINT_32) sme->key_idx; prWepKey->u4KeyIndex |= BIT(31); if (prWepKey->u4KeyLength > 32) { DBGLOG(REQ, WARN, ("Too long key length (%u)\n", prWepKey->u4KeyLength)); return -EINVAL; } kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); rStatus = kalIoctl(prGlueInfo, wlanoidSetAddWep, prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\n", rStatus)); return -EFAULT; } } if(sme->ssid_len > 0) { /* connect by SSID */ COPY_SSID(rNewSsid.aucSsid, rNewSsid.u4SsidLen, sme->ssid, sme->ssid_len); rStatus = kalIoctl(prGlueInfo, wlanoidSetSsid, (PVOID) &rNewSsid, sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set SSID:%lx\n", rStatus)); return -EINVAL; } } else { /* connect by BSSID */ rStatus = kalIoctl(prGlueInfo, wlanoidSetBssid, (PVOID) sme->bssid, sizeof(MAC_ADDR_LEN), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set BSSID:%lx\n", rStatus)); return -EINVAL; } } return 0; }
/*----------------------------------------------------------------------------*/ VOID rlmObssScanDone ( P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr ) { P_MSG_SCN_SCAN_DONE prScanDoneMsg; P_BSS_INFO_T prBssInfo; P_MSDU_INFO_T prMsduInfo; P_ACTION_20_40_COEXIST_FRAME prTxFrame; UINT_16 i, u2PayloadLen; ASSERT(prMsgHdr); prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; ASSERT(prBssInfo); DBGLOG(RLM, INFO, ("OBSS Scan Done (NetIdx=%d, Mode=%d)\n", prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode)); cnmMemFree(prAdapter, prMsgHdr); #if CFG_ENABLE_WIFI_DIRECT /* AP mode */ if ((prAdapter->fgIsP2PRegistered) && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { return; } #endif /* STA mode */ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { DBGLOG(RLM, WARN, ("OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex)); return; } /* To do: check 2.4G channel list to decide if obss mgmt should be * sent to associated AP. Note: how to handle concurrent network? * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence * management frame is needed. */ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && (prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN)) != NULL) { DBGLOG(RLM, INFO, ("Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0])); prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; /* To do: find correct algorithm */ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; prTxFrame->rBssCoexist.ucLength = 1; prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; u2PayloadLen = 2 + 3; if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) { prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i+1]; } u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); } ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); /* Clear up channel lists in 2.4G band */ prBssInfo->auc2G_20mReqChnlList[0] = 0; prBssInfo->auc2G_NonHtChnlList[0] = 0; //4 Update information of MSDU_INFO_T prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; prMsduInfo->fgIs802_1x = FALSE; prMsduInfo->fgIs802_11 = TRUE; prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); prMsduInfo->pfTxDoneHandler = NULL; prMsduInfo->fgIsBasicRate = FALSE; //4 Enqueue the frame to send this action frame. nicTxEnqueueMsdu(prAdapter, prMsduInfo); } /* end of prMsduInfo != NULL */ if (prBssInfo->u2ObssScanInterval > 0) { DBGLOG(RLM, INFO, ("Set OBSS timer (NetIdx=%d, %d sec)\n", prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval)); cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); } }