/* * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend * @adapter: pointer to _adapter structure * @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup * Return _SUCCESS or _FAIL */ int _rtw_pwr_wakeup(struct rtw_adapter *padapter, u32 ips_deffer_ms, const char *caller) { struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; int ret = _SUCCESS; u32 start = rtw_get_current_time(); #ifdef CONFIG_CONCURRENT_MODE if (padapter->pbuddy_adapter) LeaveAllPowerSaveMode(padapter->pbuddy_adapter); if ((padapter->isprimary == false) && padapter->pbuddy_adapter) { padapter = padapter->pbuddy_adapter; pwrpriv = &padapter->pwrctrlpriv; pmlmepriv = &padapter->mlmepriv; } #endif if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms)) pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms); if (pwrpriv->ps_processing) { DBG_8192D("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) rtw_msleep_os(10); if (pwrpriv->ps_processing) DBG_8192D("%s wait ps_processing timeout\n", __func__); else DBG_8192D("%s wait ps_processing done\n", __func__); } if (pwrpriv->bInternalAutoSuspend == false && pwrpriv->bInSuspend) { DBG_8192D("%s wait bInSuspend...\n", __func__); while (pwrpriv->bInSuspend && ((rtw_get_passing_time_ms(start) <= 3000 && !rtw_is_do_late_resume(pwrpriv)) || (rtw_get_passing_time_ms(start) <= 500 && rtw_is_do_late_resume(pwrpriv)))) { rtw_msleep_os(10); } if (pwrpriv->bInSuspend) DBG_8192D("%s wait bInSuspend timeout\n", __func__); else DBG_8192D("%s wait bInSuspend done\n", __func__); } /* System suspend is not allowed to wakeup */ if ((pwrpriv->bInternalAutoSuspend == false) && (true == pwrpriv->bInSuspend)) { ret = _FAIL; goto exit; } /* block??? */ if ((pwrpriv->bInternalAutoSuspend == true) && (padapter->net_closed == true)) { ret = _FAIL; goto exit; } /* I think this should be check in IPS, LPS, autosuspend functions... */ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { ret = _SUCCESS; goto exit; } if (rf_off == pwrpriv->rf_pwrstate) { #ifdef CONFIG_AUTOSUSPEND if (pwrpriv->brfoffbyhw == true) { DBG_8192D("hw still in rf_off state ...........\n"); ret = _FAIL; goto exit; } else if (padapter->registrypriv.usbss_enable) { DBG_8192D("%s call autoresume_enter....\n", __func__); if (_FAIL == autoresume_enter(padapter)) { DBG_8192D ("======> autoresume fail.............\n"); ret = _FAIL; goto exit; } } else #endif { #ifdef CONFIG_IPS DBG_8192D("%s call ips_leave....\n", __func__); if (_FAIL == ips_leave(padapter)) { DBG_8192D ("======> ips_leave fail.............\n"); ret = _FAIL; goto exit; } #endif } } /* TODO: the following checking need to be merged... */ if (padapter->bDriverStopped || !padapter->bup || !padapter->hw_init_completed) { DBG_8192D ("%s: bDriverStopped=%d, bup=%d, hw_init_completed=%u\n", caller, padapter->bDriverStopped, padapter->bup, padapter->hw_init_completed); ret = false; goto exit; } exit: if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms)) pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms); return ret; }
u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid) { _irqL irqL; u8 status = _TRUE; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; _queue *queue = &pmlmepriv->scanned_queue; #ifdef PLATFORM_WINDOWS LARGE_INTEGER sys_time; u32 diff_time,cur_time ; #endif _func_enter_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, ("+rtw_set_802_11_ssid: 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")); return _FALSE; } _enter_critical_bh(&pmlmepriv->lock, &irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is not allowed under surveying || adhoc master || under linking\n")); status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); goto _Abort_Set_SSID; } 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); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else { goto _Abort_Set_SSID;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } } #ifdef CONFIG_LPS else { 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); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } #ifdef PLATFORM_WINDOWS if (padapter->securitypriv.btkip_countermeasure==_TRUE) { 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 = _FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time <60s.\n")); goto _Abort_Set_SSID; } } #endif #ifdef PLATFORM_LINUX if (padapter->securitypriv.btkip_countermeasure == _TRUE) { status = _FALSE; goto _Abort_Set_SSID; } #endif if (rtw_validate_ssid(ssid) == _FALSE) { status = _FALSE; goto _Abort_Set_SSID; } _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); pmlmepriv->assoc_by_bssid=_FALSE; status = do_join(padapter); goto done; _Abort_Set_SSID: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("-rtw_set_802_11_ssid: _Abort_Set_SSID: status=%d\n", status)); done: _exit_critical_bh(&pmlmepriv->lock, &irqL); _func_exit_; return status; }
static u8 do_join(_adapter * padapter) { _list *plist, *phead; u8* pibss = NULL; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); _queue *queue = &(pmlmepriv->scanned_queue); u8 ret=_TRUE; phead = get_list_head(queue); plist = get_next(phead); _func_enter_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("\n do_join: phead = %p; plist = %p \n\n\n", phead, plist)); pmlmepriv->cur_network.join_res = -2; pmlmepriv->fw_state |= _FW_UNDER_LINKING; pmlmepriv->pscanned = plist; pmlmepriv->to_join = _TRUE; if(_rtw_queue_empty(queue)== _TRUE) { if(pmlmepriv->fw_state & _FW_UNDER_LINKING) pmlmepriv->fw_state ^= _FW_UNDER_LINKING; //when set_ssid/set_bssid for do_join(), but scanning queue is empty //we try to issue sitesurvey firstly if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE) { // submit site_survey_cmd rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("do_join(): site survey if scanned_queue is empty\n.")); } //ret=_FALSE; goto exit; } else { int ret; if((ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS) { _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); } #if 0 else if(ret == 2) { DBG_8712("*****UNDER_LINKED WITH SAME NETWORK, RETURN*****\n"); if(pmlmepriv->fw_state & _FW_UNDER_LINKING) pmlmepriv->fw_state ^= _FW_UNDER_LINKING; } #endif else { if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) { // submit rtw_createbss_cmd to change to a ADHOC_MASTER //pmlmepriv->lock has been acquired by caller... WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network); pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; pibss = padapter->registrypriv.dev_network.MacAddress; _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); rtw_update_registrypriv_dev_network(padapter); rtw_generate_random_ibss(pibss); if(rtw_createbss_cmd(padapter)!=_SUCCESS) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>do_goin: rtw_createbss_cmd status FAIL*** \n ")); return _FALSE; } pmlmepriv->to_join = _FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("***Error=> rtw_select_and_join_from_scanned_queue FAIL under STA_Mode*** \n ")); } else { // can't associate ; reset under-linking if(pmlmepriv->fw_state & _FW_UNDER_LINKING) pmlmepriv->fw_state ^= _FW_UNDER_LINKING; #if 0 if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) { if(_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) { // for funk to do roaming // funk will reconnect, but funk will not sitesurvey before reconnect RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("for funk to do roaming")); if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE) rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); } } #endif //when set_ssid/set_bssid for do_join(), but there are no desired bss in scanning queue //we try to issue sitesurvey firstly if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE) { //printk("do_join() when no desired bss in scanning queue \n"); rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); } } } } exit: _func_exit_; return ret; }
/* * 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=NULL; //_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.DataRate = pattrib->data_rate; //rtl8723b_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; rtl8723b_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; } } rtl8723b_process_phy_info(padapter, precvframe); } }
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) { u8 reg_value_1 = 0; u8 reg_value_2 = 0; u8 reg_value_3 = 0; 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]); //try to recover the transmission reg_value_1 = rtw_read8(padapter, REG_SYS_FUNC_EN); reg_value_2 = rtw_read8(padapter, REG_CR); reg_value_3 = rtw_read8(padapter, REG_TXPAUSE); DBG_871X("Before recovery: REG_SYS_FUNC_EN = 0x%X, REG_CR = 0x%X, REG_TXPAUSE = 0x%X\n", reg_value_1, reg_value_2, reg_value_3); rtw_write8(padapter, REG_SYS_FUNC_EN, reg_value_1 | 0x01); rtw_write8(padapter, REG_CR, reg_value_2 | 0xC0); rtw_write8(padapter, REG_TXPAUSE, 0); DBG_871X("After recovery: REG_SYS_FUNC_EN = 0x%X, REG_CR = 0x%X, REG_TXPAUSE = 0x%X\n", rtw_read8(padapter, REG_SYS_FUNC_EN), rtw_read8(padapter, REG_CR), rtw_read8(padapter, REG_TXPAUSE)); } 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[PUBLIC_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; }
// // Description: // Perform interrupt migration dynamically to reduce CPU utilization. // // Assumption: // 1. Do not enable migration under WIFI test. // // Created by Roger, 2010.03.05. // VOID dm_InterruptMigration( IN PADAPTER Adapter ) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); BOOLEAN bCurrentIntMt, bCurrentACIntDisable; BOOLEAN IntMtToSet = _FALSE; BOOLEAN ACIntToSet = _FALSE; // Retrieve current interrupt migration and Tx four ACs IMR settings first. bCurrentIntMt = pHalData->bInterruptMigration; bCurrentACIntDisable = pHalData->bDisableTxInt; // // <Roger_Notes> Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics // when interrupt migration is set before. 2010.03.05. // if(!Adapter->registrypriv.wifi_spec && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && pmlmepriv->LinkDetectInfo.bHigherBusyTraffic) { IntMtToSet = _TRUE; // To check whether we should disable Tx interrupt or not. if(pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic ) ACIntToSet = _TRUE; } //Update current settings. if( bCurrentIntMt != IntMtToSet ){ DBG_8192C("%s(): Update interrrupt migration(%d)\n",__FUNCTION__,IntMtToSet); if(IntMtToSet) { // // <Roger_Notes> Set interrrupt migration timer and corresponging Tx/Rx counter. // timer 25ns*0xfa0=100us for 0xf packets. // 2010.03.05. // rtw_write32(Adapter, REG_INT_MIG, 0xff000fa0);// 0x306:Rx, 0x307:Tx pHalData->bInterruptMigration = IntMtToSet; } else { // Reset all interrupt migration settings. rtw_write32(Adapter, REG_INT_MIG, 0); pHalData->bInterruptMigration = IntMtToSet; } } /*if( bCurrentACIntDisable != ACIntToSet ){ DBG_8192C("%s(): Update AC interrrupt(%d)\n",__FUNCTION__,ACIntToSet); if(ACIntToSet) // Disable four ACs interrupts. { // // <Roger_Notes> Disable VO, VI, BE and BK four AC interrupts to gain more efficient CPU utilization. // When extremely highly Rx OK occurs, we will disable Tx interrupts. // 2010.03.05. // UpdateInterruptMask8192CE( Adapter, 0, RT_AC_INT_MASKS ); pHalData->bDisableTxInt = ACIntToSet; } else// Enable four ACs interrupts. { UpdateInterruptMask8192CE( Adapter, RT_AC_INT_MASKS, 0 ); pHalData->bDisableTxInt = ACIntToSet; } }*/ }
static void rtl8723bs_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) { DBG_8192C("%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(padapter, 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 !(MP_DRIVER==1) DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__); #endif rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); break; } rx_report_sz = RXDESC_SIZE + pattrib->drvinfo_sz; pkt_offset = rx_report_sz + pattrib->shift_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)) { #ifdef CONFIG_MP_INCLUDED if (padapter->registrypriv.mp_mode == 1) { if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0)) { if (pattrib->crc_err == 1) padapter->mppriv.rx_crcerrpktcount++; } } #endif 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 + pattrib->shift_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("%s: alloc_skb fail, drop frag frame\n", __FUNCTION__); 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 + pattrib->shift_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("%s: rtw_skb_clone fail\n", __FUNCTION__); 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_C2H_PACKET_EN if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet { #endif #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_dump_, ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",__FUNCTION__)); } } #ifdef CONFIG_C2H_PACKET_EN } else if(pattrib->pkt_rpt_type == C2H_PACKET) { C2H_EVT_HDR C2hEvent; u16 len_c2h = pattrib->pkt_len; u8 *pbuf_c2h = precvframe->u.hdr.rx_data; u8 *pdata_c2h; C2hEvent.CmdID = pbuf_c2h[0]; C2hEvent.CmdSeq = pbuf_c2h[1]; C2hEvent.CmdLen = (len_c2h -2); pdata_c2h = pbuf_c2h+2; if(C2hEvent.CmdID == C2H_CCX_TX_RPT) { CCX_FwC2HTxRpt_8723b(padapter, pdata_c2h, C2hEvent.CmdLen); } else { rtl8723bs_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len); } rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); } #endif } pkt_offset = _RND8(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); }
/* ALPHA, added by chiyoko, 20090106 */ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); struct LED_871x *pLed = &(ledpriv->SwLed0); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); switch (LedAction) { case LED_CTL_POWER_ON: case LED_CTL_START_TO_LINK: case LED_CTL_NO_LINK: if (!pLed->bLedNoLinkBlinkInProgress) { if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); } break; case LED_CTL_LINK: if (!pLed->bLedLinkBlinkInProgress) { if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); } break; case LED_CTL_SITE_SURVEY: if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ; } else if (!pLed->bLedScanBlinkInProgress) { if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SCAN; pLed->BlinkTimes = 24; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_TX: case LED_CTL_RX: if (!pLed->bLedBlinkInProgress) { if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_TXRX; pLed->BlinkTimes = 2; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_CTL_START_WPS: /* wait until xinpin finish */ case LED_CTL_START_WPS_BOTTON: if (!pLed->bLedWPSBlinkInProgress) { if (pLed->bLedNoLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_STOP_WPS: if (pLed->bLedNoLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) del_timer_sync(&(pLed->BlinkTimer)); else pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS_STOP; if (pLed->bLedOn) { pLed->BlinkingLedState = RTW_LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA); } else { pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), 0); } break; case LED_CTL_STOP_WPS_FAIL: if (pLed->bLedWPSBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); break; case LED_CTL_POWER_OFF: pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; if (pLed->bLedNoLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { del_timer_sync(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } SwLedOff(padapter, pLed); break; default: break; } RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState)); }
static void SwLedBlink1(struct LED_871x *pLed) { struct adapter *padapter = pLed->padapter; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == RTW_LED_ON) { SwLedOn(padapter, pLed); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); } else { SwLedOff(padapter, pLed); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); } if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { SwLedOff(padapter, pLed); ResetLedStatus(pLed); return; } switch (pLed->CurrLedState) { case LED_BLINK_SLOWLY: if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); break; case LED_BLINK_NORMAL: if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); break; case LED_BLINK_SCAN: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); } pLed->bLedScanBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_BLINK_TXRX: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); } pLed->BlinkTimes = 0; pLed->bLedBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_BLINK_WPS: if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); break; case LED_BLINK_WPS_STOP: /* WPS success */ if (pLed->BlinkingLedState == RTW_LED_ON) bStopBlinking = false; else bStopBlinking = true; if (bStopBlinking) { pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else pLed->BlinkingLedState = RTW_LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); pLed->bLedWPSBlinkInProgress = false; } else { pLed->BlinkingLedState = RTW_LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA); } break; default: break; } }
VOID rtl8723a_HalDmWatchDog( IN PADAPTER Adapter ) { BOOLEAN bFwCurrentInPSMode = _FALSE; BOOLEAN bFwPSAwake = _TRUE; u8 hw_init_completed = _FALSE; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; #ifdef CONFIG_CONCURRENT_MODE PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; #endif //CONFIG_CONCURRENT_MODE hw_init_completed = Adapter->hw_init_completed; if (hw_init_completed == _FALSE) goto skip_dm; #ifdef CONFIG_LPS #ifdef CONFIG_CONCURRENT_MODE if (Adapter->iface_type != IFACE_PORT0 && pbuddy_adapter) { bFwCurrentInPSMode = pbuddy_adapter->pwrctrlpriv.bFwCurrentInPSMode; rtw_hal_get_hwreg(pbuddy_adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); } else #endif //CONFIG_CONCURRENT_MODE { bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode; rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); } #endif #ifdef CONFIG_P2P_PS // Fw is under p2p powersaving mode, driver should stop dynamic mechanism. // modifed by thomas. 2011.06.11. if(Adapter->wdinfo.p2p_ps_mode) bFwPSAwake = _FALSE; #endif //CONFIG_P2P_PS if( (hw_init_completed == _TRUE) && ((!bFwCurrentInPSMode) && bFwPSAwake)) { // // Calculate Tx/Rx statistics. // dm_CheckStatistics(Adapter); #ifdef CONFIG_CONCURRENT_MODE if(Adapter->adapter_type > PRIMARY_ADAPTER) goto _record_initrate; #endif // // Dynamically switch RTS/CTS protection. // //dm_CheckProtection(Adapter); #ifdef CONFIG_PCI_HCI // 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput. // Tx Migration settings. //dm_InterruptMigration(Adapter); //if(Adapter->HalFunc.TxCheckStuckHandler(Adapter)) // PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem)); #endif _record_initrate: // Read REG_INIDATA_RATE_SEL value for TXDESC. if(check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) { pdmpriv->INIDATA_RATE[0] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f; } else { u8 i; for(i=1 ; i < (Adapter->stapriv.asoc_sta_count + 1); i++) { pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f; } } } //ODM if (hw_init_completed == _TRUE) { u8 bLinked=_FALSE; #ifdef CONFIG_DISABLE_ODM pHalData->odmpriv.SupportAbility = 0; #endif if(rtw_linked_check(Adapter)) bLinked = _TRUE; #ifdef CONFIG_CONCURRENT_MODE if(pbuddy_adapter && rtw_linked_check(pbuddy_adapter)) bLinked = _TRUE; #endif //CONFIG_CONCURRENT_MODE ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked); ODM_DMWatchdog(&pHalData->odmpriv); } skip_dm: // Check GPIO to determine current RF on/off and Pbc status. // Check Hardware Radio ON/OFF or not #ifdef CONFIG_PCI_HCI if(pHalData->bGpioHwWpsPbc) #endif { dm_CheckPbcGPIO(Adapter); // Add by hpfan 2008-03-11 } }
int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) { _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; #ifdef CONFIG_TX_MCAST2UNI struct mlme_priv *pmlmepriv = &padapter->mlmepriv; extern int rtw_mc2u_disable; #endif // CONFIG_TX_MCAST2UNI s32 res = 0; #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) u16 queue; #endif _func_enter_; RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("+xmit_enry\n")); if (rtw_if_up(padapter) == _FALSE) { RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit_entry: rtw_if_up fail\n")); #ifdef DBG_TX_DROP_FRAME DBG_871X("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__); #endif goto drop_packet; } rtw_check_xmit_resource(padapter, pkt); #ifdef CONFIG_TX_MCAST2UNI if ( !rtw_mc2u_disable && check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && ( IP_MCAST_MAC(pkt->data) || ICMPV6_MCAST_MAC(pkt->data) ) && (padapter->registrypriv.wifi_spec == 0) ) { if ( pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME/4) ) { res = rtw_mlcst2unicst(padapter, pkt); if (res == _TRUE) { goto exit; } } else { //DBG_871X("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt); //DBG_871X("!m2u ); } } #endif // CONFIG_TX_MCAST2UNI res = rtw_xmit(padapter, &pkt); if (res < 0) { #ifdef DBG_TX_DROP_FRAME DBG_871X("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__); #endif goto drop_packet; } RT_TRACE(_module_xmit_osdep_c_, _drv_info_, ("rtw_xmit_entry: tx_pkts=%d\n", (u32)pxmitpriv->tx_pkts)); goto exit; drop_packet: pxmitpriv->tx_drop++; rtw_skb_free(pkt); RT_TRACE(_module_xmit_osdep_c_, _drv_notice_, ("rtw_xmit_entry: drop, tx_drop=%d\n", (u32)pxmitpriv->tx_drop)); exit: _func_exit_; return 0; }
int _rtw_pwr_wakeup(struct rtl_priv *rtlpriv, uint32_t ips_deffer_ms, const char *caller) { struct pwrctrl_priv *pwrpriv = &rtlpriv->pwrctrlpriv; struct mlme_priv *pmlmepriv = &rtlpriv->mlmepriv; int ret = _SUCCESS; uint32_t start = jiffies; if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); if (pwrpriv->ps_processing) { DBG_871X("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) msleep(10); if (pwrpriv->ps_processing) DBG_871X("%s wait ps_processing timeout\n", __func__); else DBG_871X("%s wait ps_processing done\n", __func__); } if (pwrpriv->bInternalAutoSuspend == _FALSE && pwrpriv->bInSuspend) { DBG_871X("%s wait bInSuspend...\n", __func__); while (pwrpriv->bInSuspend && ((rtw_get_passing_time_ms(start) <= 3000) || (rtw_get_passing_time_ms(start) <= 500)) ) { msleep(10); } if (pwrpriv->bInSuspend) DBG_871X("%s wait bInSuspend timeout\n", __func__); else DBG_871X("%s wait bInSuspend done\n", __func__); } //System suspend is not allowed to wakeup if ((pwrpriv->bInternalAutoSuspend == _FALSE) && (_TRUE == pwrpriv->bInSuspend )){ ret = _FAIL; goto exit; } //block??? if ((pwrpriv->bInternalAutoSuspend == _TRUE) && (rtlpriv->net_closed == _TRUE)) { ret = _FAIL; goto exit; } //I think this should be check in IPS, LPS, autosuspend functions... if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { ret = _SUCCESS; goto exit; } if (rf_off == pwrpriv->rf_pwrstate ) { #ifdef CONFIG_AUTOSUSPEND if (pwrpriv->brfoffbyhw==_TRUE) { DBG_8192C("hw still in rf_off state ...........\n"); ret = _FAIL; goto exit; } else if (rtlpriv->registrypriv.usbss_enable) { DBG_8192C("%s call autoresume_enter....\n",__FUNCTION__); if (_FAIL == autoresume_enter(rtlpriv)) { DBG_8192C("======> autoresume fail.............\n"); ret = _FAIL; goto exit; } } else #endif { DBG_8192C("%s call ips_leave....\n",__FUNCTION__); if (_FAIL == rtw_ips_leave(rtlpriv)) { DBG_8192C("======> ips_leave fail.............\n"); ret = _FAIL; goto exit; } } } //TODO: the following checking need to be merged... if (rtlpriv->bDriverStopped || !rtlpriv->bup || !rtlpriv->hw_init_completed ){ DBG_8192C("%s: bDriverStopped=%d, bup=%d, hw_init_completed=%u\n" , caller , rtlpriv->bDriverStopped , rtlpriv->bup , rtlpriv->hw_init_completed); ret= _FALSE; goto exit; } exit: if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); return ret; }
u8 joinbss_cmd(_adapter *padapter, struct wlan_network* pnetwork) { u8 *auth, res=_SUCCESS; uint t_len=0; NDIS_WLAN_BSSID_EX *psecnetwork; struct cmd_obj* pcmd; struct cmd_priv *pcmdpriv=&padapter->cmdpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct qos_priv *pqospriv= &pmlmepriv->qospriv; struct security_priv *psecuritypriv=&padapter->securitypriv; struct registry_priv *pregistrypriv = &padapter->registrypriv; NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode; _func_enter_; if (pmlmepriv->assoc_ssid.SsidLength == 0){ RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("@@@@@ Join cmd for Any SSid\n")); } else{ RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("@@@@@ Join cmd for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); } pcmd = (struct cmd_obj*)_malloc(sizeof(struct cmd_obj)); if(pcmd==NULL){ res=_FAIL; RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("\n joinbss_cmd :memory allocate for cmd_obj fail!!!\n")); goto exit; } t_len = sizeof (ULONG) + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + sizeof (NDIS_802_11_SSID) + sizeof (ULONG) + sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + sizeof (NDIS_802_11_CONFIGURATION) + sizeof (NDIS_802_11_NETWORK_INFRASTRUCTURE) + sizeof (NDIS_802_11_RATES_EX)+ sizeof (ULONG) + MAX_IE_SZ; //for hidden ap to set fw_state here if(check_fwstate(pmlmepriv, (WIFI_STATION_STATE|WIFI_ADHOC_STATE))!= _TRUE) { switch(ndis_network_mode) { case Ndis802_11IBSS: pmlmepriv->fw_state |=WIFI_ADHOC_STATE; break; case Ndis802_11Infrastructure: pmlmepriv->fw_state |= WIFI_STATION_STATE; break; case Ndis802_11APMode: case Ndis802_11AutoUnknown: case Ndis802_11InfrastructureMax: break; } } psecnetwork=(NDIS_WLAN_BSSID_EX *)&psecuritypriv->sec_bss; if(psecnetwork==NULL) { if(pcmd !=NULL) _mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); res=_FAIL; RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("\n joinbss_cmd :psecnetwork==NULL!!!\n")); goto exit; } _memset(psecnetwork, 0, t_len); _memcpy(psecnetwork, &pnetwork->network, t_len); auth=&psecuritypriv->authenticator_ie[0]; psecuritypriv->authenticator_ie[0]=(unsigned char)psecnetwork->IELength; if((psecnetwork->IELength-12) < (256-1)) { _memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12); } else { _memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1)); } psecnetwork->IELength = 0; // Added by Albert 2009/02/18 // If the the driver wants to use the bssid to create the connection. // If not, we have to copy the connecting AP's MAC address to it so that // the driver just has the bssid information for PMKIDList searching. if ( pmlmepriv->assoc_by_bssid == _FALSE ) { _memcpy( &pmlmepriv->assoc_bssid[ 0 ], &pnetwork->network.MacAddress[ 0 ], ETH_ALEN ); } psecnetwork->IELength = restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength); pqospriv->qos_option = 0; if(pregistrypriv->wmm_enable) { u32 tmp_len; tmp_len = restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength); if (psecnetwork->IELength != tmp_len) { psecnetwork->IELength = tmp_len; pqospriv->qos_option = 1; //There is WMM IE in this corresp. beacon } else { pqospriv->qos_option = 0;//There is no WMM IE in this corresp. beacon } } #ifdef CONFIG_80211N_HT if(pregistrypriv->ht_enable) { //restructure_ht_ie restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, &psecnetwork->IELength); } #endif psecuritypriv->supplicant_ie[0]=(u8)psecnetwork->IELength; if(psecnetwork->IELength < (256-1)) { _memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], psecnetwork->IELength); } else { _memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], (256-1)); } pcmd->cmdsz = (get_NDIS_WLAN_BSSID_EX_sz(psecnetwork));//get cmdsz before endian conversion //wlan_network endian conversion psecnetwork->Length = cpu_to_le32(psecnetwork->Length); psecnetwork->Ssid.SsidLength= cpu_to_le32(psecnetwork->Ssid.SsidLength); psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy); psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi); psecnetwork->NetworkTypeInUse = cpu_to_le32(psecnetwork->NetworkTypeInUse); psecnetwork->Configuration.ATIMWindow = cpu_to_le32(psecnetwork->Configuration.ATIMWindow); psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(psecnetwork->Configuration.BeaconPeriod); psecnetwork->Configuration.DSConfig = cpu_to_le32(psecnetwork->Configuration.DSConfig); psecnetwork->Configuration.FHConfig.DwellTime=cpu_to_le32(psecnetwork->Configuration.FHConfig.DwellTime); psecnetwork->Configuration.FHConfig.HopPattern=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopPattern); psecnetwork->Configuration.FHConfig.HopSet=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopSet); psecnetwork->Configuration.FHConfig.Length=cpu_to_le32(psecnetwork->Configuration.FHConfig.Length); psecnetwork->Configuration.Length = cpu_to_le32(psecnetwork->Configuration.Length); psecnetwork->InfrastructureMode = cpu_to_le32(psecnetwork->InfrastructureMode); psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength); _init_listhead(&pcmd->list); pcmd->cmdcode = _JoinBss_CMD_; pcmd->parmbuf = (unsigned char *)psecnetwork; pcmd->rsp = NULL; pcmd->rspsz = 0; enqueue_cmd(pcmdpriv, pcmd); exit: _func_exit_; return res; }
u8 setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key) { struct cmd_obj* ph2c; struct set_stakey_parm *psetstakey_para; struct cmd_priv *pcmdpriv=&padapter->cmdpriv; struct set_stakey_rsp *psetstakey_rsp = NULL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct sta_info* sta = (struct sta_info* )psta; u8 res=_SUCCESS; _func_enter_; ph2c = (struct cmd_obj*)_malloc(sizeof(struct cmd_obj)); if ( ph2c == NULL){ res= _FAIL; goto exit; } psetstakey_para = (struct set_stakey_parm*)_malloc(sizeof(struct set_stakey_parm)); if(psetstakey_para==NULL){ _mfree((u8 *) ph2c, sizeof(struct cmd_obj)); res=_FAIL; goto exit; } psetstakey_rsp = (struct set_stakey_rsp*)_malloc(sizeof(struct set_stakey_rsp)); if(psetstakey_rsp == NULL){ _mfree((u8 *) ph2c, sizeof(struct cmd_obj)); _mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); res=_FAIL; goto exit; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); ph2c->rsp = (u8 *) psetstakey_rsp; ph2c->rspsz = sizeof(struct set_stakey_rsp); _memcpy(psetstakey_para->addr, sta->hwaddr,ETH_ALEN); if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)) psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm; else GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE); if(unicast_key == _TRUE) { _memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); } else { _memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid-1].skey, 16); } enqueue_cmd(pcmdpriv, ph2c); exit: _func_exit_; return res; }
/* * Return * _TRUE dump packet directly * _FALSE enqueue packet */ static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe) { _irqL irqL; s32 res; struct xmit_buf *pxmitbuf = NULL; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct pkt_attrib *pattrib = &pxmitframe->attrib; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; #ifdef CONFIG_CONCURRENT_MODE PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); #endif _enter_critical_bh(&pxmitpriv->lock, &irqL); //DBG_8192C("==> %s \n",__FUNCTION__); if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) { //DBG_8192C("enqueue AC(%d)\n",pattrib->priority); goto enqueue; } if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) goto enqueue; #ifdef CONFIG_CONCURRENT_MODE if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) goto enqueue; #endif pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); if (pxmitbuf == NULL) goto enqueue; _exit_critical_bh(&pxmitpriv->lock, &irqL); pxmitframe->pxmitbuf = pxmitbuf; pxmitframe->buf_addr = pxmitbuf->pbuf; pxmitbuf->priv_data = pxmitframe; if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) { rtw_free_xmitbuf(pxmitpriv, pxmitbuf); rtw_free_xmitframe(pxmitpriv, pxmitframe); } return _TRUE; enqueue: res = rtw_xmitframe_enqueue(padapter, pxmitframe); _exit_critical_bh(&pxmitpriv->lock, &irqL); if (res != _SUCCESS) { RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n")); rtw_free_xmitframe(pxmitpriv, pxmitframe); // Trick, make the statistics correct pxmitpriv->tx_pkts--; pxmitpriv->tx_drop++; return _TRUE; } return _FALSE; }
static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) { int pull=0; uint qsel; _adapter *padapter = pxmitframe->padapter; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; #ifdef CONFIG_AP_MODE struct mlme_priv *pmlmepriv = &padapter->mlmepriv; #endif //CONFIG_AP_MODE struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct pkt_attrib *pattrib = &pxmitframe->attrib; struct tx_desc *ptxdesc = (struct tx_desc *)pmem; sint bmcst = IS_MCAST(pattrib->ra); #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &padapter->wdinfo; struct registry_priv *pregistrypriv = &padapter->registrypriv; #endif //CONFIG_P2P #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX if (padapter->registrypriv.mp_mode == 0) { if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0)) { ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ); pull = 1; pxmitframe->pkt_offset --; } } #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc)); 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 //Insert Early Mode Content after tx desc position. if((pHalData->bEarlyModeEnable) && (_TRUE == bagg_pkt)){ ptxdesc->txdw0 |= cpu_to_le32(((USB_HWDESC_HEADER_LEN-8) << OFFSET_SHT) & 0x00ff0000);//32 bytes for TX Desc if(pxmitframe->EMPktNum > 0){ InsertEMContent(pxmitframe, pmem+TXDESC_SIZE); } } } 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)); } #ifdef CONFIG_P2P if(pregistrypriv->wifi_spec==1 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate ptxdesc->txdw5 = cpu_to_le32(0x0001ff00);// ptxdesc->txdw5 |= cpu_to_le32(BIT(2));// use OFDM 6Mbps } #endif //CONFIG_P2P //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 #ifdef CONFIG_XMIT_ACK //CCX-TXRPT ack for xmit mgmt frames. if (pxmitframe->ack_report) { ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); #ifdef DBG_CCX DBG_871X("%s set ccx\n", __func__); #endif } #endif //CONFIG_XMIT_ACK //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 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable #ifdef CONFIG_P2P if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ptxdesc->txdw5 |= cpu_to_le32(0x00080000);//retry limit = 2 } else #endif //CONFIG_P2P 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)); } // 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 ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff); ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//32 bytes for TX Desc if(bmcst) { ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); } RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0)); //offset 4 // pkt_offset, unit:8 bytes padding if (pxmitframe->pkt_offset > 0) ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); #ifdef CONFIG_USB_TX_AGGREGATION if (pxmitframe->agg_num > 1) ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000); #endif rtl8192du_cal_txdesc_chksum(ptxdesc); return pull; }
static int rtw_gspi_suspend(struct spi_device *spi, pm_message_t mesg) { struct dvobj_priv *dvobj = spi_get_drvdata(spi); PADAPTER padapter = dvobj->if1; struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct net_device *pnetdev = padapter->pnetdev; int ret = 0; u32 start_time = rtw_get_current_time(); _func_enter_; DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); pwrpriv->bInSuspend = _TRUE; while (pwrpriv->bips_processing == _TRUE) rtw_msleep_os(1); if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved)) { DBG_871X("%s bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", __FUNCTION__ ,padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved); goto exit; } rtw_cancel_all_timer(padapter); LeaveAllPowerSaveMode(padapter); //padapter->net_closed = _TRUE; //s1. if(pnetdev) { netif_carrier_off(pnetdev); rtw_netif_stop_queue(pnetdev); } #ifdef CONFIG_WOWLAN padapter->pwrctrlpriv.bSupportRemoteWakeup=_TRUE; #else //s2. //s2-1. issue rtw_disassoc_cmd to fw disconnect_hdl(padapter, NULL); //rtw_disassoc_cmd(padapter); #endif #ifdef CONFIG_LAYER2_ROAMING_RESUME if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) ) { DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__, pmlmepriv->cur_network.network.Ssid.Ssid, MAC_ARG(pmlmepriv->cur_network.network.MacAddress), pmlmepriv->cur_network.network.Ssid.SsidLength, pmlmepriv->assoc_ssid.SsidLength); pmlmepriv->to_roaming = 1; } #endif //s2-2. indicate disconnect to os rtw_indicate_disconnect(padapter); //s2-3. rtw_free_assoc_resources(padapter, 1); //s2-4. rtw_free_network_queue(padapter, _TRUE); rtw_led_control(padapter, LED_CTL_POWER_OFF); rtw_dev_unload(padapter); if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) rtw_indicate_scan_done(padapter, 1); if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) rtw_indicate_disconnect(padapter); // interface deinit gspi_deinit(dvobj); RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("%s: deinit GSPI complete!\n", __FUNCTION__)); rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_OFF); rtw_mdelay_os(1); exit: DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__ , ret, rtw_get_passing_time_ms(start_time)); _func_exit_; return ret; }
static void FindMinimumRSSI_8723b( IN PADAPTER pAdapter ) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; //1 1.Determine the minimum RSSI #ifdef CONFIG_CONCURRENT_MODE // FindMinimumRSSI() per-adapter { PADAPTER pbuddy_adapter = pAdapter->pbuddy_adapter; PHAL_DATA_TYPE pbuddy_HalData = GET_HAL_DATA(pbuddy_adapter); struct dm_priv *pbuddy_dmpriv = &pbuddy_HalData->dmpriv; if((pdmpriv->EntryMinUndecoratedSmoothedPWDB != 0) && (pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB != 0)) { if(pdmpriv->EntryMinUndecoratedSmoothedPWDB > pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB) pdmpriv->EntryMinUndecoratedSmoothedPWDB = pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB; } else { if(pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0) pdmpriv->EntryMinUndecoratedSmoothedPWDB = pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB; } #if 0 if((pdmpriv->UndecoratedSmoothedPWDB != (-1)) && (pbuddy_dmpriv->UndecoratedSmoothedPWDB != (-1))) { if((pdmpriv->UndecoratedSmoothedPWDB > pbuddy_dmpriv->UndecoratedSmoothedPWDB) && (pbuddy_dmpriv->UndecoratedSmoothedPWDB!=0)) pdmpriv->UndecoratedSmoothedPWDB = pbuddy_dmpriv->UndecoratedSmoothedPWDB; } else { if((pdmpriv->UndecoratedSmoothedPWDB == (-1)) && (pbuddy_dmpriv->UndecoratedSmoothedPWDB!=0)) pdmpriv->UndecoratedSmoothedPWDB = pbuddy_dmpriv->UndecoratedSmoothedPWDB; } #endif } #endif if((check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) && (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) { pdmpriv->MinUndecoratedPWDBForDM = 0; //ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("Not connected to any \n")); } if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) // Default port { #if 0 if((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) { pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; //ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("AP Client PWDB = 0x%x \n", pHalData->MinUndecoratedPWDBForDM)); } else//for STA mode { pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->UndecoratedSmoothedPWDB; //ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("STA Default Port PWDB = 0x%x \n", pHalData->MinUndecoratedPWDBForDM)); } #else pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; #endif } else // associated entry pwdb { pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; //ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("AP Ext Port or disconnet PWDB = 0x%x \n", pHalData->MinUndecoratedPWDBForDM)); } //odm_FindMinimumRSSI_Dmsp(pAdapter); //DBG_8192C("%s=>MinUndecoratedPWDBForDM(%d)\n",__FUNCTION__,pdmpriv->MinUndecoratedPWDBForDM); //ODM_RT_TRACE(pDM_Odm,COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",pHalData->MinUndecoratedPWDBForDM)); }
VOID rtl8723b_HalDmWatchDog( IN PADAPTER Adapter ) { BOOLEAN bFwCurrentInPSMode = _FALSE; BOOLEAN bFwPSAwake = _TRUE; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); #ifdef CONFIG_CONCURRENT_MODE PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; #endif //CONFIG_CONCURRENT_MODE //#if MP_DRIVER if (Adapter->registrypriv.mp_mode == 1 && Adapter->mppriv.mp_dm ==0) // for MP power tracking return; //#endif if (!rtw_is_hw_init_completed(Adapter)) goto skip_dm; #ifdef CONFIG_LPS bFwCurrentInPSMode = adapter_to_pwrctl(Adapter)->bFwCurrentInPSMode; rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); #endif #ifdef CONFIG_P2P // Fw is under p2p powersaving mode, driver should stop dynamic mechanism. // modifed by thomas. 2011.06.11. if(Adapter->wdinfo.p2p_ps_mode) bFwPSAwake = _FALSE; #endif //CONFIG_P2P if ((rtw_is_hw_init_completed(Adapter)) && ((!bFwCurrentInPSMode) && bFwPSAwake)) { // // Calculate Tx/Rx statistics. // dm_CheckStatistics(Adapter); rtw_hal_check_rxfifo_full(Adapter); // // Dynamically switch RTS/CTS protection. // //dm_CheckProtection(Adapter); #ifdef CONFIG_PCI_HCI // 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput. // Tx Migration settings. //dm_InterruptMigration(Adapter); //if(Adapter->HalFunc.TxCheckStuckHandler(Adapter)) // PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem)); #endif } //ODM if (rtw_is_hw_init_completed(Adapter)) { u8 bLinked=_FALSE; u8 bsta_state=_FALSE; u8 bBtDisabled = _TRUE; if(rtw_linked_check(Adapter)){ bLinked = _TRUE; if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) bsta_state = _TRUE; } #ifdef CONFIG_CONCURRENT_MODE if(pbuddy_adapter && rtw_linked_check(pbuddy_adapter)){ bLinked = _TRUE; if(pbuddy_adapter && check_fwstate(&pbuddy_adapter->mlmepriv, WIFI_STATION_STATE)) bsta_state = _TRUE; } #endif //CONFIG_CONCURRENT_MODE ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked); ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_STATION_STATE, bsta_state); //ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM); #ifdef CONFIG_BT_COEXIST bBtDisabled = rtw_btcoex_IsBtDisabled(Adapter); #endif // CONFIG_BT_COEXIST ODM_CmnInfoUpdate(&pHalData->odmpriv, ODM_CMNINFO_BT_ENABLED, ((bBtDisabled == _TRUE)?_FALSE:_TRUE)); ODM_DMWatchdog(&pHalData->odmpriv); } skip_dm: // Check GPIO to determine current RF on/off and Pbc status. // Check Hardware Radio ON/OFF or not //if(Adapter->MgntInfo.PowerSaveControl.bGpioRfSw) //{ //RTPRINT(FPWR, PWRHW, ("dm_CheckRfCtrlGPIO \n")); // dm_CheckRfCtrlGPIO(Adapter); //} #ifdef CONFIG_SUPPORT_HW_WPS_PBC dm_CheckPbcGPIO(Adapter); #endif return; }
int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) { int ret = _SUCCESS; u8 *p; u8 *pHT_caps_ie = NULL; u8 *pHT_info_ie = NULL; struct sta_info *psta = NULL; u16 cap, ht_cap = false; uint ie_len = 0; int group_cipher, pairwise_cipher; u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; int supportRateNum = 0; u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01}; u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; u8 *ie = pbss_network->ies; /* SSID */ /* Supported rates */ /* DS Params */ /* WLAN_EID_COUNTRY */ /* ERP Information element */ /* Extended supported rates */ /* WPA/WPA2 */ /* Wi-Fi Wireless Multimedia Extensions */ /* ht_capab, ht_oper */ /* WPS IE */ DBG_88E("%s, len =%d\n", __func__, len); if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) return _FAIL; if (len < 0 || len > MAX_IE_SZ) return _FAIL; pbss_network->ie_length = len; memset(ie, 0, MAX_IE_SZ); memcpy(ie, pbuf, pbss_network->ie_length); if (pbss_network->InfrastructureMode != Ndis802_11APMode) return _FAIL; pbss_network->Rssi = 0; ether_addr_copy(pbss_network->MacAddress, myid(&padapter->eeprompriv)); /* beacon interval */ p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p); /* capability */ cap = get_unaligned_le16(ie); /* SSID */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) { memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(pbss_network->ssid.ssid, (p + 2), ie_len); pbss_network->ssid.ssid_length = ie_len; } /* channel */ channel = 0; pbss_network->Configuration.Length = 0; p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) channel = *(p + 2); pbss_network->Configuration.DSConfig = channel; memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX); /* get supported rates */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p) { memcpy(supportRate, p + 2, ie_len); supportRateNum = ie_len; } /* get ext_supported rates */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_); if (p) { memcpy(supportRate + supportRateNum, p + 2, ie_len); supportRateNum += ie_len; } network_type = rtw_check_network_type(supportRate, supportRateNum, channel); rtw_set_supported_rate(pbss_network->SupportedRates, network_type); /* parsing ERP_IE */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) ERP_IE_handler(padapter, (struct ndis_802_11_var_ie *)p); /* update privacy/security */ if (cap & BIT(4)) pbss_network->Privacy = 1; else pbss_network->Privacy = 0; psecuritypriv->wpa_psk = 0; /* wpa2 */ group_cipher = 0; pairwise_cipher = 0; psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) { if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ psecuritypriv->wpa_psk |= BIT(1); psecuritypriv->wpa2_group_cipher = group_cipher; psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; } } /* wpa */ ie_len = 0; group_cipher = 0; pairwise_cipher = 0; psecuritypriv->wpa_group_cipher = _NO_PRIVACY_; psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_; for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) { p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2))); if ((p) && (!memcmp(p + 2, OUI1, 4))) { if (rtw_parse_wpa_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ psecuritypriv->wpa_psk |= BIT(0); psecuritypriv->wpa_group_cipher = group_cipher; psecuritypriv->wpa_pairwise_cipher = pairwise_cipher; } break; } if ((!p) || (ie_len == 0)) break; } /* wmm */ ie_len = 0; pmlmepriv->qospriv.qos_option = 0; if (pregistrypriv->wmm_enable) { for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) { p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2))); if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) { pmlmepriv->qospriv.qos_option = 1; /* QoS Info, support U-APSD */ *(p + 8) |= BIT(7); /* disable all ACM bits since the WMM * admission control is not supported */ *(p + 10) &= ~BIT(4); /* BE */ *(p + 14) &= ~BIT(4); /* BK */ *(p + 18) &= ~BIT(4); /* VI */ *(p + 22) &= ~BIT(4); /* VO */ break; } if ((!p) || (ie_len == 0)) break; } } /* parsing HT_CAP_IE */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) { struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p + 2); pHT_caps_ie = p; ht_cap = true; network_type |= WIRELESS_11_24N; if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) || (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2)); else pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); /* set Max Rx AMPDU size to 64K */ pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03); pht_cap->mcs.rx_mask[0] = 0xff; pht_cap->mcs.rx_mask[1] = 0x0; memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); } /* parsing HT_INFO_IE */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) pHT_info_ie = p; switch (network_type) { case WIRELESS_11B: pbss_network->NetworkTypeInUse = Ndis802_11DS; break; case WIRELESS_11G: case WIRELESS_11BG: case WIRELESS_11G_24N: case WIRELESS_11BG_24N: pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; break; case WIRELESS_11A: pbss_network->NetworkTypeInUse = Ndis802_11OFDM5; break; default: pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; break; } pmlmepriv->cur_network.network_type = network_type; pmlmepriv->htpriv.ht_option = false; if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) { /* todo: */ /* ht_cap = false; */ } /* ht_cap */ if (pregistrypriv->ht_enable && ht_cap) { pmlmepriv->htpriv.ht_option = true; pmlmepriv->qospriv.qos_option = 1; if (pregistrypriv->ampdu_enable == 1) pmlmepriv->htpriv.ampdu_enable = true; HT_caps_handler(padapter, (struct ndis_802_11_var_ie *)pHT_caps_ie); HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie); } pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pbss_network); /* issue beacon to start bss network */ start_bss_network(padapter, (u8 *)pbss_network); /* alloc sta_info for ap itself */ psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress); if (!psta) { psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress); if (!psta) return _FAIL; } /* fix bug of flush_cam_entry at STOP AP mode */ psta->state |= WIFI_AP_STATE; rtw_indicate_connect(padapter); pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */ return ret; }
static void rtl8723bs_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_, ("rtl8723bs_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(padapter, precvframe, (struct recv_stat*)ptr); #if 0 { int i, len = 64; u8 *pptr = ptr; if((*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x80) && (*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x40)) { DBG_871X("##############RxDESC############### \n"); for(i=0; i<32;i=i+16) DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(pptr+i), *(pptr+i+1), *(pptr+i+2) ,*(pptr+i+3) ,*(pptr+i+4),*(pptr+i+5), *(pptr+i+6), *(pptr+i+7), *(pptr+i+8), *(pptr+i+9), *(pptr+i+10), *(pptr+i+11), *(pptr+i+12), *(pptr+i+13), *(pptr+i+14), *(pptr+i+15)); if(pattrib->pkt_len < 100) len = pattrib->pkt_len; pptr = ptr + RXDESC_SIZE + pattrib->drvinfo_sz; DBG_871X("##############Len=%d############### \n", pattrib->pkt_len); for(i=0; i<len;i=i+16) DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(pptr+i), *(pptr+i+1), *(pptr+i+2) ,*(pptr+i+3) ,*(pptr+i+4),*(pptr+i+5), *(pptr+i+6), *(pptr+i+7), *(pptr+i+8), *(pptr+i+9), *(pptr+i+10), *(pptr+i+11), *(pptr+i+12), *(pptr+i+13), *(pptr+i+14), *(pptr+i+15)); DBG_871X("############################# \n"); } } #endif // fix Hardware RX data error, drop whole recv_buffer if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err) { 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)) { #ifdef CONFIG_MP_INCLUDED if (padapter->registrypriv.mp_mode == 1) { if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0)) { if (pattrib->crc_err == 1) padapter->mppriv.rx_crcerrpktcount++; } } #endif 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_, ("rtl8723bs_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; } if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet { #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_info_, ("rtl8723bs_recv_tasklet: rtw_recv_entry(precvframe) != _SUCCESS\n")); } } } #ifdef CONFIG_C2H_PACKET_EN else if(pattrib->pkt_rpt_type == C2H_PACKET) { rtl8723bs_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); } #endif } pkt_offset = _RND8(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); }
bool rtw_pwr_unassociated_idle(_adapter *adapter) { _adapter *buddy = adapter->pbuddy_adapter; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); #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; } } #ifdef CONFIG_INTEL_PROXIM if(adapter->proximity.proxim_on==_TRUE){ return; } #endif ret = _TRUE; exit: return ret; }
/* * 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); _enter_critical_bh(&pxmitpriv->lock, &irql); 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 DBG_871X("%s: coalesce FAIL!", __FUNCTION__); } 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); _exit_critical_bh(&pxmitpriv->lock, &irql); // 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; }
int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame) { struct recv_priv *precvpriv; _queue *pfree_recv_queue; _pkt *skb; struct mlme_priv*pmlmepriv = &padapter->mlmepriv; #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; #endif #ifdef CONFIG_BR_EXT void *br_port = NULL; #endif _func_enter_; precvpriv = &(padapter->recvpriv); pfree_recv_queue = &(precvpriv->free_recv_queue); #ifdef CONFIG_DRVEXT_MODULE if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS) { goto _recv_indicatepkt_drop; } #endif skb = precv_frame->u.hdr.pkt; if(skb == NULL) { RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n")); goto _recv_indicatepkt_drop; } RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n")); RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data)); RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len)); skb->data = precv_frame->u.hdr.rx_data; skb_set_tail_pointer(skb, precv_frame->u.hdr.len); skb->len = precv_frame->u.hdr.len; RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb->tail, skb->end, skb->len)); if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { _pkt *pskb2=NULL; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; int bmcast = IS_MCAST(pattrib->dst); //DBG_871X("bmcast=%d\n", bmcast); if(_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)==_FALSE) { //DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst); if(bmcast) { psta = rtw_get_bcmc_stainfo(padapter); pskb2 = rtw_skb_clone(skb); } else { psta = rtw_get_stainfo(pstapriv, pattrib->dst); } if(psta) { int tx_ret; struct net_device *pnetdev= (struct net_device*)padapter->pnetdev; //DBG_871X("directly forwarding to the rtw_xmit_entry\n"); //skb->ip_summed = CHECKSUM_NONE; skb->dev = pnetdev; #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) skb_set_queue_mapping(skb, rtw_recv_select_queue(skb)); #endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) tx_ret = _rtw_xmit_entry(skb, pnetdev); if (tx_ret != NETDEV_TX_OK) { padapter->xmitpriv.tx_drop++; rtw_skb_free(skb); } if(bmcast) skb = pskb2; else goto _recv_indicatepkt_end; } } else// to APself { //DBG_871X("to APSelf\n"); } } #ifdef CONFIG_BR_EXT #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) br_port = padapter->pnetdev->br_port; #else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) rcu_read_lock(); br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); rcu_read_unlock(); #endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) if( br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) ) { int nat25_handle_frame(_adapter *priv, struct sk_buff *skb); if (nat25_handle_frame(padapter, skb) == -1) { //priv->ext_stats.rx_data_drops++; //DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); //return FAIL; #if 1 // bypass this frame to upper layer!! #else goto _recv_indicatepkt_drop; #endif } } #endif // CONFIG_BR_EXT #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { skb->ip_summed = CHECKSUM_UNNECESSARY; //DBG_871X("CHECKSUM_UNNECESSARY \n"); } else { skb->ip_summed = CHECKSUM_NONE; //DBG_871X("CHECKSUM_NONE(%d, %d) \n", pattrib->tcpchk_valid, pattrib->tcp_chkrpt); } #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */ skb->ip_summed = CHECKSUM_NONE; #endif skb->dev = padapter->pnetdev; skb->protocol = eth_type_trans(skb, padapter->pnetdev); rtw_netif_rx(padapter->pnetdev, skb); _recv_indicatepkt_end: precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe() rtw_free_recvframe(precv_frame, pfree_recv_queue); RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_netif_rx!!!!\n")); _func_exit_; return _SUCCESS; _recv_indicatepkt_drop: //enqueue back to free_recv_queue if(precv_frame) rtw_free_recvframe(precv_frame, pfree_recv_queue); return _FAIL; _func_exit_; }
u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid) { _irqL irqL; u8 status=_TRUE; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; _queue *queue = &pmlmepriv->scanned_queue; _func_enter_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, ("+rtw_set_802_11_bssid: bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5])); 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 = _FALSE; return status; } _enter_critical_bh(&pmlmepriv->lock, &irqL); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("\n rtw_set_802_11_bssid: bssid= 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5])); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set BSSID is not allowed under surveying || adhoc master || under linking, fw_state=0x%08x\n", get_fwstate(pmlmepriv))); status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); goto _Abort_Set_BSSID; } 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 _Abort_Set_BSSID;//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 ssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", bssid[0],bssid[1],bssid[2],bssid[3],bssid[4],bssid[5])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", pmlmepriv->cur_network.network.MacAddress[0],pmlmepriv->cur_network.network.MacAddress[1],pmlmepriv->cur_network.network.MacAddress[2], pmlmepriv->cur_network.network.MacAddress[3],pmlmepriv->cur_network.network.MacAddress[4],pmlmepriv->cur_network.network.MacAddress[5])); rtw_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); pmlmepriv->assoc_by_bssid=_TRUE; status = do_join(padapter); goto done; _Abort_Set_BSSID: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_bssid: _Abort_Set_BSSID\n")); done: _exit_critical_bh(&pmlmepriv->lock, &irqL); _func_exit_; return status; }
static int rtw_hw_suspend(struct adapter *padapter) { struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct net_device *pnetdev = padapter->pnetdev; if ((!padapter->bup) || (padapter->bDriverStopped) || (padapter->bSurpriseRemoved)) { DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", padapter->bup, padapter->bDriverStopped, padapter->bSurpriseRemoved); goto error_exit; } /* system suspend */ LeaveAllPowerSaveMode(padapter); DBG_88E("==> rtw_hw_suspend\n"); _enter_pwrlock(&pwrpriv->lock); pwrpriv->bips_processing = true; /* s1. */ if (pnetdev) { netif_carrier_off(pnetdev); netif_tx_stop_all_queues(pnetdev); } /* s2. */ rtw_disassoc_cmd(padapter, 500, false); /* s2-2. indicate disconnect to os */ { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (check_fwstate(pmlmepriv, _FW_LINKED)) { _clr_fwstate_(pmlmepriv, _FW_LINKED); rtw_led_control(padapter, LED_CTL_NO_LINK); rtw_os_indicate_disconnect(padapter); /* donnot enqueue cmd */ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0); } } /* s2-3. */ rtw_free_assoc_resources(padapter); /* s2-4. */ rtw_free_network_queue(padapter, true); rtw_ips_dev_unload(padapter); pwrpriv->rf_pwrstate = rf_off; pwrpriv->bips_processing = false; _exit_pwrlock(&pwrpriv->lock); return 0; error_exit: DBG_88E("%s, failed\n", __func__); return -1; }
u8 rtw_set_802_11_infrastructure_mode(_adapter* padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) { _irqL irqL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &pmlmepriv->cur_network; NDIS_802_11_NETWORK_INFRASTRUCTURE* pold_state = &(cur_network->network.InfrastructureMode); _func_enter_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_notice_, ("+rtw_set_802_11_infrastructure_mode: old=%d new=%d fw_state=0x%08x\n", *pold_state, networktype, pmlmepriv->fw_state)); if(*pold_state != networktype) { _enter_critical_bh(&pmlmepriv->lock, &irqL); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,(" change mode!")); //DBG_871X("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, pmlmepriv->fw_state); if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||(*pold_state==Ndis802_11IBSS)) rtw_disassoc_cmd(padapter); if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)== _TRUE) ) rtw_free_assoc_resources(padapter); if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) || (*pold_state==Ndis802_11Infrastructure) ||(*pold_state==Ndis802_11IBSS)) { rtw_indicate_disconnect(padapter); //will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not } if(*pold_state==Ndis802_11APMode) { //todo: change to other mode from Ndis802_11APMode cur_network->join_res = -1; } *pold_state = networktype; // clear WIFI_STATION_STATE; WIFI_AP_STATE; WIFI_ADHOC_STATE; WIFI_ADHOC_MASTER_STATE //pmlmepriv->fw_state &= 0xffffff87; _clr_fwstate_(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE); switch(networktype) { case Ndis802_11IBSS: set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); break; case Ndis802_11Infrastructure: set_fwstate(pmlmepriv, WIFI_STATION_STATE); break; case Ndis802_11APMode: set_fwstate(pmlmepriv, WIFI_AP_STATE); //rtw_indicate_connect(padapter); break; case Ndis802_11AutoUnknown: case Ndis802_11InfrastructureMax: break; } //SecClearAllKeys(adapter); //RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", // pmlmepriv->fw_state )); _exit_critical_bh(&pmlmepriv->lock, &irqL); } _func_exit_; return _TRUE; }
int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller) { struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; unsigned long expires; unsigned long start; int ret = _SUCCESS; expires = jiffies + msecs_to_jiffies(ips_deffer_ms); if (time_before(pwrpriv->ips_deny_time, expires)) pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms); start = jiffies; if (pwrpriv->ps_processing) { DBG_88E("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && jiffies_to_msecs(jiffies - start) <= 3000) usleep_range(1000, 3000); if (pwrpriv->ps_processing) DBG_88E("%s wait ps_processing timeout\n", __func__); else DBG_88E("%s wait ps_processing done\n", __func__); } /* System suspend is not allowed to wakeup */ if ((!pwrpriv->bInternalAutoSuspend) && (pwrpriv->bInSuspend)) { ret = _FAIL; goto exit; } /* block??? */ if ((pwrpriv->bInternalAutoSuspend) && (padapter->net_closed)) { ret = _FAIL; goto exit; } /* I think this should be check in IPS, LPS, autosuspend functions... */ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ret = _SUCCESS; goto exit; } if (rf_off == pwrpriv->rf_pwrstate) { DBG_88E("%s call ips_leave....\n", __func__); if (_FAIL == ips_leave(padapter)) { DBG_88E("======> ips_leave fail.............\n"); ret = _FAIL; goto exit; } } /* TODO: the following checking need to be merged... */ if (padapter->bDriverStopped || !padapter->bup || !padapter->hw_init_completed) { DBG_88E("%s: bDriverStopped=%d, bup=%d, hw_init_completed =%u\n" , caller , padapter->bDriverStopped , padapter->bup , padapter->hw_init_completed); ret = false; goto exit; } exit: expires = jiffies + msecs_to_jiffies(ips_deffer_ms); if (time_before(pwrpriv->ips_deny_time, expires)) pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms); return ret; }
u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){ uint encryptionalgo; u8 * pbssid; struct sta_info *stainfo; u8 bgroup = _FALSE; u8 bgrouptkey = _FALSE;//can be remove later u8 ret=_SUCCESS; _func_enter_; if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){ // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, // it must fail the request and return NDIS_STATUS_INVALID_DATA. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActSet_802_11_ADD_KEY: ((key->KeyIndex & 0x80000000) == 0)[=%d] ",(int)(key->KeyIndex & 0x80000000) == 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActSet_802_11_ADD_KEY:((key->KeyIndex & 0x40000000) > 0)[=%d]" , (int)(key->KeyIndex & 0x40000000) > 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActSet_802_11_ADD_KEY: key->KeyIndex=%d \n" ,(int)key->KeyIndex)); ret= _FAIL; goto exit; } if(key->KeyIndex & 0x40000000) { // Pairwise key RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n")); pbssid=get_bssid(&padapter->mlmepriv); stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid); if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n")); encryptionalgo=stainfo->dot118021XPrivacy; } else{ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n")); encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; } RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Set_802_11_ADD_KEY: (encryptionalgo ==%d)!\n",encryptionalgo )); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Set_802_11_ADD_KEY: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Set_802_11_ADD_KEY: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm)); if((stainfo!=NULL)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Set_802_11_ADD_KEY: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy)); } if(key->KeyIndex & 0x000000FF){ // The key index is specified in the lower 8 bits by values of zero to 255. // The key index should be set to zero for a Pairwise key, and the driver should fail with // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n")); ret= _FAIL; goto exit; } // check BSSID if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MacAddr_isBcst(key->BSSID)\n")); ret= _FALSE; goto exit; } // Check key length for TKIP. //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength)); ret=_FAIL; goto exit; } // Check key length for AES. if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) { // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. if(key->KeyLength == 32) { key->KeyLength = 16; } else { ret= _FAIL; goto exit; } } // Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. if( (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength)); ret=_FAIL; goto exit; } bgroup = _FALSE; // Check the pairwise key. Added by Annie, 2005-07-06. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); } else { // Group key - KeyIndex(BIT30==0) RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n")); // when add wep key through add key and didn't assigned encryption type before if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("keylen=%d( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength,padapter->securitypriv.dot11PrivacyAlgrthm,padapter->securitypriv.dot118021XGrpPrivacy)); switch(key->KeyLength) { case 5: padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; case 13: padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; default: padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; } encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm)); } else { encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm,encryptionalgo,padapter->securitypriv.dot118021XGrpPrivacy,key->KeyLength)); } if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n")); ret= _FAIL; goto exit; } // Check key length for TKIP if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength)); ret= _FAIL; goto exit; } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) { // Check key length for AES // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength)); ret= _FAIL; goto exit; } // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) { key->KeyLength = 16; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) ); } if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000 bgrouptkey = _TRUE; } if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE)) { bgrouptkey = _TRUE; } bgroup = _TRUE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") ); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") ); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); } // If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_)) { u8 ret; u32 keyindex; u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength; NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n")); wep->Length = len; keyindex = key->KeyIndex&0x7fffffff; wep->KeyIndex = keyindex ; wep->KeyLength = key->KeyLength; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n")); _rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); _rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength; padapter->securitypriv.dot11PrivacyKeyIndex=keyindex; ret = rtw_set_802_11_add_wep(padapter, wep); goto exit; } if(key->KeyIndex & 0x20000000){ // SetRSC RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n")); if(bgroup == _TRUE) { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; _rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8); } else { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; _rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8); } } // Indicate this key idx is used for TX // Save the key in KeyMaterial if(bgroup == _TRUE) // Group transmit key { int res; if(bgrouptkey == _TRUE) { padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex; } if((key->KeyIndex&0x3) == 0){ ret = _FAIL; goto exit; } _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex-1) & 0x03)], 0, 16); _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey, 0, 16); _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey, 0, 16); if((key->KeyIndex & 0x10000000)) { _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey, key->KeyMaterial + 16, 8); _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey, key->KeyMaterial + 24, 8); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", padapter->securitypriv.dot118021XGrprxmickey.skey[0],padapter->securitypriv.dot118021XGrprxmickey.skey[1], padapter->securitypriv.dot118021XGrprxmickey.skey[2],padapter->securitypriv.dot118021XGrprxmickey.skey[3], padapter->securitypriv.dot118021XGrprxmickey.skey[4],padapter->securitypriv.dot118021XGrprxmickey.skey[5], padapter->securitypriv.dot118021XGrprxmickey.skey[6],padapter->securitypriv.dot118021XGrprxmickey.skey[7])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); } else { _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey, key->KeyMaterial + 24, 8); _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey, key->KeyMaterial + 16, 8); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", padapter->securitypriv.dot118021XGrprxmickey.skey[0],padapter->securitypriv.dot118021XGrprxmickey.skey[1], padapter->securitypriv.dot118021XGrprxmickey.skey[2],padapter->securitypriv.dot118021XGrprxmickey.skey[3], padapter->securitypriv.dot118021XGrprxmickey.skey[4],padapter->securitypriv.dot118021XGrprxmickey.skey[5], padapter->securitypriv.dot118021XGrprxmickey.skey[6],padapter->securitypriv.dot118021XGrprxmickey.skey[7])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); } //set group key by index _rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex-1) & 0x03)], key->KeyMaterial, key->KeyLength); key->KeyIndex=key->KeyIndex & 0x03; padapter->securitypriv.binstallGrpkey=_TRUE; padapter->securitypriv.bcheck_grpkey=_FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key")); res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex); if(res==_FAIL) ret= _FAIL; goto exit; } else // Pairwise Key { u8 res; pbssid=get_bssid(&padapter->mlmepriv); stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid ); if(stainfo!=NULL) { _rtw_memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer _rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); if(encryptionalgo== _TKIP_) { padapter->securitypriv.busetkipkey=_FALSE; _set_timer(&padapter->securitypriv.tkip_timer, 50); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n")); // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] if((key->KeyIndex & 0x10000000)){ _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); } else { _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); } } else if(encryptionalgo == _AES_) { } //Set key to CAM through H2C command if(bgrouptkey)//never go to here { res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n")); } else{ res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n")); } if(res ==_FALSE) ret= _FAIL; } } exit: _func_exit_; return ret; }
VOID rtl8192e_HalDmWatchDog( IN PADAPTER Adapter ) { BOOLEAN bFwCurrentInPSMode = _FALSE; BOOLEAN bFwPSAwake = _TRUE; u8 hw_init_completed = _FALSE; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); #ifdef CONFIG_CONCURRENT_MODE PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; #endif //CONFIG_CONCURRENT_MODE _func_enter_; hw_init_completed = Adapter->hw_init_completed; if (hw_init_completed == _FALSE) goto skip_dm; #ifdef CONFIG_LPS bFwCurrentInPSMode = adapter_to_pwrctl(Adapter)->bFwCurrentInPSMode; rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); #endif #ifdef CONFIG_P2P_PS // Fw is under p2p powersaving mode, driver should stop dynamic mechanism. // modifed by thomas. 2011.06.11. if(Adapter->wdinfo.p2p_ps_mode) bFwPSAwake = _FALSE; #endif //CONFIG_P2P_PS if( (hw_init_completed == _TRUE) && ((!bFwCurrentInPSMode) && bFwPSAwake)) { // // Calculate Tx/Rx statistics. // dm_CheckStatistics(Adapter); rtw_hal_check_rxfifo_full(Adapter); // // Dynamically switch RTS/CTS protection. // //dm_CheckProtection(Adapter); #ifdef CONFIG_PCI_HCI // 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput. // Tx Migration settings. //dm_InterruptMigration(Adapter); //if(Adapter->HalFunc.TxCheckStuckHandler(Adapter)) // PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem)); #endif } //ODM if (hw_init_completed == _TRUE) { u8 bLinked=_FALSE; u8 bsta_state=_FALSE; #ifdef CONFIG_DISABLE_ODM pHalData->odmpriv.SupportAbility = 0; #endif if(rtw_linked_check(Adapter)){ bLinked = _TRUE; if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) bsta_state = _TRUE; } #ifdef CONFIG_CONCURRENT_MODE if(pbuddy_adapter && rtw_linked_check(pbuddy_adapter)){ bLinked = _TRUE; if(pbuddy_adapter && check_fwstate(&pbuddy_adapter->mlmepriv, WIFI_STATION_STATE)) bsta_state = _TRUE; } #endif //CONFIG_CONCURRENT_MODE ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked); ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_STATION_STATE, bsta_state); ODM_DMWatchdog(&pHalData->odmpriv); } skip_dm: #ifdef CONFIG_SUPPORT_HW_WPS_PBC // Check GPIO to determine current Pbc status. dm_CheckPbcGPIO(Adapter); #endif return; }