1/*
2 * txCtrlServ.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in
15 *    the documentation and/or other materials provided with the
16 *    distribution.
17 *  * Neither the name Texas Instruments nor the names of its
18 *    contributors may be used to endorse or promote products derived
19 *    from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35/****************************************************************************/
36/*                                                                          */
37/*  MODULE:     txCtrlServ.c                                                */
38/*                                                                          */
39/*  PURPOSE:    Tx services module, e.g. send-null packet.                  */
40/*              A sub-module of TxCtrl module (uses it's object).           */
41/*                                                                          */
42/****************************************************************************/
43
44#define __FILE_ID__  FILE_ID_58
45#include "paramOut.h"
46#include "osApi.h"
47#include "TWDriver.h"
48#include "report.h"
49#include "txCtrl.h"
50#include "Ethernet.h"
51#include "qosMngr_API.h"
52
53
54
55/***********************************************************************
56 *                        txCtrlServ_buildNullFrame
57 ***********************************************************************
58
59DESCRIPTION:    Build Null frame Function.
60                The function does the following:
61                -   Builds Null Data Frame, considering current QoS mode.
62
63INPUT:      hTxCtrl     - Tx Ctrl module handle (the txServ uses the txCtrl object!!).
64            pFrame      - A pointer to a buffer where the frame should be stored
65            pLength     - A pointer to a placeholder for the frame length
66
67************************************************************************/
68TI_STATUS txCtrlServ_buildNullFrame(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength)
69{
70    txCtrl_t            *pTxCtrl = (txCtrl_t *)hTxCtrl;
71    EHeaderConvertMode  qosMode = pTxCtrl->headerConverMode;
72    dot11_header_t      *pHeader; /* Note : there is no body for null frame */
73    TI_STATUS           status;
74    TI_UINT16           fc;
75
76    pHeader = (dot11_header_t*)(pFrame);
77
78    if (qosMode == HDR_CONVERT_QOS)
79    {
80        *pLength = WLAN_QOS_HDR_LEN;
81		SET_WLAN_WORD(&pHeader->qosControl, 0);     /* We are using user priority 0 (BE) so no need for shift and endianess */
82    }
83    else
84    {
85        *pLength = WLAN_HDR_LEN;
86    }
87
88
89    /* Set the Frame Control with Null Data type, QoS or non-QoS */
90    if (qosMode == HDR_CONVERT_QOS)
91        fc = DOT11_FC_DATA_NULL_QOS | DOT11_FC_TO_DS;
92    else
93        fc = DOT11_FC_DATA_NULL_FUNCTION | DOT11_FC_TO_DS;
94    COPY_WLAN_WORD(&pHeader->fc, &fc); /* copy with endianess handling. */
95
96    /* copy destination mac address */
97    status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, pHeader->address3);
98    if (status != TI_OK)
99    {
100        return TI_NOK;
101    }
102
103    /* copy source mac address */
104    status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, pHeader->address2);
105    if (status != TI_OK)
106    {
107        return TI_NOK;
108    }
109
110    /* copy BSSID (destination mac address) */
111    MAC_COPY (pHeader->address1, pHeader->address3);
112
113    return status;
114}
115
116
117/***********************************************************************
118 *                        txCtrlServ_buildWlanHeader
119 ***********************************************************************
120
121DESCRIPTION:    Build WLAN header from Ethernet header.
122
123INPUT:      hTxCtrl     - Tx Ctrl module handle (the txServ uses the txCtrl object!!).
124            pFrame      - A pointer to a buffer where the frame should be stored
125            pLength     - A pointer to a placeholder for the frame length
126
127************************************************************************/
128TI_STATUS txCtrlServ_buildWlanHeader(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength)
129{
130    txCtrl_t         *pTxCtrl = (txCtrl_t *)hTxCtrl;
131    TI_STATUS        status;
132    TMacAddr         daBssid;
133    TMacAddr         saBssid;
134    EQosProtocol     qosProt;
135    ScanBssType_e    currBssType;
136    TMacAddr         currBssId;
137    TI_UINT32        headerLength;
138    TI_UINT16        headerFlags;
139    TI_BOOL          currentPrivacyInvokedMode;
140    TI_UINT8         encryptionFieldSize;
141    TTxCtrlBlk       tPktCtrlBlk;
142    dot11_header_t   *pDot11Header = (dot11_header_t*)(tPktCtrlBlk.aPktHdr);
143    Wlan_LlcHeader_T *pWlanSnapHeader;
144
145    /*
146     * If QoS is used, add two bytes padding before the header for 4-bytes alignment.
147     * Note that the header length doesn't include it, so the txCtrl detects the pad existence
148     *   by checking if the header-length is a multiple of 4.
149     */
150    qosMngr_getParamsActiveProtocol(pTxCtrl->hQosMngr, &qosProt);
151
152    if (qosProt == QOS_WME)
153    {
154        headerLength = WLAN_QOS_HDR_LEN;
155        headerFlags  = DOT11_FC_DATA_QOS | DOT11_FC_TO_DS;
156        pDot11Header->qosControl = 0;
157    }
158    else
159    {
160        headerLength = WLAN_HDR_LEN;
161        headerFlags  = DOT11_FC_DATA | DOT11_FC_TO_DS;
162    }
163
164    /*
165     * Handle encryption if needed (decision was done at RSN and is provided by TxCtrl):
166     *   - Set WEP bit in header.
167     *   - Add padding for FW security overhead: 4 bytes for TKIP, 8 for AES.
168     */
169    txCtrlParams_getCurrentEncryptionInfo (hTxCtrl,
170                                           &currentPrivacyInvokedMode,
171                                           &encryptionFieldSize);
172    if (currentPrivacyInvokedMode)
173    {
174        headerFlags |= DOT11_FC_WEP;
175        headerLength += encryptionFieldSize;
176    }
177
178    COPY_WLAN_WORD (&pDot11Header->fc, &headerFlags); /* copy with endianess handling. */
179
180    /* Get the Destination MAC address */
181    status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, daBssid);
182    if (status != TI_OK)
183    {
184        return TI_NOK;
185    }
186
187    /* Get the Source MAC address */
188    status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, saBssid);
189    if (status != TI_OK)
190    {
191        return TI_NOK;
192    }
193
194    /* receive BssId and Bss Type from control module */
195    ctrlData_getCurrBssTypeAndCurrBssId (pTxCtrl->hCtrlData, &currBssId, &currBssType);
196    if (currBssType != BSS_INFRASTRUCTURE)
197    {
198        return TI_NOK;
199    }
200
201    /* copy BSSID */
202    MAC_COPY (pDot11Header->address1, currBssId);
203    /* copy source mac address */
204    MAC_COPY (pDot11Header->address2, saBssid);
205    /* copy destination mac address*/
206    MAC_COPY (pDot11Header->address3, daBssid);
207
208
209    /* Set the SNAP header pointer right after the other header parts handled above. */
210    pWlanSnapHeader = (Wlan_LlcHeader_T *)&(tPktCtrlBlk.aPktHdr[headerLength]);
211
212   	pWlanSnapHeader->DSAP = SNAP_CHANNEL_ID;
213   	pWlanSnapHeader->SSAP = SNAP_CHANNEL_ID;
214   	pWlanSnapHeader->Control = LLC_CONTROL_UNNUMBERED_INFORMATION;
215
216    /* add RFC1042. */
217	pWlanSnapHeader->OUI[0] = SNAP_OUI_RFC1042_BYTE0;
218	pWlanSnapHeader->OUI[1] = SNAP_OUI_RFC1042_BYTE1;
219	pWlanSnapHeader->OUI[2] = SNAP_OUI_RFC1042_BYTE2;
220
221    /* set ETH type to IP */
222    pWlanSnapHeader->Type = HTOWLANS(ETHERTYPE_IP);
223
224    /* Add the SNAP length to the total header length. */
225    headerLength += sizeof(Wlan_LlcHeader_T);
226
227    /* copy WLAN header */
228    os_memoryCopy (pTxCtrl->hOs, pFrame, tPktCtrlBlk.aPktHdr, headerLength);
229    *pLength = headerLength;
230
231    return TI_OK;
232}
233
234