Commit | Line | Data |
---|---|---|
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 | ||
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 | } |