import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6628 / wlan / mgmt / p2p_rlm_obss.c
CommitLineData
6fa3eb70
S
1/*
2** $Id: @(#) gl_p2p_cfg80211.c@@
3*/
4
5/*! \file gl_p2p_cfg80211.c
6 \brief Main routines of Linux driver interface for Wi-Fi Direct
7 using cfg80211 interface
8
9 This file contains the main routines of Linux driver for MediaTek Inc. 802.11
10 Wireless LAN Adapters.
11*/
12
13
14
15
16/*******************************************************************************
17* C O M P I L E R F L A G S
18********************************************************************************
19*/
20
21/*******************************************************************************
22* E X T E R N A L R E F E R E N C E S
23********************************************************************************
24*/
25
26/*******************************************************************************
27* C O N S T A N T S
28********************************************************************************
29*/
30
31/*******************************************************************************
32* D A T A T Y P E S
33********************************************************************************
34*/
35
36/*******************************************************************************
37* P U B L I C D A T A
38********************************************************************************
39*/
40
41/*******************************************************************************
42* P R I V A T E D A T A
43********************************************************************************
44*/
45
46/*******************************************************************************
47* M A C R O S
48********************************************************************************
49*/
50
51/*******************************************************************************
52* F U N C T I O N D E C L A R A T I O N S
53********************************************************************************
54*/
55
56/*******************************************************************************
57* F U N C T I O N S
58********************************************************************************
59*/
60
61
62#include "precomp.h"
63
64
65static UINT_8
66rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend);
67
68static UINT_8
69rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend);
70
71
72/*----------------------------------------------------------------------------*/
73/*!
74* \brief Different concurrent network has itself channel lists, and
75* concurrent networks should have been recorded in channel lists.
76* If role of active P2P is GO, assume associated AP of AIS will
77* record our Beacon for P2P GO because of same channel.
78*
79* Note: If we have scenario of different channel in the future,
80* the internal FW communication channel shall be established.
81*
82* \param[in]
83*
84* \return none
85*/
86/*----------------------------------------------------------------------------*/
87UINT_8
88rlmObssChnlLevel(P_BSS_INFO_T prBssInfo,
89 ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend)
90{
91 UINT_8 ucChannelLevel;
92
93 ASSERT(prBssInfo);
94
95 if (eBand == BAND_2G4) {
96 ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend);
97
98 /* (TBD) If concurrent networks permit different channel, extra
99 * channel judgement should be added. Please refer to
100 * previous version of this file.
101 */
102 } else if (eBand == BAND_5G) {
103 ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend);
104
105 /* (TBD) If concurrent networks permit different channel, extra
106 * channel judgement should be added. Please refer to
107 * previous version of this file.
108 */
109 } else {
110 ucChannelLevel = CHNL_LEVEL0;
111 }
112
113 return ucChannelLevel;
114}
115
116/*----------------------------------------------------------------------------*/
117/*!
118* \brief
119*
120* \param[in]
121*
122* \return none
123*/
124/*----------------------------------------------------------------------------*/
125static UINT_8
126rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend)
127{
128 UINT_8 i, ucChannelLevel;
129 UINT_8 ucSecChannel, ucCenterChannel;
130 UINT_8 ucAffectedChnl_L, ucAffectedChnl_H;
131
132 ASSERT(prBssInfo);
133
134 ucChannelLevel = CHNL_LEVEL2;
135
136 /* Calculate center channel for 2.4G band */
137 if (eExtend == CHNL_EXT_SCA) {
138 ucCenterChannel = ucPriChannel + 2;
139 ucSecChannel = ucPriChannel + 4;
140 } else if (eExtend == CHNL_EXT_SCB) {
141 ucCenterChannel = ucPriChannel - 2;
142 ucSecChannel = ucPriChannel - 4;
143 } else {
144 return CHNL_LEVEL0;
145 }
146 ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14);
147
148 /* Calculated low/upper channels in affected freq range */
149 ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ?
150 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET);
151
152 ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ?
153 14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET);
154
155
156 /* Check intolerant (Non-HT) channel list */
157 ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
158 for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
159 if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L &&
160 prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) &&
161 prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) {
162
163 ucChannelLevel = CHNL_LEVEL0;
164 goto L_2G4_level_end;
165 }
166 }
167
168 /* Check 20M BW request channel list */
169 ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
170 for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
171 if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L &&
172 prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) {
173
174 ucChannelLevel = CHNL_LEVEL0;
175 goto L_2G4_level_end;
176 }
177 }
178
179 /* Check 2.4G primary channel list */
180 ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G);
181 for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
182 if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L &&
183 prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) &&
184 prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) {
185
186 ucChannelLevel = CHNL_LEVEL0;
187 goto L_2G4_level_end;
188 }
189 }
190
191 /* Check 2.4G secondary channel list */
192 ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G);
193 for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
194 if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L &&
195 prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) &&
196 prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) {
197
198 ucChannelLevel = CHNL_LEVEL0;
199 goto L_2G4_level_end;
200 }
201 }
202
203 L_2G4_level_end:
204
205 return ucChannelLevel;
206}
207
208/*----------------------------------------------------------------------------*/
209/*!
210* \brief
211*
212* \param[in]
213*
214* \return none
215*/
216/*----------------------------------------------------------------------------*/
217static UINT_8
218rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend)
219{
220 UINT_8 i, ucChannelLevel;
221 UINT_8 ucSecChannel;
222
223 ASSERT(prBssInfo);
224
225 ucChannelLevel = CHNL_LEVEL2;
226
227 /* Calculate center channel for 2.4G band */
228 if (eExtend == CHNL_EXT_SCA) {
229 ucSecChannel = ucPriChannel + 4;
230 } else if (eExtend == CHNL_EXT_SCB) {
231 ucSecChannel = ucPriChannel - 4;
232 } else {
233 return CHNL_LEVEL0;
234 }
235 ASSERT(ucSecChannel >= 36);
236
237 /* Check 5G primary channel list */
238 ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G);
239 for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) {
240 if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) {
241
242 ucChannelLevel = CHNL_LEVEL0;
243 goto L_5G_level_end;
244 } else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) {
245 ucChannelLevel = CHNL_LEVEL1;
246 }
247 }
248
249 /* Check non-HT channel list */
250 ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G);
251 for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) {
252 if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) {
253
254 ucChannelLevel = CHNL_LEVEL0;
255 goto L_5G_level_end;
256 } else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) {
257 ucChannelLevel = CHNL_LEVEL1;
258 }
259 }
260
261 /* Check secondary channel list */
262 ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G);
263 for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) {
264 if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) {
265
266 ucChannelLevel = CHNL_LEVEL0;
267 goto L_5G_level_end;
268 }
269 }
270
271 L_5G_level_end:
272
273 return ucChannelLevel;
274}
275
276/*----------------------------------------------------------------------------*/
277/*!
278* \brief
279*
280* \param[in]
281*
282* \return none
283*/
284/*----------------------------------------------------------------------------*/
285VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb)
286{
287 P_MSDU_INFO_T prMsduInfo;
288 P_ACTION_20_40_COEXIST_FRAME prTxFrame;
289
290 /* To do: need an algorithm to do judgement. Now always reject request */
291
292 prMsduInfo = (P_MSDU_INFO_T)
293 cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
294 if (prMsduInfo == NULL) {
295 return;
296 }
297
298 DBGLOG(RLM, INFO, ("Send 20/40 coexistence rsp frame!\n"));
299
300 prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket;
301
302 prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
303 COPY_MAC_ADDR(prTxFrame->aucDestAddr,
304 ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr);
305 COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
306 COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
307
308 prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
309 prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;
310
311 /* To do: find correct algorithm */
312 prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
313 prTxFrame->rBssCoexist.ucLength = 1;
314 prTxFrame->rBssCoexist.ucData = 0;
315
316 ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN);
317
318 prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
319 prMsduInfo->ucStaRecIndex = prSwRfb->ucStaRecIdx;
320 prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
321 prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
322 prMsduInfo->fgIs802_1x = FALSE;
323 prMsduInfo->fgIs802_11 = TRUE;
324 prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5;
325 prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
326 prMsduInfo->pfTxDoneHandler = NULL;
327 prMsduInfo->fgIsBasicRate = FALSE;
328
329 /* Send them to HW queue */
330 nicTxEnqueueMsdu(prAdapter, prMsduInfo);
331}