// 1: write RCR DATA BIT
// 2: issue peer traffic indication
// 3: go back to the channel linked with AP, terminating channel switch procedure
// 4: init channel sensing, receive all data and mgnt frame
// 5: channel sensing and report candidate channel
// 6: first time set channel to off channel
// 7: go back tp the channel linked with AP when set base channel as target channel
void TDLS_option_workitem_callback(struct work_struct *work)
{
	struct sta_info *ptdls_sta = container_of(work, struct sta_info, option_workitem);
	_adapter *padapter = ptdls_sta->padapter;
	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
	u32 bit_6=1<<6, bit_7=1<<7, bit_4=1<<4;
	u8 survey_channel, i, min;
	
	switch(ptdls_sta->option){
		case 1:
			//As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0
			//such we can receive all kinds of data frames.
			rtw_write32(padapter, 0x0608, rtw_read32(padapter, 0x0608)&(~bit_6));
			DBG_8192C("wirte 0x0608, set bit6 off\n");
			break;
		case 2:
			issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
			break;
		case 3:
			_cancel_timer_ex(&ptdls_sta->base_ch_timer);
			_cancel_timer_ex(&ptdls_sta->off_ch_timer);
			SelectChannel(padapter, pmlmeext->cur_channel);
			ptdls_sta->state &= ~(TDLS_CH_SWITCH_ON_STATE | 
								TDLS_PEER_AT_OFF_STATE | 
								TDLS_AT_OFF_CH_STATE);
			DBG_8192C("go back to base channel\n ");
			issue_nulldata(padapter, 0);
			break;
		case 4:
			rtw_write32(padapter, 0x0608, rtw_read32(padapter, 0x0608)&(~bit_6)&(~bit_7));
			rtw_write16(padapter, 0x06A4,0xffff);	//maybe don't need to write here

			//disable update TSF
			rtw_write8(padapter, 0x0550, rtw_read8(padapter, 0x0550)|bit_4);

			pmlmeext->sitesurvey_res.channel_idx = 0;
			ptdls_sta->option = 5;
			_set_workitem(&ptdls_sta->option_workitem);
			break;
		case 5:
			survey_channel = pmlmeext->channel_set[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
			if(survey_channel){
				SelectChannel(padapter, survey_channel);
				pmlmeinfo->tdls_cur_channel = survey_channel;
				pmlmeext->sitesurvey_res.channel_idx++;
				_set_timer(&ptdls_sta->option_timer, SURVEY_TO);
			}else{
				SelectChannel(padapter, pmlmeext->cur_channel);

				//enable update TSF
				rtw_write8(padapter, 0x0550, rtw_read8(padapter, 0x0550)&(~bit_4));
				rtw_write32(padapter, 0x0608, rtw_read32(padapter, 0x0608)|(bit_7));

				if(pmlmeinfo->tdls_ch_sensing==1){
					pmlmeinfo->tdls_ch_sensing=0;
					pmlmeinfo->tdls_cur_channel=1;
					min=pmlmeinfo->tdls_collect_pkt_num[0];
					for(i=1; i<14-1; i++){
						if(min > pmlmeinfo->tdls_collect_pkt_num[i]){
							pmlmeinfo->tdls_cur_channel=i+1;
							min=pmlmeinfo->tdls_collect_pkt_num[i];
						}
						pmlmeinfo->tdls_collect_pkt_num[i]=0;
					}
					pmlmeinfo->tdls_collect_pkt_num[0]=0;
					pmlmeinfo->tdls_candidate_ch=pmlmeinfo->tdls_cur_channel;
					DBG_8192C("TDLS channel sensing done, candidate channel: %02x\n", pmlmeinfo->tdls_candidate_ch);
					pmlmeinfo->tdls_cur_channel=0;

				}

				if(ptdls_sta->state & TDLS_PEER_SLEEP_STATE){
					ptdls_sta->state |= TDLS_APSD_CHSW_STATE;
				}else{
					//send null data with pwrbit==1 before send ch_switching_req to peer STA.
					issue_nulldata(padapter, 1);

					ptdls_sta->state |= TDLS_CH_SW_INITIATOR_STATE;

					issue_tdls_ch_switch_req(padapter, ptdls_sta->hwaddr);
					DBG_8192C("issue tdls ch switch req\n");
				}
			}
			break;
		case 6:
			issue_nulldata(padapter, 1);
			SelectChannel(padapter, ptdls_sta->off_ch);

			DBG_8192C("change channel to tar ch:%02x\n", ptdls_sta->off_ch);
			ptdls_sta->state |= TDLS_AT_OFF_CH_STATE;
			ptdls_sta->state &= ~(TDLS_PEER_AT_OFF_STATE);
			_set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
			break;
		case 7:
			_cancel_timer_ex(&ptdls_sta->base_ch_timer);
			_cancel_timer_ex(&ptdls_sta->off_ch_timer);
			SelectChannel(padapter, pmlmeext->cur_channel);
			ptdls_sta->state &= ~(TDLS_CH_SWITCH_ON_STATE | 
								TDLS_PEER_AT_OFF_STATE | 
								TDLS_AT_OFF_CH_STATE);
			DBG_8192C("go back to base channel\n ");
			issue_nulldata(padapter, 0);
			_set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
			break;			
	}
	
}
Example #2
0
static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_buf	*precvbuf, struct phy_stat *pphy_status)
{	
	s32 ret=_SUCCESS;
#ifdef CONFIG_CONCURRENT_MODE	
	u8 *primary_myid, *secondary_myid, *paddr1;
	union recv_frame	*precvframe_if2 = NULL;
	_adapter *primary_padapter = precvframe->u.hdr.adapter;
	_adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
	struct recv_priv *precvpriv = &primary_padapter->recvpriv;
	_queue *pfree_recv_queue = &precvpriv->free_recv_queue;
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(primary_padapter);

	if(!secondary_padapter)
		return ret;

	paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data);

	if(IS_MCAST(paddr1) == _FALSE)//unicast packets
	{
		//primary_myid = myid(&primary_padapter->eeprompriv);
		secondary_myid = myid(&secondary_padapter->eeprompriv);

		if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN))
		{			
			//change to secondary interface
			precvframe->u.hdr.adapter = secondary_padapter;
		}	

		//ret = recv_entry(precvframe);

	}
	else // Handle BC/MC Packets	
	{
		//clone/copy to if2
		_pkt	 *pkt_copy = NULL;
		struct rx_pkt_attrib *pattrib = NULL;
		
		precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);

		if(!precvframe_if2)
			return _FAIL;
		
		precvframe_if2->u.hdr.adapter = secondary_padapter;
		_rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
		pattrib = &precvframe_if2->u.hdr.attrib;

		//driver need to set skb len for rtw_skb_copy().
		//If skb->len is zero, rtw_skb_copy() will not copy data from original skb.
		skb_put(precvframe->u.hdr.pkt, pattrib->pkt_len);

		pkt_copy = rtw_skb_copy(precvframe->u.hdr.pkt);
		if (pkt_copy == NULL)
		{
			if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
			{				
				DBG_8192C("pre_recv_entry(): rtw_skb_copy fail , drop frag frame \n");
				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
				return ret;
			}

			pkt_copy = rtw_skb_clone(precvframe->u.hdr.pkt);
			if(pkt_copy == NULL)
			{
				DBG_8192C("pre_recv_entry(): rtw_skb_clone fail , drop frame\n");
				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
				return ret;
			}
		}
		
		pkt_copy->dev = secondary_padapter->pnetdev;

		precvframe_if2->u.hdr.pkt = pkt_copy;
		precvframe_if2->u.hdr.rx_head = pkt_copy->head;
		precvframe_if2->u.hdr.rx_data = pkt_copy->data;
		precvframe_if2->u.hdr.rx_tail = skb_tail_pointer(pkt_copy);
		precvframe_if2->u.hdr.rx_end = skb_end_pointer(pkt_copy);
		precvframe_if2->u.hdr.len = pkt_copy->len;

		//recvframe_put(precvframe_if2, pattrib->pkt_len);

		if ( pHalData->ReceiveConfig & RCR_APPFCS)
			recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN);

		if (pattrib->physt) 
			update_recvframe_phyinfo(precvframe_if2, pphy_status);

		if(rtw_recv_entry(precvframe_if2) != _SUCCESS)
		{
			RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
				("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
		}
	}

	if (precvframe->u.hdr.attrib.physt)
		update_recvframe_phyinfo(precvframe, pphy_status);

	ret = rtw_recv_entry(precvframe);
#endif

	return ret;

}
/*****************************************
* H2C Msg format :
* 0x1DF - 0x1D0
*| 31 - 8	| 7-5 	 4 - 0	|
*| h2c_msg 	|Class_ID CMD_ID	|
*
* Extend 0x1FF - 0x1F0
*|31 - 0	  |
*|ext_msg|
******************************************/
static s32 FillH2CCmd_8812(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
{
	u8 bcmd_down = _FALSE;
	s32 retry_cnts = 100;
	u8 h2c_box_num;
	u32	msgbox_addr;
	u32 msgbox_ex_addr;
	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
	u8 cmd_idx,ext_cmd_len;
	u32	h2c_cmd = 0;
	u32	h2c_cmd_ex = 0;
	s32 ret = _FAIL;

_func_enter_;

	padapter = GET_PRIMARY_ADAPTER(padapter);		
	pHalData = GET_HAL_DATA(padapter);

	
	if(padapter->bFWReady == _FALSE)
	{
		//DBG_8192C("FillH2CCmd_8812(): return H2C cmd because fw is not ready\n");
		return ret;
	}

	_enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);


	if (!pCmdBuffer) {
		goto exit;
	}
	if (CmdLen > RTL8812_MAX_CMD_LEN) {
		goto exit;
	}
	if (padapter->bSurpriseRemoved == _TRUE)
		goto exit;

	//pay attention to if  race condition happened in  H2C cmd setting.
	do{
		h2c_box_num = pHalData->LastHMEBoxNum;

		if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){
			DBG_8192C(" fw read cmd failed...\n");
			goto exit;
		}

		*(u8*)(&h2c_cmd) = ElementID;

		if(CmdLen<=3)
		{
			_rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen );
		}
		else{			
			_rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer,3);
			ext_cmd_len = CmdLen-3;	
			_rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3,ext_cmd_len );

			//Write Ext command
			msgbox_ex_addr = REG_HMEBOX_EXT0_8812 + (h2c_box_num *RTL8812_EX_MESSAGE_BOX_SIZE);
			#ifdef CONFIG_H2C_EF
			for(cmd_idx=0;cmd_idx<ext_cmd_len;cmd_idx++ ){
				rtw_write8(padapter,msgbox_ex_addr+cmd_idx,*((u8*)(&h2c_cmd_ex)+cmd_idx));
			}
			#else
			h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex );
			rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);
			#endif
		}
		// Write command
		msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *RTL8812_MESSAGE_BOX_SIZE);
		#ifdef CONFIG_H2C_EF
		for(cmd_idx=0;cmd_idx<RTL8812_MESSAGE_BOX_SIZE;cmd_idx++ ){
			rtw_write8(padapter,msgbox_addr+cmd_idx,*((u8*)(&h2c_cmd)+cmd_idx));
		}
		#else
		h2c_cmd = le32_to_cpu( h2c_cmd );
		rtw_write32(padapter,msgbox_addr, h2c_cmd);
		#endif

		bcmd_down = _TRUE;

	//	DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n"
	//	 	,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex);

		pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL8812_MAX_H2C_BOX_NUMS;

	}while((!bcmd_down) && (retry_cnts--));

	ret = _SUCCESS;

exit:

	_exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);	

_func_exit_;

	return ret;
}
Example #4
0
void interrupt_handler_8812au(_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_88E )
		DBG_871X("===> %s Tx Error Flag Interrupt Status \n",__FUNCTION__);
	if(  pHalData->IntArray[1]  & IMR_RXERR_88E )
		DBG_871X("===> %s Rx Error Flag INT Status \n",__FUNCTION__);
	if(  pHalData->IntArray[1]  & IMR_TXFOVW_88E )
		DBG_871X("===> %s Transmit FIFO Overflow \n",__FUNCTION__);
	if(  pHalData->IntArray[1]  & IMR_RXFOVW_88E )
		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..
	}		
		
}
Example #5
0
int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
{
	_adapter	*padapter = pintfhdl->padapter;
	struct dvobj_priv  *pdvobjpriv = adapter_to_dvobj(padapter);
	struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobjpriv);
	struct usb_device *udev=pdvobjpriv->pusbdev;

	unsigned int pipe;
	int status = 0;
	u32 tmp_buflen=0;
	u8 reqtype;
	u8 *pIo_buf;
	int vendorreq_times = 0;

	#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
	u8 *tmp_buf;
	#else // use stack memory
	u8 tmp_buf[MAX_USB_IO_CTL_SIZE];
	#endif

#ifdef CONFIG_CONCURRENT_MODE
	if(padapter->adapter_type > PRIMARY_ADAPTER)
	{
		padapter = padapter->pbuddy_adapter;
		pdvobjpriv = adapter_to_dvobj(padapter);
		udev = pdvobjpriv->pusbdev;
	}
#endif

	//DBG_871X("%s %s:%d\n",__FUNCTION__, current->comm, current->pid);

	if (RTW_CANNOT_IO(padapter)){
		RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq:(RTW_CANNOT_IO)!!!\n"));
		status = -EPERM; 
		goto exit;
	}	

	if(len>MAX_VENDOR_REQ_CMD_SIZE){
		DBG_8192C( "[%s] Buffer len error ,vendor request failed\n", __FUNCTION__ );
		status = -EINVAL;
		goto exit;
	}	

	#ifdef CONFIG_USB_VENDOR_REQ_MUTEX
	_enter_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL);
	#endif	

	
	// Acquire IO memory for vendorreq
#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC
	pIo_buf = pdvobjpriv->usb_vendor_req_buf;
#else
	#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
	tmp_buf = rtw_malloc( (u32) len + ALIGNMENT_UNIT);
	tmp_buflen =  (u32)len + ALIGNMENT_UNIT;
	#else // use stack memory
	tmp_buflen = MAX_USB_IO_CTL_SIZE;
	#endif

	// Added by Albert 2010/02/09
	// For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment.
	// Trying to fix it here.
	pIo_buf = (tmp_buf==NULL)?NULL:tmp_buf + ALIGNMENT_UNIT -((SIZE_PTR)(tmp_buf) & 0x0f );	
#endif

	if ( pIo_buf== NULL) {
		DBG_8192C( "[%s] pIo_buf == NULL \n", __FUNCTION__ );
		status = -ENOMEM;
		goto release_mutex;
	}
	
	while(++vendorreq_times<= MAX_USBCTRL_VENDORREQ_TIMES)
	{
		_rtw_memset(pIo_buf, 0, len);
		
		if (requesttype == 0x01)
		{
			pipe = usb_rcvctrlpipe(udev, 0);//read_in
			reqtype =  REALTEK_USB_VENQT_READ;		
		} 
		else 
		{
			pipe = usb_sndctrlpipe(udev, 0);//write_out
			reqtype =  REALTEK_USB_VENQT_WRITE;		
			_rtw_memcpy( pIo_buf, pdata, len);
		}		
	
		status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
		
		if ( status == len)   // Success this control transfer.
		{
			rtw_reset_continual_io_error(pdvobjpriv);
			if ( requesttype == 0x01 )
			{   // For Control read transfer, we have to copy the read data from pIo_buf to pdata.
				_rtw_memcpy( pdata, pIo_buf,  len );
			}
		}
		else { // error cases
			DBG_8192C("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n"
				, value,(requesttype == 0x01)?"read":"write" , len, status, *(u32*)pdata, vendorreq_times);
			
			if (status < 0) {
				if(status == (-ESHUTDOWN)	|| status == -ENODEV	)
				{			
					padapter->bSurpriseRemoved = _TRUE;
				} else {
					#ifdef DBG_CONFIG_ERROR_DETECT
					{
						HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
						pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
					}
					#endif
				}
			}
			else // status != len && status >= 0
			{
				if(status > 0) {
					if ( requesttype == 0x01 )
					{   // For Control read transfer, we have to copy the read data from pIo_buf to pdata.
						_rtw_memcpy( pdata, pIo_buf,  len );
					}
				}
			}

			if(rtw_inc_and_chk_continual_io_error(pdvobjpriv) == _TRUE ){
				padapter->bSurpriseRemoved = _TRUE;
				break;
			}
	
		}
	
		// firmware download is checksumed, don't retry
		if( (value >= FW_START_ADDRESS ) || status == len )
			break;
	
	}

	// release IO memory used by vendorreq
	#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
	rtw_mfree(tmp_buf, tmp_buflen);
	#endif

release_mutex:
	#ifdef CONFIG_USB_VENDOR_REQ_MUTEX
	_exit_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL);
	#endif
exit:
	return status;

}
Example #6
0
s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
{
    s32 ret = _SUCCESS;
    s32 inner_ret = _SUCCESS;
    _irqL irqL;
    int	t, sz, w_sz, pull=0;
    //u8	*mem_addr;
    u32	ff_hwaddr;
    struct xmit_buf		*pxmitbuf = pxmitframe->pxmitbuf;
    struct pkt_attrib		*pattrib = &pxmitframe->attrib;
    struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
    struct dvobj_priv		*pdvobjpriv = adapter_to_dvobj(padapter);
    struct security_priv	*psecuritypriv = &padapter->securitypriv;
    struct tx_desc		*ptxdesc;

    if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
            (pxmitframe->attrib.ether_type != 0x0806) &&
            (pxmitframe->attrib.ether_type != 0x888e) &&
            (pxmitframe->attrib.dhcp_pkt != 1))
    {
        rtw_issue_addbareq_cmd(padapter, pxmitframe);
    }

    //mem_addr = pxmitframe->buf_addr;

    RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));

    for (t = 0; t < pattrib->nr_frags; t++)
    {
        if (inner_ret != _SUCCESS && ret == _SUCCESS)
            ret = _FAIL;

        if (t != (pattrib->nr_frags - 1))
        {
            RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));

            sz = pxmitpriv->frag_len;
            sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
        }
        else //no frag
        {
            sz = pattrib->last_txcmdsz;
        }

        ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);

        _enter_critical(&pdvobjpriv->irq_th_lock, &irqL);

        ptxdesc = get_txdesc(pxmitframe, ff_hwaddr);
        if(ptxdesc == NULL)
        {
            _exit_critical(&pdvobjpriv->irq_th_lock, &irqL);
            rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
            DBG_8192C("##### Tx desc unavailable !#####\n");
            break;
        }

        update_txdesc(pxmitframe, (uint*)ptxdesc, sz);

        rtl8192de_enqueue_xmitbuf(&pxmitpriv->tx_ring[ff_hwaddr], pxmitbuf);

        pxmitbuf->len = sz;

        _exit_critical(&pdvobjpriv->irq_th_lock, &irqL);

        w_sz = sz;

        rtw_write16(padapter, REG_PCIE_CTRL_REG, ffaddr2dma(ff_hwaddr));

        inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);

        rtw_count_tx_stats(padapter, pxmitframe, sz);

        RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz));
        //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority);

        //mem_addr += w_sz;

        //mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));

    }

    rtw_free_xmitframe(pxmitpriv, pxmitframe);

    if  (ret != _SUCCESS)
        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);

    return ret;
}
Example #7
0
void sd_int_dpc(PADAPTER padapter)
{
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);

	if (pHalData->sdio_hisr & SDIO_HISR_CPWM1)
	{
		struct reportpwrstate_parm report;

		_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
				{
					struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;

					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(&padapter->pwrctrlpriv.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(&adapter_to_dvobj(padapter)->intf_data, addr, 4, status);
			_sd_write(&adapter_to_dvobj(padapter)->intf_data, 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

	}
void rtw_ps_processor(_adapter*padapter)
{
#ifdef CONFIG_P2P
	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo );
#endif
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
	int res;
	rt_rf_power_state rfpwrstate;
	
#ifdef SUPPORT_HW_RFOFF_DETECTED
	if(pwrpriv->bips_processing == _TRUE)	return;		
	
	//DBG_8192C("==> fw report state(0x%x)\n",rtw_read8(padapter,0x1ca));	
	if(padapter->pwrctrlpriv.bHWPwrPindetect) 
	{
	#ifdef CONFIG_AUTOSUSPEND
		if(padapter->registrypriv.usbss_enable)
		{
			if(padapter->net_closed == _TRUE)	return;
			
			if(pwrpriv->current_rfpwrstate == rf_on)
			{
				rfpwrstate = RfOnOffDetect(padapter);
				DBG_8192C("@@@@- #1  %s==> rfstate:%s \n",__FUNCTION__,(rfpwrstate==rf_on)?"rf_on":"rf_off");
				if(rfpwrstate!= pwrpriv->current_rfpwrstate)
				{
					if(rfpwrstate == rf_off)
					{
						pwrpriv->change_rfpwrstate = rf_off;
						
						pwrpriv->bkeepfwalive = _TRUE;	
						pwrpriv->brfoffbyhw = _TRUE;						
						
						autosuspend_enter(padapter);							
					}
				}
			}			
		}
		else
	#endif
		{
			rfpwrstate = RfOnOffDetect(padapter);
			DBG_8192C("@@@@- #2  %s==> rfstate:%s \n",__FUNCTION__,(rfpwrstate==rf_on)?"rf_on":"rf_off");

			if(rfpwrstate!= pwrpriv->current_rfpwrstate)
			{
				if(rfpwrstate == rf_off)
				{	
					pwrpriv->change_rfpwrstate = rf_off;														
					pwrpriv->brfoffbyhw = _TRUE;
					padapter->bCardDisableWOHSM = _TRUE;
					rtw_hw_suspend(padapter );	
				}
				else
				{
					pwrpriv->change_rfpwrstate = rf_on;
					rtw_hw_resume(padapter );			
				}
				DBG_8192C("current_rfpwrstate(%s)\n",(pwrpriv->current_rfpwrstate == rf_off)?"rf_off":"rf_on");
			}
		}
		pwrpriv->pwr_state_check_cnts ++;	
	}
	
#endif
	if( pwrpriv->power_mgnt == PS_MODE_ACTIVE )	return;
				
	if(padapter->net_closed == _TRUE)	return;

	if((pwrpriv->current_rfpwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4)==0))
	{
		if (	(check_fwstate(pmlmepriv, _FW_LINKED|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) ||
			(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) ||
			(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
			(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
			(padapter->net_closed == _TRUE)|| (padapter->bup == _FALSE)	
#ifdef CONFIG_P2P
			|| (pwdinfo->p2p_state != P2P_STATE_NONE)
#endif
		)
		{
			return;
		}
		DBG_8192C("==>%s .fw_state(%x)\n",__FUNCTION__,padapter->mlmepriv.fw_state);
		pwrpriv->change_rfpwrstate = rf_off;

#ifdef CONFIG_AUTOSUSPEND
		if(padapter->registrypriv.usbss_enable)
		{		
			if(padapter->pwrctrlpriv.bHWPwrPindetect) 
				pwrpriv->bkeepfwalive = _TRUE;				
			
			padapter->bCardDisableWOHSM = _TRUE;
			autosuspend_enter(padapter);
		}		
		else if(padapter->pwrctrlpriv.bHWPwrPindetect)
		{
		}
		else
#endif	
		{
#ifdef CONFIG_IPS	
			ips_enter(padapter);			
#endif
		}
	}

	
}
void rtw_set_ps_mode(_adapter * padapter, u8 ps_mode, u8 smart_ps)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
#ifdef CONFIG_P2P
	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo );
#endif

_func_enter_;

	RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("========= Power Mode is :%d, Smart_PS = %d\n", ps_mode,smart_ps));
	//DBG_8192C("========= Power Mode is :%d, Smart_PS = %d\n", ps_mode,smart_ps);

	if(ps_mode > PM_Card_Disable) {
		RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("ps_mode:%d error\n", ps_mode));
		return;
	}

	if((pwrpriv->pwr_mode == ps_mode) &&
		(pwrpriv->smart_ps == smart_ps)){
		return;
	}

	//if(pwrpriv->pwr_mode == PS_MODE_ACTIVE)
	if(ps_mode == PS_MODE_ACTIVE)
	{
#ifdef CONFIG_P2P
		if(pwdinfo->opp_ps == 0)
#endif
		{
			DBG_8192C("rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..\n");
			pwrpriv->smart_ps = smart_ps;
			pwrpriv->pwr_mode = ps_mode;
			rtw_set_rpwm(padapter, PS_STATE_S4);
			padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
			pwrpriv->bFwCurrentInPSMode = _FALSE;
		}
	}
	else
	{
		if(PS_RDY_CHECK(padapter))
		{
			DBG_8192C("rtw_set_ps_mode(): Enter 802.11 power save mode...\n");
			pwrpriv->smart_ps = smart_ps;
			pwrpriv->pwr_mode = ps_mode;
			pwrpriv->bFwCurrentInPSMode = _TRUE;
			padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
#ifdef CONFIG_P2P
			// Set CTWindow after LPS
			if(pwdinfo->opp_ps == 1)
			//if(pwdinfo->p2p_ps_enable == _TRUE)
				p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
#endif
			rtw_set_rpwm(padapter, PS_STATE_S2);
		}
		//else
		//{
		//	pwrpriv->pwr_mode = PS_MODE_ACTIVE;
		//}
	}

_func_exit_;
}
Example #10
0
void sd_int_dpc(PADAPTER padapter)
{
	PHAL_DATA_TYPE phal;
	struct dvobj_priv *dvobj;
	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
	struct pwrctrl_priv *pwrctl;


	phal = GET_HAL_DATA(padapter);
	dvobj = adapter_to_dvobj(padapter);
	pwrctl = dvobj_to_pwrctl(dvobj);

	if (phal->sdio_hisr & SDIO_HISR_CPWM1)
	{
		struct reportpwrstate_parm report;

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

		report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8723B);

#ifdef CONFIG_LPS_LCLK
		//cpwm_int_hdl(padapter, &report);
		_set_workitem(&(pwrctl->cpwm_event));
#endif
	}

	if (phal->sdio_hisr & SDIO_HISR_TXERR)
	{
		u8 *status;
		u32 addr;

		status = rtw_malloc(4);
		if (status)
		{
			addr = REG_TXDMA_STATUS;
			HalSdioGetCmdAddr8723BSdio(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__);
		}
	}

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

	if (phal->sdio_hisr & SDIO_HISR_TXBCNERR)
	{
		DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
	}
#ifndef CONFIG_C2H_PACKET_EN
	if (phal->sdio_hisr & SDIO_HISR_C2HCMD)
	{
		struct c2h_evt_hdr_88xx *c2h_evt;

		DBG_8192C("%s: C2H Command\n", __func__);
		if ((c2h_evt = (struct c2h_evt_hdr_88xx*)rtw_zmalloc(16)) != NULL) {
			if (rtw_hal_c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) {
				if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
					/* Handle CCX report here */
					rtw_hal_c2h_handler(padapter, (u8 *)c2h_evt);
					rtw_mfree((u8*)c2h_evt, 16);
				} else {
					rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt);
				}
			}
		} else {
			/* Error handling for malloc fail */
			if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS)
				DBG_871X("%s rtw_cbuf_push fail\n", __func__);
			_set_workitem(&padapter->evtpriv.c2h_wk);
		}
	}
#endif

	if (phal->sdio_hisr & SDIO_HISR_RXFOVW)
	{
		DBG_8192C("%s: Rx Overflow\n", __func__);
	}
	if (phal->sdio_hisr & SDIO_HISR_RXERR)
	{
		DBG_8192C("%s: Rx Error\n", __func__);
	}

	if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST)
	{
		struct recv_buf *precvbuf;
		int alloc_fail_time=0;
		u32 hisr;

//		DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
		phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
		do {
			phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN);
			if (phal->SdioRxFIFOSize != 0)
			{
#ifdef CONFIG_MAC_LOOPBACK_DRIVER
				sd_recv_loopback(padapter, phal->SdioRxFIFOSize);
#else
				precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize);
				if (precvbuf)
					sd_rxhandler(padapter, precvbuf);
				else
				{
					alloc_fail_time++;
					DBG_871X("precvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
					if (alloc_fail_time >= 10)
						break;
				}
				phal->SdioRxFIFOSize = 0;
#endif
			}
			else
				break;

			hisr = 0;
			ReadInterrupt8723BSdio(padapter, &hisr);
			hisr &= SDIO_HISR_RX_REQUEST;
			if (!hisr)
				break;
		} while (1);

		if(alloc_fail_time==10)
			DBG_871X("exit because alloc memory failed more than 10 times \n");

	}
}
Example #11
0
u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr)
{
	PADAPTER padapter;
	u8 bMacPwrCtrlOn;
	u8 deviceId;
	u16 offset;
	u32 ftaddr;
	u8 shift;
	u32 val;
	s32 err;

_func_enter_;

	padapter = pintfhdl->padapter;
	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);

	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
		|| (_FALSE == bMacPwrCtrlOn)
#ifdef CONFIG_LPS_LCLK
		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
#endif
		)
	{
		err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8*)&val);
#ifdef SDIO_DEBUG_IO
		if (!err) {
#endif
			val = le32_to_cpu(val);
			return val;
#ifdef SDIO_DEBUG_IO
		}

		DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr);
		return SDIO_ERR_VAL32;
#endif
	}

	// 4 bytes alignment
	shift = ftaddr & 0x3;
	if (shift == 0) {
		val = sd_read32(pintfhdl, ftaddr, NULL);
	} else {
		u8 *ptmpbuf;

		ptmpbuf = (u8*)rtw_malloc(8);
		if (NULL == ptmpbuf) {
			DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr);
			return SDIO_ERR_VAL32;
		}

		ftaddr &= ~(u16)0x3;
		sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
		_rtw_memcpy(&val, ptmpbuf+shift, 4);
		val = le32_to_cpu(val);

		rtw_mfree(ptmpbuf, 8);
	}

_func_exit_;

	return val;
}
Example #12
0
/*
 * Notice:
 *	Before calling this function,
 *	precvframe->u.hdr.rx_data should be ready!
 */
void update_recvframe_phyinfo(
	union recv_frame	*precvframe,
	struct phy_stat *pphy_status)
{
	PADAPTER 			padapter= precvframe->u.hdr.adapter;
	struct rx_pkt_attrib	*pattrib = &precvframe->u.hdr.attrib;
	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(padapter);	
	PODM_PHY_INFO_T 	pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info);
	
	u8			*wlanhdr;
	ODM_PACKET_INFO_T	pkt_info;
	u8 *sa;
	//_irqL		irqL;
	struct sta_priv *pstapriv;
	struct sta_info *psta;
	
	pkt_info.bPacketMatchBSSID =_FALSE;
	pkt_info.bPacketToSelf = _FALSE;
	pkt_info.bPacketBeacon = _FALSE;


	wlanhdr = get_recvframe_data(precvframe);

	pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) &&
		!pattrib->icv_err && !pattrib->crc_err &&
		_rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN));

	pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_da(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN));

	pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON);

	if(pkt_info.bPacketBeacon){
		if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){				
			sa = padapter->mlmepriv.cur_network.network.MacAddress;
			#if 0
			{					
				DBG_8192C("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n",
					sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]);					
			}
			#endif
		}
		//to do Ad-hoc
	}
	else{
		sa = get_sa(wlanhdr);
	}			
		
	pkt_info.StationID = 0xFF;
	
	pstapriv = &padapter->stapriv;
	psta = rtw_get_stainfo(pstapriv, sa);
	if (psta)
	{
      		pkt_info.StationID = psta->mac_id;
		//DBG_8192C("%s ==> StationID(%d)\n",__FUNCTION__,pkt_info.StationID);
	}
	pkt_info.Rate = pattrib->mcs_rate;
		

	//rtl8192c_query_rx_phy_status(precvframe, pphy_status);
	//_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
	ODM_PhyStatusQuery(&pHalData->odmpriv,pPHYInfo,(u8 *)pphy_status,&(pkt_info));
	//_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
	precvframe->u.hdr.psta = NULL;
	if (pkt_info.bPacketMatchBSSID &&
		(check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE))
	{
		if (psta)
		{ 
			precvframe->u.hdr.psta = psta;
			rtl8192c_process_phy_info(padapter, precvframe);
              }
	}
	else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon)
	{
		if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)
		{
			if (psta)
			{
				precvframe->u.hdr.psta = psta;
			}
		}
		rtl8192c_process_phy_info(padapter, precvframe);             
	}
}
Example #13
0
static void rtl8723as_recv_tasklet(void *priv)
{
	PADAPTER				padapter;
	PHAL_DATA_TYPE			pHalData;
	struct recv_priv		*precvpriv;
	struct recv_buf			*precvbuf;
	union recv_frame		*precvframe;
	struct recv_frame_hdr	*phdr;
	struct rx_pkt_attrib	*pattrib;
	u8			*ptr;
	_pkt		*ppkt;
	u32			pkt_offset;
	_irqL		irql;


	padapter = (PADAPTER)priv;
	pHalData = GET_HAL_DATA(padapter);
	precvpriv = &padapter->recvpriv;

	do {
		precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
		if (NULL == precvbuf) break;

		ptr = precvbuf->pdata;

		while (ptr < precvbuf->ptail)
		{
			precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
			if (precvframe == NULL) {
				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("rtl8723as_recv_tasklet: no enough recv frame!\n"));
				rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);

				// The case of can't allocte recvframe should be temporary,
				// schedule again and hope recvframe is available next time.
#ifdef PLATFORM_LINUX
				tasklet_schedule(&precvpriv->recv_tasklet);
#endif
				return;
			}

			phdr = &precvframe->u.hdr;
			pattrib = &phdr->attrib;

			update_recvframe_attrib(precvframe, (struct recv_stat*)ptr);

			// fix Hardware RX data error, drop whole recv_buffer
			if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
			{
				if (padapter->registrypriv.mp_mode == 1)
					padapter->mppriv.rx_crcerrpktcount++;
				else
					DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
				break;
			}

			pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->pkt_len;
#if 0 // reduce check to speed up
			if ((ptr + pkt_offset) > precvbuf->ptail) {
				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
						("%s: next pkt len(%p,%d) exceed ptail(%p)!\n",
						__FUNCTION__, ptr, pkt_offset, precvbuf->ptail));
				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
				break;
			}
#endif

			if ((pattrib->crc_err) || (pattrib->icv_err))
			{
				if (padapter->registrypriv.mp_mode == 0)
				DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
			}
			else
			{
				ppkt = rtw_skb_clone(precvbuf->pskb);
				if (ppkt == NULL)
				{
					RT_TRACE(_module_rtl871x_recv_c_, _drv_crit_, ("rtl8723as_recv_tasklet: no enough memory to allocate SKB!\n"));
					rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
					rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);

					// The case of can't allocte skb is serious and may never be recovered,
					// once bDriverStopped is enable, this task should be stopped.
					if (padapter->bDriverStopped == _FALSE) {
#ifdef PLATFORM_LINUX
						tasklet_schedule(&precvpriv->recv_tasklet);
#endif
					}

					return;
				}

				phdr->pkt = ppkt;
				phdr->len = 0;
				phdr->rx_head = precvbuf->phead;
				phdr->rx_data = phdr->rx_tail = precvbuf->pdata;
				phdr->rx_end = precvbuf->pend;
				recvframe_put(precvframe, pkt_offset);
				recvframe_pull(precvframe, RXDESC_SIZE + pattrib->drvinfo_sz);
				if (pHalData->ReceiveConfig & RCR_APPFCS)
					recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);

				// move to drv info position
				ptr += RXDESC_SIZE;

				// update drv info
				if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
//					rtl8723s_update_bassn(padapter, pdrvinfo);
					ptr += 4;
				}

#ifdef CONFIG_CONCURRENT_MODE
				if(rtw_buddy_adapter_up(padapter))
				{
					if(pre_recv_entry(precvframe, precvbuf, (struct phy_stat*)ptr) != _SUCCESS)
					{
						RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
							("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
					}
				}
				else
#endif
				{
					if (pattrib->physt)
						update_recvframe_phyinfo(precvframe, (struct phy_stat*)ptr);

					if (rtw_recv_entry(precvframe) != _SUCCESS)
					{
						RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("rtl8723as_recv_tasklet: rtw_recv_entry(precvframe) != _SUCCESS\n"));
					}
				}
			}

			// Page size of receive package is 128 bytes alignment => DMA agg
			// refer to _InitTransferPageSize()
			pkt_offset = _RND128(pkt_offset);
			precvbuf->pdata += pkt_offset;
			ptr = precvbuf->pdata;
		}

		rtw_skb_free(precvbuf->pskb);
		precvbuf->pskb = NULL;
		rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
	} while (1);
}
Example #14
0
static void rtl8723as_recv_tasklet(void *priv)
{
	PADAPTER			padapter;
	PHAL_DATA_TYPE		pHalData;
	struct recv_priv		*precvpriv;
	struct recv_buf		*precvbuf;
	union recv_frame		*precvframe;
	struct recv_frame_hdr	*phdr;
	struct rx_pkt_attrib	*pattrib;
	_irqL	irql;
	u8		*ptr;
	u32		pkt_len, pkt_offset, skb_len, alloc_sz;
	_pkt		*pkt_copy = NULL;
	u8		shift_sz = 0, rx_report_sz = 0;


	padapter = (PADAPTER)priv;
	pHalData = GET_HAL_DATA(padapter);
	precvpriv = &padapter->recvpriv;
	
	do {
		precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
		if (NULL == precvbuf) break;

		ptr = precvbuf->pdata;

		while (ptr < precvbuf->ptail)
		{
			precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
			if (precvframe == NULL) {
				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("%s: no enough recv frame!\n",__FUNCTION__));
				rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);

				// The case of can't allocte recvframe should be temporary,
				// schedule again and hope recvframe is available next time.
#ifdef PLATFORM_LINUX
				tasklet_schedule(&precvpriv->recv_tasklet);
#endif
				return;
			}

			//rx desc parsing
			update_recvframe_attrib(precvframe, (struct recv_stat*)ptr);

			pattrib = &precvframe->u.hdr.attrib;

			// fix Hardware RX data error, drop whole recv_buffer
			if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
			{
				if (padapter->registrypriv.mp_mode == 1)
					padapter->mppriv.rx_crcerrpktcount++;
				else
					DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);

				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
				break;
			}

			if (pHalData->ReceiveConfig & RCR_APP_BA_SSN)
				rx_report_sz = RXDESC_SIZE + 4 + pattrib->drvinfo_sz;
			else
				rx_report_sz = RXDESC_SIZE + pattrib->drvinfo_sz;

			pkt_offset = rx_report_sz + pattrib->pkt_len;

			if ((ptr + pkt_offset) > precvbuf->ptail) {
				DBG_8192C("%s()-%d: : next pkt len(%p,%d) exceed ptail(%p)!\n", __FUNCTION__, __LINE__, ptr, pkt_offset, precvbuf->ptail);
				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
				break;
			}

			if ((pattrib->crc_err) || (pattrib->icv_err))
			{
				if (padapter->registrypriv.mp_mode == 0)
				DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
			}
			else
			{
				//	Modified by Albert 20101213
				//	For 8 bytes IP header alignment.
				if (pattrib->qos)	//	Qos data, wireless lan header length is 26
				{
					shift_sz = 6;
				}
				else
				{
					shift_sz = 0;
				}

				skb_len = pattrib->pkt_len;

				// for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
				// modify alloc_sz for recvive crc error packet by thomas 2011-06-02
				if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
					//alloc_sz = 1664;	//1664 is 128 alignment.
					if(skb_len <= 1650)
						alloc_sz = 1664;
					else
						alloc_sz = skb_len + 14;
				}
				else {
					alloc_sz = skb_len;
					//	6 is for IP header 8 bytes alignment in QoS packet case.
					//	8 is for skb->data 4 bytes alignment.
					alloc_sz += 14;
				}

				pkt_copy = rtw_skb_alloc(alloc_sz);

				if(pkt_copy)
				{
					pkt_copy->dev = padapter->pnetdev;
					precvframe->u.hdr.pkt = pkt_copy;
					skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
					skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
					_rtw_memcpy(pkt_copy->data, (ptr + rx_report_sz), skb_len);
					precvframe->u.hdr.rx_head = pkt_copy->head;
					precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
					precvframe->u.hdr.rx_end = skb_end_pointer(pkt_copy);
				}
				else
				{
					if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
					{				
						DBG_8192C("rtl8723as_recv_tasklet: alloc_skb fail , drop frag frame \n");
						rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
						break;
					}
					
					precvframe->u.hdr.pkt = rtw_skb_clone(precvbuf->pskb);
					if(precvframe->u.hdr.pkt)
					{
						_pkt	*pkt_clone = precvframe->u.hdr.pkt;

						pkt_clone->data = ptr + rx_report_sz;
						skb_reset_tail_pointer(pkt_clone);
						precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail 
							= pkt_clone->data;
						precvframe->u.hdr.rx_end =  pkt_clone->data + skb_len;
					}
					else
					{
						DBG_8192C("rtl8723as_recv_tasklet: rtw_skb_clone fail\n");
						rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
						break;
					}
				}

				recvframe_put(precvframe, skb_len);
				//recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);

				if (pHalData->ReceiveConfig & RCR_APPFCS)
					recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);

				// move to drv info position
				ptr += RXDESC_SIZE;

				// update drv info
				if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
					//rtl8723s_update_bassn(padapter, pdrvinfo);
					ptr += 4;
				}

#ifdef CONFIG_CONCURRENT_MODE
				if(rtw_buddy_adapter_up(padapter))
				{
					if(pre_recv_entry(precvframe, precvbuf, (struct phy_stat*)ptr) != _SUCCESS)
					{
						RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
							("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
					}
				}
				else
#endif
				{
					if (pattrib->physt)
						update_recvframe_phyinfo(precvframe, (struct phy_stat*)ptr);

					if (rtw_recv_entry(precvframe) != _SUCCESS)
					{
						RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",__FUNCTION__));
					}
				}
			}

			// Page size of receive package is 128 bytes alignment =>DMA AGG
			// refer to _InitTransferPageSize()
			pkt_offset = _RND128(pkt_offset);
			precvbuf->pdata += pkt_offset;
			ptr = precvbuf->pdata;
			precvframe = NULL;
			pkt_copy = NULL;
		}

		rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
	} while (1);

}
int hostapd_mode_init(_adapter *padapter)
{
	unsigned char mac[ETH_ALEN];
	struct hostapd_priv *phostapdpriv;
	struct net_device *pnetdev;
	
	pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv));	
	if (!pnetdev)
	   return -ENOMEM;

	//SET_MODULE_OWNER(pnetdev);
       ether_setup(pnetdev);

	//pnetdev->type = ARPHRD_IEEE80211;
	
	phostapdpriv = rtw_netdev_priv(pnetdev);
	phostapdpriv->pmgnt_netdev = pnetdev;
	phostapdpriv->padapter= padapter;
	padapter->phostapdpriv = phostapdpriv;
	
	//pnetdev->init = NULL;
	
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))

	DBG_8192C("register rtl871x_mgnt_netdev_ops to netdev_ops\n");

	pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops;
	
#else

	pnetdev->open = mgnt_netdev_open;

	pnetdev->stop = mgnt_netdev_close;	
	
	pnetdev->hard_start_xmit = mgnt_xmit_entry;
	
	//pnetdev->set_mac_address = r871x_net_set_mac_address;
	
	//pnetdev->get_stats = r871x_net_get_stats;

	//pnetdev->do_ioctl = r871x_mp_ioctl;
	
#endif

	pnetdev->watchdog_timeo = HZ; /* 1 second timeout */	

	//pnetdev->wireless_handlers = NULL;

#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
	pnetdev->features |= NETIF_F_IP_CSUM;
#endif	

	
	
	if(dev_alloc_name(pnetdev,"mgnt.wlan%d") < 0)
	{
		DBG_8192C("hostapd_mode_init(): dev_alloc_name, fail! \n");		
	}


	//SET_NETDEV_DEV(pnetdev, pintfpriv->udev);


	mac[0]=0x00;
	mac[1]=0xe0;
	mac[2]=0x4c;
	mac[3]=0x87;
	mac[4]=0x11;
	mac[5]=0x12;
				
	_rtw_memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
	

	netif_carrier_off(pnetdev);


	/* Tell the network stack we exist */
	if (register_netdev(pnetdev) != 0)
	{
		DBG_8192C("hostapd_mode_init(): register_netdev fail!\n");
		
		if(pnetdev)
      		{	 
			rtw_free_netdev(pnetdev);
      		}
	}
	
	return 0;
	
}
//
// Description: Leave all power save mode: LPS, FwLPS, IPS if needed.
// Move code to function by tynli. 2010.03.26. 
//
void LeaveAllPowerSaveMode(IN PADAPTER Adapter)
{
	struct mlme_priv	*pmlmepriv = &(Adapter->mlmepriv);
	u32 LPSLeaveTimeOut = 10000;
	//u32 IPSLeaveTimeOut = 10000;

_func_enter_;

	DBG_8192C("%s.....\n",__FUNCTION__);
	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
	{ //connect
#ifdef CONFIG_P2P
		p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, 0);
#endif
#ifdef CONFIG_LPS
		//DBG_8192C("==> leave LPS.......\n");
		LPS_Leave(Adapter);

		if (Adapter->pwrctrlpriv.bLeisurePs)
		{
			BOOLEAN bAwake = _TRUE;
			Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bAwake));
			while(!bAwake)
			{
				rtw_usleep_os(100);
				LPSLeaveTimeOut--;
				if(LPSLeaveTimeOut <= 0)
				{
					DBG_8192C("Wait for FW LPS leave too long!!! LPSLeaveTimeOut  = %d\n", LPSLeaveTimeOut );
					break;
				}
				Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bAwake));
			}
		}
#endif
	}
	else
	{
		if(Adapter->pwrctrlpriv.current_rfpwrstate== rf_off)
		{
			DBG_8192C("==> leave IPS.......\n");
			#ifdef CONFIG_AUTOSUSPEND
			if(Adapter->registrypriv.usbss_enable)
			{
				#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
				usb_disable_autosuspend(Adapter->dvobjpriv.pusbdev);
				#elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,34))
				Adapter->dvobjpriv.pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;//autosuspend disabled by the user
				#endif
			}
			else
			#endif
			{
				#ifdef CONFIG_IPS
				if(_FALSE == ips_leave(Adapter))
				{
					DBG_8192C("======> ips_leave fail.............\n");			
				}
				#endif
			}				
		}	
	}

_func_exit_;
}
Example #17
0
static s32 update_txdesc(struct xmit_frame *pxmitframe, u32 *pmem, s32 sz)
{
    uint	qsel;
    _adapter				*padapter = pxmitframe->padapter;
    HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(padapter);
    struct dm_priv		*pdmpriv = &pHalData->dmpriv;
    struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
    struct dvobj_priv		*pdvobjpriv = adapter_to_dvobj(padapter);
    struct pkt_attrib		*pattrib = &pxmitframe->attrib;
    struct ht_priv			*phtpriv = &pmlmepriv->htpriv;
    struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
    struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
    struct tx_desc		*ptxdesc = (struct tx_desc *)pmem;
    sint	bmcst = IS_MCAST(pattrib->ra);

    dma_addr_t	mapping = pci_map_single(pdvobjpriv->ppcidev, pxmitframe->buf_addr , sz, PCI_DMA_TODEVICE);

    _rtw_memset(ptxdesc, 0, TX_DESC_NEXT_DESC_OFFSET);

    if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
    {
        //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");

        //offset 4
        ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id)&0x1f);

        qsel = (uint)(pattrib->qsel & 0x0000001f);
        ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);

        ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);

        fill_txdesc_sectype(pattrib, ptxdesc);

        if(pattrib->ampdu_en==_TRUE)
            ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN
        else
            ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK

        //offset 8


        //offset 12
        ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);


        //offset 16 , offset 20
        if (pattrib->qos_en)
            ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS

        if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1))
        {
            //Non EAP & ARP & DHCP type data packet

            fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
            fill_txdesc_phy(pattrib, &ptxdesc->txdw4);

            ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M
            ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);//
            //ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M

            //use REG_INIDATA_RATE_SEL value
            ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]);

            if(0)//for driver dbg
            {
                ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate

                if(pattrib->ht_en)
                    ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI

                ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7
            }
        }
        else
        {
            // EAP data packet and ARP packet.
            // Use the 1M data rate to send the EAP/ARP packet.
            // This will maybe make the handshake smooth.

            ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK

            ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate

            if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
                ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT

            ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
        }

        //offset 24

#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
        if ( pattrib->hw_tcp_csum == 1 ) {
            // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!!
            u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8;
            ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16);
            DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7);
        }
#endif
    }
    else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
    {
        //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");

        //offset 4
        ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id)&0x1f);

        qsel = (uint)(pattrib->qsel&0x0000001f);
        ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00);

        ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);

        //fill_txdesc_sectype(pattrib, ptxdesc);

        //offset 8

        //offset 12
        ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);

        //offset 16
        ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate

        //offset 20
#ifdef CONFIG_AP_MODE
        ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable
        ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6
#endif

#ifdef CONFIG_INTEL_PROXIM
        if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)) {
            printk("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
            ptxdesc->txdw5 |= cpu_to_le32( pattrib->rate);
        }
        else
#endif
        {
            ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
        }
    }
    else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
    {
        DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
    }
#ifdef CONFIG_MP_INCLUDED
    else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG)
    {
        fill_txdesc_for_mp(padapter, ptxdesc);
    }
#endif
    else
    {
        DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);

        //offset 4
        ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID)

        ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid

        //offset 8

        //offset 12
        ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);

        //offset 16
        ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate

        //offset 20
        ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
    }

    //offset 28
    ptxdesc->txdw7 |= cpu_to_le32(sz&0x0000ffff);

    //offset 32
    ptxdesc->txdw8 = cpu_to_le32(mapping);

    // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
    // (1) The sequence number of each non-Qos frame / broadcast / multicast /
    // mgnt frame should be controled by Hw because Fw will also send null data
    // which we cannot control when Fw LPS enable.
    // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
    // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
    // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
    // 2010.06.23. Added by tynli.
    if(!pattrib->qos_en)
    {
        ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
        ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
    }

    //offset 0
    if(bmcst)
    {
        ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
    }
    ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff);
    ptxdesc->txdw0 |= cpu_to_le32(FSG | LSG);
    ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//32 bytes for TX Desc
    ptxdesc->txdw0 |= cpu_to_le32(OWN);
    RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0));

    return 0;

}
/*
 * Description:
 *	Aggregation packets and send to hardware
 *
 * Return:
 *	0	Success
 *	-1	Hardware resource(TX FIFO) not ready
 *	-2	Software resource(xmitbuf) not ready
 */
static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv)
{
	s32 err, ret;
	u32 k;
	struct hw_xmit *hwxmits;
	u8 no_res, idx, hwentry;
	_irqL irql;
//	_irqL irqL0, irqL1;
	struct tx_servq *ptxservq;
	_list *sta_plist, *sta_phead, *frame_plist, *frame_phead;
	struct xmit_frame *pxmitframe;
	_queue *pframe_queue;
	struct xmit_buf *pxmitbuf;
	u32 txlen;


	err = 0;
	no_res = _FALSE;
	hwxmits = pxmitpriv->hwxmits;
	hwentry = pxmitpriv->hwxmit_entry;
	ptxservq = NULL;
	pxmitframe = NULL;
	pframe_queue = NULL;
	pxmitbuf = NULL;

	// 0(VO), 1(VI), 2(BE), 3(BK)
	for (idx = 0; idx < hwentry; idx++, hwxmits++)
	{
//		_enter_critical(&hwxmits->sta_queue->lock, &irqL0);

		sta_phead = get_list_head(hwxmits->sta_queue);
		sta_plist = get_next(sta_phead);

		while (rtw_end_of_queue_search(sta_phead, sta_plist) == _FALSE)
		{
			ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
			sta_plist = get_next(sta_plist);

			pframe_queue = &ptxservq->sta_pending;

//			_enter_critical(&pframe_queue->lock, &irqL1);
			_enter_critical_bh(&pxmitpriv->lock, &irql);

			frame_phead = get_list_head(pframe_queue);

			while (rtw_is_list_empty(frame_phead) == _FALSE)
			{
				frame_plist = get_next(frame_phead);
				pxmitframe = LIST_CONTAINOR(frame_plist, struct xmit_frame, list);

				// check xmit_buf size enough or not
				txlen = TXDESC_SIZE + rtw_wlan_pkt_size(pxmitframe);
				if ((NULL == pxmitbuf) ||
					((pxmitbuf->ptail + txlen) > pxmitbuf->pend)
#ifdef SDIO_TX_AGG_MAX
					|| (k >= SDIO_TX_AGG_MAX)
#endif
					)
				{
					if (pxmitbuf) {
						struct xmit_frame *pframe;
						pframe = (struct xmit_frame*)pxmitbuf->priv_data;
						pframe->agg_num = k;
						pxmitbuf->agg_num = k;
						rtl8723a_update_txdesc(pframe, pframe->buf_addr);
						rtw_free_xmitframe(pxmitpriv, pframe);
						pxmitbuf->priv_data = NULL;
						enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
						//rtw_yield_os();
					}

					pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
					if (pxmitbuf == NULL) {
						RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: xmit_buf is not enough!\n", __FUNCTION__));
						err = -2;
						break;
					}
					k = 0;
				}

				// ok to send, remove frame from queue
				//_enter_critical_bh(&pxmitpriv->lock, &irql);
#ifdef CONFIG_AP_MODE
				if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
				{
					if ((pxmitframe->attrib.psta->state & WIFI_SLEEP_STATE) &&
						(pxmitframe->attrib.triggered == 0))
					{
						//_exit_critical_bh(&pxmitpriv->lock, &irql);
						
						DBG_8192C("%s: one not triggered pkt in queue when STA sleep\n", __func__);
						break;
					}
				}
#endif
				rtw_list_delete(&pxmitframe->list);
				ptxservq->qcnt--;
				hwxmits->accnt--;
				

				if (k == 0) {
					pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
					pxmitbuf->priv_data = (u8*)pxmitframe;
				}

				// coalesce the xmitframe to xmitbuf
				pxmitframe->pxmitbuf = pxmitbuf;
				pxmitframe->buf_addr = pxmitbuf->ptail;

				ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
				if (ret == _FAIL) {
					RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: coalesce FAIL!", __FUNCTION__));
					// Todo: error handler
				} else {
					k++;
					if (k != 1)
						rtl8723a_update_txdesc(pxmitframe, pxmitframe->buf_addr);
					rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz);

					txlen = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
					pxmitframe->pg_num = (txlen + 127)/128;
					pxmitbuf->pg_num += (txlen + 127)/128;					
					//if (k != 1)
					//	((struct xmit_frame*)pxmitbuf->priv_data)->pg_num += pxmitframe->pg_num;
					pxmitbuf->ptail += _RND(txlen, 8); // round to 8 bytes alignment
					pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen;
				}

				if (k != 1)
					rtw_free_xmitframe(pxmitpriv, pxmitframe);
				pxmitframe = NULL;
			}

			//_enter_critical_bh(&pxmitpriv->lock, &irql);
			if (_rtw_queue_empty(pframe_queue) == _TRUE)
				rtw_list_delete(&ptxservq->tx_pending);
			//_exit_critical_bh(&pxmitpriv->lock, &irql);

//			_exit_critical(&pframe_queue->lock, &irqL1);
			_exit_critical_bh(&pxmitpriv->lock, &irql);

			if (err) break;
		}

//		_exit_critical(&hwxmits->sta_queue->lock, &irqL0);

		// dump xmit_buf to hw tx fifo
		if (pxmitbuf)
		{
			RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("pxmitbuf->len=%d enqueue\n",pxmitbuf->len));

			if (pxmitbuf->len > 0) {
				struct xmit_frame *pframe;
				pframe = (struct xmit_frame*)pxmitbuf->priv_data;
				pframe->agg_num = k;
				pxmitbuf->agg_num = k;
				rtl8723a_update_txdesc(pframe, pframe->buf_addr);
				rtw_free_xmitframe(pxmitpriv, pframe);
				pxmitbuf->priv_data = NULL;
				enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
				rtw_yield_os();
			}
			else
				rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
			
			pxmitbuf = NULL;
		}

		if (err) break;
	}

	return err;
}
Example #19
0
void rtl8192de_xmitframe_resume(_adapter *padapter)
{
    struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
    struct xmit_frame *pxmitframe = NULL;
    struct xmit_buf	*pxmitbuf = NULL;
    int res=_SUCCESS, xcnt = 0;

    RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtl8192ce_xmitframe_resume()\n"));

    while(1)
    {
        if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
        {
            DBG_8192C("rtl8192ce_xmitframe_resume => bDriverStopped or bSurpriseRemoved \n");
            break;
        }

        pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
        if(!pxmitbuf)
        {
            break;
        }

        pxmitframe =  rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);

        if(pxmitframe)
        {
            pxmitframe->pxmitbuf = pxmitbuf;

            pxmitframe->buf_addr = pxmitbuf->pbuf;

            pxmitbuf->priv_data = pxmitframe;

            if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
            {
                if(pxmitframe->attrib.priority<=15)//TID0~15
                {
                    res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
                }

                rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
            }

            RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtl8192ce_xmitframe_resume(): rtw_dump_xframe\n"));

            if(res == _SUCCESS)
            {
                rtw_dump_xframe(padapter, pxmitframe);
            }
            else
            {
                rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
                rtw_free_xmitframe(pxmitpriv, pxmitframe);
            }

            xcnt++;
        }
        else
        {
            rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
            break;
        }
    }
}
s32 rtl8723_dequeue_writeport(PADAPTER padapter, u8 *freePage)
{
	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
	struct xmit_buf *pxmitbuf;
	//struct xmit_frame *pframe;
	PADAPTER pri_padapter = padapter;
	u32 deviceId;
	u32 requiredPage;
	u8 PageIdx;
	_irqL irql;
	u32 n;
	s32 ret = 0;
	//HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
#ifdef CONFIG_CONCURRENT_MODE
	s32 buddy_rm_stop = _FAIL;
#endif

#ifdef CONFIG_CONCURRENT_MODE
	if(rtw_buddy_adapter_up(padapter))
		ret = check_buddy_fwstate( padapter,  _FW_UNDER_SURVEY);
#endif

	ret = ret || check_fwstate(pmlmepriv, _FW_UNDER_SURVEY);

	if (_TRUE == ret)
		pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
	else
		pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);

	if (pxmitbuf == NULL) 
		return _TRUE;

	//pframe = (struct xmit_frame*)pxmitbuf->priv_data;
	//requiredPage = pframe->pg_num;
	requiredPage = pxmitbuf->pg_num;

	//translate queue index to sdio fifo addr
	deviceId = pdvobjpriv->Queue2Pipe[pxmitbuf->ff_hwaddr];

	// translate sdio fifo addr to tx fifo page index
	switch (deviceId)
	{
		case WLAN_TX_HIQ_DEVICE_ID:
				PageIdx = HI_QUEUE_IDX;
				break;

		case WLAN_TX_MIQ_DEVICE_ID:
				PageIdx = MID_QUEUE_IDX;
				break;

		case WLAN_TX_LOQ_DEVICE_ID:
				PageIdx = LOW_QUEUE_IDX;
				break;
	}

	// check if hardware tx fifo page is enough
	n = 0;
//	_enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
	do {
		if (requiredPage <= freePage[PageIdx]) {
			freePage[PageIdx] -= requiredPage;
			break;
		}
		// The number of page which public page included is available.
		if ((freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]) > (requiredPage + 1))
		{
			u8 requiredPublicPage;

			requiredPublicPage = requiredPage - freePage[PageIdx];
			freePage[PageIdx] = 0;
			freePage[PUBLIC_QUEUE_IDX] -= requiredPublicPage;
			break;
		}
//		_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);

		ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
		if (ret) {
			RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: bSurpriseRemoved(update TX FIFO page)\n", __func__));
			goto free_xmitbuf;
		}

		n++;
		//if ((n & 0x3FF) == 0) 
		if ((n % 2) == 0) 
		{		
			if (n > 5000) {
				DBG_8192C(KERN_NOTICE "%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
					__func__, n, pxmitbuf->len, pxmitbuf->agg_num, pxmitbuf->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]);
			} else {
				//RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				//	("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
				//	__FUNCTION__, n, pxmitbuf->len, pxmitbuf->agg_num, pxmitbuf->pg_num, freePage[PageIdx] + freePage[UBLIC_QUEUE_IDX]));
			}
			//rtw_yield_os();
			rtw_msleep_os(1);
		}

		// Total number of page is NOT available, so update current FIFO status
#ifdef CONFIG_CONCURRENT_MODE
		if (padapter->adapter_type > 0)
			pri_padapter = padapter->pbuddy_adapter;
#endif
		HalQueryTxBufferStatus8723ASdio(pri_padapter);

	} while (1);

	if ((padapter->bSurpriseRemoved == _TRUE)
#ifdef CONFIG_CONCURRENT_MODE
		||((padapter->pbuddy_adapter)&& (padapter->pbuddy_adapter->bSurpriseRemoved))
#endif
	){
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
			 ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__));
		goto free_xmitbuf;
	}
	rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf);

free_xmitbuf:
	//rtw_free_xmitframe(pxmitpriv, pframe);
	//pxmitbuf->priv_data = NULL;
	rtw_free_xmitbuf(pxmitpriv, pxmitbuf);

	return _FAIL;
}
Example #21
0
static s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status)
{	
	s32 ret=_SUCCESS;
#ifdef CONFIG_CONCURRENT_MODE	
	u8 *secondary_myid, *paddr1;
	union recv_frame	*precvframe_if2 = NULL;
	_adapter *primary_padapter = precvframe->u.hdr.adapter;
	_adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
	struct recv_priv *precvpriv = &primary_padapter->recvpriv;
	_queue *pfree_recv_queue = &precvpriv->free_recv_queue;
	u8	*pbuf = precvframe->u.hdr.rx_data;
	
	if(!secondary_padapter)
		return ret;
	
	paddr1 = GetAddr1Ptr(pbuf);

	if(IS_MCAST(paddr1) == _FALSE)//unicast packets
	{
		secondary_myid = adapter_mac_addr(secondary_padapter);

		if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN))
		{			
			//change to secondary interface
			precvframe->u.hdr.adapter = secondary_padapter;
		}	

		//ret = recv_entry(precvframe);

	}
	else // Handle BC/MC Packets	
	{
		
		u8 clone = _TRUE;
#if 0
		u8 type, subtype, *paddr2, *paddr3;
	
		type =  GetFrameType(pbuf);
		subtype = GetFrameSubType(pbuf); //bit(7)~bit(2)
		
		switch (type)
		{
			case WIFI_MGT_TYPE: //Handle BC/MC mgnt Packets
				if(subtype == WIFI_BEACON)
				{
					paddr3 = GetAddr3Ptr(precvframe->u.hdr.rx_data);
				
					if (check_fwstate(&secondary_padapter->mlmepriv, _FW_LINKED) &&
						_rtw_memcmp(paddr3, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN))
					{
						//change to secondary interface
						precvframe->u.hdr.adapter = secondary_padapter;
						clone = _FALSE;
					}

					if(check_fwstate(&primary_padapter->mlmepriv, _FW_LINKED) &&
						_rtw_memcmp(paddr3, get_bssid(&primary_padapter->mlmepriv), ETH_ALEN))
					{
						if(clone==_FALSE)
						{
							clone = _TRUE;									
						}	
						else
						{
							clone = _FALSE;
						}

						precvframe->u.hdr.adapter = primary_padapter;	
					}

					if(check_fwstate(&primary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) ||
						check_fwstate(&secondary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING))
					{
						clone = _TRUE;
						precvframe->u.hdr.adapter = primary_padapter;	
					}
				
				}
				else if(subtype == WIFI_PROBEREQ)
				{
					//probe req frame is only for interface2
					//change to secondary interface
					precvframe->u.hdr.adapter = secondary_padapter;
					clone = _FALSE;
				}			
				break;
			case WIFI_CTRL_TYPE: // Handle BC/MC ctrl Packets
			
				break;
			case WIFI_DATA_TYPE: //Handle BC/MC data Packets
					//Notes: AP MODE never rx BC/MC data packets
			
				paddr2 = GetAddr2Ptr(precvframe->u.hdr.rx_data);

				if(_rtw_memcmp(paddr2, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN))
				{
					//change to secondary interface
					precvframe->u.hdr.adapter = secondary_padapter;
					clone = _FALSE;
				}

				break;
			default:
			
				break;			
		}
#endif

		if(_TRUE == clone)
		{
			//clone/copy to if2		
			struct rx_pkt_attrib *pattrib = NULL;
		
			precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);
			if(precvframe_if2)
			{
				precvframe_if2->u.hdr.adapter = secondary_padapter;
		
				_rtw_init_listhead(&precvframe_if2->u.hdr.list);	
				precvframe_if2->u.hdr.precvbuf = NULL;	//can't access the precvbuf for new arch.
				precvframe_if2->u.hdr.len=0;

				_rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));

				pattrib = &precvframe_if2->u.hdr.attrib;

				if(rtw_os_alloc_recvframe(secondary_padapter, precvframe_if2, pbuf, NULL) == _SUCCESS)				
				{						
					recvframe_put(precvframe_if2, pattrib->pkt_len);
					//recvframe_pull(precvframe_if2, drvinfo_sz + RXDESC_SIZE);

					if (pattrib->physt && pphy_status)
						rx_query_phy_status(precvframe_if2, pphy_status);
	
					ret = rtw_recv_entry(precvframe_if2);				
				}	
				else
				{
					rtw_free_recvframe(precvframe_if2, pfree_recv_queue);
					DBG_8192C("%s()-%d: alloc_skb() failed!\n", __FUNCTION__, __LINE__);	
				}

			}
			
		}
		
	}
	//if (precvframe->u.hdr.attrib.physt)
	//	rx_query_phy_status(precvframe, pphy_status);
	
	//ret = rtw_recv_entry(precvframe);

#endif

	return ret;

}
Example #22
0
static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz ,u8 bagg_pkt)
{	
      int	pull=0;
	uint	qsel;
	u8 data_rate,pwr_status,offset;
	_adapter			*padapter = pxmitframe->padapter;
	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;		
	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
	//struct dm_priv	*pdmpriv = &pHalData->dmpriv;
	u8	*ptxdesc =  pmem;
	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
	sint	bmcst = IS_MCAST(pattrib->ra);
	
#ifdef CONFIG_P2P
	struct wifidirect_info*	pwdinfo = &padapter->wdinfo;
#endif //CONFIG_P2P


#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX 
	if (padapter->registrypriv.mp_mode == 0)
	{
		//if((!bagg_pkt) &&(urb_zero_packet_chk(padapter, sz)==0))//(sz %512) != 0
		if((!bagg_pkt) &&(rtw_usb_bulk_size_boundary(padapter,TXDESC_SIZE+sz)==_FALSE))	
		{
			ptxdesc = (pmem+PACKET_OFFSET_SZ);
			//DBG_8192C("==> non-agg-pkt,shift pointer...\n");
			pull = 1;
		}
	}
#endif	// CONFIG_USE_USB_BUFFER_ALLOC_TX

	_rtw_memset(ptxdesc, 0, TXDESC_SIZE);
	
        //4 offset 0
		
	//DBG_8192C("%s==> pkt_len=%d,bagg_pkt=%02x\n",__FUNCTION__,sz,bagg_pkt);
	SET_TX_DESC_PKT_SIZE_92E(ptxdesc, sz);
	
	offset = TXDESC_SIZE + OFFSET_SZ;		

#ifdef CONFIG_TX_EARLY_MODE	
	if(bagg_pkt){		
		offset += EARLY_MODE_INFO_SIZE ;//0x28			
	}
#endif
	//DBG_8192C("%s==>offset(0x%02x)  \n",__FUNCTION__,offset);
	SET_TX_DESC_OFFSET_92E(ptxdesc, offset);

	if (bmcst) {
		SET_TX_DESC_BMC_92E(ptxdesc, 1);
	}

#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
	if (padapter->registrypriv.mp_mode == 0)
	{
		if(!bagg_pkt){
			if((pull) && (pxmitframe->pkt_offset>0)) {	
				pxmitframe->pkt_offset = pxmitframe->pkt_offset -1;		
			}
		}
	}	
#endif

	//DBG_8192C("%s, pkt_offset=0x%02x\n",__FUNCTION__,pxmitframe->pkt_offset);
	// pkt_offset, unit:8 bytes padding
	if (pxmitframe->pkt_offset > 0) {
		SET_TX_DESC_PKT_OFFSET_92E(ptxdesc, pxmitframe->pkt_offset);
	}

	SET_TX_DESC_MACID_92E(ptxdesc, pattrib->mac_id);
	SET_TX_DESC_RATE_ID_92E(ptxdesc, pattrib->raid);

	SET_TX_DESC_QUEUE_SEL_92E(ptxdesc,  pattrib->qsel);

	//offset 12

	if (!pattrib->qos_en) {
		SET_TX_DESC_EN_HWSEQ_92E(ptxdesc, 1); // Hw set sequence number
	} else {
		SET_TX_DESC_SEQ_92E(ptxdesc, pattrib->seqnum);
	}

	if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
	{
		//DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");		

		fill_txdesc_sectype(pattrib, ptxdesc);

		if (pattrib->ampdu_en==_TRUE) {
			SET_TX_DESC_AGG_ENABLE_92E(ptxdesc, 1);
			SET_TX_DESC_MAX_AGG_NUM_92E(ptxdesc, 0x1f);
			// Set A-MPDU aggregation.
			SET_TX_DESC_AMPDU_DENSITY_92E(ptxdesc, pHalData->AMPDUDensity);
		} else {
			SET_TX_DESC_BK_92E(ptxdesc, 1);
		}

		//offset 20
#ifdef CONFIG_USB_TX_AGGREGATION
		if (pxmitframe->agg_num > 1){
			//DBG_8192C("%s agg_num:%d\n",__FUNCTION__,pxmitframe->agg_num );
			SET_TX_DESC_USB_TXAGG_NUM_92E(ptxdesc, pxmitframe->agg_num);
		}
#endif

		if ((pattrib->ether_type != 0x888e) &&
		    (pattrib->ether_type != 0x0806) &&
		    (pattrib->ether_type != 0x88b4) &&
		    (pattrib->dhcp_pkt != 1)
#ifdef CONFIG_AUTO_AP_MODE
		    && (pattrib->pctrl != _TRUE)
#endif
		    )
		{
			//Non EAP & ARP & DHCP type data packet
              	
			fill_txdesc_vcs(pattrib, ptxdesc);
			fill_txdesc_phy(padapter, pattrib, ptxdesc);

			SET_TX_DESC_RTS_RATE_92E(ptxdesc, 0x8);//RTS Rate=24M
			//DATA/RTS  Rate FB LMT
			SET_TX_DESC_DATA_RATE_FB_LIMIT_92E(ptxdesc, 0x1f);
			SET_TX_DESC_RTS_RATE_FB_LIMIT_92E(ptxdesc, 0xf);
			
			if(pHalData->fw_ractrl == _FALSE)  {
				struct dm_priv	*pdmpriv = &pHalData->dmpriv;
				SET_TX_DESC_USE_RATE_92E(ptxdesc, 1);
				
				if(pdmpriv->INIDATA_RATE[pattrib->mac_id] & BIT(7))
					SET_TX_DESC_DATA_SHORT_92E(ptxdesc, 1);

				SET_TX_DESC_TX_RATE_92E(ptxdesc, (pdmpriv->INIDATA_RATE[pattrib->mac_id] & 0x7F));
			}

			//for debug
               	#if 1
			if(padapter->fix_rate!= 0xFF){
				struct dm_priv	*pdmpriv = &pHalData->dmpriv;
				SET_TX_DESC_USE_RATE_92E(ptxdesc, 1);
				if(pdmpriv->INIDATA_RATE[pattrib->mac_id] & BIT(7))
                 		{
					if(padapter->fix_rate & BIT(7))
						SET_TX_DESC_DATA_SHORT_92E(ptxdesc, 1);
				}
				SET_TX_DESC_TX_RATE_92E(ptxdesc, (padapter->fix_rate & 0x7F));
				
				//ptxdesc->datarate = padapter->fix_rate;
			}
			#endif
				
		}
		else
		{
			// EAP data packet and ARP packet and DHCP.
			// Use the 1M data rate to send the EAP/ARP packet.
			// This will maybe make the handshake smooth.

			SET_TX_DESC_USE_RATE_92E(ptxdesc, 1);

			SET_TX_DESC_BK_92E(ptxdesc, 1);

			// HW will ignore this setting if the transmission rate is legacy OFDM.
			if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) {
				SET_TX_DESC_DATA_SHORT_92E(ptxdesc, 1);
			}

			SET_TX_DESC_TX_RATE_92E(ptxdesc, MRateToHwRate(pmlmeext->tx_rate));
		}
	}
	else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
	{
		//DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");	

		SET_TX_DESC_MBSSID_92E(ptxdesc, pattrib->mbssid);//for issue port1/mbssid beacon

		//offset 20
		SET_TX_DESC_RETRY_LIMIT_ENABLE_92E(ptxdesc, 1);
		if (pattrib->retry_ctrl == _TRUE) {
			SET_TX_DESC_DATA_RETRY_LIMIT_92E(ptxdesc, 6);
		} else {
			SET_TX_DESC_DATA_RETRY_LIMIT_92E(ptxdesc, 12);
		}

		SET_TX_DESC_USE_RATE_92E(ptxdesc, 1);

#ifdef CONFIG_INTEL_PROXIM
		if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
			DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
			SET_TX_DESC_TX_RATE_92E(ptxdesc, pattrib->rate);
		}
		else
#endif
		{
			SET_TX_DESC_TX_RATE_92E(ptxdesc, MRateToHwRate(pmlmeext->tx_rate));
		}
	}
	else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
	{
		DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
	}
#ifdef CONFIG_MP_INCLUDED
	else if(((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) &&
		(padapter->registrypriv.mp_mode == 1))
	{
		fill_txdesc_for_mp(padapter, (struct tx_desc *)ptxdesc);
	}
#endif
	else
	{
		DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);

		SET_TX_DESC_USE_RATE_92E(ptxdesc, 1);
		SET_TX_DESC_TX_RATE_92E(ptxdesc, MRateToHwRate(pmlmeext->tx_rate));
	}

	rtl8192e_cal_txdesc_chksum(ptxdesc);
	_dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc);	
	return pull;
}
Example #23
0
int recvbuf2recvframe(PADAPTER padapter, void *ptr)
{
	u8	*pbuf;
	u8	pkt_cnt = 0;
	u32	pkt_offset;
	s32	transfer_len;
	u8				*pphy_status = NULL;	
	union recv_frame	*precvframe = NULL;
	struct rx_pkt_attrib	*pattrib = NULL;
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
	struct recv_priv	*precvpriv = &padapter->recvpriv;
	_queue			*pfree_recv_queue = &precvpriv->free_recv_queue;
	_pkt *pskb;

#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
	pskb = NULL;
	transfer_len = (s32)((struct recv_buf*)ptr)->transfer_len;
	pbuf = ((struct recv_buf*)ptr)->pbuf;
#else
	pskb = (_pkt*)ptr;
	transfer_len = (s32)pskb->len;
	pbuf = pskb->data;
#endif//CONFIG_USE_USB_BUFFER_ALLOC_RX


#ifdef CONFIG_USB_RX_AGGREGATION
	pkt_cnt = GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8812(pbuf);
#endif

	do{
		precvframe = rtw_alloc_recvframe(pfree_recv_queue);
		if(precvframe==NULL)
		{
			RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: precvframe==NULL\n"));
			DBG_8192C("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __FUNCTION__, __LINE__);	
			goto _exit_recvbuf2recvframe;
		}

		_rtw_init_listhead(&precvframe->u.hdr.list);	
		precvframe->u.hdr.precvbuf = NULL;	//can't access the precvbuf for new arch.
		precvframe->u.hdr.len=0;

		rtl8812_query_rx_desc_status(precvframe, pbuf);

		pattrib = &precvframe->u.hdr.attrib;		
				
		if ((padapter->registrypriv.mp_mode == 0) && ((pattrib->crc_err) || (pattrib->icv_err)))
		{
			DBG_8192C("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);

			rtw_free_recvframe(precvframe, pfree_recv_queue);
			goto _exit_recvbuf2recvframe;
		}

		pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;

		if((pattrib->pkt_len<=0) || (pkt_offset>transfer_len))
		{	
			RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("recvbuf2recvframe: pkt_len<=0\n"));
			DBG_8192C("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfer_len \n", __FUNCTION__, __LINE__);	
			rtw_free_recvframe(precvframe, pfree_recv_queue);
			goto _exit_recvbuf2recvframe;
		}

#ifdef CONFIG_RX_PACKET_APPEND_FCS
		if(pattrib->pkt_rpt_type == NORMAL_RX)
			pattrib->pkt_len -= IEEE80211_FCS_LEN;
#endif
		if(rtw_os_alloc_recvframe(padapter, precvframe, 
			(pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), pskb) == _FAIL)
		{
			rtw_free_recvframe(precvframe, pfree_recv_queue);

			goto _exit_recvbuf2recvframe;
		}

		recvframe_put(precvframe, pattrib->pkt_len);
		//recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);

		if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet
		{
			if(pattrib->physt)
				pphy_status = (pbuf + RXDESC_OFFSET);

#ifdef CONFIG_CONCURRENT_MODE
			if(rtw_buddy_adapter_up(padapter))
			{
				if(pre_recv_entry(precvframe, pphy_status) != _SUCCESS)
				{
					RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
						("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
				}
			}
#endif //CONFIG_CONCURRENT_MODE

			if(pattrib->physt && pphy_status)
				rx_query_phy_status(precvframe, pphy_status);

			if(rtw_recv_entry(precvframe) != _SUCCESS)
			{
				RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
					("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
			}

		}
		else{ // pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP,HIS_REPORT-USB HISR RTP
			if (pattrib->pkt_rpt_type == C2H_PACKET) {
				//DBG_8192C("rx C2H_PACKET \n");
				C2HPacketHandler_8812(padapter,precvframe->u.hdr.rx_data,pattrib->pkt_len);
			}
			rtw_free_recvframe(precvframe, pfree_recv_queue);
		}

#ifdef CONFIG_USB_RX_AGGREGATION
		// jaguar 8-byte alignment
		pkt_offset = (u16)_RND8(pkt_offset);
		pkt_cnt--;
		pbuf += pkt_offset;
#endif
		transfer_len -= pkt_offset;
		precvframe = NULL;

	}while(transfer_len>0);

_exit_recvbuf2recvframe:

	return _SUCCESS;	
}
//
//	Description:
//		Download 8192C firmware code.
//
//
int FirmwareDownload92C(
	IN	PADAPTER			Adapter
)
{	
	int	rtStatus = _SUCCESS;	
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);

	char 			R92CFwImageFileName_TSMC[] ={RTL8192C_FW_TSMC_IMG};
	char 			R92CFwImageFileName_UMC[] ={RTL8192C_FW_UMC_IMG};
	char 			R8723FwImageFileName_UMC[] ={RTL8723_FW_UMC_IMG};

	char *			FwImage;
	u32				FwImageLen;	
	
	char*			pFwImageFileName;	

	//vivi, merge 92c and 92s into one driver, 20090817
	//vivi modify this temply, consider it later!!!!!!!!
	//PRT_FIRMWARE	pFirmware = GET_FIRMWARE_819X(Adapter);	
	//PRT_FIRMWARE_92C	pFirmware = GET_FIRMWARE_8192C(Adapter);
	PRT_FIRMWARE_92C	pFirmware = NULL;
	PRT_8192C_FIRMWARE_HDR		pFwHdr = NULL;
	u8		*pFirmwareBuf;
	u32		FirmwareLen;

	pFirmware = (PRT_FIRMWARE_92C)_rtw_malloc(sizeof(RT_FIRMWARE_92C));
	if(!pFirmware)
	{
		rtStatus = _FAIL;
		goto Exit;
	}
	
	

	//RT_TRACE(COMP_INIT, DBG_LOUD, (" ===> FirmwareDownload91C() fw:%s\n", pFwImageFileName));

#ifdef CONFIG_EMBEDDED_FWIMG
	pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
#else
	pFirmware->eFWSource = FW_SOURCE_IMG_FILE; 
#endif
	if(IS_NORMAL_CHIP(pHalData->VersionID))
	{
		if(IS_VENDOR_UMC_A_CUT(pHalData->VersionID) && !IS_92C_SERIAL(pHalData->VersionID))// UMC , 8188
		{						
			pFwImageFileName = R92CFwImageFileName_UMC;
			FwImage = Rtl819XFwUMCImageArray;
			FwImageLen = UMCImgArrayLength;
			DBG_871X(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_UMC\n");
				
		}
		else
		{
			pFwImageFileName = R92CFwImageFileName_TSMC;
			FwImage = Rtl819XFwTSMCImageArray;
			FwImageLen = TSMCImgArrayLength;
			DBG_871X(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_TSMC\n");
		}
	}
	else
	{
	#if 0
		pFwImageFileName = TestChipFwFile;
		FwImage = Rtl8192CTestFwImg;
		FwImageLen = Rtl8192CTestFwImgLen;
		RT_TRACE(COMP_INIT, DBG_LOUD, (" ===> FirmwareDownload91C() fw:Rtl8192CTestFwImg\n"));
	#endif
	}
		

	switch(pFirmware->eFWSource)
	{
		case FW_SOURCE_IMG_FILE:
			//TODO:load fw bin file
			break;
		case FW_SOURCE_HEADER_FILE:
			if(TSMCImgArrayLength > FW_8192C_SIZE){
				rtStatus = _FAIL;
				//RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE) );
				DBG_871X("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE);
				goto Exit;
			}
			_rtw_memcpy(pFirmware->szFwBuffer, FwImage, FwImageLen);
			pFirmware->ulFwLength = FwImageLen;
			break;
	}

	pFirmwareBuf = pFirmware->szFwBuffer;
	FirmwareLen = pFirmware->ulFwLength;

	// To Check Fw header. 
	pFwHdr = (PRT_8192C_FIRMWARE_HDR)pFirmware->szFwBuffer;

	pHalData->FirmwareVersion =  le16_to_cpu(pFwHdr->Version); 
	pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion); 

	//RT_TRACE(COMP_INIT, DBG_LOUD, (" FirmwareVersion(%#x), Signature(%#x)\n", 
	//	Adapter->MgntInfo.FirmwareVersion, pFwHdr->Signature));

	DBG_8192C("fw_ver=v%d, fw_subver=%d, sig=0x%x\n", 
		pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, le16_to_cpu(pFwHdr->Signature)&0xFFF0);

	if(IS_FW_HEADER_EXIST(pFwHdr))
	{
		//RT_TRACE(COMP_INIT, DBG_LOUD,("Shift 32 bytes for FW header!!\n"));
		pFirmwareBuf = pFirmwareBuf + 32;
		FirmwareLen = FirmwareLen -32;
	}
		
	// Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself,
	// or it will cause download Fw fail. 2010.02.01. by tynli.
	if(rtw_read8(Adapter, REG_MCUFWDL)&BIT7) //8051 RAM code
	{	
		DBG_8192C("8051 in Ram......prepare to reset by itself\n");
		_FirmwareSelfReset(Adapter);
		rtw_write8(Adapter, REG_MCUFWDL, 0x00);		
	}

		
	_FWDownloadEnable(Adapter, _TRUE);
	_WriteFW(Adapter, pFirmwareBuf, FirmwareLen);
	_FWDownloadEnable(Adapter, _FALSE);

	rtStatus = _FWFreeToGo(Adapter);
	if(_SUCCESS != rtStatus){
		//RT_TRACE(COMP_INIT, DBG_SERIOUS, ("DL Firmware failed!\n") );	
		goto Exit;
	}	
	//RT_TRACE(COMP_INIT, DBG_LOUD, (" Firmware is ready to run!\n"));

Exit:

	if(pFirmware)
		_rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_92C));

	//RT_TRACE(COMP_INIT, DBG_LOUD, (" <=== FirmwareDownload91C()\n"));
	return rtStatus;

}
Example #25
0
static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
{
	_irqL irqL;
	int i;
	struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
	//struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
	//_adapter			*padapter = pxmitframe->padapter;
	_adapter	*padapter = pxmitbuf->padapter;
       struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;		
	//struct pkt_attrib *pattrib = &pxmitframe->attrib;
	   
_func_enter_;

	switch(pxmitbuf->flags)
	{
		case VO_QUEUE_INX:
			pxmitpriv->voq_cnt--;			
			break;
		case VI_QUEUE_INX:
			pxmitpriv->viq_cnt--;		
			break;
		case BE_QUEUE_INX:
			pxmitpriv->beq_cnt--;			
			break;
		case BK_QUEUE_INX:
			pxmitpriv->bkq_cnt--;			
			break;
		default:			
			break;
	}
		

/*
	_enter_critical(&pxmitpriv->lock, &irqL);

	pxmitpriv->txirp_cnt--;
	
	switch(pattrib->priority) 
	{
		case 1:				
		case 2:
			pxmitpriv->bkq_cnt--;
			//DBG_8192C("pxmitpriv->bkq_cnt=%d\n", pxmitpriv->bkq_cnt);
			break;
		case 4:
		case 5:
			pxmitpriv->viq_cnt--;
			//DBG_8192C("pxmitpriv->viq_cnt=%d\n", pxmitpriv->viq_cnt);
			break;
		case 6:
		case 7:
			pxmitpriv->voq_cnt--;
			//DBG_8192C("pxmitpriv->voq_cnt=%d\n", pxmitpriv->voq_cnt);
			break;
		case 0:
		case 3:			
		default:
			pxmitpriv->beq_cnt--;
			//DBG_8192C("pxmitpriv->beq_cnt=%d\n", pxmitpriv->beq_cnt);
			break;
			
	}	
	
	_exit_critical(&pxmitpriv->lock, &irqL);
	
	
	if(pxmitpriv->txirp_cnt==0)
	{
		RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: txirp_cnt== 0, set allrxreturnevt!\n"));		
		_rtw_up_sema(&(pxmitpriv->tx_retevt));
	}
*/
        //rtw_free_xmitframe(pxmitpriv, pxmitframe);
	
	if (RTW_CANNOT_TX(padapter))
	{
		RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
		DBG_8192C("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) pxmitbuf->buf_tag(%x) \n", 
		__FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved,pxmitbuf->buf_tag);	

		goto check_completion;
	}


	if (purb->status==0) {
	
	} else {
		RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete : purb->status(%d) != 0 \n", purb->status));
		DBG_871X("###=> urb_write_port_complete status(%d)\n",purb->status);
		if((purb->status==-EPIPE)||(purb->status==-EPROTO))
		{
			//usb_clear_halt(pusbdev, purb->pipe);	
			//msleep(10);
			sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL);
		} else if (purb->status == -EINPROGRESS) {
			RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: EINPROGESS\n"));
			goto check_completion;

		} else if (purb->status == -ENOENT) {
			DBG_871X("%s: -ENOENT\n", __func__);
			goto check_completion;
			
		} else if (purb->status == -ECONNRESET) {
			DBG_871X("%s: -ECONNRESET\n", __func__);
			goto check_completion;

		} else if (purb->status == -ESHUTDOWN) {
			RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: ESHUTDOWN\n"));
			padapter->bDriverStopped=_TRUE;
			RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped=TRUE\n"));

			goto check_completion;
		}
		else
		{					
			padapter->bSurpriseRemoved=_TRUE;
			DBG_8192C("bSurpriseRemoved=TRUE\n");
			//rtl8192cu_trigger_gpio_0(padapter);
			RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bSurpriseRemoved=TRUE\n"));

			goto check_completion;
		}
	}

	#ifdef DBG_CONFIG_ERROR_DETECT
	{	
		HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
		pHalData->srestpriv.last_tx_complete_time = jiffies;		
	}
	#endif

check_completion:
	_enter_critical(&pxmitpriv->lock_sctx, &irqL);
	rtw_sctx_done_err(&pxmitbuf->sctx,
	purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
	_exit_critical(&pxmitpriv->lock_sctx, &irqL);

	rtw_free_xmitbuf(pxmitpriv, pxmitbuf);

	//if(rtw_txframes_pending(padapter))	
	{
		tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
	}
	
_func_exit_;	

}
int	rtl8192eu_init_recv_priv(_adapter *padapter)
{
	struct recv_priv	*precvpriv = &padapter->recvpriv;
	int	i, res = _SUCCESS;
	struct recv_buf *precvbuf;

#ifdef CONFIG_RECV_THREAD_MODE	
	_rtw_init_sema(&precvpriv->recv_sema, 0);//will be removed
	_rtw_init_sema(&precvpriv->terminate_recvthread_sema, 0);//will be removed
#endif

#ifdef PLATFORM_LINUX
	tasklet_init(&precvpriv->recv_tasklet,
	     (void(*)(unsigned long))rtl8192eu_recv_tasklet,
	     (unsigned long)padapter);
#endif

#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
#ifdef PLATFORM_LINUX
	precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if(precvpriv->int_in_urb == NULL){
		res= _FAIL;
		DBG_8192C("alloc_urb for interrupt in endpoint fail !!!!\n");
		goto exit;
	}
#endif
	precvpriv->int_in_buf = rtw_zmalloc(INTERRUPT_MSG_FORMAT_LEN);
	if(precvpriv->int_in_buf == NULL){
		res= _FAIL;
		DBG_8192C("alloc_mem for interrupt in endpoint fail !!!!\n");
		goto exit;
	}
#endif

	//init recv_buf
	_rtw_init_queue(&precvpriv->free_recv_buf_queue);

#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
	_rtw_init_queue(&precvpriv->recv_buf_pending_queue);
#endif	// CONFIG_USE_USB_BUFFER_ALLOC_RX

	precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF *sizeof(struct recv_buf) + 4);
	if(precvpriv->pallocated_recv_buf==NULL){
		res= _FAIL;
		RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("alloc recv_buf fail!\n"));
		goto exit;
	}
	_rtw_memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF *sizeof(struct recv_buf) + 4);

	precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
	
	precvbuf = (struct recv_buf*)precvpriv->precv_buf;

	for(i=0; i < NR_RECVBUFF ; i++)
	{
		_rtw_init_listhead(&precvbuf->list);

		_rtw_spinlock_init(&precvbuf->recvbuf_lock);

		precvbuf->alloc_sz = MAX_RECVBUF_SZ;

		res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
		if(res==_FAIL)
			break;

		precvbuf->ref_cnt = 0;
		precvbuf->adapter =padapter;


		//rtw_list_insert_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue));

		precvbuf++;

	}

	precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;

#ifdef PLATFORM_LINUX

	skb_queue_head_init(&precvpriv->rx_skb_queue);

#ifdef CONFIG_PREALLOC_RECV_SKB
	{
		int i;
		SIZE_PTR tmpaddr=0;
		SIZE_PTR alignment=0;
		struct sk_buff *pskb=NULL;

		skb_queue_head_init(&precvpriv->free_recv_skb_queue);

		for(i=0; i<NR_PREALLOC_RECV_SKB; i++)
		{
			pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);

			if(pskb)
			{
				pskb->dev = padapter->pnetdev;

				tmpaddr = (SIZE_PTR)pskb->data;
				alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
				skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));

				skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
			}

			pskb=NULL;

		}
	}
#endif

#endif

exit:

	return res;

}