blob: e86188eab4d7338f09646680ec7c1dfb4c4388aa [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam1ed83fc2014-02-19 01:15:45 -08002 * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam1ed83fc2014-02-19 01:15:45 -080021
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 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=========================================================================
29
30 \file wlan_qct_pal_packet.c
31
32 \brief Implementation for PAL packet. wpt = (Wlan Pal Type) wpal = (Wlan PAL)
33
34 Definitions for platform with VOSS packet support and LA.
35
36 Copyright 2010 (c) Qualcomm, Incorporated. All Rights Reserved.
37
38 Qualcomm Confidential and Proprietary.
39
40 ========================================================================*/
41
42#include "wlan_qct_pal_packet.h"
43#include "wlan_qct_pal_api.h"
44#include "wlan_qct_pal_trace.h"
Mihir Shete058fcff2014-06-26 18:54:06 +053045#include "wlan_qct_os_status.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070046#include "vos_packet.h"
47#include "vos_trace.h"
48#include "vos_list.h"
49
50#include <linux/skbuff.h>
51#include "dma-mapping.h"
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053052#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54/*Per spec definition*/
55#define WPAL_ETHERNET_PAKCET_HEADER_SIZE 14
56
57/*Per spec definition - not including QOS field*/
58#define WPAL_802_11_PACKET_HEADER_SIZE 24
59
60/*p is a pointer to wpt_packet*/
61#define WPAL_TO_VOS_PKT(p) ((vos_pkt_t *)(p))
62
63
64typedef struct
65{
66 void* pPhyAddr;
67 wpt_uint32 uLen;
68}wpt_iterator_info;
69
70/* Storage for DXE CB function pointer */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070071static wpalPacketLowPacketCB wpalPacketAvailableCB;
Jeff Johnson295189b2012-06-20 16:38:30 -070072
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -070073/* Temp storage for transport channel DIAG/LOG information
74 * Each channel will update information with different context
75 * Before send stored date to DIAG,
76 * temporary it should be stored */
77static wpt_log_data_stall_type wpalTrasportStallInfo;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -070078
Jeff Johnson295189b2012-06-20 16:38:30 -070079/*
80 wpalPacketInit is no-op for VOSS-support wpt_packet
81*/
82wpt_status wpalPacketInit(void *pPalContext)
83{
84 return eWLAN_PAL_STATUS_SUCCESS;
85}
86
87
88/*
89 wpalPacketClose is no-op for VOSS-support wpt_packet
90*/
91wpt_status wpalPacketClose(void *pPalContext)
92{
93 return eWLAN_PAL_STATUS_SUCCESS;
94}
95
96/*---------------------------------------------------------------------------
97 wpalPacketRXLowResourceCB – RX RAW packer CB function
98 Param:
99 pPacket – Available RX packet
100 userData - PAL Client Context, DXE
101 Return:
102 Status
103---------------------------------------------------------------------------*/
104VOS_STATUS wpalPacketRXLowResourceCB(vos_pkt_t *pPacket, v_VOID_t *userData)
105{
106 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
107 void* pData = NULL;
108
109 if (NULL == pPacket)
110 {
111 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
112 "Get new RX PAL packet fail");
113 return VOS_STATUS_E_FAILURE;
114 }
115 vosStatus = vos_pkt_reserve_head_fast( pPacket, &pData,
116 VPKT_SIZE_BUFFER );
117 if(VOS_STATUS_SUCCESS != vosStatus)
118 {
119 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
120 "Prepare RX packet for DXE fail");
121 return VOS_STATUS_E_FAILURE;
122 }
123
124 if((NULL == wpalPacketAvailableCB) || (NULL == userData))
125 {
126 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
127 "Invalid ARG for new RX packet");
128 return VOS_STATUS_E_FAILURE;
129 }
130
131 wpalPacketAvailableCB( (wpt_packet *)pPacket, userData );
Madan Mohan Koyyalamudic2994452013-08-16 11:27:23 +0530132
Jeff Johnson295189b2012-06-20 16:38:30 -0700133 return VOS_STATUS_SUCCESS;
134}
135
136/*---------------------------------------------------------------------------
137 wpalPacketAlloc – Allocate a wpt_packet from PAL.
138 Param:
139 pktType – specify the type of wpt_packet to allocate
140 nPktSize - packet size
141 Return:
142 A pointer to the wpt_packet. NULL means fail.
143---------------------------------------------------------------------------*/
144wpt_packet * wpalPacketAlloc(wpt_packet_type pktType, wpt_uint32 nPktSize,
145 wpalPacketLowPacketCB rxLowCB, void *usrData)
146{
147 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
148 wpt_packet* pPkt = NULL;
149 vos_pkt_t* pVosPkt = NULL;
150 void* pData = NULL;
Leo Changb419a912013-03-29 18:58:21 -0700151 v_U16_t allocLen;
Jeff Johnson295189b2012-06-20 16:38:30 -0700152 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
153
Jeff Johnson295189b2012-06-20 16:38:30 -0700154 switch (pktType)
155 {
156 case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT:
157 vosStatus = vos_pkt_get_packet(&pVosPkt, VOS_PKT_TYPE_TX_802_11_MGMT,
158 nPktSize, 1, VOS_FALSE,
159 NULL, NULL /*no callback*/);
160 break;
161
162 case eWLAN_PAL_PKT_TYPE_RX_RAW:
Mihir Sheteb20fd742013-12-31 12:41:35 +0530163 /* Set the wpalPacketAvailableCB before we try to get a VOS
164 * packet from the 'free list' and reset it if vos_pkt_get_packet()
165 * returns a valid packet. This order is required to avoid the
166 * race condition:
167 * 1. The below call to vos_pkt_get_packet() in RX_Thread determines
168 * that no more packets are available in the 'free list' and sets
169 * the low resource callbacks.
170 * 2. in parallel vos_pkt_return_packet() is called in MC_Thread for a
171 * Management frame before wpalPacketAlloc() gets a chance to set
172 * wpalPacketAvailableCB and since the 'low resource callbacks'
173 * are set the callback function - wpalPacketRXLowResourceCB is
174 * executed,but since wpalPacketAvailableCB is still NULL the low
175 * resource recovery fails.
176 */
177 wpalPacketAvailableCB = rxLowCB;
178
Jeff Johnson295189b2012-06-20 16:38:30 -0700179 vosStatus = vos_pkt_get_packet(&pVosPkt, VOS_PKT_TYPE_RX_RAW,
180 nPktSize, 1, VOS_FALSE,
181 wpalPacketRXLowResourceCB, usrData);
182
183#ifndef FEATURE_R33D
184 /* Reserve the entire raw rx buffer for DXE */
185 if( vosStatus == VOS_STATUS_SUCCESS )
186 {
Mihir Sheteb20fd742013-12-31 12:41:35 +0530187 wpalPacketAvailableCB = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700188 vosStatus = vos_pkt_reserve_head_fast( pVosPkt, &pData, nPktSize );
189 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700190#endif /* FEATURE_R33D */
Leo Chang59232a82013-05-07 14:25:35 -0700191 if((NULL != pVosPkt) && (VOS_STATUS_E_RESOURCES != vosStatus))
Leo Changb419a912013-03-29 18:58:21 -0700192 {
Leo Chang59232a82013-05-07 14:25:35 -0700193 vos_pkt_get_packet_length(pVosPkt, &allocLen);
194 if (nPktSize != allocLen)
195 {
196 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
197 "RX packet alloc has problem, discard this frame, Len %d", allocLen);
198 vos_pkt_return_packet(pVosPkt);
199 return NULL;
200 }
Leo Changb419a912013-03-29 18:58:21 -0700201 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700202 break;
203
204 default:
205 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800206 " try to allocate unsupported packet type (%d)", pktType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 break;
208 }
209
210 if(VOS_IS_STATUS_SUCCESS(vosStatus))
211 {
212 pPkt = (wpt_packet *)pVosPkt;
213 }
214
215
216 return pPkt;
217}/*wpalPacketAlloc*/
218
219
220
221/*---------------------------------------------------------------------------
222 wpalPacketFree – Free a wpt_packet chain for one particular type.
223 For our legacy UMAC, it is not needed because vos_packet contains pal_packet.
224 Param:
225 pPkt – pointer to a wpt_packet
226 Return:
227 eWLAN_PAL_STATUS_SUCCESS - success
228---------------------------------------------------------------------------*/
229wpt_status wpalPacketFree(wpt_packet *pPkt)
230{
231 VOS_STATUS vosStatus;
232
233 if(NULL != pPkt->pInternalData)
234 {
235 wpalMemoryFree(pPkt->pInternalData);
236 }
237 vosStatus = vos_pkt_return_packet(WPAL_TO_VOS_PKT(pPkt));
238
239 //With VOSS support, we can cast between wpt_status and VOS_STATUS
240 return (wpt_status)vosStatus;
241}/*wpalPacketFree*/
242
243
244/*---------------------------------------------------------------------------
245 wpalPacketGetLength – Get number of bytes in a wpt_packet. It include the
246 bytes in a BD if it exist.
247 Param:
248 pPkt - pointer to a packet to be freed.
249 Return:
250 Length of the data include layer-2 headers. For example, if the frame
251 is 802.3, the length includes the ethernet header.
252---------------------------------------------------------------------------*/
253wpt_uint32 wpalPacketGetLength(wpt_packet *pPkt)
254{
255 v_U16_t len = 0, pktLen = 0;
256
257 // Validate the parameter pointers
258 if (unlikely(NULL == pPkt))
259 {
260 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700261 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 return eWLAN_PAL_STATUS_E_INVAL;
263 }
264
265
266 if( WPAL_PACKET_GET_BD_POINTER(pPkt) )
267 {
268 len = WPAL_PACKET_GET_BD_LENGTH(pPkt);
269 }
270 if( VOS_IS_STATUS_SUCCESS(vos_pkt_get_packet_length(WPAL_TO_VOS_PKT(pPkt), &pktLen)) )
271 {
272 len += pktLen;
273 }
274 else
275 {
Arif Hussain9a5d5382013-11-17 22:05:35 -0800276 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s failed",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700277 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 }
279
280 return ((wpt_uint32)len);
281}/*wpalPacketGetLength*/
282
283
284/*---------------------------------------------------------------------------
285 wpalPacketRawTrimHead – Move the starting offset and return the head pointer
286 before the moving. The function can only be used with raw packets,
287 whose buffer is one piece and allocated by WLAN driver. This also
288 reduce the length of the packet.
289 Param:
290 pPkt - pointer to a wpt_packet.
291 size – number of bytes to take off the head.
292 Return:
293 A pointer to the original buffer head before the trimming.
294---------------------------------------------------------------------------*/
295wpt_status wpalPacketRawTrimHead(wpt_packet *pPkt, wpt_uint32 size)
296{
297 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
298
299 // Validate the parameter pointers
300 if (unlikely(NULL == pPkt))
301 {
302 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700303 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 return eWLAN_PAL_STATUS_E_INVAL;
305 }
306
Manjunathappa Prakashfb585462013-12-23 19:07:07 -0800307 if ((eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) ||
308 (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt)))
309 {
310 // Continue to trim the packet
311 }
312 else
313 {
314 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
315 "%s : neither 80211 managment packet nor RAW packet", __func__);
316 VOS_ASSERT(0);
317 return eWLAN_PAL_STATUS_E_INVAL;
318 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700319
320 if( !VOS_IS_STATUS_SUCCESS(vos_pkt_trim_head(WPAL_TO_VOS_PKT(pPkt), (v_SIZE_t)size)) )
321 {
Arif Hussain9a5d5382013-11-17 22:05:35 -0800322 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s Invalid trim(%d)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700323 __func__, size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700324 status = eWLAN_PAL_STATUS_E_INVAL;
325 }
326
327 return status;
328}/*wpalPacketRawTrimHead*/
329
330/*---------------------------------------------------------------------------
331 wpalPacketRawTrimTail – reduce the length of the packet.
332 Param:
333 pPkt - pointer to a wpt_packet.
334 size – number of bytes to take of the packet length
335 Return:
336 eWLAN_PAL_STATUS_SUCCESS – success. Otherwise fail.
337---------------------------------------------------------------------------*/
338wpt_status wpalPacketRawTrimTail(wpt_packet *pPkt, wpt_uint32 size)
339{
340 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
341
342 // Validate the parameter pointers
343 if (unlikely(NULL == pPkt))
344 {
345 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700346 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700347 return eWLAN_PAL_STATUS_E_INVAL;
348 }
349
Manjunathappa Prakashfb585462013-12-23 19:07:07 -0800350 if ((eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) ||
351 (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt)))
352 {
353 // Continue to trim the packet
354 }
355 else
356 {
357 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
358 "%s : neither 80211 managment packet nor RAW packet", __func__);
359 VOS_ASSERT(0);
360 return eWLAN_PAL_STATUS_E_INVAL;
361 }
362
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 if( !VOS_IS_STATUS_SUCCESS(vos_pkt_trim_tail(WPAL_TO_VOS_PKT(pPkt), (v_SIZE_t)size)) )
364 {
Arif Hussain9a5d5382013-11-17 22:05:35 -0800365 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s Invalid trim(%d)",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700366 __func__, size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700367 status = eWLAN_PAL_STATUS_E_INVAL;
368 }
369
370 return status;
371}/*wpalPacketRawTrimTail*/
372
373
374/*---------------------------------------------------------------------------
375 wpalPacketGetRawBuf – Return the starting buffer virtual address for the RAW flat buffer
376 It is inline in hope of faster implementation for certain platform. For Winxp, it
377 will be slow.
378 Param:
379 pPkt - pointer to a wpt_packet.
380 Return:
381 NULL - fail.
382 Otherwise the address of the starting of the buffer
383---------------------------------------------------------------------------*/
384wpt_uint8 *wpalPacketGetRawBuf(wpt_packet *pPkt)
385{
386 wpt_uint8 *pRet = NULL;
387
388 // Validate the parameter pointers
389 if (unlikely(NULL == pPkt))
390 {
391 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700392 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700393 return NULL;
394 }
395
396 //Since it is a flat buffer, all we need is to get one byte of offset 0
397 if( (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt)) ||
398 (eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) )
399 {
400 vos_pkt_peek_data(WPAL_TO_VOS_PKT(pPkt), 0, (v_VOID_t**)&pRet, 1);
401 WPAL_ASSERT(NULL != pRet);
402 }
403
404 return pRet;
405}/*wpalPacketGetRawBuf*/
406
407
408/*---------------------------------------------------------------------------
409 wpalPacketSetRxLength – Set the valid data length on a RX packet. This function must
410 be called once per RX packet per receiving. It indicates the available data length from
411 the start of the buffer.
412 Param:
413 pPkt - pointer to a wpt_packet.
414 Return:
415 NULL - fail.
416 Otherwise the address of the starting of the buffer
417---------------------------------------------------------------------------*/
418wpt_status wpalPacketSetRxLength(wpt_packet *pPkt, wpt_uint32 len)
419{
420 // Validate the parameter pointers
421 if (unlikely(NULL == pPkt))
422 {
423 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700424 "%s : NULL packet pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700425 return eWLAN_PAL_STATUS_E_INVAL;
426 }
427
428 /*Only allowed for RX Raw packets */
429 if( (eWLAN_PAL_PKT_TYPE_RX_RAW != WPAL_PACKET_GET_TYPE(pPkt)))
430 {
431 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800432 "%s Invalid packet type(%d)", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700433 WPAL_PACKET_GET_TYPE(pPkt));
434 return eWLAN_PAL_STATUS_E_INVAL;
435 }
436
437 if(VOS_IS_STATUS_SUCCESS(vos_pkt_set_rx_length(WPAL_TO_VOS_PKT(pPkt), len)))
438 {
439 return eWLAN_PAL_STATUS_SUCCESS;
440 }
441 else
442 {
443 return eWLAN_PAL_STATUS_E_INVAL;
444 }
445}/*wpalPacketSetRxLength*/
446
447/*
448 Set of helper functions that will prepare packet for DMA transfer,
449 based on the type of transfer : - to and from the device
450 - following these calls the packet will be locked for DMA only,
451 CPU will not be able to modify it => the packet must be explicitly returned to
452 the CPU once the DMA transfer is complete
453*/
454WPT_STATIC WPT_INLINE void* itGetOSPktAddrForDevice( wpt_packet *pPacket )
455{
456 struct sk_buff *skb;
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530457 struct device *wcnss_device = (struct device *)gContext.devHandle;
Jeff Johnson295189b2012-06-20 16:38:30 -0700458 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530459
Jeff Johnson295189b2012-06-20 16:38:30 -0700460 if ( VOS_STATUS_SUCCESS !=
461 vos_pkt_get_os_packet(WPAL_TO_VOS_PKT(pPacket), (void**)&skb, VOS_FALSE ))
462 {
463 return NULL;
464 }
465 else
466 {
467 /*Map skb data into dma-able memory
468 (changes will be commited from cache) */
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530469 return (void*)dma_map_single( wcnss_device, skb->data, skb->len, DMA_TO_DEVICE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700470 }
471}/*itGetOSPktAddrForDevice*/
472
473WPT_STATIC WPT_INLINE void* itGetOSPktAddrFromDevice( wpt_packet *pPacket )
474{
Jeff Johnson295189b2012-06-20 16:38:30 -0700475 struct sk_buff *skb;
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530476 struct device *wcnss_device = (struct device *)gContext.devHandle;
Jeff Johnson295189b2012-06-20 16:38:30 -0700477 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530478
Jeff Johnson295189b2012-06-20 16:38:30 -0700479 if ( VOS_STATUS_SUCCESS !=
480 vos_pkt_get_os_packet(WPAL_TO_VOS_PKT(pPacket), (void**)&skb, VOS_FALSE ))
481 {
482 return NULL;
483 }
484 else
485 {
Arun Kumar Khandavalli1d0647d2014-03-26 18:16:15 +0530486 if((uintptr_t)skb->data == (uintptr_t)skb->tail)
Mihir Shete5929ea52014-02-18 00:10:36 +0530487 {
488#ifdef WLAN_BUG_ON_SKB_ERROR
489 wpalDevicePanic();
490#else
491 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_FATAL,
492 "%s: skb->data == skb->tail. Attempting recovery "
493 "skb:%p, head:%p, tail:%p, data:%p",
494 __func__, skb, skb->head, skb->tail, skb->data);
495
496 skb->data = skb->head;
497#endif
498 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700499 /*Map skb data into dma-able memory
500 (changes will be commited from cache) */
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530501 return (void*)dma_map_single( wcnss_device, skb->data, skb->len, DMA_FROM_DEVICE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700502 }
503}/*itGetOSPktAddrFromDevice*/
504
505/*
506 Set of helper functions that will return a DMA-ed packet to the CPU,
507 based on the type of transfer : - to and from the device
508*/
509WPT_STATIC WPT_INLINE void itReturnOSPktAddrForDevice( wpt_packet *pPacket, void* addr, wpt_uint32 size )
510{
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530511 struct device *wcnss_device = (struct device *)gContext.devHandle;
512
513 dma_unmap_single( wcnss_device, (dma_addr_t)addr, size, DMA_TO_DEVICE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700514}
515
516WPT_STATIC WPT_INLINE void itReturnOSPktAddrFromDevice( wpt_packet *pPacket, void* addr, wpt_uint32 size )
517{
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530518 struct device *wcnss_device = (struct device *)gContext.devHandle;
Jeff Johnson295189b2012-06-20 16:38:30 -0700519
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +0530520 dma_unmap_single( wcnss_device, (dma_addr_t)addr, size, DMA_FROM_DEVICE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700521}
522
523
524/*---------------------------------------------------------------------------
525 wpalIteratorInit – Initialize an interator by updating pCur to first item.
526 Param:
527 pIter – pointer to a caller allocated wpt_iterator
528 pPacket – pointer to a wpt_packet
529 Return:
530 eWLAN_PAL_STATUS_SUCCESS - success
531---------------------------------------------------------------------------*/
532wpt_status wpalIteratorInit(wpt_iterator *pIter, wpt_packet *pPacket)
533{
534 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
535 wpt_iterator_info* pCurInfo = NULL;
536 wpt_iterator_info* pNextInfo = NULL;
537 wpt_iterator_info* pPktInfo = NULL;
538
539 // Validate the parameter pointers
540 if (unlikely((NULL == pPacket)||(NULL==pIter)))
541 {
542 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsonbf6c4892013-11-03 19:27:59 -0800543 "%s : NULL input pointers %p %p", __func__, pPacket, pIter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700544 return eWLAN_PAL_STATUS_E_INVAL;
545 }
546
547 pPktInfo = (wpt_iterator_info*)pPacket->pInternalData;
548 if (unlikely(NULL == pPktInfo))
549 {
550 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700551 "%s : Invalid Packet Info", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700552 return eWLAN_PAL_STATUS_E_INVAL;
553 }
554
555 // if there is NO BD on this frame, then initialize the next pointer to
556 // point the first fragment.
557 if ( NULL == WPAL_PACKET_GET_BD_PHYS(pPacket) )
558 {
559 pCurInfo = pPktInfo;
560 pNextInfo = NULL;
561 }
562 else
563 {
564 /*Allocate memory for the current info*/
565 pCurInfo = wpalMemoryAllocate( sizeof(wpt_iterator_info) );
566
567 // Validate the memory allocation
568 if (unlikely(NULL == pCurInfo))
569 {
570 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700571 "%s : Failed to allocate memory ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 return eWLAN_PAL_STATUS_E_INVAL;
573 }
574
575 pCurInfo->pPhyAddr = WPAL_PACKET_GET_BD_PHYS(pPacket);
576 pCurInfo->uLen = WPAL_PACKET_GET_BD_LENGTH(pPacket);
577
578 pNextInfo = pPktInfo;
579 }
580
581 pIter->pCur = (void*)pCurInfo;
582 pIter->pNext = (void*)pNextInfo;
583 pIter->pContext = NULL;
584
585 return status;
586}/*wpalIteratorInit*/
587
588/*---------------------------------------------------------------------------
589 wpalIteratorNext – Get the address for the next item
590 Param:
591 pIter – pointer to a caller allocated wpt_iterator
592 pPacket – pointer to a wpt_packet
593 ppAddr – Caller allocated pointer to return the address of the item.
594 For DMA-able devices, this is the physical address of the item.
595 pLen – To return the number of bytes in the item.
596 Return:
597 eWLAN_PAL_STATUS_SUCCESS - success
598---------------------------------------------------------------------------*/
599wpt_status wpalIteratorNext(wpt_iterator *pIter, wpt_packet *pPacket, void **ppAddr, wpt_uint32 *pLen)
600{
601 wpt_iterator_info* pCurInfo = NULL;
602 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
603
604 /*-------------------------------------------------------------------------
605 Sanity check
606 -------------------------------------------------------------------------*/
607 if (unlikely(( NULL == pIter )||( NULL == pPacket ) ||
608 ( NULL == ppAddr ) || ( NULL == pLen )))
609 {
610 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800611 "%s Invalid input parameters", __func__ );
Jeff Johnson295189b2012-06-20 16:38:30 -0700612 return eWLAN_PAL_STATUS_E_INVAL;
613 }
614
615 pCurInfo = (wpt_iterator_info*)pIter->pCur;
616 /*-------------------------------------------------------------------------
617 If current pointer is NULL - there is no data in the packet - return
618 -------------------------------------------------------------------------*/
619 if( pIter->pCur == NULL )
620 {
621 *ppAddr = NULL;
622 *pLen = 0;
623 return eWLAN_PAL_STATUS_SUCCESS;
624 }
625
626 /*Address and length are kept in the current field*/
627 *ppAddr = pCurInfo->pPhyAddr;
628 *pLen = pCurInfo->uLen;
629
630 if( NULL == pIter->pNext )
631 {
632 /*Save the iterator for cleanup*/
633 pPacket->pInternalData = pIter->pCur;
634 pIter->pCur = NULL;
635 }
636 else
637 {
638 /*Release the memory saved for storing the BD information*/
639 wpalMemoryFree(pCurInfo);
640
641 /*For LA - the packet is represented by maximum 2 fields of data
642 - BD and actual data from sk buff */
643 pIter->pCur = pIter->pNext;
644 pIter->pNext = NULL;
645 }
646
647 return eWLAN_PAL_STATUS_SUCCESS;
648}
649
650/*---------------------------------------------------------------------------
651 wpalLockPacketForTransfer – Map the data buffer from dma so that the
652 data is commited from cache and the cpu relinquishes
653 ownership of the buffer
654
655 Param:
656 pPacket – pointer to a wpt_packet
657
658 Return:
659 eWLAN_PAL_STATUS_SUCCESS - success
660---------------------------------------------------------------------------*/
661wpt_status wpalLockPacketForTransfer( wpt_packet *pPacket)
662{
663 void* pPhyData = NULL;
664 wpt_iterator_info* pInfo = NULL;
665 v_U16_t uLenData = 0;
666
667 // Validate the parameter pointers
668 if (unlikely(NULL == pPacket))
669 {
670 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700671 "%s : NULL input pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700672 return eWLAN_PAL_STATUS_E_INVAL;
673 }
674
675 switch(WPAL_PACKET_GET_TYPE(pPacket))
676 {
677 /* For management frames, BD is allocated by WDI, header is in raw buffer,
678 rest of the frame is also in raw buffer */
679 case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT:
680 {
681 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
682 accordingly */
683 pPhyData = (void*)itGetOSPktAddrForDevice( pPacket );
684 }
685 break;
686 /* Data packets - BD (allocated by WDI), header (in VOSS header),
687 rest of the packet (DSM items) */
688 case eWLAN_PAL_PKT_TYPE_TX_802_11_DATA:
689 case eWLAN_PAL_PKT_TYPE_TX_802_3_DATA:
690 {
691 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
692 accordingly */
693 pPhyData = (void*)itGetOSPktAddrForDevice( pPacket );
694 }
695 break;
696
697 /* For Raw RX, BD + header + rest of the packet is all contained in the raw
698 buffer */
699 case eWLAN_PAL_PKT_TYPE_RX_RAW:
700 {
701 /*RX Packets need to be DMA-ed from the device, perform DMA mapping
702 accordingly */
703 pPhyData = (void*)itGetOSPktAddrFromDevice( pPacket );
704 }
705 break;
706
707 default:
708 {
709 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700710 " WLAN_PAL: %s: Invalid packet type %d!", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 WPAL_PACKET_GET_TYPE(pPacket) );
712 WPAL_ASSERT(0);
713 return eWLAN_PAL_STATUS_E_FAILURE;
714 }
715 }
716
717 /*Get packet length*/
718 vos_pkt_get_packet_length(WPAL_TO_VOS_PKT(pPacket),&uLenData);
719
720 /*Allocate memory for the current info*/
721 pInfo = wpalMemoryAllocate( sizeof(wpt_iterator_info) );
722
723 // Validate the memory allocation
724 if (unlikely(NULL == pInfo))
725 {
726 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700727 "%s : Failed to allocate memory ", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700728 return eWLAN_PAL_STATUS_E_INVAL;
729 }
730
731 pInfo->pPhyAddr = pPhyData;
732 pInfo->uLen = uLenData;
733
734 pPacket->pInternalData = pInfo;
735 return eWLAN_PAL_STATUS_SUCCESS;
736}/*wpalLockPacketForTransfer*/
737
738/*---------------------------------------------------------------------------
739 wpalUnlockPacket – Unmap the data buffer from dma so that cpu can regain
740 ownership on it
741 Param:
742 pPacket – pointer to a wpt_packet
743
744 Return:
745 eWLAN_PAL_STATUS_SUCCESS - success
746---------------------------------------------------------------------------*/
747wpt_status wpalUnlockPacket( wpt_packet *pPacket)
748{
749
750 wpt_iterator_info* pInfo;
751
752 // Validate the parameter pointers
753 if (unlikely(NULL == pPacket))
754 {
755 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700756 "%s : NULL input pointer pPacket", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700757 return eWLAN_PAL_STATUS_E_INVAL;
758 }
759
760 pInfo = (wpt_iterator_info*)pPacket->pInternalData;
761
762 // Validate pInfo
763 if (unlikely(NULL == pInfo))
764 {
765 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700766 "%s : NULL input pointer pInfo", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 return eWLAN_PAL_STATUS_E_INVAL;
768 }
769
770 switch(WPAL_PACKET_GET_TYPE(pPacket))
771 {
772 /* For management frames, BD is allocated by WDI, header is in raw buffer,
773 rest of the frame is also in raw buffer */
774 case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT:
775 {
776 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
777 accordingly */
778 itReturnOSPktAddrForDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen);
779 }
780 break;
781 /* Data packets - BD (allocated by WDI), header (in VOSS header),
782 rest of the packet (DSM items) */
783 case eWLAN_PAL_PKT_TYPE_TX_802_11_DATA:
784 case eWLAN_PAL_PKT_TYPE_TX_802_3_DATA:
785 {
786 /*TX Packets need to be DMA-ed to the device, perform DMA mapping
787 accordingly */
788 itReturnOSPktAddrForDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen);
789 }
790 break;
791
792 /* For Raw RX, BD + header + rest of the packet is all contained in the raw
793 buffer */
794 case eWLAN_PAL_PKT_TYPE_RX_RAW:
795 {
796 /*RX Packets need to be DMA-ed from the device, perform DMA mapping
797 accordingly */
Madan Mohan Koyyalamudif850f1c2012-12-05 16:03:53 -0800798 if(NULL == pInfo->pPhyAddr)
799 {
800 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
801 " WLAN_PAL: %s: RX frame was not locked properly", __func__);
802 }
803 else
804 {
805 itReturnOSPktAddrFromDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen);
806 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700807 }
808 break;
809
810 default:
811 {
812 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700813 " WLAN_PAL: %s: Invalid packet type %d!", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700814 WPAL_PACKET_GET_TYPE(pPacket) );
815 WPAL_ASSERT(0);
816 return eWLAN_PAL_STATUS_E_FAILURE;
817 }
818 }
819
820 wpalMemoryFree(pInfo);
821 pPacket->pInternalData = NULL;
822 return eWLAN_PAL_STATUS_SUCCESS;
823}/*wpalUnlockPacket*/
824
825/*---------------------------------------------------------------------------
826 wpalIsPacketLocked – Check whether the Packet is locked for DMA.
827 Param:
828 pPacket – pointer to a wpt_packet
829
830 Return:
831 eWLAN_PAL_STATUS_SUCCESS
832 eWLAN_PAL_STATUS_E_FAILURE
833 eWLAN_PAL_STATUS_E_INVAL
834---------------------------------------------------------------------------*/
835wpt_status wpalIsPacketLocked( wpt_packet *pPacket)
836{
837
838 wpt_iterator_info* pInfo;
839
840 /* Validate the parameter pointers */
841 if (NULL == pPacket)
842 {
Gopichand Nakkala0dfe0a92013-06-19 21:50:26 +0530843 WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700844 "%s : NULL input pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700845 return eWLAN_PAL_STATUS_E_INVAL;
846 }
847
848 /* Validate pInternalData */
849 pInfo = (wpt_iterator_info*)pPacket->pInternalData;
850 return (NULL == pInfo)? eWLAN_PAL_STATUS_E_FAILURE :
851 eWLAN_PAL_STATUS_SUCCESS;
852}/*wpalIsPacketLocked*/
853
Gopichand Nakkalaa2cb10c2013-05-03 17:48:29 -0700854/*---------------------------------------------------------------------------
855 wpalGetNumRxRawPacket Query available RX RAW total buffer count
856 param:
857 numRxResource pointer of queried value
858
859 return:
860 eWLAN_PAL_STATUS_SUCCESS
861---------------------------------------------------------------------------*/
862wpt_status wpalGetNumRxRawPacket(wpt_uint32 *numRxResource)
863{
864 *numRxResource = (wpt_uint32)vos_pkt_get_num_of_rx_raw_pkts();
865
866 return eWLAN_PAL_STATUS_SUCCESS;
867}
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700868
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700869/*---------------------------------------------------------------------------
Mihir Shete058fcff2014-06-26 18:54:06 +0530870 wpalGetNumRxFreePacket Query available RX Free buffer count
871 param:
872 numRxResource pointer of queried value
873
874 return:
875 WPT_STATUS
876---------------------------------------------------------------------------*/
877wpt_status wpalGetNumRxFreePacket(wpt_uint32 *numRxResource)
878{
879 VOS_STATUS status;
880
881 status = vos_pkt_get_available_buffer_pool(VOS_PKT_TYPE_RX_RAW,
882 (v_SIZE_t *)numRxResource);
883
884 return WPAL_VOS_TO_WPAL_STATUS(status);
885}
886
887/*---------------------------------------------------------------------------
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700888 wpalPacketStallUpdateInfo – Update each channel information when stall
889 detected, also power state and free resource count
890
891 Param:
892 powerState ? WLAN system power state when stall detected
893 numFreeBd ? Number of free resource count in HW
894 channelInfo ? Each channel specific information when stall happen
895 channelNum ? Channel number update information
896
897 Return:
898 NONE
899
900---------------------------------------------------------------------------*/
901void wpalPacketStallUpdateInfo
902(
903 v_U32_t *powerState,
904 v_U32_t *numFreeBd,
905 wpt_log_data_stall_channel_type *channelInfo,
906 v_U8_t channelNum
907)
908{
909 /* Update power state when stall detected */
910 if(NULL != powerState)
911 {
912 wpalTrasportStallInfo.PowerState = *powerState;
913 }
914
915 /* Update HW free resource count */
916 if(NULL != numFreeBd)
917 {
918 wpalTrasportStallInfo.numFreeBd = *numFreeBd;
919 }
920
921 /* Update channel information */
922 if(NULL != channelInfo)
923 {
924 wpalMemoryCopy(&wpalTrasportStallInfo.dxeChannelInfo[channelNum],
925 channelInfo,
926 sizeof(wpt_log_data_stall_channel_type));
927 }
928
929 return;
930}
931
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530932#ifdef FEATURE_WLAN_DIAG_SUPPORT
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700933/*---------------------------------------------------------------------------
934 wpalPacketStallDumpLog – Trigger to send log packet to DIAG
935 Updated transport system information will be sent to DIAG
936
937 Param:
938 NONE
939
940 Return:
941 NONE
942
943---------------------------------------------------------------------------*/
944void wpalPacketStallDumpLog
945(
946 void
947)
948{
949 vos_log_data_stall_type *log_ptr = NULL;
950
951 WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_data_stall_type, LOG_TRSP_DATA_STALL_C);
952 if(log_ptr)
953 {
954 log_ptr->PowerState = wpalTrasportStallInfo.PowerState;
955 log_ptr->numFreeBd = wpalTrasportStallInfo.numFreeBd;
956 wpalMemoryCopy(&log_ptr->dxeChannelInfo[0],
957 &wpalTrasportStallInfo.dxeChannelInfo[0],
958 WPT_NUM_TRPT_CHANNEL * sizeof(vos_log_data_stall_channel_type));
959 pr_info("Stall log dump");
960 WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
961 }
962
963 return;
964}
965#endif /* FEATURE_WLAN_DIAG_SUPPORT */