Esempio n. 1
0
static u8 _rtw_mi_set_tx_beacon_cmd(_adapter *adapter, void *data)
{
    struct mlme_priv *pmlmepriv = &adapter->mlmepriv;

    if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
        if (pmlmepriv->update_bcn == _TRUE)
            set_tx_beacon_cmd(adapter);
    }
    return _TRUE;
}
Esempio n. 2
0
void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
{
	struct mlme_priv *pmlmepriv;
	struct mlme_ext_priv	*pmlmeext;

	if (!padapter)
		return;

	pmlmepriv = &padapter->mlmepriv;
	pmlmeext = &padapter->mlmeextpriv;

	if (!pmlmeext->bstart_bss)
		return;

	spin_lock_bh(&pmlmepriv->bcn_update_lock);

	switch (ie_id) {
	case _TIM_IE_:
		update_BCNTIM(padapter);
		break;
	case _ERPINFO_IE_:
		update_bcn_erpinfo_ie(padapter);
		break;
	case _VENDOR_SPECIFIC_IE_:
		update_bcn_vendor_spec_ie(padapter, oui);
		break;
	default:
		break;
	}

	pmlmepriv->update_bcn = true;

	spin_unlock_bh(&pmlmepriv->bcn_update_lock);

	if (tx)
		set_tx_beacon_cmd(padapter);
}
Esempio n. 3
0
void interrupt_handler_8723bu(_adapter *padapter,u16 pkt_len,u8 *pbuf)
{
	HAL_DATA_TYPE	*pHalData=GET_HAL_DATA(padapter);
	struct reportpwrstate_parm pwr_rpt;

	if ( pkt_len != INTERRUPT_MSG_FORMAT_LEN )
	{
		DBG_8192C("%s Invalid interrupt content length (%d)!\n", __FUNCTION__, pkt_len);
		return ;
	}

	// HISR 
	_rtw_memcpy(&(pHalData->IntArray[0]), &(pbuf[USB_INTR_CONTENT_HISR_OFFSET]), 4);
	_rtw_memcpy(&(pHalData->IntArray[1]), &(pbuf[USB_INTR_CONTENT_HISRE_OFFSET]), 4);

	#if 0 //DBG
	{
		u32 hisr=0 ,hisr_ex=0;
		_rtw_memcpy(&hisr,&(pHalData->IntArray[0]),4);
		hisr = le32_to_cpu(hisr);	
		
		_rtw_memcpy(&hisr_ex,&(pHalData->IntArray[1]),4);
		hisr_ex = le32_to_cpu(hisr_ex);
		
		if((hisr != 0) || (hisr_ex!=0))
			DBG_871X("===> %s hisr:0x%08x ,hisr_ex:0x%08x \n",__FUNCTION__,hisr,hisr_ex);
	}
	#endif


#ifdef CONFIG_LPS_LCLK
	if(  pHalData->IntArray[0]  & IMR_CPWM_88E )
	{
		_rtw_memcpy(&pwr_rpt.state, &(pbuf[USB_INTR_CONTENT_CPWM1_OFFSET]), 1);
		//_rtw_memcpy(&pwr_rpt.state2, &(pbuf[USB_INTR_CONTENT_CPWM2_OFFSET]), 1);

		//88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow.		
		pwr_rpt.state |= PS_STATE_S2;		
		_set_workitem(&(adapter_to_pwrctl(padapter)->cpwm_event));
	}
#endif//CONFIG_LPS_LCLK

#ifdef CONFIG_INTERRUPT_BASED_TXBCN

	#ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
	if (pHalData->IntArray[0] & IMR_BCNDMAINT0_88E)
	#endif
	#ifdef  CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
	if (pHalData->IntArray[0] & (IMR_TBDER_88E|IMR_TBDOK_88E))
	#endif	
	{
		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
		#if 0
		if(pHalData->IntArray[0] & IMR_BCNDMAINT0_88E)
			DBG_8192C("%s: HISR_BCNERLY_INT\n", __func__);
		if(pHalData->IntArray[0] & IMR_TBDOK_88E)
			DBG_8192C("%s: HISR_TXBCNOK\n", __func__);
		if(pHalData->IntArray[0] & IMR_TBDER_88E)
			DBG_8192C("%s: HISR_TXBCNERR\n", __func__);
		#endif
		

		if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
	{
			//send_beacon(padapter);
			if(pmlmepriv->update_bcn == _TRUE)
	{
				//tx_beacon_hdl(padapter, NULL);
				set_tx_beacon_cmd(padapter);
	}
	}
#ifdef CONFIG_CONCURRENT_MODE
		if(check_buddy_fwstate(padapter, WIFI_AP_STATE))
	{
			//send_beacon(padapter);
			if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE)
	{
				//tx_beacon_hdl(padapter, NULL);
				set_tx_beacon_cmd(padapter->pbuddy_adapter);
	}
	}
#endif

	}
#endif //CONFIG_INTERRUPT_BASED_TXBCN




#ifdef DBG_CONFIG_ERROR_DETECT_INT
	if(  pHalData->IntArray[1]  & IMR_TXERR_8723B )
		DBG_871X("===> %s Tx Error Flag Interrupt Status \n",__FUNCTION__);
	if(  pHalData->IntArray[1]  & IMR_RXERR_8723B )
		DBG_871X("===> %s Rx Error Flag INT Status \n",__FUNCTION__);
	if(  pHalData->IntArray[1]  & IMR_TXFOVW_8723B )
		DBG_871X("===> %s Transmit FIFO Overflow \n",__FUNCTION__);
	if(  pHalData->IntArray[1]  & IMR_RXFOVW_8723B )
		DBG_871X("===> %s Receive FIFO Overflow \n",__FUNCTION__);
#endif//DBG_CONFIG_ERROR_DETECT_INT


	// C2H Event 
	if(pbuf[0]!= 0){
		_rtw_memcpy(&(pHalData->C2hArray[0]), &(pbuf[USB_INTR_CONTENT_C2H_OFFSET]), 16);		
		//rtw_c2h_wk_cmd(padapter); to do..
	}		

		}
Esempio n. 4
0
void sd_int_dpc(PADAPTER padapter)
{
	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;

#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
	if (pHalData->sdio_hisr & SDIO_HISR_AVAL)
	{
		//_irqL irql;
		u8	freepage[4];

		_sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage);
		//_enter_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql);
		//_rtw_memcpy(pHalData->SdioTxFIFOFreePage, freepage, 4);
		//_exit_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql);
		//DBG_871X("SDIO_HISR_AVAL, Tx Free Page = 0x%x%x%x%x\n",
		//	freepage[0],
		//	freepage[1],
		//	freepage[2],
		//	freepage[3]);
		_rtw_up_sema(&(padapter->xmitpriv.xmit_sema));
	}
#endif
	if (pHalData->sdio_hisr & SDIO_HISR_CPWM1)
	{
		struct reportpwrstate_parm report;

#ifdef CONFIG_LPS_RPWM_TIMER
		u8 bcancelled;
		_cancel_timer(&(adapter_to_pwrctl(padapter)->pwr_rpwm_timer), &bcancelled);
#endif // CONFIG_LPS_RPWM_TIMER

		_sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state);
#ifdef CONFIG_LPS_LCLK
		//88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow.
		//modify by Thomas. 2012/4/2.

#ifdef CONFIG_EXT_CLK //for sprd
		if(report.state & BIT(4)) //indicate FW entering 32k
		{
			u8 chk_cnt = 0;

			do{
				if(_sdio_read8(padapter, 0x90)&BIT(0))//FW in 32k already
				{
					if(pwrpriv->rpwm < PS_STATE_S2)
					{
						//DBG_871X("disable ext clk when FW in LPS-32K already!\n");
						EnableGpio5ClockReq(padapter, _TRUE, 0);
					}

					break;
				}

				chk_cnt++;

			}while(chk_cnt<10);

			if(chk_cnt==10)
			{
				DBG_871X("polling fw in 32k already, fail!\n");
			}

		}
		else //indicate fw leaving 32K
#endif //CONFIG_EXT_CLK
		{
		report.state |= PS_STATE_S2;
		//cpwm_int_hdl(padapter, &report);
		_set_workitem(&(pwrpriv->cpwm_event));
		}
#endif
	}

#ifdef CONFIG_WOWLAN
	if (pHalData->sdio_hisr & SDIO_HISR_CPWM2) {
		u32	value;
		value = rtw_read32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR);
		DBG_871X_LEVEL(_drv_always_, "Reset SDIO HISR(0x%08x) original:0x%08x\n",
			SDIO_LOCAL_BASE+SDIO_REG_HISR, value);
		value |= BIT19;
		rtw_write32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR, value);

		value = rtw_read8(padapter, SDIO_LOCAL_BASE+SDIO_REG_HIMR+2);
		DBG_871X_LEVEL(_drv_always_, "Reset SDIO HIMR CPWM2(0x%08x) original:0x%02x\n",
			SDIO_LOCAL_BASE+SDIO_REG_HIMR + 2, value);
	}
#endif
	if (pHalData->sdio_hisr & SDIO_HISR_TXERR)
	{
		u8 *status;
		u32 addr;

		status = rtw_malloc(4);
		if (status)
		{
			addr = REG_TXDMA_STATUS;
			HalSdioGetCmdAddr8723ASdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
			_sd_read(pintfhdl, addr, 4, status);
			_sd_write(pintfhdl, addr, 4, status);
			DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status));
			rtw_mfree(status, 4);
		} else {
			DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
		}
	}

#ifdef CONFIG_INTERRUPT_BASED_TXBCN

	#ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
	if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
	#endif
	#ifdef  CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
	if (pHalData->sdio_hisr & (SDIO_HISR_TXBCNOK|SDIO_HISR_TXBCNERR))
	#endif
	{
		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;

		#if 0 //for debug
		if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
			DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__);

		if (pHalData->sdio_hisr & SDIO_HISR_TXBCNOK)
			DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);

		if (pHalData->sdio_hisr & SDIO_HISR_TXBCNERR)
			DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
		#endif


		if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
		{
			//send_beacon(padapter);
			if(pmlmepriv->update_bcn == _TRUE)
			{
				//tx_beacon_hdl(padapter, NULL);
				set_tx_beacon_cmd(padapter);
			}
		}
#ifdef CONFIG_CONCURRENT_MODE
		if(check_buddy_fwstate(padapter, WIFI_AP_STATE))
		{
			//send_beacon(padapter);
			if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE)
			{
				//tx_beacon_hdl(padapter, NULL);
				set_tx_beacon_cmd(padapter->pbuddy_adapter);
			}
		}
#endif
	}
#endif //CONFIG_INTERRUPT_BASED_TXBCN

#ifdef CONFIG_EXT_CLK
	if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
	{
		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;

		if(check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE))
		{
			//DBG_8192C("BCNERLY_INT for enabling ext clk\n");
			EnableGpio5ClockReq(padapter, _TRUE, 1);
		}
	}
#endif //CONFIG_EXT_CLK

	if (pHalData->sdio_hisr & SDIO_HISR_C2HCMD)
	{
		DBG_8192C("%s: C2H Command\n", __func__);
	}

	if (pHalData->sdio_hisr & SDIO_HISR_RX_REQUEST)
	{
		struct recv_buf *precvbuf;

		//DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
		pHalData->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
#ifdef CONFIG_MAC_LOOPBACK_DRIVER
		sd_recv_loopback(padapter, pHalData->SdioRxFIFOSize);
#else
		do {
			//Sometimes rx length will be zero. driver need to use cmd53 read again.
			if(pHalData->SdioRxFIFOSize == 0)
			{
				u8 data[4];

				_sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, data);

				pHalData->SdioRxFIFOSize = le16_to_cpu(*(u16*)data);
			}

			if(pHalData->SdioRxFIFOSize)
			{
				precvbuf = sd_recv_rxfifo(padapter, pHalData->SdioRxFIFOSize);

				pHalData->SdioRxFIFOSize = 0;

				if (precvbuf)
					sd_rxhandler(padapter, precvbuf);
				else
					break;
			}
			else
				break;
#ifdef CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP
		} while (0);
#else
		} while (1);
#endif
#endif

	}
Esempio n. 5
0
static void update_BCNTIM(struct adapter *padapter)
{
	struct sta_priv *pstapriv = &padapter->stapriv;
	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
	struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
	unsigned char *pie = pnetwork_mlmeext->ies;
	u8 *p, *dst_ie, *premainder_ie = NULL;
	u8 *pbackup_remainder_ie = NULL;
	uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;

	/* update TIM IE */
	p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen,
			pnetwork_mlmeext->ie_length - _FIXED_IE_LENGTH_);
	if (p && tim_ielen > 0) {
		tim_ielen += 2;
		premainder_ie = p + tim_ielen;
		tim_ie_offset = (int)(p - pie);
		remainder_ielen = pnetwork_mlmeext->ie_length -
					tim_ie_offset - tim_ielen;
		/* append TIM IE from dst_ie offset */
		dst_ie = p;
	} else {
		tim_ielen = 0;

		/* calculate head_len */
		offset = _FIXED_IE_LENGTH_;
		offset += pnetwork_mlmeext->Ssid.SsidLength + 2;

		/*  get supported rates len */
		p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_,
			       &tmp_len, (pnetwork_mlmeext->ie_length -
					  _BEACON_IE_OFFSET_));
		if (p)
			offset += tmp_len+2;

		/* DS Parameter Set IE, len = 3 */
		offset += 3;

		premainder_ie = pie + offset;

		remainder_ielen = pnetwork_mlmeext->ie_length -
					offset - tim_ielen;

		/* append TIM IE from offset */
		dst_ie = pie + offset;
	}

	if (remainder_ielen > 0) {
		pbackup_remainder_ie = rtw_malloc(remainder_ielen);
		if (pbackup_remainder_ie && premainder_ie)
			memcpy(pbackup_remainder_ie, premainder_ie,
			       remainder_ielen);
	}
	*dst_ie++ = _TIM_IE_;

	if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fc))
		tim_ielen = 5;
	else
		tim_ielen = 4;

	*dst_ie++ = tim_ielen;

	*dst_ie++ = 0;/* DTIM count */
	*dst_ie++ = 1;/* DTIM period */

	if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */
		*dst_ie++ = BIT(0);/* bitmap ctrl */
	else
		*dst_ie++ = 0;

	if (tim_ielen == 4) {
		*dst_ie++ = pstapriv->tim_bitmap & 0xff;
	} else if (tim_ielen == 5) {
		put_unaligned_le16(pstapriv->tim_bitmap, dst_ie);
		dst_ie += 2;
	}

	/* copy remainder IE */
	if (pbackup_remainder_ie) {
		memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);

		kfree(pbackup_remainder_ie);
	}
	offset =  (uint)(dst_ie - pie);
	pnetwork_mlmeext->ie_length = offset + remainder_ielen;

	set_tx_beacon_cmd(padapter);
}