/************************************************************************
 *                        removeSiteEntry								*
 ************************************************************************
DESCRIPTION: Removes the site entry from the site table

INPUT:      pSiteMgr		   - Handle to site mgr
            pCurrSiteTblParams - Pointer to current site table parameters
            hashPtr			   - Pointer to the site entry


OUTPUT:

RETURN:

************************************************************************/
void removeSiteEntry(siteMgr_t  *pSiteMgr,
                     siteTablesParams_t  *pCurrSiteTblParams,
                     siteEntry_t         *pSiteEntry)
{
	TI_UINT8			index;

	if (pSiteEntry == NULL) {
		TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "REMOVAL failure, site is NULL\n\n");
		return;
	}

	if (pCurrSiteTblParams->numOfSites == 0) {
		TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "REMOVAL failure, site table is empty\n\n");
		return;
	}

	TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "removeSiteEntry REMOVE ssid=, bssid= 0x%x-0x%x-0x%x-0x%x-0x%x-0x%x\n\n",			   pSiteEntry->bssid[0], pSiteEntry->bssid[1], pSiteEntry->bssid[2],			   pSiteEntry->bssid[3], pSiteEntry->bssid[4], pSiteEntry->bssid[5] );

	pCurrSiteTblParams->numOfSites--;

	/* Now remove (exclude) hashPtr entry from the linked list */

	TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "REMOVAL success, bssid: %X-%X-%X-%X-%X-%X\n\n", pSiteEntry->bssid[0], pSiteEntry->bssid[1], pSiteEntry->bssid[2], pSiteEntry->bssid[3], pSiteEntry->bssid[4], pSiteEntry->bssid[5]);
	TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, " SITE TABLE remaining entries number  %d \n", pCurrSiteTblParams->numOfSites);

	/* Clean the rest of the entry structure */
	index = pSiteEntry->index;     /* keep the index of the siteTable entry */
	os_memoryZero(pSiteMgr->hOs, pSiteEntry, sizeof(siteEntry_t));

	/* This is not required!!!! - Remove!!*/
	pSiteEntry->dtimPeriod = 1;
	pSiteEntry->siteType = SITE_NULL;
	pSiteEntry->index = index;   /* restore the index of the siteTable */

	/* if removing previous primary site - update the link */
	if (pSiteEntry == pSiteMgr->pSitesMgmtParams->pPrevPrimarySite) {
		pSiteMgr->pSitesMgmtParams->pPrevPrimarySite = NULL;
	}

	return;
}
/** 
 * \fn     sme_AppScanResult
 * \brief  Callback function from scan concentrator app for results and scan complete indications
 * 
 * Callback function from scan concentrator app for results and scan complete indications, used
 * for scans wehen the SME is in manual.
 * 
 * \param  hSme - handle to the SME object
 * \param  eStatus - the reason for calling the CB  
 * \param  pFrameInfo - frame information (if the CB is called due to received frame)
 * \param  uResultCount - number of results rceived
 * \return None
 */ 
void sme_AppScanResult (TI_HANDLE hSme, EScanCncnResultStatus eStatus,
                        TScanFrameInfo* pFrameInfo)
{
    TSme                *pSme = (TSme*)hSme;

    /* in manual mode, store the frame in the SME scan result table */
    if (CONNECT_MODE_MANUAL == pSme->eConnectMode)
    { 
        switch (eStatus)
        {
        /* a frame was received - update the scan result table */
        case SCAN_CRS_RECEIVED_FRAME:
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_AppScanResult: received frame from BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]);
    
            if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo))
            {
                TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_AppScanResult: unable to update enrty for BSSID %02x:%02x:%02x:%02x:%02x:%02x because table is full\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]);
            }
            break;
    
        /* scan was completed successfully */
        case SCAN_CRS_SCAN_COMPLETE_OK:
        /* an error occured, try selecting a site anyway */
        case SCAN_CRS_SCAN_ABORTED_FW_RESET:
        case SCAN_CRS_SCAN_STOPPED:
        case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY:
        case SCAN_CRS_SCAN_FAILED:
        case SCAN_CRS_TSF_ERROR:
            TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_AppScanResult: received scan complete indication with status %d\n", eStatus);
    
            /* stablizie the scan result table - delete its contenst if no results were recived during last scan */
            scanResultTable_SetStableState (pSme->hScanResultTable);
            break;

        default:
            TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_AppScanResult: received unrecognized status %d\n", eStatus);
            break;
        }
    }
}
/**
 * \fn     twIf_TxnDoneCb
 * \brief  Transaction completion CB
 *
 * This callback is called by the TxnQ upon transaction completion, unless is was completed in
 *     the original context where it was issued.
 * It may be called from bus driver external context (TxnDone ISR) or from WLAN driver context.
 *
 * \note
 * \param  hTwIf - The module's object
 * \param  pTxn  - The completed transaction object
 * \return void
 * \sa     twIf_HandleTxnDone
 */
static void twIf_TxnDoneCb (TI_HANDLE hTwIf, TTxnStruct *pTxn)
{
	TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;

#ifdef TI_DBG
	pTwIf->uDbgCountTxnDoneCb++;
	TRACE6(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_TxnDoneCb: Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n", pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);
#endif

	/* In case of recovery flag, Call directly restart callback */
	if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_RECOVERY) {
		if (pTwIf->fRecoveryCb) {
			TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_TxnDoneCb: During Recovery\n");
			pTwIf->bTxnDoneInRecovery = TI_TRUE;
			/* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
			context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
			return;
		}
	}

	/* If the completed Txn is ELP, nothing to do (not counted) so exit */
	if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) {
		return;
	}

	if (pTxn->fTxnDoneCb) {
		TI_STATUS eStatus;

		/* In critical section, enqueue the completed transaction in the TxnDoneQ. */
		context_EnterCriticalSection (pTwIf->hContext);
		eStatus = que_Enqueue (pTwIf->hTxnDoneQueue, (TI_HANDLE)pTxn);
		if (eStatus != TI_OK) {
			TRACE3(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_TxnDoneCb(): Enqueue failed, pTxn=0x%x, HwAddr=0x%x, Len0=%d\n", pTxn, pTxn->uHwAddr, pTxn->aLen[0]);
		}
		context_LeaveCriticalSection (pTwIf->hContext);
	} else {
		context_EnterCriticalSection (pTwIf->hContext);
		/* Decrement pending Txn counter, It's value will be checked in twIf_HandleTxnDone() */
		if (pTwIf->uPendingTxnCount > 0) { /* in case of callback on recovery after restart */
			pTwIf->uPendingTxnCount--;
		}
		context_LeaveCriticalSection (pTwIf->hContext);

	}

	/* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
	context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
}
Exemple #4
0
static size_t csf_write_page(CSF_CTX *ctx, int pgno, void *data, size_t data_sz) {
  off_t start_offset = HDR_SZ + (pgno * ctx->page_sz);
  off_t cur_offset =  lseek(*ctx->fh, 0L, SEEK_CUR);
  int to_write = ctx->page_sz;
  size_t write_sz = 0;
  CSF_PAGE_HEADER header;

  assert(data_sz <= ctx->data_sz);

  header.data_sz = data_sz;

  if(cur_offset != start_offset) { /* if not in proper position for page, seek there */
    cur_offset = lseek(*ctx->fh, start_offset, SEEK_SET);
  }
  
  RAND_pseudo_bytes(ctx->page_buffer, ctx->iv_sz);

  memcpy(ctx->scratch_buffer, &header, sizeof(header));
  memcpy(ctx->scratch_buffer + ctx->page_header_sz, data, data_sz);

  /* normally this would encrypt here */
  if(ctx->encrypted) {
    EVP_CIPHER_CTX ectx;
    void *out_ptr =  ctx->page_buffer + ctx->iv_sz;
    int out_sz, cipher_sz = 0;

    EVP_CipherInit(&ectx, CIPHER, NULL, NULL, 1);
    EVP_CIPHER_CTX_set_padding(&ectx, 0);
    EVP_CipherInit(&ectx, NULL, ctx->key_data, ctx->page_buffer, 1);
    EVP_CipherUpdate(&ectx, out_ptr + cipher_sz, &out_sz, ctx->scratch_buffer, ctx->page_header_sz + ctx->data_sz);
    cipher_sz += out_sz;
    EVP_CipherFinal(&ectx, out_ptr + cipher_sz, &out_sz);
    cipher_sz += out_sz;
    EVP_CIPHER_CTX_cleanup(&ectx);
    assert(cipher_sz == (ctx->page_header_sz + ctx->data_sz));
  } else {
    memcpy(ctx->page_buffer + ctx->iv_sz, ctx->scratch_buffer, ctx->page_header_sz + ctx->data_sz);
  }

  for(;write_sz < to_write;) { /* FIXME - error handling */ 
    size_t bytes_write = write(*ctx->fh, ctx->page_buffer + write_sz, to_write - write_sz);
    write_sz += bytes_write;
  }  
  
  TRACE6("csf_write_page(%d,%d,x,%d), cur_offset=%d, write_sz= %d\n", *ctx->fh, pgno, data_sz, cur_offset, write_sz);

  return data_sz;
}
Exemple #5
0
int __darwin_posix_spawn(pid_t* pid, const char* path, const __darwin_posix_spawn_file_actions_t* file_actions, const __darwin_posix_spawnattr_t* attrp,
		        char* const argv[], char* const envp[])
{
	TRACE6(pid, path, file_actions, attrp, argv, envp);
	char* const* argv_copy = nullptr;
	int err;

	path = translatePathCI(path);

	if (MachO::isMachO(path))
		argv = argv_copy = Darling::prependLoaderPath(argv, path);	

	err = AutoErrnoPosix(posix_spawn, pid, path, file_actions->native, attrp->native, argv, envp);

	delete [] argv_copy;
	return err;
}
void tet_si_serverloop()
{
	register struct ptab *pp;
	register time_t timeout;
	register int delay, rc;
	extern struct ptab *tet_ptab;

	/* see how long it is to the next timeout */
	timeout = INFINITY;
	for (pp = tet_ptab; pp; pp = pp->pt_next) {
		ASSERT(pp->pt_magic == PT_MAGIC);
		if (pp->pt_timeout && pp->pt_timeout < timeout)
			timeout = pp->pt_timeout;
	}
	if (timeout == INFINITY)
		delay = tet_ptab ? LONGDELAY : SHORTDELAY;
	else if ((delay = (int) (timeout - time((time_t *) 0))) < 0 ||
		delay > LONGDELAY)
			delay = LONGDELAY;

	TRACE3(tet_Tloop, 2,
		"tet_si_serverloop TOP: tet_ptab = %s, poll timeout = %s",
		tet_i2x(tet_ptab), tet_i2a(delay));

#ifndef NOTRACE
	if (tet_Tloop) {
		TRACE2(tet_Tloop, 10, "process table:%s",
			tet_ptab ? "" : " empty");
		for (pp = tet_ptab; pp; pp = pp->pt_next)
			TRACE6(tet_Tloop, 10,
		"pp = %s, next = %s, proc = %s, state = %s, flags = %s",
				tet_i2x(pp), tet_i2x(pp->pt_next),
				tet_r2a(&pp->pt_rid),
				tet_ptstate(pp->pt_state),
				tet_ptflags(pp->pt_flags));
	}
#endif

	/* perform the main loop */
	if ((rc = tet_ts_poll(tet_ptab, delay)) > 0)
		si_procrun();
	else if (rc < 0)
		exit(1);
	if (si_timeouts() > 0)
		si_procrun();
}
Exemple #7
0
static size_t csf_read_page(CSF_CTX *ctx, int pgno, void *data) {
  off_t start_offset = HDR_SZ + (pgno * ctx->page_sz);
  off_t cur_offset =  lseek(*ctx->fh, 0L, SEEK_CUR);
  int to_read = ctx->page_sz;
  size_t read_sz = 0;
  CSF_PAGE_HEADER header;

  if(cur_offset != start_offset) { /* if not in proper position for page, seek there */
    cur_offset = lseek(*ctx->fh, start_offset, SEEK_SET);
  }
 
  /* FIXME - error handling */
  for(;read_sz < to_read;) {
    size_t bytes_read = read(*ctx->fh, ctx->page_buffer + read_sz, to_read - read_sz);
    read_sz += bytes_read;
    if(bytes_read < 0) {
      return 0;
    }
  }  

  if(ctx->encrypted) {
    EVP_CIPHER_CTX ectx;
    void *out_ptr =  ctx->scratch_buffer;
    int out_sz, cipher_sz = 0;

    EVP_CipherInit(&ectx, CIPHER, NULL, NULL, 0);
    EVP_CIPHER_CTX_set_padding(&ectx, 0);
    EVP_CipherInit(&ectx, NULL, ctx->key_data, ctx->page_buffer, 0);
    EVP_CipherUpdate(&ectx, out_ptr + cipher_sz, &out_sz, ctx->page_buffer + ctx->iv_sz, ctx->page_header_sz + ctx->data_sz);
    cipher_sz += out_sz;
    EVP_CipherFinal(&ectx, out_ptr + cipher_sz, &out_sz);
    cipher_sz += out_sz;
    EVP_CIPHER_CTX_cleanup(&ectx);
    assert(cipher_sz == (ctx->page_header_sz + ctx->data_sz));
  } else {
    memcpy(ctx->scratch_buffer, ctx->page_buffer + ctx->iv_sz, ctx->page_header_sz + ctx->data_sz);
  }

  memcpy(&header, ctx->scratch_buffer, sizeof(header));
  memcpy(data, ctx->scratch_buffer + ctx->page_header_sz, header.data_sz);

  TRACE6("csf_read_page(%d,%d,x), cur_offset=%d, read_sz=%d, return=%d\n", *ctx->fh, pgno, cur_offset, read_sz, data_sz);

  return header.data_sz;
}
Exemple #8
0
int csf_ctx_init(CSF_CTX **ctx_out, int *fh, unsigned char *key_data, int key_sz, int page_sz) {
  EVP_CIPHER_CTX ectx;
  CSF_CTX *ctx;

  ctx = csf_malloc(sizeof(CSF_CTX));
  ctx->seek_ptr = ctx->file_sz = 0;
  ctx->fh = fh;

  ctx->key_sz = key_sz;
  ctx->key_data = csf_malloc(ctx->key_sz);
  memcpy(ctx->key_data, key_data, ctx->key_sz);

  EVP_EncryptInit(&ectx, CIPHER, ctx->key_data, NULL);
  ctx->block_sz = EVP_CIPHER_CTX_block_size(&ectx);
  ctx->iv_sz = EVP_CIPHER_CTX_iv_length(&ectx);

  /* the combined page size includes the size of the initialization  
     vector, an integer for the count of bytes on page, and the data block */
  ctx->page_sz = page_sz;

  /* ensure the page header allocation ends on an even block alignment */
  ctx->page_header_sz = (sizeof(CSF_PAGE_HEADER) % ctx->block_sz == 0) ? (sizeof(CSF_PAGE_HEADER) / ctx->block_sz) : (sizeof(CSF_PAGE_HEADER) / ctx->block_sz) + ctx->block_sz;

  /* determine unused space avaliable for data */
  ctx->data_sz = ctx->page_sz - ctx->iv_sz - ctx->page_header_sz;

  assert(ctx->iv_sz %  ctx->block_sz == 0);
  assert(ctx->page_header_sz %  ctx->block_sz == 0);
  assert(ctx->data_sz %  ctx->block_sz == 0);
  assert(ctx->page_sz %  ctx->block_sz == 0);

  ctx->page_buffer = csf_malloc(ctx->page_sz);
  ctx->csf_buffer = csf_malloc(ctx->page_sz);
  ctx->scratch_buffer = csf_malloc(ctx->page_sz);
  
  EVP_CIPHER_CTX_cleanup(&ectx);

  ctx->encrypted=1;

  TRACE6("csf_init() ctx->data_sz=%d, ctx->page_sz=%d, ctx->block_sz=%d, ctx->iv_sz=%d, ctx->key_sz=%d\n", ctx->data_sz, ctx->page_sz, ctx->block_sz, ctx->iv_sz, ctx->key_sz);

  *ctx_out = ctx;

  return 0;  
}
/**
*
* mainSec_setKey
*
* \b Description: 
*
* Start the NULL main security SM. Reports success to the rsn module immediately.
*
* \b ARGS:
*
*  none
*
* \b RETURNS:
*
*  TI_OK on success, TI_NOK otherwise.
*
* \sa 
*/
TI_STATUS mainSec_setKey(struct _mainSec_t *pMainSec, TSecurityKeys *pKey)
{
    TI_STATUS               status = TI_OK;
    
    if ((pMainSec == NULL) || (pKey == NULL))
    {
        return TI_NOK;
    }

    if (pKey->keyType != KEY_NULL)
    {
        TRACE6(pMainSec->hReport, REPORT_SEVERITY_INFORMATION, "MAIN_SEC_SM: setting key #%d, value = 0x%X 0x%X 0x%X 0x%X 0x%X\n", pKey->keyIndex, (TI_UINT8)pKey->encKey[0], (TI_UINT8)pKey->encKey[1], (TI_UINT8)pKey->encKey[2], (TI_UINT8)pKey->encKey[3], (TI_UINT8)pKey->encKey[4]);

        status = pMainSec->pParent->setKey(pMainSec->pParent, pKey);
    }
    
    return status;
}
Exemple #10
0
int __darwin_posix_spawnp(pid_t* pid, const char* file, const __darwin_posix_spawn_file_actions_t* file_actions,const __darwin_posix_spawnattr_t* attrp,
		        char* const argv[], char* const envp[])
{
	TRACE6(pid, file, file_actions, attrp, argv, envp);
	char* const* argv_copy = nullptr;
	int err;

	const char* path = Darling::findInPath(file);
	if (!path)
		return DARWIN_ENOENT;

	if (MachO::isMachO(path))
		argv = argv_copy = Darling::prependLoaderPath(argv, path);

	err = AutoErrnoPosix(posix_spawn, pid, path, file_actions->native, attrp->native, argv, envp);

	delete [] argv_copy;
	return err;
}
Exemple #11
0
size_t csf_read(CSF_CTX *ctx, void *data, size_t nbyte) {
  int start_page = csf_pageno_for_offset(ctx, ctx->seek_ptr);
  int start_offset = ctx->seek_ptr % ctx->data_sz;
  int to_read = nbyte + start_offset;
  int pages_to_read = csf_page_count_for_length(ctx, to_read);
  int i, data_offset = 0;
  int page_count = csf_page_count_for_file(ctx);

  for(i = 0; i < pages_to_read && i < page_count; i++) { /* dont read past end of file */
    int data_sz = (to_read < ctx->data_sz ? to_read : ctx->data_sz);
    int l_data_sz = data_sz - start_offset;
    int bytes_read = csf_read_page(ctx, start_page + i, ctx->csf_buffer);
    memcpy(data + data_offset, ctx->csf_buffer + start_offset, l_data_sz);
    to_read -= bytes_read;
    data_offset += l_data_sz;
    ctx->seek_ptr += l_data_sz;
    start_offset = 0; /* after the first iteration the start offset will always be at the beginning of the page */
    memset(ctx->csf_buffer, 0, ctx->page_sz);
  }

  TRACE6("csf_read(%d,x,%d), pages_to_read = %d, ctx->seek_ptr = %d, return=%d\n", *ctx->fh, nbyte, pages_to_read, ctx->seek_ptr, data_offset);
  return data_offset;
}
/**
 * \\n
 * \date 08-November-2005\n
 * \brief Handle a DRIVER_MODE_SUCCESS event by sending start measure command to the FW.\n
 *
 * Function Scope \e Public.\n
 * \param hMeasurementSrv - handle to the Measurement SRV object.\n
 * \return always TI_OK.\n
 */
TI_STATUS measurementSRVSM_requestMeasureStart( TI_HANDLE hMeasurementSRV )
{
	measurementSRV_t     *pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV;
	TMeasurementParams    pMeasurementCmd;
	TI_STATUS             status;
	TI_UINT32                currentTime = os_timeStampMs( pMeasurementSRV->hOS );

	/* check if request time has expired (note: timer wrap-around is also handled)*/
	if ( (pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs)
	        < currentTime )
	{
		TI_INT32 i;

		TRACE2( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": request time has expired, request expiry time:%d, current time:%d\n", pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs, currentTime);

		/* mark that all measurement types has failed */
		for ( i = 0; i < pMeasurementSRV->msrRequest.numberOfTypes; i++ )
		{
			pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK;
		}

		/* send a measurement complete event */
		measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState),
		                          MSR_SRV_EVENT_STOP_COMPLETE );

		return TI_OK;
	}

	pMeasurementCmd.channel = pMeasurementSRV->msrRequest.channel;
	pMeasurementCmd.band = pMeasurementSRV->msrRequest.band;
	pMeasurementCmd.duration = 0; /* Infinite */
	pMeasurementCmd.eTag = pMeasurementSRV->msrRequest.eTag;

	if ( measurementSRVIsBeaconMeasureIncluded( hMeasurementSRV ))
	{  /* Beacon Measurement is one of the types */

		/* get the current channel */
		TTwdParamInfo	paramInfo;

		paramInfo.paramType = TWD_CURRENT_CHANNEL_PARAM_ID;
		cmdBld_GetParam (pMeasurementSRV->hCmdBld, &paramInfo);

		pMeasurementCmd.ConfigOptions = RX_CONFIG_OPTION_FOR_MEASUREMENT;

		/* check if the request is on the serving channel */
		if ( paramInfo.content.halCtrlCurrentChannel == pMeasurementSRV->msrRequest.channel )
		{
			/* Set the RX Filter to the join one, so that any packets will
			be received on the serving channel - beacons and probe requests for
			the measurmenet, and also data (for normal operation) */
			pMeasurementCmd.FilterOptions = RX_FILTER_OPTION_JOIN;
		}
		else
		{
			/* not on the serving channle - only beacons and rpobe responses are required */
			pMeasurementCmd.FilterOptions = RX_FILTER_OPTION_DEF_PRSP_BCN;
		}
	}
	else
	{  /* No beacon measurement - use the current RX Filter */
		pMeasurementCmd.ConfigOptions = 0xffffffff;
		pMeasurementCmd.FilterOptions = 0xffffffff;
	}

	/* Send start measurement command */
	status = cmdBld_CmdMeasurement (pMeasurementSRV->hCmdBld,
	                                &pMeasurementCmd,
	                                (void *)measurementSRVSM_requestMeasureStartResponseCB,
	                                pMeasurementSRV);

	if ( TI_OK != status )
	{
		TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Failed to send measurement start command, statud=%d,\n", status);

		/* keep the faulty return status */
		pMeasurementSRV->returnStatus = status;

		/* send a measurement start fail event */
		return measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState),
		                                 MSR_SRV_EVENT_START_FAILURE );
	}

	TRACE6( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": measure start command sent. Params:\n channel=%d, band=%d, duration=%d, \n configOptions=0x%x, filterOptions=0x%x, status=%d, \n", pMeasurementCmd.channel, pMeasurementCmd.band, pMeasurementCmd.duration, pMeasurementCmd.ConfigOptions, pMeasurementCmd.FilterOptions, status);

	/* start the FW guard timer */
	pMeasurementSRV->bStartStopTimerRunning = TI_TRUE;
	tmr_StartTimer (pMeasurementSRV->hStartStopTimer,
	                MacServices_measurementSRV_startStopTimerExpired,
	                (TI_HANDLE)pMeasurementSRV,
	                MSR_FW_GUARD_TIME,
	                TI_FALSE);

	return TI_OK;
}
/** 
 * \fn     sme_Select
 * \brief  Select a connection candidate from the scan result table
 * 
 * Select a connection candidate from the scan result table.
 * 
 * Connection candidate must match SSID, BSSID, BSS type, RSN and WSC settings, has the best
 * RSSI level from all matching sites, and connection was not attempted to it in this SME cycle
 * (since last scan was completed)
 * 
 * \param  hSme - handle to the SME object
 * \return A pointer to the selected site, NULL if no site macthes the selection criteria
 */ 
TSiteEntry *sme_Select (TI_HANDLE hSme)
{
    TSme            *pSme = (TSme*)hSme;
    TSiteEntry      *pCurrentSite, *pSelectedSite = NULL;
    TI_INT8         iSelectedSiteRssi = -127; /* minimum RSSI */
    TI_BOOL         bWscPbAbort, pWscPbApFound = TI_FALSE;
    int             apFoundCtr =0;
    TIWLN_SIMPLE_CONFIG_MODE eWscMode;

    TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select called\n");

    /* on SG avalanche, select is not needed, send connect event automatically */
    if (TI_TRUE == pSme->bReselect)
    {        
        paramInfo_t *pParam;

        TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: reselect flag is on, reselecting the current site\n");

        pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t));
        if (!pParam)
        {
            return NULL;
        }

        pSme->bReselect = TI_FALSE;

        /* Get Primary Site */
        pParam->paramType = SITE_MGR_GET_PRIMARY_SITE;
        siteMgr_getParam(pSme->hSiteMgr, pParam);
        pCurrentSite = pParam->content.pPrimarySite;
        os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t));
        return pCurrentSite;
    }

    /* get the first site from the scan result table */
    pCurrentSite = scanResultTable_GetFirst (pSme->hScanResultTable);

    /* check all sites */
    while (NULL != pCurrentSite)
    {
        TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: considering BSSID: %02x:%02x:%02x:%02x:%02x:%02x for selection\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);

        /* if this site was previously selected in the current SME connection attempt, and conn mode is auto */
        if (TI_TRUE == pCurrentSite->bConsideredForSelect)
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x was selected previously\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* check if site matches */
        /* first check SSID match */
        if (TI_FALSE == sme_SelectSsidMatch (hSme, &(pCurrentSite->ssid), &(pSme->tSsid), pSme->eSsidType))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match SSID\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* Now check BSSID match */
        if (TI_FALSE == sme_SelectBssidMatch (&(pCurrentSite->bssid), &(pSme->tBssid)))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match SSID\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* and BSS type match */
        if (TI_FALSE == sme_SelectBssTypeMatch (pCurrentSite->bssType, pSme->eBssType))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match BSS type\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

         if (pCurrentSite->WSCSiteMode == TIWLN_SIMPLE_CONFIG_PBC_METHOD)
         {
           apFoundCtr++;
         }
         if (apFoundCtr > 1)
         {
           pWscPbApFound = TI_TRUE;
         }

        /* and simple config match */
        if (TI_FALSE == sme_SelectWscMatch (hSme, pCurrentSite, &bWscPbAbort, &pWscPbApFound))
        /* site doesn't match */
        {
            /* also check if abort was indicated */
            if (TI_TRUE == bWscPbAbort)
            {
                /* send event to user mode to indicate this */
                EvHandlerSendEvent (pSme->hEvHandler, IPC_EVENT_WPS_SESSION_OVERLAP, NULL, 0);
                /* select failed - will rescan in time */
                return NULL;
            }
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match WSC\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* and security match */
        siteMgr_getParamWSC(pSme->hSiteMgr, &eWscMode); 

        /* we don't need to check RSN match while WSC is active */
        if ((pCurrentSite->WSCSiteMode == TIWLN_SIMPLE_CONFIG_OFF) || (pCurrentSite->WSCSiteMode != eWscMode))
        {
            if (TI_FALSE == sme_SelectRsnMatch (hSme, pCurrentSite))
            /* site doesn't match */
            {
                TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match RSN\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
                pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
                /* get the next site and continue the loop */
                pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
                continue;
            }
        }

        /* and rate match */
        if (TI_FALSE == siteMgr_SelectRateMatch (pSme->hSiteMgr, pCurrentSite))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match rates\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        if (TI_TRUE == pCurrentSite->bChannelSwitchAnnoncIEFound)
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x has channel switch IE so ignore it \n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* if this site RSSI is higher than current maximum, select it */
        if (pCurrentSite->rssi > iSelectedSiteRssi)
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x match and has highest RSSI so far!\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pSelectedSite = pCurrentSite;
            iSelectedSiteRssi = pCurrentSite->rssi;
        }

        /* and continue to the next site */
        pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
    }

    /* if a matching site was found */
    if (NULL != pSelectedSite)
    {
        /* mark that a connection to this site was (actually is) attempted */
        pSelectedSite->bConsideredForSelect = TI_TRUE;

        /* hope this is the correct place for siteMgr_changeBandParams */
        siteMgr_changeBandParams (pSme->hSiteMgr, pSelectedSite->eBand);

        /*
         * Coordinate between SME module site table and Site module site Table 
         * copy candidate AP to Site module site Table.
         */
        siteMgr_CopyToPrimarySite(pSme->hSiteMgr, pSelectedSite);

		/* copy the result, rather than returning a pointer to the entry in the scan result table.
		 * This is done since the table might change durring the connection process, and the pointer 
		 * will point to the wrong entry in the table, causing connection/disconnection problems */
		os_memoryCopy(pSme->hOS, &(pSme->tCandidate), pSelectedSite, sizeof(TSiteEntry));

		return &(pSme->tCandidate);
    }

    /* return NULL if no site was selected */
    return NULL;
}
/**
 * Activates the next measurement request.
 * 
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_activateNextRequest(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;
    requestHandler_t * pRequestH = (requestHandler_t *) pMeasurementMgr->hRequestH;
    MeasurementRequest_t * pRequestArr[MAX_NUM_REQ];
    TI_UINT8 numOfRequestsInParallel = 0;
    TI_BOOL valid;
    TI_UINT8 index;

	/* Keep note of the time we started processing the request. this will be used */
    /* to give the measurementSRV a time frame to perform the measurement operation */
    pMeasurementMgr->currentRequestStartTime = os_timeStampMs(pMeasurementMgr->hOs);

    TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Timer started at %d, we have 20ms to begin measurement...\n", pMeasurementMgr->currentRequestStartTime);

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Looking for a valid request\n");

    do
    {
        TI_STATUS status;

        if (numOfRequestsInParallel != 0)
        {
            TRACE4(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Changing activeRequestID from %d to %d, and numOfWaitingRequests from %d to %d.\n", pRequestH->activeRequestID, pRequestH->activeRequestID + numOfRequestsInParallel, pRequestH->numOfWaitingRequests, pRequestH->numOfWaitingRequests - numOfRequestsInParallel);
        }

        pRequestH->activeRequestID += numOfRequestsInParallel;
        pRequestH->numOfWaitingRequests -= numOfRequestsInParallel;

        for (index = 0; index < MAX_NUM_REQ; index++)
        {
            pRequestArr[index] = NULL;
        }
        numOfRequestsInParallel = 0;

        /* Getting the next request/requests from the request handler */
        status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_FALSE, pRequestArr, 
                                           &numOfRequestsInParallel);
        
        /* Checking if there are no waiting requests */
        if (status != TI_OK)
        {
            TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": There are no waiting requests in the queue\n");

            return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
        }

        /* Checking validity of request/s */
        valid = measurementMgr_isRequestValid(pMeasurementMgr, pRequestArr, 
                                numOfRequestsInParallel);

        /* Checking if the current request is Beacon Table */
        if( (numOfRequestsInParallel == 1) && 
            (pRequestArr[0]->Type == MSR_TYPE_BEACON_MEASUREMENT) &&
            (pRequestArr[0]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) )
        {
            TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Received Beacon Table request, building a report for it and continuing\n");

            pMeasurementMgr->buildReport(hMeasurementMgr, *(pRequestArr[0]), NULL);
            valid = TI_FALSE; /* In order to get the next request/s*/
        }
        
    } while (valid == TI_FALSE);
    
    
    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request(s) for activation:\n");

    for (index = 0; index < numOfRequestsInParallel; index++)
    {
        TRACE6(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": \n\nRequest #%d:\n Type: %d\n Measured Channel: %d (Serving Channel: %d)\n Scan Mode: %d\n Duration: %d\n\n", index+1, pRequestArr[index]->Type, pRequestArr[index]->channelNumber, pMeasurementMgr->servingChannelID, pRequestArr[index]->ScanMode, pRequestArr[index]->DurationTime);
    }

    /* Ignore requests if traffic intensity is high */
    if (measurementMgr_isTrafficIntensityHigherThanThreshold(pMeasurementMgr) == TI_TRUE)
    {
        TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Traffic intensity too high, giving up...\n");

        measurementMgr_rejectPendingRequests(pMeasurementMgr, MSR_REJECT_TRAFFIC_INTENSITY_TOO_HIGH);

        return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
    }

    TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request is Valid, about to start\n");
    
    pMeasurementMgr->measuredChannelID = pRequestArr[0]->channelNumber;
  
    /* Request resource from the SCR */
    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
        MEASUREMENTMGR_EVENT_REQUEST_SCR, pMeasurementMgr);    
}   
/**
*
* roamingMngr_smSelection 
*
* \b Description: 
*
* This procedure is called when selection should be performed.
*   It perform the following:
 * Prepare the candidate APs to roam according to:
 *  - Priority APs
 *  - Pre-Authenticated APs
 * If the candidate AP list is empty, only the current AP can be re-selected
 * Select one AP and trigger REQ_HANDOVER event.
 * 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smSelection(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t               *pRoamingMngr;
    TI_UINT32                      index;


    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
    pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
    pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;

    pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;

    if ((pRoamingMngr->pListOfAPs == NULL) || 
        (pRoamingMngr->pListOfAPs->numOfEntries == 0))
    {   /* Error, there cannot be selection  */
        TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smSelection pListOfAPs is empty \n");
        roamingMngr_smEvent(ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr);
        return;
    }

    /* Build the candidate AP list */
    for (index=0; index<pRoamingMngr->pListOfAPs->numOfEntries; index++ )
    {
        if ( (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP) &&
            (pRoamingMngr->pListOfAPs->BSSList[index].RSSI < pRoamingMngr->roamingMngrConfig.apQualityThreshold))
        {   /* Do not insert APs with low quality to the selection table, 
                if the Roaming Trigger was low Quality */
            TRACE8(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "candidate AP %x-%x-%x-%x-%x-%x with RSSI too low =%d, Quality=%d  \n", pRoamingMngr->pListOfAPs->BSSList[index].BSSID[0], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[1], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[2], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[3], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[4], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[5], pRoamingMngr->pListOfAPs->BSSList[index].RSSI, pRoamingMngr->roamingMngrConfig.apQualityThreshold);

            continue;
        }

        if (apConn_isSiteBanned(pRoamingMngr->hAPConnection, &pRoamingMngr->pListOfAPs->BSSList[index].BSSID) == TI_TRUE)
        {
            TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, ": Candidate AP %02X-%02X-%02X-%02X-%02X-%02X is banned!\n",									 pRoamingMngr->pListOfAPs->BSSList[index].BSSID[0],	pRoamingMngr->pListOfAPs->BSSList[index].BSSID[1], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[2], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[3], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[4], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[5]);
            continue;
        }

        if (pRoamingMngr->pListOfAPs->BSSList[index].bNeighborAP)
        {   /* The AP is a neighbor AP, insert its index to the neighbor APs list */
            pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS] = index; 
            pRoamingMngr->listOfCandidateAps.numOfNeighborBSS++;
        }
        else if (apConn_getPreAuthAPStatus(pRoamingMngr->hAPConnection, 
										   &pRoamingMngr->pListOfAPs->BSSList[index].BSSID))
        {   /* This AP is a pre-auth AP */
            pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS] = index; 
            pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS++;
        }
        else
        {   /* This AP is not Neighbor nor Pre-Auth */
            pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS] = index; 
            pRoamingMngr->listOfCandidateAps.numOfRegularBSS++;
        }
    }

#ifdef TI_DBG
    {   /* for debug */
        paramInfo_t     param;

        param.paramType = ROAMING_MNGR_PRINT_CANDIDATE_TABLE;
        roamingMngr_getParam(pRoamingMngr, &param);

    }
#endif
    roamingMngr_smEvent(ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr);

}
Exemple #16
0
/** 
 * \fn     twIf_HandleTxnDone
 * \brief  Completed transactions handler
 * 
 * The completed transactions handler, called upon TxnDone event, either from the context engine
 *     or directly from twIf_TxnDoneCb() if we are already in the WLAN driver's context.
 * Dequeue all completed transactions in critical section, and call their callbacks if available.
 * If awake is not required and no pending transactions in TxnQ, issue Sleep event to SM.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \return void
 * \sa     
 */
static void twIf_HandleTxnDone(TI_HANDLE hTwIf)
{
	TTwIfObj *pTwIf = (TTwIfObj *) hTwIf;
	TTxnStruct *pTxn;

	/* In case of recovery, call the recovery callback and exit */
	if (pTwIf->bTxnDoneInRecovery) {
		TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
		       "twIf_HandleTxnDone: call RecoveryCb\n");
		pTwIf->bTxnDoneInRecovery = TI_FALSE;
		if (pTwIf->bPendRestartTimerRunning) {
			tmr_StopTimer(pTwIf->hPendRestartTimer);
			pTwIf->bPendRestartTimerRunning = TI_FALSE;
		}
		pTwIf->fRecoveryCb(pTwIf->hRecoveryCb);
		return;
	}

	/* Loop while there are completed transactions to handle */
	while (1) {
		/* In critical section, dequeue completed transaction from the TxnDoneQ. */
		context_EnterCriticalSection(pTwIf->hContext);
		pTxn = (TTxnStruct *) que_Dequeue(pTwIf->hTxnDoneQueue);
		context_LeaveCriticalSection(pTwIf->hContext);

		/* If no more transactions to handle, exit */
		if (pTxn != NULL) {
			context_EnterCriticalSection(pTwIf->hContext);
			/* Decrement pending Txn counter */
			if (pTwIf->uPendingTxnCount > 0) {	/* in case of callback on recovery after restart */
				pTwIf->uPendingTxnCount--;
			}
			context_LeaveCriticalSection(pTwIf->hContext);

			TRACE4(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
			       "twIf_HandleTxnDone: Completed-Txn: Params=0x%x, HwAddr=0x%x, Len0=%d, fTxnDoneCb=0x%x\n",
			       pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0],
			       pTxn->fTxnDoneCb);

			/* If Txn failed and error CB available, call it to initiate recovery */
			if (TXN_PARAM_GET_STATUS(pTxn) ==
			    TXN_PARAM_STATUS_ERROR) {
				TRACE6(pTwIf->hReport, REPORT_SEVERITY_ERROR,
				       "twIf_HandleTxnDone: Txn failed!!  Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n",
				       pTxn->uTxnParams, pTxn->uHwAddr,
				       pTxn->aLen[0], pTxn->aLen[1],
				       pTxn->aLen[2], pTxn->aLen[3]);

				if (pTwIf->fErrCb) {
					pTwIf->fErrCb(pTwIf->hErrCb,
						      BUS_FAILURE);
				}
				/* in error do not continue */
				return;
			}

			/* If Txn specific CB available, call it (may free Txn resources and issue new Txns) */
			if (pTxn->fTxnDoneCb != NULL) {
				((TTxnDoneCb) (pTxn->fTxnDoneCb)) (pTxn->
								   hCbHandle,
								   pTxn);
			}
		}

		/*If uPendingTxnCount == 0 and awake not required, issue Sleep event to SM */
		if ((pTwIf->uAwakeReqCount == 0)
		    && (pTwIf->uPendingTxnCount == 0)) {
			twIf_HandleSmEvent(pTwIf, SM_EVENT_SLEEP);
		}

		if (pTxn == NULL) {
			return;
		}
	}
}
Exemple #17
0
/** 
 * \fn     twIf_SendTransaction
 * \brief  Send a transaction to the device
 * 
 * This method is used by the Xfer modules and the TwIf to send all transaction types to the device.
 * Send the transaction to the TxnQ and update the SM if needed.
 * 
 * \note   
 * \param  pTwIf - The module's object
 * \param  pTxn  - The transaction object 
 * \return COMPLETE if the transaction was completed in this context, PENDING if not, ERROR if failed
 * \sa     
 */
static ETxnStatus twIf_SendTransaction(TTwIfObj * pTwIf, TTxnStruct * pTxn)
{
	ETxnStatus eStatus;
#ifdef TI_DBG
	TI_UINT32 data = 0;

	/* Verify that the Txn HW-Address is 4-bytes aligned */
	if (pTxn->uHwAddr & 0x3) {
		TRACE2(pTwIf->hReport, REPORT_SEVERITY_ERROR,
		       "twIf_SendTransaction: Unaligned HwAddr! HwAddr=0x%x, Params=0x%x\n",
		       pTxn->uHwAddr, pTxn->uTxnParams);
		return TXN_STATUS_ERROR;
	}
#endif

	context_EnterCriticalSection(pTwIf->hContext);
	/* increment pending Txn counter */
	pTwIf->uPendingTxnCount++;
	context_LeaveCriticalSection(pTwIf->hContext);

	/* Send transaction to TxnQ */
	eStatus = txnQ_Transact(pTwIf->hTxnQ, pTxn);

#ifdef TI_DBG
	pTwIf->uDbgCountTxn++;
	if (eStatus == TXN_STATUS_COMPLETE) {
		pTwIf->uDbgCountTxnComplete++;
	} else if (eStatus == TXN_STATUS_PENDING) {
		pTwIf->uDbgCountTxnPending++;
	}

	COPY_WLAN_LONG(&data, &(pTxn->aBuf[0]));
	TRACE8(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
	       "twIf_SendTransaction: Status = %d, Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d, Data=0x%x \n",
	       eStatus, pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0],
	       pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3], data);
#endif

	/* If Txn status is PENDING issue Start event to the SM */
	if (eStatus == TXN_STATUS_PENDING) {
		twIf_HandleSmEvent(pTwIf, SM_EVENT_START);
	}

	/* Else (COMPLETE or ERROR) */
	else {
		context_EnterCriticalSection(pTwIf->hContext);
		/* decrement pending Txn counter in case of sync transact */
		pTwIf->uPendingTxnCount--;
		context_LeaveCriticalSection(pTwIf->hContext);

		/* If Awake not required and no pending transactions in TxnQ, issue Sleep event to SM */
		if ((pTwIf->uAwakeReqCount == 0)
		    && (pTwIf->uPendingTxnCount == 0)) {
			twIf_HandleSmEvent(pTwIf, SM_EVENT_SLEEP);
		}

		/* If Txn failed and error CB available, call it to initiate recovery */
		if (eStatus == TXN_STATUS_ERROR) {
			TRACE6(pTwIf->hReport, REPORT_SEVERITY_ERROR,
			       "twIf_SendTransaction: Txn failed!!  Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n",
			       pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0],
			       pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);

			if (pTwIf->fErrCb) {
				pTwIf->fErrCb(pTwIf->hErrCb, BUS_FAILURE);
			}
		}
	}

	/* Return the Txn status (COMPLETE if completed in this context, PENDING if not, ERROR if failed) */
	return eStatus;
}
/** 
 * \fn     sme_ScanResultCB
 * \brief  Callback function from scan concentrator for results and scan complete indications
 * 
 * Callback function from scan concentrator for results and scan complete indications
 * 
 * \param  hSme - handle to the SME object
 * \param  eStatus - the reason for calling the CB  
 * \param  pFrameInfo - frame information (if the CB is called due to received frame)
 * \param  uSPSStatus - SPS attened channels (if the CB is called to inidcate an SPS scan complete)
 * \return None
 */ 
void sme_ScanResultCB (TI_HANDLE hSme, EScanCncnResultStatus eStatus,
                       TScanFrameInfo* pFrameInfo, TI_UINT16 uSPSStatus)
{
    TSme                *pSme = (TSme*)hSme;
    paramInfo_t	        param;


    switch (eStatus)
    {
    /* a frame was received - update the scan result table */
    case SCAN_CRS_RECEIVED_FRAME:

        TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received frame from BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]);

        /* 
         * in auto mode in order to find country IE only !!!
         * filter frames according to desired SSID, in case we are also trying to find 
         * country IE in passive scan, to avoid a table overflow (in manual mode, the SME table must be equal to the app
         * table, the app is responsible to decide which SSIDs to use for scan)
         */
        if (CONNECT_MODE_AUTO == pSme->eConnectMode)
        {
            if (SSID_TYPE_SPECIFIC == pSme->eSsidType)
            {
#ifndef XCC_MODULE_INCLUDED
                if ((pSme->tSsid.len == pFrameInfo->parsedIEs->content.iePacket.pSsid->hdr[ 1 ]) &&
                    (0 == os_memoryCompare (pSme->hOS, &(pSme->tSsid.str[ 0 ]),
                                            &(pFrameInfo->parsedIEs->content.iePacket.pSsid->serviceSetId[ 0 ]),
                                            pSme->tSsid.len)))
#endif
                {

                    if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo))
                    {
                        TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update specific enrty for BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]);
                    }
                }
            }
            else
            {

                if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo))
                {
                    TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update enrty for BSSID %02x:%02x:%02x:%02x:%02x:%02x because table is full\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]);
                }
            }
        }
        else
        /* manual mode */
        {
            if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo))
            {
                TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update application scan enrty for BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]);
            }
        }
        break;

    /* scan was completed successfully */
    case SCAN_CRS_SCAN_COMPLETE_OK:
    /* an error occured, try selecting a site anyway */
    case SCAN_CRS_SCAN_ABORTED_FW_RESET:
    case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY:
    case SCAN_CRS_SCAN_FAILED:
    case SCAN_CRS_TSF_ERROR:
        TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received scan complete indication with status %d\n", eStatus);

        /* stablizie the scan result table - delete its contenst if no results were recived during last scan */
        scanResultTable_SetStableState (pSme->hScanResultTable);

        if (CONNECT_MODE_AUTO == pSme->eConnectMode)
        {
 
           /* try to select a site */
           pSme->pCandidate = sme_Select (hSme);

           /* if no matching site was found */
           if (NULL == pSme->pCandidate)
           {
               /* for IBSS or any, if no entries where found, add the self site */
               if (pSme->eBssType == BSS_INFRASTRUCTURE)
               {
                   TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: No candidate available, sending connect failure\n");

                   genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme);
                   break;
               }

               {
                   TI_UINT8     uDesiredChannel;

                   param.paramType = SITE_MGR_DESIRED_CHANNEL_PARAM;
                   siteMgr_getParam(pSme->hSiteMgr, &param);
                   uDesiredChannel = param.content.siteMgrDesiredChannel;

                   if (uDesiredChannel >= SITE_MGR_CHANNEL_A_MIN)
                   {
                       param.content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ;
                   } 
                   else 
                   {
                       param.content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ;
                   }

                   /*
                   update the regulatory domain with the selected band
                   */
                   /* Check if the selected channel is valid according to regDomain */
                   param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
                   param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
                   param.content.channelCapabilityReq.channelNum = uDesiredChannel;

                   regulatoryDomain_getParam (pSme->hRegDomain,&param);
                   if (!param.content.channelCapabilityRet.channelValidity)
                   {
                       TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "IBSS SELECT FAILURE  - No channel !!!\n\n");

                       genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme);

                       break;
                   }

                   pSme->pCandidate = (TSiteEntry *)addSelfSite(pSme->hSiteMgr);

                   if (pSme->pCandidate == NULL)
                   {
                       TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "IBSS SELECT FAILURE  - could not open self site !!!\n\n");

                       genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme);

                       break;
                   }

#ifdef REPORT_LOG    
                   TRACE6(pSme->hReport, REPORT_SEVERITY_CONSOLE,"%%%%%%%%%%%%%%	SELF SELECT SUCCESS, bssid: %X-%X-%X-%X-%X-%X	%%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5]);
                   WLAN_OS_REPORT (("%%%%%%%%%%%%%%	SELF SELECT SUCCESS, bssid: %02x.%02x.%02x.%02x.%02x.%02x %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5]));
#endif
                }
           }

           /* a connection candidate is available, send a connect event */
           genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme);
        }
        break;        

    /*
     * scan was stopped according to SME request (should happen when moving to disconnecting from scanning), send a 
     * connect failure event to move out of disconnecting
     */
    case SCAN_CRS_SCAN_STOPPED:
        TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received scan stopped indication\n");
        genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme);
        break;

    default:
        TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: received unrecognized status %d\n", eStatus);
        break;
    }
}
Exemple #19
0
/****************************************************************************
 *                  txHwQueue_AllocResources()
 ****************************************************************************
 * DESCRIPTION: 
   ============
    1.  Estimate required HW-blocks number.
    2.1  If the required blocks are not available for the link or no free descriptor, 
            return  link STOP_CURRENT  (to stop current link and requeue the packet).
    2.2  If the required blocks are not available for the queue or no free descriptor, 
            return  queue STOP_CURRENT  (to stop current queue and requeue the packet).
    3.  Resources are available so update allocated blocks and descriptors counters.
    4.1  If no link resources for another similar packet, set STOP_NEXT (to stop current link).
    4.2  If no queue resources for another similar packet, set STOP_NEXT (to stop current queue).
        Else, return SUCCESS
 ****************************************************************************/
ETxHwQueStatus txHwQueue_AllocResources (TI_HANDLE hTxHwQueue, TTxCtrlBlk *pTxCtrlBlk)
{
    TTxHwQueue *pTxHwQueue = (TTxHwQueue *)hTxHwQueue;
    TI_UINT32 uNumBlksToAlloc; /* The number of blocks required for the current packet. */
    TI_UINT32 uExcludedLength; /* The data length not included in the rough blocks calculation */
    TI_UINT32 uAvailableBlks;  /* Max blocks that are currently available for this queue. */
    TI_UINT32 uReservedBlks;   /* How many blocks are reserved for this queue before this allocation. */
    TI_UINT32 uQueueId = WMEQosTagToACTable[pTxCtrlBlk->tTxDescriptor.tid];
    TTxHwQueueInfo *pQueueInfo = &(pTxHwQueue->aTxHwQueueInfo[uQueueId]);
    ETxHwQueStatus retStatus = TX_HW_QUE_STATUS_SUCCESS;
    TI_UINT32 uHlid = pTxCtrlBlk->tTxDescriptor.hlid;
#ifdef AP_MODE_ENABLED
    TTxHwLinkInfo *pLinkInfo = &(pTxHwQueue->aTxHwLinkInfo[uHlid]);
    TI_UINT32 uAvailableLinkBlks;  /* Max blocks that are currently available for this link. */
#endif

    /***********************************************************************/
    /*  Calculate packet required HW blocks.                               */
    /***********************************************************************/

    /* Divide length by 256 instead of 252 (block size) to save CPU */
    uNumBlksToAlloc = ( pTxCtrlBlk->tTxDescriptor.length + 20 ) >> 8;

    /* The length not yet included in the uNumBlksToAlloc is the sum of:
        1) 4 bytes per block as a result of using 256 instead of 252 block size.
        2) The remainder of the division by 256. 
        3) Overhead due to header translation, security and LLC header (subtracting ethernet header).
    */
    uExcludedLength = (uNumBlksToAlloc << 2) + ((pTxCtrlBlk->tTxDescriptor.length + 20) & 0xFF) + MAX_HEADER_SIZE - 14;

    /* Add 1 or 2 blocks for the excluded length, according to its size */
    uNumBlksToAlloc += (uExcludedLength > 252) ? 2 : 1;

    /* Add extra blocks needed in case of fragmentation */
    uNumBlksToAlloc += BLKS_HW_ALLOC_SPARE;


#ifdef AP_MODE_ENABLED
    /*
     * Check LINK resources and then AC resources
     * In case of no resources for the link, return STOP CURRENT and don't continue to check AC resources
     */

    /***********************************************************************/
    /*            Check link resources                                     */
    /***********************************************************************/

    /* Find max available blocks for this link (0 could indicate no descriptors). */
    uAvailableLinkBlks = txHwQueue_CheckLinkResources (pTxHwQueue, pLinkInfo);

    /* If we need more blocks than available, return  STOP_CURRENT (stop current link and requeue packet). */
    if (uNumBlksToAlloc > uAvailableLinkBlks)
    {
        TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": No link resources, Link=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, uFwMax=%d, uAvailableLinkBlks=%d\n", 
               uHlid, uNumBlksToAlloc, pLinkInfo->uFwFree, pLinkInfo->uHostAlloc, pLinkInfo->uFwMax, uAvailableLinkBlks);
        pLinkInfo->uNumBlksCausedBusy = uNumBlksToAlloc; /* used as prediction in free resources */
        pLinkInfo->bBusy = TI_TRUE;
        return TX_HW_LINK_STATUS_STOP_CURRENT;  /**** Exit! (we should stop link and requeue packet) ****/
    }
#endif

    /***********************************************************************/
    /*            Check if the required resources are available            */
    /***********************************************************************/

    /* Find max available blocks for this queue (0 could indicate no descriptors). */
    uAvailableBlks = txHwQueue_CheckResources (pTxHwQueue, pQueueInfo);
    
    /* If we need more blocks than available, return  STOP_CURRENT (stop current queue and requeue packet). */
    if (uNumBlksToAlloc > uAvailableBlks)
    {
        TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": No resources, Queue=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, AvailBlks=%d, UsedPkts=%d\n", uQueueId, uNumBlksToAlloc, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, uAvailableBlks, pTxHwQueue->uNumUsedDescriptors);
        pQueueInfo->uNumBlksCausedBusy = uNumBlksToAlloc;
        pQueueInfo->bQueueBusy = TI_TRUE;

        return TX_HW_QUE_STATUS_STOP_CURRENT;  /**** Exit! (we should stop queue and requeue packet) ****/
    }

    /***********************************************************************/
    /*                    Allocate required resources                      */
    /***********************************************************************/

    /* Update blocks numbers in Tx descriptor */
    pTxCtrlBlk->tTxDescriptor.extraMemBlks = BLKS_HW_ALLOC_SPARE;
    pTxCtrlBlk->tTxDescriptor.totalMemBlks = uNumBlksToAlloc;

    /* Update packet allocation info:  */
    pTxHwQueue->uNumUsedDescriptors++; /* Update number of packets in FW (for descriptors allocation check). */
    pTxHwQueue->uDrvTxPacketsCntr++;
    pQueueInfo->uAllocatedBlksCntr += uNumBlksToAlloc; /* For FW counter coordination. */
    uReservedBlks = pQueueInfo->uNumBlksReserved;

    /* If we are currently using less than the low threshold (i.e. we have some reserved blocks), 
        blocks allocation should reduce the reserved blocks number as follows:
    */
    if (uReservedBlks)
    {

        /* If adding the allocated blocks to the used blocks will pass the low-threshold,
            only the part up to the low-threshold is subtracted from the reserved blocks.
            This is because blocks are reserved for the Queue only up to its low-threshold. 
            
              0   old used                    low      new used       high
              |######|                         |          |            |
              |######|                         |          |            |
                      <------------ allocated ----------->
                      <----- old reserved ---->
                             new reserved = 0     (we passed the low threshold)
        */
        if (uNumBlksToAlloc > uReservedBlks)
        {
            pQueueInfo->uNumBlksReserved = 0;
            pTxHwQueue->uNumTotalBlksReserved -= uReservedBlks; /* reduce change from total reserved.*/
        }


        /* Else, if allocating less than reserved,
            the allocated blocks are subtracted from the reserved blocks:
            
              0   old used       new used               low      high
              |######|               |                   |        |
              |######|               |                   |        |
                      <- allocated ->
                      <--------- old reserved ---------->
                                     <-- new reserved -->
        */
        else
        {
            pQueueInfo->uNumBlksReserved -= uNumBlksToAlloc;
            pTxHwQueue->uNumTotalBlksReserved -= uNumBlksToAlloc; /* reduce change from total reserved.*/
        }
    }


    /* Update total free blocks and Queue used blocks with the allocated blocks number. */
    pTxHwQueue->uNumTotalBlksFree -= uNumBlksToAlloc;
    pQueueInfo->uNumBlksUsed += uNumBlksToAlloc;

    TRACE7(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": SUCCESS,  Link=%d, Queue=%d, Req-blks=%d , Free=%d, Used=%d, Reserved=%d, Accumulated=%d\n", uHlid, uQueueId, uNumBlksToAlloc, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, pQueueInfo->uNumBlksReserved, pQueueInfo->uAllocatedBlksCntr);

#ifdef AP_MODE_ENABLED

    /* Update Link used blocks with the allocated blocks number. */
    pLinkInfo->uLastAllocNumBlks = uNumBlksToAlloc; /* used as prediction in free resources */
    pLinkInfo->uHostAlloc += uNumBlksToAlloc;
    /*
     * At this stage, the resources for this LINK and AC are allocated successfully
     * Need to check if there is a place for anothoer similar packet (LINK and AC resources)
     * return bitmap of STOP NEXT, for link if no link resources and for AC if no queue resources
     */

    /* If no resources for another similar packet, return STOP_NEXT (to stop current link). */
    /* Note: Current packet transmission is continued */
    if ( (uNumBlksToAlloc << 1) > uAvailableLinkBlks )
    {
        TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": No link resources for next packet, Link=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, uFwMax=%d, uAvailableLinkBlks=%d\n", 
               uHlid, uNumBlksToAlloc, pLinkInfo->uFwFree, pLinkInfo->uHostAlloc, pLinkInfo->uFwMax, uAvailableLinkBlks);
        pLinkInfo->bBusy = TI_TRUE;
        retStatus |= TX_HW_LINK_STATUS_STOP_NEXT;
    }
#endif

    /* If no resources for another similar packet, return STOP_NEXT (to stop current queue). */
    /* Note: Current packet transmission is continued */
    if ( (uNumBlksToAlloc << 1) > uAvailableBlks )
    {
        TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": No resources for next pkt, Queue=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, AvailBlks=%d, UsedPkts=%d\n", uQueueId, uNumBlksToAlloc, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, uAvailableBlks, pTxHwQueue->uNumUsedDescriptors);
        pQueueInfo->uNumBlksCausedBusy = uNumBlksToAlloc;
        pQueueInfo->bQueueBusy = TI_TRUE;
        retStatus |= TX_HW_QUE_STATUS_STOP_NEXT;
    }

    return retStatus;
}
/** 
 * \fn     mgmtQueuesSM
 * \brief  The module state-machine (static function)
 * 
 * The SM follows the system management states (see ETxConnState) and the Mgmt queues
 *   status (empty or not), and contorls the Tx queues flow accordingly (mgmt and data queues).
 * For detailed explanation, see the Tx-Path LLD document!
 * 
 * \note   To avoid recursion issues, all SM actions are done at the end of the function, 
 *            since some of them may invoke the SM again.
 * \param  pTxMgmtQ - The module's object                                          
 * \param  eSmEvent - The event to act upon                                          
 * \return void 
 * \sa     txMgmtQ_SetConnState
 */ 
static void mgmtQueuesSM (TTxMgmtQ *pTxMgmtQ, ESmEvent eSmEvent)
{
	ESmState  ePrevState = pTxMgmtQ->eSmState;
	ESmAction eSmAction  = SM_ACTION_NULL;

	switch(eSmEvent)
	{
		case SM_EVENT_CLOSE:
			/* 
			 * Tx link is closed (expected in any state), so disable both mgmt queues  
			 *   and if data-queues are active disable them via txPort module.
			 */
			pTxMgmtQ->eSmState = SM_STATE_CLOSE;
			pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_MGMT]  = TI_FALSE;
			pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_EAPOL] = TI_FALSE;
			if (ePrevState == SM_STATE_OPEN_DATA)
				eSmAction = SM_ACTION_ENABLE_MGMT;
			break;

		case SM_EVENT_MGMT:
			/* 
			 * Only Mgmt packets are permitted (expected from any state):
			 *   - Enable the mgmt queue and disable the Eapol queue.
			 *   - If data-queues are active disable them via txPort (this will run the scheduler).
			 *   - Else run the scheduler (to send mgmt packets if waiting).
			 */
			pTxMgmtQ->eSmState = SM_STATE_MGMT;
			pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_MGMT]  = TI_TRUE;
			pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_EAPOL] = TI_FALSE;
			if (ePrevState == SM_STATE_OPEN_DATA)
				eSmAction = SM_ACTION_ENABLE_MGMT;
			else
				eSmAction = SM_ACTION_RUN_SCHEDULER;
			break;

		case SM_EVENT_EAPOL:
			/* 
			 * EAPOL packets are also permitted (expected in MGMT or CLOSE state), so enable the 
			 *   EAPOL queue and run the scheduler (to send packets from EAPOL queue if waiting).
			 */
			if ( (ePrevState != SM_STATE_CLOSE) && (ePrevState != SM_STATE_MGMT) )
			{
TRACE1(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "mgmtQueuesSM: Got SmEvent=EAPOL when eSmState=%d\n", ePrevState);
			}
			pTxMgmtQ->eSmState = SM_STATE_EAPOL;
			pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_MGMT]  = TI_TRUE;
			pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_EAPOL] = TI_TRUE;
			eSmAction = SM_ACTION_RUN_SCHEDULER;
			break;

		case SM_EVENT_OPEN:
			/* 
			 * All packets are now permitted (expected in EAPOL state), so if the mgmt-queues
			 *   are empty disable them and enable the data queues via txPort module.
			 */
			if (ePrevState != SM_STATE_EAPOL)
			{
TRACE1(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "mgmtQueuesSM: Got SmEvent=OPEN when eSmState=%d\n", ePrevState);
			}
			if ( ARE_ALL_MGMT_QUEUES_EMPTY(pTxMgmtQ->aQueues) )
			{
				pTxMgmtQ->eSmState = SM_STATE_OPEN_DATA;
				pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_MGMT]  = TI_FALSE;
				pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_EAPOL] = TI_FALSE;
				eSmAction = SM_ACTION_ENABLE_DATA;
			}
			else
			{
				pTxMgmtQ->eSmState = SM_STATE_OPEN_MGMT;
			}
			break;

		case SM_EVENT_QUEUES_EMPTY:
			/* 
			 * The mgmt-queues are empty, so if in OPEN_MGMT state disable the 
			 *   mgmt-queues and enable the data-queues via txPort module.
			 */
			if (ePrevState == SM_STATE_OPEN_MGMT)
			{
				pTxMgmtQ->eSmState = SM_STATE_OPEN_DATA;
				pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_MGMT]  = TI_FALSE;
				pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_EAPOL] = TI_FALSE;
				eSmAction = SM_ACTION_ENABLE_DATA;
			}
			else
			{
				/* This may happen so it's just a warning and not an error. */
TRACE1(pTxMgmtQ->hReport, REPORT_SEVERITY_WARNING, "mgmtQueuesSM: Got SmEvent=QUEUES_EMPTY when eSmState=%d\n", ePrevState);
			}
			break;

		case SM_EVENT_QUEUES_NOT_EMPTY:

			/* A packet was inserted to the mgmt-queues */

			/* 
			 * If in OPEN_DATA state, enable mgmt-queues and disable data-queues via txPort module.
			 *
			 * Note: The scheduler is not run here because the txPort will call
			 *   txMgmtQueue_wakeAll() which will run the scheduler.
			 */
			if (ePrevState == SM_STATE_OPEN_DATA)
			{
				pTxMgmtQ->eSmState = SM_STATE_OPEN_MGMT;
				pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_MGMT]  = TI_TRUE;
				pTxMgmtQ->aQueueEnabledBySM[QUEUE_TYPE_EAPOL] = TI_TRUE;
				eSmAction = SM_ACTION_ENABLE_MGMT;
			}

			/* 
			 * If in MGMT or EAPOL state, run the scheduler to transmit the packet.
			 */
			else if ( (ePrevState == SM_STATE_MGMT) || (ePrevState == SM_STATE_EAPOL) )
			{
				eSmAction = SM_ACTION_RUN_SCHEDULER;
			}

			else
			{
				/* This may happen so it's just a warning and not an error. */
TRACE1(pTxMgmtQ->hReport, REPORT_SEVERITY_WARNING, "mgmtQueuesSM: Got SmEvent=QUEUES_NOT_EMPTY when eSmState=%d\n", ePrevState);
			}
			break;

		default:
TRACE1(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "mgmtQueuesSM: Unknown SmEvent = %d\n", eSmEvent);
			break;
	}

TRACE6( pTxMgmtQ->hReport, REPORT_SEVERITY_INFORMATION, "mgmtQueuesSM: <currentState = %d, event = %d> --> nextState = %d, action = %d, MgmtQueEnbl=%d, EapolQueEnbl=%d\n", ePrevState, eSmEvent, pTxMgmtQ->eSmState, eSmAction, pTxMgmtQ->aQueueEnabledBySM[0], pTxMgmtQ->aQueueEnabledBySM[1]);

	/* 
	 * Execute the required action. 
	 * Note: This is done at the end of the SM because it may start a sequence that will call the SM again!
	 */
	switch (eSmAction)
	{
		case SM_ACTION_NULL:
			break;

		case SM_ACTION_ENABLE_DATA:
			txPort_enableData(pTxMgmtQ->hTxPort);
			break;

		case SM_ACTION_ENABLE_MGMT:
			txPort_enableMgmt(pTxMgmtQ->hTxPort);
			break;

		case SM_ACTION_RUN_SCHEDULER:
			runScheduler(pTxMgmtQ);
			break;

		default:
TRACE1(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, ": Unknown SmAction = %d\n", eSmAction);
			break;
	}
}
/** 
 * \fn     busDrv_PrepareTxnParts
 * \brief  Prepare write or read transaction parts
 * 
 * Called by busDrv_Transact().
 * Prepares the actual sequence of SDIO bus transactions in a table.
 * Use a DMA-able buffer for the bus transaction, so all data is copied
 *     to it from the host buffer(s) before write transactions,
 *     or copied from it to the host buffers after read transactions.
 * 
 * \note   
 * \param  pBusDrv - The module's object
 * \param  pTxn    - The transaction object 
 * \return TRUE if we are in the middle of a Tx aggregation
 * \sa     busDrv_Transact, busDrv_SendTxnParts, 
 */ 
static TI_BOOL busDrv_PrepareTxnParts (TBusDrvObj *pBusDrv, TTxnStruct *pTxn)
{
    TI_UINT32 uPartNum     = 0;
    TI_UINT32 uCurrHwAddr  = pTxn->uHwAddr;
    TI_BOOL   bFixedHwAddr = TXN_PARAM_GET_FIXED_ADDR(pTxn);
    TI_BOOL   bWrite       = (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_WRITE) ? TI_TRUE : TI_FALSE;
    TI_UINT8 *pHostBuf     = bWrite ? pBusDrv->pTxDmaBuf : pBusDrv->pRxDmaBuf; /* Use DMA buffer (Rx or Tx) for actual transaction */
    TI_UINT32 uBufNum;
    TI_UINT32 uBufLen;
    TI_UINT32 uRemainderLen;

    /* Go over the transaction buffers */
    for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++) 
    {
        uBufLen = pTxn->aLen[uBufNum];

        /* If no more buffers, exit the loop */
        if (uBufLen == 0)
        {
            break;
        }

        /* For write transaction, copy the data to the DMA buffer */
        if (bWrite)
        {
            os_memoryCopy (pBusDrv->hOs, pHostBuf + pBusDrv->uTxnLength, pTxn->aBuf[uBufNum], uBufLen);
        }

        /* Add buffer length to total transaction length */
        pBusDrv->uTxnLength += uBufLen;
    }

    /* If in a Tx aggregation, return TRUE (need to accumulate all parts before sending the transaction) */
    if (TXN_PARAM_GET_AGGREGATE(pTxn) == TXN_AGGREGATE_ON)
    {
        TRACE6(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_PrepareTxnParts: In aggregation so exit, uTxnLength=%d, bWrite=%d, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n", pBusDrv->uTxnLength, bWrite, pTxn->aLen[0], pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);
        return TI_TRUE;
    }

    /* If current buffer has a remainder, prepare its transaction part */
    uRemainderLen = pBusDrv->uTxnLength & pBusDrv->uBlkSizeMask;
    if (uRemainderLen > 0)
    {
        pBusDrv->aTxnParts[uPartNum].bBlkMode  = TI_FALSE;
        pBusDrv->aTxnParts[uPartNum].uLength   = uRemainderLen;
        pBusDrv->aTxnParts[uPartNum].uHwAddr   = uCurrHwAddr;
        pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)pHostBuf;
        pBusDrv->aTxnParts[uPartNum].bMore     = TI_TRUE;

        /* If not fixed HW address, increment it by this part's size */
        if (!bFixedHwAddr)
        {
            uCurrHwAddr += uRemainderLen;
        }

        uPartNum++;
    }

#ifdef  DISABLE_SDIO_MULTI_BLK_MODE

    /* SDIO multi-block mode is disabled so split to 512 bytes blocks */
    {
        TI_UINT32 uLen;

        for (uLen = uRemainderLen; uLen < pBusDrv->uTxnLength; uLen += pBusDrv->uBlkSize)
        {
            pBusDrv->aTxnParts[uPartNum].bBlkMode  = TI_FALSE;
            pBusDrv->aTxnParts[uPartNum].uLength   = pBusDrv->uBlkSize;
            pBusDrv->aTxnParts[uPartNum].uHwAddr   = uCurrHwAddr;
            pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)(pHostBuf + uLen);
            pBusDrv->aTxnParts[uPartNum].bMore     = TI_TRUE;

            /* If not fixed HW address, increment it by this part's size */
            if (!bFixedHwAddr)
            {
                uCurrHwAddr += pBusDrv->uBlkSize;
            }

            uPartNum++;
        }
    }

#else  /* Use SDIO block mode (this is the default behavior) */

    /* If current buffer has full SDIO blocks, prepare a block-mode transaction part */
    if (pBusDrv->uTxnLength >= pBusDrv->uBlkSize)
    {
        pBusDrv->aTxnParts[uPartNum].bBlkMode  = TI_TRUE;
        pBusDrv->aTxnParts[uPartNum].uLength   = pBusDrv->uTxnLength - uRemainderLen;
        pBusDrv->aTxnParts[uPartNum].uHwAddr   = uCurrHwAddr;
        pBusDrv->aTxnParts[uPartNum].pHostAddr = (void *)(pHostBuf + uRemainderLen);
        pBusDrv->aTxnParts[uPartNum].bMore     = TI_TRUE;

        uPartNum++;
    }

#endif /* DISABLE_SDIO_MULTI_BLK_MODE */

    /* Set last More flag as specified for the whole Txn */
    pBusDrv->aTxnParts[uPartNum - 1].bMore = TXN_PARAM_GET_MORE(pTxn);
    pBusDrv->uCurrTxnPartsNum = uPartNum;

    TRACE9(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_PrepareTxnParts: Txn prepared, PartsNum=%d, bWrite=%d, uTxnLength=%d, uRemainderLen=%d, uHwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n", uPartNum, bWrite, pBusDrv->uTxnLength, uRemainderLen, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);

    pBusDrv->uTxnLength = 0;

    /* Return FALSE to indicate that we are not in the middle of a Tx aggregation so the Txn is ready to send */
    return TI_FALSE;
}
Exemple #22
0
/** 
 * \fn     mlme_assocRequestMsgBuild 
 * \brief  buils association request
 * 
 * The function builds the association request according to the given parames
 * 
 * \param  pCtx - pointer to mlme_t
 * \param  reqBuf - <output> pointer to built assoc request buffer
 * \param  reqLen - <output> length of built assoc request buffer
 * 
 * \return TI_OK if auth send successfully
 *         TI_NOK otherwise
 * 
 * \sa     mlme_sendAssocRequest 
 */ 
TI_STATUS mlme_assocRequestMsgBuild(mlme_t *pCtx, TI_UINT8* reqBuf, TI_UINT32* reqLen)
{
    TI_STATUS       status;
    TI_UINT8        *pRequest;
    TI_UINT32       len;
    paramInfo_t     param;
    TTwdParamInfo   tTwdParam;
    TI_UINT16       capabilities;
	TI_BOOL spectrumManagementEnabled;
	ECipherSuite    eCipherSuite = TWD_CIPHER_NONE; /* To be used for checking whether

                                                       AP supports HT rates and TKIP */
    pRequest = reqBuf;
    *reqLen = 0;


    /* insert capabilities */
    status = mlme_assocCapBuild(pCtx, &capabilities);
    if (status == TI_OK)
    {
         *(TI_UINT16*)pRequest = ENDIAN_HANDLE_WORD(capabilities);
    }
    else
	{
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build assoc Capa\n");
        return TI_NOK;
	}

    pRequest += sizeof(TI_UINT16);
    *reqLen += sizeof(TI_UINT16);

    /* insert listen interval */
    tTwdParam.paramType = TWD_LISTEN_INTERVAL_PARAM_ID;
    status =  TWD_GetParam (pCtx->hTWD, &tTwdParam);
    if (status == TI_OK)
    {
        *(TI_UINT16*)pRequest = ENDIAN_HANDLE_WORD((TI_UINT16)tTwdParam.content.halCtrlListenInterval);
    } else {
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to get listen interval\n");
        return TI_NOK;
    }

    pRequest += sizeof(TI_UINT16);
    *reqLen += sizeof(TI_UINT16);

	if (pCtx->reAssoc)
    {   /* Insert currentAPAddress element only in reassoc request*/
        param.paramType = SITE_MGR_PREV_SITE_BSSID_PARAM;
        status = siteMgr_getParam(pCtx->hSiteMgr, &param);
        if (status == TI_OK)
        {
            MAC_COPY (pRequest, param.content.siteMgrDesiredBSSID);
            TRACE6(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - prev AP = %x-%x-%x-%x-%x-%x\n", param.content.siteMgrDesiredBSSID[0], param.content.siteMgrDesiredBSSID[1], param.content.siteMgrDesiredBSSID[2], param.content.siteMgrDesiredBSSID[3], param.content.siteMgrDesiredBSSID[4], param.content.siteMgrDesiredBSSID[5]);


            pRequest += MAC_ADDR_LEN;
            *reqLen += MAC_ADDR_LEN;
        }
        else
        {
            TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: ASSOC_REQ - No prev AP \n");
            return status;

        }
    }

    /* insert SSID element */
    status = mlme_assocSSIDBuild(pCtx, pRequest, &len);
    if (status != TI_OK)
    {
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build SSID IE\n");
        return TI_NOK;
    }

    pRequest += len;
    *reqLen += len;

    /* insert Rates element */
    status = mlme_assocRatesBuild(pCtx, pRequest, &len);
    if (status != TI_OK)
    {
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build rates IE\n");
        return TI_NOK;
    }
    pRequest += len;
    *reqLen += len;

	/* Checking if the station supports Spectrum Management (802.11h) */
    param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
    status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain,&param);
	spectrumManagementEnabled = param.content.spectrumManagementEnabled;

	/* Checking the selected AP capablities */
    param.paramType = SITE_MGR_SITE_CAPABILITY_PARAM;
    status =  siteMgr_getParam(pCtx->hSiteMgr,&param);
    if (status == TI_OK &&
    		spectrumManagementEnabled &&
    		param.content.siteMgrSiteCapability & (DOT11_SPECTRUM_MANAGEMENT != 0))
    {
         /* insert Power capability element */
         status = mlme_assocPowerCapabilityBuild(pCtx, pRequest, &len);
         if (status != TI_OK)
         {
			 TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build Power IE\n");
             return TI_NOK;
         }
         pRequest += len;
         *reqLen += len;
    }


#ifdef XCC_MODULE_INCLUDED
    status = rsn_getXCCExtendedInfoElement(pCtx->hRsn, pRequest, (TI_UINT8*)&len);
    if (status != TI_OK)
    {
        return TI_NOK;
    }
    pRequest += len;
    *reqLen += len;

    if (pCtx->reAssoc)
    {   /* insert CCKM information element only in reassoc */
        status = XCCMngr_getCckmInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len);

        if (status != TI_OK)
        {
            return TI_NOK;
        }
        pRequest += len;
        *reqLen += len;
    }
    status = XCCMngr_getXCCVersionInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len);
    if (status != TI_OK)
    {
        return TI_NOK;
    }
    pRequest += len;
    *reqLen += len;

    /* Insert Radio Mngt Capability IE */
    status = measurementMgr_radioMngtCapabilityBuild(pCtx->hMeasurementMgr, pRequest, (TI_UINT8*)&len);
    if (status != TI_OK)
    {
        return TI_NOK;
    }
    pRequest += len;
    *reqLen += len;
#endif

     /* Get Simple-Config state */
    param.paramType = SITE_MGR_SIMPLE_CONFIG_MODE;
    status = siteMgr_getParam(pCtx->hSiteMgr, &param);

   if (param.content.siteMgrWSCMode.WSCMode == TIWLN_SIMPLE_CONFIG_OFF)
   {
   /* insert RSN information elements */
    status = rsn_getInfoElement(pCtx->hRsn, pRequest, &len);

	if (status != TI_OK)
	{
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build RSN IE\n");
		return TI_NOK;
	}
	pRequest += len;
	*reqLen += len;
  }

  /* Privacy - Used later on HT */

    param.paramType = RSN_ENCRYPTION_STATUS_PARAM;

    status          = rsn_getParam(pCtx->hRsn, &param);



    if(status == TI_OK)

    {

        eCipherSuite = param.content.rsnEncryptionStatus;

    }



	/* insert QoS capability information element */
    status = qosMngr_getQosCapabiltyInfeElement(pCtx->hQosMngr,pRequest,&len);
    if (status != TI_OK)
    {
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build QoS capa IE\n");
        return TI_NOK;
    }
    pRequest += len;
    *reqLen += len;


    /* Primary Site support HT ? */
    param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT;
    siteMgr_getParam(pCtx->hSiteMgr, &param);


    /* Disallow TKIP with HT Rates: If this is the case - discard HT rates from Association Request */
    if((TI_TRUE == param.content.bPrimarySiteHtSupport) && (eCipherSuite != TWD_CIPHER_TKIP))
    {

        status = StaCap_GetHtCapabilitiesIe (pCtx->hStaCap, pRequest, &len);
    	if (status != TI_OK)
    	{
    		return TI_NOK;
    	}
    	pRequest += len;
    	*reqLen += len;
    }

	status = qosMngr_assocReqBuild(pCtx->hQosMngr,pRequest,&len);
	if (status != TI_OK)
	{
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build QoS IE\n");
		return TI_NOK;
	}
	pRequest += len;
	*reqLen += len;

	status = apConn_getVendorSpecificIE(pCtx->hApConn, pRequest, &len);
	if (status != TI_OK)
	{
		TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build vendor IE\n");
		return TI_NOK;
	}
	pRequest += len;
	*reqLen += len;

    if (*reqLen>=MAX_ASSOC_MSG_LENGTH)
    {
		TRACE1(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build, reqLen = %u\n", *reqLen);
        return TI_NOK;
    }



    return TI_OK;
}
Exemple #23
0
/** 
 * \fn     smeSm_PreConnect
 * \brief  Initiates the connection process
 * 
 * Initiates the connection process - for automatic mode, start scan, for manual mode - triggers connection
 * 
 * \param  hSme - handle to the SME object
 * \return None
 * \sa     smeSm_Connect, smeSm_ConnectSuccess
 */ 
void smeSm_PreConnect (TI_HANDLE hSme)
{
    TSme *pSme = (TSme *)hSme;
    paramInfo_t	*pParam;
//joetest
TRACE0(pSme->hReport, REPORT_SEVERITY_SM , "smeSm_PreConnect: !!!\n");
    /* set the connection mode with which this connection attempt is starting */
    pSme->eLastConnectMode = pSme->eConnectMode;
 
    /* mark that no authentication/assocaition was yet sent */
    pSme->bAuthSent = TI_FALSE;

    /* try to find a connection candidate (manual mode have already performed scann */
    pSme->pCandidate = sme_Select (hSme);
    if (NULL != pSme->pCandidate)
    {
        /* candidate is available - attempt connection */
        sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme);
    }
    /* no candidate */
    else
    {
        if (CONNECT_MODE_AUTO == pSme->eConnectMode)
        {
            /* automatic mode - start scanning */
            if (TI_OK != sme_StartScan (hSme))
            {
                TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "smeSm_PreConnect: unable to start scan, stopping the SME\n");
                pSme->bRadioOn = TI_FALSE;
                sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme);
            }

            /* update scan count counter */
            if(pSme->uScanCount < PERIODIC_SCAN_MAX_INTERVAL_NUM)
            {
                pSme->uScanCount++;
            }

        }
        else		/* Manual mode */ 
        { 
			/* for IBSS or any, if no entries where found, add the self site */
			if (pSme->eBssType == BSS_INFRASTRUCTURE)
            {
                /* makr whether we need to stop the attempt connection in manual mode */
                pSme->bConnectRequired = TI_FALSE;
    
                TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "smeSm_PreConnect: No candidate available, sending connect failure\n");
                /* manual mode and no connection candidate is available - connection failed */
 //joetest
TRACE0(pSme->hReport, REPORT_SEVERITY_SM , "smeSm_PreConnect!!!\n");
			}

			else		/* IBSS */
			{
				TI_UINT8     uDesiredChannel;     
                TI_BOOL     channelValidity;
		        pSme->bConnectRequired = TI_FALSE;

                pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t));
                if (!pParam)
                {
                    return;
                }

				pParam->paramType = SITE_MGR_DESIRED_CHANNEL_PARAM;
				siteMgr_getParam(pSme->hSiteMgr, pParam);
				uDesiredChannel = pParam->content.siteMgrDesiredChannel;

				if (uDesiredChannel >= SITE_MGR_CHANNEL_A_MIN)
				{
				   pParam->content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ;
				} 
				else 
				{
				   pParam->content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ;
				}

				/*
				update the regulatory domain with the selected band
				*/
				/* Check if the selected channel is valid according to regDomain */
				pParam->paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
				pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
				pParam->content.channelCapabilityReq.channelNum = uDesiredChannel;

				regulatoryDomain_getParam (pSme->hRegDomain,pParam);
                channelValidity = pParam->content.channelCapabilityRet.channelValidity;
                os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t));
				if (!channelValidity)
				{
				   TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "IBSS SELECT FAILURE  - No channel !!!\n\n");

				   sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme);

				   return;
				}

				pSme->pCandidate = (TSiteEntry *)addSelfSite(pSme->hSiteMgr);

				if (pSme->pCandidate == NULL)
				{
				   TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "IBSS SELECT FAILURE  - could not open self site !!!\n\n");

				   sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme);

				   return;
				}

#ifdef REPORT_LOG    
				TRACE6(pSme->hReport, REPORT_SEVERITY_CONSOLE,"%%%%%%%%%%%%%%	SELF SELECT SUCCESS, bssid: %X-%X-%X-%X-%X-%X	%%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5]);
                WLAN_OS_REPORT (("%%%%%%%%%%%%%%	SELF SELECT SUCCESS, bssid: %02x.%02x.%02x.%02x.%02x.%02x %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5]));
#endif
				/* a connection candidate is available, send a connect event */
				sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme);
			}
        }
    }
}
/************************************************************************
 *                        findAndInsertSiteEntry									*
 ************************************************************************
DESCRIPTION: Perform the following things:
			-	Compute the site's hash entry based on the site BSSID and hash function
			-	Look for the site entry in the linked list pointed by the hash entry
			-	If the site is found in the site table, returns a pointer to the site entry
			-	If the site is not found in the site table, tries to add the site
				-	If succeeds, returns a pointer to the site entry
				-	Otherwise, returns NULL

INPUT:      pSiteMgr	-	Handle to site mgr
			mac			-	The site BSSID
            band        -   The site band


OUTPUT:

RETURN:     Pointer to the site entry if site found/inserted, NULL otherwise

************************************************************************/
siteEntry_t	*findAndInsertSiteEntry(siteMgr_t		*pSiteMgr,
                                    TMacAddr    	*mac,
                                    ERadioBand      band)
{
	TI_UINT8             i, emptySiteIndex=0, nextSite2Remove=0;
	siteEntry_t         *pSiteEntry, *pPrimarySite=pSiteMgr->pSitesMgmtParams->pPrimarySite;
	sitesMgmtParams_t   *pSitesMgmtParams  = pSiteMgr->pSitesMgmtParams;
	siteTablesParams_t  *pCurrentSiteTable;
	TI_BOOL              firstEmptySiteFound = TI_FALSE;
	TI_UINT32            oldestTS;


	/* choose site table according to AP's band */
	if ( RADIO_BAND_2_4_GHZ == band ) {
		pCurrentSiteTable = &(pSitesMgmtParams->dot11BG_sitesTables);
	} else if (RADIO_BAND_5_0_GHZ == band) {
		pCurrentSiteTable = (siteTablesParams_t*) &(pSitesMgmtParams->dot11A_sitesTables);
	} else {
		TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "Bad band: %d\n\n", band);
		pCurrentSiteTable = &(pSitesMgmtParams->dot11BG_sitesTables);
	}

	/* Set the first TS to a site which is not the Primary site */
	if (pPrimarySite != &(pCurrentSiteTable->siteTable[0])) {
		oldestTS = pCurrentSiteTable->siteTable[0].localTimeStamp;
	} else {
		oldestTS = pCurrentSiteTable->siteTable[1].localTimeStamp;
	}
	/* It looks like it never happens. Anyway decided to check */
	if ( pCurrentSiteTable->maxNumOfSites > MAX_SITES_BG_BAND ) {
		TRACE2( pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		        "findAndInsertSiteEntry. pCurrentSiteTable->maxNumOfSites=%d exceeds the limit %d\n",
		        pCurrentSiteTable->maxNumOfSites, MAX_SITES_BG_BAND);
		handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
		return NULL;
	}
	/* Loop all the sites till the desired MAC is found */
	for (i = 0; i < pCurrentSiteTable->maxNumOfSites; i++) {
		pSiteEntry = &(pCurrentSiteTable->siteTable[i]);

		if (MAC_EQUAL (pSiteEntry->bssid, *mac)) {

			TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "FIND success, bssid: %X-%X-%X-%X-%X-%X\n\n", (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]);

			return pSiteEntry;
		} else if (pSiteEntry->siteType == SITE_NULL) {
			/* Save the first empty site, in case the
			desired MAC is not found */
			if (!firstEmptySiteFound) {
				emptySiteIndex = i;
				firstEmptySiteFound=TI_TRUE;
			}

		} else if (oldestTS == pSiteEntry->localTimeStamp) {
			/* Save the oldest site's index, according to TS */
			nextSite2Remove = i;
		}
	}

	TRACE4(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "INSERT failure, no free entry!, oldestTS=%d, nextSite2Remove=%d, "
	       "[0].localTimeStamp=%d, [1]localTimeStamp%d \n",
	       oldestTS, nextSite2Remove,
	       pCurrentSiteTable->siteTable[0].localTimeStamp,
	       pCurrentSiteTable->siteTable[1].localTimeStamp);

	if ((!firstEmptySiteFound) || (pCurrentSiteTable->numOfSites>=pCurrentSiteTable->maxNumOfSites)) {
		/* No NULL entry has been found. Remove the oldest site */
		pSiteEntry =  &(pCurrentSiteTable->siteTable[nextSite2Remove]);
		TRACE9(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "INSERT failure, no free entry!, numOfSites=%d, removing site index=%d,\n                                bssid: %X-%X-%X-%X-%X-%X, ts=%d \n", pCurrentSiteTable->numOfSites, nextSite2Remove, pSiteEntry->bssid[0], pSiteEntry->bssid[1], pSiteEntry->bssid[2], pSiteEntry->bssid[3], pSiteEntry->bssid[4], pSiteEntry->bssid[5], pSiteEntry->localTimeStamp);
		removeSiteEntry(pSiteMgr, pCurrentSiteTable, pSiteEntry);
		emptySiteIndex = nextSite2Remove;

	}


	pCurrentSiteTable->numOfSites++;

	pSiteEntry = &(pCurrentSiteTable->siteTable[emptySiteIndex]);

	/* fill the entry with the station mac */
	MAC_COPY (pSiteEntry->bssid, *mac);

	/* Some parameters have to be initialized immediately after entry allocation */

	if(pSiteMgr->siteMgrOperationalMode == DOT11_G_MODE)
		pSiteEntry->currentSlotTime = pSiteMgr->pDesiredParams->siteMgrDesiredSlotTime;

	TRACE8(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "INSERT success, bssid: %X-%X-%X-%X-%X-%X, band=%d, index=%d\n\n", (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5], band, emptySiteIndex);


	return pSiteEntry;
}
Exemple #25
0
/****************************************************************************
 *                  txHwQueue_UpdateFreeResources()
 ****************************************************************************
 * DESCRIPTION:
   ===========
   Called by FwEvent upon Data interrupt to update freed HW-Queue resources as follows:
    1) For all queues, update blocks and descriptors numbers according to FwStatus information.
    2) For each busy queue, if now available indicate it in the backpressure bitmap.
 ****************************************************************************/
ETxnStatus txHwQueue_UpdateFreeResources (TI_HANDLE hTxHwQueue, FwStatus_t *pFwStatus)
{
	TTxHwQueue *pTxHwQueue = (TTxHwQueue *)hTxHwQueue;
	TTxHwQueueInfo *pQueueInfo;
	TI_UINT32 uQueueId;
	TI_UINT32 uAvailableBlks; /* Max blocks available for current queue. */
	TI_UINT32 uNewNumUsedDescriptors;
	TI_UINT32 uBackpressure = 0;
	TI_UINT32 *pFreeBlocks = (TI_UINT32 *)pFwStatus->txReleasedBlks;
	TI_UINT32 uTempFwCounters;
	FwStatCntrs_t *pFwStatusCounters;

	/*
	 * If TxResults counter changed in FwStatus, update descriptors number according to  information
	 */
	uTempFwCounters = (ENDIAN_HANDLE_LONG(pFwStatus->counters));
	pFwStatusCounters = (FwStatCntrs_t *)&uTempFwCounters;
	if (pFwStatusCounters->txResultsCntr != pTxHwQueue->uFwTxResultsCntr)
	{
		pTxHwQueue->uFwTxResultsCntr = pFwStatusCounters->txResultsCntr;

		/* Calculate new number of used descriptors (the else is for wrap around case) */
		if (pTxHwQueue->uFwTxResultsCntr <= pTxHwQueue->uDrvTxPacketsCntr)
		{
			uNewNumUsedDescriptors = (TI_UINT32)(pTxHwQueue->uDrvTxPacketsCntr - pTxHwQueue->uFwTxResultsCntr);
		}
		else
		{
			uNewNumUsedDescriptors = 0x100 - (TI_UINT32)(pTxHwQueue->uFwTxResultsCntr - pTxHwQueue->uDrvTxPacketsCntr);
		}

#ifdef TI_DBG   /* Sanity check: make sure we don't free more descriptors than allocated. */
		if (uNewNumUsedDescriptors >= pTxHwQueue->uNumUsedDescriptors)
		{
			TRACE2(pTxHwQueue->hReport, REPORT_SEVERITY_ERROR, ":  Used descriptors number should decrease: UsedDesc %d, NewUsedDesc %d\n", pTxHwQueue->uNumUsedDescriptors, uNewNumUsedDescriptors);
		}
#endif

		/* Update number of packets left in FW (for descriptors allocation check). */
		pTxHwQueue->uNumUsedDescriptors = uNewNumUsedDescriptors;
	}

	/*
	 * For all queues, update blocks numbers according to FwStatus information
	 */
	for (uQueueId = 0; uQueueId < MAX_NUM_OF_AC; uQueueId++)
	{
		pQueueInfo = &(pTxHwQueue->aTxHwQueueInfo[uQueueId]);

		/* Update per queue number of used, free and reserved blocks. */
		txHwQueue_UpdateFreeBlocks (pTxHwQueue, uQueueId, pFreeBlocks[uQueueId]);
	}

	/*
	 * For each busy queue, if now available indicate it in the backpressure bitmap
	 */
	for (uQueueId = 0; uQueueId < MAX_NUM_OF_AC; uQueueId++)
	{
		pQueueInfo = &(pTxHwQueue->aTxHwQueueInfo[uQueueId]);

		/* If the queue was stopped */
		if (pQueueInfo->bQueueBusy)
		{
			/* Find max available blocks for this queue (0 could indicate no descriptors). */
			uAvailableBlks = txHwQueue_CheckResources (pTxHwQueue, pQueueInfo);

			/* If the required blocks and a descriptor are available,
			     set the queue's backpressure bit to indicate NOT-busy! */
			if (pQueueInfo->uNumBlksCausedBusy <= uAvailableBlks)
			{
				TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": Queue Available, Queue=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, AvailBlks=%d, UsedPkts=%d\n", uQueueId, pQueueInfo->uNumBlksCausedBusy, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, uAvailableBlks, pTxHwQueue->uNumUsedDescriptors);
				SET_QUEUE_BACKPRESSURE(&uBackpressure, uQueueId); /* Start queue. */
				pQueueInfo->bQueueBusy = TI_FALSE;
			}
		}
	}

	/* If released queues map is not 0, send it to the upper layers (if CB available) */
	if ((uBackpressure > 0) && (pTxHwQueue->fUpdateBusyMapCb != NULL))
	{
		pTxHwQueue->fUpdateBusyMapCb (pTxHwQueue->hUpdateBusyMapHndl, uBackpressure);
	}

	return TXN_STATUS_COMPLETE;
}
Exemple #26
0
/****************************************************************************
 *                  txHwQueue_AllocResources()
 ****************************************************************************
 * DESCRIPTION:
   ============
    1.  Estimate required HW-blocks number.
    2.  If the required blocks are not available or no free descriptor,
            return  STOP_CURRENT  (to stop current queue and requeue the packet).
    3.  Resources are available so update allocated blocks and descriptors counters.
    4.  If no resources for another similar packet, return STOP_NEXT (to stop current queue).
        Else, return SUCCESS
 ****************************************************************************/
ETxHwQueStatus txHwQueue_AllocResources (TI_HANDLE hTxHwQueue, TTxCtrlBlk *pTxCtrlBlk)
{
    TTxHwQueue *pTxHwQueue = (TTxHwQueue *)hTxHwQueue;
    TI_UINT32 uTotalLength;    /* The current packet length plus overhead due to header translation */
    TI_UINT32 uNumBlksToAlloc; /* The number of blocks required for the current packet. */
    TI_UINT32 uExcludedLength; /* The data length not included in the rough blocks calculation */
    TI_UINT32 uAvailableBlks;  /* Max blocks that are currently available for this queue. */
    TI_UINT32 uReservedBlks;   /* How many blocks are reserved for this queue before this allocation. */
    TI_UINT32 uQueueId = WMEQosTagToACTable[pTxCtrlBlk->tTxDescriptor.tid];
    TTxHwQueueInfo *pQueueInfo = &(pTxHwQueue->aTxHwQueueInfo[uQueueId]);


    /***********************************************************************/
    /*  Calculate packet required HW blocks.                               */
    /***********************************************************************/

    uTotalLength = pTxCtrlBlk->tTxDescriptor.length + 20 + MAX_HEADER_SIZE - ETHERNET_HDR_LEN;
#ifdef TNETW1283
    if (pTxHwQueue->uHostIfCfgBitmap & HOST_IF_CFG_BITMAP_TX_PAD_TO_SDIO_BLK)
    {
        TI_UINT32 uBlockMask = ((1 << pTxHwQueue->uSdioBlkSizeShift) - 1);
        uTotalLength = (uTotalLength + uBlockMask) & (~uBlockMask);
    }
#endif
    /* Divide length by 256 instead of 252 (block size) to save CPU */
    uNumBlksToAlloc = uTotalLength >> 8;

    /* The length not yet included in the uNumBlksToAlloc is the sum of:
        1) 4 bytes per block as a result of using 256 instead of 252 block size.
        2) The remainder of the division by 256.
        3) Overhead due to header translation, security and LLC header (subtracting ethernet header).
    */
    uExcludedLength = (uNumBlksToAlloc << 2) + (uTotalLength & 0xFF);

    /* Add 1 or 2 blocks for the excluded length, according to its size */
    uNumBlksToAlloc += (uExcludedLength > 252) ? 2 : 1;

    /* Add extra blocks needed in case of fragmentation */
    uNumBlksToAlloc += pTxHwQueue->uExtraHwBlocks;

    /***********************************************************************/
    /*            Check if the required resources are available            */
    /***********************************************************************/

    /* Find max available blocks for this queue (0 could indicate no descriptors). */
    uAvailableBlks = txHwQueue_CheckResources (pTxHwQueue, pQueueInfo);

    /* If we need more blocks than available, return  STOP_CURRENT (stop current queue and requeue packet). */
    if (uNumBlksToAlloc > uAvailableBlks)
    {
        TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": No resources, Queue=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, AvailBlks=%d, UsedPkts=%d\n", uQueueId, uNumBlksToAlloc, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, uAvailableBlks, pTxHwQueue->uNumUsedDescriptors);
        pQueueInfo->uNumBlksCausedBusy = uNumBlksToAlloc;
        pQueueInfo->bQueueBusy = TI_TRUE;

        return TX_HW_QUE_STATUS_STOP_CURRENT;  /**** Exit! (we should stop queue and requeue packet) ****/
    }

    /***********************************************************************/
    /*                    Allocate required resources                      */
    /***********************************************************************/

    /* Update blocks numbers in Tx descriptor */
#ifdef TNETW1283
    /* in 1283, no need of extra mem blocks setting to the hardware */
    /* set total blocks in the extra blocks field, FW will deliver only total blocks */

    /* !!!!!!!!!!!!!just for test - swap fields - OK for HW, fw will have the value on other field */
    pTxCtrlBlk->tTxDescriptor.totalMemBlks = uNumBlksToAlloc;
#else
    pTxCtrlBlk->tTxDescriptor.extraMemBlks = pTxHwQueue->uExtraHwBlocks;
    pTxCtrlBlk->tTxDescriptor.totalMemBlks = uNumBlksToAlloc;
#endif

    /* Update packet allocation info:  */
    pTxHwQueue->uNumUsedDescriptors++; /* Update number of packets in FW (for descriptors allocation check). */
    pTxHwQueue->uDrvTxPacketsCntr++;
    pQueueInfo->uAllocatedBlksCntr += uNumBlksToAlloc; /* For FW counter coordination. */
    uReservedBlks = pQueueInfo->uNumBlksReserved;

    /* If we are currently using less than the low threshold (i.e. we have some reserved blocks),
        blocks allocation should reduce the reserved blocks number as follows:
    */
    if (uReservedBlks)
    {

        /* If adding the allocated blocks to the used blocks will pass the low-threshold,
            only the part up to the low-threshold is subtracted from the reserved blocks.
            This is because blocks are reserved for the Queue only up to its low-threshold.

              0   old used                    low      new used       high
              |######|                         |          |            |
              |######|                         |          |            |
                      <------------ allocated ----------->
                      <----- old reserved ---->
                             new reserved = 0     (we passed the low threshold)
        */
        if (uNumBlksToAlloc > uReservedBlks)
        {
            pQueueInfo->uNumBlksReserved = 0;
            pTxHwQueue->uNumTotalBlksReserved -= uReservedBlks; /* reduce change from total reserved.*/
        }


        /* Else, if allocating less than reserved,
            the allocated blocks are subtracted from the reserved blocks:

              0   old used       new used               low      high
              |######|               |                   |        |
              |######|               |                   |        |
                      <- allocated ->
                      <--------- old reserved ---------->
                                     <-- new reserved -->
        */
        else
        {
            pQueueInfo->uNumBlksReserved -= uNumBlksToAlloc;
            pTxHwQueue->uNumTotalBlksReserved -= uNumBlksToAlloc; /* reduce change from total reserved.*/
        }
    }


    /* Update total free blocks and Queue used blocks with the allocated blocks number. */
    pTxHwQueue->uNumTotalBlksFree -= uNumBlksToAlloc;
    pQueueInfo->uNumBlksUsed += uNumBlksToAlloc;

    TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": SUCCESS,  Queue=%d, Req-blks=%d , Free=%d, Used=%d, Reserved=%d, Accumulated=%d\n", uQueueId, uNumBlksToAlloc, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, pQueueInfo->uNumBlksReserved, pQueueInfo->uAllocatedBlksCntr);

    /* If no resources for another similar packet, return STOP_NEXT (to stop current queue). */
    /* Note: Current packet transmission is continued */
    if ( (uNumBlksToAlloc << 1) > uAvailableBlks )
    {
        TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": No resources for next pkt, Queue=%d, ReqBlks=%d, FreeBlks=%d, UsedBlks=%d, AvailBlks=%d, UsedPkts=%d\n", uQueueId, uNumBlksToAlloc, pTxHwQueue->uNumTotalBlksFree, pQueueInfo->uNumBlksUsed, uAvailableBlks, pTxHwQueue->uNumUsedDescriptors);
        pQueueInfo->uNumBlksCausedBusy = uNumBlksToAlloc;
        pQueueInfo->bQueueBusy = TI_TRUE;
        return TX_HW_QUE_STATUS_STOP_NEXT;
    }

    /* Return SUCCESS (resources are available). */
    return TX_HW_QUE_STATUS_SUCCESS;
}
Exemple #27
0
int __darwin_sysctl(int* name, unsigned int namelen,
                    void* oldp, size_t* oldlenp,
                    void* newp, size_t newlen)
{
	TRACE6(name, namelen, oldp, oldlenp, newp, newlen);
	
	LOG << "sysctl: namelen=" << namelen;
	for (int i = 0; i < namelen; i++)
		LOG << " name[" << i << "]=" << name[i];
	LOG << " newp=" << newp << std::endl;

	if (newp)
	{
		LOG << "sysctl with newp isn't supported yet.\n";
		errno = DARWIN_EINVAL;
		return -1;
	}

	if (namelen != 2)
	{
		LOG << "sysctl with namelen=" << namelen << " isn't supported yet.\n";
		errno = DARWIN_EINVAL;
		return -1;
	}

	switch (name[0])
	{
	case CTL_HW:
	{
		if (*oldlenp != 4 && *oldlenp != 8)
		{
			LOG << "sysctl(HW) with oldlenp=" << *oldlenp << " isn't supported yet.\n";
			errno = DARWIN_EINVAL;
			return -1;
		}

		uint64_t val = 0;
		switch (name[1])
		{
		case HW_NCPU:
			val = ::sysconf(_SC_NPROCESSORS_CONF);
			break;
		case HW_AVAILCPU:
			val = ::sysconf(_SC_NPROCESSORS_ONLN);
			break;
		case HW_PHYSMEM:
		case HW_USERMEM:
		case HW_MEMSIZE:
		{
			long pages = ::sysconf(_SC_PHYS_PAGES);
			long page_size = ::sysconf(_SC_PAGE_SIZE);
			val = pages * page_size;
			break;
		}

		default:
			LOG << "sysctl(HW) with name[1]=" << name[1] << " isn't supported yet.\n";
        
			errno = DARWIN_EINVAL;
			return -1;
		}

		if (oldp)
		{
			if (*oldlenp == 4)
				*reinterpret_cast<uint32_t*>(oldp) = val;
			else if (*oldlenp == 8)
				*reinterpret_cast<uint64_t*>(oldp) = val;
		}
		else
			*oldlenp = sizeof(long);
		return 0;
    }

	case CTL_KERN:
	{
		switch (name[1])
		{
			case KERN_OSRELEASE:
				
				// TODO: use real uname?
				if (oldp)
					strcpy((char*)oldp, "10.7.0");
				*oldlenp = 7;
				break;
				
			case KERN_OSVERSION:
				if (oldp)
					strcpy((char*)oldp, "10J869");
				*oldlenp = 7;
				break;
				
			case KERN_BOOTTIME:
			{
				struct timeval tv;
				struct sysinfo si;
				
				if (*oldlenp < sizeof(struct timeval))
				{
					errno = DARWIN_ENOMEM;
					return -1;
				}
				
				sysinfo(&si);
				gettimeofday(&tv, nullptr);
				tv.tv_sec -= si.uptime;
				
				*oldlenp = sizeof(struct timeval);
				memcpy(oldp, &tv, sizeof(tv));
				return 0;
			}

			default:
				LOG << "sysctl(KERN) with name[1]=" << name[1] << " isn't supported yet.\n";
				errno = DARWIN_EINVAL;
				return -1;
		}
		return 0;
	}

	default:
		LOG << "sysctl with name[0]=" << name[0] << " isn't supported yet.\n";
		errno = DARWIN_EINVAL;
		return -1;
	}
}
Exemple #28
0
/****************************************************************************
 *                  txHwQueue_UpdateFreeResources()
 ****************************************************************************
 * DESCRIPTION: 
   ===========
   Called by FwEvent upon Data interrupt to update freed HW-Queue resources as follows:
    1) For all queues, update blocks and descriptors numbers according to FwStatus information.
    2) For each busy queue, if now available indicate it in the backpressure bitmap.
 ****************************************************************************/
ETxnStatus txHwQueue_UpdateFreeResources (TI_HANDLE hTxHwQueue, FwStatus_t *pFwStatus)
{
    TTxHwQueue *pTxHwQueue = (TTxHwQueue *)hTxHwQueue;
    TTxHwQueueInfo *pQueueInfo;
    TI_UINT32 uQueueId;
    TI_UINT32 uAvailableBlks; /* Max blocks available for current queue. */
    TI_UINT32 uNewNumUsedDescriptors;
    TI_UINT32 uBackpressure = 0;
    TI_UINT32 *pFreeQueueBlocks = (TI_UINT32 *)pFwStatus->txReleasedBlks;
    TI_UINT32 uTempFwCounters;
    FwStatCntrs_t *pFwStatusCounters;
    TI_BOOL uLinkInfoChanged = TI_FALSE;
    TI_UINT32 uLinkBackpressure = 0;
#ifdef AP_MODE_ENABLED
    TI_UINT32 uHlid;
#endif

    /* 
     * If TxResults counter changed in FwStatus, update descriptors number according to  information 
     */
    uTempFwCounters = (ENDIAN_HANDLE_LONG(pFwStatus->counters));
    pFwStatusCounters = (FwStatCntrs_t *)&uTempFwCounters;
    if (pFwStatusCounters->txResultsCntr != pTxHwQueue->uFwTxResultsCntr) 
    {
        pTxHwQueue->uFwTxResultsCntr = pFwStatusCounters->txResultsCntr; 

        /* Calculate new number of used descriptors (the else is for wrap around case) */
        if (pTxHwQueue->uFwTxResultsCntr <= pTxHwQueue->uDrvTxPacketsCntr) 
        {
            uNewNumUsedDescriptors = (TI_UINT32)(pTxHwQueue->uDrvTxPacketsCntr - pTxHwQueue->uFwTxResultsCntr);
        }
        else 
        {
            uNewNumUsedDescriptors = 0x100 - (TI_UINT32)(pTxHwQueue->uFwTxResultsCntr - pTxHwQueue->uDrvTxPacketsCntr);
        }
    
#ifdef TI_DBG   /* Sanity check: make sure we don't free more descriptors than allocated. */
        if (uNewNumUsedDescriptors >= pTxHwQueue->uNumUsedDescriptors)
        {
            TRACE2(pTxHwQueue->hReport, REPORT_SEVERITY_ERROR, ":  Used descriptors number should decrease: UsedDesc %d, NewUsedDesc %d\n", pTxHwQueue->uNumUsedDescriptors, uNewNumUsedDescriptors);
        }
#endif
    
        /* Update number of packets left in FW (for descriptors allocation check). */
        pTxHwQueue->uNumUsedDescriptors = uNewNumUsedDescriptors;
    }

#ifdef AP_MODE_ENABLED
    /* 
     * In case of change in FwFree or FwMax
     * NO_LINK_RESOURCES(hlid) =  (LinksTxBlks[hlid].HostAlloc - LinksTxBlks[hlid].FwFree) > LinksTxBlks[hlid].FwMax
     * Check if now there are resources and LinkBusy was TRUE and set backpressure bitmap for the link to FALSE
     * Check if now there is no rssources and LinkBusy was FALSE and set backpressure bitmap for the link to TRUE
     * Call the updateBusyMap callback with AC backpressure and Link backpressure bitmaps as parameters to start/stop links queue
     */
    for (uHlid = 0; uHlid < WLANLINKS_MAX_LINKS; uHlid++)
    {
        TTxHwLinkInfo *pLinkInfo = &(pTxHwQueue->aTxHwLinkInfo[uHlid]);
        TI_UINT8 new_FwFree = pFwStatus->txLinkFreeBlks[uHlid];
        TI_UINT8 new_FwMax;
        TI_UINT32 uAvailableLinkBlks;

        if((pFwStatus->linkPsBitmap >> uHlid) & 1)
        {
            if(pTxHwQueue->uNumTotalLinks == 1)
            {
                new_FwMax = HW_RESOURCES_MAX_FW_LINK_BLOCKS;
            }
            else
            {
                new_FwMax = HW_RESOURCES_MIN_FW_LINK_BLOCKS;
            }
        }
        else
        {
            new_FwMax = HW_RESOURCES_MAX_FW_LINK_BLOCKS;
        }

        /* set initial backbressure value */
        if (pLinkInfo->bBusy) 
            RESET_LINK_BACKPRESSURE(&uLinkBackpressure, uHlid); /* Init link as stopped. */
        else
            SET_LINK_BACKPRESSURE(&uLinkBackpressure, uHlid); /* Init link as started. */

        /* Check if there is a change in link info */
        if ((pLinkInfo->uFwFree != new_FwFree) || (pLinkInfo->uFwMax != new_FwMax))
        {
            uLinkInfoChanged = TI_TRUE;
            pLinkInfo->uFwFree = new_FwFree;
            pLinkInfo->uFwMax = new_FwMax;

            /* Find max available blocks for this link */
            uAvailableLinkBlks = txHwQueue_CheckLinkResources (pTxHwQueue, pLinkInfo);

            /* If the link was stopped */
            if (pLinkInfo->bBusy) 
            {
                /* Link was stopped and now, there are resources, set the link's backpressure bit to indicate NOT-BUSY */
                if (uAvailableLinkBlks > pLinkInfo->uNumBlksCausedBusy)
                {
                    TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": Link Available, Link=%d, ReqBlks=%d, FwFree=%d, HostAlloc=%d, AvailBlks=%d, FwMax=%d\n", uHlid, pLinkInfo->uNumBlksCausedBusy, pLinkInfo->uFwFree, pLinkInfo->uHostAlloc, uAvailableLinkBlks, pLinkInfo->uFwMax);
                    SET_LINK_BACKPRESSURE(&uLinkBackpressure, uHlid); /* Start link. */
                    pLinkInfo->bBusy = TI_FALSE;
                }
            }
            else
            {
                /* Link was not busy and now, there are no resources(FwMax was changed), set the link's backpressure bit to indicate BUSY */
                if (pLinkInfo->uLastAllocNumBlks > uAvailableLinkBlks)
                {
                    TRACE6(pTxHwQueue->hReport, REPORT_SEVERITY_INFORMATION, ": Link NOT Available, Link=%d, ReqBlks=%d, FwFree=%d, HostAlloc=%d, AvailBlks=%d, FwMax=%d\n", uHlid, pLinkInfo->uNumBlksCausedBusy, pLinkInfo->uFwFree, pLinkInfo->uHostAlloc, uAvailableLinkBlks, pLinkInfo->uFwMax);
                    RESET_LINK_BACKPRESSURE(&uLinkBackpressure, uHlid); /* Stop link. */
                    pLinkInfo->uNumBlksCausedBusy = uAvailableLinkBlks;
                    pLinkInfo->bBusy = TI_TRUE;
                }
            }
        }
    }