support different wifi bt chip auto compatible
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / 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 = 0;
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 (
71     IN P_ADAPTER_T              prAdapter,
72     IN P_MSDU_INFO_T            prMsduInfo,
73     IN ENUM_TX_RESULT_CODE_T    rTxDoneStatus
74     );
75
76 VOID
77 wnmComposeTimingMeasFrame (
78     IN P_ADAPTER_T         prAdapter,    
79     IN P_STA_RECORD_T      prStaRec,
80     IN PFN_TX_DONE_HANDLER pfTxDoneHandler
81     );
82
83 VOID
84 wnmTimingMeasRequest (
85     IN P_ADAPTER_T                  prAdapter,
86     IN P_SW_RFB_T                   prSwRfb
87     );
88 /*******************************************************************************
89 *                              F U N C T I O N S
90 ********************************************************************************
91 */
92
93 /*----------------------------------------------------------------------------*/
94 /*!
95 *
96 * \brief This routine is called to process the 802.11v wnm category action frame.
97 *
98 *
99 * \note
100 *      Called by: Handle Rx mgmt request
101 */
102 /*----------------------------------------------------------------------------*/
103 VOID
104 wnmWNMAction (
105     IN P_ADAPTER_T                  prAdapter,
106     IN P_SW_RFB_T                   prSwRfb
107     )
108 {
109     P_WLAN_ACTION_FRAME prRxFrame;
110
111     ASSERT(prAdapter);
112     ASSERT(prSwRfb);
113
114     prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader;
115
116 #if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
117     if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) {
118         wnmTimingMeasRequest(prAdapter, prSwRfb);
119         return;
120     }
121 #endif
122
123     DBGLOG(WNM, TRACE, ("Unsupport WNM action frame: %d\n", prRxFrame->ucAction));
124 }
125
126 #if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
127 /*----------------------------------------------------------------------------*/
128 /*!
129 *
130 * \brief This routine is called to report timing measurement data.
131 *
132 */
133 /*----------------------------------------------------------------------------*/
134 VOID
135 wnmReportTimingMeas (
136     IN P_ADAPTER_T         prAdapter,
137     IN UINT_8              ucStaRecIndex,
138     IN UINT_32             u4ToD,
139     IN UINT_32             u4ToA
140     )
141 {             
142     P_STA_RECORD_T prStaRec;    
143
144     prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex);
145
146     if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
147         return;
148     }    
149     
150     DBGLOG(WNM, TRACE, ("wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA));
151                  
152     if (!prStaRec->rWNMTimingMsmt.ucTrigger)
153           return;
154     
155     prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD);
156     prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA);
157 }
158
159 /*----------------------------------------------------------------------------*/
160 /*!
161 * @brief This function will handle TxDone(TimingMeasurement) Event.
162 *
163 * @param[in] prAdapter      Pointer to the Adapter structure.
164 * @param[in] prMsduInfo     Pointer to the MSDU_INFO_T.
165 * @param[in] rTxDoneStatus  Return TX status of the Timing Measurement frame.
166 *
167 * @retval WLAN_STATUS_SUCCESS
168 */
169 /*----------------------------------------------------------------------------*/
170 WLAN_STATUS
171 wnmRunEventTimgingMeasTxDone (
172     IN P_ADAPTER_T              prAdapter,
173     IN P_MSDU_INFO_T            prMsduInfo,
174     IN ENUM_TX_RESULT_CODE_T    rTxDoneStatus
175     )
176 {
177     P_STA_RECORD_T prStaRec;    
178
179     ASSERT(prAdapter);
180     ASSERT(prMsduInfo);
181
182     DBGLOG(WNM, LOUD, ("EVENT-TX DONE: Current Time = %ld\n", kalGetTimeTick()));
183
184     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
185
186     if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
187         return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */
188     }
189
190     DBGLOG(WNM, TRACE, ("wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x",
191                       prStaRec->rWNMTimingMsmt.ucDialogToken,
192                       prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken,
193                       prStaRec->rWNMTimingMsmt.u4ToD,
194                       prStaRec->rWNMTimingMsmt.u4ToA));
195
196     prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
197     prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;            
198            
199     wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL);
200
201     return WLAN_STATUS_SUCCESS;
202
203 } /* end of wnmRunEventTimgingMeasTxDone() */
204
205 /*----------------------------------------------------------------------------*/
206 /*!
207 * @brief This function will compose the Timing Measurement frame.
208 *
209 * @param[in] prAdapter              Pointer to the Adapter structure.
210 * @param[in] prStaRec               Pointer to the STA_RECORD_T.
211 *
212 * @return (none)
213 */
214 /*----------------------------------------------------------------------------*/
215 VOID
216 wnmComposeTimingMeasFrame (
217     IN P_ADAPTER_T         prAdapter,    
218     IN P_STA_RECORD_T      prStaRec,
219     IN PFN_TX_DONE_HANDLER pfTxDoneHandler
220     )
221 {
222     P_MSDU_INFO_T prMsduInfo;
223           P_BSS_INFO_T prBssInfo;
224     P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame;
225     UINT_16 u2PayloadLen;
226
227     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
228     ASSERT(prBssInfo);
229
230     prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
231                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
232
233     if (!prMsduInfo)
234         return;
235
236     prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME)
237         ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
238
239     prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
240     
241     COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr);
242     COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
243     COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
244
245     prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION;
246     prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT;
247
248     //3 Compose the frame body's frame.
249     prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken;
250     prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken;
251     prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD;
252     prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA;
253     prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR;
254     prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR;
255     
256     u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN;
257
258     //4 Update information of MSDU_INFO_T
259     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
260     prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
261     prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
262     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
263     prMsduInfo->fgIs802_1x = FALSE;
264     prMsduInfo->fgIs802_11 = TRUE;
265     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
266     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
267     prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
268     prMsduInfo->fgIsBasicRate = FALSE;   
269
270     DBGLOG(WNM, TRACE, ("wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n",
271            prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken,
272            prTxFrame->u4ToD, prTxFrame->u4ToA));
273
274     //4 Enqueue the frame to send this action frame.
275     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
276
277     return;
278
279 } /* end of wnmComposeTimingMeasFrame() */
280
281 /*----------------------------------------------------------------------------*/
282 /*!
283 *
284 * \brief This routine is called to process the 802.11v timing measurement request.
285 *
286 *
287 * \note
288 *      Handle Rx mgmt request
289 */
290 /*----------------------------------------------------------------------------*/
291 VOID
292 wnmTimingMeasRequest (
293     IN P_ADAPTER_T                  prAdapter,
294     IN P_SW_RFB_T                   prSwRfb
295     )
296 {             
297     P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL;
298     P_STA_RECORD_T prStaRec;
299
300     prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME)prSwRfb->pvHeader;
301     if (!prRxFrame)
302         return;
303
304     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
305     if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
306         return;
307     }
308
309     DBGLOG(WNM, TRACE, ("IEEE 802.11: Received Timing Measuremen Request from "
310            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
311
312     // reset timing msmt    
313     prStaRec->rWNMTimingMsmt.fgInitiator = TRUE;
314     prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger;
315     if (!prRxFrame->ucTrigger)
316           return;
317     
318     prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
319     prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0;
320     
321     wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone);
322 }
323
324 #if WNM_UNIT_TEST
325 VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex)
326 {
327     P_STA_RECORD_T prStaRec;
328     
329     prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex);
330     if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
331         return;
332     }
333
334     DBGLOG(WNM, INFO, ("IEEE 802.11v: Test Timing Measuremen Request from "
335            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
336
337     prStaRec->rWNMTimingMsmt.fgInitiator = TRUE;
338     prStaRec->rWNMTimingMsmt.ucTrigger = 1;
339     
340     prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken;
341     prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0;
342
343     wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone);
344 }
345 #endif
346
347 #endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */
348
349 #endif /* CFG_SUPPORT_802_11V */