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 */ 61 TI_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 */ 90 TI_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 */ 112 TI_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 */ 136 void 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 */ 171 TI_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