Merge branch 'for-linus' of git://www.jni.nu/cris
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / otus / 80211core / amsdu.c
CommitLineData
4bd43f50
LR
1/*
2 * Copyright (c) 2007-2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "cprecomp.h"
18
19
20/************************************************************************/
21/* */
22/* FUNCTION DESCRIPTION zfGetAmsduSubFrame */
23/* Get a subframe from a-MSDU. */
24/* */
25/* INPUTS */
26/* dev : device pointer */
27/* buf : A-MSDU frame buffer */
28/* offset : offset of subframe in the A-MSDU */
29/* */
30/* OUTPUTS */
31/* NULL or subframe */
32/* */
33/* AUTHOR */
34/* Stephen Chen Atheros Communications, INC. 2007.2 */
35/* */
36/************************************************************************/
41d8532b 37zbuf_t *zfGetAmsduSubFrame(zdev_t *dev, zbuf_t *buf, u16_t *offset)
4bd43f50 38{
41d8532b
DZ
39 u16_t subframeLen;
40 u16_t amsduLen = zfwBufGetSize(dev, buf);
41 zbuf_t *newBuf;
42
43 ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
44
45 /* Verify A-MSDU length */
46 if (amsduLen < (*offset + 14))
47 return NULL;
48
49 /* Locate A-MSDU subframe by offset and verify subframe length */
50 subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
51 zmw_buf_readb(dev, buf, *offset + 13);
52
53 if (subframeLen == 0)
54 return NULL;
55
56 /* Verify A-MSDU subframe length */
57 if ((*offset+14+subframeLen) <= amsduLen) {
58 /* Allocate a new buffer */
59 newBuf = zfwBufAllocate(dev, 24+2+subframeLen);
60 if (newBuf != NULL) {
61 #ifdef ZM_ENABLE_NATIVE_WIFI
62 /* Copy and convert subframe to wlan frame format
63 * SHALL NOT INCLUDE QOS and AMSDU header.
64 * Ray 20070807 For Vista
65 */
66 zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
67 zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14,
68 subframeLen);
69 zfwBufSetSize(dev, newBuf, 24+subframeLen);
70 #else
71 /* Copy subframe to new buffer */
72 zfRxBufferCopy(dev, newBuf, buf, 0, *offset,
73 14+subframeLen);
74 zfwBufSetSize(dev, newBuf, 14+subframeLen);
75 #endif
76 /* Update offset */
77 *offset += (((14+subframeLen)+3) & 0xfffc);
78
79 /* Return buffer pointer */
80 return newBuf;
81 }
82 }
83 return NULL;
4bd43f50
LR
84}
85
86
87/************************************************************************/
88/* */
89/* FUNCTION DESCRIPTION zfDeAmsdu */
90/* De-AMSDU. */
91/* */
92/* INPUTS */
93/* dev : device pointer */
94/* buf : A-MSDU frame buffer */
95/* vap : VAP port */
96/* */
97/* OUTPUTS */
98/* None */
99/* */
100/* AUTHOR */
101/* Stephen Chen Atheros Communications, INC. 2007.2 */
102/* */
103/************************************************************************/
41d8532b 104void zfDeAmsdu(zdev_t *dev, zbuf_t *buf, u16_t vap, u8_t encryMode)
4bd43f50 105{
41d8532b
DZ
106 u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
107 zbuf_t *subframeBuf;
108 zmw_get_wlan_dev(dev);
109
110 ZM_BUFFER_TRACE(dev, buf)
111
112 if (encryMode == ZM_AES || encryMode == ZM_TKIP)
113 offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
114 else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
115 offset += ZM_SIZE_OF_IV;
116
117
118 /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
119 while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL) {
120 wd->commTally.NotifyNDISRxFrmCnt++;
121 if (wd->zfcbRecvEth != NULL) {
122 wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
123 ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
124 }
125 }
126 zfwBufFree(dev, buf, 0);
127
128 return;
4bd43f50 129}