import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6620 / wlan / mgmt / wnm.c
1 /*
2 ** $Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1 $
3 */
4
5 /*! \file "wnm.c"
6 \brief This file includes the 802.11v default vale and functions.
7 */
8
9
10
11 /*
12 ** $Log: wnm.c $
13 *
14 * 01 05 2012 tsaiyuan.hsu
15 * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v
16 * add timing measurement support for 802.11v.
17 *
18 *
19 */
20
21 /*******************************************************************************
22 * C O M P I L E R F L A G S
23 ********************************************************************************
24 */
25
26 /*******************************************************************************
27 * E X T E R N A L R E F E R E N C E S
28 ********************************************************************************
29 */
30 #include "precomp.h"
31
32 #if CFG_SUPPORT_802_11V
33
34 /*******************************************************************************
35 * C O N S T A N T S
36 ********************************************************************************
37 */
38
39 #define WNM_MAX_TOD_ERROR 0
40 #define WNM_MAX_TOA_ERROR 0
41 #define MICRO_TO_10NANO(x) ((x)*100)
42 /*******************************************************************************
43 * D A T A T Y P E S
44 ********************************************************************************
45 */
46
47 /*******************************************************************************
48 * P U B L I C D A T A
49 ********************************************************************************
50 */
51
52 /*******************************************************************************
53 * P R I V A T E D A T A
54 ********************************************************************************
55 */
56
57 static UINT_8 ucTimingMeasToken;
58
59 /*******************************************************************************
60 * M A C R O S
61 ********************************************************************************
62 */
63
64 /*******************************************************************************
65 * F U N C T I O N D E C L A R A T I O N S
66 ********************************************************************************
67 */
68
69 WLAN_STATUS
70 wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter,
71 IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus);
72
73 VOID
74 wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter,
75 IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler);
76
77 VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
78 /*******************************************************************************
79 * F U N C T I O N S
80 ********************************************************************************
81 */
82
83 /*----------------------------------------------------------------------------*/
84 /*!
85 *
86 * \brief This routine is called to process the 802.11v wnm category action frame.
87 *
88 *
89 * \note
90 * Called by: Handle Rx mgmt request
91 */
92 /*----------------------------------------------------------------------------*/
93 VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
94 {
95 P_WLAN_ACTION_FRAME prRxFrame;
96
97 ASSERT(prAdapter);
98 ASSERT(prSwRfb);
99
100 prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader;
101
102 #if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
103 if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) {
104 wnmTimingMeasRequest(prAdapter, prSwRfb);
105 return;
106 }
107 #endif
108
109 DBGLOG(WNM, TRACE, ("Unsupport WNM action frame: %d\n", prRxFrame->ucAction));
110 }
111
112 #if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
113 /*----------------------------------------------------------------------------*/
114 /*!
115 *
116 * \brief This routine is called to report timing measurement data.
117 *
118 */
119 /*----------------------------------------------------------------------------*/
120 VOID
121 wnmReportTimingMeas(IN P_ADAPTER_T prAdapter,
122 IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA)
123 {
124 P_STA_RECORD_T prStaRec;
125
126 prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex);
127
128 if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
129 return;
130 }
131
132 DBGLOG(WNM, TRACE, ("wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA));
133
134 if (!prStaRec->rWNMTimingMsmt.ucTrigger)
135 return;
136
137 prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD);
138 prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA);
139 }
140
141 /*----------------------------------------------------------------------------*/
142 /*!
143 * @brief This function will handle TxDone(TimingMeasurement) Event.
144 *
145 * @param[in] prAdapter Pointer to the Adapter structure.
146 * @param[in] prMsduInfo Pointer to the MSDU_INFO_T.
147 * @param[in] rTxDoneStatus Return TX status of the Timing Measurement frame.
148 *
149 * @retval WLAN_STATUS_SUCCESS
150 */
151 /*----------------------------------------------------------------------------*/
152 WLAN_STATUS
153 wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter,
154 IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
155 {
156 P_STA_RECORD_T prStaRec;
157
158 ASSERT(prAdapter);
159 ASSERT(prMsduInfo);
160
161 DBGLOG(WNM, LOUD, ("EVENT-TX DONE: Current Time = %ld\n", kalGetTimeTick()));
162
163 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
164
165 if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
166 return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */
167 }
168
169 DBGLOG(WNM, TRACE,
170 ("wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x",
171 prStaRec->rWNMTimingMsmt.ucDialogToken,
172 prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken, prStaRec->rWNMTimingMsmt.u4ToD,
173 prStaRec->rWNMTimingMsmt.u4ToA));
174
175 prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
176 prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
177
178 wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL);
179
180 return WLAN_STATUS_SUCCESS;
181
182 } /* end of wnmRunEventTimgingMeasTxDone() */
183
184 /*----------------------------------------------------------------------------*/
185 /*!
186 * @brief This function will compose the Timing Measurement frame.
187 *
188 * @param[in] prAdapter Pointer to the Adapter structure.
189 * @param[in] prStaRec Pointer to the STA_RECORD_T.
190 *
191 * @return (none)
192 */
193 /*----------------------------------------------------------------------------*/
194 VOID
195 wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter,
196 IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
197 {
198 P_MSDU_INFO_T prMsduInfo;
199 P_BSS_INFO_T prBssInfo;
200 P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame;
201 UINT_16 u2PayloadLen;
202
203 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
204 ASSERT(prBssInfo);
205
206 prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
207 MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
208
209 if (!prMsduInfo)
210 return;
211
212 prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME)
213 ((UINT_32) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
214
215 prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
216
217 COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr);
218 COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
219 COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
220
221 prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION;
222 prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT;
223
224 /* 3 Compose the frame body's frame. */
225 prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
226 prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken;
227 prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD;
228 prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA;
229 prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR;
230 prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR;
231
232 u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN;
233
234 /* 4 Update information of MSDU_INFO_T */
235 prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */
236 prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
237 prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
238 prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
239 prMsduInfo->fgIs802_1x = FALSE;
240 prMsduInfo->fgIs802_11 = TRUE;
241 prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
242 prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
243 prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
244 prMsduInfo->fgIsBasicRate = FALSE;
245
246 DBGLOG(WNM, TRACE,
247 ("wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n",
248 prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, prTxFrame->u4ToD,
249 prTxFrame->u4ToA));
250
251 /* 4 Enqueue the frame to send this action frame. */
252 nicTxEnqueueMsdu(prAdapter, prMsduInfo);
253
254 return;
255
256 } /* end of wnmComposeTimingMeasFrame() */
257
258 /*----------------------------------------------------------------------------*/
259 /*!
260 *
261 * \brief This routine is called to process the 802.11v timing measurement request.
262 *
263 *
264 * \note
265 * Handle Rx mgmt request
266 */
267 /*----------------------------------------------------------------------------*/
268 VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
269 {
270 P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL;
271 P_STA_RECORD_T prStaRec;
272
273 prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME) prSwRfb->pvHeader;
274 if (!prRxFrame)
275 return;
276
277 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
278 if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
279 return;
280 }
281
282 DBGLOG(WNM, TRACE, ("IEEE 802.11: Received Timing Measuremen Request from "
283 MACSTR "\n", MAC2STR(prStaRec->aucMacAddr)));
284
285 /* reset timing msmt */
286 prStaRec->rWNMTimingMsmt.fgInitiator = TRUE;
287 prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger;
288 if (!prRxFrame->ucTrigger)
289 return;
290
291 prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
292 prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0;
293
294 wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone);
295 }
296
297 #if WNM_UNIT_TEST
298 VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex)
299 {
300 P_STA_RECORD_T prStaRec;
301
302 prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex);
303 if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
304 return;
305 }
306
307 DBGLOG(WNM, INFO, ("IEEE 802.11v: Test Timing Measuremen Request from "
308 MACSTR "\n", MAC2STR(prStaRec->aucMacAddr)));
309
310 prStaRec->rWNMTimingMsmt.fgInitiator = TRUE;
311 prStaRec->rWNMTimingMsmt.ucTrigger = 1;
312
313 prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
314 prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0;
315
316 wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone);
317 }
318 #endif
319
320 #endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */
321
322 #endif /* CFG_SUPPORT_802_11V */