Пример #1
0
VOID MtPsRecovery(
	RTMP_ADAPTER *pAd)
{
	MAC_TABLE_ENTRY *pMacEntry;
	STA_TR_ENTRY *tr_entry;
	UINT32 i;

	for (i=1; i < MAX_LEN_OF_MAC_TABLE; i++)
	{
		pMacEntry = &pAd->MacTab.Content[i];
		tr_entry = &pAd->MacTab.tr_entry[i];
		if (IS_ENTRY_CLIENT(pMacEntry))
		{
			if (tr_entry->ps_state == APPS_RETRIEVE_CR_PADDING) {
				tr_entry->ps_state = APPS_RETRIEVE_IDLE;
			} else if ((tr_entry->ps_state == APPS_RETRIEVE_START_PS) 
				|| (tr_entry->ps_state == APPS_RETRIEVE_GOING))
			{
				if (tr_entry->ps_queue.Number) {
					MtEnqTxSwqFromPsQueue(pAd, i, tr_entry);
				}


				 if (pAd->MacTab.tr_entry[i].PsMode == PWR_ACTIVE) {
					tr_entry->ps_state = APPS_RETRIEVE_IDLE;
					 MtHandleRxPsPoll(pAd, &pMacEntry->Addr[0], i, TRUE);
				 } else
					tr_entry->ps_state = APPS_RETRIEVE_DONE;
			} else if(tr_entry->ps_state == APPS_RETRIEVE_WAIT_EVENT)
			{
				RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_CLEAR, (VOID *)&i, sizeof(UINT32));
			}
		}
	}
}
Пример #2
0
/*
========================================================================
Routine Description:
	Parse and handle country region in beacon from associated AP.

Arguments:
	pAdCB			- WLAN control block pointer
	pVIE			- Beacon elements
	LenVIE			- Total length of Beacon elements

Return Value:
	NONE

Note:
========================================================================
*/
VOID CFG80211_BeaconCountryRegionParse(
	IN VOID						*pAdCB,
	IN NDIS_802_11_VARIABLE_IEs	*pVIE,
	IN UINT16					LenVIE)
{
	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
	UCHAR *pElement = (UCHAR *)pVIE;
	UINT32 LenEmt;


	while(LenVIE > 0)
	{
		pVIE = (NDIS_802_11_VARIABLE_IEs *)pElement;

		if (pVIE->ElementID == IE_COUNTRY)
		{
			/* send command to do regulation hint only when associated */
			RTEnqueueInternalCmd(pAd, CMDTHREAD_REG_HINT_11D,
								pVIE->data, pVIE->Length);
			break;
		} /* End of if */

		LenEmt = pVIE->Length + 2;

		if (LenVIE <= LenEmt)
			break; /* length is not enough */
		/* End of if */

		pElement += LenEmt;
		LenVIE -= LenEmt;
	} /* End of while */
} /* End of CFG80211_BeaconCountryRegionParse */
Пример #3
0
static void rtusb_null_frame_done_tasklet(unsigned long data)
{
	PRTMP_ADAPTER	pAd;
	PTX_CONTEXT		pNullContext;
	purbb_t			pUrb;
	NTSTATUS		Status;
	unsigned long	irqFlag;


	pUrb			= (purbb_t)data;
/*	pNullContext	= (PTX_CONTEXT)pUrb->context; */
	pNullContext	= (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb);
	Status			= RTMP_USB_URB_STATUS_GET(pUrb);
	pAd 			= pNullContext->pAd;
/*	Status 			= pUrb->status; */

	/* Reset Null frame context flags */
	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
	pNullContext->IRPPending 	= FALSE;
	pNullContext->InUse 		= FALSE;
	pAd->BulkOutPending[0] = FALSE;
	pAd->watchDogTxPendingCnt[0] = 0;

	if (Status == USB_ST_NOERROR)
	{
		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
		
		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
	}
	else	/* STATUS_OTHER */
	{
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
			RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
		}
		else
		{
			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
		}
	}

	/* Always call Bulk routine, even reset bulk. */
	/* The protectioon of rest bulk should be in BulkOut routine */
	RTUSBKickBulkOut(pAd);
}
Пример #4
0
static void rtusb_hcca_dma_done_tasklet(unsigned long data)
{
	PRTMP_ADAPTER		pAd;
	PHT_TX_CONTEXT		pHTTXContext;
	UCHAR				BulkOutPipeId = 4;
	purbb_t				pUrb;

	
	DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));


	pUrb			= (purbb_t)data;
/*	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context; */
	pHTTXContext	= (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb);
	pAd				= pHTTXContext->pAd;

	rtusb_dataout_complete((unsigned long)pUrb);

	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | 
								fRTMP_ADAPTER_HALT_IN_PROGRESS | 
								fRTMP_ADAPTER_NIC_NOT_EXIST)))) 
	{
		/* do nothing and return directly. */
	}
	else 
	{	
		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
		{
			RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);	
		}
		else
		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && 
				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && 
				(pHTTXContext->bCurWriting == FALSE))
			{
				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
			}
			
			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
			RTUSBKickBulkOut(pAd);
		}
	}
	
	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));

		return;
}
Пример #5
0
/*
========================================================================
Routine Description:
	Handle a alarm.

Arguments:
	pAd					- WLAN control block pointer

Return Value:
	None

Note:
	You can use different methods to handle QBSS Load alarm here.

	Current methods are:
	1. Change 20/40 to 20-only.
	2. Change channel to the clear channel.
========================================================================
*/
static VOID QBSS_LoadAlarm(
    IN		RTMP_ADAPTER	*pAd)
{
    /* suspend alarm until channel switch */
    QBSS_LoadAlarmSuspend(pAd);

    pAd->QloadAlarmNumber ++;

    /* check if we have already been 20M bandwidth */
#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
    if ((pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0) &&
            (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0))
    {
        MAC_TABLE *pMacTable;
        UINT32 StaId;


        DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Change to 20 bw...\n"));

        /* disassociate stations without D3 2040Coexistence function */
        pMacTable = &pAd->MacTab;

        for(StaId=1; StaId<MAX_LEN_OF_MAC_TABLE; StaId++)
        {
            MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[StaId];
            BOOLEAN bDisconnectSta = FALSE;

            if (!IS_ENTRY_CLIENT(pEntry))
                continue;
            /* End of if */

            if (pEntry->Sst != SST_ASSOC)
                continue;
            /* End of if */

            if (pEntry->BSS2040CoexistenceMgmtSupport)
                bDisconnectSta = TRUE;
            /* End of if */

            if (bDisconnectSta)
            {
                /* send wireless event - for ageout */
                RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0);

                {
                    PUCHAR      pOutBuffer = NULL;
                    NDIS_STATUS NStatus;
                    ULONG       FrameLen = 0;
                    HEADER_802_11 DeAuthHdr;
                    USHORT      Reason;

                    /*  send out a DISASSOC request frame */
                    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
                    if (NStatus != NDIS_STATUS_SUCCESS)
                    {
                        DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail  ..\n"));
                        /*NdisReleaseSpinLock(&pAd->MacTabLock); */
                        continue;
                    }

                    Reason = REASON_DEAUTH_STA_LEAVING;
                    MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0,
                                     pEntry->Addr,
#ifdef P2P_SUPPORT
                                     pAd->ApCfg.MBSSID[pEntry->apidx].Bssid,
#endif /* P2P_SUPPORT */
                                     pAd->ApCfg.MBSSID[pEntry->apidx].Bssid);
                    MakeOutgoingFrame(pOutBuffer,            &FrameLen,
                                      sizeof(HEADER_802_11), &DeAuthHdr,
                                      2,                     &Reason,
                                      END_OF_ARGS);
                    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
                    MlmeFreeMemory(pAd, pOutBuffer);
                }

                DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Deauth the station "
                                          "%02x:%02x:%02x:%02x:%02x:%02x\n",
                                          pEntry->Addr[0], pEntry->Addr[1],
                                          pEntry->Addr[2], pEntry->Addr[3],
                                          pEntry->Addr[4], pEntry->Addr[5]));

                MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
                continue;
            } /* End of if */
        } /* End of for */

        /* for 11n */
        pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
        pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;

        /* always 20M */
        pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;

        /* mark alarm flag */
        pAd->FlgQloadAlarm = TRUE;

        QBSS_LoadAlarmResume(pAd);
    }
    else
#endif /* DOT11N_DRAFT3 */
#endif /* DOT11_N_SUPPORT */
    {
        /* we are in 20MHz bandwidth so try to switch channel */
        DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Switch channel...\n"));

        /* send command to switch channel */
        RTEnqueueInternalCmd(pAd, CMDTHREAD_CHAN_RESCAN, NULL, 0);
    } /* End of if */
} /* End of QBSS_LoadAlarm */
Пример #6
0
VOID RTUSBWatchDog(IN RTMP_ADAPTER *pAd)
{
	PHT_TX_CONTEXT		pHTTXContext;
	int 					idx;
	ULONG				irqFlags;
	PURB		   		pUrb;
	BOOLEAN				needDumpSeq = FALSE;
	UINT32          	MACValue;

	if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))		
		return;
	
	idx = 0;
	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
	if ((MACValue & 0xff) !=0 )
	{
		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
		while((MACValue &0xff) != 0 && (idx++ < 10))
		{
		        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
		        RTMPusecDelay(1);
		}
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
	}

	idx = 0;
	if ((MACValue & 0xff00) !=0 )
	{
		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
		while((MACValue &0xff00) != 0 && (idx++ < 10))
		{
			RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
			RTMPusecDelay(1);
		}
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
	}

	
	if (pAd->watchDogRxOverFlowCnt >= 2)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
									fRTMP_ADAPTER_BULKIN_RESET |
									fRTMP_ADAPTER_HALT_IN_PROGRESS |
									fRTMP_ADAPTER_NIC_NOT_EXIST))))
		{
			DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
			RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
			needDumpSeq = TRUE;
		}
		pAd->watchDogRxOverFlowCnt = 0;
	}


	for (idx = 0; idx < NUM_OF_TX_RING; idx++)
	{
		pUrb = NULL;
		
		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
		if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
		{
			pAd->watchDogTxPendingCnt[idx]++;

			if ((pAd->watchDogTxPendingCnt[idx] > 2) && 
				 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
				)
			{
				// FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
				pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
				if (pHTTXContext->IRPPending)
				{	// Check TxContext.
					pUrb = pHTTXContext->pUrb;
				}
				else if (idx == MGMTPIPEIDX)
				{
					PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
					
					//Check MgmtContext.
					pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
					pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
					pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
					
					if (pMLMEContext->IRPPending)
					{
						ASSERT(pMLMEContext->IRPPending);
						pUrb = pMLMEContext->pUrb;
					}
					else if (pNULLContext->IRPPending)
					{	
						ASSERT(pNULLContext->IRPPending);
						pUrb = pNULLContext->pUrb;
					}
					else if (pPsPollContext->IRPPending)
					{	
						ASSERT(pPsPollContext->IRPPending);
						pUrb = pPsPollContext->pUrb;
					}
				}
				
				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
				
				DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
				if (pUrb)
				{
					DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
					// unlink it now
					RTUSB_UNLINK_URB(pUrb);
					// Sleep 200 microseconds to give cancellation time to work
					RTMPusecDelay(200);
					needDumpSeq = TRUE;
				}
				else
				{
					DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
				}
			}
			else
			{
				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
			}
		}
		else
		{
			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
		}
	}

#ifdef DOT11_N_SUPPORT
	// For Sigma debug, dump the ba_reordering sequence.
	if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
	{
		USHORT				Idx;
		PBA_REC_ENTRY		pBAEntry = NULL;
		UCHAR				count = 0;
		struct reordering_mpdu *mpdu_blk;
					
		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];

		pBAEntry = &pAd->BATable.BARecEntry[Idx];
		if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
		{
			DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
			mpdu_blk = pBAEntry->list.next;
			while (mpdu_blk)
			{
				DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
				mpdu_blk = mpdu_blk->next;
				count++;
			}

			DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
		}
	}
#endif // DOT11_N_SUPPORT //
}
Пример #7
0
VOID MtPsSendToken(
	RTMP_ADAPTER *pAd,
	UINT32 WlanIdx)
{
	MAC_TABLE_ENTRY *pEntry = NULL;
	STA_TR_ENTRY *tr_entry;
	NDIS_STATUS token_status;
	struct wtbl_entry tb_entry;
	union WTBL_1_DW3 *dw3;
	UINT32 Reg = 0;
	BOOLEAN pfgForce = 0;
	unsigned char q_idx;
	
	if (pAd->chipCap.hif_type != HIF_MT)
	{
		return;
	}

	DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s(wcid=%d): Driver didn't receive PsRetrieveStartRsp from FW.\n",__FUNCTION__, WlanIdx));
	pEntry = &pAd->MacTab.Content[WlanIdx];
	
	tr_entry = &pAd->MacTab.tr_entry[WlanIdx];
	NdisZeroMemory(&tb_entry, sizeof(tb_entry));
	dw3 = (union WTBL_1_DW3 *)&tb_entry.wtbl_1.wtbl_1_d3.word;

	if (mt_wtbl_get_entry234(pAd, WlanIdx, &tb_entry) == FALSE) 
	{
		DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s():Cannot found WTBL2/3/4, wcid=%d\n",__FUNCTION__, WlanIdx));
		return;
	}

	RTMP_IO_READ32(pAd, tb_entry.wtbl_addr[0]+12, &dw3->word);

	MtReadPseRdTabAccessReg(pAd, pEntry->wcid, &Reg);
		
	pfgForce = ( BOOLEAN ) GET_PSE_RTA_RD_RULE_F(Reg);
	
	if (pfgForce == 0)
	{
		DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("%s(ps_state = %d): PS Redirect mode didn't be enabled. Driver doesn't need to send token.\n",__FUNCTION__, tr_entry->ps_state));
		DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("%s: Reset ps_state to IDLE.\n",__FUNCTION__));
		tr_entry->ps_state = APPS_RETRIEVE_IDLE;
		return;
	}

	DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("---->%s: Start to send TOKEN frames.\n", __FUNCTION__));

	tr_entry->ps_state = APPS_RETRIEVE_GOING;

	tr_entry->ps_qbitmap = 0;
	  
	for (q_idx = 0; q_idx < NUM_OF_TX_RING; q_idx++)
	{
		token_status = RtmpEnqueueTokenFrame(pAd, &(pEntry->Addr[0]), 0, WlanIdx, 0, q_idx);
		if (!token_status)
			tr_entry->ps_qbitmap |= (1 << q_idx);
		else
			DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s(%d) Fail:  Send TOKEN Frame, AC=%d\n", __FUNCTION__, __LINE__, q_idx));
	}

	if (tr_entry->ps_qbitmap == 0)
	{
		tr_entry->ps_state = APPS_RETRIEVE_WAIT_EVENT;
		RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_CLEAR, (VOID *)&WlanIdx, sizeof(UINT32));
		DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("(ps_state = %d) token enqueue failed for all queues ==> send CMDTHREAD_PS_CLEAR cmd.\n", tr_entry->ps_state));
	}
}
Пример #8
0
/*
	==========================================================================
	Description:
		Update the station current power save mode. Calling this routine also
		prove the specified client is still alive. Otherwise AP will age-out
		this client once IdleCount exceeds a threshold.
	==========================================================================
 */
BOOLEAN MtPsIndicate(RTMP_ADAPTER *pAd, UCHAR *pAddr, UCHAR wcid, UCHAR Psm)
{
	MAC_TABLE_ENTRY *pEntry;
	UCHAR old_psmode;
	STA_TR_ENTRY *tr_entry;

	if (wcid >= MAX_LEN_OF_MAC_TABLE)
	{
		return PWR_ACTIVE;
	}

	pEntry = &pAd->MacTab.Content[wcid];
	tr_entry = &pAd->MacTab.tr_entry[wcid];

	/*
		Change power save mode first because we will call
		RTMPDeQueuePacket() in RtmpHandleRxPsPoll().

		Or when Psm = PWR_ACTIVE, we will not do Aggregation in
		RTMPDeQueuePacket().
	*/
	old_psmode = pEntry->PsMode;
	pEntry->NoDataIdleCount = 0;
	pEntry->PsMode = Psm;
	pAd->MacTab.tr_entry[wcid].PsMode = Psm;

	if ((old_psmode == PWR_SAVE) && (Psm == PWR_ACTIVE))
	{
		/*
			STA wakes up.
		*/		
		if(tr_entry->ps_state == APPS_RETRIEVE_DONE)
		{
			tr_entry->ps_state = APPS_RETRIEVE_IDLE;
			DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d): STA wakes up!\n", __FUNCTION__, __LINE__));
			MtHandleRxPsPoll(pAd, pAddr, wcid, TRUE);
		}
		else
			DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d):wcid=%d, old_psmode=%d, now_psmode=%d, wrong ps_state=%d ???\n",
					__FUNCTION__, __LINE__, wcid, old_psmode, Psm, tr_entry->ps_state));
	}
	else if ((old_psmode == PWR_ACTIVE) && (Psm == PWR_SAVE))
	{
		/*
			STA goes to sleep.
		*/

		if (tr_entry->ps_state == APPS_RETRIEVE_IDLE)
		{ 
#ifdef MT_PS
			DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d):wcid=%d, old_psmode=%d, now_psmode=%d, ps_state=%d start retrieving!!\n",
					__FUNCTION__, __LINE__, wcid, old_psmode, Psm, tr_entry->ps_state));

#if defined(MT7603) && defined(RTMP_PCI_SUPPORT)
			if (MtStartPSRetrieve(pAd, wcid) == TRUE) {
			tr_entry->ps_state = APPS_RETRIEVE_START_PS;
			} else {
				struct tx_swq_fifo *ps_fifo_swq;
				INT enq_idx;

				ps_fifo_swq = &pAd->apps_cr_q;
				enq_idx = ps_fifo_swq->enqIdx;
				if (ps_fifo_swq->swq[enq_idx] == 0)
				{
					ps_fifo_swq->swq[enq_idx] = wcid;
					INC_RING_INDEX(ps_fifo_swq->enqIdx, TX_SWQ_FIFO_LEN);
					tr_entry->ps_state = APPS_RETRIEVE_CR_PADDING;
				} else {
					INT idx;
					tr_entry->ps_state = APPS_RETRIEVE_DONE;
					DBGPRINT(RT_DEBUG_ERROR, ("%s: ERROR!! ps_fifo_swq->deqIdx=%d, ps_fifo_swq->enqIdx=%d\n", __FUNCTION__,ps_fifo_swq->deqIdx,ps_fifo_swq->enqIdx));
					for (idx =0; idx < TX_SWQ_FIFO_LEN;idx++) {
						DBGPRINT(RT_DEBUG_ERROR, (",[%d] =%d\n", idx, ps_fifo_swq->swq[idx]));
						if ((idx % 16) == 0)
							DBGPRINT(RT_DEBUG_ERROR, ("\n"));
					}
					DBGPRINT(RT_DEBUG_ERROR, ("\n"));
				}				
			}
#else /* !MT7603 && RTMP_PCI_SUPPORT */
			RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_RETRIEVE_START, pEntry, sizeof(MAC_TABLE_ENTRY));
#endif /* MT7603 && RTMP_PCI_SUPPORT */
#else /* MT_PS */
			tr_entry->ps_state = APPS_RETRIEVE_DONE;
#endif /* !MT_PS */
		}
		else
			DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d):wcid=%d, old_psmode=%d, now_psmode=%d, wrong ps_state=%d ???\n",
					__FUNCTION__, __LINE__, wcid, old_psmode, Psm, tr_entry->ps_state));
	}
	else
	{
		DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d): ps state is not changed, do nothing here.\n",
			__FUNCTION__, __LINE__));
	}
   
	return old_psmode;
}
Пример #9
0
/*
	==========================================================================
	Description:
		Scan next channel
	==========================================================================
 */
VOID ScanNextChannel(
	IN PRTMP_ADAPTER pAd) 
{
	HEADER_802_11   Hdr80211;
	PUCHAR          pOutBuffer = NULL;
	NDIS_STATUS     NStatus;
	ULONG           FrameLen = 0;
	UCHAR           SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
#ifdef CONFIG_STA_SUPPORT
	USHORT          Status;
	PHEADER_802_11  pHdr80211;
#endif // CONFIG_STA_SUPPORT //
	UINT			ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;

#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
	{
		if (MONITOR_ON(pAd))
			return;
	}
#endif // CONFIG_STA_SUPPORT //

#ifdef RALINK_ATE
	// Nothing to do in ATE mode. 
	if (ATE_ON(pAd))
		return;
#endif // RALINK_ATE //

	if (pAd->MlmeAux.Channel == 0) 
	{
		if ((pAd->CommonCfg.BBPCurrentBW == BW_40) &&
			(
#ifdef CONFIG_STA_SUPPORT
				INFRA_ON(pAd) || ADHOC_ON(pAd) ||
#endif // CONFIG_STA_SUPPORT //
			(0)))
		{
			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
			BBPValue &= (~0x18);
			BBPValue |= 0x10;
			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
		}
		else
		{
			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
		}
		
#ifdef CONFIG_STA_SUPPORT
		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
		{

			/*
				If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp.
				In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. 
				To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here.
			*/
			if (ADHOC_ON(pAd))
			{
				NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
				pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
				NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
			}
		
			//
			// To prevent data lost.
			// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
			// Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done 
			//
			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
			{
				NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
				if (NStatus	== NDIS_STATUS_SUCCESS)
				{
					pHdr80211 = (PHEADER_802_11) pOutBuffer;
					MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
					pHdr80211->Duration = 0;
					pHdr80211->FC.Type = BTYPE_DATA;
					pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);

					// Send using priority queue
					MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
					DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
					MlmeFreeMemory(pAd, pOutBuffer);
					RTMPusecDelay(5000);
				}
			}

			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
			Status = MLME_SUCCESS;
			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0);

			RTMPSendWirelessEvent(pAd, IW_SCAN_COMPLETED_EVENT_FLAG, NULL, BSS0, 0);

#ifdef LINUX
#ifdef RT_CFG80211_SUPPORT
			RTEnqueueInternalCmd(pAd, CMDTHREAD_SCAN_END, NULL, 0);
#endif // RT_CFG80211_SUPPORT //
#endif // LINUX //	
		}
#endif // CONFIG_STA_SUPPORT //



	} 
	else 
	{
Пример #10
0
INT Set_P2P_Cancel_Proc(
	IN	PRTMP_ADAPTER	pAd, 
	IN	PSTRING			arg)
{
	POS_COOKIE		pObj;
	PRT_P2P_CONFIG	pP2PCtrl = &pAd->P2pCfg;
	PWSC_CTRL pWscControl = NULL;
	INT val = (INT)simple_strtol(arg, 0, 10);

	pObj = (POS_COOKIE) pAd->OS_Cookie;
	if (pObj->ioctl_if_type != INT_P2P)
		return FALSE;

	if (val == 1)
	{
		pP2PCtrl->P2PConnectState = P2P_CONNECT_IDLE;
		if (!MAC_ADDR_EQUAL(&ZERO_MAC_ADDR[0], &pP2PCtrl->ConnectingMAC[0]))
		{
			UCHAR p2pindex;
	
			p2pindex = P2pGroupTabSearch(pAd, pP2PCtrl->ConnectingMAC);
			if (p2pindex < MAX_P2P_GROUP_SIZE)
			{
				if (pAd->P2pTable.Client[p2pindex].Rule == P2P_IS_GO)
					pAd->P2pTable.Client[p2pindex].P2pClientState = P2PSTATE_DISCOVERY_GO;
				else
					pAd->P2pTable.Client[p2pindex].P2pClientState = P2PSTATE_DISCOVERY;
				pAd->P2pTable.Client[p2pindex].StateCount = 0;
			}
			NdisZeroMemory(pP2PCtrl->ConnectingMAC, MAC_ADDR_LEN);
		}

		if (P2P_GO_ON(pAd))
		{
			UINT32 i, p2pEntryCnt=0;
			MAC_TABLE_ENTRY	*pEntry;
			INT	 IsAPConfigured;
			
			pWscControl = &pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl;
			IsAPConfigured = pWscControl->WscConfStatus;
			if (pWscControl->bWscTrigger)
			{
				WscStop(pAd, FALSE, pWscControl);
				pWscControl->WscPinCode = 0;
				WscBuildBeaconIE(pAd, IsAPConfigured, FALSE, 0, 0, MAIN_MBSSID, NULL, 0, AP_MODE);
				WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, (MAIN_MBSSID | MIN_NET_DEVICE_FOR_P2P_GO), NULL, 0, AP_MODE);
				APUpdateBeaconFrame(pAd, pObj->ioctl_if);
			}

			for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
			{
				pEntry = &pAd->MacTab.Content[i];
				if (IS_P2P_GO_ENTRY(pEntry) && (pEntry->WpaState == AS_PTKINITDONE))
					p2pEntryCnt++;
			}
			DBGPRINT(RT_DEBUG_ERROR, ("%s:: Total= %d. p2pEntry = %d.\n", __FUNCTION__, pAd->MacTab.Size, p2pEntryCnt));
			if ((p2pEntryCnt == 0) && (pAd->flg_p2p_OpStatusFlags == P2P_GO_UP))
			{
#ifdef RTMP_MAC_USB
				RTEnqueueInternalCmd(pAd, CMDTHREAD_SET_P2P_LINK_DOWN, NULL, 0);	
#endif /* RTMP_MAC_USB */
			}
	    }
		else if (P2P_CLI_ON(pAd))
		{
			pWscControl = &pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl;
			pWscControl->WscPinCode = 0;
			if (pWscControl->bWscTrigger)
				WscStop(pAd, TRUE, pWscControl);
			P2pLinkDown(pAd, P2P_DISCONNECTED);
		}
		P2pStopScan(pAd);
		pP2PCtrl->bPeriodicListen = TRUE;
		/* Reset bConfirmByUI to its default value */
		pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT;

		if (INFRA_ON(pAd) || P2P_GO_ON(pAd) || P2P_CLI_ON(pAd))
		{
			INT ch;

			// TODO: shiang-6590, why we set bw as 40 when BBPCurrentBW == BW_40??
			if (pAd->CommonCfg.BBPCurrentBW == BW_40)
			{
				rtmp_bbp_set_bw(pAd, BW_40);

				ch = pAd->CommonCfg.CentralChannel;
			}
			else
			{
				ch = pAd->CommonCfg.Channel;
			}

			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
		}
	}

	DBGPRINT(RT_DEBUG_TRACE, ("%s:: Cancel P2P action\n", __FUNCTION__));
	return TRUE;
}
Пример #11
0
/*
	==========================================================================
	Description:
		Scan next channel
	==========================================================================
 */
VOID ScanNextChannel(
	IN PRTMP_ADAPTER pAd) 
{
	HEADER_802_11   Hdr80211;
	PUCHAR          pOutBuffer = NULL;
	NDIS_STATUS     NStatus;
	ULONG           FrameLen = 0;
	UCHAR           SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
#ifdef CONFIG_STA_SUPPORT
	USHORT          Status;
#endif // CONFIG_STA_SUPPORT //
	UINT			ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
	BOOLEAN			ScanPending = FALSE;

#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
	{
		if (MONITOR_ON(pAd))
			return;
	}

	ScanPending = ((pAd->StaCfg.bImprovedScan) && (pAd->StaCfg.ScanChannelCnt>=7));
#endif // CONFIG_STA_SUPPORT //

#ifdef RALINK_ATE
	// Nothing to do in ATE mode. 
	if (ATE_ON(pAd))
		return;
#endif // RALINK_ATE //

	if ((pAd->MlmeAux.Channel == 0) || ScanPending) 
	{
		if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
#ifdef CONFIG_STA_SUPPORT
			&& (INFRA_ON(pAd) || ADHOC_ON(pAd)
				|| (pAd->OpMode == OPMODE_AP))
#endif // CONFIG_STA_SUPPORT //
			)
		{
			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
			BBPValue &= (~0x18);
			BBPValue |= 0x10;
			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
		}
		else
		{
			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
		}
		
#ifdef CONFIG_STA_SUPPORT
		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
		{

			/*
				If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp.
				In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. 
				To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here.
			*/
			if (ADHOC_ON(pAd))
			{
				NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
				pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
				NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
			}
		
			//
			// To prevent data lost.
			// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
			// Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done 
			//
			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
			{
				RTMPSendNullFrame(pAd, 
								  pAd->CommonCfg.TxRate, 
								  (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE));
				DBGPRINT(RT_DEBUG_TRACE, ("%s -- Send PSM Data frame\n", __FUNCTION__));
			}

			// keep the latest scan channel, could be 0 for scan complete, or other channel
			pAd->StaCfg.LastScanChannel = pAd->MlmeAux.Channel;

			pAd->StaCfg.ScanChannelCnt = 0;

			// Suspend scanning and Resume TxData for Fast Scanning
			if ((pAd->MlmeAux.Channel != 0) &&
				(pAd->StaCfg.bImprovedScan))	// it is scan pending
			{
				pAd->Mlme.SyncMachine.CurrState = SCAN_PENDING;
				Status = MLME_SUCCESS;
				DBGPRINT(RT_DEBUG_WARN, ("bFastRoamingScan ~~~~~~~~~~~~~ Get back to send data ~~~~~~~~~~~~~\n"));

				RTMPResumeMsduTransmission(pAd);
			}
			else
			{
				pAd->StaCfg.BssNr = pAd->ScanTab.BssNr;
				pAd->StaCfg.bImprovedScan = FALSE;
				
				pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
				Status = MLME_SUCCESS;
				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0);

				RTMPSendWirelessEvent(pAd, IW_SCAN_COMPLETED_EVENT_FLAG, NULL, BSS0, 0);
#ifdef WPA_SUPPLICANT_SUPPORT
				RtmpOSWrielessEventSend(pAd, SIOCGIWSCAN, -1, NULL, NULL, 0);
#endif // WPA_SUPPLICANT_SUPPORT //
			}

#ifdef LINUX
#ifdef RT_CFG80211_SUPPORT
			RTEnqueueInternalCmd(pAd, CMDTHREAD_SCAN_END, NULL, 0);
#endif // RT_CFG80211_SUPPORT //
#endif // LINUX //
		}
#endif // CONFIG_STA_SUPPORT //



	} 
	else 
	{
Пример #12
0
/*
========================================================================
Routine Description:
	Handle a alarm.

Arguments:
	pAd					- WLAN control block pointer

Return Value:
	None

Note:
	You can use different methods to handle QBSS Load alarm here.

	Current methods are:
	1. Change 20/40 to 20-only.
	2. Change channel to the clear channel.
========================================================================
*/
static VOID QBSS_LoadAlarm(
 	IN		struct rtmp_adapter *pAd)
{
	/* suspend alarm until channel switch */
	QBSS_LoadAlarmSuspend(pAd);

	pAd->QloadAlarmNumber ++;

	/* check if we have already been 20M bandwidth */
	if ((pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0) &&
		(pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0))
	{
		struct mt7612u_mac_table *pMacTable;
		uint32_t StaId;


		DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Change to 20 bw...\n"));

		/* disassociate stations without D3 2040Coexistence function */
		pMacTable = &pAd->MacTab;

		for(StaId=1; StaId<MAX_LEN_OF_MAC_TABLE; StaId++)
		{
			MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[StaId];
			bool bDisconnectSta = false;

			if (!IS_ENTRY_CLIENT(pEntry))
				continue;

			if (pEntry->Sst != SST_ASSOC)
				continue;

			if (pEntry->BSS2040CoexistenceMgmtSupport)
				bDisconnectSta = true;

			if (bDisconnectSta)
			{
				/* send wireless event - for ageout */
				RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0);

				{
					u8 *pOutBuffer = NULL;
					int NStatus;
					ULONG FrameLen = 0;
					HEADER_802_11 DeAuthHdr;
					unsigned short Reason;

					/*  send out a DISASSOC request frame */
					pOutBuffer = kmalloc(MGMT_DMA_BUFFER_SIZE, GFP_ATOMIC);
					if (pOutBuffer == NULL)
					{
						DBGPRINT(RT_DEBUG_TRACE, (" kmalloc fail  ..\n"));
						/*NdisReleaseSpinLock(&pAd->MacTabLock); */
						continue;
					}

					Reason = REASON_DEAUTH_STA_LEAVING;
					MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0,
									pEntry->Addr,
									pAd->ApCfg.MBSSID[pEntry->apidx].wdev.if_addr,
									pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid);
				    	MakeOutgoingFrame(pOutBuffer, &FrameLen,
				    	                  sizeof(HEADER_802_11), &DeAuthHdr,
				    	                  2,                     &Reason,
				    	                  END_OF_ARGS);
				    	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
				    	kfree(pOutBuffer);
				}

				DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Deauth the station "
						"%02x:%02x:%02x:%02x:%02x:%02x\n",
						PRINT_MAC(pEntry->Addr)));

				MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr);
				continue;
			}
		}

		/* for 11n */
		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;

		/* always 20M */
		pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;

		/* mark alarm flag */
		pAd->FlgQloadAlarm = true;

		QBSS_LoadAlarmResume(pAd);
	}
	else
	{
		/* we are in 20MHz bandwidth so try to switch channel */
		DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Switch channel...\n"));

		/* send command to switch channel */
		RTEnqueueInternalCmd(pAd, CMDTHREAD_CHAN_RESCAN, NULL, 0);
	}
}
Пример #13
0
static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
{
	PRTMP_ADAPTER 	pAd;
	PTX_CONTEXT		pMLMEContext;
	int				index;
	PNDIS_PACKET	pPacket;
	purbb_t			pUrb;
	NTSTATUS		Status;
	unsigned long	IrqFlags;


	pUrb			= (purbb_t)data;
/*	pMLMEContext	= (PTX_CONTEXT)pUrb->context; */
	pMLMEContext	= (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb);
	Status			= RTMP_USB_URB_STATUS_GET(pUrb);
	pAd 			= pMLMEContext->pAd;
/*	Status			= pUrb->status; */
	index 			= pMLMEContext->SelfIdx;

	ASSERT((pAd->MgmtRing.TxDmaIdx == index));

	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);


	if (Status != USB_ST_NOERROR)
	{
		/*Bulk-Out fail status handle */
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
			/* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
		}
	}

	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
	/* Reset MLME context flags */
	pMLMEContext->IRPPending = FALSE;
	pMLMEContext->InUse = FALSE;
	pMLMEContext->bWaitingBulkOut = FALSE;
	pMLMEContext->BulkOutSize = 0;

	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;

	/* Increase MgmtRing Index */
	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
	pAd->MgmtRing.TxSwFreeIdx++;
	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);


	/* No-matter success or fail, we free the mgmt packet. */
	if (pPacket)
		RTMPFreeNdisPacket(pAd, pPacket);

	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | 
								fRTMP_ADAPTER_HALT_IN_PROGRESS | 
								fRTMP_ADAPTER_NIC_NOT_EXIST))))
	{
		/* do nothing and return directly. */
	}
	else
	{
		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && 
			((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
		{	/* For Mgmt Bulk-Out failed, ignore it now. */
			RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
		}
		else
		{

			/* Always call Bulk routine, even reset bulk. */
			/* The protectioon of rest bulk should be in BulkOut routine */
			if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
			{
				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
			}
				RTUSBKickBulkOut(pAd);
			}
		}


#ifdef CONFIG_STA_SUPPORT
#endif /* CONFIG_STA_SUPPORT */
}
Пример #14
0
/*
========================================================================
Routine Description:
    Handle received packets.

Arguments:
	data				- URB information pointer

Return Value:
    None

Note:
========================================================================
*/
static void rx_done_tasklet(unsigned long data)
{
	purbb_t 			pUrb;
	PRX_CONTEXT			pRxContext;
	PRTMP_ADAPTER		pAd;
	NTSTATUS			Status;
	unsigned int		IrqFlags;

	pUrb		= (purbb_t)data;
/*	pRxContext	= (PRX_CONTEXT)pUrb->context; */
	pRxContext	= (PRX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb);
	Status		= RTMP_USB_URB_STATUS_GET(pUrb);
	pAd 		= pRxContext->pAd;
/*	Status = pUrb->status; */


	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
	pRxContext->InUse = FALSE;
	pRxContext->IRPPending = FALSE;
	pRxContext->BulkInOffset += RTMP_USB_URB_LEN_GET(pUrb); /*pUrb->actual_length; */
	/*NdisInterlockedDecrement(&pAd->PendingRx); */
	pAd->PendingRx--;

	if (Status == USB_ST_NOERROR)
	{
		pAd->BulkInComplete++;
		pAd->NextRxBulkInPosition = 0;
		if (pRxContext->BulkInOffset)	/* As jan's comment, it may bulk-in success but size is zero. */
		{
			pRxContext->Readable = TRUE;
			INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
		}
		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
	}
	else	 /* STATUS_OTHER */
	{
		pAd->BulkInCompleteFail++;
		/* Still read this packet although it may comtain wrong bytes. */
		pRxContext->Readable = FALSE;
		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);

		/* Parsing all packets. because after reset, the index will reset to all zero. */
		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
									fRTMP_ADAPTER_BULKIN_RESET |
									fRTMP_ADAPTER_HALT_IN_PROGRESS |
									fRTMP_ADAPTER_NIC_NOT_EXIST))))
		{
			
			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n", 
							Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, RTMP_USB_URB_LEN_GET(pRxContext->pUrb))); /*->actual_length)); */

			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
			RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
		}
	}
	
	ASSERT((pRxContext->InUse == pRxContext->IRPPending));

	RTUSBBulkReceive(pAd);


	return;

}