wifi: renew patch drivers/net/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / mt5931 / 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 (
67     P_BSS_INFO_T        prBssInfo,
68     UINT_8              ucPriChannel,
69     ENUM_CHNL_EXT_T     eExtend
70     );
71
72 static UINT_8
73 rlmObssChnlLevelIn5G (
74     P_BSS_INFO_T        prBssInfo,
75     UINT_8              ucPriChannel,
76     ENUM_CHNL_EXT_T     eExtend
77     );
78
79
80 /*----------------------------------------------------------------------------*/
81 /*!
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.
86 *
87 *        Note: If we have scenario of different channel in the future,
88 *              the internal FW communication channel shall be established.
89 *
90 * \param[in]
91 *
92 * \return none
93 */
94 /*----------------------------------------------------------------------------*/
95 UINT_8
96 rlmObssChnlLevel (
97     P_BSS_INFO_T        prBssInfo,
98     ENUM_BAND_T         eBand,
99     UINT_8              ucPriChannel,
100     ENUM_CHNL_EXT_T     eExtend
101     )
102 {
103     UINT_8              ucChannelLevel;
104
105     ASSERT(prBssInfo);
106
107     if (eBand == BAND_2G4) {
108         ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel,eExtend);
109
110         /* (TBD) If concurrent networks permit different channel, extra
111          *       channel judgement should be added. Please refer to
112          *       previous version of this file.
113          */
114     }
115     else if (eBand == BAND_5G) {
116         ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel,eExtend);
117
118         /* (TBD) If concurrent networks permit different channel, extra
119          *       channel judgement should be added. Please refer to
120          *       previous version of this file.
121          */
122     }
123     else {
124         ucChannelLevel = CHNL_LEVEL0;
125     }
126
127     return ucChannelLevel;
128 }
129
130 /*----------------------------------------------------------------------------*/
131 /*!
132 * \brief
133 *
134 * \param[in]
135 *
136 * \return none
137 */
138 /*----------------------------------------------------------------------------*/
139 static UINT_8
140 rlmObssChnlLevelIn2G4 (
141     P_BSS_INFO_T        prBssInfo,
142     UINT_8              ucPriChannel,
143     ENUM_CHNL_EXT_T     eExtend
144     )
145 {
146     UINT_8      i, ucChannelLevel;
147     UINT_8      ucSecChannel, ucCenterChannel;
148     UINT_8      ucAffectedChnl_L, ucAffectedChnl_H;
149
150     ASSERT(prBssInfo);
151
152     ucChannelLevel = CHNL_LEVEL2;
153
154     /* Calculate center channel for 2.4G band */
155     if (eExtend == CHNL_EXT_SCA) {
156         ucCenterChannel = ucPriChannel + 2;
157         ucSecChannel = ucPriChannel + 4;
158     }
159     else if (eExtend == CHNL_EXT_SCB) {
160         ucCenterChannel = ucPriChannel - 2;
161         ucSecChannel = ucPriChannel - 4;
162     }
163     else {
164         return CHNL_LEVEL0;
165     }
166     ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14);
167
168     /* Calculated low/upper channels in affected freq range */
169     ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ?
170         1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET);
171
172     ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ?
173         14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET);
174
175
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) {
183
184             ucChannelLevel = CHNL_LEVEL0;
185             goto L_2G4_level_end;
186         }
187     }
188
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)) {
195
196             ucChannelLevel = CHNL_LEVEL0;
197             goto L_2G4_level_end;
198         }
199     }
200
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) {
208
209             ucChannelLevel = CHNL_LEVEL0;
210             goto L_2G4_level_end;
211         }
212     }
213
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) {
221
222             ucChannelLevel = CHNL_LEVEL0;
223             goto L_2G4_level_end;
224         }
225     }
226
227 L_2G4_level_end:
228
229     return ucChannelLevel;
230 }
231
232 /*----------------------------------------------------------------------------*/
233 /*!
234 * \brief
235 *
236 * \param[in]
237 *
238 * \return none
239 */
240 /*----------------------------------------------------------------------------*/
241 static UINT_8
242 rlmObssChnlLevelIn5G (
243     P_BSS_INFO_T        prBssInfo,
244     UINT_8              ucPriChannel,
245     ENUM_CHNL_EXT_T     eExtend
246     )
247 {
248     UINT_8      i, ucChannelLevel;
249     UINT_8      ucSecChannel;
250
251     ASSERT(prBssInfo);
252
253     ucChannelLevel = CHNL_LEVEL2;
254
255     /* Calculate center channel for 2.4G band */
256     if (eExtend == CHNL_EXT_SCA) {
257         ucSecChannel = ucPriChannel + 4;
258     }
259     else if (eExtend == CHNL_EXT_SCB) {
260         ucSecChannel = ucPriChannel - 4;
261     }
262     else {
263         return CHNL_LEVEL0;
264     }
265     ASSERT(ucSecChannel >= 36);
266
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) {
272
273             ucChannelLevel = CHNL_LEVEL0;
274             goto L_5G_level_end;
275         }
276         else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) {
277             ucChannelLevel = CHNL_LEVEL1;
278         }
279     }
280
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) {
286
287             ucChannelLevel = CHNL_LEVEL0;
288             goto L_5G_level_end;
289         }
290         else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) {
291             ucChannelLevel = CHNL_LEVEL1;
292         }
293     }
294
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) {
300
301             ucChannelLevel = CHNL_LEVEL0;
302             goto L_5G_level_end;
303         }
304     }
305
306 L_5G_level_end:
307
308     return ucChannelLevel;
309 }
310
311 /*----------------------------------------------------------------------------*/
312 /*!
313 * \brief
314 *
315 * \param[in]
316 *
317 * \return none
318 */
319 /*----------------------------------------------------------------------------*/
320 VOID
321 rlmObssScanExemptionRsp (
322     P_ADAPTER_T         prAdapter,
323     P_BSS_INFO_T        prBssInfo,
324     P_SW_RFB_T          prSwRfb
325     )
326 {
327     P_MSDU_INFO_T                   prMsduInfo;
328     P_ACTION_20_40_COEXIST_FRAME    prTxFrame;
329
330     /* To do: need an algorithm to do judgement. Now always reject request */
331
332     prMsduInfo = (P_MSDU_INFO_T)
333                  cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
334     if (prMsduInfo == NULL) {
335         return;
336     }
337
338     DBGLOG(RLM, INFO, ("Send 20/40 coexistence rsp frame!\n"));
339
340     prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket;
341
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);
347
348     prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
349     prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;
350
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;
355
356     ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN);
357
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;
368
369     /* Send them to HW queue */
370     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
371 }
372
373
374