1/*
2 * StaCap.c
3 *
4 * Copyright(c) 1998 - 2010 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/** \file   StaCap.c
36 *  \brief  STA capabilities module that responsible to publish STA capabilities to all others modules.
37 *
38 *  \see    StaCap.c
39 */
40
41#define __FILE_ID__  FILE_ID_86
42#include "osApi.h"
43#include "report.h"
44#include "StaCap.h"
45#include "TWDriver.h"
46#include "802_11Defs.h"
47#include "qosMngr_API.h"
48#include "Device1273.h"
49#include "smeApi.h"
50
51/**
52 * \fn     staCap_Create
53 * \brief  Create the staCap module.
54 *
55 * Allocate and clear the staCap module object.
56 *
57 * \param  hOs - Handle to Os Abstraction Layer
58 * \return Handle of the allocated object
59 * \sa     staCap_Destroy
60 */
61TI_HANDLE StaCap_Create (TI_HANDLE hOs)
62{
63	TI_HANDLE hStaCap;
64
65	/* allocate module object */
66	hStaCap = os_memoryAlloc (hOs, sizeof(TStaCap));
67
68	if (!hStaCap)
69	{
70		WLAN_OS_REPORT (("StaCap_Create():  Allocation failed!!\n"));
71		return NULL;
72	}
73
74    os_memoryZero (hOs, hStaCap, (sizeof(TStaCap)));
75
76	return (hStaCap);
77}
78
79
80/**
81 * \fn     StaCap_Destroy
82 * \brief  Destroy the module.
83 *
84 * Free the module's queues and object.
85 *
86 * \param  hStaCap - The module object
87 * \return TI_OK on success or TI_NOK on failure
88 * \sa     StaCap_Create
89 */
90TI_STATUS StaCap_Destroy (TI_HANDLE hStaCap)
91{
92    TStaCap *pStaCap = (TStaCap *)hStaCap;
93
94    /* free module object */
95	os_memoryFree (pStaCap->hOs, pStaCap, sizeof(TStaCap));
96
97    return TI_OK;
98}
99
100
101/**
102 * \fn     StaCap_Init
103 * \brief  Init required handles
104 *
105 * Init required handles and module variables.
106 *
107 * \note
108 * \param  pStadHandles  - The driver modules handles
109 * \return TI_OK on success or TI_NOK on failure
110 * \sa
111 */
112TI_STATUS StaCap_Init (TStadHandlesList *pStadHandles)
113{
114	TStaCap *pStaCap = (TStaCap *)pStadHandles->hStaCap;
115
116    pStaCap->hOs       = pStadHandles->hOs;
117    pStaCap->hReport   = pStadHandles->hReport;
118    pStaCap->hTWD      = pStadHandles->hTWD;
119    pStaCap->hQosMngr  = pStadHandles->hQosMngr;
120    pStaCap->hSme      = pStadHandles->hSme;
121
122	return TI_OK;
123}
124
125
126/**
127 * \fn     StaCap_IsHtEnable
128 * \brief  verify if HT enable\disable at the STA according to 11n_Enable init flag and Chip type
129 *
130 * \note
131 * \param  hStaCap - The module object
132 * \param  b11nEnable - pointer to enable\disable flag
133 * \return NONE
134 * \sa
135 */
136void StaCap_IsHtEnable (TI_HANDLE hStaCap, TI_BOOL *b11nEnable)
137{
138    TStaCap             *pStaCap = (TStaCap *)hStaCap;
139    TTwdHtCapabilities  *pTwdHtCapabilities;
140    paramInfo_t         tParam;
141
142    tParam.paramType = SME_DESIRED_BSS_TYPE_PARAM;
143    sme_GetParam (pStaCap->hSme, &tParam);
144
145    /* If Infra-BSS, get actual HT capabilities from TWD */
146    if (tParam.content.smeDesiredBSSType == BSS_INFRASTRUCTURE)
147    {
148        TWD_GetTwdHtCapabilities (pStaCap->hTWD, &pTwdHtCapabilities);
149        *b11nEnable = pTwdHtCapabilities->b11nEnable;
150    }
151    /* If IBSS, HT shouldn't be used */
152    else
153    {
154        *b11nEnable = TI_FALSE;
155    }
156}
157
158
159/**
160 * \fn     StaCap_GetHtCapabilitiesIe
161 * \brief  Get the desired STA HT capabilities IE. get the physical HT capabilities from TWD
162 * and build HT capabilities IE.
163 *
164 * \note
165 * \param  hStaCap - The module object
166 * \param  pRequest - pointer to request buffer\n
167 * \param  len - size of returned IE\n
168 * \return TI_OK on success or TI_NOK on failure
169 * \sa
170 */
171TI_STATUS StaCap_GetHtCapabilitiesIe (TI_HANDLE hStaCap, TI_UINT8 *pRequest, TI_UINT32 *pLen)
172{
173    TStaCap                 *pStaCap = (TStaCap *)hStaCap;
174    TTwdHtCapabilities      *pTwdHtCapabilities;
175    TI_UINT8			    *pDataBuf = pRequest;
176    TStaCapHtCapabilities   tHtCapabilities;
177    TI_BOOL                 bWmeEnable;
178
179    /* verify that WME flag enable */
180    qosMngr_GetWmeEnableFlag (pStaCap->hQosMngr, &bWmeEnable);
181    if (bWmeEnable == TI_FALSE)
182    {
183        TRACE0(pStaCap->hReport, REPORT_SEVERITY_INFORMATION, "StaCap_GetHtCapabilitiesIe: 802.11n disable due to WME init flag.\n");
184   		*pLen = 0;
185		return TI_OK;
186    }
187
188    TWD_GetTwdHtCapabilities (pStaCap->hTWD, &pTwdHtCapabilities);
189    /* verify that 802.11n flag enable */
190    if (pTwdHtCapabilities->b11nEnable == TI_FALSE)
191    {
192        TRACE0(pStaCap->hReport, REPORT_SEVERITY_INFORMATION, "StaCap_GetHtCapabilitiesIe: 802.11n disable due to 11n_Enable init flag.\n");
193   		*pLen = 0;
194		return TI_OK;
195    }
196
197    /*
198     * set TWD values to HT capabilities structure
199     *
200     * Note: all numbers after "<<" represent the position of the values in the filed according
201     * to 11n SPEC.
202     */
203    tHtCapabilities.uHtCapabilitiesInfo = ((pTwdHtCapabilities->uChannelWidth   << 1) |
204                                           (pTwdHtCapabilities->uRxSTBC         << 8) |
205                                           (pTwdHtCapabilities->uMaxAMSDU       << 11)|
206                                           (DSSS_CCK_MODE                       << 12));
207
208    tHtCapabilities.uHtCapabilitiesInfo |= ((((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_LDPC_CODING)                       ? 1 : 0) << 0) |
209                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_GREENFIELD_FRAME_FORMAT)           ? 1 : 0) << 4) |
210                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_SHORT_GI_FOR_20MHZ_PACKETS)        ? 1 : 0) << 5) |
211                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_SHORT_GI_FOR_40MHZ_PACKETS)        ? 1 : 0) << 6) |
212                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_SUPPORT_FOR_STBC_IN_TRANSMISSION)  ? 1 : 0) << 7) |
213                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_DELAYED_BLOCK_ACK)                 ? 1 : 0) << 10) |
214                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_DSSS_CCK_IN_40_MHZ)                ? 1 : 0) << 12) |
215                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_LSIG_TXOP_PROTECTION)              ? 1 : 0) << 15));
216
217    tHtCapabilities.uAMpduParam = ((pTwdHtCapabilities->uMaxAMPDU       << 0) |
218                                   (pTwdHtCapabilities->uAMPDUSpacing   << 2));
219
220    /* copy RX supported MCS rates */
221    os_memoryCopy (pStaCap->hOs, tHtCapabilities.tSuppMcsSet.aRxMscBitmask, pTwdHtCapabilities->aRxMCS, RX_TX_MCS_BITMASK_SIZE);
222
223    tHtCapabilities.tSuppMcsSet.uHighestSupportedDataRate = pTwdHtCapabilities->uRxMaxDataRate;
224
225    /* check if supported MCS rates identical to TX and RX */
226    if( 0 == os_memoryCompare(pStaCap->hOs, pTwdHtCapabilities->aRxMCS, pTwdHtCapabilities->aTxMCS, RX_TX_MCS_BITMASK_SIZE))
227    {
228        tHtCapabilities.tSuppMcsSet.uTxRxSetting = ((TX_MCS_SET_YES     <<  0) |    /* set supported TX MCS rate */
229                                                    (TX_RX_NOT_EQUAL_NO <<  1));    /* set TX&RX MCS rate are equal */
230    }
231    /* in case supported MCS rates TX different from the RX */
232    else
233    {
234        TI_UINT32 i;
235
236        /* check if there are TX MCS rates supported */
237        for (i = 0; i <= (RX_TX_MCS_BITMASK_SIZE - 1); ++i)
238        {
239            if (pTwdHtCapabilities->aTxMCS[i] != 0)
240            {
241                break;
242            }
243        }
244
245        /* TX MCS supported */
246        if(i <= (RX_TX_MCS_BITMASK_SIZE -1))
247        {
248            tHtCapabilities.tSuppMcsSet.uTxRxSetting = ((TX_MCS_SET_YES         <<  0) |    /* set supported TX MCS rates */
249                                                        (TX_RX_NOT_EQUAL_YES    <<  1));    /* set TX&RX MCS rates different */
250        }
251        /* TX MCS not supported */
252        else
253        {
254            tHtCapabilities.tSuppMcsSet.uTxRxSetting = (TX_MCS_SET_NO          <<  0);      /* set no supported TX MCS rates */
255        }
256    }
257
258    tHtCapabilities.uExteCapabilities = (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_PCO) ? 1 : 0) << 0);
259
260    if (tHtCapabilities.uExteCapabilities != 0)
261    {
262        tHtCapabilities.uExteCapabilities |= (pTwdHtCapabilities->uPCOTransTime <<  1);
263    }
264
265    tHtCapabilities.uExteCapabilities |= ((pTwdHtCapabilities->uMCSFeedback << 8) |
266                                          (HTC_SUPPORT_NO                   << 10));
267
268	tHtCapabilities.uTxBfCapabilities = 0x0;
269
270    tHtCapabilities.uAselCapabilities = 0x0;
271
272
273    /* build IE */
274    *pDataBuf       = HT_CAPABILITIES_IE_ID;
275    *(pDataBuf + 1) = DOT11_HT_CAPABILITIES_ELE_LEN;
276    COPY_WLAN_WORD(pDataBuf + 2, &(tHtCapabilities.uHtCapabilitiesInfo));
277    *(pDataBuf + 4) = tHtCapabilities.uAMpduParam;
278    os_memoryCopy (pStaCap->hOs, pDataBuf + 5, tHtCapabilities.tSuppMcsSet.aRxMscBitmask, RX_TX_MCS_BITMASK_SIZE);
279    COPY_WLAN_WORD(pDataBuf + 15, &(tHtCapabilities.tSuppMcsSet.uHighestSupportedDataRate));
280    *(pDataBuf + 17) = tHtCapabilities.tSuppMcsSet.uTxRxSetting;
281    /* clear the reserved bytes */
282    os_memoryZero (pStaCap->hOs, (pDataBuf + 18), 3);
283    COPY_WLAN_WORD(pDataBuf + 21, &(tHtCapabilities.uExteCapabilities));
284    COPY_WLAN_LONG(pDataBuf + 23, &(tHtCapabilities.uTxBfCapabilities));
285    *(pDataBuf + 27) = tHtCapabilities.uAselCapabilities;
286
287    *pLen = DOT11_HT_CAPABILITIES_ELE_LEN + sizeof(dot11_eleHdr_t);
288
289    return TI_OK;
290}
291
292