blob: a56189764a20214850bbf2c80e45872b765bd249 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08005 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006/**=============================================================================
7
8 vos_list.c
9
10 \brief
11
12 Description...
13
14
15 Copyright 2008 (c) Qualcomm, Incorporated.
16 All Rights Reserved.
17 Qualcomm Confidential and Proprietary.
18
19 ============================================================================== */
20/* $HEADER$ */
21#include "bapRsnTxRx.h"
22#include "bapRsn8021xFsm.h"
23#include "bapInternal.h"
24#include "vos_trace.h"
25#include "wlan_qct_tl.h"
26#include "vos_memory.h"
27
28
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070029static pnfTxCompleteHandler bapRsnFsmTxCmpHandler;
30static pnfRxFrameHandler bapRsnFsmRxFrameHandler;
Jeff Johnson295189b2012-06-20 16:38:30 -070031
32extern int gReadToSetKey;
33
34
35VOS_STATUS bapRsnRegisterTxRxCallbacks( pnfTxCompleteHandler pfnTxCom, pnfRxFrameHandler pnfRxFrame )
36{
37 if( bapRsnFsmTxCmpHandler || bapRsnFsmRxFrameHandler )
38 {
39 return VOS_STATUS_E_ALREADY;
40 }
41
42 bapRsnFsmTxCmpHandler = pfnTxCom;
43 bapRsnFsmRxFrameHandler = pnfRxFrame;
44
45 return ( VOS_STATUS_SUCCESS );
46}
47
48void bapRsnClearTxRxCallbacks(void)
49{
50 bapRsnFsmTxCmpHandler = NULL;
51 bapRsnFsmRxFrameHandler = NULL;
52}
53
54
55//To reserve a vos_packet for Tx eapol frame
56//If success, pPacket is the packet and pData points to the head.
57static VOS_STATUS bapRsnAcquirePacket( vos_pkt_t **ppPacket, v_U8_t **ppData, v_U16_t size )
58{
59 VOS_STATUS status;
60 vos_pkt_t *pPacket;
61
62 status = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT, size, 1,
63 VOS_TRUE, NULL, NULL );
64 if( VOS_IS_STATUS_SUCCESS( status ) )
65 {
66 status = vos_pkt_reserve_head( pPacket, (v_VOID_t **)ppData, size );
67 if( !VOS_IS_STATUS_SUCCESS( status ) )
68 {
69 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
70 "bapRsnAcquirePacket failed to reserve size = %d\n", size );
71 vos_pkt_return_packet( pPacket );
72 }
73 else
74 {
75 *ppPacket = pPacket;
76 }
77 }
78 else
79 {
80 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
81 "bapRsnAcquirePacket failed to get vos_pkt\n" );
82 }
83
84 return ( status );
85}
86
87
88static VOS_STATUS bapRsnTxCompleteCallback( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus )
89{
90 int retVal;
91 ptBtampContext btampContext; // use btampContext value
92 tCsrRoamSetKey setKeyInfo;
93 tSuppRsnFsm *fsm;
94
95 if (NULL == pvosGCtx)
96 {
97 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070098 "pvosGCtx is NULL in %s", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100 return VOS_STATUS_E_FAULT;
101 }
102
103 btampContext = VOS_GET_BAP_CB(pvosGCtx);
104 if (NULL == btampContext)
105 {
106 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700107 "btampContext is NULL in %s", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109 return VOS_STATUS_E_FAULT;
110 }
111
112 fsm = &btampContext->uFsm.suppFsm;
113 if (NULL == fsm)
114 {
115 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700116 "fsm is NULL in %s", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700117
118 return VOS_STATUS_E_FAULT;
119 }
120
121 //If we get a disconect from upper layer before getting the pkt from TL the
122 //bapRsnFsmTxCmpHandler could be NULL
123 //VOS_ASSERT( bapRsnFsmTxCmpHandler );
124
125 if( bapRsnFsmTxCmpHandler )
126 {
127 //Change the state
128 //Call auth or supp FSM's handler
129 bapRsnFsmTxCmpHandler( pvosGCtx, pPacket, retStatus );
130 }
131 else
132 {
133 vos_pkt_return_packet( pPacket );
134 return (VOS_STATUS_SUCCESS );
135 }
136
137 //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one.
138 /*
139 We will move the Set key to EAPOL Completion handler. We found a race condition betweem
140 sending EAPOL frame and setting Key */
141 if (BAP_SET_RSN_KEY == gReadToSetKey) {
142 vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) );
143 setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES;
144 setKeyInfo.keyDirection = eSIR_TX_RX;
145 vos_mem_copy( setKeyInfo.peerMac, fsm->suppCtx->authMac, sizeof( tAniMacAddr ) );
146 setKeyInfo.paeRole = 0; //this is a supplicant
147 setKeyInfo.keyId = 0; //always
148 setKeyInfo.keyLength = CSR_AES_KEY_LEN;
149 vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->suppCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN );
150
151 if( !VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) )
152 {
153 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, " Supp: gotoStateStaKeySet fail to set key\n" );
154 retVal = ANI_ERROR;
155 }
156 gReadToSetKey = BAP_RESET_RSN_KEY;
157 }
158
159 return (VOS_STATUS_SUCCESS );
160}
161
162
163static VOS_STATUS bapRsnTxFrame( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket )
164{
165 VOS_STATUS status;
166 WLANTL_MetaInfoType metaInfo;
167
168 vos_mem_zero( &metaInfo, sizeof( WLANTL_MetaInfoType ) );
169 metaInfo.ucIsEapol = 1; //only send eapol frame
170 status = WLANTL_TxBAPFrm( pvosGCtx, pPacket, &metaInfo, bapRsnTxCompleteCallback );
171 if( !VOS_IS_STATUS_SUCCESS( status ) )
172 {
173 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
174 "bapRsnTxFrame failed to send vos_pkt status = %d\n", status );
175 }
176
177 return ( status );
178}
179
180
181/*
182 \brief bapRsnSendEapolFrame
183 To push an eapol frame to TL.
184
185 \param pAniPkt - a ready eapol frame that is prepared in tAniPacket format
186*/
187VOS_STATUS bapRsnSendEapolFrame( v_PVOID_t pvosGCtx, tAniPacket *pAniPkt )
188{
189 VOS_STATUS status;
Leo Changec114a02013-05-24 17:19:13 -0700190 vos_pkt_t *pPacket = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700191 v_U8_t *pData, *pSrc;
192 int pktLen = aniAsfPacketGetBytes( pAniPkt, &pSrc );
193
194 if( pktLen <= 0 )
195 {
196 return VOS_STATUS_E_EMPTY;
197 }
198 status = bapRsnAcquirePacket( &pPacket, &pData, pktLen );
Leo Changec114a02013-05-24 17:19:13 -0700199 if( VOS_IS_STATUS_SUCCESS( status ) && ( NULL != pPacket ))
Jeff Johnson295189b2012-06-20 16:38:30 -0700200 {
201 vos_mem_copy( pData, pSrc, pktLen );
202 //Send the packet, need to check whether we have an outstanding packet first.
203 status = bapRsnTxFrame( pvosGCtx, pPacket );
204 if( !VOS_IS_STATUS_SUCCESS( status ) )
205 {
206 vos_pkt_return_packet( pPacket );
207 }
208 }
209
210 return ( status );
211}
212
213
214//TL call this function on Rx frames, should only be EAPOL frames
215VOS_STATUS bapRsnRxCallback( v_PVOID_t pv, vos_pkt_t *pPacket )
216{
217 //Callback to auth or supp FSM's handler
218 VOS_ASSERT( bapRsnFsmRxFrameHandler );
219 if( bapRsnFsmRxFrameHandler )
220 {
221 bapRsnFsmRxFrameHandler( pv, pPacket );
222 }
223 else
224 {
225 //done
226 vos_pkt_return_packet( pPacket );
227 }
228
229 return ( VOS_STATUS_SUCCESS );
230}
231
232
233
234VOS_STATUS bapRsnRegisterRxCallback( v_PVOID_t pvosGCtx )
235{
236 VOS_STATUS status;
237
238 status = WLANTL_RegisterBAPClient( pvosGCtx, WLANBAP_RxCallback, WLANBAP_TLFlushCompCallback );
239 if( !VOS_IS_STATUS_SUCCESS( status ) )
240 {
241 if( VOS_STATUS_E_EXISTS != status )
242 {
243 VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
244 "bapRsnRegisterRxCallback failed with status = %d\n", status );
245 }
246 else
247 {
248 //We consider it ok to register it multiple times because only BAP's RSN should call this
249 status = VOS_STATUS_SUCCESS;
250 }
251 }
252
253 return ( status );
254}
255
256