Example #1
0
/************************************************************************
 *                        buildNullTemplate								*
 ************************************************************************
DESCRIPTION: This function build a NULL data template to set to the HAL 
				when joining an infrastructure network
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildNullTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate)
{
	paramInfo_t param;
	nullDataTemplate_t *pBuffer = (nullDataTemplate_t *) pTemplate->ptr;
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	TI_UINT16 fc;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(nullDataTemplate_t));

	/*
	 * Header First
	 */
	/* Set destination address */
	MAC_COPY(pBuffer->hdr.DA, pPrimarySite->bssid);

	/* Set BSSID address */
	MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid);

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress);

	fc = DOT11_FC_DATA_NULL_FUNCTION;
	fc |= (TI_TRUE << DOT11_FC_TO_DS_SHIFT);

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	pTemplate->len = sizeof(dot11_mgmtHeader_t);
	return TI_OK;
}
Example #2
0
/************************************************************************
 *                  insertMeasurementIEToQueue							*
 ************************************************************************
DESCRIPTION: The function inserts measurement request of one received
				measurement request information element.

INPUT:      hRequestHandler	-	A Handler to the Request Handler Object.
			frameToken		-	Frame token of the received frame in which
								This current measurement request IE is included.
            measurementObjMode - XCC or SPECTRUM_MNGMNT
			dataLen			-	pointer to the data length that is left.
			pData			-	pointer to the data.

OUTPUT:		singelRequestLen - The Length of the request that was inserted
                               to the queue.

RETURN:     TI_OK on success, TI_NOK otherwise
************************************************************************/
static TI_STATUS insertMeasurementIEToQueue(TI_HANDLE           hRequestHandler,
        TI_UINT16				frameToken,
        EMeasurementMode	measurementObjMode,
        TI_UINT8				*pData,
        TI_UINT8               *singelRequestLen)
{
	requestHandler_t	*pRequestHandler = (requestHandler_t *)hRequestHandler;

	TI_UINT16		HeaderLen;
	TI_UINT8		measurementMode;
	TI_UINT8		parallelBit;
	TI_UINT8		enableBit;
	TI_UINT16       measurementToken;

	MeasurementRequest_t	*pCurrRequest = &(pRequestHandler->reqArr[pRequestHandler->numOfWaitingRequests]);

	if (pRequestHandler->parserRequestIEHdr(pData, &HeaderLen, &measurementToken) != TI_OK)
	{
		return TI_NOK;
	}

	pCurrRequest->frameToken = frameToken;
	pCurrRequest->measurementToken = measurementToken;

	pData += HeaderLen;

	/*** Getting the Measurement Mode ***/
	measurementMode		= *pData++;

	/* getting parallel bit */
	parallelBit = measurementMode & 0x1;

	/* getting Enable bit */
	enableBit = (measurementMode & 0x2)>>1;

	/* checking enable bit, the current implementation does not support
		enable bit which set to one, so there is no need to check request/report bits	*/
	if (enableBit == 1)
		return TI_OK;

	pCurrRequest->isParallel = parallelBit;


	/* Getting the Measurement Mode */
	pCurrRequest->Type = (EMeasurementType)(*pData++);

	/* Inserting the request that is included in the current measurement request IE. */
	pCurrRequest->channelNumber = *pData++;

	pCurrRequest->ScanMode = (EMeasurementScanMode)(*pData++); /* IN dot11h - Spare = 0 */

	COPY_WLAN_WORD(&pCurrRequest->DurationTime, pData);

	*singelRequestLen = HeaderLen + 6;

	pRequestHandler->numOfWaitingRequests ++;

	return TI_OK;
}
Example #3
0
/************************************************************************
 *                        buildQosNullDataTemplate							*
 ************************************************************************
DESCRIPTION: This function build a qos null data template
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		
			pSsid		-	Desired SSID

OUTPUT:		

RETURN:     TI_OK
************************************************************************/
TI_STATUS buildQosNullDataTemplate(siteMgr_t * pSiteMgr,
				   TSetTemplate * pTemplate,
				   TI_UINT8 userPriority)
{
	paramInfo_t param;
	TI_UINT32 size;
	QosNullDataTemplate_t *pBuffer =
	    (QosNullDataTemplate_t *) pTemplate->ptr;
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	TI_UINT16 fc;
	TI_UINT16 qosControl;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(QosNullDataTemplate_t));

	/*
	 * Header First
	 */
	/* Set destination address */
	if (pPrimarySite) {
		MAC_COPY(pBuffer->hdr.address1, pPrimarySite->bssid);

		/* Set BSSID address */
		MAC_COPY(pBuffer->hdr.address3, pPrimarySite->bssid);
	} else {
		TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION,
		       "No Primary site so cannot fill QosNullData template\n");
	}

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.address2, param.content.ctrlDataDeviceMacAddress);

	fc = DOT11_FC_DATA_NULL_QOS | (1 << DOT11_FC_TO_DS_SHIFT);
	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	qosControl = (TI_UINT16) userPriority;
	qosControl <<= QOS_CONTROL_UP_SHIFT;
	COPY_WLAN_WORD(&pBuffer->hdr.qosControl, &qosControl);	/* copy with endianess handling. */

	size = WLAN_QOS_HDR_LEN;

	pTemplate->len = size;

	return TI_OK;
}
Example #4
0
/************************************************************************
 *                        buildPsPollTemplate							*
 ************************************************************************
DESCRIPTION: This function build a ps poll template
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		
			pSsid		-	Desired SSID

OUTPUT:		

RETURN:     TI_OK
************************************************************************/
TI_STATUS buildPsPollTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate)
{
	paramInfo_t param;
	TTwdParamInfo tTwdParam;
	TI_UINT32 size;
	psPollTemplate_t *pBuffer = (psPollTemplate_t *) pTemplate->ptr;
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	TI_UINT16 fc;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(psPollTemplate_t));

	/*
	 * Header First
	 */

	/* Set BSSID address */
	MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid);

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.TA, param.content.ctrlDataDeviceMacAddress);

	/*
	 **   Building the Frame Control word (16 bits)
	 ** ---------------------------------------------
	 ** Type = Control
	 ** SubType = Power Save (PS) POLL,  */
	fc = DOT11_FC_PS_POLL;
	/*
	 ** setting the Power Management bit in the Frame control field
	 ** to be "Power Save mode"
	 */
	fc |= (0x1 << DOT11_FC_PWR_MGMT_SHIFT);

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	/*
	 **   Association ID
	 ** -----------------
	 */
	tTwdParam.paramType = TWD_AID_PARAM_ID;
	TWD_GetParam(pSiteMgr->hTWD, &tTwdParam);

	/* AID should have its two MSB bit Set to "1" */
	pBuffer->hdr.AID = tTwdParam.content.halCtrlAid | 0xC000;

	size = sizeof(dot11_PsPollFrameHeader_t);

	pTemplate->len = size;

	return TI_OK;
}
Example #5
0
/***********************************************************************
 *                        txCtrlServ_buildNullFrame
 ***********************************************************************

DESCRIPTION:    Build Null frame Function.
                The function does the following:
                -   Builds Null Data Frame, considering current QoS mode.

INPUT:      hTxCtrl     - Tx Ctrl module handle (the txServ uses the txCtrl object!!).
            pFrame      - A pointer to a buffer where the frame should be stored
            pLength     - A pointer to a placeholder for the frame length

************************************************************************/
TI_STATUS txCtrlServ_buildNullFrame(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength)
{
    txCtrl_t            *pTxCtrl = (txCtrl_t *)hTxCtrl;
    EHeaderConvertMode  qosMode = pTxCtrl->headerConverMode;
    dot11_header_t      *pHeader; /* Note : there is no body for null frame */
    TI_STATUS           status;
    TI_UINT16           fc;

    pHeader = (dot11_header_t*)(pFrame);

    if (qosMode == HDR_CONVERT_QOS)
    {
        *pLength = WLAN_QOS_HDR_LEN;
		SET_WLAN_WORD(&pHeader->qosControl, 0);     /* We are using user priority 0 (BE) so no need for shift and endianess */
    }
    else
    {
        *pLength = WLAN_HDR_LEN;
    }


    /* Set the Frame Control with Null Data type, QoS or non-QoS */
    if (qosMode == HDR_CONVERT_QOS)
        fc = DOT11_FC_DATA_NULL_QOS | DOT11_FC_TO_DS;
    else
        fc = DOT11_FC_DATA_NULL_FUNCTION | DOT11_FC_TO_DS;
    COPY_WLAN_WORD(&pHeader->fc, &fc); /* copy with endianess handling. */

    /* copy destination mac address */
    status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, pHeader->address3);
    if (status != TI_OK)
    {
        return TI_NOK;
    }

    /* copy source mac address */
    status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, pHeader->address2);

    if (status != TI_OK)
    {
        return TI_NOK;
    }

    /* copy BSSID (destination mac address) */
    MAC_COPY (pHeader->address1, pHeader->address3);

    return status;
}
Example #6
0
TI_STATUS mlmeBuilder_buildFrameCtrl(mlme_t* pMlme, dot11MgmtSubType_e type, TI_UINT16* pFctrl, TI_UINT8 setWepOpt)
{
	TI_UINT16	fc = 0;

	switch (type)
	{
	case ASSOC_REQUEST:
		fc |= DOT11_FC_ASSOC_REQ;
		break;
	case ASSOC_RESPONSE:
		fc |= DOT11_FC_ASSOC_RESP;
		break;
	case RE_ASSOC_REQUEST:
		fc |= DOT11_FC_REASSOC_REQ;
		break;
	case RE_ASSOC_RESPONSE:
		fc |= DOT11_FC_REASSOC_RESP;
		break;
	case DIS_ASSOC:
		fc |= DOT11_FC_DISASSOC;
		break;
	case AUTH:
		fc |= DOT11_FC_AUTH;
		break;
	case DE_AUTH:
		fc |= DOT11_FC_DEAUTH;
		break;
	case ACTION:
		fc |= DOT11_FC_ACTION;
		break;
	default:
		*pFctrl = 0;
		return TI_NOK;
	}
	
	if (setWepOpt)
	{
		fc |= DOT11_FC_WEP;
	}

	COPY_WLAN_WORD(pFctrl, &fc); /* copy with endianess handling. */

	return TI_OK;
}
Example #7
0
/************************************************************************
 *                        buildDisconnTemplate								*
 ************************************************************************
DESCRIPTION: This function build a Death/Disassoc template to set to the HAL 
				when joining an infrastructure network
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildDisconnTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate)
{
	paramInfo_t param;
	TI_UINT32 size;
	disconnTemplate_t *pBuffer = (disconnTemplate_t *) pTemplate->ptr;
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	TI_UINT16 fc;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(disconnTemplate_t));

	/*
	 * Header First
	 */
	/* Set destination address */
	MAC_COPY(pBuffer->hdr.DA, pPrimarySite->bssid);

	/* Set BSSID address */
	MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid);

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress);

	fc = DOT11_FC_DISASSOC;	/* will be change by firmware to DOT11_FC_DEAUTH if needed */

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	pBuffer->disconnReason = 0;	/* filled by firmware */

	size = sizeof(disconnTemplate_t);

	pTemplate->len = size;

	return TI_OK;
}
Example #8
0
/************************************************************************
 *                        buildArpRspTemplate							*
 ************************************************************************
DESCRIPTION: This function builds an ARP Response template to set to 
			 the HAL when joining an infrastructure network.

             The function's steps:
             - It builds the template & set the template len. 
             - If QoS is inactive, it discards the QoS Control Field.
             ** The template type is set in the site mgr.
                                           
INPUT:       pSiteMgr  - Handle to site manager.
			 pTemplate - Pointer to the template structure.

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildArpRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate,
			      TIpAddr staIp)
{
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	ArpRspTemplate_t *pBuffer = (ArpRspTemplate_t *) pTemplate->ptr;
	TI_UINT8 *ptr = (TI_UINT8 *) pBuffer;

	paramInfo_t param;	/* To get Site and QoS params */
	TI_UINT16 fc;		/* Frame Control field in MAC header */
	TI_UINT16 macAddrItr;
	TI_BOOL privacyInvoked;
	TI_UINT8 encryptionFieldSize, copyPayloadOffset, lenToCopy;

	/* Reset the buffer */
	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(ArpRspTemplate_t));

	/* Turn on the To_DS bit in the Frame Control field */
	fc = (1 << DOT11_FC_TO_DS_SHIFT);
	
	    /* Set MAC header address fields:
	       -----------------------------
	       Since To_DS is on and From_DS is off the address meaning is as follows:
	       Address1 - BSSID
	       Address2 - Source Address
	       Address3 - Destination Address
	       Address4 - Not present */
	    /* - Set BSSID */
	    if (pPrimarySite) {
		MAC_COPY(pBuffer->hdr.address1, pPrimarySite->bssid);
	} else {
		TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION,
		       "No Primary site so cannot fill QosNullData template.\n");
	}
	/* - Set Source Address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.address2, param.content.ctrlDataDeviceMacAddress);
	/* - Set Destination Address: ARP response should be sent with broadcast DA - Set accordingly */
	for (macAddrItr = 0; macAddrItr < MAC_ADDR_LEN; macAddrItr++) {
		pBuffer->hdr.address3[macAddrItr] = 0xFF;
	}

	pBuffer->LLC.DSAP = 0xaa;
	pBuffer->LLC.SSAP = 0xaa;
	pBuffer->LLC.Control = 0x03;

	/* pBuffer->LLC.Control.OUI these 3 bytes are zeroed already */
	pBuffer->LLC.Type = WLANTOHS((TI_UINT16) 0x806);
	pBuffer->hardType = WLANTOHS((TI_UINT16) 1);
	pBuffer->protType = WLANTOHS((TI_UINT16) 0x800);
	pBuffer->hardSize = 6;
	pBuffer->protSize = 4;
	pBuffer->op = WLANTOHS((TI_UINT16) 2);	/*filled as for ARP-RSP, not for RARP_RSP */

	MAC_COPY(pBuffer->StaMac, pBuffer->hdr.address2);
	IP_COPY(pBuffer->StaIp, staIp);

	pTemplate->len = sizeof(ArpRspTemplate_t);

	/* Get encryption status */
	txCtrlParams_getCurrentEncryptionInfo(pSiteMgr->hTxCtrl,
					      &privacyInvoked,
					      &encryptionFieldSize);

	/* If no encryption is used, encryptionFieldSize has garbage value */
	encryptionFieldSize = privacyInvoked ? encryptionFieldSize : 0;

	/* Set the subtype field of fc with WEP_BIT */
	fc |= (privacyInvoked << DOT11_FC_WEP_SHIFT);

	/* Get QoS type to check if QoS is active */
	param.paramType = QOS_MNGR_ACTIVE_PROTOCOL;
	qosMngr_getParams(pSiteMgr->hQosMngr, &param);

	if (param.content.qosSiteProtocol == QOS_NONE) {	/* QoS is not active */
		copyPayloadOffset =
		    sizeof(pBuffer->hdr.qosControl) +
		    AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize;
		/* Set the subtype field of fc with DATA value (non Qos) */
		fc |= DOT11_FC_DATA;
	} else {		/* QoS is active */

		copyPayloadOffset =
		    AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize;
		/* Set the subtype field of fc with DATA_QOS */
		fc |= DOT11_FC_DATA_QOS;
	}

	/* Need to copy backward to overwrite security or QoS offset */
	if (copyPayloadOffset > 0) {
		ptr = (TI_UINT8 *) & pBuffer->LLC.DSAP;
		/* Copy back the actual payload without header & security */
		lenToCopy =
		    sizeof(ArpRspTemplate_t) - sizeof(dot11_header_t) -
		    AES_AFTER_HEADER_FIELD_SIZE;

		os_memoryCopy(pSiteMgr->hOs, ptr - copyPayloadOffset, ptr,
			      lenToCopy);
		pTemplate->len -= copyPayloadOffset;
	}

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	return TI_OK;
}
Example #9
0
/************************************************************************
 *                        buildProbeRspTemplate							*
 ************************************************************************
DESCRIPTION: This function build a probe response template to set to the HAL 
				when joining an IBSS network.
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
				-	The template is built based on the chosen site attributes

			NOTE: This function is used to build beacon template too.
			The site manager set the template type (after thos function returns) to beacon or probe response accordingly.
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildProbeRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate)
{
	paramInfo_t param;
	TI_UINT8 *pBuf;
	probeRspTemplate_t *pBuffer = (probeRspTemplate_t *) pTemplate->ptr;
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	TI_INT32 i, j;
	TI_UINT32 size;
	dot11_RATES_t *pDot11Rates;
	dot11_ERP_t *pdot11Erp;
	TI_UINT32 len = 0, ofdmIndex = 0;
	TI_BOOL extRates = TI_FALSE;
	TI_BOOL useProtection, NonErpPresent, barkerPreambleType;
	TCountry *pCountry = NULL;
	TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES];
	TI_UINT32 supportedRateMask, basicRateMask;
	TI_UINT16 headerFC = DOT11_FC_PROBE_RESP;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeRspTemplate_t));

	/*
	 * Build WLAN Header:
	 * ==================
	 */

	/* Set destination address */
	for (i = 0; i < MAC_ADDR_LEN; i++)
		pBuffer->hdr.DA[i] = 0xFF;

	/* Set BSSID address */
	MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid);

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress);

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &headerFC);

	size = sizeof(dot11_mgmtHeader_t);
	pBuf = (TI_UINT8 *) pBuffer->timeStamp;
	/*
	 * Fixed Fields
	 */
	/* we skip the timestamp field */
	size += TIME_STAMP_LEN;
	pBuf += TIME_STAMP_LEN;

	/* Beacon interval */
	COPY_WLAN_WORD(pBuf, &pPrimarySite->beaconInterval);
	size += FIX_FIELD_LEN;
	pBuf += FIX_FIELD_LEN;

	/* capabilities */
	COPY_WLAN_WORD(pBuf, &pPrimarySite->capabilities);
	size += FIX_FIELD_LEN;
	pBuf += FIX_FIELD_LEN;

	/*
	 * Build Informataion Elements:
	 * ============================
	 */

	/* SSID IE */
	/* It looks like it never happens. Anyway decided to check */
	if (pPrimarySite->ssid.len > MAX_SSID_LEN) {
		TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeRspTemplate. pPrimarySite->ssid.len=%d exceeds the limit %d\n",
		       pPrimarySite->ssid.len, MAX_SSID_LEN);
		handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
		return TI_NOK;
	}
	((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID;
	((dot11_SSID_t *) (pBuf))->hdr[1] = pPrimarySite->ssid.len;
	os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t),
		      (void *)pPrimarySite->ssid.str, pPrimarySite->ssid.len);
	size += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len;
	pBuf += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len;

	/* Rates IE */

	pDot11Rates = (dot11_RATES_t *) pBuf;

	if (pPrimarySite->channel == SPECIAL_BG_CHANNEL) {
		supportedRateMask = rate_GetDrvBitmapForDefaultSupporteSet();
		basicRateMask = rate_GetDrvBitmapForDefaultBasicSet();
	} else {
		supportedRateMask =
		    pSiteMgr->pDesiredParams->siteMgrMatchedSuppRateMask;
		basicRateMask =
		    pSiteMgr->pDesiredParams->siteMgrMatchedBasicRateMask;
	}

	rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len,
			       &ofdmIndex);

	if (pSiteMgr->siteMgrOperationalMode != DOT11_G_MODE ||
	    pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER
	    || ofdmIndex == len) {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
	} else {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		extRates = TI_TRUE;
	}

	/* DS IE */
	((dot11_DS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_DS_PARAMS_ELE_ID;
	((dot11_DS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_DS_PARAMS_ELE_LEN;
	((dot11_DS_PARAMS_t *) (pBuf))->currChannel = pPrimarySite->channel;
	size += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN;
	pBuf += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN;

	/* IBSS IE */
	((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_IBSS_PARAMS_ELE_ID;
	((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_IBSS_PARAMS_ELE_LEN;
	COPY_WLAN_WORD(&((dot11_IBSS_PARAMS_t *) (pBuf))->atimWindow,
		       &pPrimarySite->atimWindow);
	size += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN;
	pBuf += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN;

	/* Country IE */
	param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM;
	regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, &param);

	if (param.content.regulatoryDomainEnabled == TI_TRUE) {
		/* get country IE */
		param.paramType = REGULATORY_DOMAIN_COUNTRY_PARAM;
		regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, &param);
		pCountry = param.content.pCountry;

		/* Check if a country IE was found */
		if (pCountry != NULL) {
			*pBuf = DOT11_COUNTRY_ELE_ID;
			pBuf++;
			size++;
			*pBuf = (TI_UINT8) (pCountry->len);
			pBuf++;
			size++;

			/* Note: The country structure is not byte-aligned so it is copied as follows to ensure
			   that there are no gaps in the output structure (pBuf). */

			os_memoryCopy(pSiteMgr->hOs, pBuf,
				      &pCountry->countryIE.CountryString,
				      DOT11_COUNTRY_STRING_LEN);
			pBuf += DOT11_COUNTRY_STRING_LEN;
			size += DOT11_COUNTRY_STRING_LEN;

			/* Loop on all tripletChannels. Each item has three fields ('i' counts rows and 'j' counts bytes). */
			for (i = 0, j = 0;
			     j < (pCountry->len - DOT11_COUNTRY_STRING_LEN);
			     i++, j += 3) {
				*(pBuf + j) =
				    pCountry->countryIE.tripletChannels[i].
				    firstChannelNumber;
				*(pBuf + j + 1) =
				    pCountry->countryIE.tripletChannels[i].
				    maxTxPowerLevel;
				*(pBuf + j + 2) =
				    pCountry->countryIE.tripletChannels[i].
				    numberOfChannels;
			}

			pBuf += (pCountry->len - DOT11_COUNTRY_STRING_LEN);
			size += (pCountry->len - DOT11_COUNTRY_STRING_LEN);
		}
	}

	/*ERP IE */
	siteMgr_IsERP_Needed(pSiteMgr, &useProtection, &NonErpPresent,
			     &barkerPreambleType);
	if (useProtection || NonErpPresent || barkerPreambleType) {
		pdot11Erp = (dot11_ERP_t *) pBuf;
		pdot11Erp->hdr[0] = DOT11_ERP_IE_ID;
		pdot11Erp->hdr[1] = 1;
		pdot11Erp->ctrl = 0;
		if (NonErpPresent)
			pdot11Erp->ctrl |= ERP_IE_NON_ERP_PRESENT_MASK;
		if (useProtection)
			pdot11Erp->ctrl |= ERP_IE_USE_PROTECTION_MASK;
		if (barkerPreambleType)
			pdot11Erp->ctrl |= ERP_IE_BARKER_PREAMBLE_MODE_MASK;
		size += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t);

	}

	/* Extended supported rates IE */
	if (extRates) {
		pDot11Rates = (dot11_RATES_t *) pBuf;
		pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len - ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
	}

	/* no need to insert RSN information elements */

	pTemplate->len = size;
	TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION,
	       "Probe response template len = %d\n", size);

	return TI_OK;
}
Example #10
0
/************************************************************************
 *                        buildProbeReqTemplate							*
 ************************************************************************
DESCRIPTION: This function build a probe request template to set to the HAL in the scan process.
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		
			pSsid		-	Desired SSID

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildProbeReqTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate,
				TSsid * pSsid, ERadioBand radioBand)
{
	paramInfo_t param;
	char *pBuf;
	int i;
	probeReqTemplate_t *pBuffer = (probeReqTemplate_t *) pTemplate->ptr;
	TI_UINT32 size;
	dot11_RATES_t *pDot11Rates;
	TI_UINT32 len = 0, ofdmIndex = 0;
	TI_UINT32 suppRatesLen, extSuppRatesLen;
	TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES];
	TI_UINT8 WSCOuiIe[DOT11_OUI_LEN] = { 0x00, 0x50, 0xf2, 0x04 };
	TI_UINT32 supportedRateMask, basicRateMask;
	TI_UINT16 fc = DOT11_FC_PROBE_REQ;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeReqTemplate_t));

	/*
	 * Header First
	 */
	/* Set destination address */
	for (i = 0; i < MAC_ADDR_LEN; i++)
		pBuffer->hdr.DA[i] = 0xFF;

	/* Set BSSID address */

	for (i = 0; i < MAC_ADDR_LEN; i++)
		pBuffer->hdr.BSSID[i] = 0xFF;

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress);

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	size = sizeof(dot11_mgmtHeader_t);
	pBuf = (char *)&(pBuffer->infoElements);

	/*
	 * Informataion elements
	 */
	/* SSID */
	/* It looks like it never happens. Anyway decided to check */
	if (pSsid->len > MAX_SSID_LEN) {
		TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeReqTemplate. pSsid->len=%d exceeds the limit %d\n",
		       pSsid->len, MAX_SSID_LEN);
		handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
		return TI_NOK;
	}
	((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID;
	((dot11_SSID_t *) (pBuf))->hdr[1] = pSsid->len;
	os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t),
		      (void *)pSsid->str, pSsid->len);
	size += sizeof(dot11_eleHdr_t) + pSsid->len;
	pBuf += sizeof(dot11_eleHdr_t) + pSsid->len;

	/* Rates */
	pDot11Rates = (dot11_RATES_t *) pBuf;

	/* 
	 * Supported rates in probe request will always use the default rates for BG or A bands,
	 * regardless of the STA desired rates.
	 */
	if (radioBand == RADIO_BAND_2_4_GHZ) {
		/* Basic rates: 1,2,5.5,11 */
		basicRateMask =
		    rate_BasicToDrvBitmap((EBasicRateSet)
					  (pSiteMgr->pDesiredParams->
					   siteMgrRegstryBasicRate
					   [DOT11_G_MODE]), TI_FALSE);
		/* Extended: 6,9,12,18,24,36,48,54 */
		supportedRateMask =
		    rate_SupportedToDrvBitmap((ESupportedRateSet)
					      (pSiteMgr->pDesiredParams->
					       siteMgrRegstrySuppRate
					       [DOT11_G_MODE]), TI_FALSE);
	} else if (radioBand == RADIO_BAND_5_0_GHZ) {	/* Basic rates: 6,12,24 */
		basicRateMask =
		    rate_BasicToDrvBitmap((EBasicRateSet)
					  (pSiteMgr->pDesiredParams->
					   siteMgrRegstryBasicRate
					   [DOT11_A_MODE]), TI_TRUE);
		/* Extended: 9,18,24,36,48,54 */
		supportedRateMask =
		    rate_SupportedToDrvBitmap((ESupportedRateSet)
					      (pSiteMgr->pDesiredParams->
					       siteMgrRegstrySuppRate
					       [DOT11_A_MODE]), TI_TRUE);
	} else {
		TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeReqTemplate, radioBand =%d ???\n", radioBand);
		/* Use default and pray for the best */
		/* Basic rates: 1,2,5.5,11 */
		basicRateMask =
		    rate_BasicToDrvBitmap(BASIC_RATE_SET_1_2_5_5_11, TI_FALSE);
		/* Extended: 6,9,12,18,24,36,48,54 */
		supportedRateMask =
		    rate_SupportedToDrvBitmap(SUPPORTED_RATE_SET_UP_TO_54,
					      TI_FALSE);
	}

	rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len,
			       &ofdmIndex);

	TRACE5(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION,
	       "buildProbeReqTemplate, supportedRateMask=0x%x, basicRateMask=0x%x, len=%d, ofdmIndex=%d, radioBand =%d\n",
	       supportedRateMask, basicRateMask, len, ofdmIndex, radioBand);

	/* It looks like it never happens. Anyway decided to check */
	if (len > DOT11_MAX_SUPPORTED_RATES) {
		TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeReqTemplate. len=%d exceeds the limit %d\n",
		       len, DOT11_MAX_SUPPORTED_RATES);
		handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
		return TI_NOK;
	}
	if (radioBand == RADIO_BAND_5_0_GHZ ||
	    pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER
	    || ofdmIndex == len) {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
	} else {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pDot11Rates = (dot11_RATES_t *) (pBuf + suppRatesLen);
		pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len - ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]);
		extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		size += suppRatesLen + extSuppRatesLen;
		pBuf += suppRatesLen + extSuppRatesLen;
	}

	/* add HT capabilities IE */
	StaCap_GetHtCapabilitiesIe(pSiteMgr->hStaCap, (TI_UINT8 *) pBuf, &len);
	size += len;
	pBuf += len;

	/* WiFi Simple Config */
	if (pSiteMgr->includeWSCinProbeReq
	    && (pSiteMgr->siteMgrWSCCurrMode != TIWLN_SIMPLE_CONFIG_OFF)) {
		((dot11_WSC_t *) pBuf)->hdr[0] = DOT11_WSC_PARAM_ELE_ID;
		((dot11_WSC_t *) pBuf)->hdr[1] =
		    pSiteMgr->uWscIeSize + DOT11_OUI_LEN;
		pBuf += sizeof(dot11_eleHdr_t);
		os_memoryCopy(pSiteMgr->hOs, pBuf, &WSCOuiIe, DOT11_OUI_LEN);
		os_memoryCopy(pSiteMgr->hOs,
			      pBuf + DOT11_OUI_LEN,
			      &pSiteMgr->siteMgrWSCProbeReqParams,
			      pSiteMgr->uWscIeSize);
		size +=
		    sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize +
		    DOT11_OUI_LEN;
		pBuf +=
		    sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize +
		    DOT11_OUI_LEN;
	}

	pTemplate->len = size;

	return TI_OK;
}
Example #11
0
/**
 * \fn     RxQueue_ReceivePacket()
 * \brief  Main function of the RxQueue module.
 * Responsible on reorder of the packets from the RxXfer to the RX module.
 * Call from RxXfer in order to pass packet to uppers layers.
 * In order to save disordered packets the module use array of structures per TID
 * that each entry describe a packet. The array elements is sorted in the way that
 * the winStart array index represent always the winStart packet and the lowest SN.
 * Each increment index represent index at the BA window. Array index winEnd  always
 * represent winEnd packet. The indexes of winStart and winEnd handled in cyclic manner.
 *
 * SN range      :  0 - 4095
 * winStart range:  0 - 7       [0 - (RX_QUEUE_ARRAY_SIZE - 1)]
 * winSize       :  Determined by the BA session. We limit it to maximum 8 [RX_QUEUE_ARRAY_SIZE]
 * winEnd        :  = winStart + winSize - 1
 *
 * The function functionality devided to parts:
 *   Part 1:
 * In case the module received a packet with SN equal to the expected SN:
 * "	pass it to upper layers
 * "	increases winStart and array index winStart
 * "	validate that all sequential queue packet are pass to the upper layers.
 *   Part 2:
 * In case the module received a packet with SN between winStart to winEnd:
 * "	Save it sorted at the array at index: Save index = ((SN - winStart) + index array winStart) % arraySize.
 *   Part 3:
 * In case the module received a packet with SN higher than winEnd:
 * "	Update winStart and WinEnd.
 * "	Save it sorted at the array in index winEnd index.
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 *   Part 4 + 5:
 * In case the module received a BA event packet: [Remember: This is an Rx module - We expect BAR and not BA (as well as ADDBE / DELBA]
 * "	Update winStart and WinEnd
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 * "	Free BA event packet via pass it to upper layers with error status.
 *
 * \note
 * \param  hRxQueue - RxQueue handle.
 * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
 * \param  pBuffer - paket address of the packet [contains the RxIfDescriptor_t added by the FW].
 * \return None
 * \sa
 */
void RxQueue_ReceivePacket (TI_HANDLE hRxQueue, const void * pBuffer)
{
	TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
	RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
	TI_UINT8            *pFrame     = RX_BUF_DATA((TI_UINT8 *)pBuffer);
	TI_STATUS            tStatus    = TI_OK;
	dot11_header_t      *pHdr       = (dot11_header_t *)pFrame;
	TI_UINT16		     uQosControl;


	COPY_WLAN_WORD(&uQosControl, &pHdr->qosControl); /* copy with endianess handling. */



	/*
	 * Retrieving the TAG from the packet itself and not from the Rx Descriptor since by now it is not correct.
	 * If the packet is a QoS packet but the tag is not TAG_CLASS_QOS_DATA or TAG_CLASS_AMSDU - force TAG_CLASS_QOS_DATA or TAG_CLASS_AMSDU.
	 *
	 * Note: in the DR TAG_CLASS_EAPOL packet handled as TAG_CLASS_QOS_DATA
	 */
	if (IS_QOS_FRAME(*(TI_UINT16*)pFrame) && (pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU)) {


		/* Get AMSDU bit from frame */
		if ( uQosControl & DOT11_QOS_CONTROL_FIELD_A_MSDU_BITS) {
			pRxParams->packet_class_tag = TAG_CLASS_AMSDU;
		} else {
			pRxParams->packet_class_tag = TAG_CLASS_QOS_DATA;
		}
	}



	/*
	 * packet doesn't need reorder ?
	 */

	if ((pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_BA_EVENT) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU)) {

		RxQueue_PassPacket (pRxQueue, TI_OK, pBuffer);

		return;
	}



	/*
	 * pRxParams->type == TAG_CLASS_QOS_DATA ?
	 */

	if ((pRxParams->packet_class_tag == TAG_CLASS_QOS_DATA) || (pRxParams->packet_class_tag == TAG_CLASS_AMSDU)) {
		TI_UINT8            uFrameTid;
		TI_UINT16           uFrameSn;
		TI_UINT16		    uSequenceControl;
		TRxQueueTidDataBase *pTidDataBase;


		/* Get TID from frame */
		uFrameTid = uQosControl & DOT11_QOS_CONTROL_FIELD_TID_BITS;


		/* TID illegal value ? */
		if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS) {

			RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

			return;
		}

		/* Set the SA Tid pointer */
		pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);

		/* TID legal value */
		/* Packet TID BA session not established ? */
		if (pTidDataBase->aTidBaEstablished != TI_TRUE) {
			RxQueue_PassPacket (pRxQueue, TI_OK, pBuffer);

			return;
		}


		/* If we got here - Packet TID BA established */

		/* Get Sequence Number from frame */
		COPY_WLAN_WORD(&uSequenceControl, &pHdr->seqCtrl); /* copy with endianess handling. */
		uFrameSn = (uSequenceControl & DOT11_SC_SEQ_NUM_MASK) >> 4;


		/*
		 * Note:
		 * The FW never sends packet, in establish TID BA, with SN less than ESN !!!
		 */


		/* Part 1 - Received Frame Sequence Number is the expected one ? */
		if (uFrameSn == pTidDataBase->aTidExpectedSn) {


			/*
			   If the expected SN received and timer was running - Stop the timer.

			   If we wait for more than one packet we should not stop the timer - This is why we are checking after the while loop, if we have
			   more packets stored, and if we have, we start the timer again.
			*/
			if (pTidDataBase->uMissingPktTimeStamp != 0xffffffff) {
				StopMissingPktTimer(pRxQueue, uFrameTid);
			}

			/* Pass the packet */
			RxQueue_PassPacket (pRxQueue, TI_OK, pBuffer);

			/* Increase expected SN to the next */
			pTidDataBase->aTidExpectedSn++;
			pTidDataBase->aTidExpectedSn &= 0xfff;  /* SN is 12 bits long */

			/* Increase the ArrayInex to the next */
			pTidDataBase->aWinStartArrayInex++;

			/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
			pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;


			/* Pass all saved queue consecutive packets with SN higher than the expected one */
			while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL) {

				RxQueue_PassPacket (pRxQueue,
				                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
				                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

				pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

				pTidDataBase->aWinStartArrayInex++;

				/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
				pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

				pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xfff; /* SN is 12 bits long */

				/* Decrease the packets in queue */
				pTidDataBase->uStoredPackets--;
			}


			/* aTidExpectedSn % 0xfff in order to tack care of wrap around */
			pTidDataBase->aTidExpectedSn &= 0xfff;

			/* If there are still packets stored in the queue - start timer */
			if (pTidDataBase->uStoredPackets) {
				StartMissingPktTimer(pRxQueue, uFrameTid);
			}

			return;
		}


		/* Frame Sequence Number is lower than Expected sequence number (ISN) ? */
		if (! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn)) {
			/* WLAN_OS_REPORT(("%s: ERROR - SN=%u is less than ESN=%u\n", __FUNCTION__, uFrameSn, pTidDataBase->aTidExpectedSn)); */

			RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

			return;
		}


		/* Part 2 - Frame Sequence Number between winStart and winEnd ? */
		if ((BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn)) &&
		                /* mean: uFrameSn <= pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize) */
		                ( ! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn,(pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1)))) {
			TI_UINT16 uSaveIndex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);

			/* uSaveIndex % RX_QUEUE_ARRAY_SIZE */
			uSaveIndex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;


			/* Before storing packet in queue, make sure the place in the queue is vacant */
			if (pTidDataBase->aPaketsQueue[uSaveIndex].pPacket == NULL) {

				/* Store the packet in the queue */
				pTidDataBase->aPaketsQueue[uSaveIndex].tStatus  = tStatus;
				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket  = (void *)pBuffer;
				pTidDataBase->aPaketsQueue[uSaveIndex].uFrameSn = uFrameSn;

				pTidDataBase->uStoredPackets++;


				/* Start Timer */
				StartMissingPktTimer(pRxQueue, uFrameTid);
			} else {

				RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
				return;
			}

			return;
		}


		/*
		Part 3 - Frame Sequence Number higher than winEnd ?
		*/
		if ( BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, (pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1)) ) {
			TI_UINT32 i;
			TI_UINT16 uNewWinStartSn = (uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidWinSize + 1) & SEQ_NUM_MASK;
			TI_UINT16 uSaveIndex;


			/* stop timer */
			if (pTidDataBase->uMissingPktTimeStamp != 0xffffffff) {
				StopMissingPktTimer(pRxQueue, uFrameTid);
			}

			/* Increase the ArrayInex to the next */
			pTidDataBase->aWinStartArrayInex++;

			/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
			pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

			/* Update the Expected SN since the current one is lost */
			pTidDataBase->aTidExpectedSn++;
			pTidDataBase->aTidExpectedSn &= 0xFFF;

			/* Pass all saved queue packets with SN lower than the new win start */
			for (i = 0;
			        BA_SESSION_IS_A_BIGGER_THAN_B(uNewWinStartSn,pTidDataBase->aTidExpectedSn) &&
			        (i < RX_QUEUE_ARRAY_SIZE) &&
			        (i < pTidDataBase->aTidWinSize);
			        i++) {

				if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL) {
					RxQueue_PassPacket (pRxQueue,
					                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
					                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

					pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

					pTidDataBase->uStoredPackets--;
				}

				pTidDataBase->aWinStartArrayInex++;

				/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
				pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

				pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xFFF;

			}


			/* Calculate the new Expected SN */
			if (i == pTidDataBase->aTidWinSize) {
				pTidDataBase->aTidExpectedSn = uNewWinStartSn;
			} else {
				/* In case the uWinStartDelta lower than aTidWinSize - check if there are packets stored in Array */

				while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL) {

					RxQueue_PassPacket ( pRxQueue,
					                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
					                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket
					                   );

					pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

					pTidDataBase->aWinStartArrayInex++;

					/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
					pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

					pTidDataBase->aTidExpectedSn++;
					pTidDataBase->aTidExpectedSn &= 0xFFF;


					pTidDataBase->uStoredPackets--;
				}
			}


			if (pTidDataBase->aTidExpectedSn == uFrameSn) {
				/* pass the packet */
				RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

				pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xfff;
			} else {
				uSaveIndex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);


				/* uSaveIndex % RX_QUEUE_ARRAY_SIZE */
				uSaveIndex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

				/* Save the packet in the last entry of the queue */
				pTidDataBase->aPaketsQueue[uSaveIndex].tStatus = tStatus;
				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket = (void *)pBuffer;
				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket = (void *)pBuffer;

				pTidDataBase->uStoredPackets++;
			}



			/* aTidExpectedSn % 0xfff in order to take care of wrap around */
			pTidDataBase->aTidExpectedSn &= 0xfff;

			/* If there are still packets stored in the queue - start timer */
			if (pTidDataBase->uStoredPackets) {
				StartMissingPktTimer(pRxQueue, uFrameTid);
			}

			return;
		}
	}
Example #12
0
/** 
 * \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)
    {
   		*pLen = 0;
		return TI_OK;
    }

    TWD_GetTwdHtCapabilities (pStaCap->hTWD, &pTwdHtCapabilities);
    /* verify that 802.11n flag enable */
    if (pTwdHtCapabilities->b11nEnable == TI_FALSE)
    {
   		*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;
}
/***********************************************************************
 *                        txCtrlServ_buildWlanHeader
 ***********************************************************************

DESCRIPTION:    Build WLAN header from Ethernet header.

INPUT:      hTxCtrl     - Tx Ctrl module handle (the txServ uses the txCtrl object!!).
            pFrame      - A pointer to a buffer where the frame should be stored
            pLength     - A pointer to a placeholder for the frame length

************************************************************************/
TI_STATUS txCtrlServ_buildWlanHeader(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength)
{
    txCtrl_t         *pTxCtrl = (txCtrl_t *)hTxCtrl;
    TI_STATUS        status;
    TMacAddr         daBssid;
    TMacAddr         saBssid;
    EQosProtocol     qosProt;
    ScanBssType_e    currBssType;
    TMacAddr         currBssId;
    TI_UINT32        headerLength;
    TI_UINT16        headerFlags;
    TI_BOOL          currentPrivacyInvokedMode;
    TI_UINT8         encryptionFieldSize;
    TTxCtrlBlk       tPktCtrlBlk;
    dot11_header_t   *pDot11Header = (dot11_header_t*)(tPktCtrlBlk.aPktHdr);
    Wlan_LlcHeader_T *pWlanSnapHeader;

    /* 
     * If QoS is used, add two bytes padding before the header for 4-bytes alignment.
     * Note that the header length doesn't include it, so the txCtrl detects the pad existence
     *   by checking if the header-length is a multiple of 4. 
     */
    qosMngr_getParamsActiveProtocol(pTxCtrl->hQosMngr, &qosProt);

    if (qosProt == QOS_WME)  
    {
        headerLength = WLAN_QOS_HDR_LEN;
        headerFlags  = DOT11_FC_DATA_QOS | DOT11_FC_TO_DS;
        pDot11Header->qosControl = 0;
    }
    else
    {
        headerLength = WLAN_HDR_LEN;
        headerFlags  = DOT11_FC_DATA | DOT11_FC_TO_DS;
    }

    /* 
     * Handle encryption if needed (decision was done at RSN and is provided by TxCtrl):
     *   - Set WEP bit in header.
     *   - Add padding for FW security overhead: 4 bytes for TKIP, 8 for AES.  
     */
    txCtrlParams_getCurrentEncryptionInfo (hTxCtrl, 
                                           &currentPrivacyInvokedMode,
                                           &encryptionFieldSize);
    if (currentPrivacyInvokedMode)
    {
        headerFlags |= DOT11_FC_WEP;
        headerLength += encryptionFieldSize;
    }
    
    COPY_WLAN_WORD (&pDot11Header->fc, &headerFlags); /* copy with endianess handling. */

    /* Get the Destination MAC address */
    status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, daBssid);
    if (status != TI_OK)
    {
        return TI_NOK;
    }

    /* Get the Source MAC address */
    status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, saBssid);
    if (status != TI_OK)
    {
        return TI_NOK;
    }

    /* receive BssId and Bss Type from control module */
    ctrlData_getCurrBssTypeAndCurrBssId (pTxCtrl->hCtrlData, &currBssId, &currBssType);
    if (currBssType != BSS_INFRASTRUCTURE)
    {
        return TI_NOK;
    }

    /* copy BSSID */
    MAC_COPY (pDot11Header->address1, currBssId);
    /* copy source mac address */
    MAC_COPY (pDot11Header->address2, saBssid);
    /* copy destination mac address*/
    MAC_COPY (pDot11Header->address3, daBssid);


    /* Set the SNAP header pointer right after the other header parts handled above. */
    pWlanSnapHeader = (Wlan_LlcHeader_T *)&(tPktCtrlBlk.aPktHdr[headerLength]);
    
   	pWlanSnapHeader->DSAP = SNAP_CHANNEL_ID;
   	pWlanSnapHeader->SSAP = SNAP_CHANNEL_ID;
   	pWlanSnapHeader->Control = LLC_CONTROL_UNNUMBERED_INFORMATION;

    /* add RFC1042. */
	pWlanSnapHeader->OUI[0] = SNAP_OUI_RFC1042_BYTE0;
	pWlanSnapHeader->OUI[1] = SNAP_OUI_RFC1042_BYTE1;
	pWlanSnapHeader->OUI[2] = SNAP_OUI_RFC1042_BYTE2;

    /* set ETH type to IP */
    pWlanSnapHeader->Type = HTOWLANS(ETHERTYPE_IP);

    /* Add the SNAP length to the total header length. */
    headerLength += sizeof(Wlan_LlcHeader_T);

    /* copy WLAN header */
    os_memoryCopy (pTxCtrl->hOs, pFrame, tPktCtrlBlk.aPktHdr, headerLength);
    *pLength = headerLength;

    return TI_OK;
}
Example #14
0
/** 
 * \fn     RxQueue_ReceivePacket()
 * \brief  Main function of the RxQueue module. 
 * Responsible on reorder of the packets from the RxXfer to the RX module.
 * Call from RxXfer in order to pass packet to uppers layers.
 * In order to save disordered packets the module use array of structures per TID 
 * that each entry describe a packet. The array elements is sorted in the way that 
 * the winStart array index represent always the winStar packet and the lowest SN. 
 * Each increment index represent index at the BA window. Array index winEnd  always 
 * represent winEnd packet. The indexes of winStart and winEnd handled in cyclic manner.
 * The function functionality devided to parts:
 *   Part 1: 
 * in case the modulo receive packet with SN equal to winStart: 
 * "	pass it to upper layers
 * "	increases winStart and array index winStart
 * "	validate that all sequential queue packet are pass to the upper layers.
 *   Part 2: 
 * in case the modulo receive packet that SN between winStart to winEnd: 
 * "	Save it sorted at the array at index: Save index = ((SN - winStart) + index array winStart) % arraySize.
 *   Part 3: 
 * in case the modulo receive packet that SN higher then winEnd: 
 * "	Update winStart and WinEnd. 
 * "	Save it sorted at the array in index winEnd index.
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 *   Part 4 + 5: 
 * in case the modulo receive BA event packet: 
 * "	Update winStart and WinEnd 
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 * "	Free BA event packet via pass it to upper layers with error status.
 *
 * \note   
 * \param  hRxQueue - RxQueue handle.
 * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
 * \param  pBuffer - paket address of the packet
 * \return None 
 * \sa     
 */ 
void RxQueue_ReceivePacket (TI_HANDLE hRxQueue, const void * pBuffer)
{
    TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
    RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
    TI_UINT8            *pFrame     = RX_BUF_DATA((TI_UINT8 *)pBuffer);
    TI_STATUS           tStatus     = TI_OK;
    dot11_header_t      *pHdr       = (dot11_header_t *)pFrame;
    TI_UINT16		    uQosControl;

    COPY_WLAN_WORD(&uQosControl, &pHdr->qosControl); /* copy with endianess handling. */

    /* 
     * Retrieving the TAG from the packet itself and not from the Rx Descriptor since by now it is not correct  
     * Note: in the DR TAG_CLASS_EAPOL packet handled as TAG_CLASS_QOS_DATA   
     */
    if (IS_QOS_FRAME(*(TI_UINT16*)pFrame) && (pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
	{
        TRACE1(pRxQueue->hReport, REPORT_SEVERITY_WARNING, "RxQueue_ReceivePacket: BAD CLASS TAG =0x%x from FW.\n", pRxParams->packet_class_tag);
		
        /* Get AMSDU bit from frame */
        if( uQosControl & DOT11_QOS_CONTROL_FIELD_A_MSDU_BITS)
        {
            pRxParams->packet_class_tag = TAG_CLASS_AMSDU;
        }
        else
        {
            pRxParams->packet_class_tag = TAG_CLASS_QOS_DATA;
        }
	}

    /* 
     * packet doesn't need reorder ? 
     */
    if ((pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_BA_EVENT) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
    {
        TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_ReceivePacket: pass packet without reorder.\n");
        
        RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

        return;
    }


    /* 
     * pRxParams->type == TAG_CLASS_QOS_DATA ? 
     */
    if ((pRxParams->packet_class_tag == TAG_CLASS_QOS_DATA) || (pRxParams->packet_class_tag == TAG_CLASS_AMSDU))
    {
        TI_UINT8            uFrameTid;
        TI_UINT16           uFrameSn;
        TI_UINT16		    uSequenceControl;
        TRxQueueTidDataBase *pTidDataBase;
       

        /* Get TID from frame */
        uFrameTid = uQosControl & DOT11_QOS_CONTROL_FIELD_TID_BITS;

        /* TID illegal value ? */
        if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
        {
            TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: TID value too big, TID = %d. packet discarded!\n",uFrameTid);

            RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

            return;
        }

        /*set the SA Tid pointer */
        pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);

        /* TID legal value */
        /* packet TID BA not established ? */ 
        if (pTidDataBase->aTidBaEstablished != TI_TRUE)
        {
            TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");

            RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

            return;
        }

        /* packet TID BA established */
        /* Get Sequence Number from frame */
        COPY_WLAN_WORD(&uSequenceControl, &pHdr->seqCtrl); /* copy with endianess handling. */
        uFrameSn = (uSequenceControl & DOT11_SC_SEQ_NUM_MASK) >> 4;

        /* 
         * note: 
         * the FW never send paket, in establish TID BA, that the SN less then ESN !!! 
         */

        /* frame Sequence Number is the expected one ? */
        if (uFrameSn == pTidDataBase->aTidExpectedSn)
        {
            TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number == expected one Sequence Number.\n");

            /* pass the packet */
            RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

            pTidDataBase->aTidExpectedSn++;
            pTidDataBase->aTidExpectedSn &= 0xfff;

            /* increase the ArrayInex to the next */
            pTidDataBase->aWinStartArrayInex++;

            /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
            pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

            /* pass all saved queue packets with SN higher then the expected one */
            while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
            {
                RxQueue_PassPacket (pRxQueue, 
                                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

                pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

                pTidDataBase->aWinStartArrayInex++;

                /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
                pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

                 pTidDataBase->aTidExpectedSn++;
				 pTidDataBase->aTidExpectedSn &= 0xfff;
            }

            return;
        }

        /* frame Sequence Number is lower then Expected sequence number (ISN) ? */ 
        if (! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn))
        {
			/* WLAN_OS_REPORT(("%s: ERROR - SN=%u is less than ESN=%u\n", __FUNCTION__, uFrameSn, pTidDataBase->aTidExpectedSn)); */
			
			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_ERROR, 
				   "RxQueue_ReceivePacket: frame SN=%u is less than ESN=%u\n",uFrameSn,pTidDataBase->aTidExpectedSn);

			RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

            return;
        }

        /* frame Sequence Number between winStart and winEnd ? */
        if ((BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn)) &&
            /* mean: uFrameSn <= pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize) */
            ( ! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn,(pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1))))
        {
            TI_UINT16 uSaveInex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);  
            /* uSaveInex % RX_QUEUE_ARRAY_SIZE */
            uSaveInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK; 

          
			if (pTidDataBase->aPaketsQueue[uSaveInex].pPacket == NULL)
			{
                /* save the packet in the queue */
                pTidDataBase->aPaketsQueue[uSaveInex].tStatus = tStatus;
                pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
                pTidDataBase->aPaketsQueue[uSaveInex].uFrameSn = uFrameSn;
			}
			else
			{
 				 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: frame Sequence has allready saved. uFrameSn = %d\n",uFrameSn);

				 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
				 return;
			}
            return;
        }


        /* 
        frame Sequence Number higher then winEnd ? 
        */
        if ( BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, (pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1)) )
        {
            TI_UINT32 i;
            TI_UINT16 uNewWinStartSn = (uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidWinSize + 1) & SEQ_NUM_MASK;
            TI_UINT16 uSaveInex;
            
			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number higher then winEnd.\n");

            /* increase the ArrayInex to the next */
            pTidDataBase->aWinStartArrayInex++;

            /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
            pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

            /* update the Expected SN since the current one is lost */
            pTidDataBase->aTidExpectedSn++;
            pTidDataBase->aTidExpectedSn &= 0xFFF;

            /* pass all saved queue packets with SN lower then the new win start */
            for (i = 0;
                 BA_SESSION_IS_A_BIGGER_THAN_B(uNewWinStartSn,pTidDataBase->aTidExpectedSn) && 
                  (i < RX_QUEUE_ARRAY_SIZE) && 
                  (i < pTidDataBase->aTidWinSize);
                 i++)
            {
                if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
                {
                    RxQueue_PassPacket (pRxQueue, 
                                        pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                        pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
                }

                pTidDataBase->aWinStartArrayInex++;

                /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
                pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

                pTidDataBase->aTidExpectedSn++;
                pTidDataBase->aTidExpectedSn &= 0xFFF;

            }

            /* Calculate the new Expected SN */
            if (i == pTidDataBase->aTidWinSize)
            {
                pTidDataBase->aTidExpectedSn = uNewWinStartSn;
            }
            else
            {
                /* Incase the uWinStartDelta lower than aTidWinSize check if ther are packets stored in Array */
                while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL) {
                    RxQueue_PassPacket (pRxQueue, 
                                            pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                            pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    
                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    
                    pTidDataBase->aWinStartArrayInex++;
    
                    /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
                    pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    
                    pTidDataBase->aTidExpectedSn++;
                    pTidDataBase->aTidExpectedSn &= 0xFFF;
                }
            }

            if(pTidDataBase->aTidExpectedSn == uFrameSn)
            {
                /* pass the packet */
                RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
                pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xfff; 
            }
            else
            {
                uSaveInex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);  

				/* uSaveInex % RX_QUEUE_ARRAY_SIZE */
				uSaveInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK; 

				/* save the packet in the last entry of the queue */
				pTidDataBase->aPaketsQueue[uSaveInex].tStatus = tStatus;
				pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
				pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
            }

            return;
        }
    }
Example #15
0
TI_STATUS admCtrlWpa_getInfoElement(admCtrl_t *pAdmCtrl, TI_UINT8 *pIe, TI_UINT32 *pLength)
{
	wpaIePacket_t   localWpaPkt;
	wpaIePacket_t   *pWpaIePacket;
	TI_UINT8        length;
	TI_UINT16       tempInt;
	TI_STATUS       status;
	TIWLN_SIMPLE_CONFIG_MODE wscMode;

	/* Get Simple-Config state */
	status = siteMgr_getParamWSC(pAdmCtrl->pRsn->hSiteMgr, &wscMode); /* SITE_MGR_SIMPLE_CONFIG_MODE */

	if (pIe==NULL) {
		*pLength = 0;
		return TI_NOK;
	}

	if ((wscMode != TIWLN_SIMPLE_CONFIG_OFF) &&
	    (pAdmCtrl->broadcastSuite == TWD_CIPHER_NONE) &&
	    (pAdmCtrl->unicastSuite == TWD_CIPHER_NONE)) {
		*pLength = 0;
		return TI_NOK;
	}

	/* Check validity of WPA IE */
	if (!broadcastCipherSuiteValidity[pAdmCtrl->networkMode][pAdmCtrl->broadcastSuite]) {
		/* check Group suite validity */
		*pLength = 0;
		return TI_NOK;
	}


	if (pAdmCtrl->unicastSuite == TWD_CIPHER_WEP) {
		/* check pairwise suite validity */
		*pLength = 0;
		return TI_NOK;
	}

	/* Build Wpa IE */
	pWpaIePacket = &localWpaPkt;
	os_memoryZero(pAdmCtrl->hOs, pWpaIePacket, sizeof(wpaIePacket_t));
	pWpaIePacket->elementid= WPA_IE_ID;
	os_memoryCopy(pAdmCtrl->hOs, (void *)pWpaIePacket->oui, wpaIeOuiIe, 3);
	pWpaIePacket->ouiType = WPA_OUI_DEF_TYPE;

	tempInt = WPA_OUI_MAX_VERSION;
	COPY_WLAN_WORD(&pWpaIePacket->version, &tempInt);

	length = sizeof(wpaIePacket_t)-2;

	/* check defaults */
	if (pAdmCtrl->replayCnt==1) {
		length -= 2; /* 2: capabilities + 4: keyMng suite, 2: keyMng count*/
#if 0 /* The following was removed since there are APs which do no accept
	the default WPA IE */
			if (pAdmCtrl->externalAuthMode == RSN_EXT_AUTH_MODE_WPA) {
				length -= 6; /* 2: capabilities + 4: keyMng suite, 2: keyMng count*/
				if (pAdmCtrl->unicastSuite == TWD_CIPHER_TKIP) {
					length -= 6; /* 4: unicast suite, 2: unicast count */
					if (pAdmCtrl->broadcastSuite == TWD_CIPHER_TKIP) {
						length -= 4;  /* broadcast suite */
					}
				}
			}
#endif
	}
Example #16
0
/**
 * \fn     RxQueue_ReceivePacket()
 * \brief  Main function of the RxQueue module.
 * Responsible on reorder of the packets from the RxXfer to the RX module.
 * Call from RxXfer in order to pass packet to uppers layers.
 * In order to save disordered packets the module use array of structures per TID
 * that each entry describe a packet. The array elements is sorted in the way that
 * the winStart array index represent always the winStart packet and the lowest SN.
 * Each increment index represent index at the BA window. Array index winEnd  always
 * represent winEnd packet. The indexes of winStart and winEnd handled in cyclic manner.
 *
 * SN range      :  0 - 4095
 * winStart range:  0 - 7       [0 - (RX_QUEUE_ARRAY_SIZE - 1)]
 * winSize       :  Determined by the BA session. We limit it to maximum 8 [RX_QUEUE_ARRAY_SIZE]
 * winEnd        :  = winStart + winSize - 1
 *
 * The function functionality devided to parts:
 *   Part 1:
 * In case the module received a packet with SN equal to the expected SN:
 * "	pass it to upper layers
 * "	increases winStart and array index winStart
 * "	validate that all sequential queue packet are pass to the upper layers.
 *   Part 2:
 * In case the module received a packet with SN between winStart to winEnd:
 * "	Save it sorted at the array at index: Save index = ((SN - winStart) + index array winStart) % arraySize.
 *   Part 3:
 * In case the module received a packet with SN higher than winEnd:
 * "	Update winStart and WinEnd.
 * "	Save it sorted at the array in index winEnd index.
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 *   Part 4 + 5:
 * In case the module received a BA event packet: [Remember: This is an Rx module - We expect BAR and not BA (as well as ADDBE / DELBA]
 * "	Update winStart and WinEnd
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 * "	Free BA event packet via pass it to upper layers with error status.
 *
 * \note
 * \param  hRxQueue - RxQueue handle.
 * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
 * \param  pBuffer - paket address of the packet [contains the RxIfDescriptor_t added by the FW].
 * \return None
 * \sa
 */
void RxQueue_ReceivePacket (TI_HANDLE hRxQueue, const void * pBuffer)
{
	TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
	RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
	TI_UINT8            *pFrame     = RX_BUF_DATA((TI_UINT8 *)pBuffer);
	TI_STATUS            tStatus    = TI_OK;
	dot11_header_t      *pHdr       = (dot11_header_t *)pFrame;
	TI_UINT16		     uQosControl;


	COPY_WLAN_WORD(&uQosControl, &pHdr->qosControl); /* copy with endianess handling. */

	TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: packet_class_tag = 0x%x(%d)",pRxParams->packet_class_tag,pRxParams->packet_class_tag);


	/*
	 * Retrieving the TAG from the packet itself and not from the Rx Descriptor since by now it is not correct.
	 * If the packet is a QoS packet but the tag is not TAG_CLASS_QOS_DATA or TAG_CLASS_AMSDU - force TAG_CLASS_QOS_DATA or TAG_CLASS_AMSDU.
	 *
	 * Note: in the DR TAG_CLASS_EAPOL packet handled as TAG_CLASS_QOS_DATA
	 */
	if (IS_QOS_FRAME(*(TI_UINT16*)pFrame) && (pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
	{
		TRACE1(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: BAD CLASS TAG =0x%x from FW.\n", pRxParams->packet_class_tag);


		/* Get AMSDU bit from frame */
		if ( uQosControl & DOT11_QOS_CONTROL_FIELD_A_MSDU_BITS)
		{
			pRxParams->packet_class_tag = TAG_CLASS_AMSDU;
		}
		else
		{
			pRxParams->packet_class_tag = TAG_CLASS_QOS_DATA;
		}
	}



	/*
	 * packet doesn't need reorder ?
	 */

	if ((pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_BA_EVENT) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
	{
		TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_ReceivePacket: pass packet without reorder.\n");

		RxQueue_PassPacket (pRxQueue, TI_OK, pBuffer);

		return;
	}



	/*
	 * pRxParams->type == TAG_CLASS_QOS_DATA ?
	 */

	if ((pRxParams->packet_class_tag == TAG_CLASS_QOS_DATA) || (pRxParams->packet_class_tag == TAG_CLASS_AMSDU))
	{
		TI_UINT8            uFrameTid;
		TI_UINT16           uFrameSn;
		TI_UINT16		    uSequenceControl;
		TRxQueueTidDataBase *pTidDataBase;


		/* Get TID from frame */
		uFrameTid = uQosControl & DOT11_QOS_CONTROL_FIELD_TID_BITS;

		TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: QoS Packet received");
		TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uFrameTid = 0x%x(%d)",uFrameTid,uFrameTid);

		/* TID illegal value ? */
		if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
		{
			TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: TID value too big, TID = %d. packet discarded!\n",uFrameTid);

			RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

			return;
		}

		/* Set the SA Tid pointer */
		pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);

		/* TID legal value */
		/* Packet TID BA session not established ? */
		if (pTidDataBase->aTidBaEstablished != TI_TRUE)
		{
			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");

			RxQueue_PassPacket (pRxQueue, TI_OK, pBuffer);

			return;
		}


		/* If we got here - Packet TID BA established */

		/* Get Sequence Number from frame */
		COPY_WLAN_WORD(&uSequenceControl, &pHdr->seqCtrl); /* copy with endianess handling. */
		uFrameSn = (uSequenceControl & DOT11_SC_SEQ_NUM_MASK) >> 4;

		TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uFrameSn = 0x%x(%d)", uFrameSn, uFrameSn);
		TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn, pTidDataBase->aTidExpectedSn);

		/*
		 * Note:
		 * The FW never sends packet, in establish TID BA, with SN less than ESN !!!
		 */


		/* Part 1 - Received Frame Sequence Number is the expected one ? */
		if (uFrameSn == pTidDataBase->aTidExpectedSn)
		{
			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number == expected one Sequence Number.\n");


			/*
			   If the expected SN received and timer was running - Stop the timer.

			   If we wait for more than one packet we should not stop the timer - This is why we are checking after the while loop, if we have
			   more packets stored, and if we have, we start the timer again.
			*/
			if (pRxQueue->tPacketTimeout.bPacketMiss)
			{
				tmr_StopTimer (pRxQueue->hTimer);
				pRxQueue->tPacketTimeout.bPacketMiss = TI_FALSE;
			}


			/* Pass the packet */
			RxQueue_PassPacket (pRxQueue, TI_OK, pBuffer);

			/* Increase expected SN to the next */
			pTidDataBase->aTidExpectedSn++;
			pTidDataBase->aTidExpectedSn &= 0xfff;  /* SN is 12 bits long */

			/* Increase the ArrayInex to the next */
			pTidDataBase->aWinStartArrayInex++;

			/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
			pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;


			/* Pass all saved queue consecutive packets with SN higher than the expected one */
			while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
			{
				TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Pass all saved queue packets with SN higher than the expected one that was just received.");
				TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)", pTidDataBase->aTidExpectedSn, pTidDataBase->aTidExpectedSn);
				TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aWinStartArrayInex = 0x%x(%d)", pTidDataBase->aWinStartArrayInex, pTidDataBase->aWinStartArrayInex);

				RxQueue_PassPacket (pRxQueue,
				                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
				                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

				pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

				pTidDataBase->aWinStartArrayInex++;

				/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
				pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

				pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xfff; /* SN is 12 bits long */

				/* Decrease the packets in queue */
				pRxQueue->tPacketTimeout.aPacketsStored--;
			}


			/* aTidExpectedSn % 0xfff in order to tack care of wrap around */
			pTidDataBase->aTidExpectedSn &= 0xfff;

			/* If there are still packets stored in the queue - start timer */
			if (pRxQueue->tPacketTimeout.aPacketsStored)
			{
				tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);

				pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
				pRxQueue->tPacketTimeout.aFrameTid   = uFrameTid;
			}

			return;
		}


		/* Frame Sequence Number is lower than Expected sequence number (ISN) ? */
		if (! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn))
		{
			/* WLAN_OS_REPORT(("%s: ERROR - SN=%u is less than ESN=%u\n", __FUNCTION__, uFrameSn, pTidDataBase->aTidExpectedSn)); */
			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_WARNING, "RxQueue_ReceivePacket: frame Sequence Number (%d) is lower than expected sequence number (%d).\n", uFrameSn, pTidDataBase->aTidExpectedSn);

			RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

			return;
		}


		/* Part 2 - Frame Sequence Number between winStart and winEnd ? */
		if ((BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn)) &&
		        /* mean: uFrameSn <= pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize) */
		        ( ! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn,(pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1))))
		{
			TI_UINT16 uSaveIndex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);

			/* uSaveIndex % RX_QUEUE_ARRAY_SIZE */
			uSaveIndex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number between winStart and winEnd.\n");
			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uSaveIndex = 0x%x(%d)",uSaveIndex,uSaveIndex);

			/* Before storing packet in queue, make sure the place in the queue is vacant */
			if (pTidDataBase->aPaketsQueue[uSaveIndex].pPacket == NULL)
			{
				TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Enter packet to Reorder Queue");

				/* Store the packet in the queue */
				pTidDataBase->aPaketsQueue[uSaveIndex].tStatus  = tStatus;
				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket  = (void *)pBuffer;
				pTidDataBase->aPaketsQueue[uSaveIndex].uFrameSn = uFrameSn;

				pRxQueue->tPacketTimeout.aPacketsStored++;


				/* Start Timer [only if timer is not already started - according to bPacketMiss] */
				if (pRxQueue->tPacketTimeout.bPacketMiss == TI_FALSE)
				{
					tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
					pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
					pRxQueue->tPacketTimeout.aFrameTid   = uFrameTid;
				}
			}
			else
			{
				TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: frame Sequence has already saved. uFrameSn = %d\n", uFrameSn);

				RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
				return;
			}

			return;
		}


		/*
		Part 3 - Frame Sequence Number higher than winEnd ?
		*/
		if ( BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, (pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1)) )
		{
			TI_UINT32 i;
			TI_UINT16 uNewWinStartSn = (uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidWinSize + 1) & SEQ_NUM_MASK;
			TI_UINT16 uSaveIndex;


			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number higher than winEnd.\n");
			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uNewWinStartSn = 0x%x(%d) STOP TIMER",uNewWinStartSn,uNewWinStartSn);

			/* If timer is on - stop it */
			if (pRxQueue->tPacketTimeout.bPacketMiss)
			{
				tmr_StopTimer (pRxQueue->hTimer);
				pRxQueue->tPacketTimeout.bPacketMiss = TI_FALSE;
			}

			/* Increase the ArrayInex to the next */
			pTidDataBase->aWinStartArrayInex++;

			/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
			pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

			/* Update the Expected SN since the current one is lost */
			pTidDataBase->aTidExpectedSn++;
			pTidDataBase->aTidExpectedSn &= 0xFFF;

			/* Pass all saved queue packets with SN lower than the new win start */
			for (i = 0;
			        BA_SESSION_IS_A_BIGGER_THAN_B(uNewWinStartSn,pTidDataBase->aTidExpectedSn) &&
			        (i < RX_QUEUE_ARRAY_SIZE) &&
			        (i < pTidDataBase->aTidWinSize);
			        i++)
			{
				TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);
				TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aWinStartArrayInex = 0x%x(%d)",pTidDataBase->aWinStartArrayInex,pTidDataBase->aWinStartArrayInex);

				if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
				{
					TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send Packet to Upper layer");
					RxQueue_PassPacket (pRxQueue,
					                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
					                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

					pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

					pRxQueue->tPacketTimeout.aPacketsStored--;
				}

				pTidDataBase->aWinStartArrayInex++;

				/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
				pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

				pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xFFF;

			}

			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);
			TRACE1(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: i = %d",i);

			/* Calculate the new Expected SN */
			if (i == pTidDataBase->aTidWinSize)
			{
				TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Set aTidExpectedSn to uNewWinStartSn");
				pTidDataBase->aTidExpectedSn = uNewWinStartSn;
			}
			else
			{
				TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send all saved packets");
				/* In case the uWinStartDelta lower than aTidWinSize - check if there are packets stored in Array */

				while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
				{
					TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send packet with SN = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);

					RxQueue_PassPacket ( pRxQueue,
					                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
					                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket
					                   );

					pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

					pTidDataBase->aWinStartArrayInex++;

					/* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
					pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

					pTidDataBase->aTidExpectedSn++;
					pTidDataBase->aTidExpectedSn &= 0xFFF;


					pRxQueue->tPacketTimeout.aPacketsStored--;
				}
			}

			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);

			if (pTidDataBase->aTidExpectedSn == uFrameSn)
			{
				TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send current packet to uper layer");
				/* pass the packet */
				RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

				pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xfff;
			}
			else
			{
				uSaveIndex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);

				TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Enter current packet to Reorder Queue");
				TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uSaveIndex = 0x%x(%d)", uSaveIndex, uSaveIndex);

				/* uSaveIndex % RX_QUEUE_ARRAY_SIZE */
				uSaveIndex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

				/* Save the packet in the last entry of the queue */
				pTidDataBase->aPaketsQueue[uSaveIndex].tStatus = tStatus;
				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket = (void *)pBuffer;
				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket = (void *)pBuffer;

				pRxQueue->tPacketTimeout.aPacketsStored++;
			}



			/* aTidExpectedSn % 0xfff in order to take care of wrap around */
			pTidDataBase->aTidExpectedSn &= 0xfff;

			/* If there are still packets stored in the queue - start timer */
			if (pRxQueue->tPacketTimeout.aPacketsStored)
			{
				tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
				pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
				pRxQueue->tPacketTimeout.aFrameTid   = uFrameTid;
			}

			return;
		}
	}