import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6628 / wlan / mgmt / p2p_rlm_obss.c
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
65 static UINT_8
66 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend);
67
68 static UINT_8
69 rlmObssChnlLevelIn5G(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 /*----------------------------------------------------------------------------*/
87 UINT_8
88 rlmObssChnlLevel(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 /*----------------------------------------------------------------------------*/
125 static UINT_8
126 rlmObssChnlLevelIn2G4(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 /*----------------------------------------------------------------------------*/
217 static UINT_8
218 rlmObssChnlLevelIn5G(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 /*----------------------------------------------------------------------------*/
285 VOID 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 }