diff options
| author | Ravi Joshi <ravij@qca.qualcomm.com> | 2013-12-13 22:52:22 -0800 |
|---|---|---|
| committer | Prakash Dhavali <pdhavali@codeaurora.org> | 2014-01-16 21:45:56 -0800 |
| commit | a02f1d78e9c4d81aaa66b74169e102ba67f7c7aa (patch) | |
| tree | af63555cf652c1a631b91302137f8366637d694c /CORE | |
| parent | 791c922935fc4434e3f9bf4095312187d86dfe20 (diff) | |
wlan: ROME DFS Changes on branch
Implements DFS Channel Change for SAP in addition to
Radar Indication, random channel selection, SAP States
for CAC, partial changes for start beacon Indication.
.
Change-Id: I6b62e797b3c104ba716697d2bb2441aa5fccca7c
CRs-Fixed: 589876
Diffstat (limited to 'CORE')
34 files changed, 1468 insertions, 45 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index c2bdb8a8f3a9..c09a3aadd376 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -2670,6 +2670,7 @@ static __inline unsigned long utilMin( unsigned long a, unsigned long b ) #if defined (QCA_WIFI_2_0) && \ !defined (QCA_WIFI_ISOC) void hdd_update_tgt_cfg(void *context, void *param); +void hdd_dfs_indicate_radar(void *context, void *param); #endif /* QCA_WIFI_2_0 && !QCA_WIFI_ISOC */ #endif diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 245c104caf49..f73c372e8975 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1220,6 +1220,7 @@ struct hdd_context_s #ifdef QCA_WIFI_2_0 v_U32_t target_type; v_U32_t target_fw_version; + v_U32_t dfs_radar_found; #endif struct regulatory reg; #ifdef FEATURE_WLAN_CH_AVOID diff --git a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h index cc15d790d93e..96497923367e 100644 --- a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h @@ -93,4 +93,10 @@ struct hdd_tgt_cfg { #endif }; +struct hdd_dfs_radar_ind { + u_int8_t ieee_chan_number; + u_int32_t chan_freq; + u_int32_t dfs_radar_status; +}; + #endif /* HDD_TGT_CFG_H */ diff --git a/CORE/HDD/src/wlan_hdd_ftm.c b/CORE/HDD/src/wlan_hdd_ftm.c index c5257e8cee61..e1b60ee48236 100644 --- a/CORE/HDD/src/wlan_hdd_ftm.c +++ b/CORE/HDD/src/wlan_hdd_ftm.c @@ -562,8 +562,14 @@ static VOS_STATUS wlan_ftm_vos_open( v_CONTEXT_t pVosContext, v_SIZE_t hddContex macOpenParms.powersaveOffloadEnabled = pHddCtx->cfg_ini->enablePowersaveOffload; +#ifndef QCA_WIFI_ISOC + vStatus = WDA_open(gpVosContext, gpVosContext->pHDDContext, + NULL, NULL, + &macOpenParms); +#else vStatus = WDA_open(gpVosContext, gpVosContext->pHDDContext, NULL, &macOpenParms); +#endif if (!VOS_IS_STATUS_SUCCESS(vStatus)) { /* Critical Error ... Cannot proceed further */ diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 93e4edab15db..319ece470e33 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -461,6 +461,7 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa hdd_context_t *pHddCtx; hdd_scaninfo_t *pScanInfo = NULL; struct iw_michaelmicfailure msg; + v_U8_t txQueueId; dev = (struct net_device *)usrDataForCallback; pHostapdAdapter = netdev_priv(dev); @@ -555,6 +556,18 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa pHddApCtx->wepKey[i].keyLength = 0; } } + + // We should restart OS transmit queues if we came here after + // radar detection and channel change + if (VOS_TRUE == pHddCtx->dfs_radar_found) + { + pHddCtx->dfs_radar_found = VOS_FALSE; + for (txQueueId = 0; txQueueId < NUM_TX_QUEUES; txQueueId++) + { + netif_stop_subqueue(dev, txQueueId); + } + } + //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled startBssEvent = "SOFTAP.enabled"; memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event)); diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 0a4fcff7999a..06c33a258ea2 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -4718,6 +4718,56 @@ void hdd_update_tgt_cfg(void *context, void *param) hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); #endif /* #ifdef WLAN_FEATURE_11AC */ } + +/* This function is invoked when a radar in found on the + * SAP current operating channel and Data Tx from netif + * has to be stopped to honor the DFS regulations. + * Actions: Stop the netif Tx queues,Indicate Radar present + * in HDD context for future usage. + */ +void hdd_dfs_indicate_radar(void *context, void *param) +{ + hdd_context_t *pHddCtx= (hdd_context_t *)context; + struct hdd_dfs_radar_ind *hdd_radar_event = + (struct hdd_dfs_radar_ind*)param; + hdd_adapter_list_node_t *pAdapterNode = NULL, + *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + v_U8_t txQueueId; + + if (pHddCtx == NULL) + { + return; + } + if (hdd_radar_event == NULL) + { + return; + } + if (VOS_TRUE == hdd_radar_event->dfs_radar_status) + { + pHddCtx->dfs_radar_found = VOS_TRUE; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if (WLAN_HDD_SOFTAP == pAdapter->device_mode) + { + for (txQueueId = 0; txQueueId < NUM_TX_QUEUES; txQueueId++) + { + netif_stop_subqueue(pAdapter->dev, txQueueId); + } + break; + } + else + { + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } + } +} #endif /* QCA_WIFI_2_0 && !QCA_WIFI_ISOC */ /**--------------------------------------------------------------------------- diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h index 152ca3253eab..5b637bd24d36 100644 --- a/CORE/MAC/inc/aniGlobal.h +++ b/CORE/MAC/inc/aniGlobal.h @@ -248,6 +248,7 @@ typedef struct sLimTimers * for a period of time on a particular DFS channel */ TX_TIMER gLimActiveToPassiveChannelTimer; + //********************TIMER SECTION ENDS************************************************** // ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in limInitialize //**************************************************************************************** @@ -911,6 +912,10 @@ tLimMlmOemDataRsp *gpLimMlmOemDataRsp; tSirDFSChannelList dfschannelList; tANI_U8 deauthMsgCnt; tANI_U8 gLimIbssStaLimit; + + /* Number of channel switch IEs sent so far */ + tANI_U8 gLimDfsChanSwTxCount; + tANI_U8 gLimDfsTargetChanNum; } tAniSirLim, *tpAniSirLim; typedef struct sLimMgmtFrameRegistration diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 1e612e8f808d..25fe2c5bb3d3 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -4736,4 +4736,36 @@ typedef struct sSirChAvoidIndType } tSirChAvoidIndType; #endif /* FEATURE_WLAN_CH_AVOID */ +typedef struct sSirSmeDfsEventInd +{ + tANI_U32 sessionId; + tANI_U8 ieee_chan_number; + tANI_U32 chan_freq; + tANI_U32 dfs_radar_status; + int use_nol; +}tSirSmeDfsEventInd, *tpSirSmeDfsEventInd; + +typedef struct sSirChanChangeRequest +{ + tANI_U16 messageType; + tANI_U8 sessionId; + tANI_U8 targetChannel; +}tSirChanChangeRequest, *tpSirChanChangeRequest; + +typedef struct sSirChanChangeResponse +{ + tANI_U8 sessionId; + tANI_U8 newChannelNumber; + tANI_U8 channelChangeStatus; + ePhyChanBondState secondaryChannelOffset; +}tSirChanChangeResponse, *tpSirChanChangeResponse; + +typedef struct sSirStartBeaconIndication +{ + tANI_U16 messageType; + tANI_U8 sessionId; + tANI_U8 beaconStartStatus; + +}tSirStartBeaconIndication, *tpSirStartBeaconIndication; + #endif /* __SIR_API_H */ diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index 68fa22a30b46..b53797ecb00a 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -380,6 +380,12 @@ enum eWniMsgTypes #ifdef FEATURE_WLAN_CH_AVOID eWNI_SME_CH_AVOID_IND, #endif /* FEATURE_WLAN_CH_AVOID */ + /* DFS EVENTS */ + eWNI_SME_DFS_RADAR_FOUND, //RADAR found indication from DFS + eWNI_SME_CHANNEL_CHANGE_REQ,//Channel Change Request from SAP + eWNI_SME_CHANNEL_CHANGE_RSP,// Channel Change Response from WMA + eWNI_SME_START_BEACON_REQ,//Start Beacon Transmission. + eWNI_SME_MSG_TYPES_END }; diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 33ed8bed778a..f12920f14a66 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -634,6 +634,10 @@ typedef struct sSirMbMsgP2p #endif #endif +/* Handling of beacon tx indication from FW */ +#define SIR_HAL_BEACON_TX_SUCCESS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 242) +#define SIR_HAL_DFS_RADAR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 243) + #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) // CFG message types @@ -737,6 +741,7 @@ typedef struct sSirMbMsgP2p #define SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2B) #endif #define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C) + #define SIR_LIM_MSG_TYPES_END (SIR_LIM_MSG_TYPES_BEGIN+0xFF) // SCH message types diff --git a/CORE/MAC/src/pe/include/limGlobal.h b/CORE/MAC/src/pe/include/limGlobal.h index 5613a15cc73b..d3f134597e20 100644 --- a/CORE/MAC/src/pe/include/limGlobal.h +++ b/CORE/MAC/src/pe/include/limGlobal.h @@ -87,6 +87,8 @@ #define IS_5G_BAND(__rfBand) ((__rfBand & 0x3) == 0x2) #define IS_24G_BAND(__rfBand) ((__rfBand & 0x3) == 0x1) +#define LIM_MAX_CSA_IE_UPDATES ( 5 ) + // enums exported by LIM are as follows /// System role definition @@ -575,7 +577,7 @@ typedef struct sLimChannelSwitchInfo tLimChannelSwitchState state; tANI_U8 primaryChannel; ePhyChanBondState secondarySubBand; - tANI_U32 switchCount; + tANI_S8 switchCount; tANI_U32 switchTimeoutValue; tANI_U8 switchMode; } tLimChannelSwitchInfo, *tpLimChannelSwitchInfo; diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h index bc7109ca03c5..33089ff0ce3e 100644 --- a/CORE/MAC/src/pe/include/limSession.h +++ b/CORE/MAC/src/pe/include/limSession.h @@ -413,6 +413,9 @@ typedef struct sPESession // Added to Support BT-AMP tANI_U8 smpsMode; tANI_U8 chainMask; + + /* Flag to indicate Chan Sw announcement is required */ + tANI_U8 dfsIncludeChanSwIe; }tPESession, *tpPESession; #define LIM_MAX_ACTIVE_SESSIONS 4 diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index 42ef0936b4db..d383cb7c4667 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -1762,6 +1762,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT: limHandleUpdateOlbcCache(pMac); break; + #if 0 case SIR_LIM_WPS_OVERLAP_TIMEOUT: limProcessWPSOverlapTimeout(pMac); @@ -2066,6 +2067,12 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) break; } + case WDA_DFS_RADAR_IND: + limSendSmeDfsEventNotify(pMac, limMsg->type, + (void *)limMsg->bodyptr); + /* limmsg->bodyptr will be freed up by SME/CSR */ + break; + default: vos_mem_free((v_VOID_t*)limMsg->bodyptr); limMsg->bodyptr = NULL; diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 2280d94cb328..cbc9a7e1728c 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -100,6 +100,12 @@ static void __limProcessSmeDisassocCnf(tpAniSirGlobal, tANI_U32 *); static void __limProcessSmeDeauthReq(tpAniSirGlobal, tANI_U32 *); static void __limProcessSmeSetContextReq(tpAniSirGlobal, tANI_U32 *); static tANI_BOOLEAN __limProcessSmeStopBssReq(tpAniSirGlobal, tpSirMsgQ pMsg); +static void limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, + tANI_U32 *pMsg); +static void limProcessSmeStartBeaconReq(tpAniSirGlobal pMac, + tANI_U32 *pMsg); +static void limProcessSmeDfsCacIndication(tpAniSirGlobal pMac, tANI_U32 *pMsg); +static void limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg); void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *); @@ -5738,6 +5744,28 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) limSendSetTxPowerReq(pMac, pMsgBuf); break ; +#if defined WLAN_FEATURE_RELIABLE_MCAST + case eWNI_SME_ENABLE_RMC_REQ: + limProcessRMCMessages(pMac, eLIM_RMC_ENABLE_REQ, pMsgBuf); + break ; + + case eWNI_SME_DISABLE_RMC_REQ: + limProcessRMCMessages(pMac, eLIM_RMC_DISABLE_REQ, pMsgBuf); + break ; +#endif /* defined WLAN_FEATURE_RELIABLE_MCAST */ + + case eWNI_SME_CHANNEL_CHANGE_REQ: + limProcessSmeChannelChangeRequest(pMac, pMsgBuf); + break; + + case eWNI_SME_START_BEACON_REQ: + limProcessSmeStartBeaconReq(pMac, pMsgBuf); + break; + + case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ: + limProcessSmeDfsCsaIeRequest(pMac, pMsgBuf); + break; + default: vos_mem_free((v_VOID_t*)pMsg->bodyptr); pMsg->bodyptr = NULL; @@ -5746,3 +5774,212 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) return bufConsumed; } /*** end limProcessSmeReqMessages() ***/ + +/** + * limProcessSmeStartBeaconReq() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function processes SME request messages from HDD or upper layer + * application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the SME message type + * @param *pMsgBuf A pointer to the SME message buffer + * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed. + * FALSE - if pMsgBuf is not to be freed. + */ +static void +limProcessSmeStartBeaconReq(tpAniSirGlobal pMac, tANI_U32 * pMsg) +{ + tpSirStartBeaconIndication pBeaconStartInd; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + + if( pMsg == NULL ) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pBeaconStartInd = (tpSirStartBeaconIndication)pMsg; + sessionId = pBeaconStartInd->sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId)) == NULL) + { + limLog(pMac, LOGW, "Session does not exist for given sessionId %d", + pBeaconStartInd->sessionId); + return; + } + + if (pBeaconStartInd->beaconStartStatus == VOS_TRUE) + { + /* + * Currently this Indication comes from SAP + * to start Beacon Tx on a DFS channel + * since beaconing has to be done on DFS + * channel only after CAC WAIT is completed. + * On a DFS Channel LIM does not start beacon + * Tx right after the WDA_ADD_BSS_RSP. + */ + limApplyConfiguration(pMac,psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + } + else + { + limLog(pMac, LOGE,FL("Invalid Beacon Start Indication")); + return; + } +} + +static void +limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + tpSirChanChangeRequest pChannelChangeReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + tPowerdBm maxTxPwr; + if( pMsg == NULL ) + { + limLog(pMac, LOGE,FL("pMsg is NULL")); + return; + } + pChannelChangeReq = (tpSirChanChangeRequest)pMsg; + sessionId = pChannelChangeReq->sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId)) == NULL) + { + limLog(pMac, LOGW, "Session does not exist for given sessionId %d", + pChannelChangeReq->sessionId); + return; + } + + if (eLIM_AP_ROLE == psessionEntry->limSystemRole) + psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_SAP_DFS; + else + psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION; + + maxTxPwr = cfgGetRegulatoryMaxTransmitPower( pMac, + pChannelChangeReq->targetChannel ); + + if (pChannelChangeReq->messageType == eWNI_SME_CHANNEL_CHANGE_REQ + && + maxTxPwr != WDA_MAX_TXPOWER_INVALID) + { + /* + * Issue a set channel request with + * with channel bonding mode as + * PHY_SINGLE_CHANNEL_CENTERED + * TODO:Handle the channel bonding mode + * 40Mhz and 80Mhz Channel width for SAP + * channel change. + */ + + /* Store the New Channel Params in psessionEntry */ + if (psessionEntry->currentOperChannel != + pChannelChangeReq->targetChannel) + { + limLog(pMac, LOGW,FL("switch old chnl %d --> new chnl %d "), + psessionEntry->currentOperChannel, + pChannelChangeReq->targetChannel); + + limSetChannel(pMac, pChannelChangeReq->targetChannel, + PHY_SINGLE_CHANNEL_CENTERED, + maxTxPwr, + psessionEntry->peSessionId); + + psessionEntry->currentOperChannel = + pChannelChangeReq->targetChannel; + + /* + *TODO:As of now the supported Channel width + * is only 20Mhz. AP Channel Bonding Mode for + * 40 Mhz and 80Mhz is pending implementation. + */ + psessionEntry->htSecondaryChannelOffset = + PHY_SINGLE_CHANNEL_CENTERED; + psessionEntry->htSupportedChannelWidthSet = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + psessionEntry->htRecommendedTxWidthSet = + psessionEntry->htSupportedChannelWidthSet; + } + + } + else + { + limLog(pMac, LOGE,FL("Invalid Request/maxTxPwr")); + } +} + +/** + * limProcessSmeDfsCsaIeRequest() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function processes SME request messages from HDD or upper layer + * application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + */ +static void +limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + + tpSirDfsCsaIeRequest pDfsCsaIeRequest = (tSirDfsCsaIeRequest *)pMsg; + //tANI_U8 sessionId = pDfsCsaIeRequest->sessionId; + tpPESession psessionEntry; + int i; + + if ( pMsg == NULL ) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + for (i=0; i<pMac->lim.maxBssId; i++) + { + psessionEntry = peFindSessionBySessionId(pMac, i); + if (psessionEntry && psessionEntry->valid && + eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + break; + } + } + + /* target channel */ + psessionEntry->gLimChannelSwitch.primaryChannel = + pDfsCsaIeRequest->targetChannel; + + /* Channel switch announcement needs to be included in beacon */ + psessionEntry->dfsIncludeChanSwIe = VOS_TRUE; + psessionEntry->gLimChannelSwitch.switchCount = LIM_MAX_CSA_IE_UPDATES; + + /* Send CSA IE request from here */ + if (schSetFixedBeaconFields(pMac, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to set CSA IE in beacon"));) + return; + } + + /* First beacon update request is sent here, the remaining updates are + * done when the FW responds back after sending the first beacon after + * the template update + */ + limSendBeaconInd(pMac, psessionEntry); + psessionEntry->gLimChannelSwitch.switchCount--; + + return; +} diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c index d849d8a1ed41..2b85d11f4649 100644 --- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c +++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c @@ -2916,6 +2916,7 @@ void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, return; } #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /** ----------------------------------------------------------------- \brief limSendSmeCandidateFoundInd() - sends eWNI_SME_CANDIDATE_FOUND_IND @@ -2957,3 +2958,51 @@ limSendSmeCandidateFoundInd(tpAniSirGlobal pMac, tANI_U8 sessionId) } /*** end limSendSmeCandidateFoundInd() ***/ #endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/** ----------------------------------------------------------------- + \brief limSendSmeDfsEventNotify() - sends + eWNI_SME_DFS_RADAR_FOUND + After receiving WMI_PHYERR_EVENTID indication frame from FW, this + function sends a eWNI_SME_DFS_RADAR_FOUND to SME to notify + that a RADAR is found on current operating channel and SAP- + has to move to a new channel. + \param pMac - global mac structure + \param msgType - message type received from lower layer + \param event - event data received from lower layer + \return none + \sa +----------------------------------------------------------------- */ +void +limSendSmeDfsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, void *event) +{ + tSirMsgQ mmhMsg; + mmhMsg.type = eWNI_SME_DFS_RADAR_FOUND; + mmhMsg.bodyptr = event; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} + +/** ----------------------------------------------------------------- + \brief limSendSmeAPChannelSwitchResp() - sends + eWNI_SME_CHANNEL_CHANGE_RSP + After receiving WDA_SWITCH_CHANNEL_RSP indication this + function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify + that the Channel change has been done to the specified target + channel in the Channel change request + \param pMac - global mac structure + \param psessionEntry - session info + \param pChnlParams - Channel switch params +--------------------------------------------------------------------*/ +void +limSendSmeAPChannelSwitchResp(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tpSwitchChannelParams pChnlParams) +{ + tSirMsgQ mmhMsg; + mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP; + mmhMsg.bodyptr = (void *)pChnlParams; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h index 6e2602aa4598..d28c5728bfb9 100644 --- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h +++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h @@ -123,5 +123,11 @@ void limSendSmeTdlsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, #endif #endif +void limSendSmeDfsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, + void *event); +void limSendSmeAPChannelSwitchResp(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tpSwitchChannelParams pChnlParams); + #endif /* __LIM_SEND_SME_RSP_H */ diff --git a/CORE/MAC/src/pe/sch/schBeaconGen.c b/CORE/MAC/src/pe/sch/schBeaconGen.c index 50fa74e776c4..827f61880696 100644 --- a/CORE/MAC/src/pe/sch/schBeaconGen.c +++ b/CORE/MAC/src/pe/sch/schBeaconGen.c @@ -64,7 +64,7 @@ const tANI_U8 P2pOui[] = {0x50, 0x6F, 0x9A, 0x9}; tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 *pP2pIeOffset) { - tSirRetStatus status = eSIR_FAILURE; + tSirRetStatus status = eSIR_FAILURE; *pP2pIeOffset = 0; // Extra IE is not present @@ -87,7 +87,7 @@ tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 (*pP2pIeOffset)++; pExtraIe++; - }while(--extraIeLen > 0); + }while(--extraIeLen > 0); return status; } @@ -99,7 +99,7 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, tSirRetStatus status = eSIR_FAILURE; tANI_U32 present, len; tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN]; - + if((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, &present)) != eSIR_SUCCESS) { @@ -117,10 +117,10 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, return status; } - if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && + if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && ((len + *nBytes) <= maxBeaconSize)) { - if((status = wlan_cfgGetStr(pMac, + if((status = wlan_cfgGetStr(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], &len)) == eSIR_SUCCESS) { @@ -230,7 +230,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn for (i=0; i<6; i++) mac->da[i] = 0xff; - + /* Knocking out Global pMac update */ /* limGetMyMacAddr(pMac, mac->sa); */ /* limGetBssid(pMac, mac->bssId); */ @@ -271,7 +271,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn offset = sizeof( tAniBeaconStruct ); ptr = pMac->sch.schObject.gSchBeaconFrameBegin + offset; - if((psessionEntry->limSystemRole == eLIM_AP_ROLE) + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && (psessionEntry->proxyProbeRspEn)) { /* Initialize the default IE bitmap to zero */ @@ -312,7 +312,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn * Initialize the 'new' fields at the end of the beacon */ - + PopulateDot11fCountry( pMac, &pBcn2->Country, psessionEntry); if(pBcn1->Capabilities.qos) { @@ -336,7 +336,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn } #ifdef WLAN_FEATURE_11AC if(psessionEntry->vhtCapability) - { + { schLog( pMac, LOGW, FL("Populate VHT IEs in Beacon")); PopulateDot11fVHTCaps( pMac, psessionEntry, &pBcn2->VHTCaps ); PopulateDot11fVHTOperation( pMac, &pBcn2->VHTOperation); @@ -350,7 +350,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &pBcn2->ExtSuppRates, psessionEntry ); - + if( psessionEntry->pLimStartBssReq != NULL ) { PopulateDot11fWPA( pMac, &psessionEntry->pLimStartBssReq->rsnIE, @@ -367,7 +367,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn { if(psessionEntry->wps_state != SAP_WPS_DISABLED) { - PopulateDot11fBeaconWPSIEs( pMac, &pBcn2->WscBeacon, psessionEntry); + PopulateDot11fBeaconWPSIEs( pMac, &pBcn2->WscBeacon, psessionEntry); } } else @@ -395,7 +395,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn } } - if((psessionEntry->limSystemRole == eLIM_AP_ROLE) + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && (psessionEntry->proxyProbeRspEn)) { /* Can be efficiently updated whenever new IE added in Probe response in future */ @@ -447,7 +447,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn extraIeOffset = nBytes; //TODO: Append additional IE here. - schAppendAddnIE(pMac, psessionEntry, + schAppendAddnIE(pMac, psessionEntry, pMac->sch.schObject.gSchBeaconFrameEnd + nBytes, SCH_MAX_BEACON_SIZE, &nBytes); @@ -461,7 +461,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn if(eSIR_SUCCESS == status) { //Update the P2P Ie Offset - pMac->sch.schObject.p2pIeOffset = + pMac->sch.schObject.p2pIeOffset = pMac->sch.schObject.gSchBeaconOffsetBegin + TIM_IE_SIZE + extraIeOffset + p2pIeOffset; } @@ -696,7 +696,7 @@ void writeBeaconToMemory(tpAniSirGlobal pMac, tANI_U16 size, tANI_U16 length, tp for (i=0; i < pMac->sch.schObject.gSchBeaconOffsetEnd; i++) pMac->sch.schObject.gSchBeaconFrameBegin[size++] = pMac->sch.schObject.gSchBeaconFrameEnd[i]; } - + // Update the beacon length pBeacon = (tpAniBeaconStruct) pMac->sch.schObject.gSchBeaconFrameBegin; // Do not include the beaconLength indicator itself @@ -765,8 +765,8 @@ schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg) { PELOGE(schLog(pMac, LOGE, FL("session lookup fails"));) goto end; - } - + } + // If SME is not in normal mode, no need to generate beacon diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h index 13db475cebdd..73c848fac186 100644 --- a/CORE/SAP/inc/sapApi.h +++ b/CORE/SAP/inc/sapApi.h @@ -363,7 +363,6 @@ typedef struct sap_MaxAssocExceededEvent_s { v_MACADDR_t macaddr; } tSap_MaxAssocExceededEvent; - /* This struct will be filled in and passed to tpWLAN_SAPEventCB that is provided during WLANSAP_StartBss call The event id corresponding to structure in the union is defined in comment next to the structure @@ -565,6 +564,7 @@ typedef struct sap_SoftapStats_s { int sapSetPreferredChannel(tANI_U8* ptr); void sapCleanupChannelList(void); +void sapCleanupAllChannelList(void); /*========================================================================== FUNCTION WLANSAP_Set_WpsIe @@ -1536,6 +1536,67 @@ VOS_STATUS WLANSAP_RegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType, VOS_STATUS WLANSAP_DeRegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen ); +/*========================================================================== + + FUNCTION WLANSAP_ChannelChangeRequest + DESCRIPTION + This API is used to send an Indication to SME/PE to change the + current operating channel to a different target channel. + + The Channel change will be issued by SAP under the following + scenarios. + 1. A radar indication is received during SAP CAC WAIT STATE and + channel change is required. + 2. A radar indication is received during SAP STARTED STATE and + channel change is required. + + DEPENDENCIES + NA. + +PARAMETERS + +IN + pvosGCtx: Pointer to vos global context structure + TargetChannel: New target channel for channel change. + +RETURN VALUE + The VOS_STATUS code associated with performing the operation + +VOS_STATUS_SUCCESS: Success + +SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_ChannelChangeRequest(v_PVOID_t pvosGCtx, tANI_U8 tArgetChannel); + +/*========================================================================== + + FUNCTION WLANSAP_StartBeaconReq + DESCRIPTION + This API is used to send an Indication to SME/PE to start + beaconing on the current operating channel. + + Brief:When SAP is started on DFS channel and when ADD BSS RESP is received + LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When + CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon + request to LIM. + + DEPENDENCIES + NA. + +PARAMETERS + +IN + pvosGCtx: Pointer to vos global context structure + +RETURN VALUE + The VOS_STATUS code associated with performing the operation + +VOS_STATUS_SUCCESS: Success + +SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_StartBeaconReq(v_PVOID_t pSapCtx); + #ifdef __cplusplus } diff --git a/CORE/SAP/src/sapApiLinkCntl.c b/CORE/SAP/src/sapApiLinkCntl.c index 2a87dbd22d69..ae623ac8f00a 100644 --- a/CORE/SAP/src/sapApiLinkCntl.c +++ b/CORE/SAP/src/sapApiLinkCntl.c @@ -409,7 +409,18 @@ WLANSAP_RoamCallback (v_PVOID_t) eSAP_STATUS_SUCCESS ); break; - default: + case eCSR_ROAM_DFS_RADAR_IND: + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Received Radar Indication", __func__); + sapContext->SapDfsInfo.target_channel = + sapIndicateRadar(sapContext, pCsrRoamInfo->dfs_event); + break; + case eCSR_ROAM_SET_CHANNEL_RSP: + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Received set channel response", __func__); + break; + + default: VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, CSR roamStatus not handled roamStatus = %s (%d)\n", __func__, get_eRoamCmdStatus_str(roamStatus), roamStatus); break; @@ -559,13 +570,29 @@ WLANSAP_RoamCallback case eCSR_ROAM_RESULT_INFRA_STARTED: VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", __func__, "eCSR_ROAM_RESULT_INFRA_STARTED", roamResult); - /* Fill in the event structure */ - sapEvent.event = eSAP_MAC_START_BSS_SUCCESS; - sapEvent.params = pCsrRoamInfo; - sapEvent.u1 = roamStatus; - sapEvent.u2 = roamResult; + /* + * If the Current Channel is DFS then move the + * SAP State eSAP_DFS_CAC_WAIT and post the + * eSAP_DFS_CHANNEL_CAC_START event + */ + if (vos_nv_getChannelEnabledState(sapContext->channel) == NV_CHANNEL_DFS) + { + sapContext->sapsMachine = eSAP_DFS_CAC_WAIT; + sapEvent.event = eSAP_DFS_CHANNEL_CAC_START; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + } + else + { + /* Fill in the event structure */ + sapEvent.event = eSAP_MAC_START_BSS_SUCCESS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = roamStatus; + sapEvent.u2 = roamResult; + } - /* Handle event */ + /* Handle event */ vosStatus = sapFsm(sapContext, &sapEvent); if(!VOS_IS_STATUS_SUCCESS(vosStatus)) { @@ -636,6 +663,114 @@ WLANSAP_RoamCallback } break; + + case eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND: + if (eSAP_DFS_CAC_WAIT == sapContext->sapsMachine) + { + if (VOS_TRUE == sapContext->SapDfsInfo.sap_radar_found_status) + { + /* + * If Radar is found, while in DFS CAC WAIT State then + * post stop and destroy the CAC timer and post a + * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND to sapFsm. + */ + vos_timer_stop(&sapContext->SapDfsInfo.sap_dfs_cac_timer); + vos_timer_destroy(&sapContext->SapDfsInfo.sap_dfs_cac_timer); + sapContext->SapDfsInfo.is_dfs_cac_timer_running = 0; + + sapEvent.event = eSAP_DFS_CHANNEL_CAC_RADAR_FOUND; + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + } + } + else + { + /* Further actions to be taken here */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "In %s, eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in" + "(%d) state\n", __func__, sapContext->sapsMachine); + } + break; + case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS: + { + /* Channel change is successful. If the new channel is a DFS + * channel, then we will to perform channel availability check + * for 60 seconds + */ + sapContext->channel = + sapContext->SapDfsInfo.target_channel; + + /* Identify if this is channel change in radar detected state */ + if (VOS_TRUE == sapContext->SapDfsInfo.sap_radar_found_status && + eSAP_DISCONNECTING == sapContext->sapsMachine) + { + /* check if currently selected channel is a DFS channel */ + if (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState(sapContext->channel)) + { + sapContext->sapsMachine = eSAP_DISCONNECTED; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, from state %s => %s", __func__, + "eSAP_DISCONNECTING", "DISCONNECTED"); + + /* DFS Channel */ + sapEvent.event = eSAP_DFS_CHANNEL_CAC_START; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + } + else + { + /* non-DFS channel */ + sapContext->sapsMachine = eSAP_STARTING; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, from state %s => %s", __func__, + "eSAP_DISCONNECTING", "eSAP_STARTING"); + + sapContext->SapDfsInfo.sap_radar_found_status = VOS_FALSE; + sapEvent.event = eSAP_MAC_START_BSS_SUCCESS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = eCSR_ROAM_INFRA_IND; + sapEvent.u2 = eCSR_ROAM_RESULT_INFRA_STARTED; + } + + /* Handle the event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + + } + else + { + /* We may have a requirment in the future for SAP to perform + * channel change, hence leaving this here + */ + } + + break; + } + + case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE: + { + /* This is much more serious issue, we have to vacate the + * channel due to the presence of radar but our channel change + * failed, stop the BSS operation completely and inform hostapd + */ + sapContext->sapsMachine = eSAP_DISCONNECTED; + + /* Inform cfg80211 and hostapd that BSS is not alive anymore */ + } + default: VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, CSR roamResult = %s (%d) not handled\n", __func__,get_eCsrRoamResult_str(roamResult),roamResult); diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c index ddba2f0b2e69..184857b2feeb 100644 --- a/CORE/SAP/src/sapFsm.c +++ b/CORE/SAP/src/sapFsm.c @@ -93,6 +93,48 @@ static VOS_STATUS sapGetChannelList(ptSapContext sapContext, v_U8_t **channelList, v_U8_t *numberOfChannels); #endif + +/*========================================================================== + FUNCTION sapGet5GHzChannelList + + DESCRIPTION + Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] available + channels in the current regulatory domain. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext: SAP Context + + RETURN VALUE + NA + + SIDE EFFECTS +============================================================================*/ +static VOS_STATUS sapGet5GHzChannelList(ptSapContext sapContext); + +/*========================================================================== + FUNCTION sapStartDfsCacTimer + + DESCRIPTION + Function to start the DFS CAC timer when SAP is started on DFS Channel + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext: SAP Context + RETURN VALUE + DFS Timer start status + SIDE EFFECTS +============================================================================*/ + +int sapStartDfsCacTimer(ptSapContext sapContext); + /*---------------------------------------------------------------------------- * Externalized Function Definitions * -------------------------------------------------------------------------*/ @@ -881,6 +923,87 @@ sapFsm } break; + case eSAP_DFS_CAC_WAIT: + if (msg == eSAP_DFS_CHANNEL_CAC_START) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT"); + sapStartDfsCacTimer(sapContext); + } + else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) + { + /* Radar found while performing channel availability + * check, need to switch the channel again + */ + eCsrPhyMode phyMode = + sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode); + tHalHandle hHal = + (tHalHandle)vos_get_context(VOS_MODULE_ID_SME, sapContext->pvosGCtx); + + /* SAP to be moved to DISCONNECTING state */ + sapContext->sapsMachine = eSAP_DISCONNECTING; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n"); + + if (sapContext->SapDfsInfo.target_channel) + { + sme_SelectCBMode(hHal, phyMode, + sapContext->SapDfsInfo.target_channel); + } + + /* + * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND: + * A Radar is found on current DFS Channel + * while in CAC WAIT period So, do a channel switch + * to randomly selected target channel. + * Send the Channel change message to SME/PE. + * sap_radar_found_status is set to 1 + */ + + WLANSAP_ChannelChangeRequest((v_PVOID_t)sapContext, + sapContext->SapDfsInfo.target_channel); + } + else if (msg == eSAP_DFS_CHANNEL_CAC_END) + { + /* + * eSAP_DFS_CHANNEL_CAC_END: + * CAC Period elapsed and there was no radar + * found so, SAP can continue beaconing. + * sap_radar_found_status is set to 0 + */ + WLANSAP_StartBeaconReq((v_PVOID_t)sapContext); + + /* Transition from eSAP_STARTING to eSAP_STARTED + * (both without substates) + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, from state channel = %d %s => %s", + __func__,sapContext->channel, "eSAP_STARTING", + "eSAP_STARTED"); + + sapContext->sapsMachine = eSAP_STARTED; + + /*Action code for transition */ + vosStatus = sapSignalHDDevent(sapContext, roamInfo, + eSAP_START_BSS_EVENT, + (v_PVOID_t)eSAP_STATUS_SUCCESS); + + /* Transition from eSAP_STARTING to eSAP_STARTED + * (both without substates) + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, from state %s => %s", + __func__, "eSAP_DFS_CAC_WAIT", "eSAP_STARTED"); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_DFS_CAC_WAIT", msg); + } + break; + case eSAP_STARTING: if (msg == eSAP_MAC_START_BSS_SUCCESS ) { @@ -1449,3 +1572,197 @@ static VOS_STATUS sapGetChannelList(ptSapContext sapContext, return VOS_STATUS_SUCCESS; } #endif + +/* + * Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] + * available channels in the current regulatory domain. + */ +static VOS_STATUS sapGet5GHzChannelList(ptSapContext sapContext) +{ + v_U8_t count = 0; + int i; + if (NULL == sapContext) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid sapContext pointer on sapGetChannelList"); + return VOS_STATUS_E_FAULT; + } + + sapContext->SapAllChnlList.channelList = + (v_U8_t *)vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN); + if (NULL == sapContext->SapAllChnlList.channelList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + " Memory Allocation failed sapGetChannelList"); + return VOS_STATUS_E_FAULT; + } + + for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ ) + { + if( regChannels[i].enabled == NV_CHANNEL_ENABLE || + regChannels[i].enabled == NV_CHANNEL_DFS ) + { + sapContext->SapAllChnlList.channelList[count] = + rfChannels[i].channelNum; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s[%d] CHANNEL = %d",__func__, __LINE__, + sapContext->SapAllChnlList.channelList[count]); + count++; + } + } + + sapContext->SapAllChnlList.numChannel = count; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s[%d] NUMBER OF CHANNELS count = %d" + "sapContext->SapAllChnlList.numChannel = %d", + __func__,__LINE__,count,sapContext->SapAllChnlList.numChannel); + return VOS_STATUS_SUCCESS; +} + +/* + * This function randomly selects the channel to switch after the detection + * of radar + * param sapContext - sap context + * dfs_event - Dfs information from DFS + * return - channel to which AP wishes to switch + */ +v_U8_t sapIndicateRadar(ptSapContext sapContext,tSirSmeDfsEventInd *dfs_event) +{ + v_U8_t available_chan_idx[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + int available_chan_count, numGChannels = 0, numAChannels = 0; + v_U8_t total_num_channels = 0; + v_U8_t target_channel = 0; + int i; + + if (NULL == sapContext || NULL == dfs_event) + { + /* Invalid sap context of dfs event passed */ + return 0; + } + + if (!dfs_event->dfs_radar_status) + { + /*dfs status does not indicate a radar on the channel-- False Alarm*/ + return 0; + } + + /* set the Radar Found flag in SapDfsInfo */ + sapContext->SapDfsInfo.sap_radar_found_status = VOS_TRUE; + + + sapGet5GHzChannelList(sapContext); + total_num_channels = sapContext->SapAllChnlList.numChannel; + + /* + * Find how many G channels are present in the channel list + */ + for(i = 0; i < RF_CHAN_14; i++ ) + { + if( regChannels[i].enabled ) + { + numGChannels++; + } + } + numAChannels = (total_num_channels - numGChannels); + + /* + * (1) skip static turbo channel as it will require STA to be in + * static turbo to work. + * (2) skip channel which's marked with radar detction + * (3) WAR: we allow user to config not to use any DFS channel + * (4) When we pick a channel, skip excluded 11D channels + * (5) Create the available channel list with the above rules + */ + + for(i = 0, available_chan_count = 0; i<= total_num_channels; i++) + { + if (sapContext->SapAllChnlList.channelList[i] == + dfs_event->ieee_chan_number) + { + continue;//skip the channel on which radar is found + } + available_chan_idx[available_chan_count++] = + sapContext->SapAllChnlList.channelList[i]; + } + + if(available_chan_count) + { + v_U32_t random_byte = 0; + + /* logic to generate a random index */ + get_random_bytes(&random_byte,1); + i = (random_byte + jiffies) % available_chan_count; + + /* + * Pick the channel from the random index + * in available_chan_idx list + */ + target_channel = (available_chan_idx[i]); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s[%d]: Target channel Index = %d target_channel = %d", + __func__,__LINE__, i, target_channel); + return target_channel; + } + + return 0; +} + +/* + * CAC timer callback function. + * Post eSAP_DFS_CHANNEL_CAC_END event to sapFsm(). + */ +void sapDfsCacTimerCallback(void *data) +{ + ptSapContext sapContext = (ptSapContext)data; + tWLAN_SAPEvent sapEvent; + + /* Check to ensure that SAP is in DFS WAIT state*/ + if (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT ) + { + vos_timer_destroy(&sapContext->SapDfsInfo.sap_dfs_cac_timer); + sapContext->SapDfsInfo.is_dfs_cac_timer_running = 0; + /* + * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sapFsm + */ + sapEvent.event = eSAP_DFS_CHANNEL_CAC_END; + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + sapFsm(sapContext, &sapEvent); + } +} + +/* + * Function to start the DFS CAC Timer + * when SAP is started on a DFS channel + */ +int sapStartDfsCacTimer(ptSapContext sapContext) +{ + VOS_STATUS status; + if (sapContext == NULL) + { + return 0; + } + if (sapContext->SapDfsInfo.ignore_cac) + { + /* + * If User has set to ignore the CAC + * so, continue without CAC Timer. + */ + return 2; + } + vos_timer_init(&sapContext->SapDfsInfo.sap_dfs_cac_timer, + VOS_TIMER_TYPE_SW, + sapDfsCacTimerCallback, (v_PVOID_t)sapContext); + /*Start the CAC timer for 60 Seconds*/ + status = vos_timer_start(&sapContext->SapDfsInfo.sap_dfs_cac_timer, 60000); + if (status == VOS_STATUS_SUCCESS) + { + sapContext->SapDfsInfo.is_dfs_cac_timer_running = 1; + return 1; + } + else + { + return 0; + } +} diff --git a/CORE/SAP/src/sapFsm_ext.h b/CORE/SAP/src/sapFsm_ext.h index 5535732b235c..32548c5da400 100644 --- a/CORE/SAP/src/sapFsm_ext.h +++ b/CORE/SAP/src/sapFsm_ext.h @@ -50,6 +50,9 @@ typedef enum eSAP_MAC_START_FAILS, eSAP_HDD_STOP_INFRA_BSS, eSAP_WRITE_REMOTE_AMP_ASSOC, + eSAP_DFS_CHANNEL_CAC_START, + eSAP_DFS_CHANNEL_CAC_RADAR_FOUND, + eSAP_DFS_CHANNEL_CAC_END, eSAP_NO_MSG }eSapMsg_t; diff --git a/CORE/SAP/src/sapInternal.h b/CORE/SAP/src/sapInternal.h index aa23a9ba40aa..8409cf99c45a 100644 --- a/CORE/SAP/src/sapInternal.h +++ b/CORE/SAP/src/sapInternal.h @@ -121,6 +121,7 @@ typedef struct sSapContext tSapContext; typedef enum { eSAP_DISCONNECTED, eSAP_CH_SELECT, + eSAP_DFS_CAC_WAIT, eSAP_STARTING, eSAP_STARTED, eSAP_DISCONNECTING @@ -137,6 +138,20 @@ typedef struct sSapQosCfg { v_U8_t WmmIsEnabled; } tSapQosCfg; +typedef struct sSapDfsInfo { + vos_timer_t sap_dfs_cac_timer; + v_U8_t sap_radar_found_status; + v_U8_t is_dfs_cac_timer_running; + + /* + * New channel to move to when a Radar is + * detected on current Channel + */ + v_U8_t target_channel; + v_U8_t last_radar_found_channel; + v_U8_t ignore_cac; +}tSapDfsInfo; + typedef struct sSapContext { vos_lock_t SapGlobalLock; @@ -208,6 +223,18 @@ typedef struct sSapContext { // session to scan tANI_BOOLEAN isScanSessionOpen; + /* + * This list of channels will hold 5Ghz enabled,DFS in the + * Current RegDomain.This list will be used to select a channel, + * for SAP to start including any DFS channel and also to select + * any random channel[5Ghz-(NON-DFS/DFS)],if SAP is operating + * on a DFS channel and a RADAR is detected on the channel. + */ + tSapChannelListInfo SapAllChnlList; + + //Information Required for SAP DFS Master mode + tSapDfsInfo SapDfsInfo; + } *ptSapContext; @@ -772,6 +799,23 @@ eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode ); void sapUpdateUnsafeChannelList(void); #endif /* FEATURE_WLAN_CH_AVOID */ +/*--------------------------------------------------------------------------- +FUNCTION sapIndicateRadar + +DESCRIPTION Function to implement actions on Radar Detection when SAP is on + DFS Channel + +DEPENDENCIES PARAMETERS +IN sapContext : Sap Context which hold SapDfsInfo + dfs_event : Event from DFS Module + +RETURN VALUE : Target Channel For SAP to Move on to when Radar is Detected. + +SIDE EFFECTS +---------------------------------------------------------------------------*/ +v_U8_t +sapIndicateRadar(ptSapContext sapContext,tSirSmeDfsEventInd *dfs_event); + #ifdef __cplusplus } #endif diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c index b644747209af..9865ade148cb 100644 --- a/CORE/SAP/src/sapModule.c +++ b/CORE/SAP/src/sapModule.c @@ -2363,3 +2363,130 @@ VOS_STATUS WLANSAP_DeRegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType, return VOS_STATUS_E_FAULT; } + +/*========================================================================== + FUNCTION WLANSAP_ChannelChangeRequest + + DESCRIPTION + This API is used to send an Indication to SME/PE to change the + current operating channel to a different target channel. + + The Channel change will be issued by SAP under the following + scenarios. + 1. A radar indication is received during SAP CAC WAIT STATE and + channel change is required. + 2. A radar indication is received during SAP STARTED STATE and + channel change is required. + DEPENDENCIES + NA. + + PARAMETERS + IN + sapContext: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_ChannelChangeRequest(v_PVOID_t pSapCtx, tANI_U8 tArgetChannel) +{ + ptSapContext sapContext = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + sapContext = (ptSapContext)pSapCtx; + + if ( NULL == sapContext ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RoamChannelChangeReq( hHal, + sapContext->sessionId, tArgetChannel); + + if (halStatus == eHAL_STATUS_SUCCESS) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_StartBeaconReq + DESCRIPTION + This API is used to send an Indication to SME/PE to start + beaconing on the current operating channel. + + Brief:When SAP is started on DFS channel and when ADD BSS RESP is received + LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When + CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon + request to LIM. + + DEPENDENCIES + NA. + +PARAMETERS + +IN + pvosGCtx: Pointer to vos global context structure + +RETURN VALUE + The VOS_STATUS code associated with performing the operation + +VOS_STATUS_SUCCESS: Success + +SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_StartBeaconReq(v_PVOID_t pSapCtx) +{ + ptSapContext sapContext = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + tANI_U8 dfsCacWaitStatus = 0; + sapContext = (ptSapContext)pSapCtx; + + if ( NULL == sapContext ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /* No Radar was found during CAC WAIT, So start Beaconing */ + if (sapContext->SapDfsInfo.sap_radar_found_status == 0) + { + /* CAC Wait done without any Radar Detection */ + dfsCacWaitStatus = 1; + halStatus = sme_RoamStartBeaconReq( hHal, + sapContext->sessionId, dfsCacWaitStatus); + if (halStatus == eHAL_STATUS_SUCCESS) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_E_FAULT; +} diff --git a/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h b/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h index 1941422a1548..58d233028f05 100644 --- a/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h +++ b/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h @@ -32,8 +32,6 @@ ---------- --- -------------------------------------------------------- ===========================================================================*/ - - #ifndef __DFS_PHYERR_PEREGRINE_H__ #define __DFS_PHYERR_PEREGRINE_H__ diff --git a/CORE/SERVICES/WMA/regdomain.c b/CORE/SERVICES/WMA/regdomain.c index bf324c6d9a76..5a0b8d498174 100644 --- a/CORE/SERVICES/WMA/regdomain.c +++ b/CORE/SERVICES/WMA/regdomain.c @@ -372,7 +372,7 @@ u_int32_t regdmn_getwmodesnreg(u_int32_t modesAvail, return modesAvail; } -static void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail, +void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail, u_int32_t modeSelect) { const REG_DOMAIN *regdomain2G = NULL; diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 9ac4beabb503..f7f4d9e8b3a6 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -1678,9 +1678,7 @@ static int wma_unified_phyerr_rx_event_handler(void * handle, * wmi_unified_comb_phyerr_rx_event.bufp is a char pointer, * which isn't correct here - what we have received here * is an array of TLV-style PHY errors. - * We should ensure that we only decode 'num_phyerr_events' - * worth of events! - */ + */ n = 0;/* Start just after the header */ bufp = param_tlvs->bufp; while (n < pe_hdr->buf_len) @@ -1704,8 +1702,8 @@ static int wma_unified_phyerr_rx_event_handler(void * handle, * what we currently have. * Since buf_len is 32 bits, we check if it overflows * a large 32 bit value. It's not 0x7fffffff because - * we increase n by (buf_len + sizeof(hdr)), which would - * in itself cause n to overflow. + * we increase n by (buf_len + sizeof(hdr)), which would + * in itself cause n to overflow. * If "int" is 64 bits then this becomes a moot point. */ if (ev->hdr.buf_len > 0x7f000000) @@ -1746,11 +1744,11 @@ static int wma_unified_phyerr_rx_event_handler(void * handle, } } - /* - * Advance the buffer pointer to the next PHY error. - * buflen is the length of this payload, so we need to - * advance past the current header _AND_ the payload. - */ + /* + * Advance the buffer pointer to the next PHY error. + * buflen is the length of this payload, so we need to + * advance past the current header _AND_ the payload. + */ n += sizeof(*ev) + ev->hdr.buf_len; }/*end while()*/ @@ -1769,6 +1767,7 @@ static int wma_unified_phyerr_rx_event_handler(void * handle, */ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, wda_tgt_cfg_cb tgt_cfg_cb, + wda_dfs_radar_indication_cb radar_ind_cb, tMacOpenParameters *mac_params) { tp_wma_handle wma_handle; @@ -1928,6 +1927,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, wmi_unified_register_event_handler(wma_handle->wmi_handle, WMI_PHYERR_EVENTID, wma_unified_phyerr_rx_event_handler); + /* Firmware debug log */ vos_status = dbglog_init(wma_handle->wmi_handle); if (vos_status != VOS_STATUS_SUCCESS) { @@ -13432,12 +13432,12 @@ v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info) } } -static void wma_set_regdomain(u_int32_t regdmn) +static void wma_set_regdomain(struct regulatory *regdmn) { void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); u_int32_t modeSelect = 0xFFFFFFFF; - wma->dfs_ic->current_dfs_regdomain = wma_set_dfs_regdomain(wma,regdmn); + wma->dfs_ic->current_dfs_regdomain = wma_set_dfs_regdomain(wma, regdmn->reg_domain); switch (wma->phy_capability) { case WMI_11G_CAPABILITY: case WMI_11NG_CAPABILITY: @@ -14984,7 +14984,7 @@ wma_dfs_configure_channel(struct ieee80211com *dfs_ic, * Configure the regulatory domain for DFS radar filter initialization */ int -wma_set_dfs_regdomain(tp_wma_handle wma,u_int32_t regdmn) +wma_set_dfs_regdomain(tp_wma_handle wma, u_int32_t regdmn) { u_int8_t ctl; if (regdmn < 0) diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index cbbf3247e936..a62fb0fe613f 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -998,6 +998,8 @@ VOS_STATUS wma_update_vdev_tbl(tp_wma_handle wma_handle, u_int8_t vdev_id, #ifndef QCA_WIFI_ISOC int32_t regdmn_get_regdmn_for_country(u_int8_t *alpha2); +void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail, + u_int32_t modeSelect); /*get the ctl from regdomain*/ u_int8_t regdmn_get_ctl_for_regdmn(u_int32_t reg_dmn); diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h index 3a4c852d004d..bb5f5d6f57ac 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -466,6 +466,13 @@ typedef enum eCSR_ROAM_CCX_ADJ_AP_REPORT_IND, eCSR_ROAM_CCX_BCN_REPORT_IND, #endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */ + + // Radar indication from lower layers + eCSR_ROAM_DFS_RADAR_IND, + eCSR_ROAM_SET_CHANNEL_RSP, + + // Channel sw update notification + eCSR_ROAM_DFS_CHAN_SW_NOTIFY }eRoamCmdStatus; @@ -559,6 +566,16 @@ typedef enum eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED, #endif #endif + +#ifdef FEATURE_CESIUM_PROPRIETARY + eCSR_ROAM_RESULT_IBSS_PEER_INFO_SUCCESS, + eCSR_ROAM_RESULT_IBSS_PEER_INFO_FAILED, +#endif + eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND, + eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS, + eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE, + eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, + eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_FAILURE, }eCsrRoamResult; @@ -1203,6 +1220,8 @@ typedef struct tagCsrRoamInfo tANI_U8* assocReqPtr; tANI_S8 rxRssi; + tSirSmeDfsEventInd dfs_event; + tSirChanChangeResponse *channelChangeRespEvent; }tCsrRoamInfo; diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h index 53d3d50cf91d..7ed8f39ab3df 100644 --- a/CORE/SME/inc/csrInternal.h +++ b/CORE/SME/inc/csrInternal.h @@ -1422,4 +1422,20 @@ eHalStatus csrHandoffRequest(tpAniSirGlobal pMac, tCsrHandoffRequest *pHandoffIn tANI_BOOLEAN csrRoamIsStaMode(tpAniSirGlobal pMac, tANI_U32 sessionId); #endif +#if defined WLAN_FEATURE_RELIABLE_MCAST +eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId); +#endif /* WLAN_FEATURE_RELIABLE_MCAST */ + +/* Post Channel Change Indication */ +eHalStatus csrRoamChannelChangeReq( tpAniSirGlobal pMac, + tANI_U32 sessionId, tANI_U8 targetChannel); + +/* Post Beacon Tx Start Indication */ +eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac, + tANI_U32 sessionId, tANI_U8 dfsCacWaitStatus); + +eHalStatus +csrRoamSendChanSwIERequest(tpAniSirGlobal pMac, tANI_U8 sessionId, + tANI_U8 targetChannel, tANI_U8 csaIeReqd); #endif diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 548834fa4287..2747e4ceba60 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -3288,4 +3288,10 @@ eHalStatus sme_AddChAvoidCallback void (*pCallbackfn)(void *hdd_context, void *indi_param) ); #endif /* FEATURE_WLAN_CH_AVOID */ + +eHalStatus sme_RoamChannelChangeReq( tHalHandle hHal, + tANI_U8 sessionId, tANI_U8 targetChannel); + +eHalStatus sme_RoamStartBeaconReq( tHalHandle hHal, + tANI_U8 sessionId, tANI_U8 dfsCacWaitStatus); #endif //#if !defined( __SME_API_H ) diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 776b9bff9ac2..03ef64d80dff 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -17166,6 +17166,7 @@ VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId, pSession->suppCckmIeInfo.cckmIeLen = ccKmIeLen; return status; } + /* --------------------------------------------------------------------------- \fn csrRoamReadTSF \brief This function reads the TSF; and also add the time elapsed since @@ -17196,3 +17197,76 @@ VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp) return status; } #endif /*FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */ + +/* + * Post Channel Change Request to LIM + * This API is primarily used to post + * Channel Change Req for SAP + */ +eHalStatus +csrRoamChannelChangeReq( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U8 targetChannel) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirChanChangeRequest *pMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL + ( " Session does not exist for session id %d" ), sessionId); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc( sizeof(tSirChanChangeRequest) ); + if (!pMsg) + { + return ( eHAL_STATUS_FAILURE ); + } + + vos_mem_set((void *)pMsg, sizeof( tSirChanChangeRequest ), 0); + + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_CHANNEL_CHANGE_REQ); + pMsg->sessionId = sessionId; + pMsg->targetChannel = targetChannel; + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return ( status ); +} + +/* + * Post Beacon Tx Start request to LIM + * immediately after SAP CAC WAIT is + * completed without any RADAR indications. + */ +eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U8 dfsCacWaitStatus) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirStartBeaconIndication *pMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL + ( " Session does not exist for session id %d" ), sessionId); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(sizeof(tSirStartBeaconIndication)); + + if (!pMsg) + { + return eHAL_STATUS_FAILURE; + } + + vos_mem_set((void *)pMsg, sizeof( tSirStartBeaconIndication ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_START_BEACON_REQ); + pMsg->sessionId = sessionId; + pMsg->beaconStartStatus = dfsCacWaitStatus; + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return ( status ); +} diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index f701be8cde88..c52e90f96714 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -114,6 +114,14 @@ eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm ); #endif +/* Message processor for events from DFS */ +eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac, + v_U16_t msg_type,void *pMsgBuf); + +/* Channel Change Response Indication Handler */ +eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac, + v_U16_t msg_type,void *pMsgBuf); + //Internal SME APIs eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme) { @@ -1898,6 +1906,51 @@ eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, } #endif +/*------------------------------------------------------------------ + * + * Handle the DFS Radar Event and indicate it to the SAP + * + *------------------------------------------------------------------*/ +eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac,v_U16_t msgType,void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + tSirSmeDfsEventInd *dfs_event = (tSirSmeDfsEventInd *) pMsgBuf; + tANI_U32 SessionId = dfs_event->sessionId; + eRoamCmdStatus roamStatus; + eCsrRoamResult roamResult; + + pRoamInfo.dfs_event = + (tSirSmeDfsEventInd *)vos_mem_malloc(sizeof(tSirSmeDfsEventInd)); + pRoamInfo.dfs_event->sessionId = SessionId; + pRoamInfo.dfs_event->ieee_chan_number = dfs_event->ieee_chan_number; + pRoamInfo.dfs_event->chan_freq = dfs_event->chan_freq; + pRoamInfo.dfs_event->dfs_radar_status = dfs_event->dfs_radar_status; + pRoamInfo.dfs_event->use_nol = dfs_event->use_nol; + + switch (msgType) + { + case eWNI_SME_DFS_RADAR_FOUND: + { + roamStatus = eCSR_ROAM_DFS_RADAR_IND; + roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND; + break; + } + default: + { + smsLog(pMac, LOG1, "%s: Invalid DFS message = 0x%x", __func__, + msgType); + status = eHAL_STATUS_FAILURE; + return status; + } + } + + /* Indicate Radar Event to SAP */ + csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, + roamStatus, roamResult); + return status; +} + #if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD) /*------------------------------------------------------------------ * @@ -2417,6 +2470,34 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) break; #endif /* FEATURE_WLAN_CH_AVOID */ + case eWNI_SME_DFS_RADAR_FOUND: + if (pMsg->bodyptr) + { + status = dfsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); + vos_mem_free( pMsg->bodyptr ); + } + else + { + smsLog( pMac, LOGE, + "Empty rsp message for (eWNI_SME_DFS_RADAR_FOUND)," + "nothing to process"); + } + break ; + + case eWNI_SME_CHANNEL_CHANGE_RSP: + if (pMsg->bodyptr) + { + status = sme_ProcessChannelChangeResp(pMac, + pMsg->type, pMsg->bodyptr); + vos_mem_free( pMsg->bodyptr ); + } + else + { + smsLog( pMac, LOGE, + "Empty rsp message for (eWNI_SME_CHANNEL_CHANGE_RSP)," + "nothing to process"); + } + break ; default: if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) @@ -10830,3 +10911,105 @@ eHalStatus sme_AddChAvoidCallback } #endif /* FEATURE_WLAN_CH_AVOID */ +/* ------------------------------------------------------------------------- + \fn sme_RoamChannelChangeReq + \brief API to Indicate Channel change to new target channel + \param hHal - The handle returned by macOpen + \param sessionId - session ID + \param targetChannel - New Channel to move the SAP to. + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_RoamChannelChangeReq( tHalHandle hHal, + tANI_U8 sessionId, tANI_U8 targetChannel ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamChannelChangeReq( pMac, sessionId, targetChannel); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* ------------------------------------------------------------------------- + \fn sme_ProcessChannelChangeResp + \brief API to Indicate Channel change response message to SAP. + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac, + v_U16_t msg_type, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + eCsrRoamResult roamResult; + tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf; + tANI_U32 SessionId = pChnlParams->peSessionId; + + pRoamInfo.channelChangeRespEvent = + (tSirChanChangeResponse *)vos_mem_malloc( + sizeof(tSirChanChangeResponse)); + if (NULL == pRoamInfo.channelChangeRespEvent) + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, "Channel Change Event Allocation Failed: %d\n", + status); + return status; + } + if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP) + { + pRoamInfo.channelChangeRespEvent->sessionId = SessionId; + pRoamInfo.channelChangeRespEvent->newChannelNumber = + pChnlParams->channelNumber; + pRoamInfo.channelChangeRespEvent->secondaryChannelOffset = + pChnlParams->secondaryChannelOffset; + + if (pChnlParams->status == eHAL_STATUS_SUCCESS) + { + pRoamInfo.channelChangeRespEvent->channelChangeStatus = 1; + roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS; + } + else + { + pRoamInfo.channelChangeRespEvent->channelChangeStatus = 0; + roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE; + } + + csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, + eCSR_ROAM_SET_CHANNEL_RSP, roamResult); + + } + else + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, "Invalid Channel Change Resp Message: %d\n", + status); + } + return status; +} + +/* ------------------------------------------------------------------------- + \fn sme_RoamStartBeaconReq + \brief API to Indicate LIM to start Beacon Tx + \after SAP CAC Wait is completed. + \param hHal - The handle returned by macOpen + \param sessionId - session ID + \param dfsCacWaitStatus - CAC WAIT status flag + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_RoamStartBeaconReq( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 dfsCacWaitStatus) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamStartBeaconReq( pMac, sessionId, dfsCacWaitStatus); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index ca735ecaa54f..7fc08fa97881 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -405,6 +405,7 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize ) #if defined (QCA_WIFI_2_0) && \ !defined (QCA_WIFI_ISOC) hdd_update_tgt_cfg, + hdd_dfs_indicate_radar, #else NULL, #endif diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h index 634c985b53cd..c78c4cd24921 100644 --- a/CORE/WDA/inc/wlan_qct_wda.h +++ b/CORE/WDA/inc/wlan_qct_wda.h @@ -498,10 +498,15 @@ VOS_STATUS WDA_TxPacket(void *pWDA, * open WDA context */ +#ifndef QCA_WIFI_ISOC VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t pOSContext, - wda_tgt_cfg_cb pTgtUpdCB, - wda_dfs_radar_indication_cb radar_ind_cb, - tMacOpenParameters *pMacParams ) ; + wda_tgt_cfg_cb pTgtUpdCB, + wda_dfs_radar_indication_cb radar_ind_cb, + tMacOpenParameters *pMacParams ) ; +#else +VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t pOSContext, + wda_tgt_cfg_cb pTgtUpdCB, tMacOpenParameters *pMacParams ) ; +#endif #ifdef QCA_WIFI_2_0 #define WDA_start wma_start @@ -1305,6 +1310,9 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); #endif #endif +/* Message to Indicate Radar Presence on SAP Channel */ +#define WDA_DFS_RADAR_IND SIR_HAL_DFS_RADAR_IND + tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg); #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames |
