2 ** $Id: @(#) gl_p2p_cfg80211.c@@
5 /*! \file gl_p2p_cfg80211.c
6 \brief Main routines of Linux driver interface for Wi-Fi Direct
7 using cfg80211 interface
9 This file contains the main routines of Linux driver for MediaTek Inc. 802.11
10 Wireless LAN Adapters.
16 /*******************************************************************************
17 * C O M P I L E R F L A G S
18 ********************************************************************************
21 /*******************************************************************************
22 * E X T E R N A L R E F E R E N C E S
23 ********************************************************************************
26 /*******************************************************************************
28 ********************************************************************************
31 /*******************************************************************************
33 ********************************************************************************
36 /*******************************************************************************
38 ********************************************************************************
41 /*******************************************************************************
42 * P R I V A T E D A T A
43 ********************************************************************************
46 /*******************************************************************************
48 ********************************************************************************
51 /*******************************************************************************
52 * F U N C T I O N D E C L A R A T I O N S
53 ********************************************************************************
56 /*******************************************************************************
58 ********************************************************************************
66 rlmObssChnlLevelIn2G4 (
67 P_BSS_INFO_T prBssInfo,
69 ENUM_CHNL_EXT_T eExtend
73 rlmObssChnlLevelIn5G (
74 P_BSS_INFO_T prBssInfo,
76 ENUM_CHNL_EXT_T eExtend
80 /*----------------------------------------------------------------------------*/
82 * \brief Different concurrent network has itself channel lists, and
83 * concurrent networks should have been recorded in channel lists.
84 * If role of active P2P is GO, assume associated AP of AIS will
85 * record our Beacon for P2P GO because of same channel.
87 * Note: If we have scenario of different channel in the future,
88 * the internal FW communication channel shall be established.
94 /*----------------------------------------------------------------------------*/
97 P_BSS_INFO_T prBssInfo,
100 ENUM_CHNL_EXT_T eExtend
103 UINT_8 ucChannelLevel;
107 if (eBand == BAND_2G4) {
108 ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel,eExtend);
110 /* (TBD) If concurrent networks permit different channel, extra
111 * channel judgement should be added. Please refer to
112 * previous version of this file.
115 else if (eBand == BAND_5G) {
116 ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel,eExtend);
118 /* (TBD) If concurrent networks permit different channel, extra
119 * channel judgement should be added. Please refer to
120 * previous version of this file.
124 ucChannelLevel = CHNL_LEVEL0;
127 return ucChannelLevel;
130 /*----------------------------------------------------------------------------*/
138 /*----------------------------------------------------------------------------*/
140 rlmObssChnlLevelIn2G4 (
141 P_BSS_INFO_T prBssInfo,
143 ENUM_CHNL_EXT_T eExtend
146 UINT_8 i, ucChannelLevel;
147 UINT_8 ucSecChannel, ucCenterChannel;
148 UINT_8 ucAffectedChnl_L, ucAffectedChnl_H;
152 ucChannelLevel = CHNL_LEVEL2;
154 /* Calculate center channel for 2.4G band */
155 if (eExtend == CHNL_EXT_SCA) {
156 ucCenterChannel = ucPriChannel + 2;
157 ucSecChannel = ucPriChannel + 4;
159 else if (eExtend == CHNL_EXT_SCB) {
160 ucCenterChannel = ucPriChannel - 2;
161 ucSecChannel = ucPriChannel - 4;
166 ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14);
168 /* Calculated low/upper channels in affected freq range */
169 ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ?
170 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET);
172 ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ?
173 14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET);
176 /* Check intolerant (Non-HT) channel list */
177 ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
178 for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] &&
179 i <= CHNL_LIST_SZ_2G; i++) {
180 if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L &&
181 prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) &&
182 prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) {
184 ucChannelLevel = CHNL_LEVEL0;
185 goto L_2G4_level_end;
189 /* Check 20M BW request channel list */
190 ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
191 for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] &&
192 i <= CHNL_LIST_SZ_2G; i++) {
193 if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L &&
194 prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) {
196 ucChannelLevel = CHNL_LEVEL0;
197 goto L_2G4_level_end;
201 /* Check 2.4G primary channel list */
202 ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G);
203 for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] &&
204 i <= CHNL_LIST_SZ_2G; i++) {
205 if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L &&
206 prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) &&
207 prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) {
209 ucChannelLevel = CHNL_LEVEL0;
210 goto L_2G4_level_end;
214 /* Check 2.4G secondary channel list */
215 ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G);
216 for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] &&
217 i <= CHNL_LIST_SZ_2G; i++) {
218 if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L &&
219 prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) &&
220 prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) {
222 ucChannelLevel = CHNL_LEVEL0;
223 goto L_2G4_level_end;
229 return ucChannelLevel;
232 /*----------------------------------------------------------------------------*/
240 /*----------------------------------------------------------------------------*/
242 rlmObssChnlLevelIn5G (
243 P_BSS_INFO_T prBssInfo,
245 ENUM_CHNL_EXT_T eExtend
248 UINT_8 i, ucChannelLevel;
253 ucChannelLevel = CHNL_LEVEL2;
255 /* Calculate center channel for 2.4G band */
256 if (eExtend == CHNL_EXT_SCA) {
257 ucSecChannel = ucPriChannel + 4;
259 else if (eExtend == CHNL_EXT_SCB) {
260 ucSecChannel = ucPriChannel - 4;
265 ASSERT(ucSecChannel >= 36);
267 /* Check 5G primary channel list */
268 ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G);
269 for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] &&
270 i <= CHNL_LIST_SZ_5G; i++) {
271 if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) {
273 ucChannelLevel = CHNL_LEVEL0;
276 else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) {
277 ucChannelLevel = CHNL_LEVEL1;
281 /* Check non-HT channel list */
282 ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G);
283 for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] &&
284 i <= CHNL_LIST_SZ_5G; i++) {
285 if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) {
287 ucChannelLevel = CHNL_LEVEL0;
290 else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) {
291 ucChannelLevel = CHNL_LEVEL1;
295 /* Check secondary channel list */
296 ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G);
297 for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] &&
298 i <= CHNL_LIST_SZ_5G; i++) {
299 if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) {
301 ucChannelLevel = CHNL_LEVEL0;
308 return ucChannelLevel;
311 /*----------------------------------------------------------------------------*/
319 /*----------------------------------------------------------------------------*/
321 rlmObssScanExemptionRsp (
322 P_ADAPTER_T prAdapter,
323 P_BSS_INFO_T prBssInfo,
327 P_MSDU_INFO_T prMsduInfo;
328 P_ACTION_20_40_COEXIST_FRAME prTxFrame;
330 /* To do: need an algorithm to do judgement. Now always reject request */
332 prMsduInfo = (P_MSDU_INFO_T)
333 cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
334 if (prMsduInfo == NULL) {
338 DBGLOG(RLM, INFO, ("Send 20/40 coexistence rsp frame!\n"));
340 prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket;
342 prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
343 COPY_MAC_ADDR(prTxFrame->aucDestAddr,
344 ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr);
345 COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
346 COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
348 prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
349 prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;
351 /* To do: find correct algorithm */
352 prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
353 prTxFrame->rBssCoexist.ucLength = 1;
354 prTxFrame->rBssCoexist.ucData = 0;
356 ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN);
358 prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
359 prMsduInfo->ucStaRecIndex =prSwRfb->ucStaRecIdx;
360 prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
361 prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
362 prMsduInfo->fgIs802_1x = FALSE;
363 prMsduInfo->fgIs802_11 = TRUE;
364 prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5;
365 prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
366 prMsduInfo->pfTxDoneHandler = NULL;
367 prMsduInfo->fgIsBasicRate = FALSE;
369 /* Send them to HW queue */
370 nicTxEnqueueMsdu(prAdapter, prMsduInfo);