blob: 6d9436471d4e06aa1a50c35b450ba204a1ca8082 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**=========================================================================
43
44 \file vos_packet.c
45
46 \brief virtual Operating System Services (vOSS) network Packet APIs
47
48 Network Protocol packet/buffer support interfaces
49
50 Copyright 2009 (c) Qualcomm, Incorporated. All Rights Reserved.
51
52 Qualcomm Confidential and Proprietary.
53
54 ========================================================================*/
55
56/* $Header$ */
57
58/*--------------------------------------------------------------------------
59 Include Files
60 ------------------------------------------------------------------------*/
61#include <vos_packet.h>
62#include <i_vos_packet.h>
63#include <vos_timer.h>
64#include <vos_trace.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include <wlan_hdd_main.h>
Sameer Thalappild0158402013-05-03 13:19:03 -070066#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067
68/*--------------------------------------------------------------------------
69 Preprocessor definitions and constants
70 ------------------------------------------------------------------------*/
71
72/*--------------------------------------------------------------------------
73 Type declarations
74 ------------------------------------------------------------------------*/
75
76/*---------------------------------------------------------------------------
77 Data definitions
78 ------------------------------------------------------------------------*/
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070079static vos_pkt_context_t *gpVosPacketContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070080
81/*-------------------------------------------------------------------------
82 Function declarations and documentation
83 ------------------------------------------------------------------------*/
84
85static VOS_STATUS vos_pkti_packet_init( struct vos_pkt_t *pPkt,
86 VOS_PKT_TYPE pktType )
87{
88 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
89
90 // fixed fields
91 pPkt->packetType = pktType;
92 pPkt->magic = VPKT_MAGIC_NUMBER;
93
94 // some packet types need an attached skb
95 switch (pktType)
96 {
97 case VOS_PKT_TYPE_RX_RAW:
98 case VOS_PKT_TYPE_TX_802_11_MGMT:
99 // these need an attached skb.
100 // we preallocate a fixed-size skb and reserve the entire buffer
101 // as headroom since that is what other components expect
Kumar Pavan32af4e32012-12-27 17:30:09 -0800102 pPkt->pSkb = alloc_skb(VPKT_SIZE_BUFFER , in_interrupt()? GFP_ATOMIC : GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103 if (likely(pPkt->pSkb))
104 {
105 skb_reserve(pPkt->pSkb, VPKT_SIZE_BUFFER);
106 }
107 else
108 {
109 vosStatus = VOS_STATUS_E_NOMEM;
110 }
111
Jeff Johnson295189b2012-06-20 16:38:30 -0700112 /* Init PAL Packet */
113 WPAL_PACKET_SET_BD_POINTER(&(pPkt->palPacket), NULL);
114 WPAL_PACKET_SET_BD_PHYS(&(pPkt->palPacket), NULL);
115 WPAL_PACKET_SET_BD_LENGTH(&(pPkt->palPacket), 0);
116 WPAL_PACKET_SET_OS_STRUCT_POINTER(&(pPkt->palPacket), NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700117
118 break;
119 default:
120 // no attached skb needed
121 break;
122 }
123
124 return vosStatus;
125}
126
127
128
129static VOS_STATUS vos_pkti_list_destroy( struct list_head *pList )
130{
131 struct vos_pkt_t *pVosPacket;
132
133 if (unlikely(NULL == pList))
134 {
135 // something is fishy -- don't even bother trying
136 // clean up this list since it is apparently hosed
137 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
138 "VPKT [%d]: NULL pList", __LINE__);
139 VOS_ASSERT(0);
140 return VOS_STATUS_E_INVAL;
141 }
142
143 list_for_each_entry(pVosPacket, pList, node)
144 {
145
146 // is this really an initialized vos packet?
147 if (unlikely(VPKT_MAGIC_NUMBER != pVosPacket->magic))
148 {
149 // no, so don't try any deinitialization on it, and
150 // since we can't trust the linkages, stop trying
151 // to destroy the list
152 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
153 "VPKT [%d]: Invalid magic", __LINE__);
154 VOS_ASSERT(0);
155 break;
156 }
157
158 // does this vos packet have an skb attached?
159 if (pVosPacket->pSkb)
160 {
161 // yes, so give it back to the kernel
162 kfree_skb(pVosPacket->pSkb);
163 pVosPacket->pSkb = NULL;
164 }
165
166 // the vos packet itself is a static portion of the vos packet context
167 // so there is no deallocation we have to do with it. just clear the
168 // magic so we no longer think it is valid
169 pVosPacket->magic = 0;
170
171 }
172
173 // all nodes of the list have been processed so reinitialize the list
174 INIT_LIST_HEAD(pList);
175
176 return VOS_STATUS_SUCCESS;
177}
178
179
180static void vos_pkti_replenish_raw_pool(void)
181{
182 struct sk_buff * pSkb;
183 struct vos_pkt_t *pVosPacket;
184 v_BOOL_t didOne = VOS_FALSE;
185 vos_pkt_get_packet_callback callback;
Jeff Johnson295189b2012-06-20 16:38:30 -0700186
187 // if there are no packets in the replenish pool then we can't do anything
188 if (likely(0 == gpVosPacketContext->rxReplenishListCount))
189 {
190 return;
191 }
192
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700193 // we only replenish if the Rx Raw pool is empty or the Replenish pool
194 // reaches a high water mark
195 mutex_lock(&gpVosPacketContext->mlock);
196
197
Sameer Thalappild0158402013-05-03 13:19:03 -0700198 if ((gpVosPacketContext->rxReplenishListCount <
199 gpVosPacketContext->numOfRxRawPackets/4) &&
200 (!list_empty(&gpVosPacketContext->rxRawFreeList)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 {
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700202 mutex_unlock(&gpVosPacketContext->mlock);
203 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 }
205
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
207 "VPKT [%d]: Packet replenish activated", __LINE__);
208
209 // try to replenish all of the packets in the replenish pool
210 while (gpVosPacketContext->rxReplenishListCount)
211 {
212 // we preallocate a fixed-size skb and reserve the entire buffer
213 // as headroom since that is what other components expect
214 pSkb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC);
215 if (unlikely(NULL == pSkb))
216 {
217 // we have replenished all that we can
218 break;
219 }
220 skb_reserve(pSkb, VPKT_SIZE_BUFFER);
221
222 // remove a vos packet from the replenish pool
223 pVosPacket = list_first_entry(&gpVosPacketContext->rxReplenishList,
224 struct vos_pkt_t, node);
225 list_del(&pVosPacket->node);
226 gpVosPacketContext->rxReplenishListCount--;
227
228 // attach the skb to the vos packet
229 pVosPacket->pSkb = pSkb;
230
231 // add it to the Rx Raw Free Pool
232 list_add_tail(&pVosPacket->node, &gpVosPacketContext->rxRawFreeList);
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800233 gpVosPacketContext->rxRawFreeListCount++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700234
235 didOne = VOS_TRUE;
236
237 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
238 "VPKT [%d]: [%p] Packet replenished",
239 __LINE__, pVosPacket);
240
241 }
242
243 // if we replenished anything and if there is a callback waiting
244 // then invoke the callback
245 if ((VOS_TRUE == didOne) &&
246 (gpVosPacketContext->rxRawLowResourceInfo.callback))
247 {
248 // remove the first record from the free pool
249 pVosPacket = list_first_entry(&gpVosPacketContext->rxRawFreeList,
250 struct vos_pkt_t, node);
251 list_del(&pVosPacket->node);
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800252 gpVosPacketContext->rxRawFreeListCount--;
Jeff Johnson295189b2012-06-20 16:38:30 -0700253
254 // clear out the User Data pointers in the voss packet..
255 memset(&pVosPacket->pvUserData, 0, sizeof(pVosPacket->pvUserData));
256
257 // initialize the 'chain' pointer to NULL.
258 pVosPacket->pNext = NULL;
259
260 // timestamp the vos packet.
261 pVosPacket->timestamp = vos_timer_get_system_ticks();
262
263 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
264 "VPKT [%d]: [%p] Packet replenish callback",
265 __LINE__, pVosPacket);
266
267 callback = gpVosPacketContext->rxRawLowResourceInfo.callback;
268 gpVosPacketContext->rxRawLowResourceInfo.callback = NULL;
269 mutex_unlock(&gpVosPacketContext->mlock);
270 callback(pVosPacket, gpVosPacketContext->rxRawLowResourceInfo.userData);
271 }
272 else
273 {
274 mutex_unlock(&gpVosPacketContext->mlock);
275 }
276}
277
278
279#if defined( WLAN_DEBUG )
280static char *vos_pkti_packet_type_str(VOS_PKT_TYPE pktType)
281{
282 switch (pktType)
283 {
284 case VOS_PKT_TYPE_TX_802_11_MGMT:
285 return "TX_802_11_MGMT";
286 break;
287
288 case VOS_PKT_TYPE_TX_802_11_DATA:
289 return "TX_802_11_DATA";
290 break;
291
292 case VOS_PKT_TYPE_TX_802_3_DATA:
293 return "TX_802_3_DATA";
294 break;
295
296 case VOS_PKT_TYPE_RX_RAW:
297 return "RX_RAW";
298 break;
299
300 default:
301 return "UNKNOWN";
302 break;
303 }
304}
305#endif // defined( WLAN_DEBUG )
306
307/*---------------------------------------------------------------------------
308
309 \brief vos_packet_open() - initialize the vOSS Packet module
310
311 The \a vos_packet_open() function initializes the vOSS Packet
312 module.
313
314 \param pVosContext - pointer to the global vOSS Context
315
316 \param pVosPacketContext - pointer to a previously allocated
317 buffer big enough to hold the vos Packet context.
318
319 \param vosPacketContextSize - the size allocated for the vos
320 packet context.
321
322 \return VOS_STATUS_SUCCESS - vos Packet module was successfully
323 initialized and is ready to be used.
324
325 VOS_STATUS_E_RESOURCES - System resources (other than memory)
326 are unavailable to initilize the vos Packet module
327
328 VOS_STATUS_E_NOMEM - insufficient memory exists to initialize
329 the vos packet module
330
331 VOS_STATUS_E_INVAL - Invalid parameter passed to the vos open
332 function
333
334 VOS_STATUS_E_FAILURE - Failure to initialize the vos packet
335 module
336
337 \sa vos_packet_close()
338
339 -------------------------------------------------------------------------*/
340VOS_STATUS vos_packet_open( v_VOID_t *pVosContext,
341 vos_pkt_context_t *pVosPacketContext,
342 v_SIZE_t vosPacketContextSize )
343{
344 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
345 unsigned int freePacketIndex;
346 unsigned int idx;
347 struct vos_pkt_t *pPkt;
348 struct list_head *pFreeList;
349
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700350 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "Enter:%s",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700351
352 do
353 {
354
355 if (NULL == pVosContext)
356 {
357 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
358 "VPKT [%d]: NULL pVosContext", __LINE__);
359 vosStatus = VOS_STATUS_E_INVAL;
360 break;
361 }
362
363 if (NULL == pVosPacketContext)
364 {
365 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
366 "VPKT [%d]: NULL pVosPacketContext", __LINE__);
367 vosStatus = VOS_STATUS_E_INVAL;
368 break;
369 }
370
371 if (sizeof(vos_pkt_context_t) != vosPacketContextSize)
372 {
373 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
374 "VPKT [%d]: invalid vosPacketContextSize, %d vs %d",
375 __LINE__, sizeof(vos_pkt_context_t), vosPacketContextSize);
376 vosStatus = VOS_STATUS_E_INVAL;
377 break;
378 }
379
380 // clear the vos packet context. in the process this will
381 // initialize the low resource info blocks
382 memset(pVosPacketContext, 0, vosPacketContextSize);
383
384 // save a global pointer to the vos packet context.
385 gpVosPacketContext = pVosPacketContext;
386
387 // save the vos Context pointer in the vos Packet Context.
388 pVosPacketContext->vosContext = pVosContext;
389
390 // initialize the rx Replenish pool (initially empty)
391 INIT_LIST_HEAD(&pVosPacketContext->rxReplenishList);
392 pVosPacketContext->rxReplenishListCount = 0;
393
394 // index into the packet context's vosPktBuffer[] array
395 freePacketIndex = 0;
396
397 // initialize the rxRaw free list pool
398 pFreeList = &pVosPacketContext->rxRawFreeList;
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800399 pVosPacketContext->rxRawFreeListCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700400 INIT_LIST_HEAD(pFreeList);
401
Sameer Thalappild0158402013-05-03 13:19:03 -0700402 pVosPacketContext->numOfRxRawPackets = vos_pkt_get_num_of_rx_raw_pkts();
403
Jeff Johnson295189b2012-06-20 16:38:30 -0700404 // fill the rxRaw free list
Sameer Thalappild0158402013-05-03 13:19:03 -0700405 for (idx = 0; idx < pVosPacketContext->numOfRxRawPackets; idx++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700406 {
407 pPkt = &pVosPacketContext->vosPktBuffers[freePacketIndex++];
408 vosStatus = vos_pkti_packet_init(pPkt, VOS_PKT_TYPE_RX_RAW);
409
Jeff Johnson295189b2012-06-20 16:38:30 -0700410 WPAL_PACKET_SET_METAINFO_POINTER(&(pPkt->palPacket),
411 (void*)&pVosPacketContext->rxMetaInfo[idx]);
412 WPAL_PACKET_SET_TYPE(&(pPkt->palPacket),
413 eWLAN_PAL_PKT_TYPE_RX_RAW);
Jeff Johnson295189b2012-06-20 16:38:30 -0700414
415 if (VOS_STATUS_SUCCESS != vosStatus)
416 {
417 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
418 "VPKT [%d]: Packet init failure", __LINE__);
419 break;
420 }
421 list_add_tail(&pPkt->node, pFreeList);
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800422 pVosPacketContext->rxRawFreeListCount++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700423 }
424
425 // exit if any problems so far
426 if (VOS_STATUS_SUCCESS != vosStatus)
427 {
428 break;
429 }
430
431 // initialize the txData free list pool
432 pFreeList = &pVosPacketContext->txDataFreeList;
433 INIT_LIST_HEAD(pFreeList);
434
435 // fill the txData free list
436 for (idx = 0; idx < VPKT_NUM_TX_DATA_PACKETS; idx++)
437 {
438 pPkt = &pVosPacketContext->vosPktBuffers[freePacketIndex++];
439 vosStatus = vos_pkti_packet_init(pPkt, VOS_PKT_TYPE_TX_802_3_DATA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700440 WPAL_PACKET_SET_METAINFO_POINTER(&(pPkt->palPacket),
441 (void*)&pVosPacketContext->txDataMetaInfo[idx]);
442 WPAL_PACKET_SET_TYPE(&(pPkt->palPacket),
443 eWLAN_PAL_PKT_TYPE_TX_802_3_DATA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700444 if (VOS_STATUS_SUCCESS != vosStatus)
445 {
446 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
447 "VPKT [%d]: Packet init failure", __LINE__);
448 break;
449 }
450 list_add_tail(&pPkt->node, pFreeList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700451 pVosPacketContext->uctxDataFreeListCount++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700452 }
453
454 // exit if any problems so far
455 if (VOS_STATUS_SUCCESS != vosStatus)
456 {
457 break;
458 }
459
460 // initialize the txMgmt free list pool
461 pFreeList = &pVosPacketContext->txMgmtFreeList;
462 INIT_LIST_HEAD(pFreeList);
463
464 mutex_init(&gpVosPacketContext->mlock);
465 // fill the txMgmt free list
466 for (idx = 0; idx < VPKT_NUM_TX_MGMT_PACKETS; idx++)
467 {
468 pPkt = &pVosPacketContext->vosPktBuffers[freePacketIndex++];
469
470 vosStatus = vos_pkti_packet_init(pPkt, VOS_PKT_TYPE_TX_802_11_MGMT);
471
Jeff Johnson295189b2012-06-20 16:38:30 -0700472 WPAL_PACKET_SET_METAINFO_POINTER(&(pPkt->palPacket),
473 (void*)&pVosPacketContext->txMgmtMetaInfo[idx]);
474 WPAL_PACKET_SET_TYPE(&(pPkt->palPacket),
475 eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700476
477 if (VOS_STATUS_SUCCESS != vosStatus)
478 {
479 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
480 "VPKT [%d]: Packet init failure", __LINE__);
481 break;
482 }
483 list_add_tail(&pPkt->node, pFreeList);
484 }
485
486 // exit if any problems so far
487 if (VOS_STATUS_SUCCESS != vosStatus)
488 {
489 break;
490 }
491
492 } while (0);
493
494 return vosStatus;
495}
496
497
498
499/*---------------------------------------------------------------------------
500
501 \brief vos_packet_close() - Close the vOSS Packet module
502
503 The \a vos_packet_close() function closes the vOSS Packet module
504 Upon successful close all resources allocated from the OS will be
505 relinquished.
506
507 \param pVosContext - pointer to the global vOSS Context
508
509 \return VOS_STATUS_SUCCESS - Packet module was successfully closed.
510
511 VOS_STATUS_E_INVAL - Invalid parameter passed to the packet
512 close function
513
514 VOS_STATUS_E_FAILURE - Failure to close the vos Packet module
515
516 \sa vos_packet_open()
517
518 ---------------------------------------------------------------------------*/
519VOS_STATUS vos_packet_close( v_PVOID_t pVosContext )
520{
521
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700522 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "Enter:%s",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700523
524 if (unlikely(NULL == pVosContext))
525 {
526 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
527 "VPKT [%d]: NULL pVosContext", __LINE__);
528 return VOS_STATUS_E_INVAL;
529 }
530
531 if (unlikely(gpVosPacketContext->vosContext != pVosContext))
532 {
533 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
534 "VPKT [%d]: invalid pVosContext", __LINE__);
535 return VOS_STATUS_E_INVAL;
536 }
537
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700538 mutex_lock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700539 (void) vos_pkti_list_destroy(&gpVosPacketContext->txMgmtFreeList);
540 (void) vos_pkti_list_destroy(&gpVosPacketContext->txDataFreeList);
541 (void) vos_pkti_list_destroy(&gpVosPacketContext->rxRawFreeList);
542 (void) vos_pkti_list_destroy(&gpVosPacketContext->rxReplenishList);
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800543
544 gpVosPacketContext->rxRawFreeListCount = 0;
545 gpVosPacketContext->rxReplenishListCount = 0;
546 gpVosPacketContext->uctxDataFreeListCount = 0;
547
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700548 mutex_unlock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700549
Jeff Johnson295189b2012-06-20 16:38:30 -0700550 gpVosPacketContext->uctxDataFreeListCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
552 return VOS_STATUS_SUCCESS;
553}
554
555
556/**--------------------------------------------------------------------------
557
558 \brief vos_pkt_get_packet() - Get a voss Packet
559
560 Gets a voss Packet from an internally managed packet pool.
561
562 \param ppPacket - pointer to location where the voss Packet pointer is
563 returned. If multiple packets are requested, they
564 will be chained onto this first packet.
565
566 \param pktType - the packet type to be retreived. Valid packet types are:
567 <ul>
568 <li> VOS_PKT_TYPE_TX_802_11_MGMT - voss packet is for Transmitting
569 802.11 Management frames.
570
571 <li> VOS_PKT_TYPE_RX_RAW - voss Packet contains a buffer for Receiving
572 raw frames of unknown type.
573 </ul>
574
575 \param dataSize - the Data size needed in the voss Packet.
576
577 \param numPackets - the number of packets requested.
578
579 \param zeroBuffer - parameter that tells the API to zero the data buffer
580 in this voss Packet.
581 <ul>
582 <li> VOS_TRUE - the API will zero out the entire data buffer.
583
584 <li> VOS_FALSE - the API will not zero out the data buffer.
585 </ul>
586
587 \note If enough room for headers to transmit or receive the packet is not
588 available, this API will fail.
589
590 \param callback - This callback function, if provided, is invoked in the
591 case when resources are not available at the time of the call to
592 get packets. This callback function is invoked when packets are
593 available.
594
595 \param userData - This user data is passed back to the caller in the
596 callback function, if the callback is invoked.
597
598 \return VOS_STATUS_SUCCESS - the API was able to get a vos_packet for the
599 requested type. *ppPacket contains a pointer to the packet.
600
601 VOS_STATUS_E_INVAL - pktType is not a valid packet type. This
602 API only supports getting vos packets for 802_11_MGMT and
603 RX_RAW packet types. This status is also returned if the
604 numPackets or dataSize are invalid.
605
606 VOS_STATUS_E_RESOURCES - unable to get resources needed to get
607 a vos packet. If a callback function is specified and this
608 status is returned from the API, the callback will be called
609 when resources are available to fulfill the original request.
610
611 Note that the low resources condition is indicated to the caller
612 by returning VOS_STATUS_E_RESOURCES. This status is the only
613 non-success status that indicates to the caller that the callback
614 will be called when resources are available. All other status
615 indicate failures that are not recoverable and the 'callback'
616 will not be called.
617
618 VOS_STATUS_E_FAILURE - The API returns this status when unable
619 to get a packet from the packet pool because the pool
620 is depleted and the caller did not specify a low resource callback.
621
622 VOS_STATUS_E_ALREADY - This status is returned when the VOS
623 packet pool is in a 'low resource' condition and cannot
624 accomodate any more calls to retrieve packets from that
625 pool. Note this is a FAILURE and the 'low resource' callback
626 will *not* be called.
627
628 VOS_STATUS_E_FAULT - ppPacket does not specify a valid pointer.
629
630 \sa
631
632 ------------------------------------------------------------------------*/
633VOS_STATUS vos_pkt_get_packet( vos_pkt_t **ppPacket,
634 VOS_PKT_TYPE pktType,
635 v_SIZE_t dataSize,
636 v_SIZE_t numPackets,
637 v_BOOL_t zeroBuffer,
638 vos_pkt_get_packet_callback callback,
639 v_VOID_t *userData )
640{
641 struct list_head *pPktFreeList;
642 vos_pkt_low_resource_info *pLowResourceInfo;
643 struct vos_pkt_t *pVosPacket;
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800644 v_SIZE_t *pCount = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700645 // Validate the return parameter pointer
646 if (unlikely(NULL == ppPacket))
647 {
648 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
649 "VPKT [%d]: NULL ppPacket", __LINE__);
650 return VOS_STATUS_E_INVAL;
651 }
652
653 // we only support getting 1 packet at this time (as do WM & AMSS)
654 if (unlikely(1 != numPackets))
655 {
656 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
657 "VPKT [%d]: invalid numPackets, %d", __LINE__, numPackets);
658 return VOS_STATUS_E_INVAL;
659 }
660
661 // Validate the dataSize is within range
662 if (unlikely((0 == dataSize) || (dataSize > VPKT_SIZE_BUFFER)))
663 {
664 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
665 "VPKT [%d]: invalid dataSize, %d", __LINE__, dataSize);
666 return VOS_STATUS_E_INVAL;
667 }
668
669 // determine which packet pool and low resource block we should use.
670 // this API is only valid for TX MGMT and RX RAW packets
671 // (TX DATA will use vos_pkt_wrap_data_packet())
672 switch (pktType)
673 {
674
675 case VOS_PKT_TYPE_RX_RAW:
676 pPktFreeList = &gpVosPacketContext->rxRawFreeList;
677 pLowResourceInfo = &gpVosPacketContext->rxRawLowResourceInfo;
678
679 // see if we need to replenish the Rx Raw pool
680 vos_pkti_replenish_raw_pool();
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800681 pCount = &gpVosPacketContext->rxRawFreeListCount;
Jeff Johnson295189b2012-06-20 16:38:30 -0700682
683 break;
684
685 case VOS_PKT_TYPE_TX_802_11_MGMT:
686 pPktFreeList = &gpVosPacketContext->txMgmtFreeList;
687 pLowResourceInfo = &gpVosPacketContext->txMgmtLowResourceInfo;
688 break;
689
690 default:
691 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
692 "VPKT [%d]: invalid packet type %d[%s]",
693 __LINE__, pktType, vos_pkti_packet_type_str(pktType));
694 return VOS_STATUS_E_INVAL;
695 }
696
697 // is there already a low resource callback registered for this pool?
698 // we only support one callback per pool, so if one is already registered
699 // then we know we are already in a low-resource condition
700 if (unlikely(pLowResourceInfo->callback))
701 {
702 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
703 "VPKT [%d]: Low resource handler already registered",
704 __LINE__);
705 return VOS_STATUS_E_ALREADY;
706 }
707
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700708 mutex_lock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700709 // are there vos packets on the associated free pool?
710 if (unlikely(list_empty(pPktFreeList)))
711 {
712 // allocation failed
713 // did the caller specify a callback?
714 if (unlikely(NULL == callback))
715 {
716 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
717 "VPKT [%d]: Low resource condition and no callback provided",
718 __LINE__);
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700719 mutex_unlock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700720
721 return VOS_STATUS_E_FAILURE;
722 }
723
724 // save the low resource information so that we can invoke the
725 // callback when a packet becomes available
726 pLowResourceInfo->callback = callback;
727 pLowResourceInfo->userData = userData;
728 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
729 "VPKT [%d]: Low resource condition for packet type %d[%s]",
730 __LINE__, pktType, vos_pkti_packet_type_str(pktType));
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700731 mutex_unlock(&gpVosPacketContext->mlock);
732
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 return VOS_STATUS_E_RESOURCES;
734 }
735
736 // remove the first record from the free pool
737 pVosPacket = list_first_entry(pPktFreeList, struct vos_pkt_t, node);
738 list_del(&pVosPacket->node);
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -0800739 if (NULL != pCount)
740 {
741 (*pCount)--;
742 }
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700743 mutex_unlock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700744
745 // clear out the User Data pointers in the voss packet..
746 memset(&pVosPacket->pvUserData, 0, sizeof(pVosPacket->pvUserData));
747
748 // initialize the 'chain' pointer to NULL.
749 pVosPacket->pNext = NULL;
750
751 // set the packet type.
752 pVosPacket->packetType = pktType;
753
754 // timestamp the vos packet.
755 pVosPacket->timestamp = vos_timer_get_system_ticks();
756
757 // zero the data buffer if the user asked for it to be cleared.
758 if (unlikely(zeroBuffer))
759 {
760 memset(pVosPacket->pSkb->head,
761 0,
762 skb_end_pointer(pVosPacket->pSkb) - pVosPacket->pSkb->head);
763 }
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -0700764
Jeff Johnson295189b2012-06-20 16:38:30 -0700765 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
766 "VPKT [%d]: [%p] Packet allocated, type %d[%s]",
767 __LINE__, pVosPacket, pktType, vos_pkti_packet_type_str(pktType));
768
769 *ppPacket = pVosPacket;
770 return VOS_STATUS_SUCCESS;
771}
772
773
774/**--------------------------------------------------------------------------
775
776 \brief vos_pkt_wrap_data_packets() - Wrap an OS provided data packet in a
777 vos packet.
778
779 Takes as input an OS provided data packet and 'wraps' that packet in a
780 vos_packet, returning the vos_packet to the caller.
781
782 This function is intended to be called from the HDD to wrap Tx data packets
783 from the OS into vos_packets before sending them to TL for transmission.
784
785 \param ppPacket - pointer to location where the voss Packet pointer is
786 returned. If multiple packets are requested, they
787 will be chained onto this first packet.
788
789 \param pktType - the packet type to be retreived. Valid packet types are:
790 <ul>
791 <li> VOS_PKT_TYPE_802_3_DATA - voss packet is for Transmitting 802.3
792 data frames.
793
794 <li> VOS_PKT_TYPE_802_11_DATA - voss Packet is for Transmitting 802.11
795 data frames.
796 </ul>
797
798 \param pOSPacket - a pointer to the Transmit packet provided by the OS. This
799 OS provided packet will be wrapped into a vos_packet_t. Note this
800 OS packet pointer can be NULL. The OS packet pointer can be inserted
801 into a VOS packet of type VOS_PKT_TYPE_802_3_DATA or
802 VOS_PKT_TYPE_802_11_DATA through vos_pkt_set_os_packet().
803
804 \note If enough room for headers to transmit or receive the packet is not
805 available, this API will fail.
806
807 \param callback - This callback function, if provided, is invoked in the
808 case where packets are not available at the time of the call to
809 return the packets to the caller (a 'low resource' condition).
810
811 When packets become available, the callback callback function is
812 invoked to return a VOS packet to the caller. Note that the
813 OS Packet is *not* inserted into the VOS packet when it is returned
814 to the low resource callback. It is up to the caller to insert
815 the OS packet into the VOS packet by calling vos_pkt_set_os_packet()
816
817 \param userData - This user data is passed back to the caller in the
818 callback function, if the callback is invoked.
819
820 \return VOS_STATUS_SUCCESS - the API was able to get a vos_packet for the
821 requested type. *ppPacket contains a pointer to the packet.
822
823 VOS_STATUS_E_INVAL - pktType is not a valid packet type. This
824 API only supports getting vos packets for 802_11_MGMT and
825 RX_RAW packet types.
826
827 VOS_STATUS_E_RESOURCES - unable to get resources needed to get
828 a vos packet. If a callback function is specified and this
829 status is returned from the API, the callback will be called
830 when resources are available to fulfill the original request.
831
832 Note that the low resources condition is indicated to the caller
833 by returning VOS_STATUS_E_RESOURCES. This status is the only
834 non-success status that indicates to the caller that the callback
835 will be called when resources are available. All other status
836 indicate failures that are not recoverable and the 'callback'
837 will not be called.
838
839 VOS_STATUS_E_FAILURE - The API returns this status when unable
840 to get a packet from the packet pool because the pool
841 is depleted and the caller did not specify a low resource callback.
842
843 VOS_STATUS_E_ALREADY - This status is returned when the VOS
844 packet pool is in a 'low resource' condition and cannot
845 accomodate any more calls to retrieve packets from that
846 pool. Note this is a FAILURE and the 'low resource' callback
847 will *not* be called.
848
849 VOS_STATUS_E_FAULT - ppPacket or pOSPacket do not specify valid
850 pointers.
851
852 \sa vos_pkt_set_os_packet()
853
854 ------------------------------------------------------------------------*/
855VOS_STATUS vos_pkt_wrap_data_packet( vos_pkt_t **ppPacket,
856 VOS_PKT_TYPE pktType,
857 v_VOID_t *pOSPacket,
858 vos_pkt_get_packet_callback callback,
859 v_VOID_t *userData )
860{
861 struct list_head *pPktFreeList;
862 vos_pkt_low_resource_info *pLowResourceInfo;
863 struct vos_pkt_t *pVosPacket;
864
865 // Validate the return parameter pointer
866 if (unlikely(NULL == ppPacket))
867 {
868 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
869 "VPKT [%d]: NULL ppPacket", __LINE__);
870 return VOS_STATUS_E_INVAL;
871 }
872
873 // Validate the packet type. Only Tx Data packets can have an OS
874 // packet attached to them (Tx Mgmt and Rx Raw have OS packets
875 // pre-attached to them)
876 if (unlikely(VOS_PKT_TYPE_TX_802_3_DATA != pktType))
877 {
878 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530879 "VPKT [%d]: invalid pktType %d", __LINE__, pktType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700880 return VOS_STATUS_E_INVAL;
881 }
882
883 // determine which packet pool and low resource block we should use.
884 pPktFreeList = &gpVosPacketContext->txDataFreeList;
885 pLowResourceInfo = &gpVosPacketContext->txDataLowResourceInfo;
886
887 // is there already a low resource callback registered for this pool?
888 // we only support one callback per pool, so if one is already registered
889 // then we know we are already in a low-resource condition
890 if (unlikely(pLowResourceInfo->callback))
891 {
892 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
893 "VPKT [%d]: Low resource handler already registered",
894 __LINE__);
895 return VOS_STATUS_E_ALREADY;
896 }
897
898 // are there vos packets on the associated free pool?
899 if (unlikely(list_empty(pPktFreeList)))
900 {
901 // allocation failed
902 // did the caller specify a callback?
903 if (unlikely(NULL == callback))
904 {
905 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
906 "VPKT [%d]: Low resource condition and no callback provided",
907 __LINE__);
908 return VOS_STATUS_E_FAILURE;
909 }
910
911 // save the low resource information so that we can invoke the
912 // callback when a packet becomes available
913 pLowResourceInfo->callback = callback;
914 pLowResourceInfo->userData = userData;
915 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
916 "VPKT [%d]: Low resource condition for pool %s",
917 __LINE__, vos_pkti_packet_type_str(pktType));
918 return VOS_STATUS_E_RESOURCES;
919 }
920
921 // remove the first record from the free pool
922 pVosPacket = list_first_entry(pPktFreeList, struct vos_pkt_t, node);
923 list_del(&pVosPacket->node);
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 gpVosPacketContext->uctxDataFreeListCount --;
Jeff Johnson295189b2012-06-20 16:38:30 -0700925
926 // clear out the User Data pointers in the voss packet..
927 memset(&pVosPacket->pvUserData, 0, sizeof(pVosPacket->pvUserData));
928
929 // initialize the 'chain' pointer to NULL.
930 pVosPacket->pNext = NULL;
931
932 // set the packet type.
933 pVosPacket->packetType = pktType;
934
935 // set the skb pointer
936 pVosPacket->pSkb = (struct sk_buff *) pOSPacket;
937
938 // timestamp the vos packet.
939 pVosPacket->timestamp = vos_timer_get_system_ticks();
940
941 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
942 "VPKT [%d]: [%p] Packet allocated, type %s",
943 __LINE__, pVosPacket, vos_pkti_packet_type_str(pktType));
944
945 *ppPacket = pVosPacket;
946 return VOS_STATUS_SUCCESS;
947}
948
949
950
951/*---------------------------------------------------------------------------
952
953 \brief vos_pkt_set_os_packet() - set the OS packet in a VOS data packet
954
955 This API inserts an OS packet into a previously retreived VOS packet.
956 This API only applies to VOS packets of type VOS_PKT_TYPE_802_3_DATA or
957 VOS_PKT_TYPE_802_11_DATA.
958
959 There are cases where a user will need to get a VOS data packet without
960 having the OS packet to insert/wrap into the data packet. This could happen
961 if the user calls vos_pkt_wrap_data_packet() without the OS packet.
962
963 Also, when the user hit a 'low resource' situation for data packets, the
964 low resource callback is going to return a VOS packet without an OS packet
965 attached to it. The caller who gets the packet through the low resource
966 callback uses this API to insert an OS packet into the VOS packet that
967 was returned through the low resource callback.
968
969 \param pPacket - the voss Packet to insert the OS packet into.
970
971 \param pOSPacket - a pointer to the Transmit packet provided by the OS. This
972 OS provided packet will be wrapped into a vos_packet_t. Note this
973 OS packet pointer can be NULL. The OS packet pointer can be inserted
974 into a VOS packet of type VOS_PKT_TYPE_802_3_DATA or
975 VOS_PKT_TYPE_802_11_DATA through vos_pkt_set_os_packet().
976
977 Caller beware. If there is a valid OS packet wrapped into this
978 VOS packet already, this API will blindly overwrite the OS packet
979 with the new one specified on this API call. If you need to determine
980 or retreive the current OS packet from a VOS packet, call
981 vos_pkt_get_os_packet() first.
982
983 \return VOS_STATUS_SUCCESS - the API was able to insert the OS packet into
984 the vos_packet.
985
986 VOS_STATUS_E_INVAL - pktType is not a valid packet type. This
987 API only supports getting vos packets of type
988 VOS_PKT_TYPE_802_3_DATA or VOS_PKT_TYPE_802_11_DATA.
989
990 VOS_STATUS_E_FAULT - pPacket does not specify a valid pointer.
991
992 \sa vos_pkt_get_os_packet()
993
994 ---------------------------------------------------------------------------*/
995VOS_STATUS vos_pkt_set_os_packet( vos_pkt_t *pPacket,
996 v_VOID_t *pOSPacket )
997{
998 // Validate the input parameter pointers
999 if (unlikely((NULL == pPacket)||(NULL == pOSPacket)))
1000 {
1001 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1002 "VPKT [%d]: NULL pointer", __LINE__);
1003 return VOS_STATUS_E_INVAL;
1004 }
1005
1006 // Validate that this really an initialized vos packet
1007 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1008 {
1009 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1010 "VPKT [%d]: Invalid magic", __LINE__);
1011 return VOS_STATUS_E_INVAL;
1012 }
1013
1014 // Validate the packet type. Only Tx Data packets can have an OS
1015 // packet attached to them (Tx Mgmt and Rx Raw have OS packets
1016 // pre-attached to them)
1017 if (unlikely(VOS_PKT_TYPE_TX_802_3_DATA != pPacket->packetType))
1018 {
1019 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1020 "VPKT [%d]: invalid packet type %d[%s]",
1021 __LINE__, pPacket->packetType,
1022 vos_pkti_packet_type_str(pPacket->packetType));
1023 return VOS_STATUS_E_INVAL;
1024 }
1025
1026 // Is there already a packet attached? If so, just warn and continue
1027 if (unlikely(pPacket->pSkb))
1028 {
1029 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
1030 "VPKT [%d]: Packet previously attached", __LINE__);
1031 }
1032
1033 // attach
1034 pPacket->pSkb = (struct sk_buff *) pOSPacket;
1035
1036 return VOS_STATUS_SUCCESS;
1037}
1038
1039
1040/*---------------------------------------------------------------------------
1041
1042 \brief vos_pkt_get_os_packet() - get the OS packet in a VOS data packet
1043
1044 This API returns the OS packet that is inserted in a VOS packet.
1045 This API only applies to VOS packets of type VOS_PKT_TYPE_802_3_DATA or
1046 VOS_PKT_TYPE_802_11_DATA.
1047
1048 \param pPacket - the voss Packet to return the OS packet from.
1049
1050 \param ppOSPacket - a pointer to the location where the OS packet pointer
1051 retreived from the VOS packet will be returned. Note this OS packet
1052 pointer can be NULL, meaning there is no OS packet attached to this
1053 VOS data packet.
1054
1055 \param clearOSPacket - a boolean value that tells the API to clear out the
1056 OS packet pointer from the VOS packet. Setting this to 'true' will
1057 essentially remove the OS packet from the VOS packet. 'false' means
1058 the OS packet remains chained to the VOS packet. In either case,
1059 the OS packet pointer is returned to the caller.
1060
1061 \return VOS_STATUS_SUCCESS - the API was able to retreive the OS packet
1062 pointer from the VOS packet and return it to the caller in
1063 *ppOsPacket
1064
1065 VOS_STATUS_E_INVAL - pktType is not a valid packet type. This
1066 API only supports getting vos packets of type
1067 VOS_PKT_TYPE_802_3_DATA or VOS_PKT_TYPE_802_11_DATA.
1068
1069 VOS_STATUS_E_FAULT - pPacket or ppOsPacket does not specify a valid
1070 pointers.
1071
1072 \sa vos_pkt_set_os_packet(), vos_pkt_wrap_data_packet(),
1073 vos_pkt_return_packet()
1074
1075 ---------------------------------------------------------------------------*/
1076VOS_STATUS vos_pkt_get_os_packet( vos_pkt_t *pPacket,
1077 v_VOID_t **ppOSPacket,
1078 v_BOOL_t clearOSPacket )
1079{
1080 // Validate the input and output parameter pointers
1081 if (unlikely((NULL == pPacket)||(NULL == ppOSPacket)))
1082 {
1083 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1084 "VPKT [%d]: NULL pointer", __LINE__);
1085 return VOS_STATUS_E_INVAL;
1086 }
1087
1088 // Validate that this really an initialized vos packet
1089 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1090 {
1091 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1092 "VPKT [%d]: Invalid magic", __LINE__);
1093 return VOS_STATUS_E_INVAL;
1094 }
1095
1096 // get OS packet pointer
1097 *ppOSPacket = (v_VOID_t *) pPacket->pSkb;
1098
1099 // clear it?
1100 if (clearOSPacket)
1101 {
1102 pPacket->pSkb = NULL;
1103 }
1104
1105 return VOS_STATUS_SUCCESS;
1106}
1107
1108/**--------------------------------------------------------------------------
1109
1110 \brief vos_pkt_get_user_data_ptr() - return a pointer to user data area
1111 of a voss Packet
1112
1113 This API returns a pointer to a specified user Data area in the voss
1114 Packet. User data areas are uniqua areas of the voss Packet that can
1115 be used by specific components to store private data. These areas are
1116 identified by a user "ID" and should only be accessed by the component
1117 specified.
1118
1119 \param pPacket - the voss Packet to retreive the user data pointer from.
1120
1121 \param userID - the identifier for the user data area in the voss Packet
1122 to get.
1123
1124 User IDs and user data areas in the voss Packet are
1125 available for:
1126 - Transport Layer (TL)
1127 - Bus Abstraction Layer (BAL)
1128 - SDIO Services Component (SSC)
1129 - Host Device Driver (HDD)
1130
1131 \param ppUserData - pointer to location to return the pointer to the user
1132 data.
1133
1134 \return - Nothing.
1135
1136 \sa
1137
1138 ---------------------------------------------------------------------------*/
1139v_VOID_t vos_pkt_get_user_data_ptr( vos_pkt_t *pPacket,
1140 VOS_PKT_USER_DATA_ID userID,
1141 v_VOID_t **ppUserData )
1142{
1143 // Validate the input and output parameter pointers
1144 if (unlikely(NULL == pPacket))
1145 {
1146 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1147 "VPKT [%d]: NULL pointer", __LINE__);
1148 if (ppUserData != NULL)
1149 {
1150 *ppUserData = NULL;
1151 }
1152 return;
1153 }
1154
1155 // Validate that this really an initialized vos packet
1156 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1157 {
1158 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1159 "VPKT [%d]: Invalid magic", __LINE__);
1160 *ppUserData = NULL;
1161 return;
1162 }
1163
1164 // Validate userID
1165 if (unlikely(userID >= VOS_PKT_USER_DATA_ID_MAX))
1166 {
1167 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1168 "VPKT [%d]: Invalid user ID [%d]", __LINE__, userID);
1169 *ppUserData = NULL;
1170 return;
1171 }
1172
1173 // retreive the user data pointer from the vos Packet and
1174 // return it to the caller.
1175 *ppUserData = pPacket->pvUserData[userID];
1176
1177 return;
1178}
1179
1180
1181/**--------------------------------------------------------------------------
1182
1183 \brief vos_pkt_set_user_data_ptr() - set the user data pointer of a voss
1184 Packet
1185
1186 This API sets a pointer in the specified user Data area in the voss
1187 Packet. User data areas are uniqua areas of the voss Packet that can
1188 be used by specific components to store private data. These areas are
1189 identified by a user "ID" and should only be accessed by the component
1190 specified.
1191
1192 Note: The size of the user data areas in the voss Packet are fixed. The
1193 size of a single pointer is available in each user area.
1194
1195 \param pPacket - the voss Packet to set the user pointer.
1196
1197 \param userID - the identifier for the user data area in the voss Packet
1198 to set.
1199
1200 User IDs and user data areas in the voss Packet are
1201 available for:
1202 - Transport Layer (TL)
1203 - Bus Abstraction Layer (BAL)
1204 - SDIO Services Component (SSC)
1205 - Host Device Driver (HDD)
1206
1207 \param pUserData - pointer value to set in the user data area of the voss
1208 packet..
1209
1210 \return - Nothing.
1211
1212 \sa
1213
1214 ---------------------------------------------------------------------------*/
1215v_VOID_t vos_pkt_set_user_data_ptr( vos_pkt_t *pPacket,
1216 VOS_PKT_USER_DATA_ID userID,
1217 v_VOID_t *pUserData )
1218{
1219 // Validate the input parameter pointer
1220 if (unlikely(NULL == pPacket))
1221 {
1222 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1223 "VPKT [%d]: NULL pointer", __LINE__);
1224 return;
1225 }
1226
1227 // Validate that this is really an initialized vos packet
1228 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1229 {
1230 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1231 "VPKT [%d]: Invalid magic", __LINE__);
1232 return;
1233 }
1234
1235 // Validate userID
1236 if (unlikely(userID >= VOS_PKT_USER_DATA_ID_MAX))
1237 {
1238 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1239 "VPKT [%d]: Invalid user ID [%d]", __LINE__, userID);
1240 return;
1241 }
1242
1243 // retreive the user data pointer from the vos Packet and
1244 // return it to the caller.
1245 pPacket->pvUserData[userID] = pUserData;
1246
1247 return;
1248}
1249
1250/**--------------------------------------------------------------------------
1251
1252 \brief vos_pkt_return_packet() - Return a voss Packet (chain) to vOSS
1253
1254 This API returns a voss Packet to the internally managed packet pool.
1255
1256 Note: If there are multiple packets chained to this packet, the entire
1257 packet chain is returned to vOSS. The caller must unchain the
1258 packets through vos_pkt_get_next_packet() and return them individually
1259 if all packets in the packet chain are not to be returned.
1260
1261 \param pPacket - the voss Packet(s) to return. Note all packets chained
1262 to this packet are returned to vOSS.
1263
1264 \return
1265
1266 \sa
1267
1268 ---------------------------------------------------------------------------*/
1269VOS_STATUS vos_pkt_return_packet( vos_pkt_t *pPacket )
1270{
1271 vos_pkt_t *pNext;
1272 struct list_head *pPktFreeList;
1273 vos_pkt_low_resource_info *pLowResourceInfo;
1274 vos_pkt_get_packet_callback callback;
1275 v_SIZE_t *pCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 VOS_PKT_TYPE packetType = VOS_PKT_TYPE_TX_802_3_DATA;
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001277 v_BOOL_t lowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001278
1279 // Validate the input parameter pointer
1280 if (unlikely(NULL == pPacket))
1281 {
1282 return VOS_STATUS_E_INVAL;
1283 }
1284
1285 // iterate though all packets in the chain
1286 while (pPacket)
1287 {
1288 // unlink this packet from the chain
1289 pNext = pPacket->pNext;
1290 pPacket->pNext = NULL;
1291
1292 // Validate that this really an initialized vos packet
1293 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1294 {
1295 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1296 "VPKT [%d]: Invalid magic", __LINE__);
1297 return VOS_STATUS_E_INVAL;
1298 }
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -07001299
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 //If an skb is attached then reset the pointers
1301 if (pPacket->pSkb)
1302 {
1303 pPacket->pSkb->len = 0;
1304 pPacket->pSkb->data = pPacket->pSkb->head;
1305 skb_reset_tail_pointer(pPacket->pSkb);
1306 skb_reserve(pPacket->pSkb, VPKT_SIZE_BUFFER);
1307 }
1308
1309 pCount = NULL;
1310 // determine which packet pool and low resource block we should use.
1311 switch (pPacket->packetType)
1312 {
1313 case VOS_PKT_TYPE_RX_RAW:
1314 // if this packet still has an skb attached, we can put it
1315 // back in the free pool, otherwise we need to put it in the
1316 // replenish pool
1317 if (pPacket->pSkb)
1318 {
1319 pPktFreeList = &gpVosPacketContext->rxRawFreeList;
1320 pLowResourceInfo = &gpVosPacketContext->rxRawLowResourceInfo;
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -08001321 pCount = &gpVosPacketContext->rxRawFreeListCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 }
1323 else
1324 {
1325 pPktFreeList = &gpVosPacketContext->rxReplenishList;
1326 pLowResourceInfo = NULL;
1327 pCount = &gpVosPacketContext->rxReplenishListCount;
1328 }
1329 packetType = VOS_PKT_TYPE_RX_RAW;
1330 break;
1331
1332 case VOS_PKT_TYPE_TX_802_11_MGMT:
1333
1334 pPktFreeList = &gpVosPacketContext->txMgmtFreeList;
1335 pLowResourceInfo = &gpVosPacketContext->txMgmtLowResourceInfo;
1336
1337 break;
1338
1339 case VOS_PKT_TYPE_TX_802_3_DATA:
1340 pPktFreeList = &gpVosPacketContext->txDataFreeList;
1341 pLowResourceInfo = &gpVosPacketContext->txDataLowResourceInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07001342 gpVosPacketContext->uctxDataFreeListCount ++;
Jeff Johnson295189b2012-06-20 16:38:30 -07001343 break;
1344
1345 default:
1346 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1347 "VPKT [%d]: invalid packet type %d[%s]",
1348 __LINE__, pPacket->packetType,
1349 vos_pkti_packet_type_str(pPacket->packetType));
1350
1351 return VOS_STATUS_E_INVAL;
1352 }
1353
1354
1355 // is there a low resource condition pending for this packet type?
1356 if (pLowResourceInfo && pLowResourceInfo->callback)
1357 {
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001358 // pLowResourceInfo->callback is modified from threads (different CPU's).
1359 // So a mutex is enough to protect is against a race condition.
1360 // mutex is SMP safe
1361 mutex_lock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 callback = pLowResourceInfo->callback;
1363 pLowResourceInfo->callback = NULL;
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001364 mutex_unlock(&gpVosPacketContext->mlock);
1365
1366 // only one context can get a valid callback
1367 if(callback)
1368 {
1369 // [DEBUG]
1370 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"VPKT [%d]: recycle %p", __LINE__, pPacket);
1371
1372 // yes, so rather than placing the packet back in the free pool
1373 // we will invoke the low resource callback
1374 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1375 "VPKT [%d]: [%p] Packet recycled, type %d[%s]",
1376 __LINE__, pPacket, pPacket->packetType,
1377 vos_pkti_packet_type_str(pPacket->packetType));
1378
1379 // clear out the User Data pointers in the voss packet..
1380 memset(&pPacket->pvUserData, 0, sizeof(pPacket->pvUserData));
1381
1382 // initialize the 'chain' pointer to NULL.
1383 pPacket->pNext = NULL;
1384
1385 // timestamp the vos packet.
1386 pPacket->timestamp = vos_timer_get_system_ticks();
1387
1388 callback(pPacket, pLowResourceInfo->userData);
1389
1390 // We did process low resource condition
1391 lowResource = VOS_TRUE;
1392 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001393 }
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001394
1395
1396 if(!lowResource)
Jeff Johnson295189b2012-06-20 16:38:30 -07001397 {
1398 // this packet does not satisfy a low resource condition
1399 // so put it back in the appropriate free pool
1400 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
1401 "VPKT [%d]: [%p] Packet returned, type %d[%s]",
1402 __LINE__, pPacket, pPacket->packetType,
1403 vos_pkti_packet_type_str(pPacket->packetType));
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -07001404 mutex_lock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 list_add_tail(&pPacket->node, pPktFreeList);
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -07001406 mutex_unlock(&gpVosPacketContext->mlock);
1407
Jeff Johnson295189b2012-06-20 16:38:30 -07001408 if (pCount)
1409 {
1410 (*pCount)++;
1411 }
1412 }
1413
1414 // move to next packet in the chain
1415 pPacket = pNext;
1416
1417 } // while (pPacket)
1418
1419 // see if we need to replenish the Rx Raw pool
1420 if (VOS_PKT_TYPE_RX_RAW == packetType)
1421 {
1422 vos_pkti_replenish_raw_pool();
1423 }
1424 return VOS_STATUS_SUCCESS;
1425}
1426
1427/**--------------------------------------------------------------------------
1428
1429 \brief vos_pkt_chain_packet() - chain a voss Packet to another packet
1430
1431 This API chains a voss Packet to another voss Packet, creating a packet
1432 chain. Packets can be chained before or after the current packet in the
1433 packet chain.
1434
1435 \param pPacket - pointer to a voss packet to chain to
1436
1437 \param pChainPacket - pointer to packet to chain
1438
1439 \param chainAfter - boolean to specify to chain packet after or before
1440 the input packet
1441 <ul>
1442 <li> true - chain packet AFTER pPacket (chain behind)
1443 <li> false - chain packet BEFORE pPacket (chain in front)
1444 </ul>
1445
1446 \return
1447
1448 \sa
1449
1450 ---------------------------------------------------------------------------*/
1451VOS_STATUS vos_pkt_chain_packet( vos_pkt_t *pPacket,
1452 vos_pkt_t *pChainPacket,
1453 v_BOOL_t chainAfter )
1454{
1455 // Validate the parameter pointers
1456 if (unlikely((NULL == pPacket) || (NULL == pChainPacket)))
1457 {
1458 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1459 "VPKT [%d]: NULL pointer", __LINE__);
1460 return VOS_STATUS_E_INVAL;
1461 }
1462
1463 // Validate that these are really initialized vos packets
1464 if (unlikely((VPKT_MAGIC_NUMBER != pPacket->magic) ||
1465 (VPKT_MAGIC_NUMBER != pChainPacket->magic)))
1466 {
1467 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1468 "VPKT [%d]: Invalid magic", __LINE__);
1469 return VOS_STATUS_E_INVAL;
1470 }
1471
1472 // swap pointers if we chain before
1473 if (unlikely(VOS_FALSE == chainAfter))
1474 {
1475 vos_pkt_t *pTmp = pPacket;
1476 pPacket = pChainPacket;
1477 pChainPacket = pTmp;
1478 }
1479
1480 // find the end of the chain
1481 while (pPacket->pNext)
1482 {
1483 pPacket = pPacket->pNext;
1484 }
1485
1486 // attach
1487 pPacket->pNext = pChainPacket;
1488
1489 return VOS_STATUS_SUCCESS;
1490}
1491
1492
1493/**--------------------------------------------------------------------------
1494
1495 \brief vos_pkt_walk_packet_chain() - Walk packet chain and (possibly)
1496 unchain packets
1497
1498 This API will walk the voss Packet and unchain the packet from the chain,
1499 if specified. The 'next' packet in the packet chain is returned as the
1500 packet chain is traversed.
1501
1502 \param pPacket - input vos_packet walk
1503
1504 \param ppChainedPacket - pointer to location to return the 'next' voss
1505 packet pointer in the packet chain.
1506 NULL means there is was not packet chained
1507 to this packet.
1508
1509 \param unchainPacket - Flag that specifies if the caller wants the packet
1510 to be removed from the packet chain. This is
1511 provided to allow the caller to walk the packet chain
1512 with or without breaking the chain.
1513
1514 <ul>
1515 <li> true - when set 'true' the API will return
1516 the 'next' packet pointer in the voss Packte chain and
1517 *WILL* unchain the input packet from the packet chain.
1518
1519 <li> NOT false - when set 'false' the API will return
1520 the 'next' packet pointer in the voss Packet chain but
1521 *WILL NOT* unchain the packet chain. This option gives
1522 the caller the ability to walk the packet chain without
1523 modifying it in the process.
1524 </ul>
1525
1526 \note Having the packets chained has an implicaiton on how the return
1527 packet API (vos_pkt_return_packet() ) operates.
1528
1529 \return
1530
1531 \sa
1532
1533 ---------------------------------------------------------------------------*/
1534VOS_STATUS vos_pkt_walk_packet_chain( vos_pkt_t *pPacket,
1535 vos_pkt_t **ppChainedPacket,
1536 v_BOOL_t unchainPacket )
1537{
1538 // Validate the parameter pointers
1539 if (unlikely((NULL == pPacket) || (NULL == ppChainedPacket)))
1540 {
1541 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1542 "VPKT [%d]: NULL pointer", __LINE__);
1543 return VOS_STATUS_E_INVAL;
1544 }
1545
1546 // Validate that this is really an initialized vos packet
1547 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1548 {
1549 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1550 "VPKT [%d]: Invalid magic", __LINE__);
1551 return VOS_STATUS_E_INVAL;
1552 }
1553
1554 // get next packet
1555 *ppChainedPacket = pPacket->pNext;
1556
1557 // if asked to unchain, then unchain it
1558 if (VOS_FALSE != unchainPacket)
1559 {
1560 pPacket->pNext = NULL;
1561 }
1562
1563 // if end of the chain, indicate empty to the caller
1564 if (*ppChainedPacket)
1565 {
1566 return VOS_STATUS_SUCCESS;
1567 }
1568 else
1569 {
1570 return VOS_STATUS_E_EMPTY;
1571 }
1572}
1573
1574/**--------------------------------------------------------------------------
1575
1576 \brief vos_pkt_get_data_vector() - Get data vectors from a voss Packet
1577
1578 This API gets the complete set of Vectors (pointer / length pairs) that
1579 describe all of the data that makes up the voss Packet.
1580
1581 \param pPacket - pointer to the vOSS Packet to get the pointer/length
1582 vector from
1583
1584 \param pVector - pointer to the vector array where the vectors are returned.
1585
1586 \param pNumVectors - Number of vector's in the vector array (at pVector).
1587 On successful return, *pNumVectors is updated with the
1588 number of pointer/length vectors at pVector populated
1589 with valid vectors.
1590
1591 Call with NULL pVector or 0 vectorSize, will return the size of vector
1592 needed (in *pNumVectors)
1593
1594 Caller allocates and frees the vector memory.
1595
1596 \return
1597
1598 \sa
1599
1600 ---------------------------------------------------------------------------*/
1601VOS_STATUS vos_pkt_get_data_vector( vos_pkt_t *pPacket,
1602 vos_pkt_data_vector_t *pVector,
1603 v_SIZE_t *pNumVectors )
1604{
1605 // not supported
1606
1607 VOS_ASSERT(0);
1608 return VOS_STATUS_E_FAILURE;
1609}
1610
1611
1612/**--------------------------------------------------------------------------
1613
1614 \brief vos_pkt_extract_data() - Extract data from the voss Packet.
1615
1616 This API extracts data from a voss Packet, copying the data into the
1617 supplied output buffer. Note the data is copied from the vos packet
1618 but the data remains in the vos packet and the size is unaffected.
1619
1620 \param pPacket - the voss Packet to get the data from.
1621
1622 \param pktOffset - the offset from the start of the voss Packet to get the
1623 data. (i.e. 0 would be the beginning of the voss Packet).
1624
1625 \param pOutputBuffer - Pointer to the location where the voss Packet data
1626 will be copied.
1627
1628 \param pOutputBufferSize - on input, contains the amount of data to extract
1629 into the output buffer. Upon return, contains the amount of data
1630 extracted into the output buffer.
1631
1632 Note: an input of 0 in *pOutputBufferSize, means to copy *all*
1633 data in the voss Packet into the output buffer. The caller is
1634 responsible for assuring the output buffer size is big enough
1635 since the size of the buffer is not being passed in!
1636
1637 \return
1638
1639 \sa
1640
1641 ---------------------------------------------------------------------------*/
1642VOS_STATUS vos_pkt_extract_data( vos_pkt_t *pPacket,
1643 v_SIZE_t pktOffset,
1644 v_VOID_t *pOutputBuffer,
1645 v_SIZE_t *pOutputBufferSize )
1646{
1647 v_SIZE_t len;
1648 struct sk_buff *skb;
1649
1650 // Validate the parameter pointers
1651 if (unlikely((NULL == pPacket) ||
1652 (NULL == pOutputBuffer) ||
1653 (NULL == pOutputBufferSize)))
1654 {
1655 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1656 "VPKT [%d]: NULL pointer", __LINE__);
1657 return VOS_STATUS_E_INVAL;
1658 }
1659
1660 // Validate that this is really an initialized vos packet
1661 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1662 {
1663 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1664 "VPKT [%d]: Invalid magic", __LINE__);
1665 return VOS_STATUS_E_INVAL;
1666 }
1667
1668 // get pointer to the skb
1669 skb = pPacket->pSkb;
1670
1671 // Validate the skb
1672 if (unlikely(NULL == skb))
1673 {
1674 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1675 "VPKT [%d]: NULL skb", __LINE__);
1676 return VOS_STATUS_E_INVAL;
1677 }
1678
1679 // get number of bytes requested
1680 len = *pOutputBufferSize;
1681
1682 // if 0 is input in the *pOutputBufferSize, then the user wants us to
1683 // extract *all* the data in the buffer. Otherwise, the user has
1684 // specified the output buffer size in *pOutputBufferSize. In the
1685 // case where the output buffer size is specified, let's validate that
1686 // it is big enough.
1687 //
1688 // \note: i'm not crazy about this. we should enforce the output
1689 // buffer size on input so this API is not going to cause crashes
1690 // because buffers are too small and the caller inputs 0 == don't care
1691 // to check the size... !!
1692 if (0 == len)
1693 {
1694 len = skb->len - pktOffset;
1695
1696 // return # of bytes copied
1697 *pOutputBufferSize = len;
1698 }
1699 else
1700 {
1701 // make sure we aren't extracting past the end of the packet
1702 if (len > (skb->len - pktOffset))
1703 {
1704 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1705 "VPKT [%d]: Request overrun, "
1706 "req offset %d, req size %d, packet size %d",
1707 __LINE__, pktOffset, len, skb->len);
1708 return VOS_STATUS_E_INVAL;
1709 }
1710 }
1711
1712 // copy the data
1713 memcpy(pOutputBuffer, &skb->data[pktOffset], len);
1714
1715 return VOS_STATUS_SUCCESS;
1716}
1717
1718/**--------------------------------------------------------------------------
1719
1720 \brief vos_pkt_extract_data_chain() - Extract data from a voss Packet chain.
1721
1722 This API extracts *all* the data from a voss Packet chain, copying the
1723 data into the supplied output buffer. Note the data is copied from
1724 the vos packet chain but the data remains in the vos packet and the
1725 size of the vos packets are unaffected.
1726
1727 \param pPacket - the first voss Packet in the voss packet chain to
1728 extract data.
1729
1730 \param pOutputBuffer - Pointer to the location where the voss Packet data
1731 will be copied.
1732
1733 \param pOutputBufferSize - on input, contains the maximum amount of data
1734 that can be extracted into the output buffer. Upon return, contains
1735 the amount of data extracted from the packet chain.
1736
1737 \return VOS_STATUS_SUCCESS - the data from the entire packet chain is
1738 extracted and found at *pOutputBuffer. *pOutputBufferSize bytes
1739 were extracted.
1740
1741 VOS_STATUS_E_FAULT - pPacket, pOutputBuffer, or pOutputBufferSize
1742 is not a valid pointer.
1743
1744 VOS_STATUS_E_NOMEM - there is not enough room to extract the data
1745 from the entire packet chain. *pOutputBufferSize has been updated
1746 with the size needed to extract the entier packet chain.
1747
1748 \sa vos_pkt_extract_data()
1749
1750 ---------------------------------------------------------------------------*/
1751VOS_STATUS vos_pkt_extract_data_chain( vos_pkt_t *pPacket,
1752 v_VOID_t *pOutputBuffer,
1753 v_SIZE_t *pOutputBufferSize )
1754{
1755 VOS_STATUS vosStatus;
1756 v_SIZE_t len;
1757 struct sk_buff *skb;
1758
1759 // Validate the parameter pointers
1760 if (unlikely((NULL == pPacket) ||
1761 (NULL == pOutputBuffer) ||
1762 (NULL == pOutputBufferSize)))
1763 {
1764 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1765 "VPKT [%d]: NULL pointer", __LINE__);
1766 return VOS_STATUS_E_INVAL;
1767 }
1768
1769 // Validate that this is really an initialized vos packet
1770 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1771 {
1772 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1773 "VPKT [%d]: Invalid magic", __LINE__);
1774 return VOS_STATUS_E_INVAL;
1775 }
1776
1777 // get the length of the entire packet chain.
1778 vosStatus = vos_pkt_get_packet_chain_length(pPacket, &len);
1779 if (unlikely(VOS_STATUS_SUCCESS != vosStatus))
1780 {
1781 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1782 "VPKT [%d]: Unable to get packet chain length", __LINE__);
1783 return VOS_STATUS_E_FAILURE;
1784 }
1785
1786 // if the output buffer size is too small, return NOMEM and update
1787 // the actual size needed in *pOutputBufferSize
1788 if (len > *pOutputBufferSize)
1789 {
1790 *pOutputBufferSize = len;
1791 return VOS_STATUS_E_NOMEM;
1792 }
1793
1794 // walk through each packet in the chain, copying the data
1795 while (pPacket)
1796 {
1797 // get pointer to the skb
1798 skb = pPacket->pSkb;
1799
1800 // Validate the skb
1801 if (unlikely(NULL == skb))
1802 {
1803 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1804 "VPKT [%d]: NULL skb", __LINE__);
1805 return VOS_STATUS_E_INVAL;
1806 }
1807
1808 memcpy(pOutputBuffer, skb->data, skb->len);
1809 pOutputBuffer += skb->len;
1810
1811 pPacket = pPacket->pNext;
1812 }
1813
1814 return VOS_STATUS_SUCCESS;
1815}
1816
1817/**--------------------------------------------------------------------------
1818
1819 \brief vos_pkt_peek_data() - peek into voss Packet at given offset
1820
1821 This API provides a pointer to a specified offset into a voss Packet,
1822 allowing the caller to peek at a given number of bytes in the voss Packet.
1823 Upon successful return, the caller can access "numBytes" of data at
1824 "pPacketData".
1825
1826 This API will fail if the data length requested to peek at is not in
1827 contiguous memory in the voss Packet. In this case, the caller should
1828 use vos_pkt_extract_data() to have the data copied into a caller supplied
1829 buffer.
1830
1831 \param pPacket - the vOSS Packet to peek into
1832
1833 \param pktOffset - the offset into the voss Packet data to peek into.
1834
1835 \param ppPacketData - pointer to the location where the pointer to the
1836 packet data at pktOffset will be returned.
1837
1838 \param numBytes - the number of bytes the caller wishes to peek at.
1839
1840 \return
1841
1842 \sa
1843
1844 ---------------------------------------------------------------------------*/
1845VOS_STATUS vos_pkt_peek_data( vos_pkt_t *pPacket,
1846 v_SIZE_t pktOffset,
1847 v_VOID_t **ppPacketData,
1848 v_SIZE_t numBytes )
1849{
1850 struct sk_buff *skb;
1851
1852 // Validate the parameter pointers
1853 if (unlikely((NULL == pPacket) ||
1854 (NULL == ppPacketData)))
1855 {
1856 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1857 "VPKT [%d]: NULL pointer", __LINE__);
1858 return VOS_STATUS_E_INVAL;
1859 }
1860
1861 // Validate that this is really an initialized vos packet
1862 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1863 {
1864 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1865 "VPKT [%d]: Invalid magic", __LINE__);
1866 return VOS_STATUS_E_INVAL;
1867 }
1868
1869 // Validate numBytes
1870 if (unlikely(0 == numBytes))
1871 {
1872 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1873 "VPKT [%d]: Invalid numBytes", __LINE__);
1874 return VOS_STATUS_E_INVAL;
1875 }
1876
1877 // get pointer to the skb
1878 skb = pPacket->pSkb;
1879
1880 // Validate the skb
1881 if (unlikely(NULL == skb))
1882 {
1883 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1884 "VPKT [%d]: NULL skb", __LINE__);
1885 return VOS_STATUS_E_INVAL;
1886 }
1887
1888 // check for overflow
1889 if (unlikely((pktOffset + numBytes) > skb->len))
1890 {
1891 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1892 "VPKT [%d]: Packet overflow, offset %d size %d len %d",
1893 __LINE__, pktOffset, numBytes, skb->len);
1894 return VOS_STATUS_E_INVAL;
1895 }
1896
1897 // return pointer to the requested data
1898 *ppPacketData = &skb->data[pktOffset];
1899 return VOS_STATUS_SUCCESS;
1900}
1901
1902
1903/**--------------------------------------------------------------------------
1904
1905 \brief vos_pkt_get_packet_type() - Get packet type for a voss Packet
1906
1907 This API returns the packet Type for a voss Packet.
1908
1909 \param pPacket - the voss Packet to get the packet type from.
1910
1911 \param pPacketType - location to return the packet type for the voss Packet
1912
1913 \return
1914
1915 \sa
1916
1917 ---------------------------------------------------------------------------*/
1918VOS_STATUS vos_pkt_get_packet_type( vos_pkt_t *pPacket,
1919 VOS_PKT_TYPE *pPacketType )
1920{
1921 // Validate the parameter pointers
1922 if (unlikely((NULL == pPacket) ||
1923 (NULL == pPacketType)))
1924 {
1925 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1926 "VPKT [%d]: NULL pointer", __LINE__);
1927 return VOS_STATUS_E_INVAL;
1928 }
1929
1930 // Validate that this is really an initialized vos packet
1931 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1932 {
1933 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1934 "VPKT [%d]: Invalid magic", __LINE__);
1935 return VOS_STATUS_E_INVAL;
1936 }
1937
1938 // return the requested information
1939 *pPacketType = pPacket->packetType;
1940 return VOS_STATUS_SUCCESS;
1941}
1942
1943
1944
1945/**--------------------------------------------------------------------------
1946
1947 \brief vos_pkt_get_packet_length() - Get packet length for a voss Packet
1948
1949 This API returns the total length of the data in a voss Packet.
1950
1951 \param pPacket - the voss Packet to get the packet length from.
1952
1953 \param pPacketSize - location to return the total size of the data contained
1954 in the voss Packet.
1955 \return
1956
1957 \sa
1958
1959 ---------------------------------------------------------------------------*/
1960VOS_STATUS vos_pkt_get_packet_length( vos_pkt_t *pPacket,
1961 v_U16_t *pPacketSize )
1962{
1963 // Validate the parameter pointers
1964 if (unlikely((NULL == pPacket) ||
1965 (NULL == pPacketSize)))
1966 {
1967 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1968 "VPKT [%d]: NULL pointer", __LINE__);
1969 return VOS_STATUS_E_INVAL;
1970 }
1971
1972 // Validate that this is really an initialized vos packet
1973 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1974 {
1975 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1976 "VPKT [%d]: Invalid magic", __LINE__);
1977 return VOS_STATUS_E_INVAL;
1978 }
1979
1980 // Validate the skb
1981 if (unlikely(NULL == pPacket->pSkb))
1982 {
1983 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1984 "VPKT [%d]: NULL skb", __LINE__);
1985 return VOS_STATUS_E_INVAL;
1986 }
1987
1988 // return the requested information
1989 *pPacketSize = pPacket->pSkb->len;
1990 return VOS_STATUS_SUCCESS;
1991}
1992
1993
1994/**--------------------------------------------------------------------------
1995
1996 \brief vos_pkt_get_packet_chain_length() - Get length of a vos packet chain
1997
1998 This API returns the total length of the data in a voss Packet chain.
1999
2000 \param pPacket - the voss Packet at the start of the packet chain. This API
2001 will calculate the length of data in the packet chain stating with
2002 this packet.
2003
2004 \param pPacketSize - location to return the total size of the data contained
2005 in the voss Packet.
2006 \return
2007
2008 \sa
2009
2010 ---------------------------------------------------------------------------*/
2011VOS_STATUS vos_pkt_get_packet_chain_length( vos_pkt_t *pPacketChain,
2012 v_SIZE_t *pPacketChainSize )
2013{
2014 v_SIZE_t chainSize = 0;
2015
2016 // Validate the parameter pointers
2017 if (unlikely((NULL == pPacketChain) ||
2018 (NULL == pPacketChainSize)))
2019 {
2020 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2021 "VPKT [%d]: NULL pointer", __LINE__);
2022 return VOS_STATUS_E_INVAL;
2023 }
2024
2025 // walk through each packet in the chain, adding its length
2026 while (pPacketChain)
2027 {
2028
2029 // Validate that this is really an initialized vos packet
2030 if (unlikely(VPKT_MAGIC_NUMBER != pPacketChain->magic))
2031 {
2032 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2033 "VPKT [%d]: Invalid magic", __LINE__);
2034 return VOS_STATUS_E_INVAL;
2035 }
2036
2037 // Validate the skb
2038 if (unlikely(NULL == pPacketChain->pSkb))
2039 {
2040 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2041 "VPKT [%d]: NULL skb", __LINE__);
2042 return VOS_STATUS_E_INVAL;
2043 }
2044
2045 chainSize += pPacketChain->pSkb->len;
2046 pPacketChain = pPacketChain->pNext;
2047 }
2048
2049 // return result
2050 *pPacketChainSize = chainSize;
2051 return VOS_STATUS_SUCCESS;
2052}
2053
2054
2055/**--------------------------------------------------------------------------
2056
2057 \brief vos_pkt_push_head() - push data on the front a of a voss Packet
2058
2059 This API will push data onto the front of a voss Packet. The data will be
2060 appended in front of any data already contained in the voss Packet.
2061
2062 \param pPacket - the voss Packet to modify.
2063
2064 \param pData - pointer to the data to push onto the head of the voss Packet.
2065
2066 \param dataSize - the size of the data to put onto the head of the voss
2067 Packet.
2068
2069 \return
2070
2071 \sa
2072
2073 ---------------------------------------------------------------------------*/
2074VOS_STATUS vos_pkt_push_head( vos_pkt_t *pPacket,
2075 v_VOID_t *pData,
2076 v_SIZE_t dataSize )
2077{
2078 struct sk_buff *skb;
2079
2080 // Validate the parameter pointers
2081 if (unlikely((NULL == pPacket) || (NULL == pData)))
2082 {
2083 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2084 "VPKT [%d]: NULL pointer", __LINE__);
2085 return VOS_STATUS_E_INVAL;
2086 }
2087
2088 // Validate that this is really an initialized vos packet
2089 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2090 {
2091 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2092 "VPKT [%d]: Invalid magic", __LINE__);
2093 return VOS_STATUS_E_INVAL;
2094 }
2095
2096 // get pointer to the skb
2097 skb = pPacket->pSkb;
2098
2099 // Validate the skb
2100 if (unlikely(NULL == skb))
2101 {
2102 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2103 "VPKT [%d]: NULL skb", __LINE__);
2104 return VOS_STATUS_E_INVAL;
2105 }
2106
2107 // Make sure there is headroom. As a performance optimization we
2108 // can omit this check later since skb_push() will also perform the
2109 // check (except skb_push() will panic the kernel)
2110 if (unlikely(skb_headroom(skb) < dataSize))
2111 {
2112 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2113 "VPKT [%d]: Insufficient headroom, "
2114 "head[%p], data[%p], req[%d]",
2115 __LINE__, skb->head, skb->data, dataSize);
2116 return VOS_STATUS_E_INVAL;
2117 }
2118
2119 // actually push the data
2120 memcpy(skb_push(skb, dataSize), pData, dataSize);
2121
2122 return VOS_STATUS_SUCCESS;
2123}
2124
2125/**--------------------------------------------------------------------------
2126
2127 \brief vos_pkt_reserve_head() - Reserve space at the front of a voss Packet
2128
2129 This API will reserve space at the front of a voss Packet. The caller can
2130 then copy data into this reserved space using memcpy() like functions. This
2131 allows the caller to reserve space and build headers directly in this
2132 reserved space in the voss Packet.
2133
2134 Upon successful return, the length of the voss Packet is increased by
2135 dataSize.
2136
2137 < put a before / after picture here>
2138
2139 \param pPacket - the voss Packet to modify.
2140
2141 \param ppData - pointer to the location where the pointer to the reserved
2142 space is returned. Upon successful return, the caller has
2143 write / read access to the data space at *ppData for length
2144 dataSize to build headers, etc.
2145
2146 \param dataSize - the size of the data to reserve at the head of the voss
2147 Packet. Upon successful return, the length of the voss
2148 Packet is increased by dataSize.
2149
2150 \return
2151
2152 \sa
2153
2154 ---------------------------------------------------------------------------*/
2155VOS_STATUS vos_pkt_reserve_head( vos_pkt_t *pPacket,
2156 v_VOID_t **ppData,
2157 v_SIZE_t dataSize )
2158{
2159 struct sk_buff *skb;
2160 struct sk_buff *newskb;
2161
2162 // Validate the parameter pointers
2163 if (unlikely((NULL == pPacket) || (NULL == ppData)))
2164 {
2165 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2166 "VPKT [%d]: NULL pointer", __LINE__);
2167 return VOS_STATUS_E_INVAL;
2168 }
2169
2170 // Validate that this is really an initialized vos packet
2171 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2172 {
2173 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2174 "VPKT [%d]: Invalid magic", __LINE__);
2175 return VOS_STATUS_E_INVAL;
2176 }
2177
2178 // get pointer to the skb
2179 skb = pPacket->pSkb;
2180
2181 // Validate the skb
2182 if (unlikely(NULL == skb))
2183 {
2184 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2185 "VPKT [%d]: NULL skb", __LINE__);
2186 return VOS_STATUS_E_INVAL;
2187 }
2188
2189 // Make sure there is headroom. As a performance optimization we
2190 // can omit this check later since skb_push() will also perform the
2191 // check (except skb_push() will panic the kernel)
2192 if (unlikely(skb_headroom(skb) < dataSize))
2193 {
2194 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2195 "VPKT [%d]: Insufficient headroom, "
2196 "head[%p], data[%p], req[%d]",
2197 __LINE__, skb->head, skb->data, dataSize);
2198
2199 if ((newskb = skb_realloc_headroom(skb, dataSize)) == NULL) {
2200 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2201 "VPKT [%d]: Failed to realloc headroom", __LINE__);
2202 return VOS_STATUS_E_INVAL;
2203 }
2204
2205 kfree_skb(skb);
2206 skb = newskb;
2207
2208 // set the skb pointer
2209 pPacket->pSkb = newskb;
2210 }
2211
2212 // actually allocate the headroom
2213 *ppData = skb_push(skb, dataSize);
2214 // Zero out so we dont take the fastpath on Android.
2215 memset( (void *)*ppData, 0, dataSize );
2216
2217 return VOS_STATUS_SUCCESS;
2218}
2219
2220
2221/**--------------------------------------------------------------------------
2222
2223 \brief vos_pkt_reserve_head_fast() - Reserve space at the front of a voss Packet
2224
2225 This API will reserve space at the front of a voss Packet. The caller can
2226 then copy data into this reserved space using memcpy() like functions. This
2227 allows the caller to reserve space and build headers directly in this
2228 reserved space in the voss Packet.
2229
2230 Upon successful return, the length of the voss Packet is increased by
2231 dataSize.
2232
2233 Same as above APi but no memset to 0 at the end.
2234
2235 < put a before / after picture here>
2236
2237 \param pPacket - the voss Packet to modify.
2238
2239 \param ppData - pointer to the location where the pointer to the reserved
2240 space is returned. Upon successful return, the caller has
2241 write / read access to the data space at *ppData for length
2242 dataSize to build headers, etc.
2243
2244 \param dataSize - the size of the data to reserve at the head of the voss
2245 Packet. Upon successful return, the length of the voss
2246 Packet is increased by dataSize.
2247
2248 \return
2249
2250 \sa
2251
2252 ---------------------------------------------------------------------------*/
2253VOS_STATUS vos_pkt_reserve_head_fast( vos_pkt_t *pPacket,
2254 v_VOID_t **ppData,
2255 v_SIZE_t dataSize )
2256{
2257 struct sk_buff *skb;
2258 struct sk_buff *newskb;
2259
2260 // get pointer to the skb
2261 skb = pPacket->pSkb;
2262
2263 // Validate the skb
2264 if (unlikely(NULL == skb))
2265 {
2266 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2267 "VPKT [%d]: NULL skb", __LINE__);
2268 return VOS_STATUS_E_INVAL;
2269 }
2270
2271 // Make sure there is headroom. As a performance optimization we
2272 // can omit this check later since skb_push() will also perform the
2273 // check (except skb_push() will panic the kernel)
2274 if (unlikely(skb_headroom(skb) < dataSize))
2275 {
2276 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2277 "VPKT [%d]: Insufficient headroom, "
2278 "head[%p], data[%p], req[%d]",
2279 __LINE__, skb->head, skb->data, dataSize);
2280
2281 if ((newskb = skb_realloc_headroom(skb, dataSize)) == NULL) {
2282 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2283 "VPKT [%d]: Failed to realloc headroom", __LINE__);
2284 return VOS_STATUS_E_INVAL;
2285 }
2286
2287 kfree_skb(skb);
2288 skb = newskb;
2289
2290 // set the skb pointer
2291 pPacket->pSkb = newskb;
2292 }
2293
2294 // actually allocate the headroom
2295 *ppData = skb_push(skb, dataSize);
2296 // Zero out so we dont take the fastpath on Android.
2297 //memset( (void *)*ppData, 0, dataSize );
2298
2299 return VOS_STATUS_SUCCESS;
2300}
2301
2302/**--------------------------------------------------------------------------
2303
2304 \brief vos_pkt_pop_head() - Remove data from the front of the voss Packet
2305
2306 This API removes data from the front of a voss Packet. The data is
2307 copied into the output buffer described by pData and pDataSize
2308
2309 \param pPacket - the voss Packet to operate on.
2310
2311 \param pData - pointer to the data buffer where the data removed from the
2312 voss Packet is placed.
2313
2314 \param dataSize - The amount of space to remove from the head of the voss
2315 Packet. The output buffer (at *pData) must contain at
2316 least this amount of space.
2317
2318 \return
2319
2320 \sa
2321
2322 ---------------------------------------------------------------------------*/
2323VOS_STATUS vos_pkt_pop_head( vos_pkt_t *pPacket,
2324 v_VOID_t *pData,
2325 v_SIZE_t dataSize )
2326{
2327 struct sk_buff *skb;
2328
2329 // Validate the parameter pointers
2330 if (unlikely((NULL == pPacket) || (NULL == pData)))
2331 {
2332 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2333 "VPKT [%d]: NULL pointer", __LINE__);
2334 return VOS_STATUS_E_INVAL;
2335 }
2336
2337 // Validate that this is really an initialized vos packet
2338 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2339 {
2340 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2341 "VPKT [%d]: Invalid magic", __LINE__);
2342 return VOS_STATUS_E_INVAL;
2343 }
2344
2345 // get pointer to the skb
2346 skb = pPacket->pSkb;
2347
2348 // Validate the skb
2349 if (unlikely(NULL == skb))
2350 {
2351 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2352 "VPKT [%d]: NULL skb", __LINE__);
2353 return VOS_STATUS_E_INVAL;
2354 }
2355
2356 // Make sure there is enough data to pop
2357 if (unlikely(skb->len < dataSize))
2358 {
2359 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2360 "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]",
2361 __LINE__, skb->len, dataSize);
2362 return VOS_STATUS_E_INVAL;
2363 }
2364
2365 // copy the data
2366 memcpy(pData, skb->data, dataSize);
2367 skb_pull(skb, dataSize);
2368
2369 return VOS_STATUS_SUCCESS;
2370}
2371
2372
2373/**--------------------------------------------------------------------------
2374
2375 \brief vos_pkt_trim_head() - Skip over bytes at the front of a voss Packet
2376
2377 This API moves the pointers at the head of a voss Packet to essentially
2378 skip over data at the front of a voss Packet. Upon successful return, the
2379 length of the voss Packet is reduced by dataSize and the starting pointer
2380 to the voss Packet is adjusted to eliminate the data from the start of the
2381 voss Packet.
2382
2383 This API has the opposite effect of \a vos_pkt_reserve_head().
2384
2385 \param pPacket - the voss Packet to operate on.
2386
2387 \param dataSize - The amount of space to skip at the start of the voss
2388 Packet.
2389
2390 Note that upon return, the data skipped over is
2391 inaccessible to the caller. If the caller needs access
2392 to the head data, use vos_pkt_pop_head() or
2393 vos_pkt_extract_data() to get a copy of the data.
2394
2395 \return
2396
2397 \sa
2398
2399 ---------------------------------------------------------------------------*/
2400VOS_STATUS vos_pkt_trim_head( vos_pkt_t *pPacket,
2401 v_SIZE_t dataSize )
2402{
2403 struct sk_buff *skb;
2404
2405 // Validate the parameter pointers
2406 if (unlikely(NULL == pPacket))
2407 {
2408 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2409 "VPKT [%d]: NULL pointer", __LINE__);
2410 return VOS_STATUS_E_INVAL;
2411 }
2412
2413 // Validate that this is really an initialized vos packet
2414 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2415 {
2416 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2417 "VPKT [%d]: Invalid magic", __LINE__);
2418 return VOS_STATUS_E_INVAL;
2419 }
2420
2421 // get pointer to the skb
2422 skb = pPacket->pSkb;
2423
2424 // Validate the skb
2425 if (unlikely(NULL == skb))
2426 {
2427 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2428 "VPKT [%d]: NULL skb", __LINE__);
2429 return VOS_STATUS_E_INVAL;
2430 }
2431
2432 // Make sure there is enough data to trim
2433 if (unlikely(skb->len < dataSize))
2434 {
2435 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2436 "VPKT [%d]: trim exceeds packet size, len[%d], req[%d]",
2437 __LINE__, skb->len, dataSize);
2438 return VOS_STATUS_E_INVAL;
2439 }
2440
2441 // adjust the skb
2442 skb_pull(skb, dataSize);
2443
2444 return VOS_STATUS_SUCCESS;
2445}
2446
2447/**--------------------------------------------------------------------------
2448
2449 \brief vos_pkt_push_tail() - push data on the end a of a voss Packet
2450
2451 This API will push data onto the end of a voss Packet. The data will be
2452 appended to the end of any data already contained in the voss Packet.
2453
2454 \param pPacket - the voss Packet to modify.
2455
2456 \param pData - pointer to the data to push onto the tail of the voss Packet.
2457
2458 \param dataSize - the size of the data to put onto the tail of the voss Packet.
2459
2460 \return
2461
2462 \sa
2463
2464 ---------------------------------------------------------------------------*/
2465VOS_STATUS vos_pkt_push_tail( vos_pkt_t *pPacket,
2466 v_VOID_t *pData,
2467 v_SIZE_t dataSize )
2468{
2469 struct sk_buff *skb;
2470
2471 // Validate the parameter pointers
2472 if (unlikely((NULL == pPacket) || (NULL == pData)))
2473 {
2474 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2475 "VPKT [%d]: NULL pointer", __LINE__);
2476 return VOS_STATUS_E_INVAL;
2477 }
2478
2479 // Validate that this is really an initialized vos packet
2480 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2481 {
2482 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2483 "VPKT [%d]: Invalid magic", __LINE__);
2484 return VOS_STATUS_E_INVAL;
2485 }
2486
2487 // get pointer to the skb
2488 skb = pPacket->pSkb;
2489
2490 // Validate the skb
2491 if (unlikely(NULL == skb))
2492 {
2493 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2494 "VPKT [%d]: NULL skb", __LINE__);
2495 return VOS_STATUS_E_INVAL;
2496 }
2497
2498 // Make sure there is tailroom. As a performance optimization we
2499 // can omit this check later since skb_put() will also perform the
2500 // check (except skb_put() will panic the kernel)
2501 if (unlikely(skb_tailroom(skb) < dataSize))
2502 {
2503 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2504 "VPKT [%d]: Insufficient tailroom, "
2505 "tail[%p], end[%p], req[%d]",
2506 __LINE__, skb_tail_pointer(skb),
2507 skb_end_pointer(skb), dataSize);
2508 return VOS_STATUS_E_INVAL;
2509 }
2510
2511 // actually push the data
2512 memcpy(skb_put(skb, dataSize), pData, dataSize);
2513
2514 return VOS_STATUS_SUCCESS;
2515}
2516
2517
2518/**--------------------------------------------------------------------------
2519
2520 \brief vos_pkt_reserve_tail() - Reserve space at the end of a voss Packet
2521
2522 This API will reserve space at the end of a voss Packet. The caller can
2523 then copy data into this reserved space using memcpy() like functions. This
2524 allows the caller to reserve space and build headers directly in this
2525 reserved space in the voss Packet.
2526
2527 Upon successful return, the length of the voss Packet is increased by
2528 dataSize.
2529
2530 \param pPacket - the voss Packet to modify.
2531
2532 \param ppData - pointer to the location where the pointer to the reserved
2533 space is returned. Upon successful return, the caller has
2534 write / read access to the data space at *ppData for length
2535 dataSize to build headers, etc.
2536
2537 \param dataSize - the size of the data to reserve at the head of the voss
2538 Packet. Upon successful return, the length of the voss
2539 Packet is increased by dataSize.
2540
2541 \return
2542
2543 \sa
2544
2545 ---------------------------------------------------------------------------*/
2546VOS_STATUS vos_pkt_reserve_tail( vos_pkt_t *pPacket,
2547 v_VOID_t **ppData,
2548 v_SIZE_t dataSize )
2549{
2550 struct sk_buff *skb;
2551
2552 // Validate the parameter pointers
2553 if (unlikely((NULL == pPacket) || (NULL == ppData)))
2554 {
2555 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2556 "VPKT [%d]: NULL pointer", __LINE__);
2557 return VOS_STATUS_E_INVAL;
2558 }
2559
2560 // Validate that this is really an initialized vos packet
2561 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2562 {
2563 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2564 "VPKT [%d]: Invalid magic", __LINE__);
2565 return VOS_STATUS_E_INVAL;
2566 }
2567
2568 // get pointer to the skb
2569 skb = pPacket->pSkb;
2570
2571 // Validate the skb
2572 if (unlikely(NULL == skb))
2573 {
2574 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2575 "VPKT [%d]: NULL skb", __LINE__);
2576 return VOS_STATUS_E_INVAL;
2577 }
2578
2579 // Make sure there is tailroom. As a performance optimization we
2580 // can omit this check later since skb_put() will also perform the
2581 // check (except skb_put() will panic the kernel)
2582 if (unlikely(skb_tailroom(skb) < dataSize))
2583 {
2584 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2585 "VPKT [%d]: Insufficient tailroom, "
2586 "tail[%p], end[%p], req[%d]",
2587 __LINE__, skb_tail_pointer(skb),
2588 skb_end_pointer(skb), dataSize);
2589 return VOS_STATUS_E_INVAL;
2590 }
2591
2592 // actually allocate the space
2593 *ppData = skb_put(skb, dataSize);
2594
2595 return VOS_STATUS_SUCCESS;
2596}
2597
2598
2599
2600/**--------------------------------------------------------------------------
2601
2602 \brief vos_pkt_pop_tail() - Remove data from the end of the voss Packet
2603
2604 This API removes data from the end of a voss Packet. The data is
2605 copied into the output buffer described by pData and pDataSize
2606
2607 \param pPacket - the voss Packet to operate on.
2608
2609 \param pData - pointer to the data buffer where the data removed from the
2610 voss Packet is placed.
2611
2612 \param dataSize - The amount of space to remove from the end of the voss
2613 Packet. The output buffer (at *pData) must contain at
2614 least this amount of space.
2615
2616 \return
2617
2618 \sa
2619
2620 ---------------------------------------------------------------------------*/
2621VOS_STATUS vos_pkt_pop_tail( vos_pkt_t *pPacket,
2622 v_VOID_t *pData,
2623 v_SIZE_t dataSize )
2624{
2625 struct sk_buff *skb;
2626
2627 // Validate the parameter pointers
2628 if (unlikely((NULL == pPacket) || (NULL == pData)))
2629 {
2630 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2631 "VPKT [%d]: NULL pointer", __LINE__);
2632 return VOS_STATUS_E_INVAL;
2633 }
2634
2635 // Validate that this is really an initialized vos packet
2636 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2637 {
2638 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2639 "VPKT [%d]: Invalid magic", __LINE__);
2640 return VOS_STATUS_E_INVAL;
2641 }
2642
2643 // get pointer to the skb
2644 skb = pPacket->pSkb;
2645
2646 // Validate the skb
2647 if (unlikely(NULL == skb))
2648 {
2649 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2650 "VPKT [%d]: NULL skb", __LINE__);
2651 return VOS_STATUS_E_INVAL;
2652 }
2653
2654 // Make sure there is enough data to pop
2655 if (unlikely(skb->len < dataSize))
2656 {
2657 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2658 "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]",
2659 __LINE__, skb->len, dataSize);
2660 return VOS_STATUS_E_INVAL;
2661 }
2662
2663 // adjust pointers (there isn't a native Linux API for this)
2664 skb->tail -= dataSize;
2665 skb->len -= dataSize;
2666
2667 // actually push the data
2668 memcpy(pData, skb_tail_pointer(skb), dataSize);
2669
2670 return VOS_STATUS_SUCCESS;
2671}
2672
2673/**--------------------------------------------------------------------------
2674
2675 \brief vos_pkt_trim_tail() - Skip over bytes at the end of a voss Packet
2676
2677 This API moves the pointers at the head of a voss Packet to essentially
2678 skip over data at the end of a voss Packet. Upon successful return, the
2679 length of the voss Packet is reduced by dataSize and voss Packet is
2680 adjusted to eliminate the data from the end of the voss Packet.
2681
2682 This API has the opposite effect of \a vos_pkt_reserve_tail().
2683
2684 \param pPacket - the voss Packet to operate on.
2685
2686 \param dataSize - The amount of space to remove at the end of the voss
2687 Packet.
2688
2689 Note that upon return, the data skipped over is
2690 inaccessible to the caller. If the caller needs access
2691 to the tail data, use vos_pkt_pop_tail() or
2692 vos_pkt_extract_data() to get a copy of the data.
2693
2694 \return
2695
2696 \sa
2697
2698 ---------------------------------------------------------------------------*/
2699VOS_STATUS vos_pkt_trim_tail( vos_pkt_t *pPacket,
2700 v_SIZE_t dataSize )
2701{
2702 struct sk_buff *skb;
2703
2704 // Validate the parameter pointers
2705 if (unlikely(NULL == pPacket))
2706 {
2707 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2708 "VPKT [%d]: NULL pointer", __LINE__);
2709 return VOS_STATUS_E_INVAL;
2710 }
2711
2712 // Validate that this is really an initialized vos packet
2713 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2714 {
2715 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2716 "VPKT [%d]: Invalid magic", __LINE__);
2717 return VOS_STATUS_E_INVAL;
2718 }
2719
2720 // get pointer to the skb
2721 skb = pPacket->pSkb;
2722
2723 // Validate the skb
2724 if (unlikely(NULL == skb))
2725 {
2726 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2727 "VPKT [%d]: NULL skb", __LINE__);
2728 return VOS_STATUS_E_INVAL;
2729 }
2730
2731 // Make sure there is enough data to pop
2732 if (unlikely(skb->len < dataSize))
2733 {
2734 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2735 "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]",
2736 __LINE__, skb->len, dataSize);
2737 return VOS_STATUS_E_INVAL;
2738 }
2739
2740 // adjust pointers (there isn't a native Linux API for this)
2741 skb->tail -= dataSize;
2742 skb->len -= dataSize;
2743
2744 return VOS_STATUS_SUCCESS;
2745}
2746
2747
2748/**--------------------------------------------------------------------------
2749
2750 \brief vos_pkt_get_timestamp() - Retrive the timestamp attribute from the
2751 specified VOSS packet
2752
2753 \param pPacket - the voss Packet to operate on.
2754
2755 \param pTstamp - the timestamp will be returned here.
2756
2757 \return VOS_STATUS_E_FAULT - invalid parameter(s) specified
2758
2759 VOS_STATUS_SUCCESS - timestamp retrived successfully
2760
2761 \sa
2762
2763 ---------------------------------------------------------------------------*/
2764VOS_STATUS vos_pkt_get_timestamp( vos_pkt_t *pPacket,
2765 v_TIME_t* pTstamp )
2766{
2767 // Validate the parameter pointers
2768 if (unlikely((NULL == pPacket) ||
2769 (NULL == pTstamp)))
2770 {
2771 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2772 "VPKT [%d]: NULL pointer", __LINE__);
2773 return VOS_STATUS_E_INVAL;
2774 }
2775
2776 // Validate that this is really an initialized vos packet
2777 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2778 {
2779 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2780 "VPKT [%d]: Invalid magic", __LINE__);
2781 return VOS_STATUS_E_INVAL;
2782 }
2783
2784 // return the requested information
2785 *pTstamp = pPacket->timestamp;
2786 return VOS_STATUS_SUCCESS;
2787}
2788
2789
2790/**--------------------------------------------------------------------------
2791
2792 \brief vos_pkt_flatten_rx_pkt() - Transform a platform based RX VOSS
2793 packet into a flat buffer based VOSS packet if needed. This is needed in
2794 cases where for reasons of efficiency we want the RX packets to be very
2795 platform specific (for e.g. DSM based on AMSS, etc). However platform
2796 independent code may rely on making calls on the VOSS packet which can only
2797 be supported by the flat buffer based implementation of a RX packet. This API
2798 will allocate a new VOSS packet with flat buffer, extract the data from the
2799 input VOSS packet and then release the input VOSS packet. The new VOSS packet
2800 will be returned from this call.
2801
2802 \param ppPacket - the voss Packet to operate on. On input contains
2803 the platform based packet. On output contains the flat
2804 buffer based packet. Any applicable resources
2805 are freed as part of this call.
2806
2807 \return VOS_STATUS_E_FAULT - invalid parameter specified
2808
2809 VOS_STATUS_E_INVAL - packet type not RX_RAW
2810
2811 VOS_STATUS_SUCCESS - transform successful
2812
2813 other VOSS status - other errors encountered
2814
2815 \sa
2816
2817 ----------------------------------------------------------------------------*/
2818VOS_STATUS vos_pkt_flatten_rx_pkt( vos_pkt_t **ppPacket )
2819{
2820 // Linux/Android skbs are already flat, no work required
2821 return VOS_STATUS_SUCCESS;
2822}
2823
2824/**--------------------------------------------------------------------------
2825
2826 \brief vos_pkt_set_rx_length() - Set the length of a received packet
2827
2828 This API set the length of the data inside the packet after a DMA has occurred
2829 on rx, it will also set the tail pointer to the end of the data.
2830
2831 \param pPacket - the voss Packet to operate on.
2832
2833 \param pktLen - The size of the data placed in the Rx packet during DMA.
2834
2835
2836 \return
2837
2838 \sa
2839
2840 ---------------------------------------------------------------------------*/
2841VOS_STATUS vos_pkt_set_rx_length( vos_pkt_t *pPacket,
2842 v_SIZE_t pktLen )
2843{
2844 struct sk_buff *skb;
2845
2846 // Validate the parameter pointers
2847 if (unlikely(NULL == pPacket))
2848 {
2849 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2850 "VPKT [%d]: NULL pointer", __LINE__);
2851 return VOS_STATUS_E_INVAL;
2852 }
2853
2854 // Validate that this is really an initialized vos packet
2855 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2856 {
2857 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2858 "VPKT [%d]: Invalid magic", __LINE__);
2859 return VOS_STATUS_E_INVAL;
2860 }
2861
2862 // get pointer to the skb
2863 skb = pPacket->pSkb;
2864
2865 // Validate the skb
2866 if (unlikely(NULL == skb))
2867 {
2868 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2869 "VPKT [%d]: NULL skb", __LINE__);
2870 return VOS_STATUS_E_INVAL;
2871 }
2872
2873 // adjust pointers (there isn't a native Linux API for this)
2874 // ?? - is this sufficient?
2875 skb_set_tail_pointer(skb, pktLen);
2876 skb->len = pktLen;
2877
2878 return VOS_STATUS_SUCCESS;
2879
2880}
2881/**--------------------------------------------------------------------------
2882
2883 \brief vos_pkt_get_available_buffer_pool() - Get avaliable VOS packet size
2884 VOSS Packet pool is limitted resource
2885 VOSS Client need to know how many packet pool is still avaliable to control
2886 the flow
2887
2888 \param pktType - Packet type want to know free buffer count
2889 VOS_PKT_TYPE_TX_802_11_MGMT, management free buffer count,
2890 VOS_PKT_TYPE_TX_802_11_DATA
2891 VOS_PKT_TYPE_TX_802_3_DATA, TX free buffer count
2892 VOS_PKT_TYPE_RX_RAW, RX free buffer count
2893
2894 vosFreeBuffer - free frame buffer size
2895
2896 \return VOS_STATUS_E_INVAL - invalid input parameter
2897
2898 VOS_STATUS_SUCCESS - Get size success
2899
2900 \sa
2901
2902 ----------------------------------------------------------------------------*/
2903VOS_STATUS vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE pktType,
2904 v_SIZE_t *vosFreeBuffer)
2905{
2906 struct list_head *pList;
2907 struct list_head *pNode;
2908 v_SIZE_t count;
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 if (NULL == vosFreeBuffer)
2910 {
2911 return VOS_STATUS_E_INVAL;
2912 }
2913
2914 switch (pktType)
2915 {
2916 case VOS_PKT_TYPE_TX_802_11_MGMT:
2917 pList = &gpVosPacketContext->txMgmtFreeList;
2918 break;
2919
2920 case VOS_PKT_TYPE_TX_802_11_DATA:
2921 case VOS_PKT_TYPE_TX_802_3_DATA:
Jeff Johnson295189b2012-06-20 16:38:30 -07002922 if (VOS_STA_SAP_MODE == hdd_get_conparam())
2923 {
2924 *vosFreeBuffer = gpVosPacketContext->uctxDataFreeListCount;
2925 return VOS_STATUS_SUCCESS;
2926 }
2927 else
Jeff Johnson295189b2012-06-20 16:38:30 -07002928 pList = &gpVosPacketContext->txDataFreeList;
2929 break;
2930
2931 case VOS_PKT_TYPE_RX_RAW:
2932 // if the caller is curious how many raw packets are available
2933 // then he probably wants as many packets to be available as
2934 // possible so replenish the raw pool
2935 vos_pkti_replenish_raw_pool();
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -08002936 // Return the pre-calculated count 'rxRawFreeListCount'
2937 *vosFreeBuffer = gpVosPacketContext->rxRawFreeListCount;
2938 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002939 break;
2940
2941 default:
2942 return (VOS_STATUS_E_INVAL);
2943 }
2944
2945 count = 0;
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -07002946 mutex_lock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002947 list_for_each(pNode, pList)
2948 {
2949 count++;
2950 }
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -07002951 mutex_unlock(&gpVosPacketContext->mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002952 *vosFreeBuffer = count;
2953 return VOS_STATUS_SUCCESS;
2954}
2955
Sameer Thalappild0158402013-05-03 13:19:03 -07002956/**
2957 @brief vos_pkt_get_num_of_rx_raw_pkts() - Get the number of RX packets
2958 that should be allocated.
2959
2960 This function is called by VOS packet module to know how many RX raw
2961 packets it should allocate/reserve. This value can be configured thru
2962 Kernel device tree to save memory usage.
2963
2964 @param
2965 NONE
2966 @return
2967 v_SIZE_t the number of packets to allocate
2968
2969*/
2970v_SIZE_t vos_pkt_get_num_of_rx_raw_pkts(void)
2971{
2972#ifdef HAVE_WCNSS_RX_BUFF_COUNT
2973 v_SIZE_t buffCount;
2974
2975 buffCount = wcnss_get_wlan_rx_buff_count();
2976 return (buffCount > VPKT_NUM_RX_RAW_PACKETS ?
2977 VPKT_NUM_RX_RAW_PACKETS : buffCount);
2978#else
2979 return VPKT_NUM_RX_RAW_PACKETS;
2980#endif
2981}
Jeff Johnson295189b2012-06-20 16:38:30 -07002982
2983#ifdef VOS_PACKET_UNIT_TEST
2984#include "vos_packet_test.c"
2985#endif