blob: 1765c804b7768a347633fb4aaa8f7f3d13abf2f6 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam1ed83fc2014-02-19 01:15:45 -08003 *
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
Jeff Johnson295189b2012-06-20 16:38:30 -070037 ========================================================================*/
38
39/* $Header$ */
40
41/*--------------------------------------------------------------------------
42 Include Files
43 ------------------------------------------------------------------------*/
44#include <vos_packet.h>
45#include <i_vos_packet.h>
46#include <vos_timer.h>
47#include <vos_trace.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070048#include <wlan_hdd_main.h>
Sameer Thalappild0158402013-05-03 13:19:03 -070049#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51/*--------------------------------------------------------------------------
52 Preprocessor definitions and constants
53 ------------------------------------------------------------------------*/
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -080054/* Protocol specific packet tracking feature */
55#define VOS_PKT_PROT_ETH_TYPE_OFFSET 12
56#define VOS_PKT_PROT_IP_OFFSET 14
57#define VOS_PKT_PROT_IP_HEADER_SIZE 20
58#define VOS_PKT_PROT_DHCP_SRV_PORT 67
59#define VOS_PKT_PROT_DHCP_CLI_PORT 68
60#define VOS_PKT_PROT_EAPOL_ETH_TYPE 0x888E
Mihir Shete39f7c752015-06-11 15:40:09 +053061#define VOS_PKT_PROT_ARP_ETH_TYPE 0x0806
Bhargav Shah7dbfb6f2016-02-12 20:49:58 +053062#define VOS_PKT_GET_HEAD(skb) (skb->head)
63#define VOS_PKT_GET_END(skb) (skb->end)
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 {
Mihir Shete058fcff2014-06-26 18:54:06 +0530212 gpVosPacketContext->rxReplenishFailCount++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700213 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,
Jeff Johnson1b067b52017-09-19 08:33:10 -0700233 "VPKT [%d]: [%pK] Packet replenished",
Jeff Johnson295189b2012-06-20 16:38:30 -0700234 __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,
Jeff Johnson1b067b52017-09-19 08:33:10 -0700259 "VPKT [%d]: [%pK] Packet replenish callback",
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 __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,
Jeff Johnson1b067b52017-09-19 08:33:10 -0700778 "VPKT [%d]: [%pK] Packet allocated, type %d[%s]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700779 __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,
Jeff Johnson1b067b52017-09-19 08:33:10 -0700962 "VPKT [%d]: [%pK] Packet allocated, type %s",
Jeff Johnson295189b2012-06-20 16:38:30 -0700963 __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;
Mihir Sheteaf278b32014-05-08 13:02:05 +05301297 v_BOOL_t lowResource;
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
Mihir Sheteaf278b32014-05-08 13:02:05 +05301313 lowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 // Validate that this really an initialized vos packet
1315 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1316 {
1317 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1318 "VPKT [%d]: Invalid magic", __LINE__);
1319 return VOS_STATUS_E_INVAL;
1320 }
Madan Mohan Koyyalamudi700913e2012-09-24 13:50:50 -07001321
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 //If an skb is attached then reset the pointers
1323 if (pPacket->pSkb)
1324 {
1325 pPacket->pSkb->len = 0;
1326 pPacket->pSkb->data = pPacket->pSkb->head;
1327 skb_reset_tail_pointer(pPacket->pSkb);
1328 skb_reserve(pPacket->pSkb, VPKT_SIZE_BUFFER);
1329 }
1330
1331 pCount = NULL;
1332 // determine which packet pool and low resource block we should use.
1333 switch (pPacket->packetType)
1334 {
1335 case VOS_PKT_TYPE_RX_RAW:
1336 // if this packet still has an skb attached, we can put it
1337 // back in the free pool, otherwise we need to put it in the
1338 // replenish pool
1339 if (pPacket->pSkb)
1340 {
1341 pPktFreeList = &gpVosPacketContext->rxRawFreeList;
1342 pLowResourceInfo = &gpVosPacketContext->rxRawLowResourceInfo;
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -08001343 pCount = &gpVosPacketContext->rxRawFreeListCount;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301344 mlock = &gpVosPacketContext->rxRawFreeListLock;
Jeff Johnson295189b2012-06-20 16:38:30 -07001345 }
1346 else
1347 {
1348 pPktFreeList = &gpVosPacketContext->rxReplenishList;
1349 pLowResourceInfo = NULL;
1350 pCount = &gpVosPacketContext->rxReplenishListCount;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301351 mlock = &gpVosPacketContext->rxReplenishListLock;
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 }
1353 packetType = VOS_PKT_TYPE_RX_RAW;
1354 break;
1355
1356 case VOS_PKT_TYPE_TX_802_11_MGMT:
1357
1358 pPktFreeList = &gpVosPacketContext->txMgmtFreeList;
1359 pLowResourceInfo = &gpVosPacketContext->txMgmtLowResourceInfo;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301360 mlock = &gpVosPacketContext->txMgmtFreeListLock;
1361
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 break;
1363
1364 case VOS_PKT_TYPE_TX_802_3_DATA:
1365 pPktFreeList = &gpVosPacketContext->txDataFreeList;
1366 pLowResourceInfo = &gpVosPacketContext->txDataLowResourceInfo;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301367 mlock = &gpVosPacketContext->txDataFreeListLock;
Jeff Johnson295189b2012-06-20 16:38:30 -07001368 gpVosPacketContext->uctxDataFreeListCount ++;
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 break;
1370
1371 default:
1372 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1373 "VPKT [%d]: invalid packet type %d[%s]",
1374 __LINE__, pPacket->packetType,
1375 vos_pkti_packet_type_str(pPacket->packetType));
1376
1377 return VOS_STATUS_E_INVAL;
1378 }
1379
1380
1381 // is there a low resource condition pending for this packet type?
1382 if (pLowResourceInfo && pLowResourceInfo->callback)
1383 {
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001384 // pLowResourceInfo->callback is modified from threads (different CPU's).
1385 // So a mutex is enough to protect is against a race condition.
1386 // mutex is SMP safe
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301387 mutex_lock(mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 callback = pLowResourceInfo->callback;
1389 pLowResourceInfo->callback = NULL;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301390 mutex_unlock(mlock);
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001391
1392 // only one context can get a valid callback
1393 if(callback)
1394 {
1395 // [DEBUG]
Jeff Johnson1b067b52017-09-19 08:33:10 -07001396 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"VPKT [%d]: recycle %pK", __LINE__, pPacket);
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001397
1398 // yes, so rather than placing the packet back in the free pool
1399 // we will invoke the low resource callback
1400 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1b067b52017-09-19 08:33:10 -07001401 "VPKT [%d]: [%pK] Packet recycled, type %d[%s]",
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001402 __LINE__, pPacket, pPacket->packetType,
1403 vos_pkti_packet_type_str(pPacket->packetType));
1404
1405 // clear out the User Data pointers in the voss packet..
1406 memset(&pPacket->pvUserData, 0, sizeof(pPacket->pvUserData));
1407
1408 // initialize the 'chain' pointer to NULL.
1409 pPacket->pNext = NULL;
1410
1411 // timestamp the vos packet.
1412 pPacket->timestamp = vos_timer_get_system_ticks();
1413
1414 callback(pPacket, pLowResourceInfo->userData);
1415
1416 // We did process low resource condition
1417 lowResource = VOS_TRUE;
1418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001419 }
Madan Mohan Koyyalamudi87209592012-11-19 20:30:29 -08001420
1421
1422 if(!lowResource)
Jeff Johnson295189b2012-06-20 16:38:30 -07001423 {
1424 // this packet does not satisfy a low resource condition
1425 // so put it back in the appropriate free pool
1426 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1b067b52017-09-19 08:33:10 -07001427 "VPKT [%d]: [%pK] Packet returned, type %d[%s]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 __LINE__, pPacket, pPacket->packetType,
1429 vos_pkti_packet_type_str(pPacket->packetType));
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301430 mutex_lock(mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 list_add_tail(&pPacket->node, pPktFreeList);
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301432
Jeff Johnson295189b2012-06-20 16:38:30 -07001433 if (pCount)
1434 {
1435 (*pCount)++;
1436 }
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05301437 mutex_unlock(mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 }
1439
1440 // move to next packet in the chain
1441 pPacket = pNext;
1442
1443 } // while (pPacket)
1444
1445 // see if we need to replenish the Rx Raw pool
1446 if (VOS_PKT_TYPE_RX_RAW == packetType)
1447 {
1448 vos_pkti_replenish_raw_pool();
1449 }
1450 return VOS_STATUS_SUCCESS;
1451}
1452
1453/**--------------------------------------------------------------------------
1454
1455 \brief vos_pkt_chain_packet() - chain a voss Packet to another packet
1456
1457 This API chains a voss Packet to another voss Packet, creating a packet
1458 chain. Packets can be chained before or after the current packet in the
1459 packet chain.
1460
1461 \param pPacket - pointer to a voss packet to chain to
1462
1463 \param pChainPacket - pointer to packet to chain
1464
1465 \param chainAfter - boolean to specify to chain packet after or before
1466 the input packet
1467 <ul>
1468 <li> true - chain packet AFTER pPacket (chain behind)
1469 <li> false - chain packet BEFORE pPacket (chain in front)
1470 </ul>
1471
1472 \return
1473
1474 \sa
1475
1476 ---------------------------------------------------------------------------*/
1477VOS_STATUS vos_pkt_chain_packet( vos_pkt_t *pPacket,
1478 vos_pkt_t *pChainPacket,
1479 v_BOOL_t chainAfter )
1480{
1481 // Validate the parameter pointers
1482 if (unlikely((NULL == pPacket) || (NULL == pChainPacket)))
1483 {
1484 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1485 "VPKT [%d]: NULL pointer", __LINE__);
1486 return VOS_STATUS_E_INVAL;
1487 }
1488
1489 // Validate that these are really initialized vos packets
1490 if (unlikely((VPKT_MAGIC_NUMBER != pPacket->magic) ||
1491 (VPKT_MAGIC_NUMBER != pChainPacket->magic)))
1492 {
1493 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1494 "VPKT [%d]: Invalid magic", __LINE__);
1495 return VOS_STATUS_E_INVAL;
1496 }
1497
1498 // swap pointers if we chain before
1499 if (unlikely(VOS_FALSE == chainAfter))
1500 {
1501 vos_pkt_t *pTmp = pPacket;
1502 pPacket = pChainPacket;
1503 pChainPacket = pTmp;
1504 }
1505
1506 // find the end of the chain
1507 while (pPacket->pNext)
1508 {
1509 pPacket = pPacket->pNext;
1510 }
1511
1512 // attach
1513 pPacket->pNext = pChainPacket;
1514
1515 return VOS_STATUS_SUCCESS;
1516}
1517
1518
1519/**--------------------------------------------------------------------------
1520
1521 \brief vos_pkt_walk_packet_chain() - Walk packet chain and (possibly)
1522 unchain packets
1523
1524 This API will walk the voss Packet and unchain the packet from the chain,
1525 if specified. The 'next' packet in the packet chain is returned as the
1526 packet chain is traversed.
1527
1528 \param pPacket - input vos_packet walk
1529
1530 \param ppChainedPacket - pointer to location to return the 'next' voss
1531 packet pointer in the packet chain.
1532 NULL means there is was not packet chained
1533 to this packet.
1534
1535 \param unchainPacket - Flag that specifies if the caller wants the packet
1536 to be removed from the packet chain. This is
1537 provided to allow the caller to walk the packet chain
1538 with or without breaking the chain.
1539
1540 <ul>
1541 <li> true - when set 'true' the API will return
1542 the 'next' packet pointer in the voss Packte chain and
1543 *WILL* unchain the input packet from the packet chain.
1544
1545 <li> NOT false - when set 'false' the API will return
1546 the 'next' packet pointer in the voss Packet chain but
1547 *WILL NOT* unchain the packet chain. This option gives
1548 the caller the ability to walk the packet chain without
1549 modifying it in the process.
1550 </ul>
1551
1552 \note Having the packets chained has an implicaiton on how the return
1553 packet API (vos_pkt_return_packet() ) operates.
1554
1555 \return
1556
1557 \sa
1558
1559 ---------------------------------------------------------------------------*/
1560VOS_STATUS vos_pkt_walk_packet_chain( vos_pkt_t *pPacket,
1561 vos_pkt_t **ppChainedPacket,
1562 v_BOOL_t unchainPacket )
1563{
1564 // Validate the parameter pointers
1565 if (unlikely((NULL == pPacket) || (NULL == ppChainedPacket)))
1566 {
1567 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1568 "VPKT [%d]: NULL pointer", __LINE__);
1569 return VOS_STATUS_E_INVAL;
1570 }
1571
1572 // Validate that this is really an initialized vos packet
1573 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1574 {
1575 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1576 "VPKT [%d]: Invalid magic", __LINE__);
1577 return VOS_STATUS_E_INVAL;
1578 }
1579
1580 // get next packet
1581 *ppChainedPacket = pPacket->pNext;
1582
1583 // if asked to unchain, then unchain it
1584 if (VOS_FALSE != unchainPacket)
1585 {
1586 pPacket->pNext = NULL;
1587 }
1588
1589 // if end of the chain, indicate empty to the caller
1590 if (*ppChainedPacket)
1591 {
1592 return VOS_STATUS_SUCCESS;
1593 }
1594 else
1595 {
1596 return VOS_STATUS_E_EMPTY;
1597 }
1598}
1599
Sravan Kumar Kairam04f093a2017-11-16 19:59:05 +05301600
1601bool vos_is_pkt_chain(vos_pkt_t *pPacket)
1602{
1603 if (pPacket->pNext != NULL)
1604 return true;
1605 else
1606 return false;
1607}
1608
Jeff Johnson295189b2012-06-20 16:38:30 -07001609/**--------------------------------------------------------------------------
1610
1611 \brief vos_pkt_get_data_vector() - Get data vectors from a voss Packet
1612
1613 This API gets the complete set of Vectors (pointer / length pairs) that
1614 describe all of the data that makes up the voss Packet.
1615
1616 \param pPacket - pointer to the vOSS Packet to get the pointer/length
1617 vector from
1618
1619 \param pVector - pointer to the vector array where the vectors are returned.
1620
1621 \param pNumVectors - Number of vector's in the vector array (at pVector).
1622 On successful return, *pNumVectors is updated with the
1623 number of pointer/length vectors at pVector populated
1624 with valid vectors.
1625
1626 Call with NULL pVector or 0 vectorSize, will return the size of vector
1627 needed (in *pNumVectors)
1628
1629 Caller allocates and frees the vector memory.
1630
1631 \return
1632
1633 \sa
1634
1635 ---------------------------------------------------------------------------*/
1636VOS_STATUS vos_pkt_get_data_vector( vos_pkt_t *pPacket,
1637 vos_pkt_data_vector_t *pVector,
1638 v_SIZE_t *pNumVectors )
1639{
1640 // not supported
1641
1642 VOS_ASSERT(0);
1643 return VOS_STATUS_E_FAILURE;
1644}
1645
1646
1647/**--------------------------------------------------------------------------
1648
1649 \brief vos_pkt_extract_data() - Extract data from the voss Packet.
1650
1651 This API extracts data from a voss Packet, copying the data into the
1652 supplied output buffer. Note the data is copied from the vos packet
1653 but the data remains in the vos packet and the size is unaffected.
1654
1655 \param pPacket - the voss Packet to get the data from.
1656
1657 \param pktOffset - the offset from the start of the voss Packet to get the
1658 data. (i.e. 0 would be the beginning of the voss Packet).
1659
1660 \param pOutputBuffer - Pointer to the location where the voss Packet data
1661 will be copied.
1662
1663 \param pOutputBufferSize - on input, contains the amount of data to extract
1664 into the output buffer. Upon return, contains the amount of data
1665 extracted into the output buffer.
1666
1667 Note: an input of 0 in *pOutputBufferSize, means to copy *all*
1668 data in the voss Packet into the output buffer. The caller is
1669 responsible for assuring the output buffer size is big enough
1670 since the size of the buffer is not being passed in!
1671
1672 \return
1673
1674 \sa
1675
1676 ---------------------------------------------------------------------------*/
1677VOS_STATUS vos_pkt_extract_data( vos_pkt_t *pPacket,
1678 v_SIZE_t pktOffset,
1679 v_VOID_t *pOutputBuffer,
1680 v_SIZE_t *pOutputBufferSize )
1681{
1682 v_SIZE_t len;
1683 struct sk_buff *skb;
1684
1685 // Validate the parameter pointers
1686 if (unlikely((NULL == pPacket) ||
1687 (NULL == pOutputBuffer) ||
1688 (NULL == pOutputBufferSize)))
1689 {
1690 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1691 "VPKT [%d]: NULL pointer", __LINE__);
1692 return VOS_STATUS_E_INVAL;
1693 }
1694
1695 // Validate that this is really an initialized vos packet
1696 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1697 {
1698 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1699 "VPKT [%d]: Invalid magic", __LINE__);
1700 return VOS_STATUS_E_INVAL;
1701 }
1702
1703 // get pointer to the skb
1704 skb = pPacket->pSkb;
1705
1706 // Validate the skb
1707 if (unlikely(NULL == skb))
1708 {
1709 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1710 "VPKT [%d]: NULL skb", __LINE__);
1711 return VOS_STATUS_E_INVAL;
1712 }
1713
1714 // get number of bytes requested
1715 len = *pOutputBufferSize;
1716
1717 // if 0 is input in the *pOutputBufferSize, then the user wants us to
1718 // extract *all* the data in the buffer. Otherwise, the user has
1719 // specified the output buffer size in *pOutputBufferSize. In the
1720 // case where the output buffer size is specified, let's validate that
1721 // it is big enough.
1722 //
1723 // \note: i'm not crazy about this. we should enforce the output
1724 // buffer size on input so this API is not going to cause crashes
1725 // because buffers are too small and the caller inputs 0 == don't care
1726 // to check the size... !!
1727 if (0 == len)
1728 {
1729 len = skb->len - pktOffset;
1730
1731 // return # of bytes copied
1732 *pOutputBufferSize = len;
1733 }
1734 else
1735 {
1736 // make sure we aren't extracting past the end of the packet
1737 if (len > (skb->len - pktOffset))
1738 {
1739 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1740 "VPKT [%d]: Request overrun, "
1741 "req offset %d, req size %d, packet size %d",
1742 __LINE__, pktOffset, len, skb->len);
1743 return VOS_STATUS_E_INVAL;
1744 }
1745 }
1746
1747 // copy the data
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301748 vos_mem_copy(pOutputBuffer, &skb->data[pktOffset], len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001749
1750 return VOS_STATUS_SUCCESS;
1751}
1752
1753/**--------------------------------------------------------------------------
1754
1755 \brief vos_pkt_extract_data_chain() - Extract data from a voss Packet chain.
1756
1757 This API extracts *all* the data from a voss Packet chain, copying the
1758 data into the supplied output buffer. Note the data is copied from
1759 the vos packet chain but the data remains in the vos packet and the
1760 size of the vos packets are unaffected.
1761
1762 \param pPacket - the first voss Packet in the voss packet chain to
1763 extract data.
1764
1765 \param pOutputBuffer - Pointer to the location where the voss Packet data
1766 will be copied.
1767
1768 \param pOutputBufferSize - on input, contains the maximum amount of data
1769 that can be extracted into the output buffer. Upon return, contains
1770 the amount of data extracted from the packet chain.
1771
1772 \return VOS_STATUS_SUCCESS - the data from the entire packet chain is
1773 extracted and found at *pOutputBuffer. *pOutputBufferSize bytes
1774 were extracted.
1775
1776 VOS_STATUS_E_FAULT - pPacket, pOutputBuffer, or pOutputBufferSize
1777 is not a valid pointer.
1778
1779 VOS_STATUS_E_NOMEM - there is not enough room to extract the data
1780 from the entire packet chain. *pOutputBufferSize has been updated
1781 with the size needed to extract the entier packet chain.
1782
1783 \sa vos_pkt_extract_data()
1784
1785 ---------------------------------------------------------------------------*/
1786VOS_STATUS vos_pkt_extract_data_chain( vos_pkt_t *pPacket,
1787 v_VOID_t *pOutputBuffer,
1788 v_SIZE_t *pOutputBufferSize )
1789{
1790 VOS_STATUS vosStatus;
1791 v_SIZE_t len;
1792 struct sk_buff *skb;
1793
1794 // Validate the parameter pointers
1795 if (unlikely((NULL == pPacket) ||
1796 (NULL == pOutputBuffer) ||
1797 (NULL == pOutputBufferSize)))
1798 {
1799 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1800 "VPKT [%d]: NULL pointer", __LINE__);
1801 return VOS_STATUS_E_INVAL;
1802 }
1803
1804 // Validate that this is really an initialized vos packet
1805 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1808 "VPKT [%d]: Invalid magic", __LINE__);
1809 return VOS_STATUS_E_INVAL;
1810 }
1811
1812 // get the length of the entire packet chain.
1813 vosStatus = vos_pkt_get_packet_chain_length(pPacket, &len);
1814 if (unlikely(VOS_STATUS_SUCCESS != vosStatus))
1815 {
1816 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1817 "VPKT [%d]: Unable to get packet chain length", __LINE__);
1818 return VOS_STATUS_E_FAILURE;
1819 }
1820
1821 // if the output buffer size is too small, return NOMEM and update
1822 // the actual size needed in *pOutputBufferSize
1823 if (len > *pOutputBufferSize)
1824 {
1825 *pOutputBufferSize = len;
1826 return VOS_STATUS_E_NOMEM;
1827 }
1828
1829 // walk through each packet in the chain, copying the data
1830 while (pPacket)
1831 {
1832 // get pointer to the skb
1833 skb = pPacket->pSkb;
1834
1835 // Validate the skb
1836 if (unlikely(NULL == skb))
1837 {
1838 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1839 "VPKT [%d]: NULL skb", __LINE__);
1840 return VOS_STATUS_E_INVAL;
1841 }
1842
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05301843 vos_mem_copy(pOutputBuffer, skb->data, skb->len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 pOutputBuffer += skb->len;
1845
1846 pPacket = pPacket->pNext;
1847 }
1848
1849 return VOS_STATUS_SUCCESS;
1850}
1851
1852/**--------------------------------------------------------------------------
1853
1854 \brief vos_pkt_peek_data() - peek into voss Packet at given offset
1855
1856 This API provides a pointer to a specified offset into a voss Packet,
1857 allowing the caller to peek at a given number of bytes in the voss Packet.
1858 Upon successful return, the caller can access "numBytes" of data at
1859 "pPacketData".
1860
1861 This API will fail if the data length requested to peek at is not in
1862 contiguous memory in the voss Packet. In this case, the caller should
1863 use vos_pkt_extract_data() to have the data copied into a caller supplied
1864 buffer.
1865
1866 \param pPacket - the vOSS Packet to peek into
1867
1868 \param pktOffset - the offset into the voss Packet data to peek into.
1869
1870 \param ppPacketData - pointer to the location where the pointer to the
1871 packet data at pktOffset will be returned.
1872
1873 \param numBytes - the number of bytes the caller wishes to peek at.
1874
1875 \return
1876
1877 \sa
1878
1879 ---------------------------------------------------------------------------*/
1880VOS_STATUS vos_pkt_peek_data( vos_pkt_t *pPacket,
1881 v_SIZE_t pktOffset,
1882 v_VOID_t **ppPacketData,
1883 v_SIZE_t numBytes )
1884{
1885 struct sk_buff *skb;
1886
1887 // Validate the parameter pointers
1888 if (unlikely((NULL == pPacket) ||
1889 (NULL == ppPacketData)))
1890 {
1891 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1892 "VPKT [%d]: NULL pointer", __LINE__);
1893 return VOS_STATUS_E_INVAL;
1894 }
1895
1896 // Validate that this is really an initialized vos packet
1897 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1898 {
1899 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1900 "VPKT [%d]: Invalid magic", __LINE__);
1901 return VOS_STATUS_E_INVAL;
1902 }
1903
1904 // Validate numBytes
1905 if (unlikely(0 == numBytes))
1906 {
1907 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1908 "VPKT [%d]: Invalid numBytes", __LINE__);
1909 return VOS_STATUS_E_INVAL;
1910 }
1911
1912 // get pointer to the skb
1913 skb = pPacket->pSkb;
1914
1915 // Validate the skb
1916 if (unlikely(NULL == skb))
1917 {
1918 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1919 "VPKT [%d]: NULL skb", __LINE__);
1920 return VOS_STATUS_E_INVAL;
1921 }
1922
1923 // check for overflow
1924 if (unlikely((pktOffset + numBytes) > skb->len))
1925 {
1926 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1927 "VPKT [%d]: Packet overflow, offset %d size %d len %d",
1928 __LINE__, pktOffset, numBytes, skb->len);
1929 return VOS_STATUS_E_INVAL;
1930 }
1931
1932 // return pointer to the requested data
1933 *ppPacketData = &skb->data[pktOffset];
1934 return VOS_STATUS_SUCCESS;
1935}
1936
1937
1938/**--------------------------------------------------------------------------
1939
1940 \brief vos_pkt_get_packet_type() - Get packet type for a voss Packet
1941
1942 This API returns the packet Type for a voss Packet.
1943
1944 \param pPacket - the voss Packet to get the packet type from.
1945
1946 \param pPacketType - location to return the packet type for the voss Packet
1947
1948 \return
1949
1950 \sa
1951
1952 ---------------------------------------------------------------------------*/
1953VOS_STATUS vos_pkt_get_packet_type( vos_pkt_t *pPacket,
1954 VOS_PKT_TYPE *pPacketType )
1955{
1956 // Validate the parameter pointers
1957 if (unlikely((NULL == pPacket) ||
1958 (NULL == pPacketType)))
1959 {
1960 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1961 "VPKT [%d]: NULL pointer", __LINE__);
1962 return VOS_STATUS_E_INVAL;
1963 }
1964
1965 // Validate that this is really an initialized vos packet
1966 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
1967 {
1968 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
1969 "VPKT [%d]: Invalid magic", __LINE__);
1970 return VOS_STATUS_E_INVAL;
1971 }
1972
1973 // return the requested information
1974 *pPacketType = pPacket->packetType;
1975 return VOS_STATUS_SUCCESS;
1976}
1977
1978
1979
1980/**--------------------------------------------------------------------------
1981
1982 \brief vos_pkt_get_packet_length() - Get packet length for a voss Packet
1983
1984 This API returns the total length of the data in a voss Packet.
1985
1986 \param pPacket - the voss Packet to get the packet length from.
1987
1988 \param pPacketSize - location to return the total size of the data contained
1989 in the voss Packet.
1990 \return
1991
1992 \sa
1993
1994 ---------------------------------------------------------------------------*/
1995VOS_STATUS vos_pkt_get_packet_length( vos_pkt_t *pPacket,
1996 v_U16_t *pPacketSize )
1997{
1998 // Validate the parameter pointers
1999 if (unlikely((NULL == pPacket) ||
2000 (NULL == pPacketSize)))
2001 {
2002 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2003 "VPKT [%d]: NULL pointer", __LINE__);
2004 return VOS_STATUS_E_INVAL;
2005 }
2006
2007 // Validate that this is really an initialized vos packet
2008 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2009 {
2010 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2011 "VPKT [%d]: Invalid magic", __LINE__);
2012 return VOS_STATUS_E_INVAL;
2013 }
2014
2015 // Validate the skb
2016 if (unlikely(NULL == pPacket->pSkb))
2017 {
2018 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2019 "VPKT [%d]: NULL skb", __LINE__);
2020 return VOS_STATUS_E_INVAL;
2021 }
2022
2023 // return the requested information
2024 *pPacketSize = pPacket->pSkb->len;
2025 return VOS_STATUS_SUCCESS;
2026}
2027
2028
2029/**--------------------------------------------------------------------------
2030
2031 \brief vos_pkt_get_packet_chain_length() - Get length of a vos packet chain
2032
2033 This API returns the total length of the data in a voss Packet chain.
2034
2035 \param pPacket - the voss Packet at the start of the packet chain. This API
2036 will calculate the length of data in the packet chain stating with
2037 this packet.
2038
2039 \param pPacketSize - location to return the total size of the data contained
2040 in the voss Packet.
2041 \return
2042
2043 \sa
2044
2045 ---------------------------------------------------------------------------*/
2046VOS_STATUS vos_pkt_get_packet_chain_length( vos_pkt_t *pPacketChain,
2047 v_SIZE_t *pPacketChainSize )
2048{
2049 v_SIZE_t chainSize = 0;
2050
2051 // Validate the parameter pointers
2052 if (unlikely((NULL == pPacketChain) ||
2053 (NULL == pPacketChainSize)))
2054 {
2055 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2056 "VPKT [%d]: NULL pointer", __LINE__);
2057 return VOS_STATUS_E_INVAL;
2058 }
2059
2060 // walk through each packet in the chain, adding its length
2061 while (pPacketChain)
2062 {
2063
2064 // Validate that this is really an initialized vos packet
2065 if (unlikely(VPKT_MAGIC_NUMBER != pPacketChain->magic))
2066 {
2067 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2068 "VPKT [%d]: Invalid magic", __LINE__);
2069 return VOS_STATUS_E_INVAL;
2070 }
2071
2072 // Validate the skb
2073 if (unlikely(NULL == pPacketChain->pSkb))
2074 {
2075 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2076 "VPKT [%d]: NULL skb", __LINE__);
2077 return VOS_STATUS_E_INVAL;
2078 }
2079
2080 chainSize += pPacketChain->pSkb->len;
2081 pPacketChain = pPacketChain->pNext;
2082 }
2083
2084 // return result
2085 *pPacketChainSize = chainSize;
2086 return VOS_STATUS_SUCCESS;
2087}
2088
2089
2090/**--------------------------------------------------------------------------
2091
2092 \brief vos_pkt_push_head() - push data on the front a of a voss Packet
2093
2094 This API will push data onto the front of a voss Packet. The data will be
2095 appended in front of any data already contained in the voss Packet.
2096
2097 \param pPacket - the voss Packet to modify.
2098
2099 \param pData - pointer to the data to push onto the head of the voss Packet.
2100
2101 \param dataSize - the size of the data to put onto the head of the voss
2102 Packet.
2103
2104 \return
2105
2106 \sa
2107
2108 ---------------------------------------------------------------------------*/
2109VOS_STATUS vos_pkt_push_head( vos_pkt_t *pPacket,
2110 v_VOID_t *pData,
2111 v_SIZE_t dataSize )
2112{
2113 struct sk_buff *skb;
2114
2115 // Validate the parameter pointers
2116 if (unlikely((NULL == pPacket) || (NULL == pData)))
2117 {
2118 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2119 "VPKT [%d]: NULL pointer", __LINE__);
2120 return VOS_STATUS_E_INVAL;
2121 }
2122
2123 // Validate that this is really an initialized vos packet
2124 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2125 {
2126 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2127 "VPKT [%d]: Invalid magic", __LINE__);
2128 return VOS_STATUS_E_INVAL;
2129 }
2130
2131 // get pointer to the skb
2132 skb = pPacket->pSkb;
2133
2134 // Validate the skb
2135 if (unlikely(NULL == skb))
2136 {
2137 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2138 "VPKT [%d]: NULL skb", __LINE__);
2139 return VOS_STATUS_E_INVAL;
2140 }
2141
2142 // Make sure there is headroom. As a performance optimization we
2143 // can omit this check later since skb_push() will also perform the
2144 // check (except skb_push() will panic the kernel)
2145 if (unlikely(skb_headroom(skb) < dataSize))
2146 {
2147 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2148 "VPKT [%d]: Insufficient headroom, "
Jeff Johnson1b067b52017-09-19 08:33:10 -07002149 "head[%pK], data[%pK], req[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 __LINE__, skb->head, skb->data, dataSize);
2151 return VOS_STATUS_E_INVAL;
2152 }
2153
2154 // actually push the data
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302155 vos_mem_copy(skb_push(skb, dataSize), pData, dataSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002156
2157 return VOS_STATUS_SUCCESS;
2158}
2159
2160/**--------------------------------------------------------------------------
2161
2162 \brief vos_pkt_reserve_head() - Reserve space at the front of a voss Packet
2163
2164 This API will reserve space at the front of a voss Packet. The caller can
2165 then copy data into this reserved space using memcpy() like functions. This
2166 allows the caller to reserve space and build headers directly in this
2167 reserved space in the voss Packet.
2168
2169 Upon successful return, the length of the voss Packet is increased by
2170 dataSize.
2171
2172 < put a before / after picture here>
2173
2174 \param pPacket - the voss Packet to modify.
2175
2176 \param ppData - pointer to the location where the pointer to the reserved
2177 space is returned. Upon successful return, the caller has
2178 write / read access to the data space at *ppData for length
2179 dataSize to build headers, etc.
2180
2181 \param dataSize - the size of the data to reserve at the head of the voss
2182 Packet. Upon successful return, the length of the voss
2183 Packet is increased by dataSize.
2184
2185 \return
2186
2187 \sa
2188
2189 ---------------------------------------------------------------------------*/
2190VOS_STATUS vos_pkt_reserve_head( vos_pkt_t *pPacket,
2191 v_VOID_t **ppData,
2192 v_SIZE_t dataSize )
2193{
2194 struct sk_buff *skb;
2195 struct sk_buff *newskb;
2196
2197 // Validate the parameter pointers
2198 if (unlikely((NULL == pPacket) || (NULL == ppData)))
2199 {
2200 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2201 "VPKT [%d]: NULL pointer", __LINE__);
2202 return VOS_STATUS_E_INVAL;
2203 }
2204
2205 // Validate that this is really an initialized vos packet
2206 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2207 {
2208 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2209 "VPKT [%d]: Invalid magic", __LINE__);
2210 return VOS_STATUS_E_INVAL;
2211 }
2212
2213 // get pointer to the skb
2214 skb = pPacket->pSkb;
2215
2216 // Validate the skb
2217 if (unlikely(NULL == skb))
2218 {
2219 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2220 "VPKT [%d]: NULL skb", __LINE__);
2221 return VOS_STATUS_E_INVAL;
2222 }
2223
2224 // Make sure there is headroom. As a performance optimization we
2225 // can omit this check later since skb_push() will also perform the
2226 // check (except skb_push() will panic the kernel)
2227 if (unlikely(skb_headroom(skb) < dataSize))
2228 {
2229 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2230 "VPKT [%d]: Insufficient headroom, "
Jeff Johnson1b067b52017-09-19 08:33:10 -07002231 "head[%pK], data[%pK], req[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002232 __LINE__, skb->head, skb->data, dataSize);
2233
2234 if ((newskb = skb_realloc_headroom(skb, dataSize)) == NULL) {
2235 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2236 "VPKT [%d]: Failed to realloc headroom", __LINE__);
2237 return VOS_STATUS_E_INVAL;
2238 }
2239
2240 kfree_skb(skb);
2241 skb = newskb;
2242
2243 // set the skb pointer
2244 pPacket->pSkb = newskb;
2245 }
2246
2247 // actually allocate the headroom
2248 *ppData = skb_push(skb, dataSize);
2249 // Zero out so we dont take the fastpath on Android.
2250 memset( (void *)*ppData, 0, dataSize );
2251
2252 return VOS_STATUS_SUCCESS;
2253}
2254
2255
2256/**--------------------------------------------------------------------------
2257
2258 \brief vos_pkt_reserve_head_fast() - Reserve space at the front of a voss Packet
2259
2260 This API will reserve space at the front of a voss Packet. The caller can
2261 then copy data into this reserved space using memcpy() like functions. This
2262 allows the caller to reserve space and build headers directly in this
2263 reserved space in the voss Packet.
2264
2265 Upon successful return, the length of the voss Packet is increased by
2266 dataSize.
2267
2268 Same as above APi but no memset to 0 at the end.
2269
2270 < put a before / after picture here>
2271
2272 \param pPacket - the voss Packet to modify.
2273
2274 \param ppData - pointer to the location where the pointer to the reserved
2275 space is returned. Upon successful return, the caller has
2276 write / read access to the data space at *ppData for length
2277 dataSize to build headers, etc.
2278
2279 \param dataSize - the size of the data to reserve at the head of the voss
2280 Packet. Upon successful return, the length of the voss
2281 Packet is increased by dataSize.
2282
2283 \return
2284
2285 \sa
2286
2287 ---------------------------------------------------------------------------*/
2288VOS_STATUS vos_pkt_reserve_head_fast( vos_pkt_t *pPacket,
2289 v_VOID_t **ppData,
2290 v_SIZE_t dataSize )
2291{
2292 struct sk_buff *skb;
2293 struct sk_buff *newskb;
2294
2295 // get pointer to the skb
2296 skb = pPacket->pSkb;
2297
2298 // Validate the skb
2299 if (unlikely(NULL == skb))
2300 {
2301 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2302 "VPKT [%d]: NULL skb", __LINE__);
2303 return VOS_STATUS_E_INVAL;
2304 }
2305
2306 // Make sure there is headroom. As a performance optimization we
2307 // can omit this check later since skb_push() will also perform the
2308 // check (except skb_push() will panic the kernel)
2309 if (unlikely(skb_headroom(skb) < dataSize))
2310 {
2311 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
2312 "VPKT [%d]: Insufficient headroom, "
Jeff Johnson1b067b52017-09-19 08:33:10 -07002313 "head[%pK], data[%pK], req[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 __LINE__, skb->head, skb->data, dataSize);
2315
2316 if ((newskb = skb_realloc_headroom(skb, dataSize)) == NULL) {
2317 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2318 "VPKT [%d]: Failed to realloc headroom", __LINE__);
2319 return VOS_STATUS_E_INVAL;
2320 }
2321
2322 kfree_skb(skb);
2323 skb = newskb;
2324
2325 // set the skb pointer
2326 pPacket->pSkb = newskb;
2327 }
2328
2329 // actually allocate the headroom
2330 *ppData = skb_push(skb, dataSize);
2331 // Zero out so we dont take the fastpath on Android.
2332 //memset( (void *)*ppData, 0, dataSize );
2333
2334 return VOS_STATUS_SUCCESS;
2335}
2336
2337/**--------------------------------------------------------------------------
2338
2339 \brief vos_pkt_pop_head() - Remove data from the front of the voss Packet
2340
2341 This API removes data from the front of a voss Packet. The data is
2342 copied into the output buffer described by pData and pDataSize
2343
2344 \param pPacket - the voss Packet to operate on.
2345
2346 \param pData - pointer to the data buffer where the data removed from the
2347 voss Packet is placed.
2348
2349 \param dataSize - The amount of space to remove from the head of the voss
2350 Packet. The output buffer (at *pData) must contain at
2351 least this amount of space.
2352
2353 \return
2354
2355 \sa
2356
2357 ---------------------------------------------------------------------------*/
2358VOS_STATUS vos_pkt_pop_head( vos_pkt_t *pPacket,
2359 v_VOID_t *pData,
2360 v_SIZE_t dataSize )
2361{
2362 struct sk_buff *skb;
2363
2364 // Validate the parameter pointers
2365 if (unlikely((NULL == pPacket) || (NULL == pData)))
2366 {
2367 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2368 "VPKT [%d]: NULL pointer", __LINE__);
2369 return VOS_STATUS_E_INVAL;
2370 }
2371
2372 // Validate that this is really an initialized vos packet
2373 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2374 {
2375 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2376 "VPKT [%d]: Invalid magic", __LINE__);
2377 return VOS_STATUS_E_INVAL;
2378 }
2379
2380 // get pointer to the skb
2381 skb = pPacket->pSkb;
2382
2383 // Validate the skb
2384 if (unlikely(NULL == skb))
2385 {
2386 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2387 "VPKT [%d]: NULL skb", __LINE__);
2388 return VOS_STATUS_E_INVAL;
2389 }
2390
2391 // Make sure there is enough data to pop
2392 if (unlikely(skb->len < dataSize))
2393 {
Kaushik, Sushante386ee12014-05-01 15:50:52 +05302394 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Jeff Johnson295189b2012-06-20 16:38:30 -07002395 "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]",
2396 __LINE__, skb->len, dataSize);
2397 return VOS_STATUS_E_INVAL;
2398 }
2399
2400 // copy the data
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302401 vos_mem_copy(pData, skb->data, dataSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 skb_pull(skb, dataSize);
2403
2404 return VOS_STATUS_SUCCESS;
2405}
2406
2407
2408/**--------------------------------------------------------------------------
2409
2410 \brief vos_pkt_trim_head() - Skip over bytes at the front of a voss Packet
2411
2412 This API moves the pointers at the head of a voss Packet to essentially
2413 skip over data at the front of a voss Packet. Upon successful return, the
2414 length of the voss Packet is reduced by dataSize and the starting pointer
2415 to the voss Packet is adjusted to eliminate the data from the start of the
2416 voss Packet.
2417
2418 This API has the opposite effect of \a vos_pkt_reserve_head().
2419
2420 \param pPacket - the voss Packet to operate on.
2421
2422 \param dataSize - The amount of space to skip at the start of the voss
2423 Packet.
2424
2425 Note that upon return, the data skipped over is
2426 inaccessible to the caller. If the caller needs access
2427 to the head data, use vos_pkt_pop_head() or
2428 vos_pkt_extract_data() to get a copy of the data.
2429
2430 \return
2431
2432 \sa
2433
2434 ---------------------------------------------------------------------------*/
2435VOS_STATUS vos_pkt_trim_head( vos_pkt_t *pPacket,
2436 v_SIZE_t dataSize )
2437{
2438 struct sk_buff *skb;
2439
2440 // Validate the parameter pointers
2441 if (unlikely(NULL == pPacket))
2442 {
2443 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2444 "VPKT [%d]: NULL pointer", __LINE__);
2445 return VOS_STATUS_E_INVAL;
2446 }
2447
2448 // Validate that this is really an initialized vos packet
2449 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2450 {
2451 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2452 "VPKT [%d]: Invalid magic", __LINE__);
2453 return VOS_STATUS_E_INVAL;
2454 }
2455
2456 // get pointer to the skb
2457 skb = pPacket->pSkb;
2458
2459 // Validate the skb
2460 if (unlikely(NULL == skb))
2461 {
2462 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2463 "VPKT [%d]: NULL skb", __LINE__);
2464 return VOS_STATUS_E_INVAL;
2465 }
2466
2467 // Make sure there is enough data to trim
2468 if (unlikely(skb->len < dataSize))
2469 {
2470 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2471 "VPKT [%d]: trim exceeds packet size, len[%d], req[%d]",
2472 __LINE__, skb->len, dataSize);
2473 return VOS_STATUS_E_INVAL;
2474 }
2475
2476 // adjust the skb
2477 skb_pull(skb, dataSize);
2478
2479 return VOS_STATUS_SUCCESS;
2480}
2481
2482/**--------------------------------------------------------------------------
2483
2484 \brief vos_pkt_push_tail() - push data on the end a of a voss Packet
2485
2486 This API will push data onto the end of a voss Packet. The data will be
2487 appended to the end of any data already contained in the voss Packet.
2488
2489 \param pPacket - the voss Packet to modify.
2490
2491 \param pData - pointer to the data to push onto the tail of the voss Packet.
2492
2493 \param dataSize - the size of the data to put onto the tail of the voss Packet.
2494
2495 \return
2496
2497 \sa
2498
2499 ---------------------------------------------------------------------------*/
2500VOS_STATUS vos_pkt_push_tail( vos_pkt_t *pPacket,
2501 v_VOID_t *pData,
2502 v_SIZE_t dataSize )
2503{
2504 struct sk_buff *skb;
2505
2506 // Validate the parameter pointers
2507 if (unlikely((NULL == pPacket) || (NULL == pData)))
2508 {
2509 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2510 "VPKT [%d]: NULL pointer", __LINE__);
2511 return VOS_STATUS_E_INVAL;
2512 }
2513
2514 // Validate that this is really an initialized vos packet
2515 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2516 {
2517 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2518 "VPKT [%d]: Invalid magic", __LINE__);
2519 return VOS_STATUS_E_INVAL;
2520 }
2521
2522 // get pointer to the skb
2523 skb = pPacket->pSkb;
2524
2525 // Validate the skb
2526 if (unlikely(NULL == skb))
2527 {
2528 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2529 "VPKT [%d]: NULL skb", __LINE__);
2530 return VOS_STATUS_E_INVAL;
2531 }
2532
2533 // Make sure there is tailroom. As a performance optimization we
2534 // can omit this check later since skb_put() will also perform the
2535 // check (except skb_put() will panic the kernel)
2536 if (unlikely(skb_tailroom(skb) < dataSize))
2537 {
2538 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2539 "VPKT [%d]: Insufficient tailroom, "
Jeff Johnson1b067b52017-09-19 08:33:10 -07002540 "tail[%pK], end[%pK], req[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 __LINE__, skb_tail_pointer(skb),
2542 skb_end_pointer(skb), dataSize);
2543 return VOS_STATUS_E_INVAL;
2544 }
2545
2546 // actually push the data
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302547 vos_mem_copy(skb_put(skb, dataSize), pData, dataSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002548
2549 return VOS_STATUS_SUCCESS;
2550}
2551
2552
2553/**--------------------------------------------------------------------------
2554
2555 \brief vos_pkt_reserve_tail() - Reserve space at the end of a voss Packet
2556
2557 This API will reserve space at the end of a voss Packet. The caller can
2558 then copy data into this reserved space using memcpy() like functions. This
2559 allows the caller to reserve space and build headers directly in this
2560 reserved space in the voss Packet.
2561
2562 Upon successful return, the length of the voss Packet is increased by
2563 dataSize.
2564
2565 \param pPacket - the voss Packet to modify.
2566
2567 \param ppData - pointer to the location where the pointer to the reserved
2568 space is returned. Upon successful return, the caller has
2569 write / read access to the data space at *ppData for length
2570 dataSize to build headers, etc.
2571
2572 \param dataSize - the size of the data to reserve at the head of the voss
2573 Packet. Upon successful return, the length of the voss
2574 Packet is increased by dataSize.
2575
2576 \return
2577
2578 \sa
2579
2580 ---------------------------------------------------------------------------*/
2581VOS_STATUS vos_pkt_reserve_tail( vos_pkt_t *pPacket,
2582 v_VOID_t **ppData,
2583 v_SIZE_t dataSize )
2584{
2585 struct sk_buff *skb;
2586
2587 // Validate the parameter pointers
2588 if (unlikely((NULL == pPacket) || (NULL == ppData)))
2589 {
2590 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2591 "VPKT [%d]: NULL pointer", __LINE__);
2592 return VOS_STATUS_E_INVAL;
2593 }
2594
2595 // Validate that this is really an initialized vos packet
2596 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2597 {
2598 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2599 "VPKT [%d]: Invalid magic", __LINE__);
2600 return VOS_STATUS_E_INVAL;
2601 }
2602
2603 // get pointer to the skb
2604 skb = pPacket->pSkb;
2605
2606 // Validate the skb
2607 if (unlikely(NULL == skb))
2608 {
2609 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2610 "VPKT [%d]: NULL skb", __LINE__);
2611 return VOS_STATUS_E_INVAL;
2612 }
2613
2614 // Make sure there is tailroom. As a performance optimization we
2615 // can omit this check later since skb_put() will also perform the
2616 // check (except skb_put() will panic the kernel)
2617 if (unlikely(skb_tailroom(skb) < dataSize))
2618 {
2619 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2620 "VPKT [%d]: Insufficient tailroom, "
Jeff Johnson1b067b52017-09-19 08:33:10 -07002621 "tail[%pK], end[%pK], req[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002622 __LINE__, skb_tail_pointer(skb),
2623 skb_end_pointer(skb), dataSize);
2624 return VOS_STATUS_E_INVAL;
2625 }
2626
2627 // actually allocate the space
2628 *ppData = skb_put(skb, dataSize);
2629
2630 return VOS_STATUS_SUCCESS;
2631}
2632
2633
2634
2635/**--------------------------------------------------------------------------
2636
2637 \brief vos_pkt_pop_tail() - Remove data from the end of the voss Packet
2638
2639 This API removes data from the end of a voss Packet. The data is
2640 copied into the output buffer described by pData and pDataSize
2641
2642 \param pPacket - the voss Packet to operate on.
2643
2644 \param pData - pointer to the data buffer where the data removed from the
2645 voss Packet is placed.
2646
2647 \param dataSize - The amount of space to remove from the end of the voss
2648 Packet. The output buffer (at *pData) must contain at
2649 least this amount of space.
2650
2651 \return
2652
2653 \sa
2654
2655 ---------------------------------------------------------------------------*/
2656VOS_STATUS vos_pkt_pop_tail( vos_pkt_t *pPacket,
2657 v_VOID_t *pData,
2658 v_SIZE_t dataSize )
2659{
2660 struct sk_buff *skb;
2661
2662 // Validate the parameter pointers
2663 if (unlikely((NULL == pPacket) || (NULL == pData)))
2664 {
2665 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2666 "VPKT [%d]: NULL pointer", __LINE__);
2667 return VOS_STATUS_E_INVAL;
2668 }
2669
2670 // Validate that this is really an initialized vos packet
2671 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2672 {
2673 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2674 "VPKT [%d]: Invalid magic", __LINE__);
2675 return VOS_STATUS_E_INVAL;
2676 }
2677
2678 // get pointer to the skb
2679 skb = pPacket->pSkb;
2680
2681 // Validate the skb
2682 if (unlikely(NULL == skb))
2683 {
2684 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2685 "VPKT [%d]: NULL skb", __LINE__);
2686 return VOS_STATUS_E_INVAL;
2687 }
2688
2689 // Make sure there is enough data to pop
2690 if (unlikely(skb->len < dataSize))
2691 {
Kaushik, Sushante386ee12014-05-01 15:50:52 +05302692 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Jeff Johnson295189b2012-06-20 16:38:30 -07002693 "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]",
2694 __LINE__, skb->len, dataSize);
2695 return VOS_STATUS_E_INVAL;
2696 }
2697
2698 // adjust pointers (there isn't a native Linux API for this)
2699 skb->tail -= dataSize;
2700 skb->len -= dataSize;
2701
2702 // actually push the data
Rajesh Babu Prathipatiddbe2892014-07-01 18:57:16 +05302703 vos_mem_copy(pData, skb_tail_pointer(skb), dataSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07002704
2705 return VOS_STATUS_SUCCESS;
2706}
2707
2708/**--------------------------------------------------------------------------
2709
2710 \brief vos_pkt_trim_tail() - Skip over bytes at the end of a voss Packet
2711
2712 This API moves the pointers at the head of a voss Packet to essentially
2713 skip over data at the end of a voss Packet. Upon successful return, the
2714 length of the voss Packet is reduced by dataSize and voss Packet is
2715 adjusted to eliminate the data from the end of the voss Packet.
2716
2717 This API has the opposite effect of \a vos_pkt_reserve_tail().
2718
2719 \param pPacket - the voss Packet to operate on.
2720
2721 \param dataSize - The amount of space to remove at the end of the voss
2722 Packet.
2723
2724 Note that upon return, the data skipped over is
2725 inaccessible to the caller. If the caller needs access
2726 to the tail data, use vos_pkt_pop_tail() or
2727 vos_pkt_extract_data() to get a copy of the data.
2728
2729 \return
2730
2731 \sa
2732
2733 ---------------------------------------------------------------------------*/
2734VOS_STATUS vos_pkt_trim_tail( vos_pkt_t *pPacket,
2735 v_SIZE_t dataSize )
2736{
2737 struct sk_buff *skb;
2738
2739 // Validate the parameter pointers
2740 if (unlikely(NULL == pPacket))
2741 {
2742 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2743 "VPKT [%d]: NULL pointer", __LINE__);
2744 return VOS_STATUS_E_INVAL;
2745 }
2746
2747 // Validate that this is really an initialized vos packet
2748 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2749 {
2750 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2751 "VPKT [%d]: Invalid magic", __LINE__);
2752 return VOS_STATUS_E_INVAL;
2753 }
2754
2755 // get pointer to the skb
2756 skb = pPacket->pSkb;
2757
2758 // Validate the skb
2759 if (unlikely(NULL == skb))
2760 {
2761 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2762 "VPKT [%d]: NULL skb", __LINE__);
2763 return VOS_STATUS_E_INVAL;
2764 }
2765
2766 // Make sure there is enough data to pop
2767 if (unlikely(skb->len < dataSize))
2768 {
Kaushik, Sushante386ee12014-05-01 15:50:52 +05302769 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
Jeff Johnson295189b2012-06-20 16:38:30 -07002770 "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]",
2771 __LINE__, skb->len, dataSize);
2772 return VOS_STATUS_E_INVAL;
2773 }
2774
2775 // adjust pointers (there isn't a native Linux API for this)
2776 skb->tail -= dataSize;
2777 skb->len -= dataSize;
2778
2779 return VOS_STATUS_SUCCESS;
2780}
2781
2782
2783/**--------------------------------------------------------------------------
2784
2785 \brief vos_pkt_get_timestamp() - Retrive the timestamp attribute from the
2786 specified VOSS packet
2787
2788 \param pPacket - the voss Packet to operate on.
2789
2790 \param pTstamp - the timestamp will be returned here.
2791
2792 \return VOS_STATUS_E_FAULT - invalid parameter(s) specified
2793
2794 VOS_STATUS_SUCCESS - timestamp retrived successfully
2795
2796 \sa
2797
2798 ---------------------------------------------------------------------------*/
2799VOS_STATUS vos_pkt_get_timestamp( vos_pkt_t *pPacket,
2800 v_TIME_t* pTstamp )
2801{
2802 // Validate the parameter pointers
2803 if (unlikely((NULL == pPacket) ||
2804 (NULL == pTstamp)))
2805 {
2806 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2807 "VPKT [%d]: NULL pointer", __LINE__);
2808 return VOS_STATUS_E_INVAL;
2809 }
2810
2811 // Validate that this is really an initialized vos packet
2812 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2813 {
2814 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2815 "VPKT [%d]: Invalid magic", __LINE__);
2816 return VOS_STATUS_E_INVAL;
2817 }
2818
2819 // return the requested information
2820 *pTstamp = pPacket->timestamp;
2821 return VOS_STATUS_SUCCESS;
2822}
2823
2824
2825/**--------------------------------------------------------------------------
2826
2827 \brief vos_pkt_flatten_rx_pkt() - Transform a platform based RX VOSS
2828 packet into a flat buffer based VOSS packet if needed. This is needed in
2829 cases where for reasons of efficiency we want the RX packets to be very
2830 platform specific (for e.g. DSM based on AMSS, etc). However platform
2831 independent code may rely on making calls on the VOSS packet which can only
2832 be supported by the flat buffer based implementation of a RX packet. This API
2833 will allocate a new VOSS packet with flat buffer, extract the data from the
2834 input VOSS packet and then release the input VOSS packet. The new VOSS packet
2835 will be returned from this call.
2836
2837 \param ppPacket - the voss Packet to operate on. On input contains
2838 the platform based packet. On output contains the flat
2839 buffer based packet. Any applicable resources
2840 are freed as part of this call.
2841
2842 \return VOS_STATUS_E_FAULT - invalid parameter specified
2843
2844 VOS_STATUS_E_INVAL - packet type not RX_RAW
2845
2846 VOS_STATUS_SUCCESS - transform successful
2847
2848 other VOSS status - other errors encountered
2849
2850 \sa
2851
2852 ----------------------------------------------------------------------------*/
2853VOS_STATUS vos_pkt_flatten_rx_pkt( vos_pkt_t **ppPacket )
2854{
2855 // Linux/Android skbs are already flat, no work required
2856 return VOS_STATUS_SUCCESS;
2857}
2858
2859/**--------------------------------------------------------------------------
2860
2861 \brief vos_pkt_set_rx_length() - Set the length of a received packet
2862
2863 This API set the length of the data inside the packet after a DMA has occurred
2864 on rx, it will also set the tail pointer to the end of the data.
2865
2866 \param pPacket - the voss Packet to operate on.
2867
2868 \param pktLen - The size of the data placed in the Rx packet during DMA.
2869
2870
2871 \return
2872
2873 \sa
2874
2875 ---------------------------------------------------------------------------*/
2876VOS_STATUS vos_pkt_set_rx_length( vos_pkt_t *pPacket,
2877 v_SIZE_t pktLen )
2878{
2879 struct sk_buff *skb;
2880
2881 // Validate the parameter pointers
2882 if (unlikely(NULL == pPacket))
2883 {
2884 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2885 "VPKT [%d]: NULL pointer", __LINE__);
2886 return VOS_STATUS_E_INVAL;
2887 }
2888
2889 // Validate that this is really an initialized vos packet
2890 if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic))
2891 {
2892 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2893 "VPKT [%d]: Invalid magic", __LINE__);
2894 return VOS_STATUS_E_INVAL;
2895 }
2896
2897 // get pointer to the skb
2898 skb = pPacket->pSkb;
2899
2900 // Validate the skb
2901 if (unlikely(NULL == skb))
2902 {
2903 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
2904 "VPKT [%d]: NULL skb", __LINE__);
2905 return VOS_STATUS_E_INVAL;
2906 }
2907
2908 // adjust pointers (there isn't a native Linux API for this)
2909 // ?? - is this sufficient?
2910 skb_set_tail_pointer(skb, pktLen);
2911 skb->len = pktLen;
2912
2913 return VOS_STATUS_SUCCESS;
2914
2915}
2916/**--------------------------------------------------------------------------
2917
2918 \brief vos_pkt_get_available_buffer_pool() - Get avaliable VOS packet size
2919 VOSS Packet pool is limitted resource
2920 VOSS Client need to know how many packet pool is still avaliable to control
2921 the flow
2922
2923 \param pktType - Packet type want to know free buffer count
2924 VOS_PKT_TYPE_TX_802_11_MGMT, management free buffer count,
2925 VOS_PKT_TYPE_TX_802_11_DATA
2926 VOS_PKT_TYPE_TX_802_3_DATA, TX free buffer count
2927 VOS_PKT_TYPE_RX_RAW, RX free buffer count
2928
2929 vosFreeBuffer - free frame buffer size
2930
2931 \return VOS_STATUS_E_INVAL - invalid input parameter
2932
2933 VOS_STATUS_SUCCESS - Get size success
2934
2935 \sa
2936
2937 ----------------------------------------------------------------------------*/
2938VOS_STATUS vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE pktType,
2939 v_SIZE_t *vosFreeBuffer)
2940{
2941 struct list_head *pList;
2942 struct list_head *pNode;
2943 v_SIZE_t count;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05302944 struct mutex *mlock;
2945
Jeff Johnson295189b2012-06-20 16:38:30 -07002946 if (NULL == vosFreeBuffer)
2947 {
2948 return VOS_STATUS_E_INVAL;
2949 }
2950
2951 switch (pktType)
2952 {
2953 case VOS_PKT_TYPE_TX_802_11_MGMT:
2954 pList = &gpVosPacketContext->txMgmtFreeList;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05302955 mlock = &gpVosPacketContext->txMgmtFreeListLock;
Jeff Johnson295189b2012-06-20 16:38:30 -07002956 break;
2957
2958 case VOS_PKT_TYPE_TX_802_11_DATA:
2959 case VOS_PKT_TYPE_TX_802_3_DATA:
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 if (VOS_STA_SAP_MODE == hdd_get_conparam())
2961 {
2962 *vosFreeBuffer = gpVosPacketContext->uctxDataFreeListCount;
2963 return VOS_STATUS_SUCCESS;
2964 }
2965 else
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05302966 {
2967 pList = &gpVosPacketContext->txDataFreeList;
2968 mlock = &gpVosPacketContext->txDataFreeListLock;
2969 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002970 break;
2971
2972 case VOS_PKT_TYPE_RX_RAW:
2973 // if the caller is curious how many raw packets are available
2974 // then he probably wants as many packets to be available as
2975 // possible so replenish the raw pool
2976 vos_pkti_replenish_raw_pool();
Mahesh Kumar Kalikot Veetil78b1f372013-02-21 17:32:37 -08002977 // Return the pre-calculated count 'rxRawFreeListCount'
2978 *vosFreeBuffer = gpVosPacketContext->rxRawFreeListCount;
2979 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002980 break;
2981
2982 default:
2983 return (VOS_STATUS_E_INVAL);
2984 }
2985
2986 count = 0;
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05302987 mutex_lock(mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002988 list_for_each(pNode, pList)
2989 {
2990 count++;
2991 }
Madan Mohan Koyyalamudi1c2d1232013-10-07 23:30:54 +05302992 mutex_unlock(mlock);
Jeff Johnson295189b2012-06-20 16:38:30 -07002993 *vosFreeBuffer = count;
2994 return VOS_STATUS_SUCCESS;
2995}
2996
Sameer Thalappild0158402013-05-03 13:19:03 -07002997/**
2998 @brief vos_pkt_get_num_of_rx_raw_pkts() - Get the number of RX packets
2999 that should be allocated.
3000
3001 This function is called by VOS packet module to know how many RX raw
3002 packets it should allocate/reserve. This value can be configured thru
3003 Kernel device tree to save memory usage.
3004
3005 @param
3006 NONE
3007 @return
3008 v_SIZE_t the number of packets to allocate
3009
3010*/
3011v_SIZE_t vos_pkt_get_num_of_rx_raw_pkts(void)
3012{
3013#ifdef HAVE_WCNSS_RX_BUFF_COUNT
3014 v_SIZE_t buffCount;
3015
3016 buffCount = wcnss_get_wlan_rx_buff_count();
3017 return (buffCount > VPKT_NUM_RX_RAW_PACKETS ?
3018 VPKT_NUM_RX_RAW_PACKETS : buffCount);
3019#else
3020 return VPKT_NUM_RX_RAW_PACKETS;
3021#endif
3022}
Jeff Johnson295189b2012-06-20 16:38:30 -07003023
Mihir Sheted183cef2014-09-26 19:17:56 +05303024/**
3025 @brief vos_pkt_get_num_of_rx_raw_pkts() - Get the number of times
3026 skb allocation failed while replenishing packets
3027
3028
3029 @param
3030 NONE
3031 @return
3032 v_SIZE_t the number of times packet allocation failed
3033
3034*/
3035v_SIZE_t vos_pkt_get_num_of_rx_pkt_alloc_failures(void)
3036{
3037 v_SIZE_t failCount;
3038
3039 mutex_lock(&gpVosPacketContext->rxReplenishListLock);
3040 mutex_lock(&gpVosPacketContext->rxRawFreeListLock);
3041
3042 failCount = gpVosPacketContext->rxReplenishFailCount;
3043
3044 mutex_unlock(&gpVosPacketContext->rxReplenishListLock);
3045 mutex_unlock(&gpVosPacketContext->rxRawFreeListLock);
3046
3047 return failCount;
3048}
3049
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08003050v_U8_t vos_pkt_get_proto_type
3051(
3052 void *pskb,
3053 v_U8_t tracking_map
3054)
3055{
3056 v_U8_t pkt_proto_type = 0;
3057 v_U16_t ether_type;
3058 v_U16_t SPort;
3059 v_U16_t DPort;
3060 struct sk_buff *skb = NULL;
3061
3062
3063 if (NULL == pskb)
3064 {
3065 return pkt_proto_type;
3066 }
3067 else
3068 {
3069 skb = (struct sk_buff *)pskb;
3070 }
3071
3072 /* EAPOL Tracking enabled */
3073 if (VOS_PKT_PROTO_TYPE_EAPOL & tracking_map)
3074 {
3075 ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET));
3076 if (VOS_PKT_PROT_EAPOL_ETH_TYPE == VOS_SWAP_U16(ether_type))
3077 {
3078 pkt_proto_type |= VOS_PKT_PROTO_TYPE_EAPOL;
3079 }
3080 }
3081
Mihir Shete39f7c752015-06-11 15:40:09 +05303082 /* ARP Tracking Enabled */
3083 if (VOS_PKT_PROTO_TYPE_ARP & tracking_map)
3084 {
3085 ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET));
3086 if (VOS_PKT_PROT_ARP_ETH_TYPE == VOS_SWAP_U16(ether_type))
3087 {
3088 pkt_proto_type |= VOS_PKT_PROTO_TYPE_ARP;
3089 }
3090 }
3091
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08003092 /* DHCP Tracking enabled */
3093 if (VOS_PKT_PROTO_TYPE_DHCP & tracking_map)
3094 {
3095 SPort = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_IP_OFFSET +
3096 VOS_PKT_PROT_IP_HEADER_SIZE));
3097 DPort = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_IP_OFFSET +
3098 VOS_PKT_PROT_IP_HEADER_SIZE + sizeof(v_U16_t)));
3099 if (((VOS_PKT_PROT_DHCP_SRV_PORT == VOS_SWAP_U16(SPort)) &&
3100 (VOS_PKT_PROT_DHCP_CLI_PORT == VOS_SWAP_U16(DPort))) ||
3101 ((VOS_PKT_PROT_DHCP_CLI_PORT == VOS_SWAP_U16(SPort)) &&
3102 (VOS_PKT_PROT_DHCP_SRV_PORT == VOS_SWAP_U16(DPort))))
3103 {
3104 pkt_proto_type |= VOS_PKT_PROTO_TYPE_DHCP;
3105 }
3106 }
3107
3108 /* Protocol type map */
3109 return pkt_proto_type;
3110}
Bhargav Shah7dbfb6f2016-02-12 20:49:58 +05303111
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05303112bool vos_is_arp_pkt(void *pskb, bool is_translated)
3113{
3114 v_U16_t ether_type;
3115 struct sk_buff *skb = NULL;
3116#define HEADER_OFFSET_802_11 20
3117
3118 if (NULL == pskb)
3119 {
3120 return FALSE;
3121 }
3122
3123 skb = (struct sk_buff *)pskb;
3124
3125 if (is_translated)
3126 ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET + HEADER_OFFSET_802_11));
3127 else
3128 ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET));
3129
3130 if (VOS_PKT_PROT_ARP_ETH_TYPE == VOS_SWAP_U16(ether_type))
3131 {
3132 return TRUE;
3133 }
3134 else
3135 {
3136 return FALSE;
3137 }
3138#undef HEADER_OFFSET_802_11
3139}
3140
Bhargav Shah7dbfb6f2016-02-12 20:49:58 +05303141v_PVOID_t vos_get_pkt_head(vos_pkt_t *pPacket)
3142{
3143 struct sk_buff *skb;
3144
3145 // Validate the parameter pointers
3146 if (unlikely(NULL == pPacket))
3147 {
3148 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
3149 "VPKT [%d]: NULL pointer", __LINE__);
3150 return NULL;
3151 }
3152
3153 if ( VOS_STATUS_SUCCESS !=
3154 vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE ))
3155 {
3156 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
3157 "OS-PKT [%d]: OS PKT pointer is NULL", __LINE__);
3158 return NULL;
3159 }
3160
3161 return VOS_PKT_GET_HEAD(skb);
3162}
3163
3164v_PVOID_t vos_get_pkt_end(vos_pkt_t *pPacket)
3165{
3166 struct sk_buff *skb;
3167
3168 // Validate the parameter pointers
3169 if (unlikely(NULL == pPacket))
3170 {
3171 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
3172 "VPKT [%d]: NULL pointer", __LINE__);
3173 return NULL;
3174 }
3175
3176 if ( VOS_STATUS_SUCCESS !=
3177 vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE ))
3178 {
3179 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
3180 "OS-PKT [%d]: OS PKT pointer is NULL", __LINE__);
3181 return NULL;
3182 }
3183
3184 /* find end point if skb->end is an offset */
3185#ifdef NET_SKBUFF_DATA_USES_OFFSET
3186 return VOS_PKT_GET_HEAD(skb) + VOS_PKT_GET_END(skb);
3187#else
3188 return VOS_PKT_GET_END(skb);
3189#endif
3190}
3191
3192v_VOID_t vos_recover_tail(vos_pkt_t *pPacket)
3193{
3194 struct skb_shared_info *shinfo;
3195 struct sk_buff *skb;
3196
3197 // Validate the parameter pointers
3198 if (unlikely(NULL == pPacket))
3199 {
3200 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
3201 "VPKT [%d]: NULL pointer", __LINE__);
3202 return;
3203 }
3204
3205 if ( VOS_STATUS_SUCCESS !=
3206 vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE ))
3207 {
3208 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
3209 "OS-PKT [%d]: OS PKT pointer is NULL", __LINE__);
3210 return;
3211 }
3212
3213 shinfo = skb_shinfo(skb);
3214 memset(shinfo, 0, sizeof(struct skb_shared_info));
3215 atomic_set(&shinfo->dataref, 1);
3216 kmemcheck_annotate_variable(shinfo->destructor_arg);
3217
3218 return;
3219}
3220
Jeff Johnson295189b2012-06-20 16:38:30 -07003221#ifdef VOS_PACKET_UNIT_TEST
3222#include "vos_packet_test.c"
3223#endif