예제 #1
0
void _ips_enter(_adapter * padapter)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;	

	if (padapter->hw_init_completed == _FALSE) {
		DBG_871X("%s: hw_init_completed: %d\n", 
			__func__, padapter->hw_init_completed);
		return;
	}

	pwrpriv->bips_processing = _TRUE;	

	// syn ips_mode with request
	pwrpriv->ips_mode = pwrpriv->ips_mode_req;
	
	pwrpriv->ips_enter_cnts++;	
	DBG_871X("==>ips_enter cnts:%d\n",pwrpriv->ips_enter_cnts);
#ifdef CONFIG_BT_COEXIST
	BTDM_TurnOffBtCoexistBeforeEnterIPS(padapter);
#endif
	if(rf_off == pwrpriv->change_rfpwrstate )
	{	
		pwrpriv->bpower_saving = _TRUE;
		DBG_871X_LEVEL(_drv_always_, "nolinked power save enter\n");

		if(pwrpriv->ips_mode == IPS_LEVEL_2)
			pwrpriv->bkeepfwalive = _TRUE;
		
		rtw_ips_pwr_down(padapter);
		pwrpriv->rf_pwrstate = rf_off;
	}	
	pwrpriv->bips_processing = _FALSE;	
	
}
예제 #2
0
int _ips_leave(_adapter * padapter)
{
	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
	int result = _SUCCESS;

	if((pwrpriv->rf_pwrstate == rf_off) &&(!pwrpriv->bips_processing))
	{
		pwrpriv->bips_processing = _TRUE;
		pwrpriv->change_rfpwrstate = rf_on;
		pwrpriv->ips_leave_cnts++;
		DBG_871X("==>ips_leave cnts:%d\n",pwrpriv->ips_leave_cnts);

		if ((result = rtw_ips_pwr_up(padapter)) == _SUCCESS) {
			pwrpriv->rf_pwrstate = rf_on;
		}
		DBG_871X_LEVEL(_drv_always_, "nolinked power save leave\n");
		
		DBG_871X("==> ips_leave.....LED(0x%08x)...\n",rtw_read32(padapter,0x4c));
		pwrpriv->bips_processing = _FALSE;

		pwrpriv->bkeepfwalive = _FALSE;
		pwrpriv->bpower_saving = _FALSE;
	}

	return result;
}
예제 #3
0
void ips_enter(_adapter * padapter)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
	struct xmit_priv *pxmit_priv = &padapter->xmitpriv;

#if (MP_DRIVER == 1)
	if (padapter->registrypriv.mp_mode == 1)
		return;
#endif

	if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
		pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
		DBG_871X_LEVEL(_drv_always_, "There are some pkts to transmit\n");
		DBG_871X_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n", 
			pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);	
		return;
	}

	_enter_pwrlock(&pwrpriv->lock);

	pwrpriv->bips_processing = _TRUE;	

	// syn ips_mode with request
	pwrpriv->ips_mode = pwrpriv->ips_mode_req;
	
	pwrpriv->ips_enter_cnts++;	
	DBG_871X("==>ips_enter cnts:%d\n",pwrpriv->ips_enter_cnts);
#ifdef CONFIG_BT_COEXIST
	BTDM_TurnOffBtCoexistBeforeEnterIPS(padapter);
#endif
	if(rf_off == pwrpriv->change_rfpwrstate )
	{	
		pwrpriv->bpower_saving = _TRUE;
		DBG_871X_LEVEL(_drv_always_, "nolinked power save enter\n");

		if(pwrpriv->ips_mode == IPS_LEVEL_2)
			pwrpriv->bkeepfwalive = _TRUE;
		
		rtw_ips_pwr_down(padapter);
		pwrpriv->rf_pwrstate = rf_off;
	}	
	pwrpriv->bips_processing = _FALSE;	
	
	_exit_pwrlock(&pwrpriv->lock);
	
}
예제 #4
0
/*
 * Description
 *	Transmit xmitframe from queue
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8723bs_xmit_handler(PADAPTER padapter)
{
    struct xmit_priv *pxmitpriv;
    s32 ret;
    _irqL irql;


    pxmitpriv = &padapter->xmitpriv;

wait:
    ret = _rtw_down_sema(&pxmitpriv->SdioXmitSema);
    if (_FAIL == ret) {
        DBG_871X_LEVEL(_drv_emerg_, "%s: down sema fail!\n", __FUNCTION__);
        return _FAIL;
    }

next:
    if ((padapter->bDriverStopped == _TRUE) ||
            (padapter->bSurpriseRemoved == _TRUE)) {
        RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
                 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
                  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
        return _FAIL;
    }

    _enter_critical_bh(&pxmitpriv->lock, &irql);
    ret = rtw_txframes_pending(padapter);
    _exit_critical_bh(&pxmitpriv->lock, &irql);
    if (ret == 0) {
        if(!padapter->registrypriv.wifi_spec)
            rtw_yield_os();
        return _SUCCESS;
    }

    // dequeue frame and write to hardware

    ret = xmit_xmitframes(padapter, pxmitpriv);
    if (ret == -2) {
        //here sleep 1ms will cause big TP loss of TX
        //from 50+ to 40+
        if(padapter->registrypriv.wifi_spec)
            rtw_msleep_os(1);
        else
            rtw_yield_os();
        goto next;
    }

    _enter_critical_bh(&pxmitpriv->lock, &irql);
    ret = rtw_txframes_pending(padapter);
    _exit_critical_bh(&pxmitpriv->lock, &irql);
    if (ret == 1) {
        //rtw_msleep_os(1);
        goto next;
    }

    return _SUCCESS;
}
예제 #5
0
/*
 * Description
 *	Transmit xmitbuf to hardware tx fifo
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8723bs_xmit_buf_handler(PADAPTER padapter)
{
    PHAL_DATA_TYPE phal;
    struct mlme_priv *pmlmepriv;
    struct xmit_priv *pxmitpriv;
    struct dvobj_priv	*pdvobjpriv;
    struct xmit_buf *pxmitbuf;
    struct xmit_frame *pframe;
    u32 deviceId;
    u32 requiredPage;
    u8 PageIdx, queue_empty;
    _irqL irql;
    u32 n;
    s32 ret;


    phal = GET_HAL_DATA(padapter);
    pmlmepriv = &padapter->mlmepriv;
    pxmitpriv = &padapter->xmitpriv;
    pdvobjpriv = adapter_to_dvobj(padapter);

    ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
    if (_FAIL == ret) {
        DBG_871X_LEVEL(_drv_emerg_, "%s: down SdioXmitBufSema fail!\n", __FUNCTION__);
        return _FAIL;
    }

    ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
    if (ret) {
        RT_TRACE(_module_hal_xmit_c_, _drv_err_,
                 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
                  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
        return _FAIL;
    }

#ifdef CONFIG_LPS_LCLK
    ret = rtw_register_tx_alive(padapter);
    if (ret != _SUCCESS) {
        return _SUCCESS;
    }
#endif

    do {
        queue_empty = rtl8723_dequeue_writeport(padapter);
//	dump secondary adapter xmitbuf
#ifdef CONFIG_CONCURRENT_MODE
        if(rtw_buddy_adapter_up(padapter))
            queue_empty &= rtl8723_dequeue_writeport(padapter->pbuddy_adapter);
#endif
    } while ( !queue_empty);

#ifdef CONFIG_LPS_LCLK
    rtw_unregister_tx_alive(padapter);
#endif

    return _SUCCESS;
}
static void __exit rtw_drv_halt(void)
{
	DBG_871X_LEVEL(_drv_always_, "module exit start\n");

	drvpriv.drv_registered = _FALSE;

	spi_unregister_driver(&rtw_spi_drv);

	rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_OFF);
	rtw_wifi_gpio_deinit();

	rtw_suspend_lock_uninit();
	rtw_drv_proc_deinit();
	rtw_ndev_notifier_unregister();

	DBG_871X_LEVEL(_drv_always_, "module exit success\n");

	rtw_mstat_dump(RTW_DBGDUMP);
}
예제 #7
0
static int rtw_cfgvendor_get_feature_set_matrix(struct wiphy *wiphy,
	struct wireless_dev *wdev, const void  *data, int len)
{
	int err = 0;
	struct sk_buff *skb;
	int *reply;
	int num, mem_needed, i;

	reply = rtw_dev_get_feature_set_matrix(wdev_to_ndev(wdev), &num);

	if (!reply) {
		DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Could not get feature list matrix\n"
			, FUNC_NDEV_ARG(wdev_to_ndev(wdev)));
		err = -EINVAL;
		return err;
	}

	mem_needed = VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * num) +
	             ATTRIBUTE_U32_LEN;

	/* Alloc the SKB for vendor_event */
	skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed);
	if (unlikely(!skb)) {
		DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(wdev_to_ndev(wdev)));
		err = -ENOMEM;
		goto exit;
	}

	nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, num);
	for (i = 0; i < num; i++) {
		nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, reply[i]);
	}

	err =  rtw_cfg80211_vendor_cmd_reply(skb);

	if (unlikely(err))
		DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Vendor Command reply failed ret:%d \n"
			, FUNC_NDEV_ARG(wdev_to_ndev(wdev)), err);
exit:
	rtw_mfree((u8*)reply, sizeof(int)*num);
	return err;
}
예제 #8
0
u8 GetHalDefVar(
	struct adapter *adapter, enum HAL_DEF_VARIABLE variable, void *value
)
{
	struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
	DM_ODM_T *odm = &(hal_data->odmpriv);
	u8 bResult = _SUCCESS;

	switch (variable) {
	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
		{
			struct mlme_priv *pmlmepriv;
			struct sta_priv *pstapriv;
			struct sta_info *psta;

			pmlmepriv = &adapter->mlmepriv;
			pstapriv = &adapter->stapriv;
			psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
			if (psta)
				*((int *)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;
		}
		break;
	case HW_DEF_ODM_DBG_FLAG:
		*((u64 *)value) = odm->DebugComponents;
		break;
	case HW_DEF_ODM_DBG_LEVEL:
		*((u32 *)value) = odm->DebugLevel;
		break;
	case HAL_DEF_DBG_DM_FUNC:
		*((u32 *)value) = hal_data->odmpriv.SupportAbility;
		break;
	case HAL_DEF_DBG_DUMP_RXPKT:
		*((u8 *)value) = hal_data->bDumpRxPkt;
		break;
	case HAL_DEF_DBG_DUMP_TXPKT:
		*((u8 *)value) = hal_data->bDumpTxPkt;
		break;
	case HAL_DEF_ANT_DETECT:
		*((u8 *)value) = hal_data->AntDetection;
		break;
	case HAL_DEF_MACID_SLEEP:
		*(u8 *)value = false;
		break;
	case HAL_DEF_TX_PAGE_SIZE:
		*((u32 *)value) = PAGE_SIZE_128;
		break;
	default:
		DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __func__, variable);
		bResult = _FAIL;
		break;
	}

	return bResult;
}
예제 #9
0
/*
* rtw_set_band - 
* @adapter: pointer to _adapter structure
* @band: band to set
* 
* Return _SUCCESS or _FAIL
*/
int rtw_set_band(_adapter *adapter, enum _BAND band)
{
	if (rtw_band_valid(band)) {
		DBG_871X(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
		adapter->setband = band;
		return _SUCCESS;
	}

	DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);
	return _FAIL;
}
void	rtw_hal_set_chnl_bw(_adapter *padapter, u8 channel, CHANNEL_WIDTH Bandwidth, u8 Offset40, u8 Offset80)
{
	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
	
	ODM_AcquireSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
	if(pDM_Odm->RFCalibrateInfo.bIQKInProgress == _TRUE)
		DBG_871X_LEVEL(_drv_err_, "%s, %d, IQK may race condition\n", __func__,__LINE__);
	ODM_ReleaseSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
	padapter->HalFunc.set_chnl_bw_handler(padapter, channel, Bandwidth, Offset40, Offset80);	
}
예제 #11
0
s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
{
	_adapter *pri_adapter = GET_PRIMARY_ADAPTER(padapter);

	if (pri_adapter->bFWReady == _TRUE)
		return padapter->HalFunc.fill_h2c_cmd(padapter, ElementID, CmdLen, pCmdBuffer);
	else if (padapter->registrypriv.mp_mode == 0)
		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" FW doesn't exit when no MP mode, by pass H2C id:0x%02x\n"
			, FUNC_ADPT_ARG(padapter), ElementID);
	return _FAIL;
}
예제 #12
0
u8 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *val)
{
	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
	struct dm_priv *dm = &(hal_data->dmpriv);
	u8 bResult = _SUCCESS;

	switch(variable) {
	case HAL_DEF_DBG_DM_FUNC:
	{
		u8 dm_func = *((u8*)val);

		if (dm_func == 0){ //disable all dynamic func
			dm->DMFlag = DYNAMIC_FUNC_DISABLE;
			DBG_8192C("==> Disable all dynamic function...\n");
		}
		else if (dm_func == 1){//disable DIG
			dm->DMFlag &= (~DYNAMIC_FUNC_DIG);
			DBG_8192C("==> Disable DIG...\n");
		}
		else if (dm_func == 2){//disable High power
			dm->DMFlag &= (~DYNAMIC_FUNC_HP);
		}
		else if (dm_func == 3){//disable tx power tracking
			dm->DMFlag &= (~DYNAMIC_FUNC_SS);
			DBG_8192C("==> Disable tx power tracking...\n");
		}
		else if (dm_func == 4){//disable BT coexistence
			dm->DMFlag &= (~DYNAMIC_FUNC_BT);
		}
		else if (dm_func == 5){//disable antenna diversity
			dm->DMFlag &= (~DYNAMIC_FUNC_ANT_DIV);
		}				
		else if (dm_func == 6){//turn on all dynamic func
			if (!(dm->DMFlag & DYNAMIC_FUNC_DIG)) {
				DIG_T	*pDigTable = &dm->DM_DigTable;
				pDigTable->PreIGValue = rtw_read8(adapter, 0xc50);	
			}

			dm->DMFlag |= (DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS|
				DYNAMIC_FUNC_BT|DYNAMIC_FUNC_ANT_DIV) ;
			DBG_8192C("==> Turn on all dynamic function...\n");
		}
	}
		break;
	default:
		if(0)
		DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
		bResult = _FAIL;
		break;
	}

	return bResult;
}
예제 #13
0
/*
 * Description
 *	Transmit xmitframe from queue
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
static s32 rtl8723bs_xmit_handler(PADAPTER padapter)
{
	struct xmit_priv *pxmitpriv;
	s32 ret;
	_irqL irql;


	pxmitpriv = &padapter->xmitpriv;

	if (down_interruptible(&pxmitpriv->SdioXmitSema)) {
		DBG_871X_LEVEL(_drv_emerg_, "%s: down sema fail!\n", __FUNCTION__);
		return _FAIL;
	}

next:
	if ((padapter->bDriverStopped == true) ||
		(padapter->bSurpriseRemoved == true)) {
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
				  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
		return _FAIL;
	}

	spin_lock_bh(&pxmitpriv->lock);
	ret = rtw_txframes_pending(padapter);
	spin_unlock_bh(&pxmitpriv->lock);
	if (ret == 0) {
		return _SUCCESS;
	}

	// dequeue frame and write to hardware

	ret = xmit_xmitframes(padapter, pxmitpriv);
	if (ret == -2) {
		//here sleep 1ms will cause big TP loss of TX
		//from 50+ to 40+
		if(padapter->registrypriv.wifi_spec)
			msleep(1);
		else
			yield();
		goto next;
	}

	spin_lock_bh(&pxmitpriv->lock);
	ret = rtw_txframes_pending(padapter);
	spin_unlock_bh(&pxmitpriv->lock);
	if (ret == 1) {
		goto next;
	}

	return _SUCCESS;
}
예제 #14
0
int *rtw_dev_get_feature_set_matrix(struct net_device *dev, int *num)
{
	int feature_set_full, mem_needed;
	int *ret;

	*num = 0;
	mem_needed = sizeof(int) * MAX_FEATURE_SET_CONCURRRENT_GROUPS;
	ret = (int *)rtw_malloc(mem_needed);

	if (!ret) {
		DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" failed to allocate %d bytes\n"
			, FUNC_NDEV_ARG(dev), mem_needed);
		return ret;
	}

	feature_set_full = rtw_dev_get_feature_set(dev);

	ret[0] = (feature_set_full & WIFI_FEATURE_INFRA) |
	         (feature_set_full & WIFI_FEATURE_INFRA_5G) |
	         (feature_set_full & WIFI_FEATURE_NAN) |
	         (feature_set_full & WIFI_FEATURE_D2D_RTT) |
	         (feature_set_full & WIFI_FEATURE_D2AP_RTT) |
	         (feature_set_full & WIFI_FEATURE_PNO) |
	         (feature_set_full & WIFI_FEATURE_BATCH_SCAN) |
	         (feature_set_full & WIFI_FEATURE_GSCAN) |
	         (feature_set_full & WIFI_FEATURE_HOTSPOT) |
	         (feature_set_full & WIFI_FEATURE_ADDITIONAL_STA) |
	         (feature_set_full & WIFI_FEATURE_EPR);

	ret[1] = (feature_set_full & WIFI_FEATURE_INFRA) |
	         (feature_set_full & WIFI_FEATURE_INFRA_5G) |
	         /* Not yet verified NAN with P2P */
	         /* (feature_set_full & WIFI_FEATURE_NAN) | */
	         (feature_set_full & WIFI_FEATURE_P2P) |
	         (feature_set_full & WIFI_FEATURE_D2AP_RTT) |
	         (feature_set_full & WIFI_FEATURE_D2D_RTT) |
	         (feature_set_full & WIFI_FEATURE_EPR);

	ret[2] = (feature_set_full & WIFI_FEATURE_INFRA) |
	         (feature_set_full & WIFI_FEATURE_INFRA_5G) |
	         (feature_set_full & WIFI_FEATURE_NAN) |
	         (feature_set_full & WIFI_FEATURE_D2D_RTT) |
	         (feature_set_full & WIFI_FEATURE_D2AP_RTT) |
	         (feature_set_full & WIFI_FEATURE_TDLS) |
	         (feature_set_full & WIFI_FEATURE_TDLS_OFFCHANNEL) |
	         (feature_set_full & WIFI_FEATURE_EPR);
	*num = MAX_FEATURE_SET_CONCURRRENT_GROUPS;

	return ret;
}
예제 #15
0
void GetHwReg(_adapter *adapter, HW_VARIABLES variable, u8 *val)
{
	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
	struct dm_priv *dm = &(hal_data->dmpriv);

	switch (variable) {
	case HW_VAR_DM_FLAG:
		*((u8*)val) = dm->DMFlag;
		break;
	default:
		if(0)
		DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HW_VARIABLES(%d) not defined!\n", __FUNCTION__, variable);
		break;
	}
}
예제 #16
0
/*
 * Description
 *Transmit xmitbuf to hardware tx fifo
 *
 * Return
 *_SUCCESS	ok
 *_FAIL		something error
 */
s32 rtl8723bs_xmit_buf_handler(struct adapter *padapter)
{
	struct xmit_priv *pxmitpriv;
	u8 queue_empty, queue_pending;
	s32 ret;


	pxmitpriv = &padapter->xmitpriv;

	if (down_interruptible(&pxmitpriv->xmit_sema)) {
		DBG_871X_LEVEL(_drv_emerg_, "%s: down SdioXmitBufSema fail!\n", __func__);
		return _FAIL;
	}

	ret = (padapter->bDriverStopped == true) || (padapter->bSurpriseRemoved == true);
	if (ret) {
		RT_TRACE(
			_module_hal_xmit_c_,
			_drv_err_,
			(
				"%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
				__func__,
				padapter->bDriverStopped,
				padapter->bSurpriseRemoved
			)
		);
		return _FAIL;
	}

	queue_pending = check_pending_xmitbuf(pxmitpriv);

	if (queue_pending == false)
		return _SUCCESS;

	ret = rtw_register_tx_alive(padapter);
	if (ret != _SUCCESS) {
		return _SUCCESS;
	}

	do {
		queue_empty = rtl8723_dequeue_writeport(padapter);
/* 	dump secondary adapter xmitbuf */
	} while (!queue_empty);

	rtw_unregister_tx_alive(padapter);

	return _SUCCESS;
}
예제 #17
0
int ips_leave(_adapter * padapter)
{
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
	struct security_priv* psecuritypriv=&(padapter->securitypriv);
	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
	int result = _SUCCESS;
	sint keyid;


	_enter_pwrlock(&pwrpriv->lock);

	if((pwrpriv->rf_pwrstate == rf_off) &&(!pwrpriv->bips_processing))
	{
		pwrpriv->bips_processing = _TRUE;
		pwrpriv->change_rfpwrstate = rf_on;
		pwrpriv->ips_leave_cnts++;
		DBG_871X("==>ips_leave cnts:%d\n",pwrpriv->ips_leave_cnts);

		if ((result = rtw_ips_pwr_up(padapter)) == _SUCCESS) {
			pwrpriv->rf_pwrstate = rf_on;
		}
		DBG_871X_LEVEL(_drv_always_, "nolinked power save leave\n");

		if((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) ||(_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm))
		{
			DBG_871X("==>%s,channel(%d),processing(%x)\n",__FUNCTION__,padapter->mlmeextpriv.cur_channel,pwrpriv->bips_processing);
			set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);			
			for(keyid=0;keyid<4;keyid++){
				if(pmlmepriv->key_mask & BIT(keyid)){
					if(keyid == psecuritypriv->dot11PrivacyKeyIndex)
						result=rtw_set_key(padapter,psecuritypriv, keyid, 1);
					else
						result=rtw_set_key(padapter,psecuritypriv, keyid, 0);
				}
			}
		}
		
		DBG_871X("==> ips_leave.....LED(0x%08x)...\n",rtw_read32(padapter,0x4c));
		pwrpriv->bips_processing = _FALSE;

		pwrpriv->bkeepfwalive = _FALSE;
		pwrpriv->bpower_saving = _FALSE;
	}

	_exit_pwrlock(&pwrpriv->lock);

	return result;
}
예제 #18
0
static int rtw_cfgvendor_get_feature_set(struct wiphy *wiphy,
	struct wireless_dev *wdev, const void  *data, int len)
{
	int err = 0;
	int reply;

	reply = rtw_dev_get_feature_set(wdev_to_ndev(wdev));

	err =  rtw_cfgvendor_send_cmd_reply(wiphy, wdev_to_ndev(wdev), &reply, sizeof(int));

	if (unlikely(err))
		DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Vendor Command reply failed ret:%d \n"
			, FUNC_NDEV_ARG(wdev_to_ndev(wdev)), err);

	return err;
}
예제 #19
0
파일: rtw_io.c 프로젝트: jozzse/rtl8723bs
u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr)
{
	u8 r_val = 0x00;
	struct io_priv *pio_priv = &adapter->iopriv;
	struct intf_hdl *pintfhdl = &(pio_priv->intf);
	u8 (*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr);

	_sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8;

	if (_sd_f0_read8)
		r_val = _sd_f0_read8(pintfhdl, addr);
	else
		DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter));

	return r_val;
}
예제 #20
0
static int rtw_cfgvendor_send_cmd_reply(struct wiphy *wiphy,
	struct net_device *dev, const void  *data, int len)
{
	struct sk_buff *skb;

	/* Alloc the SKB for vendor_event */
	skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len);
	if (unlikely(!skb)) {
		DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(dev));
		return -ENOMEM;
	}

	/* Push the data to the skb */
	nla_put_nohdr(skb, len, data);

	return rtw_cfg80211_vendor_cmd_reply(skb);
}
예제 #21
0
u8 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *val)
{
	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
	struct dm_priv *dm = &(hal_data->dmpriv);
	u8 bResult = _SUCCESS;

	switch(variable) {
	case HAL_DEF_DBG_DM_FUNC:
		*((u8*)val) = dm->DMFlag;
		break;
	default:
		if(0)
		DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
		bResult = _FAIL;
		break;
	}

	return bResult;
}
s32 rtw_hal_macid_wakeup(PADAPTER padapter, u8 macid)
{
	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
	u8 support;

	support = _FALSE;
	rtw_hal_get_def_var(padapter, HAL_DEF_MACID_SLEEP, &support);
	if (_FALSE == support)
		return _FAIL;

	if (macid >= macid_ctl->num) {
		DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT": Invalid macid(%u)\n",
			FUNC_ADPT_ARG(padapter), macid);
		return _FAIL;
	}

	rtw_hal_set_hwreg(padapter, HW_VAR_MACID_WAKEUP, &macid);

	return _SUCCESS;
}
예제 #23
0
/*
 * This API is to be used for asynchronous vendor events. This
 * shouldn't be used in response to a vendor command from its
 * do_it handler context (instead rtw_cfgvendor_send_cmd_reply should
 * be used).
 */
int rtw_cfgvendor_send_async_event(struct wiphy *wiphy,
	struct net_device *dev, int event_id, const void  *data, int len)
{
	u16 kflags;
	struct sk_buff *skb;

	kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;

	/* Alloc the SKB for vendor_event */
	skb = rtw_cfg80211_vendor_event_alloc(wiphy, len, event_id, kflags);
	if (!skb) {
		DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(dev));
		return -ENOMEM;
	}

	/* Push the data to the skb */
	nla_put_nohdr(skb, len, data);

	rtw_cfg80211_vendor_event(skb, kflags);

	return 0;
}
예제 #24
0
파일: rtw_ioctl_set.c 프로젝트: Lyude/linux
u8 rtw_set_802_11_connect(struct adapter *padapter, u8 *bssid, struct ndis_802_11_ssid *ssid)
{
	u8 status = _SUCCESS;
	bool bssid_valid = true;
	bool ssid_valid = true;
	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;

	if (!ssid || rtw_validate_ssid(ssid) == false)
		ssid_valid = false;

	if (!bssid || rtw_validate_bssid(bssid) == false)
		bssid_valid = false;

	if (ssid_valid == false && bssid_valid == false) {
		DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
			FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
		status = _FAIL;
		goto exit;
	}

	if (padapter->hw_init_completed == false) {
		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
			 ("set_ssid: hw_init_completed ==false =>exit!!!\n"));
		status = _FAIL;
		goto exit;
	}

	spin_lock_bh(&pmlmepriv->lock);

	DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT"  fw_state = 0x%08x\n",
		FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));

	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
		goto handle_tkip_countermeasure;
	} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
		goto release_mlme_lock;
	}

handle_tkip_countermeasure:
	if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
		status = _FAIL;
		goto release_mlme_lock;
	}

	if (ssid && ssid_valid)
		memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
	else
		memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));

	if (bssid && bssid_valid) {
		memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
		pmlmepriv->assoc_by_bssid = true;
	} else {
		pmlmepriv->assoc_by_bssid = false;
	}

	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
		pmlmepriv->to_join = true;
	} else {
		status = rtw_do_join(padapter);
	}

release_mlme_lock:
	spin_unlock_bh(&pmlmepriv->lock);

exit:
	return status;
}
예제 #25
0
bool rtw_pwr_unassociated_idle(_adapter *adapter)
{
	_adapter *buddy = adapter->pbuddy_adapter;
	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
	struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
#ifdef CONFIG_P2P
	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
#ifdef CONFIG_IOCTL_CFG80211
	struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &adapter->cfg80211_wdinfo;
#endif
#endif

	bool ret = _FALSE;

	if (adapter->pwrctrlpriv.ips_deny_time >= rtw_get_current_time()) {
		//DBG_871X("%s ips_deny_time\n", __func__);
		goto exit;
	}

	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
		|| check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
		|| check_fwstate(pmlmepriv, WIFI_AP_STATE)
		|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
		#if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P_IPS)
		|| pcfg80211_wdinfo->is_ro_ch
		#elif defined(CONFIG_P2P)
		|| !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
		#endif
	) {
		goto exit;
	}

	/* consider buddy, if exist */
	if (buddy) {
		struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv);
		#ifdef CONFIG_P2P
		struct wifidirect_info *b_pwdinfo = &(buddy->wdinfo);
		#ifdef CONFIG_IOCTL_CFG80211
		struct cfg80211_wifidirect_info *b_pcfg80211_wdinfo = &buddy->cfg80211_wdinfo;
		#endif
		#endif

		if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
			|| check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
			|| check_fwstate(b_pmlmepriv, WIFI_AP_STATE)
			|| check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
			#if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P_IPS)
			|| b_pcfg80211_wdinfo->is_ro_ch
			#elif defined(CONFIG_P2P)
			|| !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE)
			#endif
		) {
			goto exit;
		}
	}

#if (MP_DRIVER == 1)
	if (adapter->registrypriv.mp_mode == 1)
		goto exit;
#endif

#ifdef CONFIG_INTEL_PROXIM
	if(adapter->proximity.proxim_on==_TRUE){
		return;
	}
#endif	

	if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
		pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
		DBG_871X_LEVEL(_drv_always_, "There are some pkts to transmit\n");
		DBG_871X_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n", 
			pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);	
		goto exit;
	}	

	ret = _TRUE;

exit:
	return ret;
}
예제 #26
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=0;
    struct hw_xmit *hwxmits, *phwxmit;
    u8 no_res, idx, hwentry;
    _irqL irql;
    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;
    u8 txdesc_size = TXDESC_SIZE;
    int inx[4];

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

    if (padapter->registrypriv.wifi_spec == 1) {
        for(idx=0; idx<4; idx++)
            inx[idx] = pxmitpriv->wmm_para_seq[idx];
    } else {
        inx[0] = 0;
        inx[1] = 1;
        inx[2] = 2;
        inx[3] = 3;
    }

    // 0(VO), 1(VI), 2(BE), 3(BK)
    for (idx = 0; idx < hwentry; idx++)
    {
        phwxmit = hwxmits + inx[idx];

        if((check_pending_xmitbuf(pxmitpriv) == _TRUE) && (padapter->mlmepriv.LinkDetectInfo.bHigherBusyTxTraffic == _TRUE)) {
            if ((phwxmit->accnt > 0) && (phwxmit->accnt < 5)) {
                err = -2;
                break;
            }
        }

        _enter_critical_bh(&pxmitpriv->lock, &irql);

        sta_phead = get_list_head(phwxmit->sta_queue);
        sta_plist = get_next(sta_phead);
        //because stop_sta_xmit may delete sta_plist at any time
        //so we should add lock here, or while loop can not exit
        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);

#ifdef DBG_XMIT_BUF
            DBG_871X("%s idx:%d hwxmit_pkt_num:%d ptxservq_pkt_num:%d\n", __func__, idx, phwxmit->accnt, ptxservq->qcnt);
            DBG_871X("%s free_xmit_extbuf_cnt=%d free_xmitbuf_cnt=%d free_xmitframe_cnt=%d \n",
                     __func__, pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xmitbuf_cnt,
                     pxmitpriv->free_xmitframe_cnt);
#endif
            pframe_queue = &ptxservq->sta_pending;

            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)
                    {
                        //pxmitbuf->priv_data will be NULL, and will crash here
                        if (pxmitbuf->len > 0 && pxmitbuf->priv_data)
                        {
                            struct xmit_frame *pframe;
                            pframe = (struct xmit_frame*)pxmitbuf->priv_data;
                            pframe->agg_num = k;
                            pxmitbuf->agg_num = k;
                            rtl8723b_update_txdesc(pframe, pframe->buf_addr);
                            rtw_free_xmitframe(pxmitpriv, pframe);
                            pxmitbuf->priv_data = NULL;
                            enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
                            //can not yield under lock
                            //rtw_yield_os();
                        } else {
                            rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
                        }
                    }

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

                // ok to send, remove frame from queue
#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)) {
                        DBG_871X("%s: one not triggered pkt in queue when this STA sleep,"
                                 " break and goto next sta\n", __func__);
                        break;
                    }
                }
#endif
                rtw_list_delete(&pxmitframe->list);
                ptxservq->qcnt--;
                phwxmit->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) {
                    DBG_871X_LEVEL(_drv_err_, "%s: coalesce FAIL!", __FUNCTION__);
                    // Todo: error handler
                } else {
                    k++;
                    if (k != 1)
                        rtl8723b_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;
            }

            if (_rtw_queue_empty(pframe_queue) == _TRUE)
                rtw_list_delete(&ptxservq->tx_pending);

            if (err) break;
        }
        _exit_critical_bh(&pxmitpriv->lock, &irql);

        // dump xmit_buf to hw tx fifo
        if (pxmitbuf)
        {
            RT_TRACE(_module_hal_xmit_c_, _drv_info_, ("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;
                rtl8723b_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;
}
예제 #27
0
u8 SetHalDefVar(
	struct adapter *adapter, enum HAL_DEF_VARIABLE variable, void *value
)
{
	struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
	DM_ODM_T *odm = &(hal_data->odmpriv);
	u8 bResult = _SUCCESS;

	switch (variable) {
	case HW_DEF_FA_CNT_DUMP:
		/* ODM_COMP_COMMON */
		if (*((u8 *)value))
			odm->DebugComponents |= (ODM_COMP_DIG | ODM_COMP_FA_CNT);
		else
			odm->DebugComponents &= ~(ODM_COMP_DIG | ODM_COMP_FA_CNT);
		break;
	case HAL_DEF_DBG_RX_INFO_DUMP:
		DBG_871X("============ Rx Info dump ===================\n");
		DBG_871X("bLinked = %d, RSSI_Min = %d(%%)\n",
			odm->bLinked, odm->RSSI_Min);

		if (odm->bLinked) {
			DBG_871X("RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n",
				HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B);

			#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
			rtw_dump_raw_rssi_info(adapter);
			#endif
		}
		break;
	case HW_DEF_ODM_DBG_FLAG:
		ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u64 *)value));
		break;
	case HW_DEF_ODM_DBG_LEVEL:
		ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u32 *)value));
		break;
	case HAL_DEF_DBG_DM_FUNC:
	{
		u8 dm_func = *((u8 *)value);
		struct dm_priv *dm = &hal_data->dmpriv;

		if (dm_func == 0) { /* disable all dynamic func */
			odm->SupportAbility = DYNAMIC_FUNC_DISABLE;
			DBG_8192C("==> Disable all dynamic function...\n");
		} else if (dm_func == 1) {/* disable DIG */
			odm->SupportAbility  &= (~DYNAMIC_BB_DIG);
			DBG_8192C("==> Disable DIG...\n");
		} else if (dm_func == 2) {/* disable High power */
			odm->SupportAbility  &= (~DYNAMIC_BB_DYNAMIC_TXPWR);
		} else if (dm_func == 3) {/* disable tx power tracking */
			odm->SupportAbility  &= (~DYNAMIC_RF_CALIBRATION);
			DBG_8192C("==> Disable tx power tracking...\n");
		} else if (dm_func == 4) {/* disable BT coexistence */
			dm->DMFlag &= (~DYNAMIC_FUNC_BT);
		} else if (dm_func == 5) {/* disable antenna diversity */
			odm->SupportAbility  &= (~DYNAMIC_BB_ANT_DIV);
		} else if (dm_func == 6) {/* turn on all dynamic func */
			if (!(odm->SupportAbility  & DYNAMIC_BB_DIG)) {
				DIG_T	*pDigTable = &odm->DM_DigTable;
				pDigTable->CurIGValue = rtw_read8(adapter, 0xc50);
			}
			dm->DMFlag |= DYNAMIC_FUNC_BT;
			odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
			DBG_8192C("==> Turn on all dynamic function...\n");
		}
	}
		break;
	case HAL_DEF_DBG_DUMP_RXPKT:
		hal_data->bDumpRxPkt = *((u8 *)value);
		break;
	case HAL_DEF_DBG_DUMP_TXPKT:
		hal_data->bDumpTxPkt = *((u8 *)value);
		break;
	case HAL_DEF_ANT_DETECT:
		hal_data->AntDetection = *((u8 *)value);
		break;
	default:
		DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __func__, variable);
		bResult = _FAIL;
		break;
	}

	return bResult;
}
예제 #28
0
void SetHwReg(struct adapter *adapter, u8 variable, u8 *val)
{
	struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
	DM_ODM_T *odm = &(hal_data->odmpriv);

	switch (variable) {
	case HW_VAR_PORT_SWITCH:
		hw_var_port_switch(adapter);
		break;
	case HW_VAR_INIT_RTS_RATE:
		rtw_warn_on(1);
		break;
	case HW_VAR_SEC_CFG:
	{
		u16 reg_scr;

		reg_scr = rtw_read16(adapter, REG_SECCFG);
		rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable);
	}
		break;
	case HW_VAR_SEC_DK_CFG:
	{
		struct security_priv *sec = &adapter->securitypriv;
		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);

		if (val) { /* Enable default key related setting */
			reg_scr |= SCR_TXBCUSEDK;
			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
				reg_scr |= (SCR_RxUseDK|SCR_TxUseDK);
		} else /* Disable default key related setting */
			reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK);

		rtw_write8(adapter, REG_SECCFG, reg_scr);
	}
		break;
	case HW_VAR_DM_FLAG:
		odm->SupportAbility = *((u32 *)val);
		break;
	case HW_VAR_DM_FUNC_OP:
		if (*((u8 *)val) == true) {
			/* save dm flag */
			odm->BK_SupportAbility = odm->SupportAbility;
		} else {
			/* restore dm flag */
			odm->SupportAbility = odm->BK_SupportAbility;
		}
		break;
	case HW_VAR_DM_FUNC_SET:
		if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) {
			struct dm_priv *dm = &hal_data->dmpriv;
			dm->DMFlag = dm->InitDMFlag;
			odm->SupportAbility = dm->InitODMFlag;
		} else {
			odm->SupportAbility |= *((u32 *)val);
		}
		break;
	case HW_VAR_DM_FUNC_CLR:
		/*
		* input is already a mask to clear function
		* don't invert it again! George, Lucas@20130513
		*/
		odm->SupportAbility &= *((u32 *)val);
		break;
	case HW_VAR_AMPDU_MIN_SPACE:
		/* TODO - Is something needed here? */
		break;
	case HW_VAR_WIRELESS_MODE:
		/* TODO - Is something needed here? */
		break;
	default:
		DBG_871X_LEVEL(
			_drv_always_,
			FUNC_ADPT_FMT" variable(%d) not defined!\n",
			FUNC_ADPT_ARG(adapter),
			variable
		);
		break;
	}
}
예제 #29
0
u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid)
{	
	_irqL irqL;	
	u8 status=_SUCCESS;
	u32 cur_time = 0;

	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
	
_func_enter_;
	
	DBG_871X_LEVEL(_drv_always_, "set bssid:%pM\n", bssid);

	if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) ||
	    (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF))
	{
		status = _FAIL;
		goto exit;
	}
		
	_enter_critical_bh(&pmlmepriv->lock, &irqL);


	DBG_871X("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
		goto handle_tkip_countermeasure;
	} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
		goto release_mlme_lock;
	}

	if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
	{
		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));

		if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE)
		{		
			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
				goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again.
		} else {
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same bssid\n"));
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid="MAC_FMT"\n", MAC_ARG(bssid) ));
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress) ));

			rtw_disassoc_cmd(padapter);

			if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
				rtw_indicate_disconnect(padapter);

			rtw_free_assoc_resources(padapter, 1);

			if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
			}		
		}
	}

handle_tkip_countermeasure:
	//should we add something here...?

#ifdef PLATFORM_LINUX
	if (padapter->securitypriv.btkip_countermeasure == _TRUE) {
		cur_time = rtw_get_current_time();

		if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ )
		{
			padapter->securitypriv.btkip_countermeasure = _FALSE;
			padapter->securitypriv.btkip_countermeasure_time = 0;
		}
		else
		{
			status = _FAIL;
			goto release_mlme_lock;
		}
	}
#endif

	_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
	pmlmepriv->assoc_by_bssid=_TRUE;

	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
		pmlmepriv->to_join = _TRUE;	
	}
	else {
		status = rtw_do_join(padapter);
	}

release_mlme_lock:
	_exit_critical_bh(&pmlmepriv->lock, &irqL);
		
exit:
	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
		("rtw_set_802_11_bssid: status=%d\n", status));
	
_func_exit_;

	return status;
}
예제 #30
0
u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid)
{	
	_irqL irqL;
	u8 status = _SUCCESS;
	u32 cur_time = 0;

	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
	struct wlan_network *pnetwork = &pmlmepriv->cur_network;
	
_func_enter_;
	
	DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state=0x%08x\n",
		       	ssid->Ssid, get_fwstate(pmlmepriv));

	if(padapter->hw_init_completed==_FALSE){
		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
			 ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n"));
		status = _FAIL;
		goto exit;
	}
		
	_enter_critical_bh(&pmlmepriv->lock, &irqL);

	DBG_871X("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {	
		goto handle_tkip_countermeasure;
	} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
		goto release_mlme_lock;
	}

	if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
	{
		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
			 ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));

		if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
		    (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE))
		{			
			if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE))
			{
				RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
					 ("Set SSID is the same ssid, fw_state=0x%08x\n",
					  get_fwstate(pmlmepriv)));

				if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE)
				{				
					//if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again
					rtw_disassoc_cmd(padapter);

					if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
						rtw_indicate_disconnect(padapter);
						
					rtw_free_assoc_resources(padapter, 1);

					if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
						_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
						set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
					}
				}
				else
				{
					goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again.
				}
			}
#ifdef CONFIG_LPS
			else {
				rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
			}
#endif
		}
		else
		{
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n"));
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength));

			rtw_disassoc_cmd(padapter);

			if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
				rtw_indicate_disconnect(padapter);
			
			rtw_free_assoc_resources(padapter, 1);

			if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
			}
		}		
	}

handle_tkip_countermeasure:
#ifdef PLATFORM_WINDOWS
	if (padapter->securitypriv.btkip_countermeasure==_TRUE)
	{
		LARGE_INTEGER	sys_time;
		u32  diff_time,cur_time ;
		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:padapter->securitypriv.btkip_countermeasure==_TRUE\n"));
		NdisGetCurrentSystemTime(&sys_time);	
		cur_time=(u32)(sys_time.QuadPart/10);  // In micro-second.
		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:cur_time=0x%x\n",cur_time));
		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:psecuritypriv->last_mic_err_time=0x%x\n",padapter->securitypriv.btkip_countermeasure_time));
		diff_time = cur_time -padapter->securitypriv.btkip_countermeasure_time; // In micro-second.
		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:diff_time=0x%x\n",diff_time));

		if (diff_time > 60000000) {
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time >60s.\n"));
			padapter->securitypriv.btkip_countermeasure=_FALSE;
			// Update MIC error time.
			padapter->securitypriv.btkip_countermeasure_time=0;
		} else {
			// can't join  in 60 seconds.
			status = _FAIL;
			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time <60s.\n"));
			goto release_mlme_lock;
		}
	}
#endif

#ifdef PLATFORM_LINUX
	if (padapter->securitypriv.btkip_countermeasure == _TRUE) {
		cur_time = rtw_get_current_time();

		if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ )
		{
			padapter->securitypriv.btkip_countermeasure = _FALSE;
			padapter->securitypriv.btkip_countermeasure_time = 0;
		}
		else
		{
			status = _FAIL;
			goto release_mlme_lock;
		}
	}
#endif

	#ifdef CONFIG_VALIDATE_SSID
	if (rtw_validate_ssid(ssid) == _FALSE) {
		status = _FAIL;
		goto release_mlme_lock;
	}
	#endif

	_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
	pmlmepriv->assoc_by_bssid=_FALSE;

	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
		pmlmepriv->to_join = _TRUE;	
	}
	else {
		status = rtw_do_join(padapter);
	}

release_mlme_lock:
	_exit_critical_bh(&pmlmepriv->lock, &irqL);

exit:
	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
		("-rtw_set_802_11_ssid: status=%d\n", status));
	
_func_exit_;

	return status;
	
}