blob: e4dd860bd423755437d853fdad54e0086b24ef5f [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 \file wlan_qct_pal_packet.c
9
10 \brief Implementation for PAL packet. wpt = (Wlan Pal Type) wpal = (Wlan PAL)
11
12 Definitions for platform with VOSS packet support and LA.
13
14 Copyright 2010 (c) Qualcomm, Incorporated. All Rights Reserved.
15
16 Qualcomm Confidential and Proprietary.
17
18 ========================================================================*/
19
20#include "wlan_qct_pal_packet.h"
21#include "wlan_qct_pal_api.h"
22#include "wlan_qct_pal_trace.h"
23#include "vos_packet.h"
24#include "vos_trace.h"
25#include "vos_list.h"
26
27#include <linux/skbuff.h>
28#include "dma-mapping.h"
29
30/*Per spec definition*/
31#define WPAL_ETHERNET_PAKCET_HEADER_SIZE 14
32
33/*Per spec definition - not including QOS field*/
34#define WPAL_802_11_PACKET_HEADER_SIZE 24
35
36/*p is a pointer to wpt_packet*/
37#define WPAL_TO_VOS_PKT(p) ((vos_pkt_t *)(p))
38
39
40typedef struct
41{
42 void* pPhyAddr;
43 wpt_uint32 uLen;
44}wpt_iterator_info;
45
46/* Storage for DXE CB function pointer */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070047static wpalPacketLowPacketCB wpalPacketAvailableCB;
Jeff Johnson295189b2012-06-20 16:38:30 -070048
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -070049/* Temp storage for transport channel DIAG/LOG information
50 * Each channel will update information with different context
51 * Before send stored date to DIAG,
52 * temporary it should be stored */
53static wpt_log_data_stall_type wpalTrasportStallInfo;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -070054
Jeff Johnson295189b2012-06-20 16:38:30 -070055/*
56 wpalPacketInit is no-op for VOSS-support wpt_packet
57*/
58wpt_status wpalPacketInit(void *pPalContext)
59{
60 return eWLAN_PAL_STATUS_SUCCESS;
61}
62
63
64/*
65 wpalPacketClose is no-op for VOSS-support wpt_packet
66*/
67wpt_status wpalPacketClose(void *pPalContext)
68{
69 return eWLAN_PAL_STATUS_SUCCESS;
70}
71
72/*---------------------------------------------------------------------------
73 wpalPacketRXLowResourceCB – RX RAW packer CB function
74 Param:
75 pPacket – Available RX packet
76 userData - PAL Client Context, DXE
77 Return:
78 Status
79---------------------------------------------------------------------------*/
80VOS_STATUS wpalPacketRXLowResourceCB(vos_pkt_t *pPacket, v_VOID_t *userData)
81{
82 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
83 void* pData = NULL;
84
85 if (NULL == pPacket)
86 {
87 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
88 "Get new RX PAL packet fail");
89 return VOS_STATUS_E_FAILURE;
90 }
91 vosStatus = vos_pkt_reserve_head_fast( pPacket, &pData,
92 VPKT_SIZE_BUFFER );
93 if(VOS_STATUS_SUCCESS != vosStatus)
94 {
95 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
96 "Prepare RX packet for DXE fail");
97 return VOS_STATUS_E_FAILURE;
98 }
99
100 if((NULL == wpalPacketAvailableCB) || (NULL == userData))
101 {
102 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
103 "Invalid ARG for new RX packet");
104 return VOS_STATUS_E_FAILURE;
105 }
106
107 wpalPacketAvailableCB( (wpt_packet *)pPacket, userData );
Madan Mohan Koyyalamudic2994452013-08-16 11:27:23 +0530108
Jeff Johnson295189b2012-06-20 16:38:30 -0700109 return VOS_STATUS_SUCCESS;
110}
111
112/*---------------------------------------------------------------------------
113 wpalPacketAlloc – Allocate a wpt_packet from PAL.
114 Param:
115 pktType – specify the type of wpt_packet to allocate
116 nPktSize - packet size
117 Return:
118 A pointer to the wpt_packet. NULL means fail.
119---------------------------------------------------------------------------*/
120wpt_packet * wpalPacketAlloc(wpt_packet_type pktType, wpt_uint32 nPktSize,
121 wpalPacketLowPacketCB rxLowCB, void *usrData)
122{
123 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
124 wpt_packet* pPkt = NULL;
125 vos_pkt_t* pVosPkt = NULL;
126 void* pData = NULL;
Leo Changb419a912013-03-29 18:58:21 -0700127 v_U16_t allocLen;
Jeff Johnson295189b2012-06-20 16:38:30 -0700128 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
129
Jeff Johnson295189b2012-06-20 16:38:30 -0700130 switch (pktType)
131 {
132 case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT:
133 vosStatus = vos_pkt_get_packet(&pVosPkt, VOS_PKT_TYPE_TX_802_11_MGMT,
134 nPktSize, 1, VOS_FALSE,
135 NULL, NULL /*no callback*/);
136 break;
137
138 case eWLAN_PAL_PKT_TYPE_RX_RAW:
Mihir Sheteb20fd742013-12-31 12:41:35 +0530139 /* Set the wpalPacketAvailableCB before we try to get a VOS
140 * packet from the 'free list' and reset it if vos_pkt_get_packet()
141 * returns a valid packet. This order is required to avoid the
142 * race condition:
143 * 1. The below call to vos_pkt_get_packet() in RX_Thread determines
144 * that no more packets are available in the 'free list' and sets
145 * the low resource callbacks.
146 * 2. in parallel vos_pkt_return_packet() is called in MC_Thread for a
147 * Management frame before wpalPacketAlloc() gets a chance to set
148 * wpalPacketAvailableCB and since the 'low resource callbacks'
149 * are set the callback function - wpalPacketRXLowResourceCB is
150 * executed,but since wpalPacketAvailableCB is still NULL the low
151 * resource recovery fails.
152 */
153 wpalPacketAvailableCB = rxLowCB;
154
Jeff Johnson295189b2012-06-20 16:38:30 -0700155 vosStatus = vos_pkt_get_packet(&pVosPkt, VOS_PKT_TYPE_RX_RAW,
156 nPktSize, 1, VOS_FALSE,
157 wpalPacketRXLowResourceCB, usrData);
158
159#ifndef FEATURE_R33D
160 /* Reserve the entire raw rx buffer for DXE */
161 if( vosStatus == VOS_STATUS_SUCCESS )
162 {
Mihir Sheteb20fd742013-12-31 12:41:35 +0530163 wpalPacketAvailableCB = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700164 vosStatus = vos_pkt_reserve_head_fast( pVosPkt, &pData, nPktSize );
165 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700166#endif /* FEATURE_R33D */
Leo Chang59232a82013-05-07 14:25:35 -0700167 if((NULL != pVosPkt) && (VOS_STATUS_E_RESOURCES != vosStatus))
Leo Changb419a912013-03-29 18:58:21 -0700168 {
Leo Chang59232a82013-05-07 14:25:35 -0700169 vos_pkt_get_packet_length(pVosPkt, &allocLen);
170 if (nPktSize != allocLen)
171 {
172 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
173 "RX packet alloc has problem, discard this frame, Len %d", allocLen);
174 vos_pkt_return_packet(pVosPkt);
175 return NULL;
176 }
Leo Changb419a912013-03-29 18:58:21 -0700177 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 break;
179
180 default:
181 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800182 " try to allocate unsupported packet type (%d)", pktType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700183 break;
184 }
185
186 if(VOS_IS_STATUS_SUCCESS(vosStatus))
187 {
188 pPkt = (wpt_packet *)pVosPkt;
189 }
190
191
192 return pPkt;
193}/*wpalPacketAlloc*/
194
195
196
197/*---------------------------------------------------------------------------
198 wpalPacketFree – Free a wpt_packet chain for one particular type.
199 For our legacy UMAC, it is not needed because vos_packet contains pal_packet.
200 Param:
201 pPkt – pointer to a wpt_packet
202 Return:
203 eWLAN_PAL_STATUS_SUCCESS - success
204---------------------------------------------------------------------------*/
205wpt_status wpalPacketFree(wpt_packet *pPkt)
206{
207 VOS_STATUS vosStatus;
208
209 if(NULL != pPkt->pInternalData)
210 {
211 wpalMemoryFree(pPkt->pInternalData);
212 }
213 vosStatus = vos_pkt_return_packet(WPAL_TO_VOS_PKT(pPkt));
214
215 //With VOSS support, we can cast between wpt_status and VOS_STATUS
216 return (wpt_status)vosStatus;
217}/*wpalPacketFree*/
218
219
220/*---------------------------------------------------------------------------
221 wpalPacketGetLength – Get number of bytes in a wpt_packet. It include the
222 bytes in a BD if it exist.
223 Param:
224 pPkt - pointer to a packet to be freed.
225 Return:
226 Length of the data include layer-2 headers. For example, if the frame
227 is 802.3, the length includes the ethernet header.
228---------------------------------------------------------------------------*/
229wpt_uint32 wpalPacketGetLength(wpt_packet *pPkt)
230{
231 v_U16_t len = 0, pktLen = 0;
232
233 // Validate the parameter pointers
234 if (unlikely(NULL == pPkt))
235 {
236 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700237 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700238 return eWLAN_PAL_STATUS_E_INVAL;
239 }
240
241
242 if( WPAL_PACKET_GET_BD_POINTER(pPkt) )
243 {
244 len = WPAL_PACKET_GET_BD_LENGTH(pPkt);
245 }
246 if( VOS_IS_STATUS_SUCCESS(vos_pkt_get_packet_length(WPAL_TO_VOS_PKT(pPkt), &pktLen)) )
247 {
248 len += pktLen;
249 }
250 else
251 {
Arif Hussain9a5d5382013-11-17 22:05:35 -0800252 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700253 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700254 }
255
256 return ((wpt_uint32)len);
257}/*wpalPacketGetLength*/
258
259
260/*---------------------------------------------------------------------------
261 wpalPacketRawTrimHead – Move the starting offset and return the head pointer
262 before the moving. The function can only be used with raw packets,
263 whose buffer is one piece and allocated by WLAN driver. This also
264 reduce the length of the packet.
265 Param:
266 pPkt - pointer to a wpt_packet.
267 size – number of bytes to take off the head.
268 Return:
269 A pointer to the original buffer head before the trimming.
270---------------------------------------------------------------------------*/
271wpt_status wpalPacketRawTrimHead(wpt_packet *pPkt, wpt_uint32 size)
272{
273 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
274
275 // Validate the parameter pointers
276 if (unlikely(NULL == pPkt))
277 {
278 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700279 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 return eWLAN_PAL_STATUS_E_INVAL;
281 }
282
Manjunathappa Prakashfb585462013-12-23 19:07:07 -0800283 if ((eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) ||
284 (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt)))
285 {
286 // Continue to trim the packet
287 }
288 else
289 {
290 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
291 "%s : neither 80211 managment packet nor RAW packet", __func__);
292 VOS_ASSERT(0);
293 return eWLAN_PAL_STATUS_E_INVAL;
294 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 if( !VOS_IS_STATUS_SUCCESS(vos_pkt_trim_head(WPAL_TO_VOS_PKT(pPkt), (v_SIZE_t)size)) )
297 {
Arif Hussain9a5d5382013-11-17 22:05:35 -0800298 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s Invalid trim(%d)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700299 __func__, size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700300 status = eWLAN_PAL_STATUS_E_INVAL;
301 }
302
303 return status;
304}/*wpalPacketRawTrimHead*/
305
306/*---------------------------------------------------------------------------
307 wpalPacketRawTrimTail – reduce the length of the packet.
308 Param:
309 pPkt - pointer to a wpt_packet.
310 size – number of bytes to take of the packet length
311 Return:
312 eWLAN_PAL_STATUS_SUCCESS – success. Otherwise fail.
313---------------------------------------------------------------------------*/
314wpt_status wpalPacketRawTrimTail(wpt_packet *pPkt, wpt_uint32 size)
315{
316 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
317
318 // Validate the parameter pointers
319 if (unlikely(NULL == pPkt))
320 {
321 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700322 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 return eWLAN_PAL_STATUS_E_INVAL;
324 }
325
Manjunathappa Prakashfb585462013-12-23 19:07:07 -0800326 if ((eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) ||
327 (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt)))
328 {
329 // Continue to trim the packet
330 }
331 else
332 {
333 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
334 "%s : neither 80211 managment packet nor RAW packet", __func__);
335 VOS_ASSERT(0);
336 return eWLAN_PAL_STATUS_E_INVAL;
337 }
338
Jeff Johnson295189b2012-06-20 16:38:30 -0700339 if( !VOS_IS_STATUS_SUCCESS(vos_pkt_trim_tail(WPAL_TO_VOS_PKT(pPkt), (v_SIZE_t)size)) )
340 {
Arif Hussain9a5d5382013-11-17 22:05:35 -0800341 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s Invalid trim(%d)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700342 __func__, size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700343 status = eWLAN_PAL_STATUS_E_INVAL;
344 }
345
346 return status;
347}/*wpalPacketRawTrimTail*/
348
349
350/*---------------------------------------------------------------------------
351 wpalPacketGetRawBuf – Return the starting buffer virtual address for the RAW flat buffer
352 It is inline in hope of faster implementation for certain platform. For Winxp, it
353 will be slow.
354 Param:
355 pPkt - pointer to a wpt_packet.
356 Return:
357 NULL - fail.
358 Otherwise the address of the starting of the buffer
359---------------------------------------------------------------------------*/
360wpt_uint8 *wpalPacketGetRawBuf(wpt_packet *pPkt)
361{
362 wpt_uint8 *pRet = NULL;
363
364 // Validate the parameter pointers
365 if (unlikely(NULL == pPkt))
366 {
367 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700368 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700369 return NULL;
370 }
371
372 //Since it is a flat buffer, all we need is to get one byte of offset 0
373 if( (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt)) ||
374 (eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) )
375 {
376 vos_pkt_peek_data(WPAL_TO_VOS_PKT(pPkt), 0, (v_VOID_t**)&pRet, 1);
377 WPAL_ASSERT(NULL != pRet);
378 }
379
380 return pRet;
381}/*wpalPacketGetRawBuf*/
382
383
384/*---------------------------------------------------------------------------
385 wpalPacketSetRxLength – Set the valid data length on a RX packet. This function must
386 be called once per RX packet per receiving. It indicates the available data length from
387 the start of the buffer.
388 Param:
389 pPkt - pointer to a wpt_packet.
390 Return:
391 NULL - fail.
392 Otherwise the address of the starting of the buffer
393---------------------------------------------------------------------------*/
394wpt_status wpalPacketSetRxLength(wpt_packet *pPkt, wpt_uint32 len)
395{
396 // Validate the parameter pointers
397 if (unlikely(NULL == pPkt))
398 {
399 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700400 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700401 return eWLAN_PAL_STATUS_E_INVAL;
402 }
403
404 /*Only allowed for RX Raw packets */
405 if( (eWLAN_PAL_PKT_TYPE_RX_RAW != WPAL_PACKET_GET_TYPE(pPkt)))
406 {
407 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800408 "%s Invalid packet type(%d)", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700409 WPAL_PACKET_GET_TYPE(pPkt));
410 return eWLAN_PAL_STATUS_E_INVAL;
411 }
412
413 if(VOS_IS_STATUS_SUCCESS(vos_pkt_set_rx_length(WPAL_TO_VOS_PKT(pPkt), len)))
414 {
415 return eWLAN_PAL_STATUS_SUCCESS;
416 }
417 else
418 {
419 return eWLAN_PAL_STATUS_E_INVAL;
420 }
421}/*wpalPacketSetRxLength*/
422
423/*
424 Set of helper functions that will prepare packet for DMA transfer,
425 based on the type of transfer : - to and from the device
426 - following these calls the packet will be locked for DMA only,
427 CPU will not be able to modify it => the packet must be explicitly returned to
428 the CPU once the DMA transfer is complete
429*/
430WPT_STATIC WPT_INLINE void* itGetOSPktAddrForDevice( wpt_packet *pPacket )
431{
432 struct sk_buff *skb;
433 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
434 if ( VOS_STATUS_SUCCESS !=
435 vos_pkt_get_os_packet(WPAL_TO_VOS_PKT(pPacket), (void**)&skb, VOS_FALSE ))
436 {
437 return NULL;
438 }
439 else
440 {
441 /*Map skb data into dma-able memory
442 (changes will be commited from cache) */
443 return (void*)dma_map_single( NULL, skb->data, skb->len, DMA_TO_DEVICE );
444 }
445}/*itGetOSPktAddrForDevice*/
446
447WPT_STATIC WPT_INLINE void* itGetOSPktAddrFromDevice( wpt_packet *pPacket )
448{
449
450 struct sk_buff *skb;
451 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
452 if ( VOS_STATUS_SUCCESS !=
453 vos_pkt_get_os_packet(WPAL_TO_VOS_PKT(pPacket), (void**)&skb, VOS_FALSE ))
454 {
455 return NULL;
456 }
457 else
458 {
459 /*Map skb data into dma-able memory
460 (changes will be commited from cache) */
461 return (void*)dma_map_single( NULL, skb->data, skb->len, DMA_FROM_DEVICE );
462 }
463}/*itGetOSPktAddrFromDevice*/
464
465/*
466 Set of helper functions that will return a DMA-ed packet to the CPU,
467 based on the type of transfer : - to and from the device
468*/
469WPT_STATIC WPT_INLINE void itReturnOSPktAddrForDevice( wpt_packet *pPacket, void* addr, wpt_uint32 size )
470{
471
472 dma_unmap_single( NULL, (dma_addr_t)addr, size, DMA_TO_DEVICE );
473}
474
475WPT_STATIC WPT_INLINE void itReturnOSPktAddrFromDevice( wpt_packet *pPacket, void* addr, wpt_uint32 size )
476{
477
478 dma_unmap_single( NULL, (dma_addr_t)addr, size, DMA_FROM_DEVICE );
479}
480
481
482/*---------------------------------------------------------------------------
483 wpalIteratorInit – Initialize an interator by updating pCur to first item.
484 Param:
485 pIter – pointer to a caller allocated wpt_iterator
486 pPacket – pointer to a wpt_packet
487 Return:
488 eWLAN_PAL_STATUS_SUCCESS - success
489---------------------------------------------------------------------------*/
490wpt_status wpalIteratorInit(wpt_iterator *pIter, wpt_packet *pPacket)
491{
492 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
493 wpt_iterator_info* pCurInfo = NULL;
494 wpt_iterator_info* pNextInfo = NULL;
495 wpt_iterator_info* pPktInfo = NULL;
496
497 // Validate the parameter pointers
498 if (unlikely((NULL == pPacket)||(NULL==pIter)))
499 {
500 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsonbf6c4892013-11-03 19:27:59 -0800501 "%s : NULL input pointers %p %p", __func__, pPacket, pIter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700502 return eWLAN_PAL_STATUS_E_INVAL;
503 }
504
505 pPktInfo = (wpt_iterator_info*)pPacket->pInternalData;
506 if (unlikely(NULL == pPktInfo))
507 {
508 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700509 "%s : Invalid Packet Info", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700510 return eWLAN_PAL_STATUS_E_INVAL;
511 }
512
513 // if there is NO BD on this frame, then initialize the next pointer to
514 // point the first fragment.
515 if ( NULL == WPAL_PACKET_GET_BD_PHYS(pPacket) )
516 {
517 pCurInfo = pPktInfo;
518 pNextInfo = NULL;
519 }
520 else
521 {
522 /*Allocate memory for the current info*/
523 pCurInfo = wpalMemoryAllocate( sizeof(wpt_iterator_info) );
524
525 // Validate the memory allocation
526 if (unlikely(NULL == pCurInfo))
527 {
528 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700529 "%s : Failed to allocate memory ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700530 return eWLAN_PAL_STATUS_E_INVAL;
531 }
532
533 pCurInfo->pPhyAddr = WPAL_PACKET_GET_BD_PHYS(pPacket);
534 pCurInfo->uLen = WPAL_PACKET_GET_BD_LENGTH(pPacket);
535
536 pNextInfo = pPktInfo;
537 }
538
539 pIter->pCur = (void*)pCurInfo;
540 pIter->pNext = (void*)pNextInfo;
541 pIter->pContext = NULL;
542
543 return status;
544}/*wpalIteratorInit*/
545
546/*---------------------------------------------------------------------------
547 wpalIteratorNext – Get the address for the next item
548 Param:
549 pIter – pointer to a caller allocated wpt_iterator
550 pPacket – pointer to a wpt_packet
551 ppAddr – Caller allocated pointer to return the address of the item.
552 For DMA-able devices, this is the physical address of the item.
553 pLen – To return the number of bytes in the item.
554 Return:
555 eWLAN_PAL_STATUS_SUCCESS - success
556---------------------------------------------------------------------------*/
557wpt_status wpalIteratorNext(wpt_iterator *pIter, wpt_packet *pPacket, void **ppAddr, wpt_uint32 *pLen)
558{
559 wpt_iterator_info* pCurInfo = NULL;
560 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
561
562 /*-------------------------------------------------------------------------
563 Sanity check
564 -------------------------------------------------------------------------*/
565 if (unlikely(( NULL == pIter )||( NULL == pPacket ) ||
566 ( NULL == ppAddr ) || ( NULL == pLen )))
567 {
568 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800569 "%s Invalid input parameters", __func__ );
Jeff Johnson295189b2012-06-20 16:38:30 -0700570 return eWLAN_PAL_STATUS_E_INVAL;
571 }
572
573 pCurInfo = (wpt_iterator_info*)pIter->pCur;
574 /*-------------------------------------------------------------------------
575 If current pointer is NULL - there is no data in the packet - return
576 -------------------------------------------------------------------------*/
577 if( pIter->pCur == NULL )
578 {
579 *ppAddr = NULL;
580 *pLen = 0;
581 return eWLAN_PAL_STATUS_SUCCESS;
582 }
583
584 /*Address and length are kept in the current field*/
585 *ppAddr = pCurInfo->pPhyAddr;
586 *pLen = pCurInfo->uLen;
587
588 if( NULL == pIter->pNext )
589 {
590 /*Save the iterator for cleanup*/
591 pPacket->pInternalData = pIter->pCur;
592 pIter->pCur = NULL;
593 }
594 else
595 {
596 /*Release the memory saved for storing the BD information*/
597 wpalMemoryFree(pCurInfo);
598
599 /*For LA - the packet is represented by maximum 2 fields of data
600 - BD and actual data from sk buff */
601 pIter->pCur = pIter->pNext;
602 pIter->pNext = NULL;
603 }
604
605 return eWLAN_PAL_STATUS_SUCCESS;
606}
607
608/*---------------------------------------------------------------------------
609 wpalLockPacketForTransfer – Map the data buffer from dma so that the
610 data is commited from cache and the cpu relinquishes
611 ownership of the buffer
612
613 Param:
614 pPacket – pointer to a wpt_packet
615
616 Return:
617 eWLAN_PAL_STATUS_SUCCESS - success
618---------------------------------------------------------------------------*/
619wpt_status wpalLockPacketForTransfer( wpt_packet *pPacket)
620{
621 void* pPhyData = NULL;
622 wpt_iterator_info* pInfo = NULL;
623 v_U16_t uLenData = 0;
624
625 // Validate the parameter pointers
626 if (unlikely(NULL == pPacket))
627 {
628 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700629 "%s : NULL input pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700630 return eWLAN_PAL_STATUS_E_INVAL;
631 }
632
633 switch(WPAL_PACKET_GET_TYPE(pPacket))
634 {
635 /* For management frames, BD is allocated by WDI, header is in raw buffer,
636 rest of the frame is also in raw buffer */
637 case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT:
638 {
639 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
640 accordingly */
641 pPhyData = (void*)itGetOSPktAddrForDevice( pPacket );
642 }
643 break;
644 /* Data packets - BD (allocated by WDI), header (in VOSS header),
645 rest of the packet (DSM items) */
646 case eWLAN_PAL_PKT_TYPE_TX_802_11_DATA:
647 case eWLAN_PAL_PKT_TYPE_TX_802_3_DATA:
648 {
649 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
650 accordingly */
651 pPhyData = (void*)itGetOSPktAddrForDevice( pPacket );
652 }
653 break;
654
655 /* For Raw RX, BD + header + rest of the packet is all contained in the raw
656 buffer */
657 case eWLAN_PAL_PKT_TYPE_RX_RAW:
658 {
659 /*RX Packets need to be DMA-ed from the device, perform DMA mapping
660 accordingly */
661 pPhyData = (void*)itGetOSPktAddrFromDevice( pPacket );
662 }
663 break;
664
665 default:
666 {
667 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700668 " WLAN_PAL: %s: Invalid packet type %d!", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700669 WPAL_PACKET_GET_TYPE(pPacket) );
670 WPAL_ASSERT(0);
671 return eWLAN_PAL_STATUS_E_FAILURE;
672 }
673 }
674
675 /*Get packet length*/
676 vos_pkt_get_packet_length(WPAL_TO_VOS_PKT(pPacket),&uLenData);
677
678 /*Allocate memory for the current info*/
679 pInfo = wpalMemoryAllocate( sizeof(wpt_iterator_info) );
680
681 // Validate the memory allocation
682 if (unlikely(NULL == pInfo))
683 {
684 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700685 "%s : Failed to allocate memory ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700686 return eWLAN_PAL_STATUS_E_INVAL;
687 }
688
689 pInfo->pPhyAddr = pPhyData;
690 pInfo->uLen = uLenData;
691
692 pPacket->pInternalData = pInfo;
693 return eWLAN_PAL_STATUS_SUCCESS;
694}/*wpalLockPacketForTransfer*/
695
696/*---------------------------------------------------------------------------
697 wpalUnlockPacket – Unmap the data buffer from dma so that cpu can regain
698 ownership on it
699 Param:
700 pPacket – pointer to a wpt_packet
701
702 Return:
703 eWLAN_PAL_STATUS_SUCCESS - success
704---------------------------------------------------------------------------*/
705wpt_status wpalUnlockPacket( wpt_packet *pPacket)
706{
707
708 wpt_iterator_info* pInfo;
709
710 // Validate the parameter pointers
711 if (unlikely(NULL == pPacket))
712 {
713 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700714 "%s : NULL input pointer pPacket", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700715 return eWLAN_PAL_STATUS_E_INVAL;
716 }
717
718 pInfo = (wpt_iterator_info*)pPacket->pInternalData;
719
720 // Validate pInfo
721 if (unlikely(NULL == pInfo))
722 {
723 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700724 "%s : NULL input pointer pInfo", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 return eWLAN_PAL_STATUS_E_INVAL;
726 }
727
728 switch(WPAL_PACKET_GET_TYPE(pPacket))
729 {
730 /* For management frames, BD is allocated by WDI, header is in raw buffer,
731 rest of the frame is also in raw buffer */
732 case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT:
733 {
734 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
735 accordingly */
736 itReturnOSPktAddrForDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen);
737 }
738 break;
739 /* Data packets - BD (allocated by WDI), header (in VOSS header),
740 rest of the packet (DSM items) */
741 case eWLAN_PAL_PKT_TYPE_TX_802_11_DATA:
742 case eWLAN_PAL_PKT_TYPE_TX_802_3_DATA:
743 {
744 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
745 accordingly */
746 itReturnOSPktAddrForDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen);
747 }
748 break;
749
750 /* For Raw RX, BD + header + rest of the packet is all contained in the raw
751 buffer */
752 case eWLAN_PAL_PKT_TYPE_RX_RAW:
753 {
754 /*RX Packets need to be DMA-ed from the device, perform DMA mapping
755 accordingly */
Madan Mohan Koyyalamudif850f1c2012-12-05 16:03:53 -0800756 if(NULL == pInfo->pPhyAddr)
757 {
758 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
759 " WLAN_PAL: %s: RX frame was not locked properly", __func__);
760 }
761 else
762 {
763 itReturnOSPktAddrFromDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen);
764 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700765 }
766 break;
767
768 default:
769 {
770 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700771 " WLAN_PAL: %s: Invalid packet type %d!", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700772 WPAL_PACKET_GET_TYPE(pPacket) );
773 WPAL_ASSERT(0);
774 return eWLAN_PAL_STATUS_E_FAILURE;
775 }
776 }
777
778 wpalMemoryFree(pInfo);
779 pPacket->pInternalData = NULL;
780 return eWLAN_PAL_STATUS_SUCCESS;
781}/*wpalUnlockPacket*/
782
783/*---------------------------------------------------------------------------
784 wpalIsPacketLocked – Check whether the Packet is locked for DMA.
785 Param:
786 pPacket – pointer to a wpt_packet
787
788 Return:
789 eWLAN_PAL_STATUS_SUCCESS
790 eWLAN_PAL_STATUS_E_FAILURE
791 eWLAN_PAL_STATUS_E_INVAL
792---------------------------------------------------------------------------*/
793wpt_status wpalIsPacketLocked( wpt_packet *pPacket)
794{
795
796 wpt_iterator_info* pInfo;
797
798 /* Validate the parameter pointers */
799 if (NULL == pPacket)
800 {
Gopichand Nakkala0dfe0a92013-06-19 21:50:26 +0530801 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700802 "%s : NULL input pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700803 return eWLAN_PAL_STATUS_E_INVAL;
804 }
805
806 /* Validate pInternalData */
807 pInfo = (wpt_iterator_info*)pPacket->pInternalData;
808 return (NULL == pInfo)? eWLAN_PAL_STATUS_E_FAILURE :
809 eWLAN_PAL_STATUS_SUCCESS;
810}/*wpalIsPacketLocked*/
811
Gopichand Nakkalaa2cb10c2013-05-03 17:48:29 -0700812/*---------------------------------------------------------------------------
813 wpalGetNumRxRawPacket Query available RX RAW total buffer count
814 param:
815 numRxResource pointer of queried value
816
817 return:
818 eWLAN_PAL_STATUS_SUCCESS
819---------------------------------------------------------------------------*/
820wpt_status wpalGetNumRxRawPacket(wpt_uint32 *numRxResource)
821{
822 *numRxResource = (wpt_uint32)vos_pkt_get_num_of_rx_raw_pkts();
823
824 return eWLAN_PAL_STATUS_SUCCESS;
825}
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700826
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700827/*---------------------------------------------------------------------------
828 wpalPacketStallUpdateInfo – Update each channel information when stall
829 detected, also power state and free resource count
830
831 Param:
832 powerState ? WLAN system power state when stall detected
833 numFreeBd ? Number of free resource count in HW
834 channelInfo ? Each channel specific information when stall happen
835 channelNum ? Channel number update information
836
837 Return:
838 NONE
839
840---------------------------------------------------------------------------*/
841void wpalPacketStallUpdateInfo
842(
843 v_U32_t *powerState,
844 v_U32_t *numFreeBd,
845 wpt_log_data_stall_channel_type *channelInfo,
846 v_U8_t channelNum
847)
848{
849 /* Update power state when stall detected */
850 if(NULL != powerState)
851 {
852 wpalTrasportStallInfo.PowerState = *powerState;
853 }
854
855 /* Update HW free resource count */
856 if(NULL != numFreeBd)
857 {
858 wpalTrasportStallInfo.numFreeBd = *numFreeBd;
859 }
860
861 /* Update channel information */
862 if(NULL != channelInfo)
863 {
864 wpalMemoryCopy(&wpalTrasportStallInfo.dxeChannelInfo[channelNum],
865 channelInfo,
866 sizeof(wpt_log_data_stall_channel_type));
867 }
868
869 return;
870}
871
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530872#ifdef FEATURE_WLAN_DIAG_SUPPORT
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700873/*---------------------------------------------------------------------------
874 wpalPacketStallDumpLog – Trigger to send log packet to DIAG
875 Updated transport system information will be sent to DIAG
876
877 Param:
878 NONE
879
880 Return:
881 NONE
882
883---------------------------------------------------------------------------*/
884void wpalPacketStallDumpLog
885(
886 void
887)
888{
889 vos_log_data_stall_type *log_ptr = NULL;
890
891 WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_data_stall_type, LOG_TRSP_DATA_STALL_C);
892 if(log_ptr)
893 {
894 log_ptr->PowerState = wpalTrasportStallInfo.PowerState;
895 log_ptr->numFreeBd = wpalTrasportStallInfo.numFreeBd;
896 wpalMemoryCopy(&log_ptr->dxeChannelInfo[0],
897 &wpalTrasportStallInfo.dxeChannelInfo[0],
898 WPT_NUM_TRPT_CHANNEL * sizeof(vos_log_data_stall_channel_type));
899 pr_info("Stall log dump");
900 WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
901 }
902
903 return;
904}
905#endif /* FEATURE_WLAN_DIAG_SUPPORT */