Exemple #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));
			}
		}
	}
}
Exemple #2
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;
}
Exemple #3
0
/*
  ========================================================================
  Description:
	This routine frees all packets in PSQ that's destined to a specific DA.
	BCAST/MCAST in DTIMCount=0 case is also handled here, just like a PS-POLL 
	is received from a WSTA which has MAC address FF:FF:FF:FF:FF:FF
  ========================================================================
*/
VOID RtmpHandleRxPsPoll(RTMP_ADAPTER *pAd, UCHAR *pAddr, USHORT wcid, BOOLEAN isActive)
{
	MAC_TABLE_ENTRY *pMacEntry;
	STA_TR_ENTRY *tr_entry = NULL;

	ASSERT(wcid < MAX_LEN_OF_MAC_TABLE);

	pMacEntry = &pAd->MacTab.Content[wcid];
	tr_entry = &pAd->MacTab.tr_entry[wcid];
	
	if (!RTMPEqualMemory(pMacEntry->Addr, pAddr, MAC_ADDR_LEN))
	{
		DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS,("%s(%d) PS-POLL (MAC addr not match) from %02x:%02x:%02x:%02x:%02x:%02x. Why???\n", 
			__FUNCTION__, __LINE__, PRINT_MAC(pAddr)));
		return;
	}

#ifdef UAPSD_SUPPORT00
	if (UAPSD_MR_IS_ALL_AC_UAPSD(isActive, pMacEntry))
	{
		/*
			IEEE802.11e spec.
			11.2.1.7 Receive operation for STAs in PS mode during the CP
			When a non-AP QSTA that is using U-APSD and has all ACs
			delivery-enabled detects that the bit corresponding to its AID
			is set in the TIM, the non-AP QSTA shall issue a trigger frame
			or a PS-Poll frame to retrieve the buffered MSDU or management
			frames.

			WMM Spec. v1.1a 070601
			3.6.2	U-APSD STA Operation
			3.6.2.3	In case one or more ACs are not
			delivery-enabled ACs, the WMM STA may retrieve MSDUs and
			MMPDUs belonging to those ACs by sending PS-Polls to the WMM AP.
			In case all ACs are delivery enabled ACs, WMM STA should only
			use trigger frames to retrieve MSDUs and MMPDUs belonging to
			those ACs, and it should not send PS-Poll frames.

			Different definitions in IEEE802.11e and WMM spec.
			But we follow the WiFi WMM Spec.
		*/

		DBGPRINT(RT_DEBUG_TRACE, ("All AC are UAPSD, can not use PS-Poll\n"));
		return; /* all AC are U-APSD, can not use PS-Poll */
	}
#endif /* UAPSD_SUPPORT */

	/* Reset ContinueTxFailCnt */
	pMacEntry->ContinueTxFailCnt = 0;
	pAd->MacTab.tr_entry[pMacEntry->wcid].ContinueTxFailCnt = 0;
	
	if (isActive == FALSE)
	{
		if (tr_entry->PsDeQWaitCnt == 0) {
			tr_entry->PsDeQWaitCnt = 1;
		} else {
			DBGPRINT(RT_DEBUG_TRACE,
					("%s(): : packet not send by HW then ignore other PS-Poll Aid[%d]!\n",
					__FUNCTION__, pMacEntry->Aid));
			return;
		}
	}
	else
		tr_entry->PsDeQWaitCnt = 0;

#ifdef CONFIG_AP_SUPPORT
#ifdef MT_MAC
	if (pAd->chipCap.hif_type == HIF_MT)
	{
		MtHandleRxPsPoll(pAd, pAddr, wcid, isActive);
	}
#endif /* MT_MAC */

#if defined(RTMP_MAC) || defined(RLT_MAC)
	if ((pAd->chipCap.hif_type == HIF_RTMP) 
		|| (pAd->chipCap.hif_type == HIF_RLT))
	{
		RalHandleRxPsPoll(pAd, pAddr, wcid, isActive);
	}
#endif /* RTMP_MAC || RLT_MAC */
#endif /* CONFIG_AP_SUPPORT */
}