/*
 * StaCap.c
 *
 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.      
 * All rights reserved.                                                  
 *                                                                       
 * Redistribution and use in source and binary forms, with or without    
 * modification, are permitted provided that the following conditions    
 * are met:                                                              
 *                                                                       
 *  * Redistributions of source code must retain the above copyright     
 *    notice, this list of conditions and the following disclaimer.      
 *  * Redistributions in binary form must reproduce the above copyright  
 *    notice, this list of conditions and the following disclaimer in    
 *    the documentation and/or other materials provided with the         
 *    distribution.                                                      
 *  * Neither the name Texas Instruments nor the names of its            
 *    contributors may be used to endorse or promote products derived    
 *    from this software without specific prior written permission.      
 *                                                                       
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


/** \file   StaCap.c 
 *  \brief  STA capabilities module that responsible to publish STA capabilities to all others modules.
 *  
 *  \see    StaCap.c
 */

#define __FILE_ID__  FILE_ID_86
#include "osApi.h"
#include "report.h"
#include "StaCap.h"
#include "TWDriver.h"
#include "802_11Defs.h"
#include "qosMngr_API.h"
#include "Device1273.h"
#include "smeApi.h"

/** 
 * \fn     staCap_Create 
 * \brief  Create the staCap module.
 * 
 * Allocate and clear the staCap module object.
 * 
 * \param  hOs - Handle to Os Abstraction Layer
 * \return Handle of the allocated object 
 * \sa     staCap_Destroy
 */ 
TI_HANDLE StaCap_Create (TI_HANDLE hOs)
{
	TI_HANDLE hStaCap;

	/* allocate module object */
	hStaCap = os_memoryAlloc (hOs, sizeof(TStaCap));
	
	if (!hStaCap)
	{
		WLAN_OS_REPORT (("StaCap_Create():  Allocation failed!!\n"));
		return NULL;
	}
	
    os_memoryZero (hOs, hStaCap, (sizeof(TStaCap)));

	return (hStaCap);
}


/** 
 * \fn     StaCap_Destroy
 * \brief  Destroy the module. 
 * 
 * Free the module's queues and object.
 * 
 * \param  hStaCap - The module object
 * \return TI_OK on success or TI_NOK on failure 
 * \sa     StaCap_Create
 */ 
TI_STATUS StaCap_Destroy (TI_HANDLE hStaCap)
{
    TStaCap *pStaCap = (TStaCap *)hStaCap;

    /* free module object */
	os_memoryFree (pStaCap->hOs, pStaCap, sizeof(TStaCap));
	
    return TI_OK;
}


/** 
 * \fn     StaCap_Init 
 * \brief  Init required handles 
 * 
 * Init required handles and module variables.
 * 
 * \note    
 * \param  pStadHandles  - The driver modules handles
 * \return TI_OK on success or TI_NOK on failure  
 * \sa     
 */ 
TI_STATUS StaCap_Init (TStadHandlesList *pStadHandles)
{
	TStaCap *pStaCap = (TStaCap *)pStadHandles->hStaCap;
    
    pStaCap->hOs       = pStadHandles->hOs;
    pStaCap->hReport   = pStadHandles->hReport;
    pStaCap->hTWD      = pStadHandles->hTWD;
    pStaCap->hQosMngr  = pStadHandles->hQosMngr;
    pStaCap->hSme      = pStadHandles->hSme;
    
	return TI_OK;
}


/** 
 * \fn     StaCap_IsHtEnable
 * \brief  verify if HT enable\disable at the STA according to 11n_Enable init flag and Chip type   
 * 
 * \note   
 * \param  hStaCap - The module object
 * \param  b11nEnable - pointer to enable\disable flag 
 * \return NONE 
 * \sa     
 */ 
void StaCap_IsHtEnable (TI_HANDLE hStaCap, TI_BOOL *b11nEnable)
{
    TStaCap             *pStaCap = (TStaCap *)hStaCap;
    TTwdHtCapabilities  *pTwdHtCapabilities;
    paramInfo_t         tParam;

    tParam.paramType = SME_DESIRED_BSS_TYPE_PARAM;
    sme_GetParam (pStaCap->hSme, &tParam);

    /* If Infra-BSS, get actual HT capabilities from TWD */
    if (tParam.content.smeDesiredBSSType == BSS_INFRASTRUCTURE) 
    {
        TWD_GetTwdHtCapabilities (pStaCap->hTWD, &pTwdHtCapabilities);
        *b11nEnable = pTwdHtCapabilities->b11nEnable;
    }
    /* If IBSS, HT shouldn't be used */
    else 
    {
        *b11nEnable = TI_FALSE;
    }
}


/** 
 * \fn     StaCap_GetHtCapabilitiesIe
 * \brief  Get the desired STA HT capabilities IE. get the physical HT capabilities from TWD 
 * and build HT capabilities IE. 
 * 
 * \note   
 * \param  hStaCap - The module object
 * \param  pRequest - pointer to request buffer\n 
 * \param  len - size of returned IE\n            
 * \return TI_OK on success or TI_NOK on failure 
 * \sa     
 */ 
TI_STATUS StaCap_GetHtCapabilitiesIe (TI_HANDLE hStaCap, TI_UINT8 *pRequest, TI_UINT32 *pLen)
{
    TStaCap                 *pStaCap = (TStaCap *)hStaCap;
    TTwdHtCapabilities      *pTwdHtCapabilities;
    TI_UINT8			    *pDataBuf = pRequest;
    TStaCapHtCapabilities   tHtCapabilities;
    TI_BOOL                 bWmeEnable;

    /* verify that WME flag enable */
    qosMngr_GetWmeEnableFlag (pStaCap->hQosMngr, &bWmeEnable); 
    if (bWmeEnable == TI_FALSE)
    {
        TRACE0(pStaCap->hReport, REPORT_SEVERITY_INFORMATION, "StaCap_GetHtCapabilitiesIe: 802.11n disable due to WME init flag.\n");
   		*pLen = 0;
		return TI_OK;
    }

    TWD_GetTwdHtCapabilities (pStaCap->hTWD, &pTwdHtCapabilities);
    /* verify that 802.11n flag enable */
    if (pTwdHtCapabilities->b11nEnable == TI_FALSE)
    {
        TRACE0(pStaCap->hReport, REPORT_SEVERITY_INFORMATION, "StaCap_GetHtCapabilitiesIe: 802.11n disable due to 11n_Enable init flag.\n");
   		*pLen = 0;
		return TI_OK;
    }

    /* 
     * set TWD values to HT capabilities structure 
     *
     * Note: all numbers after "<<" represent the position of the values in the filed according  
     * to 11n SPEC.
     */
    tHtCapabilities.uHtCapabilitiesInfo = ((pTwdHtCapabilities->uChannelWidth   << 1) |
                                           (pTwdHtCapabilities->uRxSTBC         << 8) |
                                           (pTwdHtCapabilities->uMaxAMSDU       << 11)|
                                           (DSSS_CCK_MODE                       << 12));

    tHtCapabilities.uHtCapabilitiesInfo |= ((((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_LDPC_CODING)                       ? 1 : 0) << 0) |
                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_GREENFIELD_FRAME_FORMAT)           ? 1 : 0) << 4) |
                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_SHORT_GI_FOR_20MHZ_PACKETS)        ? 1 : 0) << 5) |
                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_SHORT_GI_FOR_40MHZ_PACKETS)        ? 1 : 0) << 6) |
                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_SUPPORT_FOR_STBC_IN_TRANSMISSION)  ? 1 : 0) << 7) |
                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_DELAYED_BLOCK_ACK)                 ? 1 : 0) << 10) |
                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_DSSS_CCK_IN_40_MHZ)                ? 1 : 0) << 12) |
                                            (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_LSIG_TXOP_PROTECTION)              ? 1 : 0) << 15));

    tHtCapabilities.uAMpduParam = ((pTwdHtCapabilities->uMaxAMPDU       << 0) |
                                   (pTwdHtCapabilities->uAMPDUSpacing   << 2));

    /* copy RX supported MCS rates */
    os_memoryCopy (pStaCap->hOs, tHtCapabilities.tSuppMcsSet.aRxMscBitmask, pTwdHtCapabilities->aRxMCS, RX_TX_MCS_BITMASK_SIZE);

    tHtCapabilities.tSuppMcsSet.uHighestSupportedDataRate = pTwdHtCapabilities->uRxMaxDataRate;

    /* check if supported MCS rates identical to TX and RX */
    if( 0 == os_memoryCompare(pStaCap->hOs, pTwdHtCapabilities->aRxMCS, pTwdHtCapabilities->aTxMCS, RX_TX_MCS_BITMASK_SIZE))
    {
        tHtCapabilities.tSuppMcsSet.uTxRxSetting = ((TX_MCS_SET_YES     <<  0) |    /* set supported TX MCS rate */
                                                    (TX_RX_NOT_EQUAL_NO <<  1));    /* set TX&RX MCS rate are equal */
    } 
    /* in case supported MCS rates TX different from the RX */
    else
    {
        TI_UINT32 i;

        /* check if there are TX MCS rates supported */
        for (i = 0; i <= (RX_TX_MCS_BITMASK_SIZE - 1); ++i) 
        {
            if (pTwdHtCapabilities->aTxMCS[i] != 0)
            {
                break;
            }
        }

        /* TX MCS supported */
        if(i <= (RX_TX_MCS_BITMASK_SIZE -1))
        {
            tHtCapabilities.tSuppMcsSet.uTxRxSetting = ((TX_MCS_SET_YES         <<  0) |    /* set supported TX MCS rates */    
                                                        (TX_RX_NOT_EQUAL_YES    <<  1));    /* set TX&RX MCS rates different */ 
        }
        /* TX MCS not supported */
        else
        {
            tHtCapabilities.tSuppMcsSet.uTxRxSetting = (TX_MCS_SET_NO          <<  0);      /* set no supported TX MCS rates */
        }
    }

    tHtCapabilities.uExteCapabilities = (((pTwdHtCapabilities->uHTCapabilitiesBitMask & CAP_BIT_MASK_PCO) ? 1 : 0) << 0);

    if (tHtCapabilities.uExteCapabilities != 0)
    {
        tHtCapabilities.uExteCapabilities |= (pTwdHtCapabilities->uPCOTransTime <<  1);  
    }

    tHtCapabilities.uExteCapabilities |= ((pTwdHtCapabilities->uMCSFeedback << 8) |
                                          (HTC_SUPPORT_NO                   << 10));

    tHtCapabilities.uTxBfCapabilities = ((IMPLICIT_TXBF_REC_CAPABLE             << 0) |
                                         (TRANSMIT_STAGGERED_SOUNDING_CAPABLE   << 2));

    tHtCapabilities.uAselCapabilities = 0x0;


    /* build IE */
    *pDataBuf       = HT_CAPABILITIES_IE_ID;
    *(pDataBuf + 1) = DOT11_HT_CAPABILITIES_ELE_LEN;
    COPY_WLAN_WORD(pDataBuf + 2, &(tHtCapabilities.uHtCapabilitiesInfo));
    *(pDataBuf + 4) = tHtCapabilities.uAMpduParam;
    os_memoryCopy (pStaCap->hOs, pDataBuf + 5, tHtCapabilities.tSuppMcsSet.aRxMscBitmask, RX_TX_MCS_BITMASK_SIZE);
    COPY_WLAN_WORD(pDataBuf + 15, &(tHtCapabilities.tSuppMcsSet.uHighestSupportedDataRate));
    *(pDataBuf + 17) = tHtCapabilities.tSuppMcsSet.uTxRxSetting;
    /* clear the reserved bytes */
    os_memoryZero (pStaCap->hOs, (pDataBuf + 18), 3);
    COPY_WLAN_WORD(pDataBuf + 21, &(tHtCapabilities.uExteCapabilities));
    COPY_WLAN_LONG(pDataBuf + 23, &(tHtCapabilities.uTxBfCapabilities));
    *(pDataBuf + 27) = tHtCapabilities.uAselCapabilities;

    *pLen = DOT11_HT_CAPABILITIES_ELE_LEN + sizeof(dot11_eleHdr_t);

    return TI_OK;
}

