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